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(); |
279 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); | 280 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); |
280 Handle<SeqOneByteString> result; | 281 Handle<SeqOneByteString> result; |
281 ASSIGN_RETURN_ON_EXCEPTION( | 282 ASSIGN_RETURN_ON_EXCEPTION( |
282 isolate(), | 283 isolate(), |
283 result, | 284 result, |
284 NewRawOneByteString(string.length(), pretenure), | 285 NewRawOneByteString(string.length(), pretenure), |
285 String); | 286 String); |
286 | 287 |
287 DisallowHeapAllocation no_gc; | 288 DisallowHeapAllocation no_gc; |
288 // Copy the characters into the new object. | 289 // Copy the characters into the new object. |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 *data++ = *ascii_data++; | 363 *data++ = *ascii_data++; |
363 } | 364 } |
364 // Now write the remainder. | 365 // Now write the remainder. |
365 decoder->WriteUtf16(data, utf16_length); | 366 decoder->WriteUtf16(data, utf16_length); |
366 return result; | 367 return result; |
367 } | 368 } |
368 | 369 |
369 MaybeHandle<String> Factory::NewStringFromTwoByte(const uc16* string, | 370 MaybeHandle<String> Factory::NewStringFromTwoByte(const uc16* string, |
370 int length, | 371 int length, |
371 PretenureFlag pretenure) { | 372 PretenureFlag pretenure) { |
| 373 if (length == 0) return empty_string(); |
372 if (String::IsOneByte(string, length)) { | 374 if (String::IsOneByte(string, length)) { |
373 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); | 375 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); |
374 Handle<SeqOneByteString> result; | 376 Handle<SeqOneByteString> result; |
375 ASSIGN_RETURN_ON_EXCEPTION( | 377 ASSIGN_RETURN_ON_EXCEPTION( |
376 isolate(), | 378 isolate(), |
377 result, | 379 result, |
378 NewRawOneByteString(length, pretenure), | 380 NewRawOneByteString(length, pretenure), |
379 String); | 381 String); |
380 CopyChars(result->GetChars(), string, length); | 382 CopyChars(result->GetChars(), string, length); |
381 return result; | 383 return result; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 | 448 |
447 Handle<String> Factory::NewInternalizedStringImpl( | 449 Handle<String> Factory::NewInternalizedStringImpl( |
448 Handle<String> string, int chars, uint32_t hash_field) { | 450 Handle<String> string, int chars, uint32_t hash_field) { |
449 CALL_HEAP_FUNCTION( | 451 CALL_HEAP_FUNCTION( |
450 isolate(), | 452 isolate(), |
451 isolate()->heap()->AllocateInternalizedStringImpl( | 453 isolate()->heap()->AllocateInternalizedStringImpl( |
452 *string, chars, hash_field), | 454 *string, chars, hash_field), |
453 String); | 455 String); |
454 } | 456 } |
455 | 457 |
| 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 |
456 | 483 |
457 MaybeHandle<Map> Factory::InternalizedStringMapForString( | 484 MaybeHandle<Map> Factory::InternalizedStringMapForString( |
458 Handle<String> string) { | 485 Handle<String> string) { |
459 // If the string is in new space it cannot be used as internalized. | 486 // If the string is in new space it cannot be used as internalized. |
460 if (isolate()->heap()->InNewSpace(*string)) return MaybeHandle<Map>(); | 487 if (isolate()->heap()->InNewSpace(*string)) return MaybeHandle<Map>(); |
461 | 488 |
462 // Find the corresponding internalized string map for strings. | 489 return GetInternalizedStringMap(this, string); |
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 } | |
480 } | 490 } |
481 | 491 |
| 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>); |
482 | 508 |
483 MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString( | 509 MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString( |
484 int length, PretenureFlag pretenure) { | 510 int length, PretenureFlag pretenure) { |
485 if (length > String::kMaxLength || length < 0) { | 511 if (length > String::kMaxLength || length < 0) { |
486 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqOneByteString); | 512 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqOneByteString); |
487 } | 513 } |
| 514 DCHECK(length > 0); // Use Factory::empty_string() instead. |
488 CALL_HEAP_FUNCTION( | 515 CALL_HEAP_FUNCTION( |
489 isolate(), | 516 isolate(), |
490 isolate()->heap()->AllocateRawOneByteString(length, pretenure), | 517 isolate()->heap()->AllocateRawOneByteString(length, pretenure), |
491 SeqOneByteString); | 518 SeqOneByteString); |
492 } | 519 } |
493 | 520 |
494 | 521 |
495 MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString( | 522 MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString( |
496 int length, PretenureFlag pretenure) { | 523 int length, PretenureFlag pretenure) { |
497 if (length > String::kMaxLength || length < 0) { | 524 if (length > String::kMaxLength || length < 0) { |
498 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqTwoByteString); | 525 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqTwoByteString); |
499 } | 526 } |
| 527 DCHECK(length > 0); // Use Factory::empty_string() instead. |
500 CALL_HEAP_FUNCTION( | 528 CALL_HEAP_FUNCTION( |
501 isolate(), | 529 isolate(), |
502 isolate()->heap()->AllocateRawTwoByteString(length, pretenure), | 530 isolate()->heap()->AllocateRawTwoByteString(length, pretenure), |
503 SeqTwoByteString); | 531 SeqTwoByteString); |
504 } | 532 } |
505 | 533 |
506 | 534 |
507 Handle<String> Factory::LookupSingleCharacterStringFromCode(uint32_t code) { | 535 Handle<String> Factory::LookupSingleCharacterStringFromCode(uint32_t code) { |
508 if (code <= String::kMaxOneByteCharCodeU) { | 536 if (code <= String::kMaxOneByteCharCodeU) { |
509 { | 537 { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 DisallowHeapAllocation pointer_stays_valid; | 606 DisallowHeapAllocation pointer_stays_valid; |
579 SinkChar* sink = result->GetChars(); | 607 SinkChar* sink = result->GetChars(); |
580 String::WriteToFlat(*first, sink, 0, first->length()); | 608 String::WriteToFlat(*first, sink, 0, first->length()); |
581 String::WriteToFlat(*second, sink + first->length(), 0, second->length()); | 609 String::WriteToFlat(*second, sink + first->length(), 0, second->length()); |
582 return result; | 610 return result; |
583 } | 611 } |
584 | 612 |
585 | 613 |
586 MaybeHandle<String> Factory::NewConsString(Handle<String> left, | 614 MaybeHandle<String> Factory::NewConsString(Handle<String> left, |
587 Handle<String> right) { | 615 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 } |
588 int left_length = left->length(); | 622 int left_length = left->length(); |
589 if (left_length == 0) return right; | 623 if (left_length == 0) return right; |
590 int right_length = right->length(); | 624 int right_length = right->length(); |
591 if (right_length == 0) return left; | 625 if (right_length == 0) return left; |
592 | 626 |
593 int length = left_length + right_length; | 627 int length = left_length + right_length; |
594 | 628 |
595 if (length == 2) { | 629 if (length == 2) { |
596 uint16_t c1 = left->Get(0); | 630 uint16_t c1 = left->Get(0); |
597 uint16_t c2 = right->Get(0); | 631 uint16_t c2 = right->Get(0); |
(...skipping 2171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2769 Handle<AccessorInfo> prototype = | 2803 Handle<AccessorInfo> prototype = |
2770 Accessors::FunctionPrototypeInfo(isolate(), rw_attribs); | 2804 Accessors::FunctionPrototypeInfo(isolate(), rw_attribs); |
2771 AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())), | 2805 AccessorConstantDescriptor d(Handle<Name>(Name::cast(prototype->name())), |
2772 prototype, rw_attribs); | 2806 prototype, rw_attribs); |
2773 map->AppendDescriptor(&d); | 2807 map->AppendDescriptor(&d); |
2774 } | 2808 } |
2775 } | 2809 } |
2776 | 2810 |
2777 } // namespace internal | 2811 } // namespace internal |
2778 } // namespace v8 | 2812 } // namespace v8 |
OLD | NEW |