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