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 |