OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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_ |
OLD | NEW |