| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/parsing/scanner-character-streams.h" | 5 #include "src/parsing/scanner-character-streams.h" |
| 6 | 6 |
| 7 #include "include/v8.h" | 7 #include "include/v8.h" |
| 8 #include "src/counters.h" |
| 8 #include "src/globals.h" | 9 #include "src/globals.h" |
| 9 #include "src/handles.h" | 10 #include "src/handles.h" |
| 10 #include "src/objects-inl.h" | 11 #include "src/objects-inl.h" |
| 11 #include "src/parsing/scanner.h" | 12 #include "src/parsing/scanner.h" |
| 12 #include "src/unicode-inl.h" | 13 #include "src/unicode-inl.h" |
| 13 | 14 |
| 14 namespace v8 { | 15 namespace v8 { |
| 15 namespace internal { | 16 namespace internal { |
| 16 | 17 |
| 17 // ---------------------------------------------------------------------------- | 18 // ---------------------------------------------------------------------------- |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 // Utf8ExternalStreamingStream - chunked streaming of Utf-8 data. | 184 // Utf8ExternalStreamingStream - chunked streaming of Utf-8 data. |
| 184 // | 185 // |
| 185 // This implementation is fairly complex, since data arrives in chunks which | 186 // This implementation is fairly complex, since data arrives in chunks which |
| 186 // may 'cut' arbitrarily into utf-8 characters. Also, seeking to a given | 187 // may 'cut' arbitrarily into utf-8 characters. Also, seeking to a given |
| 187 // character position is tricky because the byte position cannot be dericed | 188 // character position is tricky because the byte position cannot be dericed |
| 188 // from the character position. | 189 // from the character position. |
| 189 | 190 |
| 190 class Utf8ExternalStreamingStream : public BufferedUtf16CharacterStream { | 191 class Utf8ExternalStreamingStream : public BufferedUtf16CharacterStream { |
| 191 public: | 192 public: |
| 192 Utf8ExternalStreamingStream( | 193 Utf8ExternalStreamingStream( |
| 193 ScriptCompiler::ExternalSourceStream* source_stream) | 194 ScriptCompiler::ExternalSourceStream* source_stream, |
| 195 RuntimeCallStats* stats) |
| 194 : current_({0, {0, 0, unibrow::Utf8::Utf8IncrementalBuffer(0)}}), | 196 : current_({0, {0, 0, unibrow::Utf8::Utf8IncrementalBuffer(0)}}), |
| 195 source_stream_(source_stream) {} | 197 source_stream_(source_stream), |
| 198 stats_(stats) {} |
| 196 ~Utf8ExternalStreamingStream() override { | 199 ~Utf8ExternalStreamingStream() override { |
| 197 for (size_t i = 0; i < chunks_.size(); i++) delete[] chunks_[i].data; | 200 for (size_t i = 0; i < chunks_.size(); i++) delete[] chunks_[i].data; |
| 198 } | 201 } |
| 199 | 202 |
| 200 protected: | 203 protected: |
| 201 size_t FillBuffer(size_t position) override; | 204 size_t FillBuffer(size_t position) override; |
| 202 | 205 |
| 203 private: | 206 private: |
| 204 // A position within the data stream. It stores: | 207 // A position within the data stream. It stores: |
| 205 // - The 'physical' position (# of bytes in the stream), | 208 // - The 'physical' position (# of bytes in the stream), |
| (...skipping 28 matching lines...) Expand all Loading... |
| 234 void FillBufferFromCurrentChunk(); | 237 void FillBufferFromCurrentChunk(); |
| 235 // Fetch a new chunk (assuming current_ is at the end of the current data). | 238 // Fetch a new chunk (assuming current_ is at the end of the current data). |
| 236 bool FetchChunk(); | 239 bool FetchChunk(); |
| 237 // Search through the chunks and set current_ to point to the given position. | 240 // Search through the chunks and set current_ to point to the given position. |
| 238 // (This call is potentially expensive.) | 241 // (This call is potentially expensive.) |
| 239 void SearchPosition(size_t position); | 242 void SearchPosition(size_t position); |
| 240 | 243 |
| 241 std::vector<Chunk> chunks_; | 244 std::vector<Chunk> chunks_; |
| 242 Position current_; | 245 Position current_; |
| 243 ScriptCompiler::ExternalSourceStream* source_stream_; | 246 ScriptCompiler::ExternalSourceStream* source_stream_; |
| 247 RuntimeCallStats* stats_; |
| 244 }; | 248 }; |
| 245 | 249 |
| 246 bool Utf8ExternalStreamingStream::SkipToPosition(size_t position) { | 250 bool Utf8ExternalStreamingStream::SkipToPosition(size_t position) { |
| 247 DCHECK_LE(current_.pos.chars, position); // We can only skip forward. | 251 DCHECK_LE(current_.pos.chars, position); // We can only skip forward. |
| 248 | 252 |
| 249 // Already there? Then return immediately. | 253 // Already there? Then return immediately. |
| 250 if (current_.pos.chars == position) return true; | 254 if (current_.pos.chars == position) return true; |
| 251 | 255 |
| 252 const Chunk& chunk = chunks_[current_.chunk_no]; | 256 const Chunk& chunk = chunks_[current_.chunk_no]; |
| 253 DCHECK(current_.pos.bytes >= chunk.start.bytes); | 257 DCHECK(current_.pos.bytes >= chunk.start.bytes); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 | 328 |
| 325 current_.pos.bytes = chunk.start.bytes + it; | 329 current_.pos.bytes = chunk.start.bytes + it; |
| 326 current_.pos.chars += (cursor - buffer_end_); | 330 current_.pos.chars += (cursor - buffer_end_); |
| 327 current_.pos.incomplete_char = incomplete_char; | 331 current_.pos.incomplete_char = incomplete_char; |
| 328 current_.chunk_no += (it == chunk.length); | 332 current_.chunk_no += (it == chunk.length); |
| 329 | 333 |
| 330 buffer_end_ = cursor; | 334 buffer_end_ = cursor; |
| 331 } | 335 } |
| 332 | 336 |
| 333 bool Utf8ExternalStreamingStream::FetchChunk() { | 337 bool Utf8ExternalStreamingStream::FetchChunk() { |
| 338 RuntimeCallTimerScope scope(stats_, &RuntimeCallStats::GetMoreDataCallback); |
| 334 DCHECK_EQ(current_.chunk_no, chunks_.size()); | 339 DCHECK_EQ(current_.chunk_no, chunks_.size()); |
| 335 DCHECK(chunks_.empty() || chunks_.back().length != 0); | 340 DCHECK(chunks_.empty() || chunks_.back().length != 0); |
| 336 | 341 |
| 337 const uint8_t* chunk = nullptr; | 342 const uint8_t* chunk = nullptr; |
| 338 size_t length = source_stream_->GetMoreData(&chunk); | 343 size_t length = source_stream_->GetMoreData(&chunk); |
| 339 chunks_.push_back({chunk, length, current_.pos}); | 344 chunks_.push_back({chunk, length, current_.pos}); |
| 340 return length > 0; | 345 return length > 0; |
| 341 } | 346 } |
| 342 | 347 |
| 343 void Utf8ExternalStreamingStream::SearchPosition(size_t position) { | 348 void Utf8ExternalStreamingStream::SearchPosition(size_t position) { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 | 460 |
| 456 typedef std::vector<struct Chunk> Chunks; | 461 typedef std::vector<struct Chunk> Chunks; |
| 457 | 462 |
| 458 void DeleteChunks(Chunks& chunks) { | 463 void DeleteChunks(Chunks& chunks) { |
| 459 for (size_t i = 0; i < chunks.size(); i++) delete[] chunks[i].data; | 464 for (size_t i = 0; i < chunks.size(); i++) delete[] chunks[i].data; |
| 460 } | 465 } |
| 461 | 466 |
| 462 // Return the chunk index for the chunk containing position. | 467 // Return the chunk index for the chunk containing position. |
| 463 // If position is behind the end of the stream, the index of the last, | 468 // If position is behind the end of the stream, the index of the last, |
| 464 // zero-length chunk is returned. | 469 // zero-length chunk is returned. |
| 465 size_t FindChunk(Chunks& chunks, ScriptCompiler::ExternalSourceStream* source_, | 470 size_t FindChunk(Chunks& chunks, ScriptCompiler::ExternalSourceStream* source, |
| 466 size_t position) { | 471 size_t position, RuntimeCallStats* stats) { |
| 467 size_t end_pos = | 472 size_t end_pos = |
| 468 chunks.empty() ? 0 : (chunks.back().byte_pos + chunks.back().byte_length); | 473 chunks.empty() ? 0 : (chunks.back().byte_pos + chunks.back().byte_length); |
| 469 | 474 |
| 470 // Get more data if needed. We usually won't enter the loop body. | 475 // Get more data if needed. We usually won't enter the loop body. |
| 471 bool out_of_data = !chunks.empty() && chunks.back().byte_length == 0; | 476 bool out_of_data = !chunks.empty() && chunks.back().byte_length == 0; |
| 472 while (!out_of_data && end_pos <= position + 1) { | 477 { |
| 473 const uint8_t* chunk = nullptr; | 478 RuntimeCallTimerScope scope(stats, &RuntimeCallStats::GetMoreDataCallback); |
| 474 size_t len = source_->GetMoreData(&chunk); | 479 while (!out_of_data && end_pos <= position + 1) { |
| 480 const uint8_t* chunk = nullptr; |
| 481 size_t len = source->GetMoreData(&chunk); |
| 475 | 482 |
| 476 chunks.push_back({chunk, len, end_pos}); | 483 chunks.push_back({chunk, len, end_pos}); |
| 477 end_pos += len; | 484 end_pos += len; |
| 478 out_of_data = (len == 0); | 485 out_of_data = (len == 0); |
| 486 } |
| 479 } | 487 } |
| 480 | 488 |
| 481 // Here, we should always have at least one chunk, and we either have the | 489 // Here, we should always have at least one chunk, and we either have the |
| 482 // chunk we were looking for, or we're out of data. Also, out_of_data and | 490 // chunk we were looking for, or we're out of data. Also, out_of_data and |
| 483 // end_pos are current (and designate whether we have exhausted the stream, | 491 // end_pos are current (and designate whether we have exhausted the stream, |
| 484 // and the length of data received so far, respectively). | 492 // and the length of data received so far, respectively). |
| 485 DCHECK(!chunks.empty()); | 493 DCHECK(!chunks.empty()); |
| 486 DCHECK_EQ(end_pos, chunks.back().byte_pos + chunks.back().byte_length); | 494 DCHECK_EQ(end_pos, chunks.back().byte_pos + chunks.back().byte_length); |
| 487 DCHECK_EQ(out_of_data, chunks.back().byte_length == 0); | 495 DCHECK_EQ(out_of_data, chunks.back().byte_length == 0); |
| 488 DCHECK(position < end_pos || out_of_data); | 496 DCHECK(position < end_pos || out_of_data); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 509 } // anonymous namespace | 517 } // anonymous namespace |
| 510 | 518 |
| 511 // ---------------------------------------------------------------------------- | 519 // ---------------------------------------------------------------------------- |
| 512 // OneByteExternalStreamingStream | 520 // OneByteExternalStreamingStream |
| 513 // | 521 // |
| 514 // A stream of latin-1 encoded, chunked data. | 522 // A stream of latin-1 encoded, chunked data. |
| 515 | 523 |
| 516 class OneByteExternalStreamingStream : public BufferedUtf16CharacterStream { | 524 class OneByteExternalStreamingStream : public BufferedUtf16CharacterStream { |
| 517 public: | 525 public: |
| 518 explicit OneByteExternalStreamingStream( | 526 explicit OneByteExternalStreamingStream( |
| 519 ScriptCompiler::ExternalSourceStream* source) | 527 ScriptCompiler::ExternalSourceStream* source, RuntimeCallStats* stats) |
| 520 : source_(source) {} | 528 : source_(source), stats_(stats) {} |
| 521 ~OneByteExternalStreamingStream() override { DeleteChunks(chunks_); } | 529 ~OneByteExternalStreamingStream() override { DeleteChunks(chunks_); } |
| 522 | 530 |
| 523 protected: | 531 protected: |
| 524 size_t FillBuffer(size_t position) override; | 532 size_t FillBuffer(size_t position) override; |
| 525 | 533 |
| 526 private: | 534 private: |
| 527 Chunks chunks_; | 535 Chunks chunks_; |
| 528 ScriptCompiler::ExternalSourceStream* source_; | 536 ScriptCompiler::ExternalSourceStream* source_; |
| 537 RuntimeCallStats* stats_; |
| 529 }; | 538 }; |
| 530 | 539 |
| 531 size_t OneByteExternalStreamingStream::FillBuffer(size_t position) { | 540 size_t OneByteExternalStreamingStream::FillBuffer(size_t position) { |
| 532 const Chunk& chunk = chunks_[FindChunk(chunks_, source_, position)]; | 541 const Chunk& chunk = chunks_[FindChunk(chunks_, source_, position, stats_)]; |
| 533 if (chunk.byte_length == 0) return 0; | 542 if (chunk.byte_length == 0) return 0; |
| 534 | 543 |
| 535 size_t start_pos = position - chunk.byte_pos; | 544 size_t start_pos = position - chunk.byte_pos; |
| 536 size_t len = i::Min(kBufferSize, chunk.byte_length - start_pos); | 545 size_t len = i::Min(kBufferSize, chunk.byte_length - start_pos); |
| 537 i::CopyCharsUnsigned(buffer_, chunk.data + start_pos, len); | 546 i::CopyCharsUnsigned(buffer_, chunk.data + start_pos, len); |
| 538 return len; | 547 return len; |
| 539 } | 548 } |
| 540 | 549 |
| 541 #if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64) | 550 #if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64) |
| 542 // ---------------------------------------------------------------------------- | 551 // ---------------------------------------------------------------------------- |
| 543 // TwoByteExternalStreamingStream | 552 // TwoByteExternalStreamingStream |
| 544 // | 553 // |
| 545 // A stream of ucs-2 data, delivered in chunks. Chunks may be 'cut' into the | 554 // A stream of ucs-2 data, delivered in chunks. Chunks may be 'cut' into the |
| 546 // middle of characters (or even contain only one byte), which adds a bit | 555 // middle of characters (or even contain only one byte), which adds a bit |
| 547 // of complexity. This stream avoid all data copying, except for characters | 556 // of complexity. This stream avoid all data copying, except for characters |
| 548 // that cross chunk boundaries. | 557 // that cross chunk boundaries. |
| 549 | 558 |
| 550 class TwoByteExternalStreamingStream : public Utf16CharacterStream { | 559 class TwoByteExternalStreamingStream : public Utf16CharacterStream { |
| 551 public: | 560 public: |
| 552 explicit TwoByteExternalStreamingStream( | 561 explicit TwoByteExternalStreamingStream( |
| 553 ScriptCompiler::ExternalSourceStream* source); | 562 ScriptCompiler::ExternalSourceStream* source, RuntimeCallStats* stats); |
| 554 ~TwoByteExternalStreamingStream() override; | 563 ~TwoByteExternalStreamingStream() override; |
| 555 | 564 |
| 556 protected: | 565 protected: |
| 557 bool ReadBlock() override; | 566 bool ReadBlock() override; |
| 558 | 567 |
| 559 Chunks chunks_; | 568 Chunks chunks_; |
| 560 ScriptCompiler::ExternalSourceStream* source_; | 569 ScriptCompiler::ExternalSourceStream* source_; |
| 570 RuntimeCallStats* stats_; |
| 561 uc16 one_char_buffer_; | 571 uc16 one_char_buffer_; |
| 562 }; | 572 }; |
| 563 | 573 |
| 564 TwoByteExternalStreamingStream::TwoByteExternalStreamingStream( | 574 TwoByteExternalStreamingStream::TwoByteExternalStreamingStream( |
| 565 ScriptCompiler::ExternalSourceStream* source) | 575 ScriptCompiler::ExternalSourceStream* source, RuntimeCallStats* stats) |
| 566 : Utf16CharacterStream(&one_char_buffer_, &one_char_buffer_, | 576 : Utf16CharacterStream(&one_char_buffer_, &one_char_buffer_, |
| 567 &one_char_buffer_, 0), | 577 &one_char_buffer_, 0), |
| 568 source_(source), | 578 source_(source), |
| 579 stats_(stats), |
| 569 one_char_buffer_(0) {} | 580 one_char_buffer_(0) {} |
| 570 | 581 |
| 571 TwoByteExternalStreamingStream::~TwoByteExternalStreamingStream() { | 582 TwoByteExternalStreamingStream::~TwoByteExternalStreamingStream() { |
| 572 DeleteChunks(chunks_); | 583 DeleteChunks(chunks_); |
| 573 } | 584 } |
| 574 | 585 |
| 575 bool TwoByteExternalStreamingStream::ReadBlock() { | 586 bool TwoByteExternalStreamingStream::ReadBlock() { |
| 576 size_t position = pos(); | 587 size_t position = pos(); |
| 577 | 588 |
| 578 // We'll search for the 2nd byte of our character, to make sure we | 589 // We'll search for the 2nd byte of our character, to make sure we |
| 579 // have enough data for at least one character. | 590 // have enough data for at least one character. |
| 580 size_t chunk_no = FindChunk(chunks_, source_, 2 * position + 1); | 591 size_t chunk_no = FindChunk(chunks_, source_, 2 * position + 1, stats_); |
| 581 | 592 |
| 582 // Out of data? Return 0. | 593 // Out of data? Return 0. |
| 583 if (chunks_[chunk_no].byte_length == 0) { | 594 if (chunks_[chunk_no].byte_length == 0) { |
| 584 buffer_cursor_ = buffer_start_; | 595 buffer_cursor_ = buffer_start_; |
| 585 buffer_end_ = buffer_start_; | 596 buffer_end_ = buffer_start_; |
| 586 return false; | 597 return false; |
| 587 } | 598 } |
| 588 | 599 |
| 589 Chunk& current = chunks_[chunk_no]; | 600 Chunk& current = chunks_[chunk_no]; |
| 590 | 601 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 // TwoByteExternalBufferedStream | 649 // TwoByteExternalBufferedStream |
| 639 // | 650 // |
| 640 // This class is made specifically to address unaligned access to 16-bit data | 651 // This class is made specifically to address unaligned access to 16-bit data |
| 641 // in MIPS and ARM architectures. It replaces class | 652 // in MIPS and ARM architectures. It replaces class |
| 642 // TwoByteExternalStreamingStream which in some cases does have unaligned | 653 // TwoByteExternalStreamingStream which in some cases does have unaligned |
| 643 // accesse to 16-bit data | 654 // accesse to 16-bit data |
| 644 | 655 |
| 645 class TwoByteExternalBufferedStream : public Utf16CharacterStream { | 656 class TwoByteExternalBufferedStream : public Utf16CharacterStream { |
| 646 public: | 657 public: |
| 647 explicit TwoByteExternalBufferedStream( | 658 explicit TwoByteExternalBufferedStream( |
| 648 ScriptCompiler::ExternalSourceStream* source); | 659 ScriptCompiler::ExternalSourceStream* source, RuntimeCallStats* stats); |
| 649 ~TwoByteExternalBufferedStream(); | 660 ~TwoByteExternalBufferedStream(); |
| 650 | 661 |
| 651 protected: | 662 protected: |
| 652 static const size_t kBufferSize = 512; | 663 static const size_t kBufferSize = 512; |
| 653 | 664 |
| 654 bool ReadBlock() override; | 665 bool ReadBlock() override; |
| 655 | 666 |
| 656 // FillBuffer should read up to kBufferSize characters at position and store | 667 // FillBuffer should read up to kBufferSize characters at position and store |
| 657 // them into buffer_[0..]. It returns the number of characters stored. | 668 // them into buffer_[0..]. It returns the number of characters stored. |
| 658 size_t FillBuffer(size_t position, size_t chunk_no); | 669 size_t FillBuffer(size_t position, size_t chunk_no); |
| 659 | 670 |
| 660 // Fixed sized buffer that this class reads from. | 671 // Fixed sized buffer that this class reads from. |
| 661 // The base class' buffer_start_ should always point to buffer_. | 672 // The base class' buffer_start_ should always point to buffer_. |
| 662 uc16 buffer_[kBufferSize]; | 673 uc16 buffer_[kBufferSize]; |
| 663 | 674 |
| 664 Chunks chunks_; | 675 Chunks chunks_; |
| 665 ScriptCompiler::ExternalSourceStream* source_; | 676 ScriptCompiler::ExternalSourceStream* source_; |
| 677 RuntimeCallStats* stats_; |
| 666 }; | 678 }; |
| 667 | 679 |
| 668 TwoByteExternalBufferedStream::TwoByteExternalBufferedStream( | 680 TwoByteExternalBufferedStream::TwoByteExternalBufferedStream( |
| 669 ScriptCompiler::ExternalSourceStream* source) | 681 ScriptCompiler::ExternalSourceStream* source, RuntimeCallStats* stats) |
| 670 : Utf16CharacterStream(buffer_, buffer_, buffer_, 0), source_(source) {} | 682 : Utf16CharacterStream(buffer_, buffer_, buffer_, 0), |
| 683 source_(source), |
| 684 stats_(stats) {} |
| 671 | 685 |
| 672 TwoByteExternalBufferedStream::~TwoByteExternalBufferedStream() { | 686 TwoByteExternalBufferedStream::~TwoByteExternalBufferedStream() { |
| 673 DeleteChunks(chunks_); | 687 DeleteChunks(chunks_); |
| 674 } | 688 } |
| 675 | 689 |
| 676 bool TwoByteExternalBufferedStream::ReadBlock() { | 690 bool TwoByteExternalBufferedStream::ReadBlock() { |
| 677 size_t position = pos(); | 691 size_t position = pos(); |
| 678 // Find chunk in which the position belongs | 692 // Find chunk in which the position belongs |
| 679 size_t chunk_no = FindChunk(chunks_, source_, 2 * position + 1); | 693 size_t chunk_no = FindChunk(chunks_, source_, 2 * position + 1, stats_); |
| 680 | 694 |
| 681 // Out of data? Return 0. | 695 // Out of data? Return 0. |
| 682 if (chunks_[chunk_no].byte_length == 0) { | 696 if (chunks_[chunk_no].byte_length == 0) { |
| 683 buffer_cursor_ = buffer_start_; | 697 buffer_cursor_ = buffer_start_; |
| 684 buffer_end_ = buffer_start_; | 698 buffer_end_ = buffer_start_; |
| 685 return false; | 699 return false; |
| 686 } | 700 } |
| 687 | 701 |
| 688 Chunk& current = chunks_[chunk_no]; | 702 Chunk& current = chunks_[chunk_no]; |
| 689 | 703 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 715 } | 729 } |
| 716 | 730 |
| 717 size_t TwoByteExternalBufferedStream::FillBuffer(size_t position, | 731 size_t TwoByteExternalBufferedStream::FillBuffer(size_t position, |
| 718 size_t chunk_no) { | 732 size_t chunk_no) { |
| 719 DCHECK_EQ(chunks_[chunk_no].byte_pos % 2, 1u); | 733 DCHECK_EQ(chunks_[chunk_no].byte_pos % 2, 1u); |
| 720 bool odd_start = true; | 734 bool odd_start = true; |
| 721 // Align buffer_pos_ to the size of the buffer. | 735 // Align buffer_pos_ to the size of the buffer. |
| 722 { | 736 { |
| 723 size_t new_pos = position / kBufferSize * kBufferSize; | 737 size_t new_pos = position / kBufferSize * kBufferSize; |
| 724 if (new_pos != position) { | 738 if (new_pos != position) { |
| 725 chunk_no = FindChunk(chunks_, source_, 2 * new_pos + 1); | 739 chunk_no = FindChunk(chunks_, source_, 2 * new_pos + 1, stats_); |
| 726 buffer_pos_ = new_pos; | 740 buffer_pos_ = new_pos; |
| 727 buffer_cursor_ = buffer_start_ + (position - buffer_pos_); | 741 buffer_cursor_ = buffer_start_ + (position - buffer_pos_); |
| 728 position = new_pos; | 742 position = new_pos; |
| 729 odd_start = chunks_[chunk_no].byte_pos % 2; | 743 odd_start = chunks_[chunk_no].byte_pos % 2; |
| 730 } | 744 } |
| 731 } | 745 } |
| 732 | 746 |
| 733 Chunk* current = &chunks_[chunk_no]; | 747 Chunk* current = &chunks_[chunk_no]; |
| 734 | 748 |
| 735 // Annoying edge case: Chunks may not be 2-byte aligned, meaning that a | 749 // Annoying edge case: Chunks may not be 2-byte aligned, meaning that a |
| (...skipping 21 matching lines...) Expand all Loading... |
| 757 size_t bytes_to_move = | 771 size_t bytes_to_move = |
| 758 i::Min(2 * kBufferSize - lonely_byte, | 772 i::Min(2 * kBufferSize - lonely_byte, |
| 759 current->byte_length - 2 * chunk_pos + start_offset); | 773 current->byte_length - 2 * chunk_pos + start_offset); |
| 760 i::MemMove(reinterpret_cast<uint8_t*>(buffer_) + lonely_byte, | 774 i::MemMove(reinterpret_cast<uint8_t*>(buffer_) + lonely_byte, |
| 761 current->data + 2 * chunk_pos - start_offset, bytes_to_move); | 775 current->data + 2 * chunk_pos - start_offset, bytes_to_move); |
| 762 | 776 |
| 763 // Fill up the rest of the buffer if there is space and data left. | 777 // Fill up the rest of the buffer if there is space and data left. |
| 764 totalLength += bytes_to_move; | 778 totalLength += bytes_to_move; |
| 765 position = (current->byte_pos + current->byte_length) / 2; | 779 position = (current->byte_pos + current->byte_length) / 2; |
| 766 if (position - buffer_pos_ < kBufferSize) { | 780 if (position - buffer_pos_ < kBufferSize) { |
| 767 chunk_no = FindChunk(chunks_, source_, 2 * position + 1); | 781 chunk_no = FindChunk(chunks_, source_, 2 * position + 1, stats_); |
| 768 current = &chunks_[chunk_no]; | 782 current = &chunks_[chunk_no]; |
| 769 odd_start = current->byte_pos % 2; | 783 odd_start = current->byte_pos % 2; |
| 770 bytes_to_move = i::Min(2 * kBufferSize - totalLength, current->byte_length); | 784 bytes_to_move = i::Min(2 * kBufferSize - totalLength, current->byte_length); |
| 771 while (bytes_to_move) { | 785 while (bytes_to_move) { |
| 772 // Common case: character is in current chunk. | 786 // Common case: character is in current chunk. |
| 773 DCHECK_LE(current->byte_pos, 2 * position + odd_start); | 787 DCHECK_LE(current->byte_pos, 2 * position + odd_start); |
| 774 DCHECK_LT(2 * position + 1, current->byte_pos + current->byte_length); | 788 DCHECK_LT(2 * position + 1, current->byte_pos + current->byte_length); |
| 775 | 789 |
| 776 i::MemMove(reinterpret_cast<uint8_t*>(buffer_) + totalLength, | 790 i::MemMove(reinterpret_cast<uint8_t*>(buffer_) + totalLength, |
| 777 current->data, bytes_to_move); | 791 current->data, bytes_to_move); |
| 778 totalLength += bytes_to_move; | 792 totalLength += bytes_to_move; |
| 779 position = (current->byte_pos + current->byte_length) / 2; | 793 position = (current->byte_pos + current->byte_length) / 2; |
| 780 chunk_no = FindChunk(chunks_, source_, 2 * position + 1); | 794 chunk_no = FindChunk(chunks_, source_, 2 * position + 1, stats_); |
| 781 current = &chunks_[chunk_no]; | 795 current = &chunks_[chunk_no]; |
| 782 odd_start = current->byte_pos % 2; | 796 odd_start = current->byte_pos % 2; |
| 783 bytes_to_move = | 797 bytes_to_move = |
| 784 i::Min(2 * kBufferSize - totalLength, current->byte_length); | 798 i::Min(2 * kBufferSize - totalLength, current->byte_length); |
| 785 } | 799 } |
| 786 } | 800 } |
| 787 return totalLength / 2; | 801 return totalLength / 2; |
| 788 } | 802 } |
| 789 #endif | 803 #endif |
| 790 | 804 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 817 } | 831 } |
| 818 | 832 |
| 819 std::unique_ptr<Utf16CharacterStream> ScannerStream::ForTesting( | 833 std::unique_ptr<Utf16CharacterStream> ScannerStream::ForTesting( |
| 820 const char* data, size_t length) { | 834 const char* data, size_t length) { |
| 821 return std::unique_ptr<Utf16CharacterStream>( | 835 return std::unique_ptr<Utf16CharacterStream>( |
| 822 new ExternalOneByteStringUtf16CharacterStream(data, length)); | 836 new ExternalOneByteStringUtf16CharacterStream(data, length)); |
| 823 } | 837 } |
| 824 | 838 |
| 825 Utf16CharacterStream* ScannerStream::For( | 839 Utf16CharacterStream* ScannerStream::For( |
| 826 ScriptCompiler::ExternalSourceStream* source_stream, | 840 ScriptCompiler::ExternalSourceStream* source_stream, |
| 827 v8::ScriptCompiler::StreamedSource::Encoding encoding) { | 841 v8::ScriptCompiler::StreamedSource::Encoding encoding, |
| 842 RuntimeCallStats* stats) { |
| 828 switch (encoding) { | 843 switch (encoding) { |
| 829 case v8::ScriptCompiler::StreamedSource::TWO_BYTE: | 844 case v8::ScriptCompiler::StreamedSource::TWO_BYTE: |
| 830 #if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64) | 845 #if !(V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64) |
| 831 return new TwoByteExternalStreamingStream(source_stream); | 846 return new TwoByteExternalStreamingStream(source_stream, stats); |
| 832 #else | 847 #else |
| 833 return new TwoByteExternalBufferedStream(source_stream); | 848 return new TwoByteExternalBufferedStream(source_stream, stats); |
| 834 #endif | 849 #endif |
| 835 case v8::ScriptCompiler::StreamedSource::ONE_BYTE: | 850 case v8::ScriptCompiler::StreamedSource::ONE_BYTE: |
| 836 return new OneByteExternalStreamingStream(source_stream); | 851 return new OneByteExternalStreamingStream(source_stream, stats); |
| 837 case v8::ScriptCompiler::StreamedSource::UTF8: | 852 case v8::ScriptCompiler::StreamedSource::UTF8: |
| 838 return new Utf8ExternalStreamingStream(source_stream); | 853 return new Utf8ExternalStreamingStream(source_stream, stats); |
| 839 } | 854 } |
| 840 UNREACHABLE(); | 855 UNREACHABLE(); |
| 841 return nullptr; | 856 return nullptr; |
| 842 } | 857 } |
| 843 | 858 |
| 844 } // namespace internal | 859 } // namespace internal |
| 845 } // namespace v8 | 860 } // namespace v8 |
| OLD | NEW |