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

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

Issue 254763008: Remove String::Visit (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebase Created 6 years, 7 months 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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // Review notes: 5 // Review notes:
6 // 6 //
7 // - The use of macros in these inline functions may seem superfluous 7 // - The use of macros in these inline functions may seem superfluous
8 // but it is absolutely needed to make sure gcc generates optimal 8 // but it is absolutely needed to make sure gcc generates optimal
9 // code. gcc is not happy when attempting to inline too deep. 9 // code. gcc is not happy when attempting to inline too deep.
10 // 10 //
(...skipping 3112 matching lines...) Expand 10 before | Expand all | Expand 10 after
3123 // Giving direct access to underlying string only makes sense if the 3123 // Giving direct access to underlying string only makes sense if the
3124 // wrapping string is already flattened. 3124 // wrapping string is already flattened.
3125 ASSERT(this->IsFlat()); 3125 ASSERT(this->IsFlat());
3126 ASSERT(StringShape(this).IsIndirect()); 3126 ASSERT(StringShape(this).IsIndirect());
3127 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset); 3127 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
3128 const int kUnderlyingOffset = SlicedString::kParentOffset; 3128 const int kUnderlyingOffset = SlicedString::kParentOffset;
3129 return String::cast(READ_FIELD(this, kUnderlyingOffset)); 3129 return String::cast(READ_FIELD(this, kUnderlyingOffset));
3130 } 3130 }
3131 3131
3132 3132
3133 template<class Visitor, class ConsOp> 3133 template<class Visitor>
3134 void String::Visit( 3134 ConsString* String::VisitFlat(Visitor* visitor,
3135 String* string, 3135 String* string,
3136 unsigned offset, 3136 const int offset) {
3137 Visitor& visitor, 3137 int slice_offset = offset;
3138 ConsOp& cons_op, 3138 const int length = string->length();
3139 int32_t type,
3140 unsigned length) {
3141 ASSERT(length == static_cast<unsigned>(string->length()));
3142 ASSERT(offset <= length); 3139 ASSERT(offset <= length);
3143 unsigned slice_offset = offset;
3144 while (true) { 3140 while (true) {
3145 ASSERT(type == string->map()->instance_type()); 3141 int32_t type = string->map()->instance_type();
3146
3147 switch (type & (kStringRepresentationMask | kStringEncodingMask)) { 3142 switch (type & (kStringRepresentationMask | kStringEncodingMask)) {
3148 case kSeqStringTag | kOneByteStringTag: 3143 case kSeqStringTag | kOneByteStringTag:
3149 visitor.VisitOneByteString( 3144 visitor->VisitOneByteString(
3150 SeqOneByteString::cast(string)->GetChars() + slice_offset, 3145 SeqOneByteString::cast(string)->GetChars() + slice_offset,
3151 length - offset); 3146 length - offset);
3152 return; 3147 return NULL;
3153 3148
3154 case kSeqStringTag | kTwoByteStringTag: 3149 case kSeqStringTag | kTwoByteStringTag:
3155 visitor.VisitTwoByteString( 3150 visitor->VisitTwoByteString(
3156 SeqTwoByteString::cast(string)->GetChars() + slice_offset, 3151 SeqTwoByteString::cast(string)->GetChars() + slice_offset,
3157 length - offset); 3152 length - offset);
3158 return; 3153 return NULL;
3159 3154
3160 case kExternalStringTag | kOneByteStringTag: 3155 case kExternalStringTag | kOneByteStringTag:
3161 visitor.VisitOneByteString( 3156 visitor->VisitOneByteString(
3162 ExternalAsciiString::cast(string)->GetChars() + slice_offset, 3157 ExternalAsciiString::cast(string)->GetChars() + slice_offset,
3163 length - offset); 3158 length - offset);
3164 return; 3159 return NULL;
3165 3160
3166 case kExternalStringTag | kTwoByteStringTag: 3161 case kExternalStringTag | kTwoByteStringTag:
3167 visitor.VisitTwoByteString( 3162 visitor->VisitTwoByteString(
3168 ExternalTwoByteString::cast(string)->GetChars() + slice_offset, 3163 ExternalTwoByteString::cast(string)->GetChars() + slice_offset,
3169 length - offset); 3164 length - offset);
3170 return; 3165 return NULL;
3171 3166
3172 case kSlicedStringTag | kOneByteStringTag: 3167 case kSlicedStringTag | kOneByteStringTag:
3173 case kSlicedStringTag | kTwoByteStringTag: { 3168 case kSlicedStringTag | kTwoByteStringTag: {
3174 SlicedString* slicedString = SlicedString::cast(string); 3169 SlicedString* slicedString = SlicedString::cast(string);
3175 slice_offset += slicedString->offset(); 3170 slice_offset += slicedString->offset();
3176 string = slicedString->parent(); 3171 string = slicedString->parent();
3177 type = string->map()->instance_type();
3178 continue; 3172 continue;
3179 } 3173 }
3180 3174
3181 case kConsStringTag | kOneByteStringTag: 3175 case kConsStringTag | kOneByteStringTag:
3182 case kConsStringTag | kTwoByteStringTag: 3176 case kConsStringTag | kTwoByteStringTag:
3183 string = cons_op.Operate(string, &offset, &type, &length); 3177 return ConsString::cast(string);
3184 if (string == NULL) return;
3185 slice_offset = offset;
3186 ASSERT(length == static_cast<unsigned>(string->length()));
3187 continue;
3188 3178
3189 default: 3179 default:
3190 UNREACHABLE(); 3180 UNREACHABLE();
3191 return; 3181 return NULL;
3192 } 3182 }
3193 } 3183 }
3194 } 3184 }
3195 3185
3196 3186
3197 // TODO(dcarney): Remove this class after conversion to VisitFlat.
3198 class ConsStringCaptureOp {
3199 public:
3200 inline ConsStringCaptureOp() : cons_string_(NULL) {}
3201 inline String* Operate(String* string, unsigned*, int32_t*, unsigned*) {
3202 cons_string_ = ConsString::cast(string);
3203 return NULL;
3204 }
3205 ConsString* cons_string_;
3206 };
3207
3208
3209 template<class Visitor>
3210 ConsString* String::VisitFlat(Visitor* visitor,
3211 String* string,
3212 int offset,
3213 int length,
3214 int32_t type) {
3215 ASSERT(length >= 0 && length == string->length());
3216 ASSERT(offset >= 0 && offset <= length);
3217 ConsStringCaptureOp op;
3218 Visit(string, offset, *visitor, op, type, static_cast<unsigned>(length));
3219 return op.cons_string_;
3220 }
3221
3222
3223 uint16_t SeqOneByteString::SeqOneByteStringGet(int index) { 3187 uint16_t SeqOneByteString::SeqOneByteStringGet(int index) {
3224 ASSERT(index >= 0 && index < length()); 3188 ASSERT(index >= 0 && index < length());
3225 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); 3189 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
3226 } 3190 }
3227 3191
3228 3192
3229 void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) { 3193 void SeqOneByteString::SeqOneByteStringSet(int index, uint16_t value) {
3230 ASSERT(index >= 0 && index < length() && value <= kMaxOneByteCharCode); 3194 ASSERT(index >= 0 && index < length() && value <= kMaxOneByteCharCode);
3231 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, 3195 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
3232 static_cast<byte>(value)); 3196 static_cast<byte>(value));
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
3392 return GetChars()[index]; 3356 return GetChars()[index];
3393 } 3357 }
3394 3358
3395 3359
3396 const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData( 3360 const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
3397 unsigned start) { 3361 unsigned start) {
3398 return GetChars() + start; 3362 return GetChars() + start;
3399 } 3363 }
3400 3364
3401 3365
3402 String* ConsStringNullOp::Operate(String*, unsigned*, int32_t*, unsigned*) { 3366 int ConsStringIteratorOp::OffsetForDepth(int depth) {
3403 return NULL;
3404 }
3405
3406
3407 unsigned ConsStringIteratorOp::OffsetForDepth(unsigned depth) {
3408 return depth & kDepthMask; 3367 return depth & kDepthMask;
3409 } 3368 }
3410 3369
3411 3370
3412 void ConsStringIteratorOp::PushLeft(ConsString* string) { 3371 void ConsStringIteratorOp::PushLeft(ConsString* string) {
3413 frames_[depth_++ & kDepthMask] = string; 3372 frames_[depth_++ & kDepthMask] = string;
3414 } 3373 }
3415 3374
3416 3375
3417 void ConsStringIteratorOp::PushRight(ConsString* string) { 3376 void ConsStringIteratorOp::PushRight(ConsString* string) {
3418 // Inplace update. 3377 // Inplace update.
3419 frames_[(depth_-1) & kDepthMask] = string; 3378 frames_[(depth_-1) & kDepthMask] = string;
3420 } 3379 }
3421 3380
3422 3381
3423 void ConsStringIteratorOp::AdjustMaximumDepth() { 3382 void ConsStringIteratorOp::AdjustMaximumDepth() {
3424 if (depth_ > maximum_depth_) maximum_depth_ = depth_; 3383 if (depth_ > maximum_depth_) maximum_depth_ = depth_;
3425 } 3384 }
3426 3385
3427 3386
3428 void ConsStringIteratorOp::Pop() { 3387 void ConsStringIteratorOp::Pop() {
3429 ASSERT(depth_ > 0); 3388 ASSERT(depth_ > 0);
3430 ASSERT(depth_ <= maximum_depth_); 3389 ASSERT(depth_ <= maximum_depth_);
3431 depth_--; 3390 depth_--;
3432 } 3391 }
3433 3392
3434 3393
3435 bool ConsStringIteratorOp::HasMore() {
3436 return depth_ != 0;
3437 }
3438
3439
3440 void ConsStringIteratorOp::Reset() {
3441 depth_ = 0;
3442 }
3443
3444
3445 String* ConsStringIteratorOp::ContinueOperation(int32_t* type_out,
3446 unsigned* length_out) {
3447 bool blew_stack = false;
3448 String* string = NextLeaf(&blew_stack, type_out, length_out);
3449 // String found.
3450 if (string != NULL) {
3451 // Verify output.
3452 ASSERT(*length_out == static_cast<unsigned>(string->length()));
3453 ASSERT(*type_out == string->map()->instance_type());
3454 return string;
3455 }
3456 // Traversal complete.
3457 if (!blew_stack) return NULL;
3458 // Restart search from root.
3459 unsigned offset_out;
3460 string = Search(&offset_out, type_out, length_out);
3461 // Verify output.
3462 ASSERT(string == NULL || offset_out == 0);
3463 ASSERT(string == NULL ||
3464 *length_out == static_cast<unsigned>(string->length()));
3465 ASSERT(string == NULL || *type_out == string->map()->instance_type());
3466 return string;
3467 }
3468
3469
3470 uint16_t StringCharacterStream::GetNext() { 3394 uint16_t StringCharacterStream::GetNext() {
3471 ASSERT(buffer8_ != NULL && end_ != NULL); 3395 ASSERT(buffer8_ != NULL && end_ != NULL);
3472 // Advance cursor if needed. 3396 // Advance cursor if needed.
3473 // TODO(dcarney): Ensure uses of the api call HasMore first and avoid this.
3474 if (buffer8_ == end_) HasMore(); 3397 if (buffer8_ == end_) HasMore();
3475 ASSERT(buffer8_ < end_); 3398 ASSERT(buffer8_ < end_);
3476 return is_one_byte_ ? *buffer8_++ : *buffer16_++; 3399 return is_one_byte_ ? *buffer8_++ : *buffer16_++;
3477 } 3400 }
3478 3401
3479 3402
3480 StringCharacterStream::StringCharacterStream(String* string, 3403 StringCharacterStream::StringCharacterStream(String* string,
3481 ConsStringIteratorOp* op, 3404 ConsStringIteratorOp* op,
3482 unsigned offset) 3405 int offset)
3483 : is_one_byte_(false), 3406 : is_one_byte_(false),
3484 op_(op) { 3407 op_(op) {
3485 Reset(string, offset); 3408 Reset(string, offset);
3486 } 3409 }
3487 3410
3488 3411
3489 void StringCharacterStream::Reset(String* string, unsigned offset) { 3412 void StringCharacterStream::Reset(String* string, int offset) {
3490 op_->Reset();
3491 buffer8_ = NULL; 3413 buffer8_ = NULL;
3492 end_ = NULL; 3414 end_ = NULL;
3493 int32_t type = string->map()->instance_type(); 3415 ConsString* cons_string = String::VisitFlat(this, string, offset);
3494 unsigned length = string->length(); 3416 op_->Reset(cons_string, offset);
3495 String::Visit(string, offset, *this, *op_, type, length); 3417 if (cons_string != NULL) {
3418 string = op_->Next(&offset);
3419 if (string != NULL) String::VisitFlat(this, string, offset);
3420 }
3496 } 3421 }
3497 3422
3498 3423
3499 bool StringCharacterStream::HasMore() { 3424 bool StringCharacterStream::HasMore() {
3500 if (buffer8_ != end_) return true; 3425 if (buffer8_ != end_) return true;
3501 if (!op_->HasMore()) return false; 3426 int offset;
3502 unsigned length; 3427 String* string = op_->Next(&offset);
3503 int32_t type; 3428 ASSERT_EQ(offset, 0);
3504 String* string = op_->ContinueOperation(&type, &length);
3505 if (string == NULL) return false; 3429 if (string == NULL) return false;
3506 ASSERT(!string->IsConsString()); 3430 String::VisitFlat(this, string);
3507 ASSERT(string->length() != 0);
3508 ConsStringNullOp null_op;
3509 String::Visit(string, 0, *this, null_op, type, length);
3510 ASSERT(buffer8_ != end_); 3431 ASSERT(buffer8_ != end_);
3511 return true; 3432 return true;
3512 } 3433 }
3513 3434
3514 3435
3515 void StringCharacterStream::VisitOneByteString( 3436 void StringCharacterStream::VisitOneByteString(
3516 const uint8_t* chars, unsigned length) { 3437 const uint8_t* chars, int length) {
3517 is_one_byte_ = true; 3438 is_one_byte_ = true;
3518 buffer8_ = chars; 3439 buffer8_ = chars;
3519 end_ = chars + length; 3440 end_ = chars + length;
3520 } 3441 }
3521 3442
3522 3443
3523 void StringCharacterStream::VisitTwoByteString( 3444 void StringCharacterStream::VisitTwoByteString(
3524 const uint16_t* chars, unsigned length) { 3445 const uint16_t* chars, int length) {
3525 is_one_byte_ = false; 3446 is_one_byte_ = false;
3526 buffer16_ = chars; 3447 buffer16_ = chars;
3527 end_ = reinterpret_cast<const uint8_t*>(chars + length); 3448 end_ = reinterpret_cast<const uint8_t*>(chars + length);
3528 } 3449 }
3529 3450
3530 3451
3531 void JSFunctionResultCache::MakeZeroSize() { 3452 void JSFunctionResultCache::MakeZeroSize() {
3532 set_finger_index(kEntriesIndex); 3453 set_finger_index(kEntriesIndex);
3533 set_size(kEntriesIndex); 3454 set_size(kEntriesIndex);
3534 } 3455 }
(...skipping 3447 matching lines...) Expand 10 before | Expand all | Expand 10 after
6982 #undef READ_SHORT_FIELD 6903 #undef READ_SHORT_FIELD
6983 #undef WRITE_SHORT_FIELD 6904 #undef WRITE_SHORT_FIELD
6984 #undef READ_BYTE_FIELD 6905 #undef READ_BYTE_FIELD
6985 #undef WRITE_BYTE_FIELD 6906 #undef WRITE_BYTE_FIELD
6986 #undef NOBARRIER_READ_BYTE_FIELD 6907 #undef NOBARRIER_READ_BYTE_FIELD
6987 #undef NOBARRIER_WRITE_BYTE_FIELD 6908 #undef NOBARRIER_WRITE_BYTE_FIELD
6988 6909
6989 } } // namespace v8::internal 6910 } } // namespace v8::internal
6990 6911
6991 #endif // V8_OBJECTS_INL_H_ 6912 #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