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

Issue 6342: Specialized string equality based on representation (Closed)
Patch Set: Created 12 years, 2 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
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 case kConsStringTag: { 515 case kConsStringTag: {
516 ConsString* cs = ConsString::cast(this); 516 ConsString* cs = ConsString::cast(this);
517 if (String::cast(cs->second())->length() == 0) { 517 if (String::cast(cs->second())->length() == 0) {
518 return this; 518 return this;
519 } 519 }
520 // There's little point in putting the flat string in new space if the 520 // There's little point in putting the flat string in new space if the
521 // cons string is in old space. It can never get GCed until there is 521 // cons string is in old space. It can never get GCed until there is
522 // an old space GC. 522 // an old space GC.
523 PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED : TENURED; 523 PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED : TENURED;
524 int len = length(); 524 int len = length();
525 Object* object = IsAscii() ? 525 Object* object = IsAsciiRepresentation() ?
526 Heap::AllocateRawAsciiString(len, tenure) : 526 Heap::AllocateRawAsciiString(len, tenure) :
527 Heap::AllocateRawTwoByteString(len, tenure); 527 Heap::AllocateRawTwoByteString(len, tenure);
528 if (object->IsFailure()) return object; 528 if (object->IsFailure()) return object;
529 String* result = String::cast(object); 529 String* result = String::cast(object);
530 Flatten(this, result, 0, len, 0); 530 Flatten(this, result, 0, len, 0);
531 cs->set_first(result); 531 cs->set_first(result);
532 cs->set_second(Heap::empty_string()); 532 cs->set_second(Heap::empty_string());
533 return this; 533 return this;
534 } 534 }
535 default: 535 default:
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 748
749 749
750 int HeapObject::SlowSizeFromMap(Map* map) { 750 int HeapObject::SlowSizeFromMap(Map* map) {
751 // Avoid calling functions such as FixedArray::cast during GC, which 751 // Avoid calling functions such as FixedArray::cast during GC, which
752 // read map pointer of this object again. 752 // read map pointer of this object again.
753 InstanceType instance_type = map->instance_type(); 753 InstanceType instance_type = map->instance_type();
754 754
755 if (instance_type < FIRST_NONSTRING_TYPE 755 if (instance_type < FIRST_NONSTRING_TYPE
756 && (reinterpret_cast<String*>(this)->map_representation_tag(map) 756 && (reinterpret_cast<String*>(this)->map_representation_tag(map)
757 == kSeqStringTag)) { 757 == kSeqStringTag)) {
758 if (reinterpret_cast<String*>(this)->is_ascii_map(map)) { 758 if (reinterpret_cast<String*>(this)->is_ascii_representation_map(map)) {
759 return reinterpret_cast<AsciiString*>(this)->AsciiStringSize(map); 759 return reinterpret_cast<SeqAsciiString*>(this)->AsciiStringSize(map);
760 } else { 760 } else {
761 return reinterpret_cast<TwoByteString*>(this)->TwoByteStringSize(map); 761 return reinterpret_cast<SeqTwoByteString*>(this)->TwoByteStringSize(map);
762 } 762 }
763 } 763 }
764 764
765 switch (instance_type) { 765 switch (instance_type) {
766 case FIXED_ARRAY_TYPE: 766 case FIXED_ARRAY_TYPE:
767 return reinterpret_cast<FixedArray*>(this)->FixedArraySize(); 767 return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
768 case BYTE_ARRAY_TYPE: 768 case BYTE_ARRAY_TYPE:
769 return reinterpret_cast<ByteArray*>(this)->ByteArraySize(); 769 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
770 case CODE_TYPE: 770 case CODE_TYPE:
771 return reinterpret_cast<Code*>(this)->CodeSize(); 771 return reinterpret_cast<Code*>(this)->CodeSize();
(...skipping 2191 matching lines...) Expand 10 before | Expand all | Expand 10 after
2963 case kSlicedStringTag: 2963 case kSlicedStringTag:
2964 case kExternalStringTag: 2964 case kExternalStringTag:
2965 return true; 2965 return true;
2966 default: 2966 default:
2967 return false; 2967 return false;
2968 } 2968 }
2969 } 2969 }
2970 2970
2971 2971
2972 int String::Utf8Length() { 2972 int String::Utf8Length() {
2973 if (is_ascii()) return length(); 2973 if (is_ascii_representation()) return length();
2974 // Attempt to flatten before accessing the string. It probably 2974 // Attempt to flatten before accessing the string. It probably
2975 // doesn't make Utf8Length faster, but it is very likely that 2975 // doesn't make Utf8Length faster, but it is very likely that
2976 // the string will be accessed later (for example by WriteUtf8) 2976 // the string will be accessed later (for example by WriteUtf8)
2977 // so it's still a good idea. 2977 // so it's still a good idea.
2978 TryFlatten(); 2978 TryFlatten();
2979 Access<StringInputBuffer> buffer(&string_input_buffer); 2979 Access<StringInputBuffer> buffer(&string_input_buffer);
2980 buffer->Reset(0, this); 2980 buffer->Reset(0, this);
2981 int result = 0; 2981 int result = 0;
2982 while (buffer->has_more()) 2982 while (buffer->has_more())
2983 result += unibrow::Utf8::Length(buffer->GetNext()); 2983 result += unibrow::Utf8::Length(buffer->GetNext());
2984 return result; 2984 return result;
2985 } 2985 }
2986 2986
2987 2987
2988 Vector<const char> String::ToAsciiVector() {
2989 ASSERT(IsAsciiRepresentation());
2990 ASSERT(IsFlat());
2991
2992 int offset = 0;
2993 int length = this->length();
2994 StringRepresentationTag string_tag = representation_tag();
2995 String* string = this;
2996 if (string_tag == kSlicedStringTag) {
2997 SlicedString* sliced = SlicedString::cast(string);
2998 offset += sliced->start();
2999 string = String::cast(sliced->buffer());
3000 string_tag = string->representation_tag();
3001 } else if (string_tag == kConsStringTag) {
3002 ConsString* cons = ConsString::cast(string);
3003 ASSERT(String::cast(cons->second())->length() == 0);
3004 string = String::cast(cons->first());
3005 string_tag = string->representation_tag();
3006 }
3007 if (string_tag == kSeqStringTag) {
3008 SeqAsciiString* seq = SeqAsciiString::cast(string);
3009 char* start = reinterpret_cast<char*>(seq->GetCharsAddress());
3010 return Vector<const char>(start + offset, length);
3011 }
3012 ASSERT(string_tag == kExternalStringTag);
3013 ExternalAsciiString* ext = ExternalAsciiString::cast(string);
3014 const char* start = ext->resource()->data();
3015 return Vector<const char>(start + offset, length);
3016 }
3017
3018
3019 Vector<const uc16> String::ToUC16Vector() {
3020 ASSERT(IsTwoByteStringRepresentation());
3021 ASSERT(IsFlat());
3022
3023 int offset = 0;
3024 int length = this->length();
3025 StringRepresentationTag string_tag = representation_tag();
3026 String* string = this;
3027 if (string_tag == kSlicedStringTag) {
3028 SlicedString* sliced = SlicedString::cast(string);
3029 offset += sliced->start();
3030 string = String::cast(sliced->buffer());
3031 string_tag = string->representation_tag();
3032 } else if (string_tag == kConsStringTag) {
3033 ConsString* cons = ConsString::cast(string);
3034 ASSERT(String::cast(cons->second())->length() == 0);
3035 string = String::cast(cons->first());
3036 string_tag = string->representation_tag();
3037 }
3038 if (string_tag == kSeqStringTag) {
3039 SeqTwoByteString* seq = SeqTwoByteString::cast(string);
3040 uc16* start = reinterpret_cast<uc16*>(seq->GetCharsAddress());
3041 return Vector<const uc16>(start + offset, length);
3042 }
3043 ASSERT(string_tag == kExternalStringTag);
3044 ExternalTwoByteString* ext = ExternalTwoByteString::cast(string);
3045 const uc16* start =
3046 reinterpret_cast<const uc16*>(ext->resource()->data());
3047 return Vector<const uc16>(start + offset, length);
3048 }
3049
3050
2988 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, 3051 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls,
2989 RobustnessFlag robust_flag, 3052 RobustnessFlag robust_flag,
2990 int offset, 3053 int offset,
2991 int length, 3054 int length,
2992 int* length_return) { 3055 int* length_return) {
2993 ASSERT(NativeAllocationChecker::allocation_allowed()); 3056 ASSERT(NativeAllocationChecker::allocation_allowed());
2994 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { 3057 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
2995 return SmartPointer<char>(NULL); 3058 return SmartPointer<char>(NULL);
2996 } 3059 }
2997 3060
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3044 return ToCString(allow_nulls, robust_flag, 0, -1, length_return); 3107 return ToCString(allow_nulls, robust_flag, 0, -1, length_return);
3045 } 3108 }
3046 3109
3047 3110
3048 const uc16* String::GetTwoByteData() { 3111 const uc16* String::GetTwoByteData() {
3049 return GetTwoByteData(0); 3112 return GetTwoByteData(0);
3050 } 3113 }
3051 3114
3052 3115
3053 const uc16* String::GetTwoByteData(unsigned start) { 3116 const uc16* String::GetTwoByteData(unsigned start) {
3054 ASSERT(!IsAscii()); 3117 ASSERT(!IsAsciiRepresentation());
3055 switch (representation_tag()) { 3118 switch (representation_tag()) {
3056 case kSeqStringTag: 3119 case kSeqStringTag:
3057 return TwoByteString::cast(this)->TwoByteStringGetData(start); 3120 return SeqTwoByteString::cast(this)->TwoByteStringGetData(start);
3058 case kExternalStringTag: 3121 case kExternalStringTag:
3059 return ExternalTwoByteString::cast(this)-> 3122 return ExternalTwoByteString::cast(this)->
3060 ExternalTwoByteStringGetData(start); 3123 ExternalTwoByteStringGetData(start);
3061 case kSlicedStringTag: { 3124 case kSlicedStringTag: {
3062 SlicedString* sliced_string = SlicedString::cast(this); 3125 SlicedString* sliced_string = SlicedString::cast(this);
3063 String* buffer = String::cast(sliced_string->buffer()); 3126 String* buffer = String::cast(sliced_string->buffer());
3064 if (buffer->StringIsConsString()) { 3127 if (buffer->StringIsConsString()) {
3065 ConsString* cons_string = ConsString::cast(buffer); 3128 ConsString* cons_string = ConsString::cast(buffer);
3066 // Flattened string. 3129 // Flattened string.
3067 ASSERT(String::cast(cons_string->second())->length() == 0); 3130 ASSERT(String::cast(cons_string->second())->length() == 0);
(...skipping 25 matching lines...) Expand all
3093 int i = 0; 3156 int i = 0;
3094 while (buffer->has_more()) { 3157 while (buffer->has_more()) {
3095 uint16_t character = buffer->GetNext(); 3158 uint16_t character = buffer->GetNext();
3096 result[i++] = character; 3159 result[i++] = character;
3097 } 3160 }
3098 result[i] = 0; 3161 result[i] = 0;
3099 return SmartPointer<uc16>(result); 3162 return SmartPointer<uc16>(result);
3100 } 3163 }
3101 3164
3102 3165
3103 const uc16* TwoByteString::TwoByteStringGetData(unsigned start) { 3166 const uc16* SeqTwoByteString::TwoByteStringGetData(unsigned start) {
3104 return reinterpret_cast<uc16*>( 3167 return reinterpret_cast<uc16*>(
3105 reinterpret_cast<char*>(this) - kHeapObjectTag + kHeaderSize) + start; 3168 reinterpret_cast<char*>(this) - kHeapObjectTag + kHeaderSize) + start;
3106 } 3169 }
3107 3170
3108 3171
3109 void TwoByteString::TwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* rbb, 3172 void SeqTwoByteString::TwoByteStringReadBlockIntoBuffer(ReadBlockBuffer* rbb,
3110 unsigned* offset_ptr, 3173 unsigned* offset_ptr,
3111 unsigned max_chars) { 3174 unsigned max_chars) {
3112 unsigned chars_read = 0; 3175 unsigned chars_read = 0;
3113 unsigned offset = *offset_ptr; 3176 unsigned offset = *offset_ptr;
3114 while (chars_read < max_chars) { 3177 while (chars_read < max_chars) {
3115 uint16_t c = *reinterpret_cast<uint16_t*>( 3178 uint16_t c = *reinterpret_cast<uint16_t*>(
3116 reinterpret_cast<char*>(this) - 3179 reinterpret_cast<char*>(this) -
3117 kHeapObjectTag + kHeaderSize + offset * kShortSize); 3180 kHeapObjectTag + kHeaderSize + offset * kShortSize);
3118 if (c <= kMaxAsciiCharCode) { 3181 if (c <= kMaxAsciiCharCode) {
3119 // Fast case for ASCII characters. Cursor is an input output argument. 3182 // Fast case for ASCII characters. Cursor is an input output argument.
(...skipping 12 matching lines...) Expand all
3132 } 3195 }
3133 } 3196 }
3134 offset++; 3197 offset++;
3135 chars_read++; 3198 chars_read++;
3136 } 3199 }
3137 *offset_ptr = offset; 3200 *offset_ptr = offset;
3138 rbb->remaining += chars_read; 3201 rbb->remaining += chars_read;
3139 } 3202 }
3140 3203
3141 3204
3142 const unibrow::byte* AsciiString::AsciiStringReadBlock(unsigned* remaining, 3205 const unibrow::byte* SeqAsciiString::AsciiStringReadBlock(unsigned* remaining,
3143 unsigned* offset_ptr, 3206 unsigned* offset_ptr,
3144 unsigned max_chars) { 3207 unsigned max_chars) {
3145 // Cast const char* to unibrow::byte* (signedness difference). 3208 // Cast const char* to unibrow::byte* (signedness difference).
3146 const unibrow::byte* b = reinterpret_cast<unibrow::byte*>(this) - 3209 const unibrow::byte* b = reinterpret_cast<unibrow::byte*>(this) -
3147 kHeapObjectTag + kHeaderSize + *offset_ptr * kCharSize; 3210 kHeapObjectTag + kHeaderSize + *offset_ptr * kCharSize;
3148 *remaining = max_chars; 3211 *remaining = max_chars;
3149 *offset_ptr += max_chars; 3212 *offset_ptr += max_chars;
3150 return b; 3213 return b;
3151 } 3214 }
3152 3215
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
3294 break; 3357 break;
3295 } 3358 }
3296 offset++; 3359 offset++;
3297 chars_read++; 3360 chars_read++;
3298 } 3361 }
3299 *offset_ptr = offset; 3362 *offset_ptr = offset;
3300 rbb->remaining += chars_read; 3363 rbb->remaining += chars_read;
3301 } 3364 }
3302 3365
3303 3366
3304 void AsciiString::AsciiStringReadBlockIntoBuffer(ReadBlockBuffer* rbb, 3367 void SeqAsciiString::AsciiStringReadBlockIntoBuffer(ReadBlockBuffer* rbb,
3305 unsigned* offset_ptr, 3368 unsigned* offset_ptr,
3306 unsigned max_chars) { 3369 unsigned max_chars) {
3307 unsigned capacity = rbb->capacity - rbb->cursor; 3370 unsigned capacity = rbb->capacity - rbb->cursor;
3308 if (max_chars > capacity) max_chars = capacity; 3371 if (max_chars > capacity) max_chars = capacity;
3309 memcpy(rbb->util_buffer + rbb->cursor, 3372 memcpy(rbb->util_buffer + rbb->cursor,
3310 reinterpret_cast<char*>(this) - kHeapObjectTag + kHeaderSize + 3373 reinterpret_cast<char*>(this) - kHeapObjectTag + kHeaderSize +
3311 *offset_ptr * kCharSize, 3374 *offset_ptr * kCharSize,
3312 max_chars); 3375 max_chars);
3313 rbb->remaining += max_chars; 3376 rbb->remaining += max_chars;
3314 *offset_ptr += max_chars; 3377 *offset_ptr += max_chars;
(...skipping 24 matching lines...) Expand all
3339 ReadBlockBuffer* rbb, 3402 ReadBlockBuffer* rbb,
3340 unsigned* offset_ptr, 3403 unsigned* offset_ptr,
3341 unsigned max_chars) { 3404 unsigned max_chars) {
3342 ASSERT(*offset_ptr <= static_cast<unsigned>(input->length())); 3405 ASSERT(*offset_ptr <= static_cast<unsigned>(input->length()));
3343 if (max_chars == 0) { 3406 if (max_chars == 0) {
3344 rbb->remaining = 0; 3407 rbb->remaining = 0;
3345 return NULL; 3408 return NULL;
3346 } 3409 }
3347 switch (input->representation_tag()) { 3410 switch (input->representation_tag()) {
3348 case kSeqStringTag: 3411 case kSeqStringTag:
3349 if (input->is_ascii()) { 3412 if (input->is_ascii_representation()) {
3350 return AsciiString::cast(input)->AsciiStringReadBlock(&rbb->remaining, 3413 return SeqAsciiString::cast(input)->AsciiStringReadBlock(&rbb->remaining ,
3351 offset_ptr, 3414 offset_ptr,
3352 max_chars); 3415 max_chars);
3353 } else { 3416 } else {
3354 TwoByteString::cast(input)->TwoByteStringReadBlockIntoBuffer(rbb, 3417 SeqTwoByteString::cast(input)->TwoByteStringReadBlockIntoBuffer(rbb,
3355 offset_ptr, 3418 offset_ptr,
3356 max_chars); 3419 max_chars);
3357 return rbb->util_buffer; 3420 return rbb->util_buffer;
3358 } 3421 }
3359 case kConsStringTag: 3422 case kConsStringTag:
3360 return ConsString::cast(input)->ConsStringReadBlock(rbb, 3423 return ConsString::cast(input)->ConsStringReadBlock(rbb,
3361 offset_ptr, 3424 offset_ptr,
3362 max_chars); 3425 max_chars);
3363 case kSlicedStringTag: 3426 case kSlicedStringTag:
3364 return SlicedString::cast(input)->SlicedStringReadBlock(rbb, 3427 return SlicedString::cast(input)->SlicedStringReadBlock(rbb,
3365 offset_ptr, 3428 offset_ptr,
3366 max_chars); 3429 max_chars);
3367 case kExternalStringTag: 3430 case kExternalStringTag:
3368 if (input->is_ascii()) { 3431 if (input->is_ascii_representation()) {
3369 return ExternalAsciiString::cast(input)->ExternalAsciiStringReadBlock( 3432 return ExternalAsciiString::cast(input)->ExternalAsciiStringReadBlock(
3370 &rbb->remaining, 3433 &rbb->remaining,
3371 offset_ptr, 3434 offset_ptr,
3372 max_chars); 3435 max_chars);
3373 } else { 3436 } else {
3374 ExternalTwoByteString::cast(input)-> 3437 ExternalTwoByteString::cast(input)->
3375 ExternalTwoByteStringReadBlockIntoBuffer(rbb, 3438 ExternalTwoByteStringReadBlockIntoBuffer(rbb,
3376 offset_ptr, 3439 offset_ptr,
3377 max_chars); 3440 max_chars);
3378 return rbb->util_buffer; 3441 return rbb->util_buffer;
(...skipping 23 matching lines...) Expand all
3402 // to fill up a buffer. 3465 // to fill up a buffer.
3403 void String::ReadBlockIntoBuffer(String* input, 3466 void String::ReadBlockIntoBuffer(String* input,
3404 ReadBlockBuffer* rbb, 3467 ReadBlockBuffer* rbb,
3405 unsigned* offset_ptr, 3468 unsigned* offset_ptr,
3406 unsigned max_chars) { 3469 unsigned max_chars) {
3407 ASSERT(*offset_ptr <= (unsigned)input->length()); 3470 ASSERT(*offset_ptr <= (unsigned)input->length());
3408 if (max_chars == 0) return; 3471 if (max_chars == 0) return;
3409 3472
3410 switch (input->representation_tag()) { 3473 switch (input->representation_tag()) {
3411 case kSeqStringTag: 3474 case kSeqStringTag:
3412 if (input->is_ascii()) { 3475 if (input->is_ascii_representation()) {
3413 AsciiString::cast(input)->AsciiStringReadBlockIntoBuffer(rbb, 3476 SeqAsciiString::cast(input)->AsciiStringReadBlockIntoBuffer(rbb,
3414 offset_ptr, 3477 offset_ptr,
3415 max_chars); 3478 max_chars);
3416 return; 3479 return;
3417 } else { 3480 } else {
3418 TwoByteString::cast(input)->TwoByteStringReadBlockIntoBuffer(rbb, 3481 SeqTwoByteString::cast(input)->TwoByteStringReadBlockIntoBuffer(rbb,
3419 offset_ptr, 3482 offset_ptr,
3420 max_chars); 3483 max_chars);
3421 return; 3484 return;
3422 } 3485 }
3423 case kConsStringTag: 3486 case kConsStringTag:
3424 ConsString::cast(input)->ConsStringReadBlockIntoBuffer(rbb, 3487 ConsString::cast(input)->ConsStringReadBlockIntoBuffer(rbb,
3425 offset_ptr, 3488 offset_ptr,
3426 max_chars); 3489 max_chars);
3427 return; 3490 return;
3428 case kSlicedStringTag: 3491 case kSlicedStringTag:
3429 SlicedString::cast(input)->SlicedStringReadBlockIntoBuffer(rbb, 3492 SlicedString::cast(input)->SlicedStringReadBlockIntoBuffer(rbb,
3430 offset_ptr, 3493 offset_ptr,
3431 max_chars); 3494 max_chars);
3432 return; 3495 return;
3433 case kExternalStringTag: 3496 case kExternalStringTag:
3434 if (input->is_ascii()) { 3497 if (input->is_ascii_representation()) {
3435 ExternalAsciiString::cast(input)-> 3498 ExternalAsciiString::cast(input)->
3436 ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars); 3499 ExternalAsciiStringReadBlockIntoBuffer(rbb, offset_ptr, max_chars);
3437 } else { 3500 } else {
3438 ExternalTwoByteString::cast(input)-> 3501 ExternalTwoByteString::cast(input)->
3439 ExternalTwoByteStringReadBlockIntoBuffer(rbb, 3502 ExternalTwoByteStringReadBlockIntoBuffer(rbb,
3440 offset_ptr, 3503 offset_ptr,
3441 max_chars); 3504 max_chars);
3442 } 3505 }
3443 return; 3506 return;
3444 default: 3507 default:
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
3681 } 3744 }
3682 3745
3683 3746
3684 uint16_t SlicedString::SlicedStringGet(int index) { 3747 uint16_t SlicedString::SlicedStringGet(int index) {
3685 ASSERT(index >= 0 && index < this->length()); 3748 ASSERT(index >= 0 && index < this->length());
3686 // Delegate to the buffer string. 3749 // Delegate to the buffer string.
3687 return String::cast(buffer())->Get(start() + index); 3750 return String::cast(buffer())->Get(start() + index);
3688 } 3751 }
3689 3752
3690 3753
3754 template <typename IteratorA, typename IteratorB>
3755 static inline bool CompareStringContents(IteratorA* ia, IteratorB* ib) {
3756 // General slow case check. We know that the ia and ib iterators
3757 // have the same length.
3758 while (ia->has_more()) {
3759 uc32 ca = ia->GetNext();
3760 uc32 cb = ib->GetNext();
3761 if (ca != cb)
3762 return false;
3763 }
3764 return true;
3765 }
3766
3767
3768 static StringInputBuffer string_compare_buffer_b;
3769
3770
3771 template <typename IteratorA>
3772 static inline bool CompareStringContentsPartial(IteratorA* ia, String* b) {
3773 if (b->IsFlat()) {
3774 if (b->IsAsciiRepresentation()) {
3775 VectorIterator<const char> ib(b->ToAsciiVector());
3776 return CompareStringContents(ia, &ib);
3777 } else {
3778 VectorIterator<const uc16> ib(b->ToUC16Vector());
3779 return CompareStringContents(ia, &ib);
3780 }
3781 } else {
3782 string_compare_buffer_b.Reset(0, b);
3783 return CompareStringContents(ia, &string_compare_buffer_b);
3784 }
3785 }
3786
3787
3788 static StringInputBuffer string_compare_buffer_a;
3789
3790
3691 bool String::SlowEquals(String* other) { 3791 bool String::SlowEquals(String* other) {
3692 // Fast check: negative check with lengths. 3792 // Fast check: negative check with lengths.
3693 int len = length(); 3793 int len = length();
3694 if (len != other->length()) return false; 3794 if (len != other->length()) return false;
3695 if (len == 0) return true; 3795 if (len == 0) return true;
3696 3796
3697 // Fast check: if hash code is computed for both strings 3797 // Fast check: if hash code is computed for both strings
3698 // a fast negative check can be performed. 3798 // a fast negative check can be performed.
3699 if (HasHashCode() && other->HasHashCode()) { 3799 if (HasHashCode() && other->HasHashCode()) {
3700 if (Hash() != other->Hash()) return false; 3800 if (Hash() != other->Hash()) return false;
3701 } 3801 }
3702 3802
3703 // Fast case: avoid input buffers for small strings. 3803 if (this->IsFlat()) {
3704 const int kMaxLenthForFastCaseCheck = 5; 3804 if (this->IsAsciiRepresentation()) {
3705 for (int i = 0; i < kMaxLenthForFastCaseCheck; i++) { 3805 VectorIterator<const char> buf1(this->ToAsciiVector());
3706 if (Get(i) != other->Get(i)) return false; 3806 return CompareStringContentsPartial(&buf1, other);
3707 if (i + 1 == len) return true; 3807 } else {
3808 VectorIterator<const uc16> buf1(this->ToUC16Vector());
3809 return CompareStringContentsPartial(&buf1, other);
3810 }
3811 } else {
3812 string_compare_buffer_a.Reset(0, this);
3813 return CompareStringContentsPartial(&string_compare_buffer_a, other);
3708 } 3814 }
3709
3710 // General slow case check.
3711 static StringInputBuffer buf1;
3712 static StringInputBuffer buf2;
3713 buf1.Reset(kMaxLenthForFastCaseCheck, this);
3714 buf2.Reset(kMaxLenthForFastCaseCheck, other);
3715 while (buf1.has_more()) {
3716 if (buf1.GetNext() != buf2.GetNext()) {
3717 return false;
3718 }
3719 }
3720 return true;
3721 } 3815 }
3722 3816
3723 3817
3724 bool String::MarkAsUndetectable() { 3818 bool String::MarkAsUndetectable() {
3725 if (this->IsSymbol()) return false; 3819 if (this->IsSymbol()) return false;
3726 3820
3727 Map* map = this->map(); 3821 Map* map = this->map();
3728 if (map == Heap::short_string_map()) { 3822 if (map == Heap::short_string_map()) {
3729 this->set_map(Heap::undetectable_short_string_map()); 3823 this->set_map(Heap::undetectable_short_string_map());
3730 return true; 3824 return true;
(...skipping 2713 matching lines...) Expand 10 before | Expand all | Expand 10 after
6444 // No break point. 6538 // No break point.
6445 if (break_point_objects()->IsUndefined()) return 0; 6539 if (break_point_objects()->IsUndefined()) return 0;
6446 // Single beak point. 6540 // Single beak point.
6447 if (!break_point_objects()->IsFixedArray()) return 1; 6541 if (!break_point_objects()->IsFixedArray()) return 1;
6448 // Multiple break points. 6542 // Multiple break points.
6449 return FixedArray::cast(break_point_objects())->length(); 6543 return FixedArray::cast(break_point_objects())->length();
6450 } 6544 }
6451 6545
6452 6546
6453 } } // namespace v8::internal 6547 } } // namespace v8::internal
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698