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/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
9 #include "src/ast/ast.h" | 9 #include "src/ast/ast.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 | 269 |
270 template<class StringTableKey> | 270 template<class StringTableKey> |
271 Handle<String> Factory::InternalizeStringWithKey(StringTableKey* key) { | 271 Handle<String> Factory::InternalizeStringWithKey(StringTableKey* key) { |
272 return StringTable::LookupKey(isolate(), key); | 272 return StringTable::LookupKey(isolate(), key); |
273 } | 273 } |
274 | 274 |
275 | 275 |
276 MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string, | 276 MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string, |
277 PretenureFlag pretenure) { | 277 PretenureFlag pretenure) { |
278 int length = string.length(); | 278 int length = string.length(); |
279 if (length == 0) return empty_string(); | |
280 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); | 279 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); |
281 Handle<SeqOneByteString> result; | 280 Handle<SeqOneByteString> result; |
282 ASSIGN_RETURN_ON_EXCEPTION( | 281 ASSIGN_RETURN_ON_EXCEPTION( |
283 isolate(), | 282 isolate(), |
284 result, | 283 result, |
285 NewRawOneByteString(string.length(), pretenure), | 284 NewRawOneByteString(string.length(), pretenure), |
286 String); | 285 String); |
287 | 286 |
288 DisallowHeapAllocation no_gc; | 287 DisallowHeapAllocation no_gc; |
289 // Copy the characters into the new object. | 288 // Copy the characters into the new object. |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 *data++ = *ascii_data++; | 362 *data++ = *ascii_data++; |
364 } | 363 } |
365 // Now write the remainder. | 364 // Now write the remainder. |
366 decoder->WriteUtf16(data, utf16_length); | 365 decoder->WriteUtf16(data, utf16_length); |
367 return result; | 366 return result; |
368 } | 367 } |
369 | 368 |
370 MaybeHandle<String> Factory::NewStringFromTwoByte(const uc16* string, | 369 MaybeHandle<String> Factory::NewStringFromTwoByte(const uc16* string, |
371 int length, | 370 int length, |
372 PretenureFlag pretenure) { | 371 PretenureFlag pretenure) { |
373 if (length == 0) return empty_string(); | |
374 if (String::IsOneByte(string, length)) { | 372 if (String::IsOneByte(string, length)) { |
375 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); | 373 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); |
376 Handle<SeqOneByteString> result; | 374 Handle<SeqOneByteString> result; |
377 ASSIGN_RETURN_ON_EXCEPTION( | 375 ASSIGN_RETURN_ON_EXCEPTION( |
378 isolate(), | 376 isolate(), |
379 result, | 377 result, |
380 NewRawOneByteString(length, pretenure), | 378 NewRawOneByteString(length, pretenure), |
381 String); | 379 String); |
382 CopyChars(result->GetChars(), string, length); | 380 CopyChars(result->GetChars(), string, length); |
383 return result; | 381 return result; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 | 446 |
449 Handle<String> Factory::NewInternalizedStringImpl( | 447 Handle<String> Factory::NewInternalizedStringImpl( |
450 Handle<String> string, int chars, uint32_t hash_field) { | 448 Handle<String> string, int chars, uint32_t hash_field) { |
451 CALL_HEAP_FUNCTION( | 449 CALL_HEAP_FUNCTION( |
452 isolate(), | 450 isolate(), |
453 isolate()->heap()->AllocateInternalizedStringImpl( | 451 isolate()->heap()->AllocateInternalizedStringImpl( |
454 *string, chars, hash_field), | 452 *string, chars, hash_field), |
455 String); | 453 String); |
456 } | 454 } |
457 | 455 |
458 namespace { | |
459 | |
460 MaybeHandle<Map> GetInternalizedStringMap(Factory* f, Handle<String> string) { | |
461 switch (string->map()->instance_type()) { | |
462 case STRING_TYPE: | |
463 return f->internalized_string_map(); | |
464 case ONE_BYTE_STRING_TYPE: | |
465 return f->one_byte_internalized_string_map(); | |
466 case EXTERNAL_STRING_TYPE: | |
467 return f->external_internalized_string_map(); | |
468 case EXTERNAL_ONE_BYTE_STRING_TYPE: | |
469 return f->external_one_byte_internalized_string_map(); | |
470 case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: | |
471 return f->external_internalized_string_with_one_byte_data_map(); | |
472 case SHORT_EXTERNAL_STRING_TYPE: | |
473 return f->short_external_internalized_string_map(); | |
474 case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE: | |
475 return f->short_external_one_byte_internalized_string_map(); | |
476 case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: | |
477 return f->short_external_internalized_string_with_one_byte_data_map(); | |
478 default: return MaybeHandle<Map>(); // No match found. | |
479 } | |
480 } | |
481 | |
482 } // namespace | |
483 | 456 |
484 MaybeHandle<Map> Factory::InternalizedStringMapForString( | 457 MaybeHandle<Map> Factory::InternalizedStringMapForString( |
485 Handle<String> string) { | 458 Handle<String> string) { |
486 // If the string is in new space it cannot be used as internalized. | 459 // If the string is in new space it cannot be used as internalized. |
487 if (isolate()->heap()->InNewSpace(*string)) return MaybeHandle<Map>(); | 460 if (isolate()->heap()->InNewSpace(*string)) return MaybeHandle<Map>(); |
488 | 461 |
489 return GetInternalizedStringMap(this, string); | 462 // Find the corresponding internalized string map for strings. |
| 463 switch (string->map()->instance_type()) { |
| 464 case STRING_TYPE: return internalized_string_map(); |
| 465 case ONE_BYTE_STRING_TYPE: |
| 466 return one_byte_internalized_string_map(); |
| 467 case EXTERNAL_STRING_TYPE: return external_internalized_string_map(); |
| 468 case EXTERNAL_ONE_BYTE_STRING_TYPE: |
| 469 return external_one_byte_internalized_string_map(); |
| 470 case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: |
| 471 return external_internalized_string_with_one_byte_data_map(); |
| 472 case SHORT_EXTERNAL_STRING_TYPE: |
| 473 return short_external_internalized_string_map(); |
| 474 case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE: |
| 475 return short_external_one_byte_internalized_string_map(); |
| 476 case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: |
| 477 return short_external_internalized_string_with_one_byte_data_map(); |
| 478 default: return MaybeHandle<Map>(); // No match found. |
| 479 } |
490 } | 480 } |
491 | 481 |
492 template <class StringClass> | |
493 Handle<StringClass> Factory::InternalizeExternalString(Handle<String> string) { | |
494 Handle<StringClass> cast_string = Handle<StringClass>::cast(string); | |
495 Handle<Map> map = GetInternalizedStringMap(this, string).ToHandleChecked(); | |
496 Handle<StringClass> external_string = New<StringClass>(map, OLD_SPACE); | |
497 external_string->set_length(cast_string->length()); | |
498 external_string->set_hash_field(cast_string->hash_field()); | |
499 external_string->set_resource(nullptr); | |
500 isolate()->heap()->RegisterExternalString(*external_string); | |
501 return external_string; | |
502 } | |
503 | |
504 template Handle<ExternalOneByteString> | |
505 Factory::InternalizeExternalString<ExternalOneByteString>(Handle<String>); | |
506 template Handle<ExternalTwoByteString> | |
507 Factory::InternalizeExternalString<ExternalTwoByteString>(Handle<String>); | |
508 | 482 |
509 MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString( | 483 MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString( |
510 int length, PretenureFlag pretenure) { | 484 int length, PretenureFlag pretenure) { |
511 if (length > String::kMaxLength || length < 0) { | 485 if (length > String::kMaxLength || length < 0) { |
512 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqOneByteString); | 486 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqOneByteString); |
513 } | 487 } |
514 DCHECK(length > 0); // Use Factory::empty_string() instead. | |
515 CALL_HEAP_FUNCTION( | 488 CALL_HEAP_FUNCTION( |
516 isolate(), | 489 isolate(), |
517 isolate()->heap()->AllocateRawOneByteString(length, pretenure), | 490 isolate()->heap()->AllocateRawOneByteString(length, pretenure), |
518 SeqOneByteString); | 491 SeqOneByteString); |
519 } | 492 } |
520 | 493 |
521 | 494 |
522 MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString( | 495 MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString( |
523 int length, PretenureFlag pretenure) { | 496 int length, PretenureFlag pretenure) { |
524 if (length > String::kMaxLength || length < 0) { | 497 if (length > String::kMaxLength || length < 0) { |
525 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqTwoByteString); | 498 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqTwoByteString); |
526 } | 499 } |
527 DCHECK(length > 0); // Use Factory::empty_string() instead. | |
528 CALL_HEAP_FUNCTION( | 500 CALL_HEAP_FUNCTION( |
529 isolate(), | 501 isolate(), |
530 isolate()->heap()->AllocateRawTwoByteString(length, pretenure), | 502 isolate()->heap()->AllocateRawTwoByteString(length, pretenure), |
531 SeqTwoByteString); | 503 SeqTwoByteString); |
532 } | 504 } |
533 | 505 |
534 | 506 |
535 Handle<String> Factory::LookupSingleCharacterStringFromCode(uint32_t code) { | 507 Handle<String> Factory::LookupSingleCharacterStringFromCode(uint32_t code) { |
536 if (code <= String::kMaxOneByteCharCodeU) { | 508 if (code <= String::kMaxOneByteCharCodeU) { |
537 { | 509 { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 DisallowHeapAllocation pointer_stays_valid; | 578 DisallowHeapAllocation pointer_stays_valid; |
607 SinkChar* sink = result->GetChars(); | 579 SinkChar* sink = result->GetChars(); |
608 String::WriteToFlat(*first, sink, 0, first->length()); | 580 String::WriteToFlat(*first, sink, 0, first->length()); |
609 String::WriteToFlat(*second, sink + first->length(), 0, second->length()); | 581 String::WriteToFlat(*second, sink + first->length(), 0, second->length()); |
610 return result; | 582 return result; |
611 } | 583 } |
612 | 584 |
613 | 585 |
614 MaybeHandle<String> Factory::NewConsString(Handle<String> left, | 586 MaybeHandle<String> Factory::NewConsString(Handle<String> left, |
615 Handle<String> right) { | 587 Handle<String> right) { |
616 if (left->IsThinString()) { | |
617 left = handle(Handle<ThinString>::cast(left)->actual(), isolate()); | |
618 } | |
619 if (right->IsThinString()) { | |
620 right = handle(Handle<ThinString>::cast(right)->actual(), isolate()); | |
621 } | |
622 int left_length = left->length(); | 588 int left_length = left->length(); |
623 if (left_length == 0) return right; | 589 if (left_length == 0) return right; |
624 int right_length = right->length(); | 590 int right_length = right->length(); |
625 if (right_length == 0) return left; | 591 if (right_length == 0) return left; |
626 | 592 |
627 int length = left_length + right_length; | 593 int length = left_length + right_length; |
628 | 594 |
629 if (length == 2) { | 595 if (length == 2) { |
630 uint16_t c1 = left->Get(0); | 596 uint16_t c1 = left->Get(0); |
631 uint16_t c2 = right->Get(0); | 597 uint16_t c2 = right->Get(0); |
(...skipping 2198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2830 Handle<AccessorInfo> prototype = | 2796 Handle<AccessorInfo> prototype = |
2831 Accessors::FunctionPrototypeInfo(isolate(), rw_attribs); | 2797 Accessors::FunctionPrototypeInfo(isolate(), rw_attribs); |
2832 Descriptor d = Descriptor::AccessorConstant( | 2798 Descriptor d = Descriptor::AccessorConstant( |
2833 Handle<Name>(Name::cast(prototype->name())), prototype, rw_attribs); | 2799 Handle<Name>(Name::cast(prototype->name())), prototype, rw_attribs); |
2834 map->AppendDescriptor(&d); | 2800 map->AppendDescriptor(&d); |
2835 } | 2801 } |
2836 } | 2802 } |
2837 | 2803 |
2838 } // namespace internal | 2804 } // namespace internal |
2839 } // namespace v8 | 2805 } // namespace v8 |
OLD | NEW |