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 |