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