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 2494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2505 // Giving direct access to underlying string only makes sense if the | 2505 // Giving direct access to underlying string only makes sense if the |
2506 // wrapping string is already flattened. | 2506 // wrapping string is already flattened. |
2507 ASSERT(this->IsFlat()); | 2507 ASSERT(this->IsFlat()); |
2508 ASSERT(StringShape(this).IsIndirect()); | 2508 ASSERT(StringShape(this).IsIndirect()); |
2509 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset); | 2509 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset); |
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> |
| 2516 void String::Visit( |
| 2517 String* string, |
| 2518 unsigned offset, |
| 2519 Visitor& visitor, |
| 2520 ConsOp& consOp, |
| 2521 int32_t type, |
| 2522 unsigned length) { |
| 2523 |
| 2524 ASSERT(length == static_cast<unsigned>(string->length())); |
| 2525 ASSERT(offset <= length); |
| 2526 |
| 2527 unsigned sliceOffset = offset; |
| 2528 while (true) { |
| 2529 ASSERT(type == string->map()->instance_type()); |
| 2530 |
| 2531 switch (type & (kStringRepresentationMask | kStringEncodingMask)) { |
| 2532 case kSeqStringTag | kOneByteStringTag: |
| 2533 visitor.VisitOneByteString( |
| 2534 reinterpret_cast<const uint8_t*>( |
| 2535 SeqOneByteString::cast(string)->GetChars()) + sliceOffset, |
| 2536 length - offset); |
| 2537 return; |
| 2538 |
| 2539 case kSeqStringTag | kTwoByteStringTag: |
| 2540 visitor.VisitTwoByteString( |
| 2541 reinterpret_cast<const uint16_t*>( |
| 2542 SeqTwoByteString::cast(string)->GetChars()) + sliceOffset, |
| 2543 length - offset); |
| 2544 return; |
| 2545 |
| 2546 case kExternalStringTag | kOneByteStringTag: |
| 2547 visitor.VisitOneByteString( |
| 2548 reinterpret_cast<const uint8_t*>( |
| 2549 ExternalAsciiString::cast(string)->GetChars()) + sliceOffset, |
| 2550 length - offset); |
| 2551 return; |
| 2552 |
| 2553 case kExternalStringTag | kTwoByteStringTag: |
| 2554 visitor.VisitTwoByteString( |
| 2555 reinterpret_cast<const uint16_t*>( |
| 2556 ExternalTwoByteString::cast(string)->GetChars()) + sliceOffset, |
| 2557 length - offset); |
| 2558 return; |
| 2559 |
| 2560 case kSlicedStringTag | kOneByteStringTag: |
| 2561 case kSlicedStringTag | kTwoByteStringTag: { |
| 2562 SlicedString* slicedString = SlicedString::cast(string); |
| 2563 sliceOffset += slicedString->offset(); |
| 2564 string = slicedString->parent(); |
| 2565 type = string->map()->instance_type(); |
| 2566 continue; |
| 2567 } |
| 2568 |
| 2569 case kConsStringTag | kOneByteStringTag: |
| 2570 case kConsStringTag | kTwoByteStringTag: |
| 2571 string = consOp.Operate(ConsString::cast(string), &offset, &type, |
| 2572 &length); |
| 2573 if (string == NULL) return; |
| 2574 sliceOffset = offset; |
| 2575 ASSERT(length == static_cast<unsigned>(string->length())); |
| 2576 continue; |
| 2577 |
| 2578 default: |
| 2579 UNREACHABLE(); |
| 2580 return; |
| 2581 } |
| 2582 } |
| 2583 } |
| 2584 |
| 2585 |
2515 uint16_t SeqOneByteString::SeqOneByteStringGet(int index) { | 2586 uint16_t SeqOneByteString::SeqOneByteStringGet(int index) { |
2516 ASSERT(index >= 0 && index < length()); | 2587 ASSERT(index >= 0 && index < length()); |
2517 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); | 2588 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); |
2518 } | 2589 } |
2519 | 2590 |
2520 | 2591 |
2521 void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) { | 2592 void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) { |
2522 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode); | 2593 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode); |
2523 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, | 2594 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, |
2524 static_cast<byte>(value)); | 2595 static_cast<byte>(value)); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2683 return GetChars()[index]; | 2754 return GetChars()[index]; |
2684 } | 2755 } |
2685 | 2756 |
2686 | 2757 |
2687 const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData( | 2758 const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData( |
2688 unsigned start) { | 2759 unsigned start) { |
2689 return GetChars() + start; | 2760 return GetChars() + start; |
2690 } | 2761 } |
2691 | 2762 |
2692 | 2763 |
| 2764 unsigned ConsStringIteratorOp::OffsetForDepth(unsigned depth) { |
| 2765 return depth & kDepthMask; |
| 2766 } |
| 2767 |
| 2768 |
| 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) { |
| 2785 frames_[depth_++ & kDepthMask] = string; |
| 2786 } |
| 2787 |
| 2788 |
| 2789 void ConsStringIteratorOp::PushRight(ConsString* string, int32_t type) { |
| 2790 // Inplace update |
| 2791 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 } |
| 2798 |
| 2799 |
| 2800 void ConsStringIteratorOp::AdjustMaximumDepth() { |
| 2801 if (depth_ > maximum_depth_) maximum_depth_ = depth_; |
| 2802 } |
| 2803 |
| 2804 |
| 2805 void ConsStringIteratorOp::Pop() { |
| 2806 ASSERT(depth_ > 0); |
| 2807 ASSERT(depth_ <= maximum_depth_); |
| 2808 depth_--; |
| 2809 } |
| 2810 |
| 2811 |
| 2812 void ConsStringIteratorOp::Reset() { |
| 2813 consumed_ = 0; |
| 2814 ResetStack(); |
| 2815 } |
| 2816 |
| 2817 |
| 2818 bool ConsStringIteratorOp::HasMore() { |
| 2819 return depth_ != 0; |
| 2820 } |
| 2821 |
| 2822 |
| 2823 void ConsStringIteratorOp::ResetStack() { |
| 2824 depth_ = 0; |
| 2825 maximum_depth_ = 0; |
| 2826 } |
| 2827 |
| 2828 |
| 2829 bool ConsStringIteratorOp::ContinueOperation(ContinueResponse* response) { |
| 2830 bool blewStack; |
| 2831 int32_t type; |
| 2832 String* string = NextLeaf(&blewStack, &type); |
| 2833 // String found. |
| 2834 if (string != NULL) { |
| 2835 unsigned length = string->length(); |
| 2836 consumed_ += length; |
| 2837 response->string_ = string; |
| 2838 response->offset_ = 0; |
| 2839 response->length_ = length; |
| 2840 response->type_ = type; |
| 2841 return true; |
| 2842 } |
| 2843 // Traversal complete. |
| 2844 if (!blewStack) return false; |
| 2845 // Restart search. |
| 2846 ResetStack(); |
| 2847 response->string_ = root_; |
| 2848 response->offset_ = consumed_; |
| 2849 response->length_ = root_length_; |
| 2850 response->type_ = root_type_; |
| 2851 return true; |
| 2852 } |
| 2853 |
| 2854 |
| 2855 uint16_t StringCharacterStream::GetNext() { |
| 2856 return is_one_byte_ ? *buffer8_++ : *buffer16_++; |
| 2857 } |
| 2858 |
| 2859 |
| 2860 StringCharacterStream::StringCharacterStream( |
| 2861 String* string, unsigned offset, ConsStringIteratorOp* op) |
| 2862 : buffer8_(NULL), |
| 2863 end_(NULL), |
| 2864 op_(op) { |
| 2865 op->Reset(); |
| 2866 String::Visit(string, |
| 2867 offset, *this, *op, string->map()->instance_type(), string->length()); |
| 2868 } |
| 2869 |
| 2870 |
| 2871 bool StringCharacterStream::HasMore() { |
| 2872 if (buffer8_ != end_) return true; |
| 2873 if (!op_->HasMore()) return false; |
| 2874 ConsStringIteratorOp::ContinueResponse response; |
| 2875 // This has been checked above |
| 2876 if (!op_->ContinueOperation(&response)) { |
| 2877 UNREACHABLE(); |
| 2878 return false; |
| 2879 } |
| 2880 String::Visit(response.string_, |
| 2881 response.offset_, *this, *op_, response.type_, response.length_); |
| 2882 return true; |
| 2883 } |
| 2884 |
| 2885 |
| 2886 void StringCharacterStream::VisitOneByteString( |
| 2887 const uint8_t* chars, unsigned length) { |
| 2888 is_one_byte_ = true; |
| 2889 buffer8_ = chars; |
| 2890 end_ = chars + length; |
| 2891 } |
| 2892 |
| 2893 |
| 2894 void StringCharacterStream::VisitTwoByteString( |
| 2895 const uint16_t* chars, unsigned length) { |
| 2896 is_one_byte_ = false; |
| 2897 buffer16_ = chars; |
| 2898 end_ = reinterpret_cast<const uint8_t*>(chars + length); |
| 2899 } |
| 2900 |
| 2901 |
2693 void JSFunctionResultCache::MakeZeroSize() { | 2902 void JSFunctionResultCache::MakeZeroSize() { |
2694 set_finger_index(kEntriesIndex); | 2903 set_finger_index(kEntriesIndex); |
2695 set_size(kEntriesIndex); | 2904 set_size(kEntriesIndex); |
2696 } | 2905 } |
2697 | 2906 |
2698 | 2907 |
2699 void JSFunctionResultCache::Clear() { | 2908 void JSFunctionResultCache::Clear() { |
2700 int cache_size = size(); | 2909 int cache_size = size(); |
2701 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex)); | 2910 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex)); |
2702 MemsetPointer(entries_start, | 2911 MemsetPointer(entries_start, |
(...skipping 2843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5546 #undef WRITE_UINT32_FIELD | 5755 #undef WRITE_UINT32_FIELD |
5547 #undef READ_SHORT_FIELD | 5756 #undef READ_SHORT_FIELD |
5548 #undef WRITE_SHORT_FIELD | 5757 #undef WRITE_SHORT_FIELD |
5549 #undef READ_BYTE_FIELD | 5758 #undef READ_BYTE_FIELD |
5550 #undef WRITE_BYTE_FIELD | 5759 #undef WRITE_BYTE_FIELD |
5551 | 5760 |
5552 | 5761 |
5553 } } // namespace v8::internal | 5762 } } // namespace v8::internal |
5554 | 5763 |
5555 #endif // V8_OBJECTS_INL_H_ | 5764 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |