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