| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/factory.h" | 5 #include "src/factory.h" |
| 6 | 6 |
| 7 #include "src/allocation-site-scopes.h" | 7 #include "src/allocation-site-scopes.h" |
| 8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
| 9 #include "src/conversions.h" | 9 #include "src/conversions.h" |
| 10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 decoder->Reset(string.start() + non_ascii_start, | 241 decoder->Reset(string.start() + non_ascii_start, |
| 242 length - non_ascii_start); | 242 length - non_ascii_start); |
| 243 int utf16_length = decoder->Utf16Length(); | 243 int utf16_length = decoder->Utf16Length(); |
| 244 DCHECK(utf16_length > 0); | 244 DCHECK(utf16_length > 0); |
| 245 // Allocate string. | 245 // Allocate string. |
| 246 Handle<SeqTwoByteString> result; | 246 Handle<SeqTwoByteString> result; |
| 247 ASSIGN_RETURN_ON_EXCEPTION( | 247 ASSIGN_RETURN_ON_EXCEPTION( |
| 248 isolate(), result, | 248 isolate(), result, |
| 249 NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), | 249 NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), |
| 250 String); | 250 String); |
| 251 // Copy ascii portion. | 251 // Copy ASCII portion. |
| 252 uint16_t* data = result->GetChars(); | 252 uint16_t* data = result->GetChars(); |
| 253 const char* ascii_data = string.start(); | 253 const char* ascii_data = string.start(); |
| 254 for (int i = 0; i < non_ascii_start; i++) { | 254 for (int i = 0; i < non_ascii_start; i++) { |
| 255 *data++ = *ascii_data++; | 255 *data++ = *ascii_data++; |
| 256 } | 256 } |
| 257 // Now write the remainder. | 257 // Now write the remainder. |
| 258 decoder->WriteUtf16(data, utf16_length); | 258 decoder->WriteUtf16(data, utf16_length); |
| 259 return result; | 259 return result; |
| 260 } | 260 } |
| 261 | 261 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 | 340 |
| 341 | 341 |
| 342 MaybeHandle<Map> Factory::InternalizedStringMapForString( | 342 MaybeHandle<Map> Factory::InternalizedStringMapForString( |
| 343 Handle<String> string) { | 343 Handle<String> string) { |
| 344 // If the string is in new space it cannot be used as internalized. | 344 // If the string is in new space it cannot be used as internalized. |
| 345 if (isolate()->heap()->InNewSpace(*string)) return MaybeHandle<Map>(); | 345 if (isolate()->heap()->InNewSpace(*string)) return MaybeHandle<Map>(); |
| 346 | 346 |
| 347 // Find the corresponding internalized string map for strings. | 347 // Find the corresponding internalized string map for strings. |
| 348 switch (string->map()->instance_type()) { | 348 switch (string->map()->instance_type()) { |
| 349 case STRING_TYPE: return internalized_string_map(); | 349 case STRING_TYPE: return internalized_string_map(); |
| 350 case ASCII_STRING_TYPE: return ascii_internalized_string_map(); | 350 case ONE_BYTE_STRING_TYPE: |
| 351 return one_byte_internalized_string_map(); |
| 351 case EXTERNAL_STRING_TYPE: return external_internalized_string_map(); | 352 case EXTERNAL_STRING_TYPE: return external_internalized_string_map(); |
| 352 case EXTERNAL_ASCII_STRING_TYPE: | 353 case EXTERNAL_ONE_BYTE_STRING_TYPE: |
| 353 return external_ascii_internalized_string_map(); | 354 return external_one_byte_internalized_string_map(); |
| 354 case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: | 355 case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: |
| 355 return external_internalized_string_with_one_byte_data_map(); | 356 return external_internalized_string_with_one_byte_data_map(); |
| 356 case SHORT_EXTERNAL_STRING_TYPE: | 357 case SHORT_EXTERNAL_STRING_TYPE: |
| 357 return short_external_internalized_string_map(); | 358 return short_external_internalized_string_map(); |
| 358 case SHORT_EXTERNAL_ASCII_STRING_TYPE: | 359 case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE: |
| 359 return short_external_ascii_internalized_string_map(); | 360 return short_external_one_byte_internalized_string_map(); |
| 360 case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: | 361 case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: |
| 361 return short_external_internalized_string_with_one_byte_data_map(); | 362 return short_external_internalized_string_with_one_byte_data_map(); |
| 362 default: return MaybeHandle<Map>(); // No match found. | 363 default: return MaybeHandle<Map>(); // No match found. |
| 363 } | 364 } |
| 364 } | 365 } |
| 365 | 366 |
| 366 | 367 |
| 367 MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString( | 368 MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString( |
| 368 int length, PretenureFlag pretenure) { | 369 int length, PretenureFlag pretenure) { |
| 369 if (length > String::kMaxLength || length < 0) { | 370 if (length > String::kMaxLength || length < 0) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 if (length > String::kMaxLength || length < 0) { | 488 if (length > String::kMaxLength || length < 0) { |
| 488 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); | 489 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); |
| 489 } | 490 } |
| 490 | 491 |
| 491 bool left_is_one_byte = left->IsOneByteRepresentation(); | 492 bool left_is_one_byte = left->IsOneByteRepresentation(); |
| 492 bool right_is_one_byte = right->IsOneByteRepresentation(); | 493 bool right_is_one_byte = right->IsOneByteRepresentation(); |
| 493 bool is_one_byte = left_is_one_byte && right_is_one_byte; | 494 bool is_one_byte = left_is_one_byte && right_is_one_byte; |
| 494 bool is_one_byte_data_in_two_byte_string = false; | 495 bool is_one_byte_data_in_two_byte_string = false; |
| 495 if (!is_one_byte) { | 496 if (!is_one_byte) { |
| 496 // At least one of the strings uses two-byte representation so we | 497 // At least one of the strings uses two-byte representation so we |
| 497 // can't use the fast case code for short ASCII strings below, but | 498 // can't use the fast case code for short one-byte strings below, but |
| 498 // we can try to save memory if all chars actually fit in ASCII. | 499 // we can try to save memory if all chars actually fit in one-byte. |
| 499 is_one_byte_data_in_two_byte_string = | 500 is_one_byte_data_in_two_byte_string = |
| 500 left->HasOnlyOneByteChars() && right->HasOnlyOneByteChars(); | 501 left->HasOnlyOneByteChars() && right->HasOnlyOneByteChars(); |
| 501 if (is_one_byte_data_in_two_byte_string) { | 502 if (is_one_byte_data_in_two_byte_string) { |
| 502 isolate()->counters()->string_add_runtime_ext_to_ascii()->Increment(); | 503 isolate()->counters()->string_add_runtime_ext_to_one_byte()->Increment(); |
| 503 } | 504 } |
| 504 } | 505 } |
| 505 | 506 |
| 506 // If the resulting string is small make a flat string. | 507 // If the resulting string is small make a flat string. |
| 507 if (length < ConsString::kMinLength) { | 508 if (length < ConsString::kMinLength) { |
| 508 // Note that neither of the two inputs can be a slice because: | 509 // Note that neither of the two inputs can be a slice because: |
| 509 STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength); | 510 STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength); |
| 510 DCHECK(left->IsFlat()); | 511 DCHECK(left->IsFlat()); |
| 511 DCHECK(right->IsFlat()); | 512 DCHECK(right->IsFlat()); |
| 512 | 513 |
| 513 STATIC_ASSERT(ConsString::kMinLength <= String::kMaxLength); | 514 STATIC_ASSERT(ConsString::kMinLength <= String::kMaxLength); |
| 514 if (is_one_byte) { | 515 if (is_one_byte) { |
| 515 Handle<SeqOneByteString> result = | 516 Handle<SeqOneByteString> result = |
| 516 NewRawOneByteString(length).ToHandleChecked(); | 517 NewRawOneByteString(length).ToHandleChecked(); |
| 517 DisallowHeapAllocation no_gc; | 518 DisallowHeapAllocation no_gc; |
| 518 uint8_t* dest = result->GetChars(); | 519 uint8_t* dest = result->GetChars(); |
| 519 // Copy left part. | 520 // Copy left part. |
| 520 const uint8_t* src = left->IsExternalString() | 521 const uint8_t* src = |
| 521 ? Handle<ExternalAsciiString>::cast(left)->GetChars() | 522 left->IsExternalString() |
| 522 : Handle<SeqOneByteString>::cast(left)->GetChars(); | 523 ? Handle<ExternalOneByteString>::cast(left)->GetChars() |
| 524 : Handle<SeqOneByteString>::cast(left)->GetChars(); |
| 523 for (int i = 0; i < left_length; i++) *dest++ = src[i]; | 525 for (int i = 0; i < left_length; i++) *dest++ = src[i]; |
| 524 // Copy right part. | 526 // Copy right part. |
| 525 src = right->IsExternalString() | 527 src = right->IsExternalString() |
| 526 ? Handle<ExternalAsciiString>::cast(right)->GetChars() | 528 ? Handle<ExternalOneByteString>::cast(right)->GetChars() |
| 527 : Handle<SeqOneByteString>::cast(right)->GetChars(); | 529 : Handle<SeqOneByteString>::cast(right)->GetChars(); |
| 528 for (int i = 0; i < right_length; i++) *dest++ = src[i]; | 530 for (int i = 0; i < right_length; i++) *dest++ = src[i]; |
| 529 return result; | 531 return result; |
| 530 } | 532 } |
| 531 | 533 |
| 532 return (is_one_byte_data_in_two_byte_string) | 534 return (is_one_byte_data_in_two_byte_string) |
| 533 ? ConcatStringContent<uint8_t>( | 535 ? ConcatStringContent<uint8_t>( |
| 534 NewRawOneByteString(length).ToHandleChecked(), left, right) | 536 NewRawOneByteString(length).ToHandleChecked(), left, right) |
| 535 : ConcatStringContent<uc16>( | 537 : ConcatStringContent<uc16>( |
| 536 NewRawTwoByteString(length).ToHandleChecked(), left, right); | 538 NewRawTwoByteString(length).ToHandleChecked(), left, right); |
| 537 } | 539 } |
| 538 | 540 |
| 539 Handle<Map> map = (is_one_byte || is_one_byte_data_in_two_byte_string) | 541 Handle<Map> map = (is_one_byte || is_one_byte_data_in_two_byte_string) |
| 540 ? cons_ascii_string_map() : cons_string_map(); | 542 ? cons_one_byte_string_map() |
| 543 : cons_string_map(); |
| 541 Handle<ConsString> result = New<ConsString>(map, NEW_SPACE); | 544 Handle<ConsString> result = New<ConsString>(map, NEW_SPACE); |
| 542 | 545 |
| 543 DisallowHeapAllocation no_gc; | 546 DisallowHeapAllocation no_gc; |
| 544 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 547 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
| 545 | 548 |
| 546 result->set_hash_field(String::kEmptyHashField); | 549 result->set_hash_field(String::kEmptyHashField); |
| 547 result->set_length(length); | 550 result->set_length(length); |
| 548 result->set_first(*left, mode); | 551 result->set_first(*left, mode); |
| 549 result->set_second(*right, mode); | 552 result->set_second(*right, mode); |
| 550 return result; | 553 return result; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 | 598 |
| 596 int offset = begin; | 599 int offset = begin; |
| 597 | 600 |
| 598 if (str->IsSlicedString()) { | 601 if (str->IsSlicedString()) { |
| 599 Handle<SlicedString> slice = Handle<SlicedString>::cast(str); | 602 Handle<SlicedString> slice = Handle<SlicedString>::cast(str); |
| 600 str = Handle<String>(slice->parent(), isolate()); | 603 str = Handle<String>(slice->parent(), isolate()); |
| 601 offset += slice->offset(); | 604 offset += slice->offset(); |
| 602 } | 605 } |
| 603 | 606 |
| 604 DCHECK(str->IsSeqString() || str->IsExternalString()); | 607 DCHECK(str->IsSeqString() || str->IsExternalString()); |
| 605 Handle<Map> map = str->IsOneByteRepresentation() ? sliced_ascii_string_map() | 608 Handle<Map> map = str->IsOneByteRepresentation() |
| 606 : sliced_string_map(); | 609 ? sliced_one_byte_string_map() |
| 610 : sliced_string_map(); |
| 607 Handle<SlicedString> slice = New<SlicedString>(map, NEW_SPACE); | 611 Handle<SlicedString> slice = New<SlicedString>(map, NEW_SPACE); |
| 608 | 612 |
| 609 slice->set_hash_field(String::kEmptyHashField); | 613 slice->set_hash_field(String::kEmptyHashField); |
| 610 slice->set_length(length); | 614 slice->set_length(length); |
| 611 slice->set_parent(*str); | 615 slice->set_parent(*str); |
| 612 slice->set_offset(offset); | 616 slice->set_offset(offset); |
| 613 return slice; | 617 return slice; |
| 614 } | 618 } |
| 615 | 619 |
| 616 | 620 |
| 617 MaybeHandle<String> Factory::NewExternalStringFromAscii( | 621 MaybeHandle<String> Factory::NewExternalStringFromOneByte( |
| 618 const ExternalAsciiString::Resource* resource) { | 622 const ExternalOneByteString::Resource* resource) { |
| 619 size_t length = resource->length(); | 623 size_t length = resource->length(); |
| 620 if (length > static_cast<size_t>(String::kMaxLength)) { | 624 if (length > static_cast<size_t>(String::kMaxLength)) { |
| 621 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); | 625 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); |
| 622 } | 626 } |
| 623 | 627 |
| 624 Handle<Map> map = external_ascii_string_map(); | 628 Handle<Map> map = external_one_byte_string_map(); |
| 625 Handle<ExternalAsciiString> external_string = | 629 Handle<ExternalOneByteString> external_string = |
| 626 New<ExternalAsciiString>(map, NEW_SPACE); | 630 New<ExternalOneByteString>(map, NEW_SPACE); |
| 627 external_string->set_length(static_cast<int>(length)); | 631 external_string->set_length(static_cast<int>(length)); |
| 628 external_string->set_hash_field(String::kEmptyHashField); | 632 external_string->set_hash_field(String::kEmptyHashField); |
| 629 external_string->set_resource(resource); | 633 external_string->set_resource(resource); |
| 630 | 634 |
| 631 return external_string; | 635 return external_string; |
| 632 } | 636 } |
| 633 | 637 |
| 634 | 638 |
| 635 MaybeHandle<String> Factory::NewExternalStringFromTwoByte( | 639 MaybeHandle<String> Factory::NewExternalStringFromTwoByte( |
| 636 const ExternalTwoByteString::Resource* resource) { | 640 const ExternalTwoByteString::Resource* resource) { |
| (...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1793 | 1797 |
| 1794 map->set_prototype(proxy->map()->prototype()); | 1798 map->set_prototype(proxy->map()->prototype()); |
| 1795 | 1799 |
| 1796 // Allocate the backing storage for the properties. | 1800 // Allocate the backing storage for the properties. |
| 1797 int prop_size = map->InitialPropertiesLength(); | 1801 int prop_size = map->InitialPropertiesLength(); |
| 1798 Handle<FixedArray> properties = NewFixedArray(prop_size, TENURED); | 1802 Handle<FixedArray> properties = NewFixedArray(prop_size, TENURED); |
| 1799 | 1803 |
| 1800 Heap* heap = isolate()->heap(); | 1804 Heap* heap = isolate()->heap(); |
| 1801 MaybeHandle<SharedFunctionInfo> shared; | 1805 MaybeHandle<SharedFunctionInfo> shared; |
| 1802 if (type == JS_FUNCTION_TYPE) { | 1806 if (type == JS_FUNCTION_TYPE) { |
| 1803 OneByteStringKey key(STATIC_ASCII_VECTOR("<freezing call trap>"), | 1807 OneByteStringKey key(STATIC_CHAR_VECTOR("<freezing call trap>"), |
| 1804 heap->HashSeed()); | 1808 heap->HashSeed()); |
| 1805 Handle<String> name = InternalizeStringWithKey(&key); | 1809 Handle<String> name = InternalizeStringWithKey(&key); |
| 1806 shared = NewSharedFunctionInfo(name, MaybeHandle<Code>()); | 1810 shared = NewSharedFunctionInfo(name, MaybeHandle<Code>()); |
| 1807 } | 1811 } |
| 1808 | 1812 |
| 1809 // In order to keep heap in consistent state there must be no allocations | 1813 // In order to keep heap in consistent state there must be no allocations |
| 1810 // before object re-initialization is finished and filler object is installed. | 1814 // before object re-initialization is finished and filler object is installed. |
| 1811 DisallowHeapAllocation no_allocation; | 1815 DisallowHeapAllocation no_allocation; |
| 1812 | 1816 |
| 1813 // Put in filler if the new object is smaller than the old. | 1817 // Put in filler if the new object is smaller than the old. |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2347 void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp, | 2351 void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp, |
| 2348 JSRegExp::Type type, | 2352 JSRegExp::Type type, |
| 2349 Handle<String> source, | 2353 Handle<String> source, |
| 2350 JSRegExp::Flags flags, | 2354 JSRegExp::Flags flags, |
| 2351 int capture_count) { | 2355 int capture_count) { |
| 2352 Handle<FixedArray> store = NewFixedArray(JSRegExp::kIrregexpDataSize); | 2356 Handle<FixedArray> store = NewFixedArray(JSRegExp::kIrregexpDataSize); |
| 2353 Smi* uninitialized = Smi::FromInt(JSRegExp::kUninitializedValue); | 2357 Smi* uninitialized = Smi::FromInt(JSRegExp::kUninitializedValue); |
| 2354 store->set(JSRegExp::kTagIndex, Smi::FromInt(type)); | 2358 store->set(JSRegExp::kTagIndex, Smi::FromInt(type)); |
| 2355 store->set(JSRegExp::kSourceIndex, *source); | 2359 store->set(JSRegExp::kSourceIndex, *source); |
| 2356 store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags.value())); | 2360 store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags.value())); |
| 2357 store->set(JSRegExp::kIrregexpASCIICodeIndex, uninitialized); | 2361 store->set(JSRegExp::kIrregexpLatin1CodeIndex, uninitialized); |
| 2358 store->set(JSRegExp::kIrregexpUC16CodeIndex, uninitialized); | 2362 store->set(JSRegExp::kIrregexpUC16CodeIndex, uninitialized); |
| 2359 store->set(JSRegExp::kIrregexpASCIICodeSavedIndex, uninitialized); | 2363 store->set(JSRegExp::kIrregexpLatin1CodeSavedIndex, uninitialized); |
| 2360 store->set(JSRegExp::kIrregexpUC16CodeSavedIndex, uninitialized); | 2364 store->set(JSRegExp::kIrregexpUC16CodeSavedIndex, uninitialized); |
| 2361 store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::FromInt(0)); | 2365 store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::FromInt(0)); |
| 2362 store->set(JSRegExp::kIrregexpCaptureCountIndex, | 2366 store->set(JSRegExp::kIrregexpCaptureCountIndex, |
| 2363 Smi::FromInt(capture_count)); | 2367 Smi::FromInt(capture_count)); |
| 2364 regexp->set_data(*store); | 2368 regexp->set_data(*store); |
| 2365 } | 2369 } |
| 2366 | 2370 |
| 2367 | 2371 |
| 2368 | 2372 |
| 2369 MaybeHandle<FunctionTemplateInfo> Factory::ConfigureInstance( | 2373 MaybeHandle<FunctionTemplateInfo> Factory::ConfigureInstance( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2388 return Handle<Object>::null(); | 2392 return Handle<Object>::null(); |
| 2389 } | 2393 } |
| 2390 | 2394 |
| 2391 | 2395 |
| 2392 Handle<Object> Factory::ToBoolean(bool value) { | 2396 Handle<Object> Factory::ToBoolean(bool value) { |
| 2393 return value ? true_value() : false_value(); | 2397 return value ? true_value() : false_value(); |
| 2394 } | 2398 } |
| 2395 | 2399 |
| 2396 | 2400 |
| 2397 } } // namespace v8::internal | 2401 } } // namespace v8::internal |
| OLD | NEW |