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 3405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3416 bool first_is_one_byte = first->IsOneByteRepresentation(); | 3416 bool first_is_one_byte = first->IsOneByteRepresentation(); |
3417 bool second_is_one_byte = second->IsOneByteRepresentation(); | 3417 bool second_is_one_byte = second->IsOneByteRepresentation(); |
3418 bool is_one_byte = first_is_one_byte && second_is_one_byte; | 3418 bool is_one_byte = first_is_one_byte && second_is_one_byte; |
3419 // Make sure that an out of memory exception is thrown if the length | 3419 // Make sure that an out of memory exception is thrown if the length |
3420 // of the new cons string is too large. | 3420 // of the new cons string is too large. |
3421 if (length > String::kMaxLength || length < 0) { | 3421 if (length > String::kMaxLength || length < 0) { |
3422 isolate()->context()->mark_out_of_memory(); | 3422 isolate()->context()->mark_out_of_memory(); |
3423 return Failure::OutOfMemoryException(0x4); | 3423 return Failure::OutOfMemoryException(0x4); |
3424 } | 3424 } |
3425 | 3425 |
3426 bool is_ascii_data_in_two_byte_string = false; | 3426 bool is_one_byte_data_in_two_byte_string = false; |
3427 if (!is_one_byte) { | 3427 if (!is_one_byte) { |
3428 // At least one of the strings uses two-byte representation so we | 3428 // At least one of the strings uses two-byte representation so we |
3429 // can't use the fast case code for short ASCII strings below, but | 3429 // can't use the fast case code for short ASCII strings below, but |
3430 // we can try to save memory if all chars actually fit in ASCII. | 3430 // we can try to save memory if all chars actually fit in ASCII. |
3431 is_ascii_data_in_two_byte_string = | 3431 is_one_byte_data_in_two_byte_string = |
3432 first->HasOnlyAsciiChars() && second->HasOnlyAsciiChars(); | 3432 first->HasOnlyOneByteChars() && second->HasOnlyOneByteChars(); |
3433 if (is_ascii_data_in_two_byte_string) { | 3433 if (is_one_byte_data_in_two_byte_string) { |
3434 isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment(); | 3434 isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment(); |
3435 } | 3435 } |
3436 } | 3436 } |
3437 | 3437 |
3438 // If the resulting string is small make a flat string. | 3438 // If the resulting string is small make a flat string. |
3439 if (length < ConsString::kMinLength) { | 3439 if (length < ConsString::kMinLength) { |
3440 // Note that neither of the two inputs can be a slice because: | 3440 // Note that neither of the two inputs can be a slice because: |
3441 STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength); | 3441 STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength); |
3442 ASSERT(first->IsFlat()); | 3442 ASSERT(first->IsFlat()); |
3443 ASSERT(second->IsFlat()); | 3443 ASSERT(second->IsFlat()); |
(...skipping 14 matching lines...) Expand all Loading... |
3458 for (int i = 0; i < first_length; i++) *dest++ = src[i]; | 3458 for (int i = 0; i < first_length; i++) *dest++ = src[i]; |
3459 // Copy second part. | 3459 // Copy second part. |
3460 if (second->IsExternalString()) { | 3460 if (second->IsExternalString()) { |
3461 src = ExternalAsciiString::cast(second)->GetChars(); | 3461 src = ExternalAsciiString::cast(second)->GetChars(); |
3462 } else { | 3462 } else { |
3463 src = SeqOneByteString::cast(second)->GetChars(); | 3463 src = SeqOneByteString::cast(second)->GetChars(); |
3464 } | 3464 } |
3465 for (int i = 0; i < second_length; i++) *dest++ = src[i]; | 3465 for (int i = 0; i < second_length; i++) *dest++ = src[i]; |
3466 return result; | 3466 return result; |
3467 } else { | 3467 } else { |
3468 if (is_ascii_data_in_two_byte_string) { | 3468 if (is_one_byte_data_in_two_byte_string) { |
3469 Object* result; | 3469 Object* result; |
3470 { MaybeObject* maybe_result = AllocateRawOneByteString(length); | 3470 { MaybeObject* maybe_result = AllocateRawOneByteString(length); |
3471 if (!maybe_result->ToObject(&result)) return maybe_result; | 3471 if (!maybe_result->ToObject(&result)) return maybe_result; |
3472 } | 3472 } |
3473 // Copy the characters into the new object. | 3473 // Copy the characters into the new object. |
3474 uint8_t* dest = SeqOneByteString::cast(result)->GetChars(); | 3474 uint8_t* dest = SeqOneByteString::cast(result)->GetChars(); |
3475 String::WriteToFlat(first, dest, 0, first_length); | 3475 String::WriteToFlat(first, dest, 0, first_length); |
3476 String::WriteToFlat(second, dest + first_length, 0, second_length); | 3476 String::WriteToFlat(second, dest + first_length, 0, second_length); |
3477 isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment(); | 3477 isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment(); |
3478 return result; | 3478 return result; |
3479 } | 3479 } |
3480 | 3480 |
3481 Object* result; | 3481 Object* result; |
3482 { MaybeObject* maybe_result = AllocateRawTwoByteString(length); | 3482 { MaybeObject* maybe_result = AllocateRawTwoByteString(length); |
3483 if (!maybe_result->ToObject(&result)) return maybe_result; | 3483 if (!maybe_result->ToObject(&result)) return maybe_result; |
3484 } | 3484 } |
3485 // Copy the characters into the new object. | 3485 // Copy the characters into the new object. |
3486 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); | 3486 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); |
3487 String::WriteToFlat(first, dest, 0, first_length); | 3487 String::WriteToFlat(first, dest, 0, first_length); |
3488 String::WriteToFlat(second, dest + first_length, 0, second_length); | 3488 String::WriteToFlat(second, dest + first_length, 0, second_length); |
3489 return result; | 3489 return result; |
3490 } | 3490 } |
3491 } | 3491 } |
3492 | 3492 |
3493 Map* map = (is_one_byte || is_ascii_data_in_two_byte_string) ? | 3493 Map* map = (is_one_byte || is_one_byte_data_in_two_byte_string) ? |
3494 cons_ascii_string_map() : cons_string_map(); | 3494 cons_ascii_string_map() : cons_string_map(); |
3495 | 3495 |
3496 Object* result; | 3496 Object* result; |
3497 { MaybeObject* maybe_result = Allocate(map, NEW_SPACE); | 3497 { MaybeObject* maybe_result = Allocate(map, NEW_SPACE); |
3498 if (!maybe_result->ToObject(&result)) return maybe_result; | 3498 if (!maybe_result->ToObject(&result)) return maybe_result; |
3499 } | 3499 } |
3500 | 3500 |
3501 AssertNoAllocation no_gc; | 3501 AssertNoAllocation no_gc; |
3502 ConsString* cons_string = ConsString::cast(result); | 3502 ConsString* cons_string = ConsString::cast(result); |
3503 WriteBarrierMode mode = cons_string->GetWriteBarrierMode(no_gc); | 3503 WriteBarrierMode mode = cons_string->GetWriteBarrierMode(no_gc); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3629 MaybeObject* Heap::AllocateExternalStringFromTwoByte( | 3629 MaybeObject* Heap::AllocateExternalStringFromTwoByte( |
3630 const ExternalTwoByteString::Resource* resource) { | 3630 const ExternalTwoByteString::Resource* resource) { |
3631 size_t length = resource->length(); | 3631 size_t length = resource->length(); |
3632 if (length > static_cast<size_t>(String::kMaxLength)) { | 3632 if (length > static_cast<size_t>(String::kMaxLength)) { |
3633 isolate()->context()->mark_out_of_memory(); | 3633 isolate()->context()->mark_out_of_memory(); |
3634 return Failure::OutOfMemoryException(0x6); | 3634 return Failure::OutOfMemoryException(0x6); |
3635 } | 3635 } |
3636 | 3636 |
3637 // For small strings we check whether the resource contains only | 3637 // For small strings we check whether the resource contains only |
3638 // one byte characters. If yes, we use a different string map. | 3638 // one byte characters. If yes, we use a different string map. |
3639 static const size_t kAsciiCheckLengthLimit = 32; | 3639 static const size_t kOneByteCheckLengthLimit = 32; |
3640 bool is_one_byte = length <= kAsciiCheckLengthLimit && | 3640 bool is_one_byte = length <= kOneByteCheckLengthLimit && |
3641 String::IsOneByte(resource->data(), static_cast<int>(length)); | 3641 String::IsOneByte(resource->data(), static_cast<int>(length)); |
3642 Map* map = is_one_byte ? | 3642 Map* map = is_one_byte ? |
3643 external_string_with_ascii_data_map() : external_string_map(); | 3643 external_string_with_one_byte_data_map() : external_string_map(); |
3644 Object* result; | 3644 Object* result; |
3645 { MaybeObject* maybe_result = Allocate(map, NEW_SPACE); | 3645 { MaybeObject* maybe_result = Allocate(map, NEW_SPACE); |
3646 if (!maybe_result->ToObject(&result)) return maybe_result; | 3646 if (!maybe_result->ToObject(&result)) return maybe_result; |
3647 } | 3647 } |
3648 | 3648 |
3649 ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result); | 3649 ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result); |
3650 external_string->set_length(static_cast<int>(length)); | 3650 external_string->set_length(static_cast<int>(length)); |
3651 external_string->set_hash_field(String::kEmptyHashField); | 3651 external_string->set_hash_field(String::kEmptyHashField); |
3652 external_string->set_resource(resource); | 3652 external_string->set_resource(resource); |
3653 | 3653 |
(...skipping 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4969 | 4969 |
4970 // Find the corresponding internalized string map for strings. | 4970 // Find the corresponding internalized string map for strings. |
4971 switch (string->map()->instance_type()) { | 4971 switch (string->map()->instance_type()) { |
4972 case STRING_TYPE: return internalized_string_map(); | 4972 case STRING_TYPE: return internalized_string_map(); |
4973 case ASCII_STRING_TYPE: return ascii_internalized_string_map(); | 4973 case ASCII_STRING_TYPE: return ascii_internalized_string_map(); |
4974 case CONS_STRING_TYPE: return cons_internalized_string_map(); | 4974 case CONS_STRING_TYPE: return cons_internalized_string_map(); |
4975 case CONS_ASCII_STRING_TYPE: return cons_ascii_internalized_string_map(); | 4975 case CONS_ASCII_STRING_TYPE: return cons_ascii_internalized_string_map(); |
4976 case EXTERNAL_STRING_TYPE: return external_internalized_string_map(); | 4976 case EXTERNAL_STRING_TYPE: return external_internalized_string_map(); |
4977 case EXTERNAL_ASCII_STRING_TYPE: | 4977 case EXTERNAL_ASCII_STRING_TYPE: |
4978 return external_ascii_internalized_string_map(); | 4978 return external_ascii_internalized_string_map(); |
4979 case EXTERNAL_STRING_WITH_ASCII_DATA_TYPE: | 4979 case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: |
4980 return external_internalized_string_with_ascii_data_map(); | 4980 return external_internalized_string_with_one_byte_data_map(); |
4981 case SHORT_EXTERNAL_STRING_TYPE: | 4981 case SHORT_EXTERNAL_STRING_TYPE: |
4982 return short_external_internalized_string_map(); | 4982 return short_external_internalized_string_map(); |
4983 case SHORT_EXTERNAL_ASCII_STRING_TYPE: | 4983 case SHORT_EXTERNAL_ASCII_STRING_TYPE: |
4984 return short_external_ascii_internalized_string_map(); | 4984 return short_external_ascii_internalized_string_map(); |
4985 case SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE: | 4985 case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: |
4986 return short_external_internalized_string_with_ascii_data_map(); | 4986 return short_external_internalized_string_with_one_byte_data_map(); |
4987 default: return NULL; // No match found. | 4987 default: return NULL; // No match found. |
4988 } | 4988 } |
4989 } | 4989 } |
4990 | 4990 |
4991 | 4991 |
4992 static inline void WriteOneByteData(Vector<const char> vector, | 4992 static inline void WriteOneByteData(Vector<const char> vector, |
4993 uint8_t* chars, | 4993 uint8_t* chars, |
4994 int len) { | 4994 int len) { |
4995 // Only works for ascii. | 4995 // Only works for ascii. |
4996 ASSERT(vector.length() == len); | 4996 ASSERT(vector.length() == len); |
(...skipping 2883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7880 if (FLAG_parallel_recompilation) { | 7880 if (FLAG_parallel_recompilation) { |
7881 heap_->relocation_mutex_->Lock(); | 7881 heap_->relocation_mutex_->Lock(); |
7882 #ifdef DEBUG | 7882 #ifdef DEBUG |
7883 heap_->relocation_mutex_locked_by_optimizer_thread_ = | 7883 heap_->relocation_mutex_locked_by_optimizer_thread_ = |
7884 heap_->isolate()->optimizing_compiler_thread()->IsOptimizerThread(); | 7884 heap_->isolate()->optimizing_compiler_thread()->IsOptimizerThread(); |
7885 #endif // DEBUG | 7885 #endif // DEBUG |
7886 } | 7886 } |
7887 } | 7887 } |
7888 | 7888 |
7889 } } // namespace v8::internal | 7889 } } // namespace v8::internal |
OLD | NEW |