| 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 |