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 |