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 |