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: | |
Yang
2012/12/04 14:49:11
We usually indent switch-case-clauses like
switch
| |
2533 visitor.VisitOneByteString( | |
2534 reinterpret_cast<const uint8_t*>( | |
2535 SeqOneByteString::cast(string)->GetChars()) + sliceOffset, | |
2536 length - offset); | |
Yang
2012/12/04 14:49:11
I suggest adding four more spaces as indentation.
| |
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 { | |
2563 SlicedString* slicedString = SlicedString::cast(string); | |
2564 sliceOffset += slicedString->offset(); | |
2565 string = slicedString->parent(); | |
2566 type = string->map()->instance_type(); | |
2567 continue; | |
2568 } | |
2569 | |
2570 case kConsStringTag | kOneByteStringTag: | |
2571 case kConsStringTag | kTwoByteStringTag: | |
2572 string = consOp.Operate( | |
2573 ConsString::cast(string), &offset, &type, &length); | |
2574 if (string == NULL) | |
Yang
2012/12/04 14:49:11
no line break here.
| |
2575 return; | |
2576 sliceOffset = offset; | |
2577 ASSERT(length == static_cast<unsigned>(string->length())); | |
2578 continue; | |
2579 | |
2580 default: | |
2581 UNREACHABLE(); | |
2582 return; | |
2583 } | |
2584 } | |
2585 } | |
2586 | |
2587 | |
2515 uint16_t SeqOneByteString::SeqOneByteStringGet(int index) { | 2588 uint16_t SeqOneByteString::SeqOneByteStringGet(int index) { |
2516 ASSERT(index >= 0 && index < length()); | 2589 ASSERT(index >= 0 && index < length()); |
2517 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); | 2590 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); |
2518 } | 2591 } |
2519 | 2592 |
2520 | 2593 |
2521 void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) { | 2594 void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) { |
2522 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode); | 2595 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode); |
2523 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, | 2596 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, |
2524 static_cast<byte>(value)); | 2597 static_cast<byte>(value)); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2683 return GetChars()[index]; | 2756 return GetChars()[index]; |
2684 } | 2757 } |
2685 | 2758 |
2686 | 2759 |
2687 const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData( | 2760 const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData( |
2688 unsigned start) { | 2761 unsigned start) { |
2689 return GetChars() + start; | 2762 return GetChars() + start; |
2690 } | 2763 } |
2691 | 2764 |
2692 | 2765 |
2766 unsigned ConsStringIteratorOp::OffsetForDepth(unsigned depth) { | |
2767 return depth & depthMask; | |
2768 } | |
2769 | |
2770 | |
2771 uint32_t ConsStringIteratorOp::MaskForDepth(unsigned depth) { | |
2772 return 1 << OffsetForDepth(depth); | |
2773 } | |
2774 | |
2775 | |
2776 void ConsStringIteratorOp::SetRightDescent() { | |
2777 trace |= MaskForDepth(depth - 1); | |
2778 } | |
2779 | |
2780 | |
2781 void ConsStringIteratorOp::ClearRightDescent() { | |
2782 trace &= ~MaskForDepth(depth - 1); | |
2783 } | |
2784 | |
2785 | |
2786 void ConsStringIteratorOp::PushLeft(ConsString* string) { | |
2787 frames[depth++ & depthMask] = string; | |
2788 } | |
2789 | |
2790 | |
2791 void ConsStringIteratorOp::PushRight(ConsString* string, int32_t type) { | |
2792 // Inplace update | |
2793 frames[depth-1 & depthMask] = string; | |
2794 // Optimization: can replace root here. | |
2795 if (depth == 1) { | |
2796 root = string; | |
2797 rootType = type; | |
2798 rootLength = root->length(); | |
2799 } | |
2800 } | |
2801 | |
2802 | |
2803 void ConsStringIteratorOp::AdjustMaximumDepth() { | |
2804 if (depth > maximumDepth) | |
2805 maximumDepth = depth; | |
Yang
2012/12/04 14:49:11
No line break here.
| |
2806 } | |
2807 | |
2808 | |
2809 void ConsStringIteratorOp::Pop() { | |
2810 ASSERT(depth > 0); | |
2811 ASSERT(depth <= maximumDepth); | |
2812 depth--; | |
2813 } | |
2814 | |
2815 | |
2816 void ConsStringIteratorOp::Reset() { | |
2817 consumed = 0; | |
2818 ResetStack(); | |
2819 } | |
2820 | |
2821 | |
2822 bool ConsStringIteratorOp::HasMore() { | |
2823 return depth != 0; | |
2824 } | |
2825 | |
2826 | |
2827 void ConsStringIteratorOp::ResetStack() { | |
2828 depth = 0; | |
2829 maximumDepth = 0; | |
2830 } | |
2831 | |
2832 | |
2833 bool ConsStringIteratorOp::ContinueOperation(ContinueResponse* response) { | |
2834 bool blewStack; | |
2835 int32_t type; | |
2836 String* string = NextLeaf(&blewStack, &type); | |
2837 // String found. | |
2838 if (string != NULL) { | |
2839 unsigned length = string->length(); | |
2840 consumed += length; | |
2841 response->string = string; | |
2842 response->offset = 0; | |
2843 response->length = length; | |
2844 response->type = type; | |
2845 return true; | |
2846 } | |
2847 // Traversal complete. | |
2848 if (!blewStack) | |
2849 return false; | |
Yang
2012/12/04 14:49:11
no line break.
| |
2850 // Restart search. | |
2851 ResetStack(); | |
2852 response->string = root; | |
2853 response->offset = consumed; | |
2854 response->length = root->length(); | |
2855 response->type = rootType; | |
2856 return true; | |
2857 } | |
2858 | |
2859 | |
2860 uint16_t StringBufferStream::GetNext() { | |
2861 return isOneByte ? *buffer8++ : *buffer16++; | |
2862 } | |
2863 | |
2864 | |
2865 void StringBufferStream::Reset(String* string, unsigned offset, | |
Yang
2012/12/04 14:49:11
Please put all arguments on the second line.
| |
2866 ConsStringIteratorOp* op) { | |
2867 buffer8 = NULL; | |
2868 end = NULL; | |
2869 this->op = op; | |
2870 op->Reset(); | |
2871 String::Visit(string, | |
2872 offset, *this, *op, string->map()->instance_type(), string->length()); | |
2873 } | |
2874 | |
2875 | |
2876 bool StringBufferStream::has_more() { | |
2877 if (buffer8 != end) | |
2878 return true; | |
Yang
2012/12/04 14:49:11
no line break here and in the following if.
| |
2879 if (!op->HasMore()) | |
2880 return false; | |
2881 ConsStringIteratorOp::ContinueResponse response; | |
2882 // This has been checked above | |
2883 if (!op->ContinueOperation(&response)) { | |
2884 UNREACHABLE(); | |
2885 return false; | |
2886 } | |
2887 String::Visit(response.string, | |
2888 response.offset, *this, *op, response.type, response.length); | |
2889 return true; | |
2890 } | |
2891 | |
2892 | |
2893 void StringBufferStream::VisitOneByteString(const uint8_t* chars, | |
2894 unsigned length) { | |
Yang
2012/12/04 14:49:11
Either align the two arguments or put both on the
| |
2895 isOneByte = true; | |
2896 buffer8 = chars; | |
2897 end = chars + length; | |
2898 } | |
2899 | |
2900 | |
2901 void StringBufferStream::VisitTwoByteString(const uint16_t* chars, | |
2902 unsigned length) { | |
Yang
2012/12/04 14:49:11
Ditto.
| |
2903 isOneByte = false; | |
2904 buffer16 = chars; | |
2905 end = reinterpret_cast<const uint8_t*>(chars + length); | |
2906 } | |
2907 | |
2908 | |
2693 void JSFunctionResultCache::MakeZeroSize() { | 2909 void JSFunctionResultCache::MakeZeroSize() { |
2694 set_finger_index(kEntriesIndex); | 2910 set_finger_index(kEntriesIndex); |
2695 set_size(kEntriesIndex); | 2911 set_size(kEntriesIndex); |
2696 } | 2912 } |
2697 | 2913 |
2698 | 2914 |
2699 void JSFunctionResultCache::Clear() { | 2915 void JSFunctionResultCache::Clear() { |
2700 int cache_size = size(); | 2916 int cache_size = size(); |
2701 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex)); | 2917 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex)); |
2702 MemsetPointer(entries_start, | 2918 MemsetPointer(entries_start, |
(...skipping 2843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5546 #undef WRITE_UINT32_FIELD | 5762 #undef WRITE_UINT32_FIELD |
5547 #undef READ_SHORT_FIELD | 5763 #undef READ_SHORT_FIELD |
5548 #undef WRITE_SHORT_FIELD | 5764 #undef WRITE_SHORT_FIELD |
5549 #undef READ_BYTE_FIELD | 5765 #undef READ_BYTE_FIELD |
5550 #undef WRITE_BYTE_FIELD | 5766 #undef WRITE_BYTE_FIELD |
5551 | 5767 |
5552 | 5768 |
5553 } } // namespace v8::internal | 5769 } } // namespace v8::internal |
5554 | 5770 |
5555 #endif // V8_OBJECTS_INL_H_ | 5771 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |