OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2510 const int kUnderlyingOffset = SlicedString::kParentOffset; | 2510 const int kUnderlyingOffset = SlicedString::kParentOffset; |
2511 return String::cast(READ_FIELD(this, kUnderlyingOffset)); | 2511 return String::cast(READ_FIELD(this, kUnderlyingOffset)); |
2512 } | 2512 } |
2513 | 2513 |
2514 | 2514 |
2515 template<class Visitor, class ConsOp> | 2515 template<class Visitor, class ConsOp> |
2516 void String::Visit( | 2516 void String::Visit( |
2517 String* string, | 2517 String* string, |
2518 unsigned offset, | 2518 unsigned offset, |
2519 Visitor& visitor, | 2519 Visitor& visitor, |
2520 ConsOp& consOp, | 2520 ConsOp& cons_op, |
2521 int32_t type, | 2521 int32_t type, |
2522 unsigned length) { | 2522 unsigned length) { |
2523 | |
2524 ASSERT(length == static_cast<unsigned>(string->length())); | 2523 ASSERT(length == static_cast<unsigned>(string->length())); |
2525 ASSERT(offset <= length); | 2524 ASSERT(offset <= length); |
2526 | 2525 unsigned slice_offset = offset; |
2527 unsigned sliceOffset = offset; | |
2528 while (true) { | 2526 while (true) { |
2529 ASSERT(type == string->map()->instance_type()); | 2527 ASSERT(type == string->map()->instance_type()); |
2530 | 2528 |
2531 switch (type & (kStringRepresentationMask | kStringEncodingMask)) { | 2529 switch (type & (kStringRepresentationMask | kStringEncodingMask)) { |
2532 case kSeqStringTag | kOneByteStringTag: | 2530 case kSeqStringTag | kOneByteStringTag: |
2533 visitor.VisitOneByteString( | 2531 visitor.VisitOneByteString( |
2534 reinterpret_cast<const uint8_t*>( | 2532 reinterpret_cast<const uint8_t*>( |
2535 SeqOneByteString::cast(string)->GetChars()) + sliceOffset, | 2533 SeqOneByteString::cast(string)->GetChars()) + slice_offset, |
2536 length - offset); | 2534 length - offset); |
2537 return; | 2535 return; |
2538 | 2536 |
2539 case kSeqStringTag | kTwoByteStringTag: | 2537 case kSeqStringTag | kTwoByteStringTag: |
2540 visitor.VisitTwoByteString( | 2538 visitor.VisitTwoByteString( |
2541 reinterpret_cast<const uint16_t*>( | 2539 reinterpret_cast<const uint16_t*>( |
2542 SeqTwoByteString::cast(string)->GetChars()) + sliceOffset, | 2540 SeqTwoByteString::cast(string)->GetChars()) + slice_offset, |
2543 length - offset); | 2541 length - offset); |
2544 return; | 2542 return; |
2545 | 2543 |
2546 case kExternalStringTag | kOneByteStringTag: | 2544 case kExternalStringTag | kOneByteStringTag: |
2547 visitor.VisitOneByteString( | 2545 visitor.VisitOneByteString( |
2548 reinterpret_cast<const uint8_t*>( | 2546 reinterpret_cast<const uint8_t*>( |
2549 ExternalAsciiString::cast(string)->GetChars()) + sliceOffset, | 2547 ExternalAsciiString::cast(string)->GetChars()) + slice_offset, |
2550 length - offset); | 2548 length - offset); |
2551 return; | 2549 return; |
2552 | 2550 |
2553 case kExternalStringTag | kTwoByteStringTag: | 2551 case kExternalStringTag | kTwoByteStringTag: |
2554 visitor.VisitTwoByteString( | 2552 visitor.VisitTwoByteString( |
2555 reinterpret_cast<const uint16_t*>( | 2553 reinterpret_cast<const uint16_t*>( |
2556 ExternalTwoByteString::cast(string)->GetChars()) + sliceOffset, | 2554 ExternalTwoByteString::cast(string)->GetChars()) |
| 2555 + slice_offset, |
2557 length - offset); | 2556 length - offset); |
2558 return; | 2557 return; |
2559 | 2558 |
2560 case kSlicedStringTag | kOneByteStringTag: | 2559 case kSlicedStringTag | kOneByteStringTag: |
2561 case kSlicedStringTag | kTwoByteStringTag: { | 2560 case kSlicedStringTag | kTwoByteStringTag: { |
2562 SlicedString* slicedString = SlicedString::cast(string); | 2561 SlicedString* slicedString = SlicedString::cast(string); |
2563 sliceOffset += slicedString->offset(); | 2562 slice_offset += slicedString->offset(); |
2564 string = slicedString->parent(); | 2563 string = slicedString->parent(); |
2565 type = string->map()->instance_type(); | 2564 type = string->map()->instance_type(); |
2566 continue; | 2565 continue; |
2567 } | 2566 } |
2568 | 2567 |
2569 case kConsStringTag | kOneByteStringTag: | 2568 case kConsStringTag | kOneByteStringTag: |
2570 case kConsStringTag | kTwoByteStringTag: | 2569 case kConsStringTag | kTwoByteStringTag: |
2571 string = consOp.Operate(ConsString::cast(string), &offset, &type, | 2570 string = cons_op.Operate(ConsString::cast(string), &offset, &type, |
2572 &length); | 2571 &length); |
2573 if (string == NULL) return; | 2572 if (string == NULL) return; |
2574 sliceOffset = offset; | 2573 slice_offset = offset; |
2575 ASSERT(length == static_cast<unsigned>(string->length())); | 2574 ASSERT(length == static_cast<unsigned>(string->length())); |
2576 continue; | 2575 continue; |
2577 | 2576 |
2578 default: | 2577 default: |
2579 UNREACHABLE(); | 2578 UNREACHABLE(); |
2580 return; | 2579 return; |
2581 } | 2580 } |
2582 } | 2581 } |
2583 } | 2582 } |
2584 | 2583 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2759 unsigned start) { | 2758 unsigned start) { |
2760 return GetChars() + start; | 2759 return GetChars() + start; |
2761 } | 2760 } |
2762 | 2761 |
2763 | 2762 |
2764 unsigned ConsStringIteratorOp::OffsetForDepth(unsigned depth) { | 2763 unsigned ConsStringIteratorOp::OffsetForDepth(unsigned depth) { |
2765 return depth & kDepthMask; | 2764 return depth & kDepthMask; |
2766 } | 2765 } |
2767 | 2766 |
2768 | 2767 |
2769 uint32_t ConsStringIteratorOp::MaskForDepth(unsigned depth) { | |
2770 return 1 << OffsetForDepth(depth); | |
2771 } | |
2772 | |
2773 | |
2774 void ConsStringIteratorOp::SetRightDescent() { | |
2775 trace_ |= MaskForDepth(depth_ - 1); | |
2776 } | |
2777 | |
2778 | |
2779 void ConsStringIteratorOp::ClearRightDescent() { | |
2780 trace_ &= ~MaskForDepth(depth_ - 1); | |
2781 } | |
2782 | |
2783 | |
2784 void ConsStringIteratorOp::PushLeft(ConsString* string) { | 2768 void ConsStringIteratorOp::PushLeft(ConsString* string) { |
2785 frames_[depth_++ & kDepthMask] = string; | 2769 frames_[depth_++ & kDepthMask] = string; |
2786 } | 2770 } |
2787 | 2771 |
2788 | 2772 |
2789 void ConsStringIteratorOp::PushRight(ConsString* string, int32_t type) { | 2773 void ConsStringIteratorOp::PushRight(ConsString* string) { |
2790 // Inplace update | 2774 // Inplace update. |
2791 frames_[(depth_-1) & kDepthMask] = string; | 2775 frames_[(depth_-1) & kDepthMask] = string; |
2792 if (depth_ != 1) return; | |
2793 // Optimization: can replace root in this case. | |
2794 root_ = string; | |
2795 root_type_ = type; | |
2796 root_length_ = string->length(); | |
2797 } | 2776 } |
2798 | 2777 |
2799 | 2778 |
2800 void ConsStringIteratorOp::AdjustMaximumDepth() { | 2779 void ConsStringIteratorOp::AdjustMaximumDepth() { |
2801 if (depth_ > maximum_depth_) maximum_depth_ = depth_; | 2780 if (depth_ > maximum_depth_) maximum_depth_ = depth_; |
2802 } | 2781 } |
2803 | 2782 |
2804 | 2783 |
2805 void ConsStringIteratorOp::Pop() { | 2784 void ConsStringIteratorOp::Pop() { |
2806 ASSERT(depth_ > 0); | 2785 ASSERT(depth_ > 0); |
2807 ASSERT(depth_ <= maximum_depth_); | 2786 ASSERT(depth_ <= maximum_depth_); |
2808 depth_--; | 2787 depth_--; |
2809 } | 2788 } |
2810 | 2789 |
2811 | 2790 |
2812 void ConsStringIteratorOp::Reset() { | 2791 void ConsStringIteratorOp::Reset() { |
2813 consumed_ = 0; | 2792 depth_ = 0; |
2814 ResetStack(); | 2793 maximum_depth_ = 0; |
2815 } | 2794 } |
2816 | 2795 |
2817 | 2796 |
2818 bool ConsStringIteratorOp::HasMore() { | 2797 bool ConsStringIteratorOp::HasMore() { |
2819 return depth_ != 0; | 2798 return depth_ != 0; |
2820 } | 2799 } |
2821 | 2800 |
2822 | 2801 |
2823 void ConsStringIteratorOp::ResetStack() { | |
2824 depth_ = 0; | |
2825 maximum_depth_ = 0; | |
2826 } | |
2827 | |
2828 | |
2829 bool ConsStringIteratorOp::ContinueOperation(ContinueResponse* response) { | 2802 bool ConsStringIteratorOp::ContinueOperation(ContinueResponse* response) { |
2830 bool blewStack; | 2803 bool blew_stack; |
2831 int32_t type; | 2804 int32_t type; |
2832 String* string = NextLeaf(&blewStack, &type); | 2805 unsigned length; |
| 2806 String* string = NextLeaf(&blew_stack, &type, &length); |
2833 // String found. | 2807 // String found. |
2834 if (string != NULL) { | 2808 if (string != NULL) { |
2835 unsigned length = string->length(); | |
2836 consumed_ += length; | 2809 consumed_ += length; |
2837 response->string_ = string; | 2810 response->string_ = string; |
2838 response->offset_ = 0; | 2811 response->offset_ = 0; |
2839 response->length_ = length; | 2812 response->length_ = length; |
2840 response->type_ = type; | 2813 response->type_ = type; |
2841 return true; | 2814 return true; |
2842 } | 2815 } |
2843 // Traversal complete. | 2816 // Traversal complete. |
2844 if (!blewStack) return false; | 2817 if (!blew_stack) return false; |
2845 // Restart search. | 2818 // Restart search. |
2846 ResetStack(); | 2819 Reset(); |
| 2820 // TODO(dcarney) This is unnecessary. |
| 2821 // After a reset, we don't need a String::Visit |
2847 response->string_ = root_; | 2822 response->string_ = root_; |
2848 response->offset_ = consumed_; | 2823 response->offset_ = consumed_; |
2849 response->length_ = root_length_; | 2824 response->length_ = root_length_; |
2850 response->type_ = root_type_; | 2825 response->type_ = root_type_; |
2851 return true; | 2826 return true; |
2852 } | 2827 } |
2853 | 2828 |
2854 | 2829 |
2855 uint16_t StringCharacterStream::GetNext() { | 2830 uint16_t StringCharacterStream::GetNext() { |
2856 ASSERT(buffer8_ != NULL); | 2831 ASSERT((buffer8_ == NULL && end_ == NULL) || buffer8_ < end_); |
2857 return is_one_byte_ ? *buffer8_++ : *buffer16_++; | 2832 return is_one_byte_ ? *buffer8_++ : *buffer16_++; |
2858 } | 2833 } |
2859 | 2834 |
2860 | 2835 |
2861 StringCharacterStream::StringCharacterStream( | 2836 StringCharacterStream::StringCharacterStream( |
2862 String* string, unsigned offset, ConsStringIteratorOp* op) | 2837 String* string, unsigned offset, ConsStringIteratorOp* op) |
2863 : is_one_byte_(true), | 2838 : is_one_byte_(false), |
2864 buffer8_(NULL), | 2839 buffer8_(NULL), |
2865 end_(NULL), | 2840 end_(NULL), |
2866 op_(op) { | 2841 op_(op) { |
2867 op->Reset(); | 2842 op->Reset(); |
2868 String::Visit(string, | 2843 String::Visit(string, |
2869 offset, *this, *op, string->map()->instance_type(), string->length()); | 2844 offset, *this, *op, string->map()->instance_type(), string->length()); |
2870 } | 2845 } |
2871 | 2846 |
2872 | 2847 |
2873 bool StringCharacterStream::HasMore() { | 2848 bool StringCharacterStream::HasMore() { |
2874 if (buffer8_ != end_) return true; | 2849 if (buffer8_ != end_) return true; |
2875 if (!op_->HasMore()) return false; | 2850 if (!op_->HasMore()) return false; |
2876 ConsStringIteratorOp::ContinueResponse response; | 2851 ConsStringIteratorOp::ContinueResponse response; |
2877 // This has been checked above | 2852 if (!op_->ContinueOperation(&response)) return false; |
2878 if (!op_->ContinueOperation(&response)) { | |
2879 UNREACHABLE(); | |
2880 return false; | |
2881 } | |
2882 String::Visit(response.string_, | 2853 String::Visit(response.string_, |
2883 response.offset_, *this, *op_, response.type_, response.length_); | 2854 response.offset_, *this, *op_, response.type_, response.length_); |
2884 return true; | 2855 return true; |
2885 } | 2856 } |
2886 | 2857 |
2887 | 2858 |
2888 void StringCharacterStream::VisitOneByteString( | 2859 void StringCharacterStream::VisitOneByteString( |
2889 const uint8_t* chars, unsigned length) { | 2860 const uint8_t* chars, unsigned length) { |
2890 is_one_byte_ = true; | 2861 is_one_byte_ = true; |
2891 buffer8_ = chars; | 2862 buffer8_ = chars; |
(...skipping 2874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5766 #undef WRITE_UINT32_FIELD | 5737 #undef WRITE_UINT32_FIELD |
5767 #undef READ_SHORT_FIELD | 5738 #undef READ_SHORT_FIELD |
5768 #undef WRITE_SHORT_FIELD | 5739 #undef WRITE_SHORT_FIELD |
5769 #undef READ_BYTE_FIELD | 5740 #undef READ_BYTE_FIELD |
5770 #undef WRITE_BYTE_FIELD | 5741 #undef WRITE_BYTE_FIELD |
5771 | 5742 |
5772 | 5743 |
5773 } } // namespace v8::internal | 5744 } } // namespace v8::internal |
5774 | 5745 |
5775 #endif // V8_OBJECTS_INL_H_ | 5746 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |