| OLD | NEW |
| 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 2767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2778 roots_[constant_symbol_table[i].index] = String::cast(obj); | 2778 roots_[constant_symbol_table[i].index] = String::cast(obj); |
| 2779 } | 2779 } |
| 2780 | 2780 |
| 2781 // Allocate the hidden symbol which is used to identify the hidden properties | 2781 // Allocate the hidden symbol which is used to identify the hidden properties |
| 2782 // in JSObjects. The hash code has a special value so that it will not match | 2782 // in JSObjects. The hash code has a special value so that it will not match |
| 2783 // the empty string when searching for the property. It cannot be part of the | 2783 // the empty string when searching for the property. It cannot be part of the |
| 2784 // loop above because it needs to be allocated manually with the special | 2784 // loop above because it needs to be allocated manually with the special |
| 2785 // hash code in place. The hash code for the hidden_symbol is zero to ensure | 2785 // hash code in place. The hash code for the hidden_symbol is zero to ensure |
| 2786 // that it will always be at the first entry in property descriptors. | 2786 // that it will always be at the first entry in property descriptors. |
| 2787 { MaybeObject* maybe_obj = | 2787 { MaybeObject* maybe_obj = |
| 2788 AllocateSymbol(CStrVector(""), 0, String::kEmptyStringHash); | 2788 AllocateOneByteSymbol(OneByteVector("", 0), String::kEmptyStringHash); |
| 2789 if (!maybe_obj->ToObject(&obj)) return false; | 2789 if (!maybe_obj->ToObject(&obj)) return false; |
| 2790 } | 2790 } |
| 2791 hidden_symbol_ = String::cast(obj); | 2791 hidden_symbol_ = String::cast(obj); |
| 2792 | 2792 |
| 2793 // Allocate the foreign for __proto__. | 2793 // Allocate the foreign for __proto__. |
| 2794 { MaybeObject* maybe_obj = | 2794 { MaybeObject* maybe_obj = |
| 2795 AllocateForeign((Address) &Accessors::ObjectPrototype); | 2795 AllocateForeign((Address) &Accessors::ObjectPrototype); |
| 2796 if (!maybe_obj->ToObject(&obj)) return false; | 2796 if (!maybe_obj->ToObject(&obj)) return false; |
| 2797 } | 2797 } |
| 2798 set_prototype_accessors(Foreign::cast(obj)); | 2798 set_prototype_accessors(Foreign::cast(obj)); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2831 obj); | 2831 obj); |
| 2832 if (!maybe_obj->ToObject(&obj)) return false; | 2832 if (!maybe_obj->ToObject(&obj)) return false; |
| 2833 } | 2833 } |
| 2834 set_intrinsic_function_names(StringDictionary::cast(obj)); | 2834 set_intrinsic_function_names(StringDictionary::cast(obj)); |
| 2835 | 2835 |
| 2836 { MaybeObject* maybe_obj = AllocateInitialNumberStringCache(); | 2836 { MaybeObject* maybe_obj = AllocateInitialNumberStringCache(); |
| 2837 if (!maybe_obj->ToObject(&obj)) return false; | 2837 if (!maybe_obj->ToObject(&obj)) return false; |
| 2838 } | 2838 } |
| 2839 set_number_string_cache(FixedArray::cast(obj)); | 2839 set_number_string_cache(FixedArray::cast(obj)); |
| 2840 | 2840 |
| 2841 // Allocate cache for single character ASCII strings. | 2841 // Allocate cache for single character one byte strings. |
| 2842 { MaybeObject* maybe_obj = | 2842 { MaybeObject* maybe_obj = |
| 2843 AllocateFixedArray(String::kMaxAsciiCharCode + 1, TENURED); | 2843 AllocateFixedArray(String::kMaxOneByteCharCode + 1, TENURED); |
| 2844 if (!maybe_obj->ToObject(&obj)) return false; | 2844 if (!maybe_obj->ToObject(&obj)) return false; |
| 2845 } | 2845 } |
| 2846 set_single_character_string_cache(FixedArray::cast(obj)); | 2846 set_single_character_string_cache(FixedArray::cast(obj)); |
| 2847 | 2847 |
| 2848 // Allocate cache for string split. | 2848 // Allocate cache for string split. |
| 2849 { MaybeObject* maybe_obj = AllocateFixedArray( | 2849 { MaybeObject* maybe_obj = AllocateFixedArray( |
| 2850 RegExpResultsCache::kRegExpResultsCacheSize, TENURED); | 2850 RegExpResultsCache::kRegExpResultsCacheSize, TENURED); |
| 2851 if (!maybe_obj->ToObject(&obj)) return false; | 2851 if (!maybe_obj->ToObject(&obj)) return false; |
| 2852 } | 2852 } |
| 2853 set_string_split_cache(FixedArray::cast(obj)); | 2853 set_string_split_cache(FixedArray::cast(obj)); |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3302 uint16_t c1, | 3302 uint16_t c1, |
| 3303 uint16_t c2) { | 3303 uint16_t c2) { |
| 3304 String* symbol; | 3304 String* symbol; |
| 3305 // Numeric strings have a different hash algorithm not known by | 3305 // Numeric strings have a different hash algorithm not known by |
| 3306 // LookupTwoCharsSymbolIfExists, so we skip this step for such strings. | 3306 // LookupTwoCharsSymbolIfExists, so we skip this step for such strings. |
| 3307 if ((!Between(c1, '0', '9') || !Between(c2, '0', '9')) && | 3307 if ((!Between(c1, '0', '9') || !Between(c2, '0', '9')) && |
| 3308 heap->symbol_table()->LookupTwoCharsSymbolIfExists(c1, c2, &symbol)) { | 3308 heap->symbol_table()->LookupTwoCharsSymbolIfExists(c1, c2, &symbol)) { |
| 3309 return symbol; | 3309 return symbol; |
| 3310 // Now we know the length is 2, we might as well make use of that fact | 3310 // Now we know the length is 2, we might as well make use of that fact |
| 3311 // when building the new string. | 3311 // when building the new string. |
| 3312 } else if (static_cast<unsigned>(c1 | c2) <= String::kMaxAsciiCharCodeU) { | 3312 } else if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) { |
| 3313 // We can do this. | 3313 // We can do this. |
| 3314 ASSERT(IsPowerOf2(String::kMaxAsciiCharCodeU + 1)); // because of this. | 3314 ASSERT(IsPowerOf2(String::kMaxOneByteCharCodeU + 1)); // because of this. |
| 3315 Object* result; | 3315 Object* result; |
| 3316 { MaybeObject* maybe_result = heap->AllocateRawOneByteString(2); | 3316 { MaybeObject* maybe_result = heap->AllocateRawOneByteString(2); |
| 3317 if (!maybe_result->ToObject(&result)) return maybe_result; | 3317 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3318 } | 3318 } |
| 3319 char* dest = SeqOneByteString::cast(result)->GetChars(); | 3319 char* dest = SeqOneByteString::cast(result)->GetChars(); |
| 3320 dest[0] = static_cast<char>(c1); | 3320 dest[0] = static_cast<char>(c1); |
| 3321 dest[1] = static_cast<char>(c2); | 3321 dest[1] = static_cast<char>(c2); |
| 3322 return result; | 3322 return result; |
| 3323 } else { | 3323 } else { |
| 3324 Object* result; | 3324 Object* result; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3348 | 3348 |
| 3349 // Optimization for 2-byte strings often used as keys in a decompression | 3349 // Optimization for 2-byte strings often used as keys in a decompression |
| 3350 // dictionary. Check whether we already have the string in the symbol | 3350 // dictionary. Check whether we already have the string in the symbol |
| 3351 // table to prevent creation of many unneccesary strings. | 3351 // table to prevent creation of many unneccesary strings. |
| 3352 if (length == 2) { | 3352 if (length == 2) { |
| 3353 uint16_t c1 = first->Get(0); | 3353 uint16_t c1 = first->Get(0); |
| 3354 uint16_t c2 = second->Get(0); | 3354 uint16_t c2 = second->Get(0); |
| 3355 return MakeOrFindTwoCharacterString(this, c1, c2); | 3355 return MakeOrFindTwoCharacterString(this, c1, c2); |
| 3356 } | 3356 } |
| 3357 | 3357 |
| 3358 bool first_is_ascii = first->IsOneByteRepresentation(); | 3358 bool first_is_one_byte = first->IsOneByteRepresentation(); |
| 3359 bool second_is_ascii = second->IsOneByteRepresentation(); | 3359 bool second_is_one_byte = second->IsOneByteRepresentation(); |
| 3360 bool is_ascii = first_is_ascii && second_is_ascii; | 3360 bool is_one_byte = first_is_one_byte && second_is_one_byte; |
| 3361 | |
| 3362 // Make sure that an out of memory exception is thrown if the length | 3361 // Make sure that an out of memory exception is thrown if the length |
| 3363 // of the new cons string is too large. | 3362 // of the new cons string is too large. |
| 3364 if (length > String::kMaxLength || length < 0) { | 3363 if (length > String::kMaxLength || length < 0) { |
| 3365 isolate()->context()->mark_out_of_memory(); | 3364 isolate()->context()->mark_out_of_memory(); |
| 3366 return Failure::OutOfMemoryException(); | 3365 return Failure::OutOfMemoryException(); |
| 3367 } | 3366 } |
| 3368 | 3367 |
| 3369 bool is_ascii_data_in_two_byte_string = false; | 3368 bool is_ascii_data_in_two_byte_string = false; |
| 3370 if (!is_ascii) { | 3369 if (!is_one_byte) { |
| 3371 // At least one of the strings uses two-byte representation so we | 3370 // At least one of the strings uses two-byte representation so we |
| 3372 // can't use the fast case code for short ASCII strings below, but | 3371 // can't use the fast case code for short ASCII strings below, but |
| 3373 // we can try to save memory if all chars actually fit in ASCII. | 3372 // we can try to save memory if all chars actually fit in ASCII. |
| 3374 is_ascii_data_in_two_byte_string = | 3373 is_ascii_data_in_two_byte_string = |
| 3375 first->HasOnlyAsciiChars() && second->HasOnlyAsciiChars(); | 3374 first->HasOnlyAsciiChars() && second->HasOnlyAsciiChars(); |
| 3376 if (is_ascii_data_in_two_byte_string) { | 3375 if (is_ascii_data_in_two_byte_string) { |
| 3377 isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment(); | 3376 isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment(); |
| 3378 } | 3377 } |
| 3379 } | 3378 } |
| 3380 | 3379 |
| 3381 // If the resulting string is small make a flat string. | 3380 // If the resulting string is small make a flat string. |
| 3382 if (length < ConsString::kMinLength) { | 3381 if (length < ConsString::kMinLength) { |
| 3383 // Note that neither of the two inputs can be a slice because: | 3382 // Note that neither of the two inputs can be a slice because: |
| 3384 STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength); | 3383 STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength); |
| 3385 ASSERT(first->IsFlat()); | 3384 ASSERT(first->IsFlat()); |
| 3386 ASSERT(second->IsFlat()); | 3385 ASSERT(second->IsFlat()); |
| 3387 if (is_ascii) { | 3386 if (is_one_byte) { |
| 3388 Object* result; | 3387 Object* result; |
| 3389 { MaybeObject* maybe_result = AllocateRawOneByteString(length); | 3388 { MaybeObject* maybe_result = AllocateRawOneByteString(length); |
| 3390 if (!maybe_result->ToObject(&result)) return maybe_result; | 3389 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3391 } | 3390 } |
| 3392 // Copy the characters into the new object. | 3391 // Copy the characters into the new object. |
| 3393 char* dest = SeqOneByteString::cast(result)->GetChars(); | 3392 char* dest = SeqOneByteString::cast(result)->GetChars(); |
| 3394 // Copy first part. | 3393 // Copy first part. |
| 3395 const char* src; | 3394 const char* src; |
| 3396 if (first->IsExternalString()) { | 3395 if (first->IsExternalString()) { |
| 3397 src = ExternalAsciiString::cast(first)->GetChars(); | 3396 src = ExternalAsciiString::cast(first)->GetChars(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 3426 if (!maybe_result->ToObject(&result)) return maybe_result; | 3425 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3427 } | 3426 } |
| 3428 // Copy the characters into the new object. | 3427 // Copy the characters into the new object. |
| 3429 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); | 3428 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); |
| 3430 String::WriteToFlat(first, dest, 0, first_length); | 3429 String::WriteToFlat(first, dest, 0, first_length); |
| 3431 String::WriteToFlat(second, dest + first_length, 0, second_length); | 3430 String::WriteToFlat(second, dest + first_length, 0, second_length); |
| 3432 return result; | 3431 return result; |
| 3433 } | 3432 } |
| 3434 } | 3433 } |
| 3435 | 3434 |
| 3436 Map* map = (is_ascii || is_ascii_data_in_two_byte_string) ? | 3435 Map* map = (is_one_byte || is_ascii_data_in_two_byte_string) ? |
| 3437 cons_ascii_string_map() : cons_string_map(); | 3436 cons_ascii_string_map() : cons_string_map(); |
| 3438 | 3437 |
| 3439 Object* result; | 3438 Object* result; |
| 3440 { MaybeObject* maybe_result = Allocate(map, NEW_SPACE); | 3439 { MaybeObject* maybe_result = Allocate(map, NEW_SPACE); |
| 3441 if (!maybe_result->ToObject(&result)) return maybe_result; | 3440 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3442 } | 3441 } |
| 3443 | 3442 |
| 3444 AssertNoAllocation no_gc; | 3443 AssertNoAllocation no_gc; |
| 3445 ConsString* cons_string = ConsString::cast(result); | 3444 ConsString* cons_string = ConsString::cast(result); |
| 3446 WriteBarrierMode mode = cons_string->GetWriteBarrierMode(no_gc); | 3445 WriteBarrierMode mode = cons_string->GetWriteBarrierMode(no_gc); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3474 buffer = buffer->TryFlattenGetString(); | 3473 buffer = buffer->TryFlattenGetString(); |
| 3475 | 3474 |
| 3476 if (!FLAG_string_slices || | 3475 if (!FLAG_string_slices || |
| 3477 !buffer->IsFlat() || | 3476 !buffer->IsFlat() || |
| 3478 length < SlicedString::kMinLength || | 3477 length < SlicedString::kMinLength || |
| 3479 pretenure == TENURED) { | 3478 pretenure == TENURED) { |
| 3480 Object* result; | 3479 Object* result; |
| 3481 // WriteToFlat takes care of the case when an indirect string has a | 3480 // WriteToFlat takes care of the case when an indirect string has a |
| 3482 // different encoding from its underlying string. These encodings may | 3481 // different encoding from its underlying string. These encodings may |
| 3483 // differ because of externalization. | 3482 // differ because of externalization. |
| 3484 bool is_ascii = buffer->IsOneByteRepresentation(); | 3483 bool is_one_byte = buffer->IsOneByteRepresentation(); |
| 3485 { MaybeObject* maybe_result = is_ascii | 3484 { MaybeObject* maybe_result = is_one_byte |
| 3486 ? AllocateRawOneByteString(length, pretenure) | 3485 ? AllocateRawOneByteString(length, pretenure) |
| 3487 : AllocateRawTwoByteString(length, pretenure); | 3486 : AllocateRawTwoByteString(length, pretenure); |
| 3488 if (!maybe_result->ToObject(&result)) return maybe_result; | 3487 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3489 } | 3488 } |
| 3490 String* string_result = String::cast(result); | 3489 String* string_result = String::cast(result); |
| 3491 // Copy the characters into the new object. | 3490 // Copy the characters into the new object. |
| 3492 if (is_ascii) { | 3491 if (is_one_byte) { |
| 3493 ASSERT(string_result->IsOneByteRepresentation()); | 3492 ASSERT(string_result->IsOneByteRepresentation()); |
| 3494 char* dest = SeqOneByteString::cast(string_result)->GetChars(); | 3493 char* dest = SeqOneByteString::cast(string_result)->GetChars(); |
| 3495 String::WriteToFlat(buffer, dest, start, end); | 3494 String::WriteToFlat(buffer, dest, start, end); |
| 3496 } else { | 3495 } else { |
| 3497 ASSERT(string_result->IsTwoByteRepresentation()); | 3496 ASSERT(string_result->IsTwoByteRepresentation()); |
| 3498 uc16* dest = SeqTwoByteString::cast(string_result)->GetChars(); | 3497 uc16* dest = SeqTwoByteString::cast(string_result)->GetChars(); |
| 3499 String::WriteToFlat(buffer, dest, start, end); | 3498 String::WriteToFlat(buffer, dest, start, end); |
| 3500 } | 3499 } |
| 3501 return result; | 3500 return result; |
| 3502 } | 3501 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3573 | 3572 |
| 3574 MaybeObject* Heap::AllocateExternalStringFromTwoByte( | 3573 MaybeObject* Heap::AllocateExternalStringFromTwoByte( |
| 3575 const ExternalTwoByteString::Resource* resource) { | 3574 const ExternalTwoByteString::Resource* resource) { |
| 3576 size_t length = resource->length(); | 3575 size_t length = resource->length(); |
| 3577 if (length > static_cast<size_t>(String::kMaxLength)) { | 3576 if (length > static_cast<size_t>(String::kMaxLength)) { |
| 3578 isolate()->context()->mark_out_of_memory(); | 3577 isolate()->context()->mark_out_of_memory(); |
| 3579 return Failure::OutOfMemoryException(); | 3578 return Failure::OutOfMemoryException(); |
| 3580 } | 3579 } |
| 3581 | 3580 |
| 3582 // For small strings we check whether the resource contains only | 3581 // For small strings we check whether the resource contains only |
| 3583 // ASCII characters. If yes, we use a different string map. | 3582 // one byte characters. If yes, we use a different string map. |
| 3584 static const size_t kAsciiCheckLengthLimit = 32; | 3583 static const size_t kAsciiCheckLengthLimit = 32; |
| 3585 bool is_ascii = length <= kAsciiCheckLengthLimit && | 3584 bool is_one_byte = length <= kAsciiCheckLengthLimit && |
| 3586 String::IsAscii(resource->data(), static_cast<int>(length)); | 3585 String::IsOneByte(resource->data(), static_cast<int>(length)); |
| 3587 Map* map = is_ascii ? | 3586 Map* map = is_one_byte ? |
| 3588 external_string_with_ascii_data_map() : external_string_map(); | 3587 external_string_with_ascii_data_map() : external_string_map(); |
| 3589 Object* result; | 3588 Object* result; |
| 3590 { MaybeObject* maybe_result = Allocate(map, NEW_SPACE); | 3589 { MaybeObject* maybe_result = Allocate(map, NEW_SPACE); |
| 3591 if (!maybe_result->ToObject(&result)) return maybe_result; | 3590 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3592 } | 3591 } |
| 3593 | 3592 |
| 3594 ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result); | 3593 ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result); |
| 3595 external_string->set_length(static_cast<int>(length)); | 3594 external_string->set_length(static_cast<int>(length)); |
| 3596 external_string->set_hash_field(String::kEmptyHashField); | 3595 external_string->set_hash_field(String::kEmptyHashField); |
| 3597 external_string->set_resource(resource); | 3596 external_string->set_resource(resource); |
| 3598 | 3597 |
| 3599 return result; | 3598 return result; |
| 3600 } | 3599 } |
| 3601 | 3600 |
| 3602 | 3601 |
| 3603 MaybeObject* Heap::LookupSingleCharacterStringFromCode(uint16_t code) { | 3602 MaybeObject* Heap::LookupSingleCharacterStringFromCode(uint16_t code) { |
| 3604 if (code <= String::kMaxAsciiCharCode) { | 3603 if (code <= String::kMaxOneByteCharCode) { |
| 3605 Object* value = single_character_string_cache()->get(code); | 3604 Object* value = single_character_string_cache()->get(code); |
| 3606 if (value != undefined_value()) return value; | 3605 if (value != undefined_value()) return value; |
| 3607 | 3606 |
| 3608 char buffer[1]; | 3607 uint8_t buffer[1]; |
| 3609 buffer[0] = static_cast<char>(code); | 3608 buffer[0] = static_cast<uint8_t>(code); |
| 3610 Object* result; | 3609 Object* result; |
| 3611 MaybeObject* maybe_result = | 3610 MaybeObject* maybe_result = |
| 3612 LookupOneByteSymbol(Vector<const char>(buffer, 1)); | 3611 LookupOneByteSymbol(Vector<const uint8_t>(buffer, 1)); |
| 3613 | 3612 |
| 3614 if (!maybe_result->ToObject(&result)) return maybe_result; | 3613 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3615 single_character_string_cache()->set(code, result); | 3614 single_character_string_cache()->set(code, result); |
| 3616 return result; | 3615 return result; |
| 3617 } | 3616 } |
| 3618 | 3617 |
| 3619 Object* result; | 3618 Object* result; |
| 3620 { MaybeObject* maybe_result = AllocateRawTwoByteString(1); | 3619 { MaybeObject* maybe_result = AllocateRawTwoByteString(1); |
| 3621 if (!maybe_result->ToObject(&result)) return maybe_result; | 3620 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3622 } | 3621 } |
| (...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4513 | 4512 |
| 4514 // Reset the map for the object. | 4513 // Reset the map for the object. |
| 4515 object->set_map(constructor->initial_map()); | 4514 object->set_map(constructor->initial_map()); |
| 4516 | 4515 |
| 4517 // Reinitialize the object from the constructor map. | 4516 // Reinitialize the object from the constructor map. |
| 4518 InitializeJSObjectFromMap(object, FixedArray::cast(properties), map); | 4517 InitializeJSObjectFromMap(object, FixedArray::cast(properties), map); |
| 4519 return object; | 4518 return object; |
| 4520 } | 4519 } |
| 4521 | 4520 |
| 4522 | 4521 |
| 4523 MaybeObject* Heap::AllocateStringFromOneByte(Vector<const char> string, | 4522 MaybeObject* Heap::AllocateStringFromOneByte(Vector<const uint8_t> string, |
| 4524 PretenureFlag pretenure) { | 4523 PretenureFlag pretenure) { |
| 4525 int length = string.length(); | 4524 int length = string.length(); |
| 4526 if (length == 1) { | 4525 if (length == 1) { |
| 4527 return Heap::LookupSingleCharacterStringFromCode(string[0]); | 4526 return Heap::LookupSingleCharacterStringFromCode(string[0]); |
| 4528 } | 4527 } |
| 4529 Object* result; | 4528 Object* result; |
| 4530 { MaybeObject* maybe_result = | 4529 { MaybeObject* maybe_result = |
| 4531 AllocateRawOneByteString(string.length(), pretenure); | 4530 AllocateRawOneByteString(string.length(), pretenure); |
| 4532 if (!maybe_result->ToObject(&result)) return maybe_result; | 4531 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 4533 } | 4532 } |
| 4534 | 4533 |
| 4535 // Copy the characters into the new object. | 4534 // Copy the characters into the new object. |
| 4536 CopyChars(SeqOneByteString::cast(result)->GetChars(), string.start(), length); | 4535 CopyChars(SeqOneByteString::cast(result)->GetCharsU(), |
| 4536 string.start(), |
| 4537 length); |
| 4537 return result; | 4538 return result; |
| 4538 } | 4539 } |
| 4539 | 4540 |
| 4540 | 4541 |
| 4541 MaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string, | 4542 MaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string, |
| 4542 int non_ascii_start, | 4543 int non_ascii_start, |
| 4543 PretenureFlag pretenure) { | 4544 PretenureFlag pretenure) { |
| 4544 // Continue counting the number of characters in the UTF-8 string, starting | 4545 // Continue counting the number of characters in the UTF-8 string, starting |
| 4545 // from the first non-ascii character or word. | 4546 // from the first non-ascii character or word. |
| 4546 Access<UnicodeCache::Utf8Decoder> | 4547 Access<UnicodeCache::Utf8Decoder> |
| (...skipping 25 matching lines...) Expand all Loading... |
| 4572 } | 4573 } |
| 4573 | 4574 |
| 4574 | 4575 |
| 4575 MaybeObject* Heap::AllocateStringFromTwoByte(Vector<const uc16> string, | 4576 MaybeObject* Heap::AllocateStringFromTwoByte(Vector<const uc16> string, |
| 4576 PretenureFlag pretenure) { | 4577 PretenureFlag pretenure) { |
| 4577 // Check if the string is an ASCII string. | 4578 // Check if the string is an ASCII string. |
| 4578 Object* result; | 4579 Object* result; |
| 4579 int length = string.length(); | 4580 int length = string.length(); |
| 4580 const uc16* start = string.start(); | 4581 const uc16* start = string.start(); |
| 4581 | 4582 |
| 4582 if (String::IsAscii(start, length)) { | 4583 if (String::IsOneByte(start, length)) { |
| 4583 MaybeObject* maybe_result = AllocateRawOneByteString(length, pretenure); | 4584 MaybeObject* maybe_result = AllocateRawOneByteString(length, pretenure); |
| 4584 if (!maybe_result->ToObject(&result)) return maybe_result; | 4585 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 4585 CopyChars(SeqOneByteString::cast(result)->GetChars(), start, length); | 4586 CopyChars(SeqOneByteString::cast(result)->GetChars(), start, length); |
| 4586 } else { // It's not an ASCII string. | 4587 } else { // It's not a one byte string. |
| 4587 MaybeObject* maybe_result = AllocateRawTwoByteString(length, pretenure); | 4588 MaybeObject* maybe_result = AllocateRawTwoByteString(length, pretenure); |
| 4588 if (!maybe_result->ToObject(&result)) return maybe_result; | 4589 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 4589 CopyChars(SeqTwoByteString::cast(result)->GetChars(), start, length); | 4590 CopyChars(SeqTwoByteString::cast(result)->GetChars(), start, length); |
| 4590 } | 4591 } |
| 4591 return result; | 4592 return result; |
| 4592 } | 4593 } |
| 4593 | 4594 |
| 4594 | 4595 |
| 4595 Map* Heap::SymbolMapForString(String* string) { | 4596 Map* Heap::SymbolMapForString(String* string) { |
| 4596 // If the string is in new space it cannot be used as a symbol. | 4597 // If the string is in new space it cannot be used as a symbol. |
| (...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5621 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; | 5622 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; |
| 5622 } | 5623 } |
| 5623 // Can't use set_symbol_table because SymbolTable::cast knows that | 5624 // Can't use set_symbol_table because SymbolTable::cast knows that |
| 5624 // SymbolTable is a singleton and checks for identity. | 5625 // SymbolTable is a singleton and checks for identity. |
| 5625 roots_[kSymbolTableRootIndex] = new_table; | 5626 roots_[kSymbolTableRootIndex] = new_table; |
| 5626 ASSERT(symbol != NULL); | 5627 ASSERT(symbol != NULL); |
| 5627 return symbol; | 5628 return symbol; |
| 5628 } | 5629 } |
| 5629 | 5630 |
| 5630 | 5631 |
| 5631 MaybeObject* Heap::LookupOneByteSymbol(Vector<const char> string) { | 5632 MaybeObject* Heap::LookupOneByteSymbol(Vector<const uint8_t> string) { |
| 5632 Object* symbol = NULL; | 5633 Object* symbol = NULL; |
| 5633 Object* new_table; | 5634 Object* new_table; |
| 5634 { MaybeObject* maybe_new_table = | 5635 { MaybeObject* maybe_new_table = |
| 5635 symbol_table()->LookupOneByteSymbol(string, &symbol); | 5636 symbol_table()->LookupOneByteSymbol(string, &symbol); |
| 5636 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; | 5637 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; |
| 5637 } | 5638 } |
| 5638 // Can't use set_symbol_table because SymbolTable::cast knows that | 5639 // Can't use set_symbol_table because SymbolTable::cast knows that |
| 5639 // SymbolTable is a singleton and checks for identity. | 5640 // SymbolTable is a singleton and checks for identity. |
| 5640 roots_[kSymbolTableRootIndex] = new_table; | 5641 roots_[kSymbolTableRootIndex] = new_table; |
| 5641 ASSERT(symbol != NULL); | 5642 ASSERT(symbol != NULL); |
| (...skipping 1714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7356 static_cast<int>(object_sizes_last_time_[index])); | 7357 static_cast<int>(object_sizes_last_time_[index])); |
| 7357 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) | 7358 FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) |
| 7358 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 7359 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
| 7359 | 7360 |
| 7360 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 7361 memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
| 7361 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 7362 memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
| 7362 ClearObjectStats(); | 7363 ClearObjectStats(); |
| 7363 } | 7364 } |
| 7364 | 7365 |
| 7365 } } // namespace v8::internal | 7366 } } // namespace v8::internal |
| OLD | NEW |