Commit f04a9b49 authored by predrag.rudic's avatar predrag.rudic Committed by Commit bot

Fix 'MIPS: Fix Utf16CharacterStream scanner crash due to missaligned access'

Removed a wrong condition test in  TwoByteExternalBufferedStream. This changed fixes errors that may occur under some conditions.

Review-Url: https://codereview.chromium.org/2469723002
Cr-Commit-Position: refs/heads/master@{#40722}
parent 9b308dca
...@@ -537,7 +537,7 @@ size_t OneByteExternalStreamingStream::FillBuffer(size_t position) { ...@@ -537,7 +537,7 @@ size_t OneByteExternalStreamingStream::FillBuffer(size_t position) {
return len; return len;
} }
#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM) #if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// TwoByteExternalStreamingStream // TwoByteExternalStreamingStream
// //
...@@ -703,6 +703,7 @@ bool TwoByteExternalBufferedStream::ReadBlock() { ...@@ -703,6 +703,7 @@ bool TwoByteExternalBufferedStream::ReadBlock() {
DCHECK_EQ(position, pos()); DCHECK_EQ(position, pos());
return true; return true;
} else { } else {
buffer_start_ = buffer_;
buffer_pos_ = position; buffer_pos_ = position;
buffer_cursor_ = buffer_; buffer_cursor_ = buffer_;
buffer_end_ = buffer_ + FillBuffer(position, chunk_no); buffer_end_ = buffer_ + FillBuffer(position, chunk_no);
...@@ -714,6 +715,8 @@ bool TwoByteExternalBufferedStream::ReadBlock() { ...@@ -714,6 +715,8 @@ bool TwoByteExternalBufferedStream::ReadBlock() {
size_t TwoByteExternalBufferedStream::FillBuffer(size_t position, size_t TwoByteExternalBufferedStream::FillBuffer(size_t position,
size_t chunk_no) { size_t chunk_no) {
DCHECK_EQ(chunks_[chunk_no].byte_pos % 2, 1);
bool odd_start = true;
// Align buffer_pos_ to the size of the buffer. // Align buffer_pos_ to the size of the buffer.
{ {
size_t new_pos = position / kBufferSize * kBufferSize; size_t new_pos = position / kBufferSize * kBufferSize;
...@@ -722,6 +725,7 @@ size_t TwoByteExternalBufferedStream::FillBuffer(size_t position, ...@@ -722,6 +725,7 @@ size_t TwoByteExternalBufferedStream::FillBuffer(size_t position,
buffer_pos_ = new_pos; buffer_pos_ = new_pos;
buffer_cursor_ = buffer_start_ + (position - buffer_pos_); buffer_cursor_ = buffer_start_ + (position - buffer_pos_);
position = new_pos; position = new_pos;
odd_start = chunks_[chunk_no].byte_pos % 2;
} }
} }
...@@ -742,18 +746,18 @@ size_t TwoByteExternalBufferedStream::FillBuffer(size_t position, ...@@ -742,18 +746,18 @@ size_t TwoByteExternalBufferedStream::FillBuffer(size_t position,
} }
// Common case: character is in current chunk. // Common case: character is in current chunk.
DCHECK_LE(current->byte_pos, 2 * position + 1); DCHECK_LE(current->byte_pos, 2 * position + odd_start);
DCHECK_LT(2 * position + 1, current->byte_pos + current->byte_length); DCHECK_LT(2 * position + 1, current->byte_pos + current->byte_length);
// Copy characters from current chunk starting from chunk_pos to the end of // Copy characters from current chunk starting from chunk_pos to the end of
// buffer or chunk. // buffer or chunk.
size_t chunk_pos = position - current->byte_pos / 2; size_t chunk_pos = position - current->byte_pos / 2;
bool middle_of_chunk = chunk_pos != 0; size_t start_offset = odd_start && chunk_pos != 0;
size_t bytes_to_move = size_t bytes_to_move =
i::Min(2 * kBufferSize - !middle_of_chunk, i::Min(2 * kBufferSize - lonely_byte,
current->byte_length - 2 * chunk_pos + middle_of_chunk); current->byte_length - 2 * chunk_pos + start_offset);
i::MemMove(reinterpret_cast<uint8_t*>(buffer_) + !middle_of_chunk, i::MemMove(reinterpret_cast<uint8_t*>(buffer_) + lonely_byte,
current->data + 2 * chunk_pos - middle_of_chunk, bytes_to_move); current->data + 2 * chunk_pos - start_offset, bytes_to_move);
// Fill up the rest of the buffer if there is space and data left. // Fill up the rest of the buffer if there is space and data left.
totalLength += bytes_to_move; totalLength += bytes_to_move;
...@@ -761,10 +765,11 @@ size_t TwoByteExternalBufferedStream::FillBuffer(size_t position, ...@@ -761,10 +765,11 @@ size_t TwoByteExternalBufferedStream::FillBuffer(size_t position,
if (position - buffer_pos_ < kBufferSize) { if (position - buffer_pos_ < kBufferSize) {
chunk_no = FindChunk(chunks_, source_, 2 * position + 1); chunk_no = FindChunk(chunks_, source_, 2 * position + 1);
current = &chunks_[chunk_no]; current = &chunks_[chunk_no];
odd_start = current->byte_pos % 2;
bytes_to_move = i::Min(2 * kBufferSize - totalLength, current->byte_length); bytes_to_move = i::Min(2 * kBufferSize - totalLength, current->byte_length);
while (bytes_to_move && current->byte_pos % 2) { while (bytes_to_move) {
// Common case: character is in current chunk. // Common case: character is in current chunk.
DCHECK_LE(current->byte_pos, 2 * position + 1); DCHECK_LE(current->byte_pos, 2 * position + odd_start);
DCHECK_LT(2 * position + 1, current->byte_pos + current->byte_length); DCHECK_LT(2 * position + 1, current->byte_pos + current->byte_length);
i::MemMove(reinterpret_cast<uint8_t*>(buffer_) + totalLength, i::MemMove(reinterpret_cast<uint8_t*>(buffer_) + totalLength,
...@@ -773,6 +778,7 @@ size_t TwoByteExternalBufferedStream::FillBuffer(size_t position, ...@@ -773,6 +778,7 @@ size_t TwoByteExternalBufferedStream::FillBuffer(size_t position,
position = (current->byte_pos + current->byte_length) / 2; position = (current->byte_pos + current->byte_length) / 2;
chunk_no = FindChunk(chunks_, source_, 2 * position + 1); chunk_no = FindChunk(chunks_, source_, 2 * position + 1);
current = &chunks_[chunk_no]; current = &chunks_[chunk_no];
odd_start = current->byte_pos % 2;
bytes_to_move = bytes_to_move =
i::Min(2 * kBufferSize - totalLength, current->byte_length); i::Min(2 * kBufferSize - totalLength, current->byte_length);
} }
...@@ -820,7 +826,7 @@ Utf16CharacterStream* ScannerStream::For( ...@@ -820,7 +826,7 @@ Utf16CharacterStream* ScannerStream::For(
v8::ScriptCompiler::StreamedSource::Encoding encoding) { v8::ScriptCompiler::StreamedSource::Encoding encoding) {
switch (encoding) { switch (encoding) {
case v8::ScriptCompiler::StreamedSource::TWO_BYTE: case v8::ScriptCompiler::StreamedSource::TWO_BYTE:
#if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_ARM) #if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64)
return new TwoByteExternalStreamingStream(source_stream); return new TwoByteExternalStreamingStream(source_stream);
#else #else
return new TwoByteExternalBufferedStream(source_stream); return new TwoByteExternalBufferedStream(source_stream);
......
...@@ -27,7 +27,7 @@ class ChunkSource : public v8::ScriptCompiler::ExternalSourceStream { ...@@ -27,7 +27,7 @@ class ChunkSource : public v8::ScriptCompiler::ExternalSourceStream {
// If extra_chunky, we'll use increasingly large chunk sizes. // If extra_chunky, we'll use increasingly large chunk sizes.
// If not, we'll have a single chunk of full length. // If not, we'll have a single chunk of full length.
size_t chunk_size = extra_chunky ? 1 : len; size_t chunk_size = extra_chunky ? 1 : len;
for (size_t i = 0; i < len; i += chunk_size, chunk_size *= 2) { for (size_t i = 0; i < len; i += chunk_size, chunk_size++) {
chunks_.push_back({data + i, i::Min(chunk_size, len - i)}); chunks_.push_back({data + i, i::Min(chunk_size, len - i)});
} }
chunks_.push_back({nullptr, 0}); chunks_.push_back({nullptr, 0});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment