Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(336)

Side by Side Diff: src/objects-inl.h

Issue 11428106: Add StringBufferStream (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Right traversal optimization Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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_
OLDNEW
« src/objects.cc ('K') | « src/objects.cc ('k') | test/cctest/test-strings.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698