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