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 3 // found in the LICENSE file. 4 5 #include "src/factory.h" 6 7 #include "src/conversions.h" 8 #include "src/isolate-inl.h" 9 #include "src/macro-assembler.h" 10 11 namespace v8 { 12 namespace internal { 13 14 15 template<typename T> 16 Handle<T> Factory::New(Handle<Map> map, AllocationSpace space) { 17 CALL_HEAP_FUNCTION( 18 isolate(), 19 isolate()->heap()->Allocate(*map, space), 20 T); 21 } 22 23 24 template<typename T> 25 Handle<T> Factory::New(Handle<Map> map, 26 AllocationSpace space, 27 Handle<AllocationSite> allocation_site) { 28 CALL_HEAP_FUNCTION( 29 isolate(), 30 isolate()->heap()->Allocate(*map, space, *allocation_site), 31 T); 32 } 33 34 35 Handle<HeapObject> Factory::NewFillerObject(int size, 36 bool double_align, 37 AllocationSpace space) { 38 CALL_HEAP_FUNCTION( 39 isolate(), 40 isolate()->heap()->AllocateFillerObject(size, double_align, space), 41 HeapObject); 42 } 43 44 45 Handle<Box> Factory::NewBox(Handle<Object> value) { 46 Handle<Box> result = Handle<Box>::cast(NewStruct(BOX_TYPE)); 47 result->set_value(*value); 48 return result; 49 } 50 51 52 Handle<Oddball> Factory::NewOddball(Handle<Map> map, 53 const char* to_string, 54 Handle<Object> to_number, 55 byte kind) { 56 Handle<Oddball> oddball = New<Oddball>(map, OLD_POINTER_SPACE); 57 Oddball::Initialize(isolate(), oddball, to_string, to_number, kind); 58 return oddball; 59 } 60 61 62 Handle<FixedArray> Factory::NewFixedArray(int size, PretenureFlag pretenure) { 63 ASSERT(0 <= size); 64 CALL_HEAP_FUNCTION( 65 isolate(), 66 isolate()->heap()->AllocateFixedArray(size, pretenure), 67 FixedArray); 68 } 69 70 71 Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size, 72 PretenureFlag pretenure) { 73 ASSERT(0 <= size); 74 CALL_HEAP_FUNCTION( 75 isolate(), 76 isolate()->heap()->AllocateFixedArrayWithFiller(size, 77 pretenure, 78 *the_hole_value()), 79 FixedArray); 80 } 81 82 83 Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) { 84 CALL_HEAP_FUNCTION( 85 isolate(), 86 isolate()->heap()->AllocateUninitializedFixedArray(size), 87 FixedArray); 88 } 89 90 91 Handle<FixedArrayBase> Factory::NewFixedDoubleArray(int size, 92 PretenureFlag pretenure) { 93 ASSERT(0 <= size); 94 CALL_HEAP_FUNCTION( 95 isolate(), 96 isolate()->heap()->AllocateUninitializedFixedDoubleArray(size, pretenure), 97 FixedArrayBase); 98 } 99 100 101 Handle<FixedArrayBase> Factory::NewFixedDoubleArrayWithHoles( 102 int size, 103 PretenureFlag pretenure) { 104 ASSERT(0 <= size); 105 Handle<FixedArrayBase> array = NewFixedDoubleArray(size, pretenure); 106 if (size > 0) { 107 Handle<FixedDoubleArray> double_array = 108 Handle<FixedDoubleArray>::cast(array); 109 for (int i = 0; i < size; ++i) { 110 double_array->set_the_hole(i); 111 } 112 } 113 return array; 114 } 115 116 117 Handle<ConstantPoolArray> Factory::NewConstantPoolArray( 118 const ConstantPoolArray::NumberOfEntries& small) { 119 ASSERT(small.total_count() > 0); 120 CALL_HEAP_FUNCTION( 121 isolate(), 122 isolate()->heap()->AllocateConstantPoolArray(small), 123 ConstantPoolArray); 124 } 125 126 127 Handle<ConstantPoolArray> Factory::NewExtendedConstantPoolArray( 128 const ConstantPoolArray::NumberOfEntries& small, 129 const ConstantPoolArray::NumberOfEntries& extended) { 130 ASSERT(small.total_count() > 0); 131 ASSERT(extended.total_count() > 0); 132 CALL_HEAP_FUNCTION( 133 isolate(), 134 isolate()->heap()->AllocateExtendedConstantPoolArray(small, extended), 135 ConstantPoolArray); 136 } 137 138 139 Handle<OrderedHashSet> Factory::NewOrderedHashSet() { 140 return OrderedHashSet::Allocate(isolate(), 4); 141 } 142 143 144 Handle<OrderedHashMap> Factory::NewOrderedHashMap() { 145 return OrderedHashMap::Allocate(isolate(), 4); 146 } 147 148 149 Handle<AccessorPair> Factory::NewAccessorPair() { 150 Handle<AccessorPair> accessors = 151 Handle<AccessorPair>::cast(NewStruct(ACCESSOR_PAIR_TYPE)); 152 accessors->set_getter(*the_hole_value(), SKIP_WRITE_BARRIER); 153 accessors->set_setter(*the_hole_value(), SKIP_WRITE_BARRIER); 154 accessors->set_access_flags(Smi::FromInt(0), SKIP_WRITE_BARRIER); 155 return accessors; 156 } 157 158 159 Handle<TypeFeedbackInfo> Factory::NewTypeFeedbackInfo() { 160 Handle<TypeFeedbackInfo> info = 161 Handle<TypeFeedbackInfo>::cast(NewStruct(TYPE_FEEDBACK_INFO_TYPE)); 162 info->initialize_storage(); 163 return info; 164 } 165 166 167 // Internalized strings are created in the old generation (data space). 168 Handle<String> Factory::InternalizeUtf8String(Vector<const char> string) { 169 Utf8StringKey key(string, isolate()->heap()->HashSeed()); 170 return InternalizeStringWithKey(&key); 171 } 172 173 174 // Internalized strings are created in the old generation (data space). 175 Handle<String> Factory::InternalizeString(Handle<String> string) { 176 if (string->IsInternalizedString()) return string; 177 return StringTable::LookupString(isolate(), string); 178 } 179 180 181 Handle<String> Factory::InternalizeOneByteString(Vector<const uint8_t> string) { 182 OneByteStringKey key(string, isolate()->heap()->HashSeed()); 183 return InternalizeStringWithKey(&key); 184 } 185 186 187 Handle<String> Factory::InternalizeOneByteString( 188 Handle<SeqOneByteString> string, int from, int length) { 189 SubStringKey<uint8_t> key(string, from, length); 190 return InternalizeStringWithKey(&key); 191 } 192 193 194 Handle<String> Factory::InternalizeTwoByteString(Vector<const uc16> string) { 195 TwoByteStringKey key(string, isolate()->heap()->HashSeed()); 196 return InternalizeStringWithKey(&key); 197 } 198 199 200 template<class StringTableKey> 201 Handle<String> Factory::InternalizeStringWithKey(StringTableKey* key) { 202 return StringTable::LookupKey(isolate(), key); 203 } 204 205 206 template Handle<String> Factory::InternalizeStringWithKey< 207 SubStringKey<uint8_t> > (SubStringKey<uint8_t>* key); 208 template Handle<String> Factory::InternalizeStringWithKey< 209 SubStringKey<uint16_t> > (SubStringKey<uint16_t>* key); 210 211 212 MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string, 213 PretenureFlag pretenure) { 214 int length = string.length(); 215 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); 216 Handle<SeqOneByteString> result; 217 ASSIGN_RETURN_ON_EXCEPTION( 218 isolate(), 219 result, 220 NewRawOneByteString(string.length(), pretenure), 221 String); 222 223 DisallowHeapAllocation no_gc; 224 // Copy the characters into the new object. 225 CopyChars(SeqOneByteString::cast(*result)->GetChars(), 226 string.start(), 227 length); 228 return result; 229 } 230 231 MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string, 232 PretenureFlag pretenure) { 233 // Check for ASCII first since this is the common case. 234 const char* start = string.start(); 235 int length = string.length(); 236 int non_ascii_start = String::NonAsciiStart(start, length); 237 if (non_ascii_start >= length) { 238 // If the string is ASCII, we do not need to convert the characters 239 // since UTF8 is backwards compatible with ASCII. 240 return NewStringFromOneByte(Vector<const uint8_t>::cast(string), pretenure); 241 } 242 243 // Non-ASCII and we need to decode. 244 Access<UnicodeCache::Utf8Decoder> 245 decoder(isolate()->unicode_cache()->utf8_decoder()); 246 decoder->Reset(string.start() + non_ascii_start, 247 length - non_ascii_start); 248 int utf16_length = decoder->Utf16Length(); 249 ASSERT(utf16_length > 0); 250 // Allocate string. 251 Handle<SeqTwoByteString> result; 252 ASSIGN_RETURN_ON_EXCEPTION( 253 isolate(), result, 254 NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), 255 String); 256 // Copy ascii portion. 257 uint16_t* data = result->GetChars(); 258 const char* ascii_data = string.start(); 259 for (int i = 0; i < non_ascii_start; i++) { 260 *data++ = *ascii_data++; 261 } 262 // Now write the remainder. 263 decoder->WriteUtf16(data, utf16_length); 264 return result; 265 } 266 267 268 MaybeHandle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string, 269 PretenureFlag pretenure) { 270 int length = string.length(); 271 const uc16* start = string.start(); 272 if (String::IsOneByte(start, length)) { 273 Handle<SeqOneByteString> result; 274 ASSIGN_RETURN_ON_EXCEPTION( 275 isolate(), 276 result, 277 NewRawOneByteString(length, pretenure), 278 String); 279 CopyChars(result->GetChars(), start, length); 280 return result; 281 } else { 282 Handle<SeqTwoByteString> result; 283 ASSIGN_RETURN_ON_EXCEPTION( 284 isolate(), 285 result, 286 NewRawTwoByteString(length, pretenure), 287 String); 288 CopyChars(result->GetChars(), start, length); 289 return result; 290 } 291 } 292 293 294 Handle<String> Factory::NewInternalizedStringFromUtf8(Vector<const char> str, 295 int chars, 296 uint32_t hash_field) { 297 CALL_HEAP_FUNCTION( 298 isolate(), 299 isolate()->heap()->AllocateInternalizedStringFromUtf8( 300 str, chars, hash_field), 301 String); 302 } 303 304 305 MUST_USE_RESULT Handle<String> Factory::NewOneByteInternalizedString( 306 Vector<const uint8_t> str, 307 uint32_t hash_field) { 308 CALL_HEAP_FUNCTION( 309 isolate(), 310 isolate()->heap()->AllocateOneByteInternalizedString(str, hash_field), 311 String); 312 } 313 314 315 MUST_USE_RESULT Handle<String> Factory::NewTwoByteInternalizedString( 316 Vector<const uc16> str, 317 uint32_t hash_field) { 318 CALL_HEAP_FUNCTION( 319 isolate(), 320 isolate()->heap()->AllocateTwoByteInternalizedString(str, hash_field), 321 String); 322 } 323 324 325 Handle<String> Factory::NewInternalizedStringImpl( 326 Handle<String> string, int chars, uint32_t hash_field) { 327 CALL_HEAP_FUNCTION( 328 isolate(), 329 isolate()->heap()->AllocateInternalizedStringImpl( 330 *string, chars, hash_field), 331 String); 332 } 333 334 335 MaybeHandle<Map> Factory::InternalizedStringMapForString( 336 Handle<String> string) { 337 // If the string is in new space it cannot be used as internalized. 338 if (isolate()->heap()->InNewSpace(*string)) return MaybeHandle<Map>(); 339 340 // Find the corresponding internalized string map for strings. 341 switch (string->map()->instance_type()) { 342 case STRING_TYPE: return internalized_string_map(); 343 case ASCII_STRING_TYPE: return ascii_internalized_string_map(); 344 case EXTERNAL_STRING_TYPE: return external_internalized_string_map(); 345 case EXTERNAL_ASCII_STRING_TYPE: 346 return external_ascii_internalized_string_map(); 347 case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: 348 return external_internalized_string_with_one_byte_data_map(); 349 case SHORT_EXTERNAL_STRING_TYPE: 350 return short_external_internalized_string_map(); 351 case SHORT_EXTERNAL_ASCII_STRING_TYPE: 352 return short_external_ascii_internalized_string_map(); 353 case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: 354 return short_external_internalized_string_with_one_byte_data_map(); 355 default: return MaybeHandle<Map>(); // No match found. 356 } 357 } 358 359 360 MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString( 361 int length, PretenureFlag pretenure) { 362 if (length > String::kMaxLength || length < 0) { 363 return isolate()->Throw<SeqOneByteString>(NewInvalidStringLengthError()); 364 } 365 CALL_HEAP_FUNCTION( 366 isolate(), 367 isolate()->heap()->AllocateRawOneByteString(length, pretenure), 368 SeqOneByteString); 369 } 370 371 372 MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString( 373 int length, PretenureFlag pretenure) { 374 if (length > String::kMaxLength || length < 0) { 375 return isolate()->Throw<SeqTwoByteString>(NewInvalidStringLengthError()); 376 } 377 CALL_HEAP_FUNCTION( 378 isolate(), 379 isolate()->heap()->AllocateRawTwoByteString(length, pretenure), 380 SeqTwoByteString); 381 } 382 383 384 Handle<String> Factory::LookupSingleCharacterStringFromCode(uint32_t code) { 385 if (code <= String::kMaxOneByteCharCodeU) { 386 { 387 DisallowHeapAllocation no_allocation; 388 Object* value = single_character_string_cache()->get(code); 389 if (value != *undefined_value()) { 390 return handle(String::cast(value), isolate()); 391 } 392 } 393 uint8_t buffer[1]; 394 buffer[0] = static_cast<uint8_t>(code); 395 Handle<String> result = 396 InternalizeOneByteString(Vector<const uint8_t>(buffer, 1)); 397 single_character_string_cache()->set(code, *result); 398 return result; 399 } 400 ASSERT(code <= String::kMaxUtf16CodeUnitU); 401 402 Handle<SeqTwoByteString> result = NewRawTwoByteString(1).ToHandleChecked(); 403 result->SeqTwoByteStringSet(0, static_cast<uint16_t>(code)); 404 return result; 405 } 406 407 408 // Returns true for a character in a range. Both limits are inclusive. 409 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) { 410 // This makes uses of the the unsigned wraparound. 411 return character - from <= to - from; 412 } 413 414 415 static inline Handle<String> MakeOrFindTwoCharacterString(Isolate* isolate, 416 uint16_t c1, 417 uint16_t c2) { 418 // Numeric strings have a different hash algorithm not known by 419 // LookupTwoCharsStringIfExists, so we skip this step for such strings. 420 if (!Between(c1, '0', '9') || !Between(c2, '0', '9')) { 421 Handle<String> result; 422 if (StringTable::LookupTwoCharsStringIfExists(isolate, c1, c2). 423 ToHandle(&result)) { 424 return result; 425 } 426 } 427 428 // Now we know the length is 2, we might as well make use of that fact 429 // when building the new string. 430 if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) { 431 // We can do this. 432 ASSERT(IsPowerOf2(String::kMaxOneByteCharCodeU + 1)); // because of this. 433 Handle<SeqOneByteString> str = 434 isolate->factory()->NewRawOneByteString(2).ToHandleChecked(); 435 uint8_t* dest = str->GetChars(); 436 dest[0] = static_cast<uint8_t>(c1); 437 dest[1] = static_cast<uint8_t>(c2); 438 return str; 439 } else { 440 Handle<SeqTwoByteString> str = 441 isolate->factory()->NewRawTwoByteString(2).ToHandleChecked(); 442 uc16* dest = str->GetChars(); 443 dest[0] = c1; 444 dest[1] = c2; 445 return str; 446 } 447 } 448 449 450 template<typename SinkChar, typename StringType> 451 Handle<String> ConcatStringContent(Handle<StringType> result, 452 Handle<String> first, 453 Handle<String> second) { 454 DisallowHeapAllocation pointer_stays_valid; 455 SinkChar* sink = result->GetChars(); 456 String::WriteToFlat(*first, sink, 0, first->length()); 457 String::WriteToFlat(*second, sink + first->length(), 0, second->length()); 458 return result; 459 } 460 461 462 MaybeHandle<String> Factory::NewConsString(Handle<String> left, 463 Handle<String> right) { 464 int left_length = left->length(); 465 if (left_length == 0) return right; 466 int right_length = right->length(); 467 if (right_length == 0) return left; 468 469 int length = left_length + right_length; 470 471 if (length == 2) { 472 uint16_t c1 = left->Get(0); 473 uint16_t c2 = right->Get(0); 474 return MakeOrFindTwoCharacterString(isolate(), c1, c2); 475 } 476 477 // Make sure that an out of memory exception is thrown if the length 478 // of the new cons string is too large. 479 if (length > String::kMaxLength || length < 0) { 480 return isolate()->Throw<String>(NewInvalidStringLengthError()); 481 } 482 483 bool left_is_one_byte = left->IsOneByteRepresentation(); 484 bool right_is_one_byte = right->IsOneByteRepresentation(); 485 bool is_one_byte = left_is_one_byte && right_is_one_byte; 486 bool is_one_byte_data_in_two_byte_string = false; 487 if (!is_one_byte) { 488 // At least one of the strings uses two-byte representation so we 489 // can't use the fast case code for short ASCII strings below, but 490 // we can try to save memory if all chars actually fit in ASCII. 491 is_one_byte_data_in_two_byte_string = 492 left->HasOnlyOneByteChars() && right->HasOnlyOneByteChars(); 493 if (is_one_byte_data_in_two_byte_string) { 494 isolate()->counters()->string_add_runtime_ext_to_ascii()->Increment(); 495 } 496 } 497 498 // If the resulting string is small make a flat string. 499 if (length < ConsString::kMinLength) { 500 // Note that neither of the two inputs can be a slice because: 501 STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength); 502 ASSERT(left->IsFlat()); 503 ASSERT(right->IsFlat()); 504 505 STATIC_ASSERT(ConsString::kMinLength <= String::kMaxLength); 506 if (is_one_byte) { 507 Handle<SeqOneByteString> result = 508 NewRawOneByteString(length).ToHandleChecked(); 509 DisallowHeapAllocation no_gc; 510 uint8_t* dest = result->GetChars(); 511 // Copy left part. 512 const uint8_t* src = left->IsExternalString() 513 ? Handle<ExternalAsciiString>::cast(left)->GetChars() 514 : Handle<SeqOneByteString>::cast(left)->GetChars(); 515 for (int i = 0; i < left_length; i++) *dest++ = src[i]; 516 // Copy right part. 517 src = right->IsExternalString() 518 ? Handle<ExternalAsciiString>::cast(right)->GetChars() 519 : Handle<SeqOneByteString>::cast(right)->GetChars(); 520 for (int i = 0; i < right_length; i++) *dest++ = src[i]; 521 return result; 522 } 523 524 return (is_one_byte_data_in_two_byte_string) 525 ? ConcatStringContent<uint8_t>( 526 NewRawOneByteString(length).ToHandleChecked(), left, right) 527 : ConcatStringContent<uc16>( 528 NewRawTwoByteString(length).ToHandleChecked(), left, right); 529 } 530 531 Handle<Map> map = (is_one_byte || is_one_byte_data_in_two_byte_string) 532 ? cons_ascii_string_map() : cons_string_map(); 533 Handle<ConsString> result = New<ConsString>(map, NEW_SPACE); 534 535 DisallowHeapAllocation no_gc; 536 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 537 538 result->set_hash_field(String::kEmptyHashField); 539 result->set_length(length); 540 result->set_first(*left, mode); 541 result->set_second(*right, mode); 542 return result; 543 } 544 545 546 Handle<String> Factory::NewFlatConcatString(Handle<String> first, 547 Handle<String> second) { 548 int total_length = first->length() + second->length(); 549 if (first->IsOneByteRepresentation() && second->IsOneByteRepresentation()) { 550 return ConcatStringContent<uint8_t>( 551 NewRawOneByteString(total_length).ToHandleChecked(), first, second); 552 } else { 553 return ConcatStringContent<uc16>( 554 NewRawTwoByteString(total_length).ToHandleChecked(), first, second); 555 } 556 } 557 558 559 Handle<String> Factory::NewProperSubString(Handle<String> str, 560 int begin, 561 int end) { 562 #if VERIFY_HEAP 563 if (FLAG_verify_heap) str->StringVerify(); 564 #endif 565 ASSERT(begin > 0 || end < str->length()); 566 567 str = String::Flatten(str); 568 569 int length = end - begin; 570 if (length <= 0) return empty_string(); 571 if (length == 1) { 572 return LookupSingleCharacterStringFromCode(str->Get(begin)); 573 } 574 if (length == 2) { 575 // Optimization for 2-byte strings often used as keys in a decompression 576 // dictionary. Check whether we already have the string in the string 577 // table to prevent creation of many unnecessary strings. 578 uint16_t c1 = str->Get(begin); 579 uint16_t c2 = str->Get(begin + 1); 580 return MakeOrFindTwoCharacterString(isolate(), c1, c2); 581 } 582 583 if (!FLAG_string_slices || length < SlicedString::kMinLength) { 584 if (str->IsOneByteRepresentation()) { 585 Handle<SeqOneByteString> result = 586 NewRawOneByteString(length).ToHandleChecked(); 587 uint8_t* dest = result->GetChars(); 588 DisallowHeapAllocation no_gc; 589 String::WriteToFlat(*str, dest, begin, end); 590 return result; 591 } else { 592 Handle<SeqTwoByteString> result = 593 NewRawTwoByteString(length).ToHandleChecked(); 594 uc16* dest = result->GetChars(); 595 DisallowHeapAllocation no_gc; 596 String::WriteToFlat(*str, dest, begin, end); 597 return result; 598 } 599 } 600 601 int offset = begin; 602 603 if (str->IsSlicedString()) { 604 Handle<SlicedString> slice = Handle<SlicedString>::cast(str); 605 str = Handle<String>(slice->parent(), isolate()); 606 offset += slice->offset(); 607 } 608 609 ASSERT(str->IsSeqString() || str->IsExternalString()); 610 Handle<Map> map = str->IsOneByteRepresentation() ? sliced_ascii_string_map() 611 : sliced_string_map(); 612 Handle<SlicedString> slice = New<SlicedString>(map, NEW_SPACE); 613 614 slice->set_hash_field(String::kEmptyHashField); 615 slice->set_length(length); 616 slice->set_parent(*str); 617 slice->set_offset(offset); 618 return slice; 619 } 620 621 622 MaybeHandle<String> Factory::NewExternalStringFromAscii( 623 const ExternalAsciiString::Resource* resource) { 624 size_t length = resource->length(); 625 if (length > static_cast<size_t>(String::kMaxLength)) { 626 return isolate()->Throw<String>(NewInvalidStringLengthError()); 627 } 628 629 Handle<Map> map = external_ascii_string_map(); 630 Handle<ExternalAsciiString> external_string = 631 New<ExternalAsciiString>(map, NEW_SPACE); 632 external_string->set_length(static_cast<int>(length)); 633 external_string->set_hash_field(String::kEmptyHashField); 634 external_string->set_resource(resource); 635 636 return external_string; 637 } 638 639 640 MaybeHandle<String> Factory::NewExternalStringFromTwoByte( 641 const ExternalTwoByteString::Resource* resource) { 642 size_t length = resource->length(); 643 if (length > static_cast<size_t>(String::kMaxLength)) { 644 return isolate()->Throw<String>(NewInvalidStringLengthError()); 645 } 646 647 // For small strings we check whether the resource contains only 648 // one byte characters. If yes, we use a different string map. 649 static const size_t kOneByteCheckLengthLimit = 32; 650 bool is_one_byte = length <= kOneByteCheckLengthLimit && 651 String::IsOneByte(resource->data(), static_cast<int>(length)); 652 Handle<Map> map = is_one_byte ? 653 external_string_with_one_byte_data_map() : external_string_map(); 654 Handle<ExternalTwoByteString> external_string = 655 New<ExternalTwoByteString>(map, NEW_SPACE); 656 external_string->set_length(static_cast<int>(length)); 657 external_string->set_hash_field(String::kEmptyHashField); 658 external_string->set_resource(resource); 659 660 return external_string; 661 } 662 663 664 Handle<Symbol> Factory::NewSymbol() { 665 CALL_HEAP_FUNCTION( 666 isolate(), 667 isolate()->heap()->AllocateSymbol(), 668 Symbol); 669 } 670 671 672 Handle<Symbol> Factory::NewPrivateSymbol() { 673 Handle<Symbol> symbol = NewSymbol(); 674 symbol->set_is_private(true); 675 return symbol; 676 } 677 678 679 Handle<Context> Factory::NewNativeContext() { 680 Handle<FixedArray> array = NewFixedArray(Context::NATIVE_CONTEXT_SLOTS); 681 array->set_map_no_write_barrier(*native_context_map()); 682 Handle<Context> context = Handle<Context>::cast(array); 683 context->set_js_array_maps(*undefined_value()); 684 ASSERT(context->IsNativeContext()); 685 return context; 686 } 687 688 689 Handle<Context> Factory::NewGlobalContext(Handle<JSFunction> function, 690 Handle<ScopeInfo> scope_info) { 691 Handle<FixedArray> array = 692 NewFixedArray(scope_info->ContextLength(), TENURED); 693 array->set_map_no_write_barrier(*global_context_map()); 694 Handle<Context> context = Handle<Context>::cast(array); 695 context->set_closure(*function); 696 context->set_previous(function->context()); 697 context->set_extension(*scope_info); 698 context->set_global_object(function->context()->global_object()); 699 ASSERT(context->IsGlobalContext()); 700 return context; 701 } 702 703 704 Handle<Context> Factory::NewModuleContext(Handle<ScopeInfo> scope_info) { 705 Handle<FixedArray> array = 706 NewFixedArray(scope_info->ContextLength(), TENURED); 707 array->set_map_no_write_barrier(*module_context_map()); 708 // Instance link will be set later. 709 Handle<Context> context = Handle<Context>::cast(array); 710 context->set_extension(Smi::FromInt(0)); 711 return context; 712 } 713 714 715 Handle<Context> Factory::NewFunctionContext(int length, 716 Handle<JSFunction> function) { 717 ASSERT(length >= Context::MIN_CONTEXT_SLOTS); 718 Handle<FixedArray> array = NewFixedArray(length); 719 array->set_map_no_write_barrier(*function_context_map()); 720 Handle<Context> context = Handle<Context>::cast(array); 721 context->set_closure(*function); 722 context->set_previous(function->context()); 723 context->set_extension(Smi::FromInt(0)); 724 context->set_global_object(function->context()->global_object()); 725 return context; 726 } 727 728 729 Handle<Context> Factory::NewCatchContext(Handle<JSFunction> function, 730 Handle<Context> previous, 731 Handle<String> name, 732 Handle<Object> thrown_object) { 733 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == Context::THROWN_OBJECT_INDEX); 734 Handle<FixedArray> array = NewFixedArray(Context::MIN_CONTEXT_SLOTS + 1); 735 array->set_map_no_write_barrier(*catch_context_map()); 736 Handle<Context> context = Handle<Context>::cast(array); 737 context->set_closure(*function); 738 context->set_previous(*previous); 739 context->set_extension(*name); 740 context->set_global_object(previous->global_object()); 741 context->set(Context::THROWN_OBJECT_INDEX, *thrown_object); 742 return context; 743 } 744 745 746 Handle<Context> Factory::NewWithContext(Handle<JSFunction> function, 747 Handle<Context> previous, 748 Handle<JSReceiver> extension) { 749 Handle<FixedArray> array = NewFixedArray(Context::MIN_CONTEXT_SLOTS); 750 array->set_map_no_write_barrier(*with_context_map()); 751 Handle<Context> context = Handle<Context>::cast(array); 752 context->set_closure(*function); 753 context->set_previous(*previous); 754 context->set_extension(*extension); 755 context->set_global_object(previous->global_object()); 756 return context; 757 } 758 759 760 Handle<Context> Factory::NewBlockContext(Handle<JSFunction> function, 761 Handle<Context> previous, 762 Handle<ScopeInfo> scope_info) { 763 Handle<FixedArray> array = 764 NewFixedArrayWithHoles(scope_info->ContextLength()); 765 array->set_map_no_write_barrier(*block_context_map()); 766 Handle<Context> context = Handle<Context>::cast(array); 767 context->set_closure(*function); 768 context->set_previous(*previous); 769 context->set_extension(*scope_info); 770 context->set_global_object(previous->global_object()); 771 return context; 772 } 773 774 775 Handle<Struct> Factory::NewStruct(InstanceType type) { 776 CALL_HEAP_FUNCTION( 777 isolate(), 778 isolate()->heap()->AllocateStruct(type), 779 Struct); 780 } 781 782 783 Handle<CodeCache> Factory::NewCodeCache() { 784 Handle<CodeCache> code_cache = 785 Handle<CodeCache>::cast(NewStruct(CODE_CACHE_TYPE)); 786 code_cache->set_default_cache(*empty_fixed_array(), SKIP_WRITE_BARRIER); 787 code_cache->set_normal_type_cache(*undefined_value(), SKIP_WRITE_BARRIER); 788 return code_cache; 789 } 790 791 792 Handle<AliasedArgumentsEntry> Factory::NewAliasedArgumentsEntry( 793 int aliased_context_slot) { 794 Handle<AliasedArgumentsEntry> entry = Handle<AliasedArgumentsEntry>::cast( 795 NewStruct(ALIASED_ARGUMENTS_ENTRY_TYPE)); 796 entry->set_aliased_context_slot(aliased_context_slot); 797 return entry; 798 } 799 800 801 Handle<DeclaredAccessorDescriptor> Factory::NewDeclaredAccessorDescriptor() { 802 return Handle<DeclaredAccessorDescriptor>::cast( 803 NewStruct(DECLARED_ACCESSOR_DESCRIPTOR_TYPE)); 804 } 805 806 807 Handle<DeclaredAccessorInfo> Factory::NewDeclaredAccessorInfo() { 808 Handle<DeclaredAccessorInfo> info = 809 Handle<DeclaredAccessorInfo>::cast( 810 NewStruct(DECLARED_ACCESSOR_INFO_TYPE)); 811 info->set_flag(0); // Must clear the flag, it was initialized as undefined. 812 return info; 813 } 814 815 816 Handle<ExecutableAccessorInfo> Factory::NewExecutableAccessorInfo() { 817 Handle<ExecutableAccessorInfo> info = 818 Handle<ExecutableAccessorInfo>::cast( 819 NewStruct(EXECUTABLE_ACCESSOR_INFO_TYPE)); 820 info->set_flag(0); // Must clear the flag, it was initialized as undefined. 821 return info; 822 } 823 824 825 Handle<Script> Factory::NewScript(Handle<String> source) { 826 // Generate id for this script. 827 Heap* heap = isolate()->heap(); 828 int id = heap->last_script_id()->value() + 1; 829 if (!Smi::IsValid(id) || id < 0) id = 1; 830 heap->set_last_script_id(Smi::FromInt(id)); 831 832 // Create and initialize script object. 833 Handle<Foreign> wrapper = NewForeign(0, TENURED); 834 Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE)); 835 script->set_source(*source); 836 script->set_name(heap->undefined_value()); 837 script->set_id(Smi::FromInt(id)); 838 script->set_line_offset(Smi::FromInt(0)); 839 script->set_column_offset(Smi::FromInt(0)); 840 script->set_context_data(heap->undefined_value()); 841 script->set_type(Smi::FromInt(Script::TYPE_NORMAL)); 842 script->set_wrapper(*wrapper); 843 script->set_line_ends(heap->undefined_value()); 844 script->set_eval_from_shared(heap->undefined_value()); 845 script->set_eval_from_instructions_offset(Smi::FromInt(0)); 846 script->set_flags(Smi::FromInt(0)); 847 848 return script; 849 } 850 851 852 Handle<Foreign> Factory::NewForeign(Address addr, PretenureFlag pretenure) { 853 CALL_HEAP_FUNCTION(isolate(), 854 isolate()->heap()->AllocateForeign(addr, pretenure), 855 Foreign); 856 } 857 858 859 Handle<Foreign> Factory::NewForeign(const AccessorDescriptor* desc) { 860 return NewForeign((Address) desc, TENURED); 861 } 862 863 864 Handle<ByteArray> Factory::NewByteArray(int length, PretenureFlag pretenure) { 865 ASSERT(0 <= length); 866 CALL_HEAP_FUNCTION( 867 isolate(), 868 isolate()->heap()->AllocateByteArray(length, pretenure), 869 ByteArray); 870 } 871 872 873 Handle<ExternalArray> Factory::NewExternalArray(int length, 874 ExternalArrayType array_type, 875 void* external_pointer, 876 PretenureFlag pretenure) { 877 ASSERT(0 <= length && length <= Smi::kMaxValue); 878 CALL_HEAP_FUNCTION( 879 isolate(), 880 isolate()->heap()->AllocateExternalArray(length, 881 array_type, 882 external_pointer, 883 pretenure), 884 ExternalArray); 885 } 886 887 888 Handle<FixedTypedArrayBase> Factory::NewFixedTypedArray( 889 int length, 890 ExternalArrayType array_type, 891 PretenureFlag pretenure) { 892 ASSERT(0 <= length && length <= Smi::kMaxValue); 893 CALL_HEAP_FUNCTION( 894 isolate(), 895 isolate()->heap()->AllocateFixedTypedArray(length, 896 array_type, 897 pretenure), 898 FixedTypedArrayBase); 899 } 900 901 902 Handle<Cell> Factory::NewCell(Handle<Object> value) { 903 AllowDeferredHandleDereference convert_to_cell; 904 CALL_HEAP_FUNCTION( 905 isolate(), 906 isolate()->heap()->AllocateCell(*value), 907 Cell); 908 } 909 910 911 Handle<PropertyCell> Factory::NewPropertyCellWithHole() { 912 CALL_HEAP_FUNCTION( 913 isolate(), 914 isolate()->heap()->AllocatePropertyCell(), 915 PropertyCell); 916 } 917 918 919 Handle<PropertyCell> Factory::NewPropertyCell(Handle<Object> value) { 920 AllowDeferredHandleDereference convert_to_cell; 921 Handle<PropertyCell> cell = NewPropertyCellWithHole(); 922 PropertyCell::SetValueInferType(cell, value); 923 return cell; 924 } 925 926 927 Handle<AllocationSite> Factory::NewAllocationSite() { 928 Handle<Map> map = allocation_site_map(); 929 Handle<AllocationSite> site = New<AllocationSite>(map, OLD_POINTER_SPACE); 930 site->Initialize(); 931 932 // Link the site 933 site->set_weak_next(isolate()->heap()->allocation_sites_list()); 934 isolate()->heap()->set_allocation_sites_list(*site); 935 return site; 936 } 937 938 939 Handle<Map> Factory::NewMap(InstanceType type, 940 int instance_size, 941 ElementsKind elements_kind) { 942 CALL_HEAP_FUNCTION( 943 isolate(), 944 isolate()->heap()->AllocateMap(type, instance_size, elements_kind), 945 Map); 946 } 947 948 949 Handle<JSObject> Factory::CopyJSObject(Handle<JSObject> object) { 950 CALL_HEAP_FUNCTION(isolate(), 951 isolate()->heap()->CopyJSObject(*object, NULL), 952 JSObject); 953 } 954 955 956 Handle<JSObject> Factory::CopyJSObjectWithAllocationSite( 957 Handle<JSObject> object, 958 Handle<AllocationSite> site) { 959 CALL_HEAP_FUNCTION(isolate(), 960 isolate()->heap()->CopyJSObject( 961 *object, 962 site.is_null() ? NULL : *site), 963 JSObject); 964 } 965 966 967 Handle<FixedArray> Factory::CopyFixedArrayWithMap(Handle<FixedArray> array, 968 Handle<Map> map) { 969 CALL_HEAP_FUNCTION(isolate(), 970 isolate()->heap()->CopyFixedArrayWithMap(*array, *map), 971 FixedArray); 972 } 973 974 975 Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) { 976 CALL_HEAP_FUNCTION(isolate(), 977 isolate()->heap()->CopyFixedArray(*array), 978 FixedArray); 979 } 980 981 982 Handle<FixedArray> Factory::CopyAndTenureFixedCOWArray( 983 Handle<FixedArray> array) { 984 ASSERT(isolate()->heap()->InNewSpace(*array)); 985 CALL_HEAP_FUNCTION(isolate(), 986 isolate()->heap()->CopyAndTenureFixedCOWArray(*array), 987 FixedArray); 988 } 989 990 991 Handle<FixedDoubleArray> Factory::CopyFixedDoubleArray( 992 Handle<FixedDoubleArray> array) { 993 CALL_HEAP_FUNCTION(isolate(), 994 isolate()->heap()->CopyFixedDoubleArray(*array), 995 FixedDoubleArray); 996 } 997 998 999 Handle<ConstantPoolArray> Factory::CopyConstantPoolArray( 1000 Handle<ConstantPoolArray> array) { 1001 CALL_HEAP_FUNCTION(isolate(), 1002 isolate()->heap()->CopyConstantPoolArray(*array), 1003 ConstantPoolArray); 1004 } 1005 1006 1007 Handle<Object> Factory::NewNumber(double value, 1008 PretenureFlag pretenure) { 1009 // We need to distinguish the minus zero value and this cannot be 1010 // done after conversion to int. Doing this by comparing bit 1011 // patterns is faster than using fpclassify() et al. 1012 if (IsMinusZero(value)) return NewHeapNumber(-0.0, pretenure); 1013 1014 int int_value = FastD2I(value); 1015 if (value == int_value && Smi::IsValid(int_value)) { 1016 return handle(Smi::FromInt(int_value), isolate()); 1017 } 1018 1019 // Materialize the value in the heap. 1020 return NewHeapNumber(value, pretenure); 1021 } 1022 1023 1024 Handle<Object> Factory::NewNumberFromInt(int32_t value, 1025 PretenureFlag pretenure) { 1026 if (Smi::IsValid(value)) return handle(Smi::FromInt(value), isolate()); 1027 // Bypass NumberFromDouble to avoid various redundant checks. 1028 return NewHeapNumber(FastI2D(value), pretenure); 1029 } 1030 1031 1032 Handle<Object> Factory::NewNumberFromUint(uint32_t value, 1033 PretenureFlag pretenure) { 1034 int32_t int32v = static_cast<int32_t>(value); 1035 if (int32v >= 0 && Smi::IsValid(int32v)) { 1036 return handle(Smi::FromInt(int32v), isolate()); 1037 } 1038 return NewHeapNumber(FastUI2D(value), pretenure); 1039 } 1040 1041 1042 Handle<HeapNumber> Factory::NewHeapNumber(double value, 1043 PretenureFlag pretenure) { 1044 CALL_HEAP_FUNCTION( 1045 isolate(), 1046 isolate()->heap()->AllocateHeapNumber(value, pretenure), HeapNumber); 1047 } 1048 1049 1050 Handle<Object> Factory::NewTypeError(const char* message, 1051 Vector< Handle<Object> > args) { 1052 return NewError("MakeTypeError", message, args); 1053 } 1054 1055 1056 Handle<Object> Factory::NewTypeError(Handle<String> message) { 1057 return NewError("$TypeError", message); 1058 } 1059 1060 1061 Handle<Object> Factory::NewRangeError(const char* message, 1062 Vector< Handle<Object> > args) { 1063 return NewError("MakeRangeError", message, args); 1064 } 1065 1066 1067 Handle<Object> Factory::NewRangeError(Handle<String> message) { 1068 return NewError("$RangeError", message); 1069 } 1070 1071 1072 Handle<Object> Factory::NewSyntaxError(const char* message, 1073 Handle<JSArray> args) { 1074 return NewError("MakeSyntaxError", message, args); 1075 } 1076 1077 1078 Handle<Object> Factory::NewSyntaxError(Handle<String> message) { 1079 return NewError("$SyntaxError", message); 1080 } 1081 1082 1083 Handle<Object> Factory::NewReferenceError(const char* message, 1084 Vector< Handle<Object> > args) { 1085 return NewError("MakeReferenceError", message, args); 1086 } 1087 1088 1089 Handle<Object> Factory::NewReferenceError(const char* message, 1090 Handle<JSArray> args) { 1091 return NewError("MakeReferenceError", message, args); 1092 } 1093 1094 1095 Handle<Object> Factory::NewReferenceError(Handle<String> message) { 1096 return NewError("$ReferenceError", message); 1097 } 1098 1099 1100 Handle<Object> Factory::NewError(const char* maker, 1101 const char* message, 1102 Vector< Handle<Object> > args) { 1103 // Instantiate a closeable HandleScope for EscapeFrom. 1104 v8::EscapableHandleScope scope(reinterpret_cast<v8::Isolate*>(isolate())); 1105 Handle<FixedArray> array = NewFixedArray(args.length()); 1106 for (int i = 0; i < args.length(); i++) { 1107 array->set(i, *args[i]); 1108 } 1109 Handle<JSArray> object = NewJSArrayWithElements(array); 1110 Handle<Object> result = NewError(maker, message, object); 1111 return result.EscapeFrom(&scope); 1112 } 1113 1114 1115 Handle<Object> Factory::NewEvalError(const char* message, 1116 Vector< Handle<Object> > args) { 1117 return NewError("MakeEvalError", message, args); 1118 } 1119 1120 1121 Handle<Object> Factory::NewError(const char* message, 1122 Vector< Handle<Object> > args) { 1123 return NewError("MakeError", message, args); 1124 } 1125 1126 1127 Handle<String> Factory::EmergencyNewError(const char* message, 1128 Handle<JSArray> args) { 1129 const int kBufferSize = 1000; 1130 char buffer[kBufferSize]; 1131 size_t space = kBufferSize; 1132 char* p = &buffer[0]; 1133 1134 Vector<char> v(buffer, kBufferSize); 1135 StrNCpy(v, message, space); 1136 space -= Min(space, strlen(message)); 1137 p = &buffer[kBufferSize] - space; 1138 1139 for (unsigned i = 0; i < ARRAY_SIZE(args); i++) { 1140 if (space > 0) { 1141 *p++ = ' '; 1142 space--; 1143 if (space > 0) { 1144 Handle<String> arg_str = Handle<String>::cast( 1145 Object::GetElement(isolate(), args, i).ToHandleChecked()); 1146 SmartArrayPointer<char> arg = arg_str->ToCString(); 1147 Vector<char> v2(p, static_cast<int>(space)); 1148 StrNCpy(v2, arg.get(), space); 1149 space -= Min(space, strlen(arg.get())); 1150 p = &buffer[kBufferSize] - space; 1151 } 1152 } 1153 } 1154 if (space > 0) { 1155 *p = '\0'; 1156 } else { 1157 buffer[kBufferSize - 1] = '\0'; 1158 } 1159 return NewStringFromUtf8(CStrVector(buffer), TENURED).ToHandleChecked(); 1160 } 1161 1162 1163 Handle<Object> Factory::NewError(const char* maker, 1164 const char* message, 1165 Handle<JSArray> args) { 1166 Handle<String> make_str = InternalizeUtf8String(maker); 1167 Handle<Object> fun_obj = Object::GetProperty( 1168 isolate()->js_builtins_object(), make_str).ToHandleChecked(); 1169 // If the builtins haven't been properly configured yet this error 1170 // constructor may not have been defined. Bail out. 1171 if (!fun_obj->IsJSFunction()) { 1172 return EmergencyNewError(message, args); 1173 } 1174 Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj); 1175 Handle<Object> message_obj = InternalizeUtf8String(message); 1176 Handle<Object> argv[] = { message_obj, args }; 1177 1178 // Invoke the JavaScript factory method. If an exception is thrown while 1179 // running the factory method, use the exception as the result. 1180 Handle<Object> result; 1181 Handle<Object> exception; 1182 if (!Execution::TryCall(fun, 1183 isolate()->js_builtins_object(), 1184 ARRAY_SIZE(argv), 1185 argv, 1186 &exception).ToHandle(&result)) { 1187 return exception; 1188 } 1189 return result; 1190 } 1191 1192 1193 Handle<Object> Factory::NewError(Handle<String> message) { 1194 return NewError("$Error", message); 1195 } 1196 1197 1198 Handle<Object> Factory::NewError(const char* constructor, 1199 Handle<String> message) { 1200 Handle<String> constr = InternalizeUtf8String(constructor); 1201 Handle<JSFunction> fun = Handle<JSFunction>::cast(Object::GetProperty( 1202 isolate()->js_builtins_object(), constr).ToHandleChecked()); 1203 Handle<Object> argv[] = { message }; 1204 1205 // Invoke the JavaScript factory method. If an exception is thrown while 1206 // running the factory method, use the exception as the result. 1207 Handle<Object> result; 1208 Handle<Object> exception; 1209 if (!Execution::TryCall(fun, 1210 isolate()->js_builtins_object(), 1211 ARRAY_SIZE(argv), 1212 argv, 1213 &exception).ToHandle(&result)) { 1214 return exception; 1215 } 1216 return result; 1217 } 1218 1219 1220 void Factory::InitializeFunction(Handle<JSFunction> function, 1221 Handle<SharedFunctionInfo> info, 1222 Handle<Context> context) { 1223 function->initialize_properties(); 1224 function->initialize_elements(); 1225 function->set_shared(*info); 1226 function->set_code(info->code()); 1227 function->set_context(*context); 1228 function->set_prototype_or_initial_map(*the_hole_value()); 1229 function->set_literals_or_bindings(*empty_fixed_array()); 1230 function->set_next_function_link(*undefined_value()); 1231 } 1232 1233 1234 Handle<JSFunction> Factory::NewFunction(Handle<Map> map, 1235 Handle<SharedFunctionInfo> info, 1236 Handle<Context> context, 1237 PretenureFlag pretenure) { 1238 AllocationSpace space = pretenure == TENURED ? OLD_POINTER_SPACE : NEW_SPACE; 1239 Handle<JSFunction> result = New<JSFunction>(map, space); 1240 InitializeFunction(result, info, context); 1241 return result; 1242 } 1243 1244 1245 Handle<JSFunction> Factory::NewFunction(Handle<Map> map, 1246 Handle<String> name, 1247 MaybeHandle<Code> code) { 1248 Handle<Context> context(isolate()->context()->native_context()); 1249 Handle<SharedFunctionInfo> info = NewSharedFunctionInfo(name, code); 1250 ASSERT((info->strict_mode() == SLOPPY) && 1251 (map.is_identical_to(isolate()->sloppy_function_map()) || 1252 map.is_identical_to( 1253 isolate()->sloppy_function_without_prototype_map()) || 1254 map.is_identical_to( 1255 isolate()->sloppy_function_with_readonly_prototype_map()))); 1256 return NewFunction(map, info, context); 1257 } 1258 1259 1260 Handle<JSFunction> Factory::NewFunction(Handle<String> name) { 1261 return NewFunction( 1262 isolate()->sloppy_function_map(), name, MaybeHandle<Code>()); 1263 } 1264 1265 1266 Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name, 1267 Handle<Code> code) { 1268 return NewFunction( 1269 isolate()->sloppy_function_without_prototype_map(), name, code); 1270 } 1271 1272 1273 Handle<JSFunction> Factory::NewFunction(Handle<String> name, 1274 Handle<Code> code, 1275 Handle<Object> prototype, 1276 bool read_only_prototype) { 1277 Handle<Map> map = read_only_prototype 1278 ? isolate()->sloppy_function_with_readonly_prototype_map() 1279 : isolate()->sloppy_function_map(); 1280 Handle<JSFunction> result = NewFunction(map, name, code); 1281 result->set_prototype_or_initial_map(*prototype); 1282 return result; 1283 } 1284 1285 1286 Handle<JSFunction> Factory::NewFunction(Handle<String> name, 1287 Handle<Code> code, 1288 Handle<Object> prototype, 1289 InstanceType type, 1290 int instance_size, 1291 bool read_only_prototype) { 1292 // Allocate the function 1293 Handle<JSFunction> function = NewFunction( 1294 name, code, prototype, read_only_prototype); 1295 1296 Handle<Map> initial_map = NewMap( 1297 type, instance_size, GetInitialFastElementsKind()); 1298 if (prototype->IsTheHole() && !function->shared()->is_generator()) { 1299 prototype = NewFunctionPrototype(function); 1300 } 1301 initial_map->set_prototype(*prototype); 1302 function->set_initial_map(*initial_map); 1303 initial_map->set_constructor(*function); 1304 1305 return function; 1306 } 1307 1308 1309 Handle<JSFunction> Factory::NewFunction(Handle<String> name, 1310 Handle<Code> code, 1311 InstanceType type, 1312 int instance_size) { 1313 return NewFunction(name, code, the_hole_value(), type, instance_size); 1314 } 1315 1316 1317 Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) { 1318 // Make sure to use globals from the function's context, since the function 1319 // can be from a different context. 1320 Handle<Context> native_context(function->context()->native_context()); 1321 Handle<Map> new_map; 1322 if (function->shared()->is_generator()) { 1323 // Generator prototypes can share maps since they don't have "constructor" 1324 // properties. 1325 new_map = handle(native_context->generator_object_prototype_map()); 1326 } else { 1327 // Each function prototype gets a fresh map to avoid unwanted sharing of 1328 // maps between prototypes of different constructors. 1329 Handle<JSFunction> object_function(native_context->object_function()); 1330 ASSERT(object_function->has_initial_map()); 1331 new_map = Map::Copy(handle(object_function->initial_map())); 1332 } 1333 1334 Handle<JSObject> prototype = NewJSObjectFromMap(new_map); 1335 1336 if (!function->shared()->is_generator()) { 1337 JSObject::SetOwnPropertyIgnoreAttributes(prototype, 1338 constructor_string(), 1339 function, 1340 DONT_ENUM).Assert(); 1341 } 1342 1343 return prototype; 1344 } 1345 1346 1347 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( 1348 Handle<SharedFunctionInfo> info, 1349 Handle<Context> context, 1350 PretenureFlag pretenure) { 1351 int map_index = Context::FunctionMapIndex(info->strict_mode(), 1352 info->is_generator()); 1353 Handle<Map> map(Map::cast(context->native_context()->get(map_index))); 1354 Handle<JSFunction> result = NewFunction(map, info, context, pretenure); 1355 1356 if (info->ic_age() != isolate()->heap()->global_ic_age()) { 1357 info->ResetForNewContext(isolate()->heap()->global_ic_age()); 1358 } 1359 1360 int index = info->SearchOptimizedCodeMap(context->native_context(), 1361 BailoutId::None()); 1362 if (!info->bound() && index < 0) { 1363 int number_of_literals = info->num_literals(); 1364 Handle<FixedArray> literals = NewFixedArray(number_of_literals, pretenure); 1365 if (number_of_literals > 0) { 1366 // Store the native context in the literals array prefix. This 1367 // context will be used when creating object, regexp and array 1368 // literals in this function. 1369 literals->set(JSFunction::kLiteralNativeContextIndex, 1370 context->native_context()); 1371 } 1372 result->set_literals(*literals); 1373 } 1374 1375 if (index > 0) { 1376 // Caching of optimized code enabled and optimized code found. 1377 FixedArray* literals = info->GetLiteralsFromOptimizedCodeMap(index); 1378 if (literals != NULL) result->set_literals(literals); 1379 Code* code = info->GetCodeFromOptimizedCodeMap(index); 1380 ASSERT(!code->marked_for_deoptimization()); 1381 result->ReplaceCode(code); 1382 return result; 1383 } 1384 1385 if (isolate()->use_crankshaft() && 1386 FLAG_always_opt && 1387 result->is_compiled() && 1388 !info->is_toplevel() && 1389 info->allows_lazy_compilation() && 1390 !info->optimization_disabled() && 1391 !isolate()->DebuggerHasBreakPoints()) { 1392 result->MarkForOptimization(); 1393 } 1394 return result; 1395 } 1396 1397 1398 Handle<JSObject> Factory::NewIteratorResultObject(Handle<Object> value, 1399 bool done) { 1400 Handle<Map> map(isolate()->native_context()->iterator_result_map()); 1401 Handle<JSObject> result = NewJSObjectFromMap(map, NOT_TENURED, false); 1402 result->InObjectPropertyAtPut( 1403 JSGeneratorObject::kResultValuePropertyIndex, *value); 1404 result->InObjectPropertyAtPut( 1405 JSGeneratorObject::kResultDonePropertyIndex, *ToBoolean(done)); 1406 return result; 1407 } 1408 1409 1410 Handle<ScopeInfo> Factory::NewScopeInfo(int length) { 1411 Handle<FixedArray> array = NewFixedArray(length, TENURED); 1412 array->set_map_no_write_barrier(*scope_info_map()); 1413 Handle<ScopeInfo> scope_info = Handle<ScopeInfo>::cast(array); 1414 return scope_info; 1415 } 1416 1417 1418 Handle<JSObject> Factory::NewExternal(void* value) { 1419 Handle<Foreign> foreign = NewForeign(static_cast<Address>(value)); 1420 Handle<JSObject> external = NewJSObjectFromMap(external_map()); 1421 external->SetInternalField(0, *foreign); 1422 return external; 1423 } 1424 1425 1426 Handle<Code> Factory::NewCodeRaw(int object_size, bool immovable) { 1427 CALL_HEAP_FUNCTION(isolate(), 1428 isolate()->heap()->AllocateCode(object_size, immovable), 1429 Code); 1430 } 1431 1432 1433 Handle<Code> Factory::NewCode(const CodeDesc& desc, 1434 Code::Flags flags, 1435 Handle<Object> self_ref, 1436 bool immovable, 1437 bool crankshafted, 1438 int prologue_offset, 1439 bool is_debug) { 1440 Handle<ByteArray> reloc_info = NewByteArray(desc.reloc_size, TENURED); 1441 Handle<ConstantPoolArray> constant_pool = 1442 desc.origin->NewConstantPool(isolate()); 1443 1444 // Compute size. 1445 int body_size = RoundUp(desc.instr_size, kObjectAlignment); 1446 int obj_size = Code::SizeFor(body_size); 1447 1448 Handle<Code> code = NewCodeRaw(obj_size, immovable); 1449 ASSERT(isolate()->code_range() == NULL || 1450 !isolate()->code_range()->valid() || 1451 isolate()->code_range()->contains(code->address())); 1452 1453 // The code object has not been fully initialized yet. We rely on the 1454 // fact that no allocation will happen from this point on. 1455 DisallowHeapAllocation no_gc; 1456 code->set_gc_metadata(Smi::FromInt(0)); 1457 code->set_ic_age(isolate()->heap()->global_ic_age()); 1458 code->set_instruction_size(desc.instr_size); 1459 code->set_relocation_info(*reloc_info); 1460 code->set_flags(flags); 1461 code->set_raw_kind_specific_flags1(0); 1462 code->set_raw_kind_specific_flags2(0); 1463 code->set_is_crankshafted(crankshafted); 1464 code->set_deoptimization_data(*empty_fixed_array(), SKIP_WRITE_BARRIER); 1465 code->set_raw_type_feedback_info(*undefined_value()); 1466 code->set_next_code_link(*undefined_value()); 1467 code->set_handler_table(*empty_fixed_array(), SKIP_WRITE_BARRIER); 1468 code->set_prologue_offset(prologue_offset); 1469 if (code->kind() == Code::OPTIMIZED_FUNCTION) { 1470 code->set_marked_for_deoptimization(false); 1471 } 1472 1473 if (is_debug) { 1474 ASSERT(code->kind() == Code::FUNCTION); 1475 code->set_has_debug_break_slots(true); 1476 } 1477 1478 desc.origin->PopulateConstantPool(*constant_pool); 1479 code->set_constant_pool(*constant_pool); 1480 1481 // Allow self references to created code object by patching the handle to 1482 // point to the newly allocated Code object. 1483 if (!self_ref.is_null()) *(self_ref.location()) = *code; 1484 1485 // Migrate generated code. 1486 // The generated code can contain Object** values (typically from handles) 1487 // that are dereferenced during the copy to point directly to the actual heap 1488 // objects. These pointers can include references to the code object itself, 1489 // through the self_reference parameter. 1490 code->CopyFrom(desc); 1491 1492 #ifdef VERIFY_HEAP 1493 if (FLAG_verify_heap) code->ObjectVerify(); 1494 #endif 1495 return code; 1496 } 1497 1498 1499 Handle<Code> Factory::CopyCode(Handle<Code> code) { 1500 CALL_HEAP_FUNCTION(isolate(), 1501 isolate()->heap()->CopyCode(*code), 1502 Code); 1503 } 1504 1505 1506 Handle<Code> Factory::CopyCode(Handle<Code> code, Vector<byte> reloc_info) { 1507 CALL_HEAP_FUNCTION(isolate(), 1508 isolate()->heap()->CopyCode(*code, reloc_info), 1509 Code); 1510 } 1511 1512 1513 Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor, 1514 PretenureFlag pretenure) { 1515 JSFunction::EnsureHasInitialMap(constructor); 1516 CALL_HEAP_FUNCTION( 1517 isolate(), 1518 isolate()->heap()->AllocateJSObject(*constructor, pretenure), JSObject); 1519 } 1520 1521 1522 Handle<JSObject> Factory::NewJSObjectWithMemento( 1523 Handle<JSFunction> constructor, 1524 Handle<AllocationSite> site) { 1525 JSFunction::EnsureHasInitialMap(constructor); 1526 CALL_HEAP_FUNCTION( 1527 isolate(), 1528 isolate()->heap()->AllocateJSObject(*constructor, NOT_TENURED, *site), 1529 JSObject); 1530 } 1531 1532 1533 Handle<JSModule> Factory::NewJSModule(Handle<Context> context, 1534 Handle<ScopeInfo> scope_info) { 1535 // Allocate a fresh map. Modules do not have a prototype. 1536 Handle<Map> map = NewMap(JS_MODULE_TYPE, JSModule::kSize); 1537 // Allocate the object based on the map. 1538 Handle<JSModule> module = 1539 Handle<JSModule>::cast(NewJSObjectFromMap(map, TENURED)); 1540 module->set_context(*context); 1541 module->set_scope_info(*scope_info); 1542 return module; 1543 } 1544 1545 1546 Handle<GlobalObject> Factory::NewGlobalObject(Handle<JSFunction> constructor) { 1547 ASSERT(constructor->has_initial_map()); 1548 Handle<Map> map(constructor->initial_map()); 1549 ASSERT(map->is_dictionary_map()); 1550 1551 // Make sure no field properties are described in the initial map. 1552 // This guarantees us that normalizing the properties does not 1553 // require us to change property values to PropertyCells. 1554 ASSERT(map->NextFreePropertyIndex() == 0); 1555 1556 // Make sure we don't have a ton of pre-allocated slots in the 1557 // global objects. They will be unused once we normalize the object. 1558 ASSERT(map->unused_property_fields() == 0); 1559 ASSERT(map->inobject_properties() == 0); 1560 1561 // Initial size of the backing store to avoid resize of the storage during 1562 // bootstrapping. The size differs between the JS global object ad the 1563 // builtins object. 1564 int initial_size = map->instance_type() == JS_GLOBAL_OBJECT_TYPE ? 64 : 512; 1565 1566 // Allocate a dictionary object for backing storage. 1567 int at_least_space_for = map->NumberOfOwnDescriptors() * 2 + initial_size; 1568 Handle<NameDictionary> dictionary = 1569 NameDictionary::New(isolate(), at_least_space_for); 1570 1571 // The global object might be created from an object template with accessors. 1572 // Fill these accessors into the dictionary. 1573 Handle<DescriptorArray> descs(map->instance_descriptors()); 1574 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { 1575 PropertyDetails details = descs->GetDetails(i); 1576 ASSERT(details.type() == CALLBACKS); // Only accessors are expected. 1577 PropertyDetails d = PropertyDetails(details.attributes(), CALLBACKS, i + 1); 1578 Handle<Name> name(descs->GetKey(i)); 1579 Handle<Object> value(descs->GetCallbacksObject(i), isolate()); 1580 Handle<PropertyCell> cell = NewPropertyCell(value); 1581 // |dictionary| already contains enough space for all properties. 1582 USE(NameDictionary::Add(dictionary, name, cell, d)); 1583 } 1584 1585 // Allocate the global object and initialize it with the backing store. 1586 Handle<GlobalObject> global = New<GlobalObject>(map, OLD_POINTER_SPACE); 1587 isolate()->heap()->InitializeJSObjectFromMap(*global, *dictionary, *map); 1588 1589 // Create a new map for the global object. 1590 Handle<Map> new_map = Map::CopyDropDescriptors(map); 1591 new_map->set_dictionary_map(true); 1592 1593 // Set up the global object as a normalized object. 1594 global->set_map(*new_map); 1595 global->set_properties(*dictionary); 1596 1597 // Make sure result is a global object with properties in dictionary. 1598 ASSERT(global->IsGlobalObject() && !global->HasFastProperties()); 1599 return global; 1600 } 1601 1602 1603 Handle<JSObject> Factory::NewJSObjectFromMap( 1604 Handle<Map> map, 1605 PretenureFlag pretenure, 1606 bool alloc_props, 1607 Handle<AllocationSite> allocation_site) { 1608 CALL_HEAP_FUNCTION( 1609 isolate(), 1610 isolate()->heap()->AllocateJSObjectFromMap( 1611 *map, 1612 pretenure, 1613 alloc_props, 1614 allocation_site.is_null() ? NULL : *allocation_site), 1615 JSObject); 1616 } 1617 1618 1619 Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind, 1620 PretenureFlag pretenure) { 1621 Context* native_context = isolate()->context()->native_context(); 1622 JSFunction* array_function = native_context->array_function(); 1623 Map* map = array_function->initial_map(); 1624 Map* transition_map = isolate()->get_initial_js_array_map(elements_kind); 1625 if (transition_map != NULL) map = transition_map; 1626 return Handle<JSArray>::cast(NewJSObjectFromMap(handle(map), pretenure)); 1627 } 1628 1629 1630 Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind, 1631 int length, 1632 int capacity, 1633 ArrayStorageAllocationMode mode, 1634 PretenureFlag pretenure) { 1635 Handle<JSArray> array = NewJSArray(elements_kind, pretenure); 1636 NewJSArrayStorage(array, length, capacity, mode); 1637 return array; 1638 } 1639 1640 1641 Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements, 1642 ElementsKind elements_kind, 1643 int length, 1644 PretenureFlag pretenure) { 1645 ASSERT(length <= elements->length()); 1646 Handle<JSArray> array = NewJSArray(elements_kind, pretenure); 1647 1648 array->set_elements(*elements); 1649 array->set_length(Smi::FromInt(length)); 1650 JSObject::ValidateElements(array); 1651 return array; 1652 } 1653 1654 1655 void Factory::NewJSArrayStorage(Handle<JSArray> array, 1656 int length, 1657 int capacity, 1658 ArrayStorageAllocationMode mode) { 1659 ASSERT(capacity >= length); 1660 1661 if (capacity == 0) { 1662 array->set_length(Smi::FromInt(0)); 1663 array->set_elements(*empty_fixed_array()); 1664 return; 1665 } 1666 1667 Handle<FixedArrayBase> elms; 1668 ElementsKind elements_kind = array->GetElementsKind(); 1669 if (IsFastDoubleElementsKind(elements_kind)) { 1670 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { 1671 elms = NewFixedDoubleArray(capacity); 1672 } else { 1673 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); 1674 elms = NewFixedDoubleArrayWithHoles(capacity); 1675 } 1676 } else { 1677 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind)); 1678 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { 1679 elms = NewUninitializedFixedArray(capacity); 1680 } else { 1681 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); 1682 elms = NewFixedArrayWithHoles(capacity); 1683 } 1684 } 1685 1686 array->set_elements(*elms); 1687 array->set_length(Smi::FromInt(length)); 1688 } 1689 1690 1691 Handle<JSGeneratorObject> Factory::NewJSGeneratorObject( 1692 Handle<JSFunction> function) { 1693 ASSERT(function->shared()->is_generator()); 1694 JSFunction::EnsureHasInitialMap(function); 1695 Handle<Map> map(function->initial_map()); 1696 ASSERT(map->instance_type() == JS_GENERATOR_OBJECT_TYPE); 1697 CALL_HEAP_FUNCTION( 1698 isolate(), 1699 isolate()->heap()->AllocateJSObjectFromMap(*map), 1700 JSGeneratorObject); 1701 } 1702 1703 1704 Handle<JSArrayBuffer> Factory::NewJSArrayBuffer() { 1705 Handle<JSFunction> array_buffer_fun( 1706 isolate()->context()->native_context()->array_buffer_fun()); 1707 CALL_HEAP_FUNCTION( 1708 isolate(), 1709 isolate()->heap()->AllocateJSObject(*array_buffer_fun), 1710 JSArrayBuffer); 1711 } 1712 1713 1714 Handle<JSDataView> Factory::NewJSDataView() { 1715 Handle<JSFunction> data_view_fun( 1716 isolate()->context()->native_context()->data_view_fun()); 1717 CALL_HEAP_FUNCTION( 1718 isolate(), 1719 isolate()->heap()->AllocateJSObject(*data_view_fun), 1720 JSDataView); 1721 } 1722 1723 1724 static JSFunction* GetTypedArrayFun(ExternalArrayType type, 1725 Isolate* isolate) { 1726 Context* native_context = isolate->context()->native_context(); 1727 switch (type) { 1728 #define TYPED_ARRAY_FUN(Type, type, TYPE, ctype, size) \ 1729 case kExternal##Type##Array: \ 1730 return native_context->type##_array_fun(); 1731 1732 TYPED_ARRAYS(TYPED_ARRAY_FUN) 1733 #undef TYPED_ARRAY_FUN 1734 1735 default: 1736 UNREACHABLE(); 1737 return NULL; 1738 } 1739 } 1740 1741 1742 Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type) { 1743 Handle<JSFunction> typed_array_fun_handle(GetTypedArrayFun(type, isolate())); 1744 1745 CALL_HEAP_FUNCTION( 1746 isolate(), 1747 isolate()->heap()->AllocateJSObject(*typed_array_fun_handle), 1748 JSTypedArray); 1749 } 1750 1751 1752 Handle<JSProxy> Factory::NewJSProxy(Handle<Object> handler, 1753 Handle<Object> prototype) { 1754 // Allocate map. 1755 // TODO(rossberg): Once we optimize proxies, think about a scheme to share 1756 // maps. Will probably depend on the identity of the handler object, too. 1757 Handle<Map> map = NewMap(JS_PROXY_TYPE, JSProxy::kSize); 1758 map->set_prototype(*prototype); 1759 1760 // Allocate the proxy object. 1761 Handle<JSProxy> result = New<JSProxy>(map, NEW_SPACE); 1762 result->InitializeBody(map->instance_size(), Smi::FromInt(0)); 1763 result->set_handler(*handler); 1764 result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER); 1765 return result; 1766 } 1767 1768 1769 Handle<JSProxy> Factory::NewJSFunctionProxy(Handle<Object> handler, 1770 Handle<Object> call_trap, 1771 Handle<Object> construct_trap, 1772 Handle<Object> prototype) { 1773 // Allocate map. 1774 // TODO(rossberg): Once we optimize proxies, think about a scheme to share 1775 // maps. Will probably depend on the identity of the handler object, too. 1776 Handle<Map> map = NewMap(JS_FUNCTION_PROXY_TYPE, JSFunctionProxy::kSize); 1777 map->set_prototype(*prototype); 1778 1779 // Allocate the proxy object. 1780 Handle<JSFunctionProxy> result = New<JSFunctionProxy>(map, NEW_SPACE); 1781 result->InitializeBody(map->instance_size(), Smi::FromInt(0)); 1782 result->set_handler(*handler); 1783 result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER); 1784 result->set_call_trap(*call_trap); 1785 result->set_construct_trap(*construct_trap); 1786 return result; 1787 } 1788 1789 1790 void Factory::ReinitializeJSReceiver(Handle<JSReceiver> object, 1791 InstanceType type, 1792 int size) { 1793 ASSERT(type >= FIRST_JS_OBJECT_TYPE); 1794 1795 // Allocate fresh map. 1796 // TODO(rossberg): Once we optimize proxies, cache these maps. 1797 Handle<Map> map = NewMap(type, size); 1798 1799 // Check that the receiver has at least the size of the fresh object. 1800 int size_difference = object->map()->instance_size() - map->instance_size(); 1801 ASSERT(size_difference >= 0); 1802 1803 map->set_prototype(object->map()->prototype()); 1804 1805 // Allocate the backing storage for the properties. 1806 int prop_size = map->InitialPropertiesLength(); 1807 Handle<FixedArray> properties = NewFixedArray(prop_size, TENURED); 1808 1809 Heap* heap = isolate()->heap(); 1810 MaybeHandle<SharedFunctionInfo> shared; 1811 if (type == JS_FUNCTION_TYPE) { 1812 OneByteStringKey key(STATIC_ASCII_VECTOR("<freezing call trap>"), 1813 heap->HashSeed()); 1814 Handle<String> name = InternalizeStringWithKey(&key); 1815 shared = NewSharedFunctionInfo(name, MaybeHandle<Code>()); 1816 } 1817 1818 // In order to keep heap in consistent state there must be no allocations 1819 // before object re-initialization is finished and filler object is installed. 1820 DisallowHeapAllocation no_allocation; 1821 1822 // Reset the map for the object. 1823 object->set_map(*map); 1824 Handle<JSObject> jsobj = Handle<JSObject>::cast(object); 1825 1826 // Reinitialize the object from the constructor map. 1827 heap->InitializeJSObjectFromMap(*jsobj, *properties, *map); 1828 1829 // Functions require some minimal initialization. 1830 if (type == JS_FUNCTION_TYPE) { 1831 map->set_function_with_prototype(true); 1832 Handle<JSFunction> js_function = Handle<JSFunction>::cast(object); 1833 Handle<Context> context(isolate()->context()->native_context()); 1834 InitializeFunction(js_function, shared.ToHandleChecked(), context); 1835 } 1836 1837 // Put in filler if the new object is smaller than the old. 1838 if (size_difference > 0) { 1839 heap->CreateFillerObjectAt( 1840 object->address() + map->instance_size(), size_difference); 1841 } 1842 } 1843 1844 1845 void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object, 1846 Handle<JSFunction> constructor) { 1847 ASSERT(constructor->has_initial_map()); 1848 Handle<Map> map(constructor->initial_map(), isolate()); 1849 1850 // The proxy's hash should be retained across reinitialization. 1851 Handle<Object> hash(object->hash(), isolate()); 1852 1853 // Check that the already allocated object has the same size and type as 1854 // objects allocated using the constructor. 1855 ASSERT(map->instance_size() == object->map()->instance_size()); 1856 ASSERT(map->instance_type() == object->map()->instance_type()); 1857 1858 // Allocate the backing storage for the properties. 1859 int prop_size = map->InitialPropertiesLength(); 1860 Handle<FixedArray> properties = NewFixedArray(prop_size, TENURED); 1861 1862 // In order to keep heap in consistent state there must be no allocations 1863 // before object re-initialization is finished. 1864 DisallowHeapAllocation no_allocation; 1865 1866 // Reset the map for the object. 1867 object->set_map(constructor->initial_map()); 1868 1869 Heap* heap = isolate()->heap(); 1870 // Reinitialize the object from the constructor map. 1871 heap->InitializeJSObjectFromMap(*object, *properties, *map); 1872 1873 // Restore the saved hash. 1874 object->set_hash(*hash); 1875 } 1876 1877 1878 void Factory::BecomeJSObject(Handle<JSReceiver> object) { 1879 ReinitializeJSReceiver(object, JS_OBJECT_TYPE, JSObject::kHeaderSize); 1880 } 1881 1882 1883 void Factory::BecomeJSFunction(Handle<JSReceiver> object) { 1884 ReinitializeJSReceiver(object, JS_FUNCTION_TYPE, JSFunction::kSize); 1885 } 1886 1887 1888 Handle<FixedArray> Factory::NewTypeFeedbackVector(int slot_count) { 1889 // Ensure we can skip the write barrier 1890 ASSERT_EQ(isolate()->heap()->uninitialized_symbol(), 1891 *TypeFeedbackInfo::UninitializedSentinel(isolate())); 1892 1893 CALL_HEAP_FUNCTION( 1894 isolate(), 1895 isolate()->heap()->AllocateFixedArrayWithFiller( 1896 slot_count, 1897 TENURED, 1898 *TypeFeedbackInfo::UninitializedSentinel(isolate())), 1899 FixedArray); 1900 } 1901 1902 1903 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( 1904 Handle<String> name, 1905 int number_of_literals, 1906 bool is_generator, 1907 Handle<Code> code, 1908 Handle<ScopeInfo> scope_info, 1909 Handle<FixedArray> feedback_vector) { 1910 Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name, code); 1911 shared->set_scope_info(*scope_info); 1912 shared->set_feedback_vector(*feedback_vector); 1913 int literals_array_size = number_of_literals; 1914 // If the function contains object, regexp or array literals, 1915 // allocate extra space for a literals array prefix containing the 1916 // context. 1917 if (number_of_literals > 0) { 1918 literals_array_size += JSFunction::kLiteralsPrefixSize; 1919 } 1920 shared->set_num_literals(literals_array_size); 1921 if (is_generator) { 1922 shared->set_instance_class_name(isolate()->heap()->Generator_string()); 1923 shared->DisableOptimization(kGenerator); 1924 } 1925 return shared; 1926 } 1927 1928 1929 Handle<JSMessageObject> Factory::NewJSMessageObject( 1930 Handle<String> type, 1931 Handle<JSArray> arguments, 1932 int start_position, 1933 int end_position, 1934 Handle<Object> script, 1935 Handle<Object> stack_frames) { 1936 Handle<Map> map = message_object_map(); 1937 Handle<JSMessageObject> message = New<JSMessageObject>(map, NEW_SPACE); 1938 message->set_properties(*empty_fixed_array(), SKIP_WRITE_BARRIER); 1939 message->initialize_elements(); 1940 message->set_elements(*empty_fixed_array(), SKIP_WRITE_BARRIER); 1941 message->set_type(*type); 1942 message->set_arguments(*arguments); 1943 message->set_start_position(start_position); 1944 message->set_end_position(end_position); 1945 message->set_script(*script); 1946 message->set_stack_frames(*stack_frames); 1947 return message; 1948 } 1949 1950 1951 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( 1952 Handle<String> name, 1953 MaybeHandle<Code> maybe_code) { 1954 Handle<Map> map = shared_function_info_map(); 1955 Handle<SharedFunctionInfo> share = New<SharedFunctionInfo>(map, 1956 OLD_POINTER_SPACE); 1957 1958 // Set pointer fields. 1959 share->set_name(*name); 1960 Handle<Code> code; 1961 if (!maybe_code.ToHandle(&code)) { 1962 code = handle(isolate()->builtins()->builtin(Builtins::kIllegal)); 1963 } 1964 share->set_code(*code); 1965 share->set_optimized_code_map(Smi::FromInt(0)); 1966 share->set_scope_info(ScopeInfo::Empty(isolate())); 1967 Code* construct_stub = 1968 isolate()->builtins()->builtin(Builtins::kJSConstructStubGeneric); 1969 share->set_construct_stub(construct_stub); 1970 share->set_instance_class_name(*Object_string()); 1971 share->set_function_data(*undefined_value(), SKIP_WRITE_BARRIER); 1972 share->set_script(*undefined_value(), SKIP_WRITE_BARRIER); 1973 share->set_debug_info(*undefined_value(), SKIP_WRITE_BARRIER); 1974 share->set_inferred_name(*empty_string(), SKIP_WRITE_BARRIER); 1975 share->set_feedback_vector(*empty_fixed_array(), SKIP_WRITE_BARRIER); 1976 share->set_profiler_ticks(0); 1977 share->set_ast_node_count(0); 1978 share->set_counters(0); 1979 1980 // Set integer fields (smi or int, depending on the architecture). 1981 share->set_length(0); 1982 share->set_formal_parameter_count(0); 1983 share->set_expected_nof_properties(0); 1984 share->set_num_literals(0); 1985 share->set_start_position_and_type(0); 1986 share->set_end_position(0); 1987 share->set_function_token_position(0); 1988 // All compiler hints default to false or 0. 1989 share->set_compiler_hints(0); 1990 share->set_opt_count_and_bailout_reason(0); 1991 1992 return share; 1993 } 1994 1995 1996 static inline int NumberCacheHash(Handle<FixedArray> cache, 1997 Handle<Object> number) { 1998 int mask = (cache->length() >> 1) - 1; 1999 if (number->IsSmi()) { 2000 return Handle<Smi>::cast(number)->value() & mask; 2001 } else { 2002 DoubleRepresentation rep(number->Number()); 2003 return 2004 (static_cast<int>(rep.bits) ^ static_cast<int>(rep.bits >> 32)) & mask; 2005 } 2006 } 2007 2008 2009 Handle<Object> Factory::GetNumberStringCache(Handle<Object> number) { 2010 DisallowHeapAllocation no_gc; 2011 int hash = NumberCacheHash(number_string_cache(), number); 2012 Object* key = number_string_cache()->get(hash * 2); 2013 if (key == *number || (key->IsHeapNumber() && number->IsHeapNumber() && 2014 key->Number() == number->Number())) { 2015 return Handle<String>( 2016 String::cast(number_string_cache()->get(hash * 2 + 1)), isolate()); 2017 } 2018 return undefined_value(); 2019 } 2020 2021 2022 void Factory::SetNumberStringCache(Handle<Object> number, 2023 Handle<String> string) { 2024 int hash = NumberCacheHash(number_string_cache(), number); 2025 if (number_string_cache()->get(hash * 2) != *undefined_value()) { 2026 int full_size = isolate()->heap()->FullSizeNumberStringCacheLength(); 2027 if (number_string_cache()->length() != full_size) { 2028 // The first time we have a hash collision, we move to the full sized 2029 // number string cache. The idea is to have a small number string 2030 // cache in the snapshot to keep boot-time memory usage down. 2031 // If we expand the number string cache already while creating 2032 // the snapshot then that didn't work out. 2033 ASSERT(!isolate()->serializer_enabled() || FLAG_extra_code != NULL); 2034 Handle<FixedArray> new_cache = NewFixedArray(full_size, TENURED); 2035 isolate()->heap()->set_number_string_cache(*new_cache); 2036 return; 2037 } 2038 } 2039 number_string_cache()->set(hash * 2, *number); 2040 number_string_cache()->set(hash * 2 + 1, *string); 2041 } 2042 2043 2044 Handle<String> Factory::NumberToString(Handle<Object> number, 2045 bool check_number_string_cache) { 2046 isolate()->counters()->number_to_string_runtime()->Increment(); 2047 if (check_number_string_cache) { 2048 Handle<Object> cached = GetNumberStringCache(number); 2049 if (!cached->IsUndefined()) return Handle<String>::cast(cached); 2050 } 2051 2052 char arr[100]; 2053 Vector<char> buffer(arr, ARRAY_SIZE(arr)); 2054 const char* str; 2055 if (number->IsSmi()) { 2056 int num = Handle<Smi>::cast(number)->value(); 2057 str = IntToCString(num, buffer); 2058 } else { 2059 double num = Handle<HeapNumber>::cast(number)->value(); 2060 str = DoubleToCString(num, buffer); 2061 } 2062 2063 // We tenure the allocated string since it is referenced from the 2064 // number-string cache which lives in the old space. 2065 Handle<String> js_string = NewStringFromAsciiChecked(str, TENURED); 2066 SetNumberStringCache(number, js_string); 2067 return js_string; 2068 } 2069 2070 2071 Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { 2072 // Get the original code of the function. 2073 Handle<Code> code(shared->code()); 2074 2075 // Create a copy of the code before allocating the debug info object to avoid 2076 // allocation while setting up the debug info object. 2077 Handle<Code> original_code(*Factory::CopyCode(code)); 2078 2079 // Allocate initial fixed array for active break points before allocating the 2080 // debug info object to avoid allocation while setting up the debug info 2081 // object. 2082 Handle<FixedArray> break_points( 2083 NewFixedArray(DebugInfo::kEstimatedNofBreakPointsInFunction)); 2084 2085 // Create and set up the debug info object. Debug info contains function, a 2086 // copy of the original code, the executing code and initial fixed array for 2087 // active break points. 2088 Handle<DebugInfo> debug_info = 2089 Handle<DebugInfo>::cast(NewStruct(DEBUG_INFO_TYPE)); 2090 debug_info->set_shared(*shared); 2091 debug_info->set_original_code(*original_code); 2092 debug_info->set_code(*code); 2093 debug_info->set_break_points(*break_points); 2094 2095 // Link debug info to function. 2096 shared->set_debug_info(*debug_info); 2097 2098 return debug_info; 2099 } 2100 2101 2102 Handle<JSObject> Factory::NewArgumentsObject(Handle<Object> callee, 2103 int length) { 2104 CALL_HEAP_FUNCTION( 2105 isolate(), 2106 isolate()->heap()->AllocateArgumentsObject(*callee, length), JSObject); 2107 } 2108 2109 2110 Handle<JSFunction> Factory::CreateApiFunction( 2111 Handle<FunctionTemplateInfo> obj, 2112 Handle<Object> prototype, 2113 ApiInstanceType instance_type) { 2114 Handle<Code> code = isolate()->builtins()->HandleApiCall(); 2115 Handle<Code> construct_stub = isolate()->builtins()->JSConstructStubApi(); 2116 2117 Handle<JSFunction> result; 2118 if (obj->remove_prototype()) { 2119 result = NewFunctionWithoutPrototype(empty_string(), code); 2120 } else { 2121 int internal_field_count = 0; 2122 if (!obj->instance_template()->IsUndefined()) { 2123 Handle<ObjectTemplateInfo> instance_template = 2124 Handle<ObjectTemplateInfo>( 2125 ObjectTemplateInfo::cast(obj->instance_template())); 2126 internal_field_count = 2127 Smi::cast(instance_template->internal_field_count())->value(); 2128 } 2129 2130 // TODO(svenpanne) Kill ApiInstanceType and refactor things by generalizing 2131 // JSObject::GetHeaderSize. 2132 int instance_size = kPointerSize * internal_field_count; 2133 InstanceType type; 2134 switch (instance_type) { 2135 case JavaScriptObject: 2136 type = JS_OBJECT_TYPE; 2137 instance_size += JSObject::kHeaderSize; 2138 break; 2139 case InnerGlobalObject: 2140 type = JS_GLOBAL_OBJECT_TYPE; 2141 instance_size += JSGlobalObject::kSize; 2142 break; 2143 case OuterGlobalObject: 2144 type = JS_GLOBAL_PROXY_TYPE; 2145 instance_size += JSGlobalProxy::kSize; 2146 break; 2147 default: 2148 UNREACHABLE(); 2149 type = JS_OBJECT_TYPE; // Keep the compiler happy. 2150 break; 2151 } 2152 2153 result = NewFunction(empty_string(), code, prototype, type, 2154 instance_size, obj->read_only_prototype()); 2155 } 2156 2157 result->shared()->set_length(obj->length()); 2158 Handle<Object> class_name(obj->class_name(), isolate()); 2159 if (class_name->IsString()) { 2160 result->shared()->set_instance_class_name(*class_name); 2161 result->shared()->set_name(*class_name); 2162 } 2163 result->shared()->set_function_data(*obj); 2164 result->shared()->set_construct_stub(*construct_stub); 2165 result->shared()->DontAdaptArguments(); 2166 2167 if (obj->remove_prototype()) { 2168 ASSERT(result->shared()->IsApiFunction()); 2169 ASSERT(!result->has_initial_map()); 2170 ASSERT(!result->has_prototype()); 2171 return result; 2172 } 2173 2174 JSObject::SetOwnPropertyIgnoreAttributes( 2175 handle(JSObject::cast(result->prototype())), 2176 constructor_string(), 2177 result, 2178 DONT_ENUM).Assert(); 2179 2180 // Down from here is only valid for API functions that can be used as a 2181 // constructor (don't set the "remove prototype" flag). 2182 2183 Handle<Map> map(result->initial_map()); 2184 2185 // Mark as undetectable if needed. 2186 if (obj->undetectable()) { 2187 map->set_is_undetectable(); 2188 } 2189 2190 // Mark as hidden for the __proto__ accessor if needed. 2191 if (obj->hidden_prototype()) { 2192 map->set_is_hidden_prototype(); 2193 } 2194 2195 // Mark as needs_access_check if needed. 2196 if (obj->needs_access_check()) { 2197 map->set_is_access_check_needed(true); 2198 } 2199 2200 // Set interceptor information in the map. 2201 if (!obj->named_property_handler()->IsUndefined()) { 2202 map->set_has_named_interceptor(); 2203 } 2204 if (!obj->indexed_property_handler()->IsUndefined()) { 2205 map->set_has_indexed_interceptor(); 2206 } 2207 2208 // Set instance call-as-function information in the map. 2209 if (!obj->instance_call_handler()->IsUndefined()) { 2210 map->set_has_instance_call_handler(); 2211 } 2212 2213 // Recursively copy parent instance templates' accessors, 2214 // 'data' may be modified. 2215 int max_number_of_additional_properties = 0; 2216 int max_number_of_static_properties = 0; 2217 FunctionTemplateInfo* info = *obj; 2218 while (true) { 2219 if (!info->instance_template()->IsUndefined()) { 2220 Object* props = 2221 ObjectTemplateInfo::cast( 2222 info->instance_template())->property_accessors(); 2223 if (!props->IsUndefined()) { 2224 Handle<Object> props_handle(props, isolate()); 2225 NeanderArray props_array(props_handle); 2226 max_number_of_additional_properties += props_array.length(); 2227 } 2228 } 2229 if (!info->property_accessors()->IsUndefined()) { 2230 Object* props = info->property_accessors(); 2231 if (!props->IsUndefined()) { 2232 Handle<Object> props_handle(props, isolate()); 2233 NeanderArray props_array(props_handle); 2234 max_number_of_static_properties += props_array.length(); 2235 } 2236 } 2237 Object* parent = info->parent_template(); 2238 if (parent->IsUndefined()) break; 2239 info = FunctionTemplateInfo::cast(parent); 2240 } 2241 2242 Map::EnsureDescriptorSlack(map, max_number_of_additional_properties); 2243 2244 // Use a temporary FixedArray to acculumate static accessors 2245 int valid_descriptors = 0; 2246 Handle<FixedArray> array; 2247 if (max_number_of_static_properties > 0) { 2248 array = NewFixedArray(max_number_of_static_properties); 2249 } 2250 2251 while (true) { 2252 // Install instance descriptors 2253 if (!obj->instance_template()->IsUndefined()) { 2254 Handle<ObjectTemplateInfo> instance = 2255 Handle<ObjectTemplateInfo>( 2256 ObjectTemplateInfo::cast(obj->instance_template()), isolate()); 2257 Handle<Object> props = Handle<Object>(instance->property_accessors(), 2258 isolate()); 2259 if (!props->IsUndefined()) { 2260 Map::AppendCallbackDescriptors(map, props); 2261 } 2262 } 2263 // Accumulate static accessors 2264 if (!obj->property_accessors()->IsUndefined()) { 2265 Handle<Object> props = Handle<Object>(obj->property_accessors(), 2266 isolate()); 2267 valid_descriptors = 2268 AccessorInfo::AppendUnique(props, array, valid_descriptors); 2269 } 2270 // Climb parent chain 2271 Handle<Object> parent = Handle<Object>(obj->parent_template(), isolate()); 2272 if (parent->IsUndefined()) break; 2273 obj = Handle<FunctionTemplateInfo>::cast(parent); 2274 } 2275 2276 // Install accumulated static accessors 2277 for (int i = 0; i < valid_descriptors; i++) { 2278 Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i))); 2279 JSObject::SetAccessor(result, accessor).Assert(); 2280 } 2281 2282 ASSERT(result->shared()->IsApiFunction()); 2283 return result; 2284 } 2285 2286 2287 Handle<MapCache> Factory::AddToMapCache(Handle<Context> context, 2288 Handle<FixedArray> keys, 2289 Handle<Map> map) { 2290 Handle<MapCache> map_cache = handle(MapCache::cast(context->map_cache())); 2291 Handle<MapCache> result = MapCache::Put(map_cache, keys, map); 2292 context->set_map_cache(*result); 2293 return result; 2294 } 2295 2296 2297 Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context, 2298 Handle<FixedArray> keys) { 2299 if (context->map_cache()->IsUndefined()) { 2300 // Allocate the new map cache for the native context. 2301 Handle<MapCache> new_cache = MapCache::New(isolate(), 24); 2302 context->set_map_cache(*new_cache); 2303 } 2304 // Check to see whether there is a matching element in the cache. 2305 Handle<MapCache> cache = 2306 Handle<MapCache>(MapCache::cast(context->map_cache())); 2307 Handle<Object> result = Handle<Object>(cache->Lookup(*keys), isolate()); 2308 if (result->IsMap()) return Handle<Map>::cast(result); 2309 // Create a new map and add it to the cache. 2310 Handle<Map> map = Map::Create( 2311 handle(context->object_function()), keys->length()); 2312 AddToMapCache(context, keys, map); 2313 return map; 2314 } 2315 2316 2317 void Factory::SetRegExpAtomData(Handle<JSRegExp> regexp, 2318 JSRegExp::Type type, 2319 Handle<String> source, 2320 JSRegExp::Flags flags, 2321 Handle<Object> data) { 2322 Handle<FixedArray> store = NewFixedArray(JSRegExp::kAtomDataSize); 2323 2324 store->set(JSRegExp::kTagIndex, Smi::FromInt(type)); 2325 store->set(JSRegExp::kSourceIndex, *source); 2326 store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags.value())); 2327 store->set(JSRegExp::kAtomPatternIndex, *data); 2328 regexp->set_data(*store); 2329 } 2330 2331 void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp, 2332 JSRegExp::Type type, 2333 Handle<String> source, 2334 JSRegExp::Flags flags, 2335 int capture_count) { 2336 Handle<FixedArray> store = NewFixedArray(JSRegExp::kIrregexpDataSize); 2337 Smi* uninitialized = Smi::FromInt(JSRegExp::kUninitializedValue); 2338 store->set(JSRegExp::kTagIndex, Smi::FromInt(type)); 2339 store->set(JSRegExp::kSourceIndex, *source); 2340 store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags.value())); 2341 store->set(JSRegExp::kIrregexpASCIICodeIndex, uninitialized); 2342 store->set(JSRegExp::kIrregexpUC16CodeIndex, uninitialized); 2343 store->set(JSRegExp::kIrregexpASCIICodeSavedIndex, uninitialized); 2344 store->set(JSRegExp::kIrregexpUC16CodeSavedIndex, uninitialized); 2345 store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::FromInt(0)); 2346 store->set(JSRegExp::kIrregexpCaptureCountIndex, 2347 Smi::FromInt(capture_count)); 2348 regexp->set_data(*store); 2349 } 2350 2351 2352 2353 MaybeHandle<FunctionTemplateInfo> Factory::ConfigureInstance( 2354 Handle<FunctionTemplateInfo> desc, Handle<JSObject> instance) { 2355 // Configure the instance by adding the properties specified by the 2356 // instance template. 2357 Handle<Object> instance_template(desc->instance_template(), isolate()); 2358 if (!instance_template->IsUndefined()) { 2359 RETURN_ON_EXCEPTION( 2360 isolate(), 2361 Execution::ConfigureInstance(isolate(), instance, instance_template), 2362 FunctionTemplateInfo); 2363 } 2364 return desc; 2365 } 2366 2367 2368 Handle<Object> Factory::GlobalConstantFor(Handle<String> name) { 2369 if (String::Equals(name, undefined_string())) return undefined_value(); 2370 if (String::Equals(name, nan_string())) return nan_value(); 2371 if (String::Equals(name, infinity_string())) return infinity_value(); 2372 return Handle<Object>::null(); 2373 } 2374 2375 2376 Handle<Object> Factory::ToBoolean(bool value) { 2377 return value ? true_value() : false_value(); 2378 } 2379 2380 2381 } } // namespace v8::internal 2382