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

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

Issue 11438046: Cleanup StringCharacterStream and add initial test cases. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Cleanup 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
« no previous file with comments | « src/objects.cc ('k') | test/cctest/test-strings.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2499 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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_
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | test/cctest/test-strings.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698