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/accessors.h" 8 #include "src/allocation-site-scopes.h" 9 #include "src/ast/ast.h" 10 #include "src/base/bits.h" 11 #include "src/bootstrapper.h" 12 #include "src/compiler.h" 13 #include "src/conversions.h" 14 #include "src/isolate-inl.h" 15 #include "src/macro-assembler.h" 16 #include "src/objects/module-info.h" 17 #include "src/objects/scope-info.h" 18 19 namespace v8 { 20 namespace internal { 21 22 23 // Calls the FUNCTION_CALL function and retries it up to three times 24 // to guarantee that any allocations performed during the call will 25 // succeed if there's enough memory. 26 // 27 // Warning: Do not use the identifiers __object__, __maybe_object__, 28 // __allocation__ or __scope__ in a call to this macro. 29 30 #define RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \ 31 if (__allocation__.To(&__object__)) { \ 32 DCHECK(__object__ != (ISOLATE)->heap()->exception()); \ 33 return Handle<TYPE>(TYPE::cast(__object__), ISOLATE); \ 34 } 35 36 #define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE) \ 37 do { \ 38 AllocationResult __allocation__ = FUNCTION_CALL; \ 39 Object* __object__ = NULL; \ 40 RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \ 41 /* Two GCs before panicking. In newspace will almost always succeed. */ \ 42 for (int __i__ = 0; __i__ < 2; __i__++) { \ 43 (ISOLATE)->heap()->CollectGarbage( \ 44 __allocation__.RetrySpace(), \ 45 GarbageCollectionReason::kAllocationFailure); \ 46 __allocation__ = FUNCTION_CALL; \ 47 RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \ 48 } \ 49 (ISOLATE)->counters()->gc_last_resort_from_handles()->Increment(); \ 50 (ISOLATE)->heap()->CollectAllAvailableGarbage( \ 51 GarbageCollectionReason::kLastResort); \ 52 { \ 53 AlwaysAllocateScope __scope__(ISOLATE); \ 54 __allocation__ = FUNCTION_CALL; \ 55 } \ 56 RETURN_OBJECT_UNLESS_RETRY(ISOLATE, TYPE) \ 57 /* TODO(1181417): Fix this. */ \ 58 v8::internal::Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); \ 59 return Handle<TYPE>(); \ 60 } while (false) 61 62 template<typename T> 63 Handle<T> Factory::New(Handle<Map> map, AllocationSpace space) { 64 CALL_HEAP_FUNCTION( 65 isolate(), 66 isolate()->heap()->Allocate(*map, space), 67 T); 68 } 69 70 71 template<typename T> 72 Handle<T> Factory::New(Handle<Map> map, 73 AllocationSpace space, 74 Handle<AllocationSite> allocation_site) { 75 CALL_HEAP_FUNCTION( 76 isolate(), 77 isolate()->heap()->Allocate(*map, space, *allocation_site), 78 T); 79 } 80 81 82 Handle<HeapObject> Factory::NewFillerObject(int size, 83 bool double_align, 84 AllocationSpace space) { 85 CALL_HEAP_FUNCTION( 86 isolate(), 87 isolate()->heap()->AllocateFillerObject(size, double_align, space), 88 HeapObject); 89 } 90 91 92 Handle<PrototypeInfo> Factory::NewPrototypeInfo() { 93 Handle<PrototypeInfo> result = 94 Handle<PrototypeInfo>::cast(NewStruct(PROTOTYPE_INFO_TYPE)); 95 result->set_prototype_users(WeakFixedArray::Empty()); 96 result->set_registry_slot(PrototypeInfo::UNREGISTERED); 97 result->set_validity_cell(Smi::kZero); 98 result->set_bit_field(0); 99 return result; 100 } 101 102 Handle<Tuple2> Factory::NewTuple2(Handle<Object> value1, 103 Handle<Object> value2) { 104 Handle<Tuple2> result = Handle<Tuple2>::cast(NewStruct(TUPLE2_TYPE)); 105 result->set_value1(*value1); 106 result->set_value2(*value2); 107 return result; 108 } 109 110 Handle<Tuple3> Factory::NewTuple3(Handle<Object> value1, Handle<Object> value2, 111 Handle<Object> value3) { 112 Handle<Tuple3> result = Handle<Tuple3>::cast(NewStruct(TUPLE3_TYPE)); 113 result->set_value1(*value1); 114 result->set_value2(*value2); 115 result->set_value3(*value3); 116 return result; 117 } 118 119 Handle<ContextExtension> Factory::NewContextExtension( 120 Handle<ScopeInfo> scope_info, Handle<Object> extension) { 121 Handle<ContextExtension> result = 122 Handle<ContextExtension>::cast(NewStruct(CONTEXT_EXTENSION_TYPE)); 123 result->set_scope_info(*scope_info); 124 result->set_extension(*extension); 125 return result; 126 } 127 128 Handle<ConstantElementsPair> Factory::NewConstantElementsPair( 129 ElementsKind elements_kind, Handle<FixedArrayBase> constant_values) { 130 Handle<ConstantElementsPair> result = Handle<ConstantElementsPair>::cast( 131 NewStruct(CONSTANT_ELEMENTS_PAIR_TYPE)); 132 result->set_elements_kind(elements_kind); 133 result->set_constant_values(*constant_values); 134 return result; 135 } 136 137 Handle<Oddball> Factory::NewOddball(Handle<Map> map, const char* to_string, 138 Handle<Object> to_number, 139 const char* type_of, byte kind) { 140 Handle<Oddball> oddball = New<Oddball>(map, OLD_SPACE); 141 Oddball::Initialize(isolate(), oddball, to_string, to_number, type_of, kind); 142 return oddball; 143 } 144 145 146 Handle<FixedArray> Factory::NewFixedArray(int size, PretenureFlag pretenure) { 147 DCHECK(0 <= size); 148 CALL_HEAP_FUNCTION( 149 isolate(), 150 isolate()->heap()->AllocateFixedArray(size, pretenure), 151 FixedArray); 152 } 153 154 MaybeHandle<FixedArray> Factory::TryNewFixedArray(int size, 155 PretenureFlag pretenure) { 156 DCHECK(0 <= size); 157 AllocationResult allocation = 158 isolate()->heap()->AllocateFixedArray(size, pretenure); 159 Object* array = NULL; 160 if (!allocation.To(&array)) return MaybeHandle<FixedArray>(); 161 return Handle<FixedArray>(FixedArray::cast(array), isolate()); 162 } 163 164 Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size, 165 PretenureFlag pretenure) { 166 DCHECK(0 <= size); 167 CALL_HEAP_FUNCTION( 168 isolate(), 169 isolate()->heap()->AllocateFixedArrayWithFiller(size, 170 pretenure, 171 *the_hole_value()), 172 FixedArray); 173 } 174 175 Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) { 176 CALL_HEAP_FUNCTION( 177 isolate(), 178 isolate()->heap()->AllocateUninitializedFixedArray(size), 179 FixedArray); 180 } 181 182 Handle<BoilerplateDescription> Factory::NewBoilerplateDescription( 183 int boilerplate, int all_properties, int index_keys, bool has_seen_proto) { 184 DCHECK_GE(boilerplate, 0); 185 DCHECK_GE(all_properties, index_keys); 186 DCHECK_GE(index_keys, 0); 187 188 int backing_store_size = 189 all_properties - index_keys - (has_seen_proto ? 1 : 0); 190 DCHECK_GE(backing_store_size, 0); 191 bool has_different_size_backing_store = boilerplate != backing_store_size; 192 193 // Space for name and value for every boilerplate property. 194 int size = 2 * boilerplate; 195 196 if (has_different_size_backing_store) { 197 // An extra entry for the backing store size. 198 size++; 199 } 200 201 Handle<BoilerplateDescription> description = 202 Handle<BoilerplateDescription>::cast(NewFixedArray(size, TENURED)); 203 204 if (has_different_size_backing_store) { 205 DCHECK((boilerplate != (all_properties - index_keys)) || has_seen_proto); 206 description->set_backing_store_size(isolate(), backing_store_size); 207 } 208 return description; 209 } 210 211 Handle<FixedArrayBase> Factory::NewFixedDoubleArray(int size, 212 PretenureFlag pretenure) { 213 DCHECK(0 <= size); 214 CALL_HEAP_FUNCTION( 215 isolate(), 216 isolate()->heap()->AllocateUninitializedFixedDoubleArray(size, pretenure), 217 FixedArrayBase); 218 } 219 220 221 Handle<FixedArrayBase> Factory::NewFixedDoubleArrayWithHoles( 222 int size, 223 PretenureFlag pretenure) { 224 DCHECK(0 <= size); 225 Handle<FixedArrayBase> array = NewFixedDoubleArray(size, pretenure); 226 if (size > 0) { 227 Handle<FixedDoubleArray>::cast(array)->FillWithHoles(0, size); 228 } 229 return array; 230 } 231 232 Handle<FrameArray> Factory::NewFrameArray(int number_of_frames, 233 PretenureFlag pretenure) { 234 DCHECK_LE(0, number_of_frames); 235 Handle<FixedArray> result = 236 NewFixedArrayWithHoles(FrameArray::LengthFor(number_of_frames)); 237 result->set(FrameArray::kFrameCountIndex, Smi::kZero); 238 return Handle<FrameArray>::cast(result); 239 } 240 241 Handle<OrderedHashSet> Factory::NewOrderedHashSet() { 242 return OrderedHashSet::Allocate(isolate(), OrderedHashSet::kMinCapacity); 243 } 244 245 246 Handle<OrderedHashMap> Factory::NewOrderedHashMap() { 247 return OrderedHashMap::Allocate(isolate(), OrderedHashMap::kMinCapacity); 248 } 249 250 251 Handle<AccessorPair> Factory::NewAccessorPair() { 252 Handle<AccessorPair> accessors = 253 Handle<AccessorPair>::cast(NewStruct(ACCESSOR_PAIR_TYPE)); 254 accessors->set_getter(*null_value(), SKIP_WRITE_BARRIER); 255 accessors->set_setter(*null_value(), SKIP_WRITE_BARRIER); 256 return accessors; 257 } 258 259 260 Handle<TypeFeedbackInfo> Factory::NewTypeFeedbackInfo() { 261 Handle<TypeFeedbackInfo> info = 262 Handle<TypeFeedbackInfo>::cast(NewStruct(TYPE_FEEDBACK_INFO_TYPE)); 263 info->initialize_storage(); 264 return info; 265 } 266 267 268 // Internalized strings are created in the old generation (data space). 269 Handle<String> Factory::InternalizeUtf8String(Vector<const char> string) { 270 Utf8StringKey key(string, isolate()->heap()->HashSeed()); 271 return InternalizeStringWithKey(&key); 272 } 273 274 275 Handle<String> Factory::InternalizeOneByteString(Vector<const uint8_t> string) { 276 OneByteStringKey key(string, isolate()->heap()->HashSeed()); 277 return InternalizeStringWithKey(&key); 278 } 279 280 281 Handle<String> Factory::InternalizeOneByteString( 282 Handle<SeqOneByteString> string, int from, int length) { 283 SeqOneByteSubStringKey key(string, from, length); 284 return InternalizeStringWithKey(&key); 285 } 286 287 288 Handle<String> Factory::InternalizeTwoByteString(Vector<const uc16> string) { 289 TwoByteStringKey key(string, isolate()->heap()->HashSeed()); 290 return InternalizeStringWithKey(&key); 291 } 292 293 294 template<class StringTableKey> 295 Handle<String> Factory::InternalizeStringWithKey(StringTableKey* key) { 296 return StringTable::LookupKey(isolate(), key); 297 } 298 299 300 MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string, 301 PretenureFlag pretenure) { 302 int length = string.length(); 303 if (length == 0) return empty_string(); 304 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); 305 Handle<SeqOneByteString> result; 306 ASSIGN_RETURN_ON_EXCEPTION( 307 isolate(), 308 result, 309 NewRawOneByteString(string.length(), pretenure), 310 String); 311 312 DisallowHeapAllocation no_gc; 313 // Copy the characters into the new object. 314 CopyChars(SeqOneByteString::cast(*result)->GetChars(), 315 string.start(), 316 length); 317 return result; 318 } 319 320 MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string, 321 PretenureFlag pretenure) { 322 // Check for ASCII first since this is the common case. 323 const char* start = string.start(); 324 int length = string.length(); 325 int non_ascii_start = String::NonAsciiStart(start, length); 326 if (non_ascii_start >= length) { 327 // If the string is ASCII, we do not need to convert the characters 328 // since UTF8 is backwards compatible with ASCII. 329 return NewStringFromOneByte(Vector<const uint8_t>::cast(string), pretenure); 330 } 331 332 // Non-ASCII and we need to decode. 333 Access<UnicodeCache::Utf8Decoder> 334 decoder(isolate()->unicode_cache()->utf8_decoder()); 335 decoder->Reset(string.start() + non_ascii_start, 336 length - non_ascii_start); 337 int utf16_length = static_cast<int>(decoder->Utf16Length()); 338 DCHECK(utf16_length > 0); 339 // Allocate string. 340 Handle<SeqTwoByteString> result; 341 ASSIGN_RETURN_ON_EXCEPTION( 342 isolate(), result, 343 NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), 344 String); 345 // Copy ASCII portion. 346 uint16_t* data = result->GetChars(); 347 const char* ascii_data = string.start(); 348 for (int i = 0; i < non_ascii_start; i++) { 349 *data++ = *ascii_data++; 350 } 351 // Now write the remainder. 352 decoder->WriteUtf16(data, utf16_length); 353 return result; 354 } 355 356 MaybeHandle<String> Factory::NewStringFromUtf8SubString( 357 Handle<SeqOneByteString> str, int begin, int length, 358 PretenureFlag pretenure) { 359 // Check for ASCII first since this is the common case. 360 const char* start = reinterpret_cast<const char*>(str->GetChars() + begin); 361 int non_ascii_start = String::NonAsciiStart(start, length); 362 if (non_ascii_start >= length) { 363 // If the string is ASCII, we can just make a substring. 364 // TODO(v8): the pretenure flag is ignored in this case. 365 return NewSubString(str, begin, begin + length); 366 } 367 368 // Non-ASCII and we need to decode. 369 Access<UnicodeCache::Utf8Decoder> decoder( 370 isolate()->unicode_cache()->utf8_decoder()); 371 decoder->Reset(start + non_ascii_start, length - non_ascii_start); 372 int utf16_length = static_cast<int>(decoder->Utf16Length()); 373 DCHECK(utf16_length > 0); 374 // Allocate string. 375 Handle<SeqTwoByteString> result; 376 ASSIGN_RETURN_ON_EXCEPTION( 377 isolate(), result, 378 NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), String); 379 380 // Reset the decoder, because the original {str} may have moved. 381 const char* ascii_data = 382 reinterpret_cast<const char*>(str->GetChars() + begin); 383 decoder->Reset(ascii_data + non_ascii_start, length - non_ascii_start); 384 // Copy ASCII portion. 385 uint16_t* data = result->GetChars(); 386 for (int i = 0; i < non_ascii_start; i++) { 387 *data++ = *ascii_data++; 388 } 389 // Now write the remainder. 390 decoder->WriteUtf16(data, utf16_length); 391 return result; 392 } 393 394 MaybeHandle<String> Factory::NewStringFromTwoByte(const uc16* string, 395 int length, 396 PretenureFlag pretenure) { 397 if (length == 0) return empty_string(); 398 if (String::IsOneByte(string, length)) { 399 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]); 400 Handle<SeqOneByteString> result; 401 ASSIGN_RETURN_ON_EXCEPTION( 402 isolate(), 403 result, 404 NewRawOneByteString(length, pretenure), 405 String); 406 CopyChars(result->GetChars(), string, length); 407 return result; 408 } else { 409 Handle<SeqTwoByteString> result; 410 ASSIGN_RETURN_ON_EXCEPTION( 411 isolate(), 412 result, 413 NewRawTwoByteString(length, pretenure), 414 String); 415 CopyChars(result->GetChars(), string, length); 416 return result; 417 } 418 } 419 420 MaybeHandle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string, 421 PretenureFlag pretenure) { 422 return NewStringFromTwoByte(string.start(), string.length(), pretenure); 423 } 424 425 MaybeHandle<String> Factory::NewStringFromTwoByte( 426 const ZoneVector<uc16>* string, PretenureFlag pretenure) { 427 return NewStringFromTwoByte(string->data(), static_cast<int>(string->size()), 428 pretenure); 429 } 430 431 Handle<String> Factory::NewInternalizedStringFromUtf8(Vector<const char> str, 432 int chars, 433 uint32_t hash_field) { 434 CALL_HEAP_FUNCTION( 435 isolate(), 436 isolate()->heap()->AllocateInternalizedStringFromUtf8( 437 str, chars, hash_field), 438 String); 439 } 440 441 442 MUST_USE_RESULT Handle<String> Factory::NewOneByteInternalizedString( 443 Vector<const uint8_t> str, 444 uint32_t hash_field) { 445 CALL_HEAP_FUNCTION( 446 isolate(), 447 isolate()->heap()->AllocateOneByteInternalizedString(str, hash_field), 448 String); 449 } 450 451 452 MUST_USE_RESULT Handle<String> Factory::NewOneByteInternalizedSubString( 453 Handle<SeqOneByteString> string, int offset, int length, 454 uint32_t hash_field) { 455 CALL_HEAP_FUNCTION( 456 isolate(), isolate()->heap()->AllocateOneByteInternalizedString( 457 Vector<const uint8_t>(string->GetChars() + offset, length), 458 hash_field), 459 String); 460 } 461 462 463 MUST_USE_RESULT Handle<String> Factory::NewTwoByteInternalizedString( 464 Vector<const uc16> str, 465 uint32_t hash_field) { 466 CALL_HEAP_FUNCTION( 467 isolate(), 468 isolate()->heap()->AllocateTwoByteInternalizedString(str, hash_field), 469 String); 470 } 471 472 473 Handle<String> Factory::NewInternalizedStringImpl( 474 Handle<String> string, int chars, uint32_t hash_field) { 475 CALL_HEAP_FUNCTION( 476 isolate(), 477 isolate()->heap()->AllocateInternalizedStringImpl( 478 *string, chars, hash_field), 479 String); 480 } 481 482 namespace { 483 484 MaybeHandle<Map> GetInternalizedStringMap(Factory* f, Handle<String> string) { 485 switch (string->map()->instance_type()) { 486 case STRING_TYPE: 487 return f->internalized_string_map(); 488 case ONE_BYTE_STRING_TYPE: 489 return f->one_byte_internalized_string_map(); 490 case EXTERNAL_STRING_TYPE: 491 return f->external_internalized_string_map(); 492 case EXTERNAL_ONE_BYTE_STRING_TYPE: 493 return f->external_one_byte_internalized_string_map(); 494 case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: 495 return f->external_internalized_string_with_one_byte_data_map(); 496 case SHORT_EXTERNAL_STRING_TYPE: 497 return f->short_external_internalized_string_map(); 498 case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE: 499 return f->short_external_one_byte_internalized_string_map(); 500 case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: 501 return f->short_external_internalized_string_with_one_byte_data_map(); 502 default: return MaybeHandle<Map>(); // No match found. 503 } 504 } 505 506 } // namespace 507 508 MaybeHandle<Map> Factory::InternalizedStringMapForString( 509 Handle<String> string) { 510 // If the string is in new space it cannot be used as internalized. 511 if (isolate()->heap()->InNewSpace(*string)) return MaybeHandle<Map>(); 512 513 return GetInternalizedStringMap(this, string); 514 } 515 516 template <class StringClass> 517 Handle<StringClass> Factory::InternalizeExternalString(Handle<String> string) { 518 Handle<StringClass> cast_string = Handle<StringClass>::cast(string); 519 Handle<Map> map = GetInternalizedStringMap(this, string).ToHandleChecked(); 520 Handle<StringClass> external_string = New<StringClass>(map, OLD_SPACE); 521 external_string->set_length(cast_string->length()); 522 external_string->set_hash_field(cast_string->hash_field()); 523 external_string->set_resource(nullptr); 524 isolate()->heap()->RegisterExternalString(*external_string); 525 return external_string; 526 } 527 528 template Handle<ExternalOneByteString> 529 Factory::InternalizeExternalString<ExternalOneByteString>(Handle<String>); 530 template Handle<ExternalTwoByteString> 531 Factory::InternalizeExternalString<ExternalTwoByteString>(Handle<String>); 532 533 MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString( 534 int length, PretenureFlag pretenure) { 535 if (length > String::kMaxLength || length < 0) { 536 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqOneByteString); 537 } 538 DCHECK(length > 0); // Use Factory::empty_string() instead. 539 CALL_HEAP_FUNCTION( 540 isolate(), 541 isolate()->heap()->AllocateRawOneByteString(length, pretenure), 542 SeqOneByteString); 543 } 544 545 546 MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString( 547 int length, PretenureFlag pretenure) { 548 if (length > String::kMaxLength || length < 0) { 549 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqTwoByteString); 550 } 551 DCHECK(length > 0); // Use Factory::empty_string() instead. 552 CALL_HEAP_FUNCTION( 553 isolate(), 554 isolate()->heap()->AllocateRawTwoByteString(length, pretenure), 555 SeqTwoByteString); 556 } 557 558 559 Handle<String> Factory::LookupSingleCharacterStringFromCode(uint32_t code) { 560 if (code <= String::kMaxOneByteCharCodeU) { 561 { 562 DisallowHeapAllocation no_allocation; 563 Object* value = single_character_string_cache()->get(code); 564 if (value != *undefined_value()) { 565 return handle(String::cast(value), isolate()); 566 } 567 } 568 uint8_t buffer[1]; 569 buffer[0] = static_cast<uint8_t>(code); 570 Handle<String> result = 571 InternalizeOneByteString(Vector<const uint8_t>(buffer, 1)); 572 single_character_string_cache()->set(code, *result); 573 return result; 574 } 575 DCHECK(code <= String::kMaxUtf16CodeUnitU); 576 577 Handle<SeqTwoByteString> result = NewRawTwoByteString(1).ToHandleChecked(); 578 result->SeqTwoByteStringSet(0, static_cast<uint16_t>(code)); 579 return result; 580 } 581 582 583 // Returns true for a character in a range. Both limits are inclusive. 584 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) { 585 // This makes uses of the the unsigned wraparound. 586 return character - from <= to - from; 587 } 588 589 590 static inline Handle<String> MakeOrFindTwoCharacterString(Isolate* isolate, 591 uint16_t c1, 592 uint16_t c2) { 593 // Numeric strings have a different hash algorithm not known by 594 // LookupTwoCharsStringIfExists, so we skip this step for such strings. 595 if (!Between(c1, '0', '9') || !Between(c2, '0', '9')) { 596 Handle<String> result; 597 if (StringTable::LookupTwoCharsStringIfExists(isolate, c1, c2). 598 ToHandle(&result)) { 599 return result; 600 } 601 } 602 603 // Now we know the length is 2, we might as well make use of that fact 604 // when building the new string. 605 if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) { 606 // We can do this. 607 DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCodeU + 608 1)); // because of this. 609 Handle<SeqOneByteString> str = 610 isolate->factory()->NewRawOneByteString(2).ToHandleChecked(); 611 uint8_t* dest = str->GetChars(); 612 dest[0] = static_cast<uint8_t>(c1); 613 dest[1] = static_cast<uint8_t>(c2); 614 return str; 615 } else { 616 Handle<SeqTwoByteString> str = 617 isolate->factory()->NewRawTwoByteString(2).ToHandleChecked(); 618 uc16* dest = str->GetChars(); 619 dest[0] = c1; 620 dest[1] = c2; 621 return str; 622 } 623 } 624 625 626 template<typename SinkChar, typename StringType> 627 Handle<String> ConcatStringContent(Handle<StringType> result, 628 Handle<String> first, 629 Handle<String> second) { 630 DisallowHeapAllocation pointer_stays_valid; 631 SinkChar* sink = result->GetChars(); 632 String::WriteToFlat(*first, sink, 0, first->length()); 633 String::WriteToFlat(*second, sink + first->length(), 0, second->length()); 634 return result; 635 } 636 637 638 MaybeHandle<String> Factory::NewConsString(Handle<String> left, 639 Handle<String> right) { 640 if (left->IsThinString()) { 641 left = handle(Handle<ThinString>::cast(left)->actual(), isolate()); 642 } 643 if (right->IsThinString()) { 644 right = handle(Handle<ThinString>::cast(right)->actual(), isolate()); 645 } 646 int left_length = left->length(); 647 if (left_length == 0) return right; 648 int right_length = right->length(); 649 if (right_length == 0) return left; 650 651 int length = left_length + right_length; 652 653 if (length == 2) { 654 uint16_t c1 = left->Get(0); 655 uint16_t c2 = right->Get(0); 656 return MakeOrFindTwoCharacterString(isolate(), c1, c2); 657 } 658 659 // Make sure that an out of memory exception is thrown if the length 660 // of the new cons string is too large. 661 if (length > String::kMaxLength || length < 0) { 662 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); 663 } 664 665 bool left_is_one_byte = left->IsOneByteRepresentation(); 666 bool right_is_one_byte = right->IsOneByteRepresentation(); 667 bool is_one_byte = left_is_one_byte && right_is_one_byte; 668 bool is_one_byte_data_in_two_byte_string = false; 669 if (!is_one_byte) { 670 // At least one of the strings uses two-byte representation so we 671 // can't use the fast case code for short one-byte strings below, but 672 // we can try to save memory if all chars actually fit in one-byte. 673 is_one_byte_data_in_two_byte_string = 674 left->HasOnlyOneByteChars() && right->HasOnlyOneByteChars(); 675 if (is_one_byte_data_in_two_byte_string) { 676 isolate()->counters()->string_add_runtime_ext_to_one_byte()->Increment(); 677 } 678 } 679 680 // If the resulting string is small make a flat string. 681 if (length < ConsString::kMinLength) { 682 // Note that neither of the two inputs can be a slice because: 683 STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength); 684 DCHECK(left->IsFlat()); 685 DCHECK(right->IsFlat()); 686 687 STATIC_ASSERT(ConsString::kMinLength <= String::kMaxLength); 688 if (is_one_byte) { 689 Handle<SeqOneByteString> result = 690 NewRawOneByteString(length).ToHandleChecked(); 691 DisallowHeapAllocation no_gc; 692 uint8_t* dest = result->GetChars(); 693 // Copy left part. 694 const uint8_t* src = 695 left->IsExternalString() 696 ? Handle<ExternalOneByteString>::cast(left)->GetChars() 697 : Handle<SeqOneByteString>::cast(left)->GetChars(); 698 for (int i = 0; i < left_length; i++) *dest++ = src[i]; 699 // Copy right part. 700 src = right->IsExternalString() 701 ? Handle<ExternalOneByteString>::cast(right)->GetChars() 702 : Handle<SeqOneByteString>::cast(right)->GetChars(); 703 for (int i = 0; i < right_length; i++) *dest++ = src[i]; 704 return result; 705 } 706 707 return (is_one_byte_data_in_two_byte_string) 708 ? ConcatStringContent<uint8_t>( 709 NewRawOneByteString(length).ToHandleChecked(), left, right) 710 : ConcatStringContent<uc16>( 711 NewRawTwoByteString(length).ToHandleChecked(), left, right); 712 } 713 714 Handle<ConsString> result = 715 (is_one_byte || is_one_byte_data_in_two_byte_string) 716 ? New<ConsString>(cons_one_byte_string_map(), NEW_SPACE) 717 : New<ConsString>(cons_string_map(), NEW_SPACE); 718 719 DisallowHeapAllocation no_gc; 720 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 721 722 result->set_hash_field(String::kEmptyHashField); 723 result->set_length(length); 724 result->set_first(*left, mode); 725 result->set_second(*right, mode); 726 return result; 727 } 728 729 Handle<String> Factory::NewSurrogatePairString(uint16_t lead, uint16_t trail) { 730 DCHECK_GE(lead, 0xD800); 731 DCHECK_LE(lead, 0xDBFF); 732 DCHECK_GE(trail, 0xDC00); 733 DCHECK_LE(trail, 0xDFFF); 734 735 Handle<SeqTwoByteString> str = 736 isolate()->factory()->NewRawTwoByteString(2).ToHandleChecked(); 737 uc16* dest = str->GetChars(); 738 dest[0] = lead; 739 dest[1] = trail; 740 return str; 741 } 742 743 Handle<String> Factory::NewProperSubString(Handle<String> str, 744 int begin, 745 int end) { 746 #if VERIFY_HEAP 747 if (FLAG_verify_heap) str->StringVerify(); 748 #endif 749 DCHECK(begin > 0 || end < str->length()); 750 751 str = String::Flatten(str); 752 753 int length = end - begin; 754 if (length <= 0) return empty_string(); 755 if (length == 1) { 756 return LookupSingleCharacterStringFromCode(str->Get(begin)); 757 } 758 if (length == 2) { 759 // Optimization for 2-byte strings often used as keys in a decompression 760 // dictionary. Check whether we already have the string in the string 761 // table to prevent creation of many unnecessary strings. 762 uint16_t c1 = str->Get(begin); 763 uint16_t c2 = str->Get(begin + 1); 764 return MakeOrFindTwoCharacterString(isolate(), c1, c2); 765 } 766 767 if (!FLAG_string_slices || length < SlicedString::kMinLength) { 768 if (str->IsOneByteRepresentation()) { 769 Handle<SeqOneByteString> result = 770 NewRawOneByteString(length).ToHandleChecked(); 771 uint8_t* dest = result->GetChars(); 772 DisallowHeapAllocation no_gc; 773 String::WriteToFlat(*str, dest, begin, end); 774 return result; 775 } else { 776 Handle<SeqTwoByteString> result = 777 NewRawTwoByteString(length).ToHandleChecked(); 778 uc16* dest = result->GetChars(); 779 DisallowHeapAllocation no_gc; 780 String::WriteToFlat(*str, dest, begin, end); 781 return result; 782 } 783 } 784 785 int offset = begin; 786 787 if (str->IsSlicedString()) { 788 Handle<SlicedString> slice = Handle<SlicedString>::cast(str); 789 str = Handle<String>(slice->parent(), isolate()); 790 offset += slice->offset(); 791 } 792 if (str->IsThinString()) { 793 Handle<ThinString> thin = Handle<ThinString>::cast(str); 794 str = handle(thin->actual(), isolate()); 795 } 796 797 DCHECK(str->IsSeqString() || str->IsExternalString()); 798 Handle<Map> map = str->IsOneByteRepresentation() 799 ? sliced_one_byte_string_map() 800 : sliced_string_map(); 801 Handle<SlicedString> slice = New<SlicedString>(map, NEW_SPACE); 802 803 slice->set_hash_field(String::kEmptyHashField); 804 slice->set_length(length); 805 slice->set_parent(*str); 806 slice->set_offset(offset); 807 return slice; 808 } 809 810 811 MaybeHandle<String> Factory::NewExternalStringFromOneByte( 812 const ExternalOneByteString::Resource* resource) { 813 size_t length = resource->length(); 814 if (length > static_cast<size_t>(String::kMaxLength)) { 815 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); 816 } 817 if (length == 0) return empty_string(); 818 819 Handle<Map> map; 820 if (resource->IsCompressible()) { 821 // TODO(hajimehoshi): Rename this to 'uncached_external_one_byte_string_map' 822 map = short_external_one_byte_string_map(); 823 } else { 824 map = external_one_byte_string_map(); 825 } 826 Handle<ExternalOneByteString> external_string = 827 New<ExternalOneByteString>(map, NEW_SPACE); 828 external_string->set_length(static_cast<int>(length)); 829 external_string->set_hash_field(String::kEmptyHashField); 830 external_string->set_resource(resource); 831 832 return external_string; 833 } 834 835 836 MaybeHandle<String> Factory::NewExternalStringFromTwoByte( 837 const ExternalTwoByteString::Resource* resource) { 838 size_t length = resource->length(); 839 if (length > static_cast<size_t>(String::kMaxLength)) { 840 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String); 841 } 842 if (length == 0) return empty_string(); 843 844 // For small strings we check whether the resource contains only 845 // one byte characters. If yes, we use a different string map. 846 static const size_t kOneByteCheckLengthLimit = 32; 847 bool is_one_byte = length <= kOneByteCheckLengthLimit && 848 String::IsOneByte(resource->data(), static_cast<int>(length)); 849 Handle<Map> map; 850 if (resource->IsCompressible()) { 851 // TODO(hajimehoshi): Rename these to 'uncached_external_string_...'. 852 map = is_one_byte ? short_external_string_with_one_byte_data_map() 853 : short_external_string_map(); 854 } else { 855 map = is_one_byte ? external_string_with_one_byte_data_map() 856 : external_string_map(); 857 } 858 Handle<ExternalTwoByteString> external_string = 859 New<ExternalTwoByteString>(map, NEW_SPACE); 860 external_string->set_length(static_cast<int>(length)); 861 external_string->set_hash_field(String::kEmptyHashField); 862 external_string->set_resource(resource); 863 864 return external_string; 865 } 866 867 Handle<ExternalOneByteString> Factory::NewNativeSourceString( 868 const ExternalOneByteString::Resource* resource) { 869 size_t length = resource->length(); 870 DCHECK_LE(length, static_cast<size_t>(String::kMaxLength)); 871 872 Handle<Map> map = native_source_string_map(); 873 Handle<ExternalOneByteString> external_string = 874 New<ExternalOneByteString>(map, OLD_SPACE); 875 external_string->set_length(static_cast<int>(length)); 876 external_string->set_hash_field(String::kEmptyHashField); 877 external_string->set_resource(resource); 878 879 return external_string; 880 } 881 882 Handle<JSStringIterator> Factory::NewJSStringIterator(Handle<String> string) { 883 Handle<Map> map(isolate()->native_context()->string_iterator_map(), 884 isolate()); 885 Handle<String> flat_string = String::Flatten(string); 886 Handle<JSStringIterator> iterator = 887 Handle<JSStringIterator>::cast(NewJSObjectFromMap(map)); 888 iterator->set_string(*flat_string); 889 iterator->set_index(0); 890 891 return iterator; 892 } 893 894 Handle<Symbol> Factory::NewSymbol() { 895 CALL_HEAP_FUNCTION( 896 isolate(), 897 isolate()->heap()->AllocateSymbol(), 898 Symbol); 899 } 900 901 902 Handle<Symbol> Factory::NewPrivateSymbol() { 903 Handle<Symbol> symbol = NewSymbol(); 904 symbol->set_is_private(true); 905 return symbol; 906 } 907 908 909 Handle<Context> Factory::NewNativeContext() { 910 Handle<FixedArray> array = 911 NewFixedArray(Context::NATIVE_CONTEXT_SLOTS, TENURED); 912 array->set_map_no_write_barrier(*native_context_map()); 913 Handle<Context> context = Handle<Context>::cast(array); 914 context->set_native_context(*context); 915 context->set_errors_thrown(Smi::kZero); 916 context->set_math_random_index(Smi::kZero); 917 Handle<WeakCell> weak_cell = NewWeakCell(context); 918 context->set_self_weak_cell(*weak_cell); 919 DCHECK(context->IsNativeContext()); 920 return context; 921 } 922 923 924 Handle<Context> Factory::NewScriptContext(Handle<JSFunction> function, 925 Handle<ScopeInfo> scope_info) { 926 DCHECK_EQ(scope_info->scope_type(), SCRIPT_SCOPE); 927 Handle<FixedArray> array = 928 NewFixedArray(scope_info->ContextLength(), TENURED); 929 array->set_map_no_write_barrier(*script_context_map()); 930 Handle<Context> context = Handle<Context>::cast(array); 931 context->set_closure(*function); 932 context->set_previous(function->context()); 933 context->set_extension(*scope_info); 934 context->set_native_context(function->native_context()); 935 DCHECK(context->IsScriptContext()); 936 return context; 937 } 938 939 940 Handle<ScriptContextTable> Factory::NewScriptContextTable() { 941 Handle<FixedArray> array = NewFixedArray(1); 942 array->set_map_no_write_barrier(*script_context_table_map()); 943 Handle<ScriptContextTable> context_table = 944 Handle<ScriptContextTable>::cast(array); 945 context_table->set_used(0); 946 return context_table; 947 } 948 949 Handle<Context> Factory::NewModuleContext(Handle<Module> module, 950 Handle<JSFunction> function, 951 Handle<ScopeInfo> scope_info) { 952 DCHECK_EQ(scope_info->scope_type(), MODULE_SCOPE); 953 Handle<FixedArray> array = 954 NewFixedArray(scope_info->ContextLength(), TENURED); 955 array->set_map_no_write_barrier(*module_context_map()); 956 Handle<Context> context = Handle<Context>::cast(array); 957 context->set_closure(*function); 958 context->set_previous(function->context()); 959 context->set_extension(*module); 960 context->set_native_context(function->native_context()); 961 DCHECK(context->IsModuleContext()); 962 return context; 963 } 964 965 Handle<Context> Factory::NewFunctionContext(int length, 966 Handle<JSFunction> function, 967 ScopeType scope_type) { 968 DCHECK(function->shared()->scope_info()->scope_type() == scope_type); 969 DCHECK(length >= Context::MIN_CONTEXT_SLOTS); 970 Handle<FixedArray> array = NewFixedArray(length); 971 Handle<Map> map; 972 switch (scope_type) { 973 case EVAL_SCOPE: 974 map = eval_context_map(); 975 break; 976 case FUNCTION_SCOPE: 977 map = function_context_map(); 978 break; 979 default: 980 UNREACHABLE(); 981 } 982 array->set_map_no_write_barrier(*map); 983 Handle<Context> context = Handle<Context>::cast(array); 984 context->set_closure(*function); 985 context->set_previous(function->context()); 986 context->set_extension(*the_hole_value()); 987 context->set_native_context(function->native_context()); 988 return context; 989 } 990 991 Handle<Context> Factory::NewCatchContext(Handle<JSFunction> function, 992 Handle<Context> previous, 993 Handle<ScopeInfo> scope_info, 994 Handle<String> name, 995 Handle<Object> thrown_object) { 996 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == Context::THROWN_OBJECT_INDEX); 997 Handle<ContextExtension> extension = NewContextExtension(scope_info, name); 998 Handle<FixedArray> array = NewFixedArray(Context::MIN_CONTEXT_SLOTS + 1); 999 array->set_map_no_write_barrier(*catch_context_map()); 1000 Handle<Context> context = Handle<Context>::cast(array); 1001 context->set_closure(*function); 1002 context->set_previous(*previous); 1003 context->set_extension(*extension); 1004 context->set_native_context(previous->native_context()); 1005 context->set(Context::THROWN_OBJECT_INDEX, *thrown_object); 1006 return context; 1007 } 1008 1009 Handle<Context> Factory::NewDebugEvaluateContext(Handle<Context> previous, 1010 Handle<ScopeInfo> scope_info, 1011 Handle<JSReceiver> extension, 1012 Handle<Context> wrapped, 1013 Handle<StringSet> whitelist) { 1014 STATIC_ASSERT(Context::WHITE_LIST_INDEX == Context::MIN_CONTEXT_SLOTS + 1); 1015 DCHECK(scope_info->IsDebugEvaluateScope()); 1016 Handle<ContextExtension> context_extension = NewContextExtension( 1017 scope_info, extension.is_null() ? Handle<Object>::cast(undefined_value()) 1018 : Handle<Object>::cast(extension)); 1019 Handle<FixedArray> array = NewFixedArray(Context::MIN_CONTEXT_SLOTS + 2); 1020 array->set_map_no_write_barrier(*debug_evaluate_context_map()); 1021 Handle<Context> c = Handle<Context>::cast(array); 1022 c->set_closure(wrapped.is_null() ? previous->closure() : wrapped->closure()); 1023 c->set_previous(*previous); 1024 c->set_native_context(previous->native_context()); 1025 c->set_extension(*context_extension); 1026 if (!wrapped.is_null()) c->set(Context::WRAPPED_CONTEXT_INDEX, *wrapped); 1027 if (!whitelist.is_null()) c->set(Context::WHITE_LIST_INDEX, *whitelist); 1028 return c; 1029 } 1030 1031 Handle<Context> Factory::NewWithContext(Handle<JSFunction> function, 1032 Handle<Context> previous, 1033 Handle<ScopeInfo> scope_info, 1034 Handle<JSReceiver> extension) { 1035 Handle<ContextExtension> context_extension = 1036 NewContextExtension(scope_info, extension); 1037 Handle<FixedArray> array = NewFixedArray(Context::MIN_CONTEXT_SLOTS); 1038 array->set_map_no_write_barrier(*with_context_map()); 1039 Handle<Context> context = Handle<Context>::cast(array); 1040 context->set_closure(*function); 1041 context->set_previous(*previous); 1042 context->set_extension(*context_extension); 1043 context->set_native_context(previous->native_context()); 1044 return context; 1045 } 1046 1047 1048 Handle<Context> Factory::NewBlockContext(Handle<JSFunction> function, 1049 Handle<Context> previous, 1050 Handle<ScopeInfo> scope_info) { 1051 DCHECK_EQ(scope_info->scope_type(), BLOCK_SCOPE); 1052 Handle<FixedArray> array = NewFixedArray(scope_info->ContextLength()); 1053 array->set_map_no_write_barrier(*block_context_map()); 1054 Handle<Context> context = Handle<Context>::cast(array); 1055 context->set_closure(*function); 1056 context->set_previous(*previous); 1057 context->set_extension(*scope_info); 1058 context->set_native_context(previous->native_context()); 1059 return context; 1060 } 1061 1062 Handle<Struct> Factory::NewStruct(InstanceType type) { 1063 CALL_HEAP_FUNCTION( 1064 isolate(), 1065 isolate()->heap()->AllocateStruct(type), 1066 Struct); 1067 } 1068 1069 Handle<AliasedArgumentsEntry> Factory::NewAliasedArgumentsEntry( 1070 int aliased_context_slot) { 1071 Handle<AliasedArgumentsEntry> entry = Handle<AliasedArgumentsEntry>::cast( 1072 NewStruct(ALIASED_ARGUMENTS_ENTRY_TYPE)); 1073 entry->set_aliased_context_slot(aliased_context_slot); 1074 return entry; 1075 } 1076 1077 1078 Handle<AccessorInfo> Factory::NewAccessorInfo() { 1079 Handle<AccessorInfo> info = 1080 Handle<AccessorInfo>::cast(NewStruct(ACCESSOR_INFO_TYPE)); 1081 info->set_flag(0); // Must clear the flag, it was initialized as undefined. 1082 info->set_is_sloppy(true); 1083 return info; 1084 } 1085 1086 1087 Handle<Script> Factory::NewScript(Handle<String> source) { 1088 // Create and initialize script object. 1089 Heap* heap = isolate()->heap(); 1090 Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE)); 1091 script->set_source(*source); 1092 script->set_name(heap->undefined_value()); 1093 script->set_id(isolate()->heap()->NextScriptId()); 1094 script->set_line_offset(0); 1095 script->set_column_offset(0); 1096 script->set_context_data(heap->undefined_value()); 1097 script->set_type(Script::TYPE_NORMAL); 1098 script->set_wrapper(heap->undefined_value()); 1099 script->set_line_ends(heap->undefined_value()); 1100 script->set_eval_from_shared(heap->undefined_value()); 1101 script->set_eval_from_position(0); 1102 script->set_shared_function_infos(*empty_fixed_array(), SKIP_WRITE_BARRIER); 1103 script->set_flags(0); 1104 1105 heap->set_script_list(*WeakFixedArray::Add(script_list(), script)); 1106 return script; 1107 } 1108 1109 1110 Handle<Foreign> Factory::NewForeign(Address addr, PretenureFlag pretenure) { 1111 CALL_HEAP_FUNCTION(isolate(), 1112 isolate()->heap()->AllocateForeign(addr, pretenure), 1113 Foreign); 1114 } 1115 1116 1117 Handle<Foreign> Factory::NewForeign(const AccessorDescriptor* desc) { 1118 return NewForeign((Address) desc, TENURED); 1119 } 1120 1121 1122 Handle<ByteArray> Factory::NewByteArray(int length, PretenureFlag pretenure) { 1123 DCHECK(0 <= length); 1124 CALL_HEAP_FUNCTION( 1125 isolate(), 1126 isolate()->heap()->AllocateByteArray(length, pretenure), 1127 ByteArray); 1128 } 1129 1130 1131 Handle<BytecodeArray> Factory::NewBytecodeArray( 1132 int length, const byte* raw_bytecodes, int frame_size, int parameter_count, 1133 Handle<FixedArray> constant_pool) { 1134 DCHECK(0 <= length); 1135 CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateBytecodeArray( 1136 length, raw_bytecodes, frame_size, 1137 parameter_count, *constant_pool), 1138 BytecodeArray); 1139 } 1140 1141 1142 Handle<FixedTypedArrayBase> Factory::NewFixedTypedArrayWithExternalPointer( 1143 int length, ExternalArrayType array_type, void* external_pointer, 1144 PretenureFlag pretenure) { 1145 DCHECK(0 <= length && length <= Smi::kMaxValue); 1146 CALL_HEAP_FUNCTION( 1147 isolate(), isolate()->heap()->AllocateFixedTypedArrayWithExternalPointer( 1148 length, array_type, external_pointer, pretenure), 1149 FixedTypedArrayBase); 1150 } 1151 1152 1153 Handle<FixedTypedArrayBase> Factory::NewFixedTypedArray( 1154 int length, ExternalArrayType array_type, bool initialize, 1155 PretenureFlag pretenure) { 1156 DCHECK(0 <= length && length <= Smi::kMaxValue); 1157 CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateFixedTypedArray( 1158 length, array_type, initialize, pretenure), 1159 FixedTypedArrayBase); 1160 } 1161 1162 Handle<Cell> Factory::NewCell(Handle<Object> value) { 1163 AllowDeferredHandleDereference convert_to_cell; 1164 CALL_HEAP_FUNCTION( 1165 isolate(), 1166 isolate()->heap()->AllocateCell(*value), 1167 Cell); 1168 } 1169 1170 Handle<Cell> Factory::NewNoClosuresCell(Handle<Object> value) { 1171 Handle<Cell> cell = NewCell(value); 1172 cell->set_map_no_write_barrier(*no_closures_cell_map()); 1173 return cell; 1174 } 1175 1176 Handle<Cell> Factory::NewOneClosureCell(Handle<Object> value) { 1177 Handle<Cell> cell = NewCell(value); 1178 cell->set_map_no_write_barrier(*one_closure_cell_map()); 1179 return cell; 1180 } 1181 1182 Handle<Cell> Factory::NewManyClosuresCell(Handle<Object> value) { 1183 Handle<Cell> cell = NewCell(value); 1184 cell->set_map_no_write_barrier(*many_closures_cell_map()); 1185 return cell; 1186 } 1187 1188 Handle<PropertyCell> Factory::NewPropertyCell() { 1189 CALL_HEAP_FUNCTION( 1190 isolate(), 1191 isolate()->heap()->AllocatePropertyCell(), 1192 PropertyCell); 1193 } 1194 1195 1196 Handle<WeakCell> Factory::NewWeakCell(Handle<HeapObject> value) { 1197 // It is safe to dereference the value because we are embedding it 1198 // in cell and not inspecting its fields. 1199 AllowDeferredHandleDereference convert_to_cell; 1200 CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateWeakCell(*value), 1201 WeakCell); 1202 } 1203 1204 1205 Handle<TransitionArray> Factory::NewTransitionArray(int capacity) { 1206 CALL_HEAP_FUNCTION(isolate(), 1207 isolate()->heap()->AllocateTransitionArray(capacity), 1208 TransitionArray); 1209 } 1210 1211 1212 Handle<AllocationSite> Factory::NewAllocationSite() { 1213 Handle<Map> map = allocation_site_map(); 1214 Handle<AllocationSite> site = New<AllocationSite>(map, OLD_SPACE); 1215 site->Initialize(); 1216 1217 // Link the site 1218 site->set_weak_next(isolate()->heap()->allocation_sites_list()); 1219 isolate()->heap()->set_allocation_sites_list(*site); 1220 return site; 1221 } 1222 1223 1224 Handle<Map> Factory::NewMap(InstanceType type, 1225 int instance_size, 1226 ElementsKind elements_kind) { 1227 CALL_HEAP_FUNCTION( 1228 isolate(), 1229 isolate()->heap()->AllocateMap(type, instance_size, elements_kind), 1230 Map); 1231 } 1232 1233 1234 Handle<JSObject> Factory::CopyJSObject(Handle<JSObject> object) { 1235 CALL_HEAP_FUNCTION(isolate(), 1236 isolate()->heap()->CopyJSObject(*object, NULL), 1237 JSObject); 1238 } 1239 1240 1241 Handle<JSObject> Factory::CopyJSObjectWithAllocationSite( 1242 Handle<JSObject> object, 1243 Handle<AllocationSite> site) { 1244 CALL_HEAP_FUNCTION(isolate(), 1245 isolate()->heap()->CopyJSObject( 1246 *object, 1247 site.is_null() ? NULL : *site), 1248 JSObject); 1249 } 1250 1251 1252 Handle<FixedArray> Factory::CopyFixedArrayWithMap(Handle<FixedArray> array, 1253 Handle<Map> map) { 1254 CALL_HEAP_FUNCTION(isolate(), 1255 isolate()->heap()->CopyFixedArrayWithMap(*array, *map), 1256 FixedArray); 1257 } 1258 1259 1260 Handle<FixedArray> Factory::CopyFixedArrayAndGrow(Handle<FixedArray> array, 1261 int grow_by, 1262 PretenureFlag pretenure) { 1263 CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->CopyFixedArrayAndGrow( 1264 *array, grow_by, pretenure), 1265 FixedArray); 1266 } 1267 1268 Handle<FixedArray> Factory::CopyFixedArrayUpTo(Handle<FixedArray> array, 1269 int new_len, 1270 PretenureFlag pretenure) { 1271 CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->CopyFixedArrayUpTo( 1272 *array, new_len, pretenure), 1273 FixedArray); 1274 } 1275 1276 Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) { 1277 CALL_HEAP_FUNCTION(isolate(), 1278 isolate()->heap()->CopyFixedArray(*array), 1279 FixedArray); 1280 } 1281 1282 1283 Handle<FixedArray> Factory::CopyAndTenureFixedCOWArray( 1284 Handle<FixedArray> array) { 1285 DCHECK(isolate()->heap()->InNewSpace(*array)); 1286 CALL_HEAP_FUNCTION(isolate(), 1287 isolate()->heap()->CopyAndTenureFixedCOWArray(*array), 1288 FixedArray); 1289 } 1290 1291 1292 Handle<FixedDoubleArray> Factory::CopyFixedDoubleArray( 1293 Handle<FixedDoubleArray> array) { 1294 CALL_HEAP_FUNCTION(isolate(), 1295 isolate()->heap()->CopyFixedDoubleArray(*array), 1296 FixedDoubleArray); 1297 } 1298 1299 1300 Handle<Object> Factory::NewNumber(double value, 1301 PretenureFlag pretenure) { 1302 // Materialize as a SMI if possible 1303 int32_t int_value; 1304 if (DoubleToSmiInteger(value, &int_value)) { 1305 return handle(Smi::FromInt(int_value), isolate()); 1306 } 1307 1308 // Materialize the value in the heap. 1309 return NewHeapNumber(value, IMMUTABLE, pretenure); 1310 } 1311 1312 1313 Handle<Object> Factory::NewNumberFromInt(int32_t value, 1314 PretenureFlag pretenure) { 1315 if (Smi::IsValid(value)) return handle(Smi::FromInt(value), isolate()); 1316 // Bypass NewNumber to avoid various redundant checks. 1317 return NewHeapNumber(FastI2D(value), IMMUTABLE, pretenure); 1318 } 1319 1320 1321 Handle<Object> Factory::NewNumberFromUint(uint32_t value, 1322 PretenureFlag pretenure) { 1323 int32_t int32v = static_cast<int32_t>(value); 1324 if (int32v >= 0 && Smi::IsValid(int32v)) { 1325 return handle(Smi::FromInt(int32v), isolate()); 1326 } 1327 return NewHeapNumber(FastUI2D(value), IMMUTABLE, pretenure); 1328 } 1329 1330 Handle<HeapNumber> Factory::NewHeapNumber(MutableMode mode, 1331 PretenureFlag pretenure) { 1332 CALL_HEAP_FUNCTION(isolate(), 1333 isolate()->heap()->AllocateHeapNumber(mode, pretenure), 1334 HeapNumber); 1335 } 1336 1337 Handle<Object> Factory::NewError(Handle<JSFunction> constructor, 1338 MessageTemplate::Template template_index, 1339 Handle<Object> arg0, Handle<Object> arg1, 1340 Handle<Object> arg2) { 1341 HandleScope scope(isolate()); 1342 if (isolate()->bootstrapper()->IsActive()) { 1343 // During bootstrapping we cannot construct error objects. 1344 return scope.CloseAndEscape(NewStringFromAsciiChecked( 1345 MessageTemplate::TemplateString(template_index))); 1346 } 1347 1348 if (arg0.is_null()) arg0 = undefined_value(); 1349 if (arg1.is_null()) arg1 = undefined_value(); 1350 if (arg2.is_null()) arg2 = undefined_value(); 1351 1352 Handle<Object> result; 1353 if (!ErrorUtils::MakeGenericError(isolate(), constructor, template_index, 1354 arg0, arg1, arg2, SKIP_NONE) 1355 .ToHandle(&result)) { 1356 // If an exception is thrown while 1357 // running the factory method, use the exception as the result. 1358 DCHECK(isolate()->has_pending_exception()); 1359 result = handle(isolate()->pending_exception(), isolate()); 1360 isolate()->clear_pending_exception(); 1361 } 1362 1363 return scope.CloseAndEscape(result); 1364 } 1365 1366 1367 Handle<Object> Factory::NewError(Handle<JSFunction> constructor, 1368 Handle<String> message) { 1369 // Construct a new error object. If an exception is thrown, use the exception 1370 // as the result. 1371 1372 Handle<Object> no_caller; 1373 MaybeHandle<Object> maybe_error = 1374 ErrorUtils::Construct(isolate(), constructor, constructor, message, 1375 SKIP_NONE, no_caller, false); 1376 if (maybe_error.is_null()) { 1377 DCHECK(isolate()->has_pending_exception()); 1378 maybe_error = handle(isolate()->pending_exception(), isolate()); 1379 isolate()->clear_pending_exception(); 1380 } 1381 1382 return maybe_error.ToHandleChecked(); 1383 } 1384 1385 Handle<Object> Factory::NewInvalidStringLengthError() { 1386 // Invalidate the "string length" protector. 1387 if (isolate()->IsStringLengthOverflowIntact()) { 1388 isolate()->InvalidateStringLengthOverflowProtector(); 1389 } 1390 return NewRangeError(MessageTemplate::kInvalidStringLength); 1391 } 1392 1393 #define DEFINE_ERROR(NAME, name) \ 1394 Handle<Object> Factory::New##NAME(MessageTemplate::Template template_index, \ 1395 Handle<Object> arg0, Handle<Object> arg1, \ 1396 Handle<Object> arg2) { \ 1397 return NewError(isolate()->name##_function(), template_index, arg0, arg1, \ 1398 arg2); \ 1399 } 1400 DEFINE_ERROR(Error, error) 1401 DEFINE_ERROR(EvalError, eval_error) 1402 DEFINE_ERROR(RangeError, range_error) 1403 DEFINE_ERROR(ReferenceError, reference_error) 1404 DEFINE_ERROR(SyntaxError, syntax_error) 1405 DEFINE_ERROR(TypeError, type_error) 1406 DEFINE_ERROR(WasmCompileError, wasm_compile_error) 1407 DEFINE_ERROR(WasmLinkError, wasm_link_error) 1408 DEFINE_ERROR(WasmRuntimeError, wasm_runtime_error) 1409 #undef DEFINE_ERROR 1410 1411 Handle<JSFunction> Factory::NewFunction(Handle<Map> map, 1412 Handle<SharedFunctionInfo> info, 1413 Handle<Object> context_or_undefined, 1414 PretenureFlag pretenure) { 1415 AllocationSpace space = pretenure == TENURED ? OLD_SPACE : NEW_SPACE; 1416 Handle<JSFunction> function = New<JSFunction>(map, space); 1417 DCHECK(context_or_undefined->IsContext() || 1418 context_or_undefined->IsUndefined(isolate())); 1419 1420 function->initialize_properties(); 1421 function->initialize_elements(); 1422 function->set_shared(*info); 1423 function->set_code(info->code()); 1424 function->set_context(*context_or_undefined); 1425 function->set_prototype_or_initial_map(*the_hole_value()); 1426 function->set_feedback_vector_cell(*undefined_cell()); 1427 function->set_next_function_link(*undefined_value(), SKIP_WRITE_BARRIER); 1428 isolate()->heap()->InitializeJSObjectBody(*function, *map, JSFunction::kSize); 1429 return function; 1430 } 1431 1432 1433 Handle<JSFunction> Factory::NewFunction(Handle<Map> map, 1434 Handle<String> name, 1435 MaybeHandle<Code> code) { 1436 Handle<Context> context(isolate()->native_context()); 1437 Handle<SharedFunctionInfo> info = 1438 NewSharedFunctionInfo(name, code, map->is_constructor()); 1439 DCHECK(is_sloppy(info->language_mode())); 1440 DCHECK(!map->IsUndefined(isolate())); 1441 DCHECK( 1442 map.is_identical_to(isolate()->sloppy_function_map()) || 1443 map.is_identical_to(isolate()->sloppy_function_without_prototype_map()) || 1444 map.is_identical_to( 1445 isolate()->sloppy_function_with_readonly_prototype_map()) || 1446 map.is_identical_to(isolate()->strict_function_map()) || 1447 map.is_identical_to(isolate()->strict_function_without_prototype_map()) || 1448 // TODO(titzer): wasm_function_map() could be undefined here. ugly. 1449 (*map == context->get(Context::WASM_FUNCTION_MAP_INDEX)) || 1450 (*map == context->get(Context::NATIVE_FUNCTION_MAP_INDEX)) || 1451 map.is_identical_to(isolate()->proxy_function_map())); 1452 return NewFunction(map, info, context); 1453 } 1454 1455 1456 Handle<JSFunction> Factory::NewFunction(Handle<String> name) { 1457 return NewFunction( 1458 isolate()->sloppy_function_map(), name, MaybeHandle<Code>()); 1459 } 1460 1461 1462 Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name, 1463 Handle<Code> code, 1464 bool is_strict) { 1465 Handle<Map> map = is_strict 1466 ? isolate()->strict_function_without_prototype_map() 1467 : isolate()->sloppy_function_without_prototype_map(); 1468 return NewFunction(map, name, code); 1469 } 1470 1471 1472 Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code, 1473 Handle<Object> prototype, 1474 bool is_strict) { 1475 Handle<Map> map = is_strict ? isolate()->strict_function_map() 1476 : isolate()->sloppy_function_map(); 1477 Handle<JSFunction> result = NewFunction(map, name, code); 1478 result->set_prototype_or_initial_map(*prototype); 1479 return result; 1480 } 1481 1482 1483 Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code, 1484 Handle<Object> prototype, 1485 InstanceType type, int instance_size, 1486 bool is_strict) { 1487 // Allocate the function 1488 Handle<JSFunction> function = NewFunction(name, code, prototype, is_strict); 1489 1490 ElementsKind elements_kind = 1491 type == JS_ARRAY_TYPE ? FAST_SMI_ELEMENTS : FAST_HOLEY_SMI_ELEMENTS; 1492 Handle<Map> initial_map = NewMap(type, instance_size, elements_kind); 1493 // TODO(littledan): Why do we have this is_generator test when 1494 // NewFunctionPrototype already handles finding an appropriately 1495 // shared prototype? 1496 if (!IsResumableFunction(function->shared()->kind())) { 1497 if (prototype->IsTheHole(isolate())) { 1498 prototype = NewFunctionPrototype(function); 1499 } 1500 } 1501 1502 JSFunction::SetInitialMap(function, initial_map, 1503 Handle<JSReceiver>::cast(prototype)); 1504 1505 return function; 1506 } 1507 1508 1509 Handle<JSFunction> Factory::NewFunction(Handle<String> name, 1510 Handle<Code> code, 1511 InstanceType type, 1512 int instance_size) { 1513 return NewFunction(name, code, the_hole_value(), type, instance_size); 1514 } 1515 1516 1517 Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) { 1518 // Make sure to use globals from the function's context, since the function 1519 // can be from a different context. 1520 Handle<Context> native_context(function->context()->native_context()); 1521 Handle<Map> new_map; 1522 if (IsResumableFunction(function->shared()->kind())) { 1523 // Generator and async function prototypes can share maps since they 1524 // don't have "constructor" properties. 1525 new_map = handle(native_context->generator_object_prototype_map()); 1526 } else { 1527 // Each function prototype gets a fresh map to avoid unwanted sharing of 1528 // maps between prototypes of different constructors. 1529 Handle<JSFunction> object_function(native_context->object_function()); 1530 DCHECK(object_function->has_initial_map()); 1531 new_map = handle(object_function->initial_map()); 1532 } 1533 1534 DCHECK(!new_map->is_prototype_map()); 1535 Handle<JSObject> prototype = NewJSObjectFromMap(new_map); 1536 1537 if (!IsResumableFunction(function->shared()->kind())) { 1538 JSObject::AddProperty(prototype, constructor_string(), function, DONT_ENUM); 1539 } 1540 1541 return prototype; 1542 } 1543 1544 1545 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( 1546 Handle<SharedFunctionInfo> info, 1547 Handle<Context> context, 1548 PretenureFlag pretenure) { 1549 int map_index = 1550 Context::FunctionMapIndex(info->language_mode(), info->kind()); 1551 Handle<Map> initial_map(Map::cast(context->native_context()->get(map_index))); 1552 1553 return NewFunctionFromSharedFunctionInfo(initial_map, info, context, 1554 pretenure); 1555 } 1556 1557 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( 1558 Handle<SharedFunctionInfo> info, Handle<Context> context, 1559 Handle<Cell> vector, PretenureFlag pretenure) { 1560 int map_index = 1561 Context::FunctionMapIndex(info->language_mode(), info->kind()); 1562 Handle<Map> initial_map(Map::cast(context->native_context()->get(map_index))); 1563 1564 return NewFunctionFromSharedFunctionInfo(initial_map, info, context, vector, 1565 pretenure); 1566 } 1567 1568 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( 1569 Handle<Map> initial_map, Handle<SharedFunctionInfo> info, 1570 Handle<Object> context_or_undefined, PretenureFlag pretenure) { 1571 DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type()); 1572 Handle<JSFunction> result = 1573 NewFunction(initial_map, info, context_or_undefined, pretenure); 1574 1575 if (info->ic_age() != isolate()->heap()->global_ic_age()) { 1576 info->ResetForNewContext(isolate()->heap()->global_ic_age()); 1577 } 1578 1579 if (context_or_undefined->IsContext()) { 1580 // Give compiler a chance to pre-initialize. 1581 Compiler::PostInstantiation(result, pretenure); 1582 } 1583 1584 return result; 1585 } 1586 1587 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo( 1588 Handle<Map> initial_map, Handle<SharedFunctionInfo> info, 1589 Handle<Object> context_or_undefined, Handle<Cell> vector, 1590 PretenureFlag pretenure) { 1591 DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type()); 1592 Handle<JSFunction> result = 1593 NewFunction(initial_map, info, context_or_undefined, pretenure); 1594 1595 // Bump the closure count that is encoded in the vector cell's map. 1596 if (vector->map() == *no_closures_cell_map()) { 1597 vector->set_map(*one_closure_cell_map()); 1598 } else if (vector->map() == *one_closure_cell_map()) { 1599 vector->set_map(*many_closures_cell_map()); 1600 } else { 1601 DCHECK_EQ(vector->map(), *many_closures_cell_map()); 1602 } 1603 1604 result->set_feedback_vector_cell(*vector); 1605 if (info->ic_age() != isolate()->heap()->global_ic_age()) { 1606 info->ResetForNewContext(isolate()->heap()->global_ic_age()); 1607 } 1608 1609 if (context_or_undefined->IsContext()) { 1610 // Give compiler a chance to pre-initialize. 1611 Compiler::PostInstantiation(result, pretenure); 1612 } 1613 1614 return result; 1615 } 1616 1617 Handle<ScopeInfo> Factory::NewScopeInfo(int length) { 1618 Handle<FixedArray> array = NewFixedArray(length, TENURED); 1619 array->set_map_no_write_barrier(*scope_info_map()); 1620 Handle<ScopeInfo> scope_info = Handle<ScopeInfo>::cast(array); 1621 return scope_info; 1622 } 1623 1624 Handle<ModuleInfo> Factory::NewModuleInfo() { 1625 Handle<FixedArray> array = NewFixedArray(ModuleInfo::kLength, TENURED); 1626 array->set_map_no_write_barrier(*module_info_map()); 1627 return Handle<ModuleInfo>::cast(array); 1628 } 1629 1630 Handle<JSObject> Factory::NewExternal(void* value) { 1631 Handle<Foreign> foreign = NewForeign(static_cast<Address>(value)); 1632 Handle<JSObject> external = NewJSObjectFromMap(external_map()); 1633 external->SetInternalField(0, *foreign); 1634 return external; 1635 } 1636 1637 1638 Handle<Code> Factory::NewCodeRaw(int object_size, bool immovable) { 1639 CALL_HEAP_FUNCTION(isolate(), 1640 isolate()->heap()->AllocateCode(object_size, immovable), 1641 Code); 1642 } 1643 1644 1645 Handle<Code> Factory::NewCode(const CodeDesc& desc, 1646 Code::Flags flags, 1647 Handle<Object> self_ref, 1648 bool immovable, 1649 bool crankshafted, 1650 int prologue_offset, 1651 bool is_debug) { 1652 Handle<ByteArray> reloc_info = NewByteArray(desc.reloc_size, TENURED); 1653 1654 bool has_unwinding_info = desc.unwinding_info != nullptr; 1655 DCHECK((has_unwinding_info && desc.unwinding_info_size > 0) || 1656 (!has_unwinding_info && desc.unwinding_info_size == 0)); 1657 1658 // Compute size. 1659 int body_size = desc.instr_size; 1660 int unwinding_info_size_field_size = kInt64Size; 1661 if (has_unwinding_info) { 1662 body_size = RoundUp(body_size, kInt64Size) + desc.unwinding_info_size + 1663 unwinding_info_size_field_size; 1664 } 1665 int obj_size = Code::SizeFor(RoundUp(body_size, kObjectAlignment)); 1666 1667 Handle<Code> code = NewCodeRaw(obj_size, immovable); 1668 DCHECK(!isolate()->heap()->memory_allocator()->code_range()->valid() || 1669 isolate()->heap()->memory_allocator()->code_range()->contains( 1670 code->address()) || 1671 obj_size <= isolate()->heap()->code_space()->AreaSize()); 1672 1673 // The code object has not been fully initialized yet. We rely on the 1674 // fact that no allocation will happen from this point on. 1675 DisallowHeapAllocation no_gc; 1676 code->set_gc_metadata(Smi::kZero); 1677 code->set_ic_age(isolate()->heap()->global_ic_age()); 1678 code->set_instruction_size(desc.instr_size); 1679 code->set_relocation_info(*reloc_info); 1680 code->set_flags(flags); 1681 code->set_has_unwinding_info(has_unwinding_info); 1682 code->set_raw_kind_specific_flags1(0); 1683 code->set_raw_kind_specific_flags2(0); 1684 code->set_is_crankshafted(crankshafted); 1685 code->set_deoptimization_data(*empty_fixed_array(), SKIP_WRITE_BARRIER); 1686 code->set_raw_type_feedback_info(Smi::kZero); 1687 code->set_next_code_link(*undefined_value(), SKIP_WRITE_BARRIER); 1688 code->set_handler_table(*empty_fixed_array(), SKIP_WRITE_BARRIER); 1689 code->set_source_position_table(*empty_byte_array(), SKIP_WRITE_BARRIER); 1690 code->set_prologue_offset(prologue_offset); 1691 code->set_constant_pool_offset(desc.instr_size - desc.constant_pool_size); 1692 code->set_builtin_index(-1); 1693 1694 if (code->kind() == Code::OPTIMIZED_FUNCTION) { 1695 code->set_marked_for_deoptimization(false); 1696 } 1697 1698 if (is_debug) { 1699 DCHECK(code->kind() == Code::FUNCTION); 1700 code->set_has_debug_break_slots(true); 1701 } 1702 1703 // Allow self references to created code object by patching the handle to 1704 // point to the newly allocated Code object. 1705 if (!self_ref.is_null()) *(self_ref.location()) = *code; 1706 1707 // Migrate generated code. 1708 // The generated code can contain Object** values (typically from handles) 1709 // that are dereferenced during the copy to point directly to the actual heap 1710 // objects. These pointers can include references to the code object itself, 1711 // through the self_reference parameter. 1712 code->CopyFrom(desc); 1713 1714 #ifdef VERIFY_HEAP 1715 if (FLAG_verify_heap) code->ObjectVerify(); 1716 #endif 1717 return code; 1718 } 1719 1720 1721 Handle<Code> Factory::CopyCode(Handle<Code> code) { 1722 CALL_HEAP_FUNCTION(isolate(), 1723 isolate()->heap()->CopyCode(*code), 1724 Code); 1725 } 1726 1727 1728 Handle<BytecodeArray> Factory::CopyBytecodeArray( 1729 Handle<BytecodeArray> bytecode_array) { 1730 CALL_HEAP_FUNCTION(isolate(), 1731 isolate()->heap()->CopyBytecodeArray(*bytecode_array), 1732 BytecodeArray); 1733 } 1734 1735 Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor, 1736 PretenureFlag pretenure) { 1737 JSFunction::EnsureHasInitialMap(constructor); 1738 CALL_HEAP_FUNCTION( 1739 isolate(), 1740 isolate()->heap()->AllocateJSObject(*constructor, pretenure), JSObject); 1741 } 1742 1743 Handle<JSObject> Factory::NewJSObjectWithNullProto(PretenureFlag pretenure) { 1744 Handle<JSObject> result = 1745 NewJSObject(isolate()->object_function(), pretenure); 1746 Handle<Map> new_map = 1747 Map::Copy(Handle<Map>(result->map()), "ObjectWithNullProto"); 1748 Map::SetPrototype(new_map, null_value()); 1749 JSObject::MigrateToMap(result, new_map); 1750 return result; 1751 } 1752 1753 Handle<JSGlobalObject> Factory::NewJSGlobalObject( 1754 Handle<JSFunction> constructor) { 1755 DCHECK(constructor->has_initial_map()); 1756 Handle<Map> map(constructor->initial_map()); 1757 DCHECK(map->is_dictionary_map()); 1758 1759 // Make sure no field properties are described in the initial map. 1760 // This guarantees us that normalizing the properties does not 1761 // require us to change property values to PropertyCells. 1762 DCHECK(map->NextFreePropertyIndex() == 0); 1763 1764 // Make sure we don't have a ton of pre-allocated slots in the 1765 // global objects. They will be unused once we normalize the object. 1766 DCHECK(map->unused_property_fields() == 0); 1767 DCHECK(map->GetInObjectProperties() == 0); 1768 1769 // Initial size of the backing store to avoid resize of the storage during 1770 // bootstrapping. The size differs between the JS global object ad the 1771 // builtins object. 1772 int initial_size = 64; 1773 1774 // Allocate a dictionary object for backing storage. 1775 int at_least_space_for = map->NumberOfOwnDescriptors() * 2 + initial_size; 1776 Handle<GlobalDictionary> dictionary = 1777 GlobalDictionary::New(isolate(), at_least_space_for); 1778 1779 // The global object might be created from an object template with accessors. 1780 // Fill these accessors into the dictionary. 1781 Handle<DescriptorArray> descs(map->instance_descriptors()); 1782 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) { 1783 PropertyDetails details = descs->GetDetails(i); 1784 // Only accessors are expected. 1785 DCHECK_EQ(kAccessor, details.kind()); 1786 PropertyDetails d(kAccessor, details.attributes(), i + 1, 1787 PropertyCellType::kMutable); 1788 Handle<Name> name(descs->GetKey(i)); 1789 Handle<PropertyCell> cell = NewPropertyCell(); 1790 cell->set_value(descs->GetValue(i)); 1791 // |dictionary| already contains enough space for all properties. 1792 USE(GlobalDictionary::Add(dictionary, name, cell, d)); 1793 } 1794 1795 // Allocate the global object and initialize it with the backing store. 1796 Handle<JSGlobalObject> global = New<JSGlobalObject>(map, OLD_SPACE); 1797 isolate()->heap()->InitializeJSObjectFromMap(*global, *dictionary, *map); 1798 1799 // Create a new map for the global object. 1800 Handle<Map> new_map = Map::CopyDropDescriptors(map); 1801 new_map->set_dictionary_map(true); 1802 1803 // Set up the global object as a normalized object. 1804 global->set_map(*new_map); 1805 global->set_properties(*dictionary); 1806 1807 // Make sure result is a global object with properties in dictionary. 1808 DCHECK(global->IsJSGlobalObject() && !global->HasFastProperties()); 1809 return global; 1810 } 1811 1812 1813 Handle<JSObject> Factory::NewJSObjectFromMap( 1814 Handle<Map> map, 1815 PretenureFlag pretenure, 1816 Handle<AllocationSite> allocation_site) { 1817 CALL_HEAP_FUNCTION( 1818 isolate(), 1819 isolate()->heap()->AllocateJSObjectFromMap( 1820 *map, 1821 pretenure, 1822 allocation_site.is_null() ? NULL : *allocation_site), 1823 JSObject); 1824 } 1825 1826 1827 Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind, 1828 PretenureFlag pretenure) { 1829 Map* map = isolate()->get_initial_js_array_map(elements_kind); 1830 if (map == nullptr) { 1831 Context* native_context = isolate()->context()->native_context(); 1832 JSFunction* array_function = native_context->array_function(); 1833 map = array_function->initial_map(); 1834 } 1835 return Handle<JSArray>::cast(NewJSObjectFromMap(handle(map), pretenure)); 1836 } 1837 1838 Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind, int length, 1839 int capacity, 1840 ArrayStorageAllocationMode mode, 1841 PretenureFlag pretenure) { 1842 Handle<JSArray> array = NewJSArray(elements_kind, pretenure); 1843 NewJSArrayStorage(array, length, capacity, mode); 1844 return array; 1845 } 1846 1847 Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements, 1848 ElementsKind elements_kind, 1849 int length, 1850 PretenureFlag pretenure) { 1851 DCHECK(length <= elements->length()); 1852 Handle<JSArray> array = NewJSArray(elements_kind, pretenure); 1853 1854 array->set_elements(*elements); 1855 array->set_length(Smi::FromInt(length)); 1856 JSObject::ValidateElements(array); 1857 return array; 1858 } 1859 1860 1861 void Factory::NewJSArrayStorage(Handle<JSArray> array, 1862 int length, 1863 int capacity, 1864 ArrayStorageAllocationMode mode) { 1865 DCHECK(capacity >= length); 1866 1867 if (capacity == 0) { 1868 array->set_length(Smi::kZero); 1869 array->set_elements(*empty_fixed_array()); 1870 return; 1871 } 1872 1873 HandleScope inner_scope(isolate()); 1874 Handle<FixedArrayBase> elms; 1875 ElementsKind elements_kind = array->GetElementsKind(); 1876 if (IsFastDoubleElementsKind(elements_kind)) { 1877 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { 1878 elms = NewFixedDoubleArray(capacity); 1879 } else { 1880 DCHECK(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); 1881 elms = NewFixedDoubleArrayWithHoles(capacity); 1882 } 1883 } else { 1884 DCHECK(IsFastSmiOrObjectElementsKind(elements_kind)); 1885 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { 1886 elms = NewUninitializedFixedArray(capacity); 1887 } else { 1888 DCHECK(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); 1889 elms = NewFixedArrayWithHoles(capacity); 1890 } 1891 } 1892 1893 array->set_elements(*elms); 1894 array->set_length(Smi::FromInt(length)); 1895 } 1896 1897 Handle<JSModuleNamespace> Factory::NewJSModuleNamespace() { 1898 Handle<Map> map = isolate()->js_module_namespace_map(); 1899 Handle<JSModuleNamespace> module_namespace( 1900 Handle<JSModuleNamespace>::cast(NewJSObjectFromMap(map))); 1901 FieldIndex index = FieldIndex::ForDescriptor( 1902 *map, JSModuleNamespace::kToStringTagFieldIndex); 1903 module_namespace->FastPropertyAtPut(index, 1904 isolate()->heap()->Module_string()); 1905 return module_namespace; 1906 } 1907 1908 Handle<JSGeneratorObject> Factory::NewJSGeneratorObject( 1909 Handle<JSFunction> function) { 1910 DCHECK(IsResumableFunction(function->shared()->kind())); 1911 JSFunction::EnsureHasInitialMap(function); 1912 Handle<Map> map(function->initial_map()); 1913 DCHECK_EQ(JS_GENERATOR_OBJECT_TYPE, map->instance_type()); 1914 CALL_HEAP_FUNCTION( 1915 isolate(), 1916 isolate()->heap()->AllocateJSObjectFromMap(*map), 1917 JSGeneratorObject); 1918 } 1919 1920 Handle<Module> Factory::NewModule(Handle<SharedFunctionInfo> code) { 1921 Handle<ModuleInfo> module_info(code->scope_info()->ModuleDescriptorInfo(), 1922 isolate()); 1923 Handle<ObjectHashTable> exports = 1924 ObjectHashTable::New(isolate(), module_info->RegularExportCount()); 1925 Handle<FixedArray> regular_exports = 1926 NewFixedArray(module_info->RegularExportCount()); 1927 Handle<FixedArray> regular_imports = 1928 NewFixedArray(module_info->regular_imports()->length()); 1929 int requested_modules_length = module_info->module_requests()->length(); 1930 Handle<FixedArray> requested_modules = 1931 requested_modules_length > 0 ? NewFixedArray(requested_modules_length) 1932 : empty_fixed_array(); 1933 1934 Handle<Module> module = Handle<Module>::cast(NewStruct(MODULE_TYPE)); 1935 module->set_code(*code); 1936 module->set_exports(*exports); 1937 module->set_regular_exports(*regular_exports); 1938 module->set_regular_imports(*regular_imports); 1939 module->set_hash(isolate()->GenerateIdentityHash(Smi::kMaxValue)); 1940 module->set_module_namespace(isolate()->heap()->undefined_value()); 1941 module->set_requested_modules(*requested_modules); 1942 DCHECK(!module->instantiated()); 1943 DCHECK(!module->evaluated()); 1944 return module; 1945 } 1946 1947 Handle<JSArrayBuffer> Factory::NewJSArrayBuffer(SharedFlag shared, 1948 PretenureFlag pretenure) { 1949 Handle<JSFunction> array_buffer_fun( 1950 shared == SharedFlag::kShared 1951 ? isolate()->native_context()->shared_array_buffer_fun() 1952 : isolate()->native_context()->array_buffer_fun()); 1953 CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateJSObject( 1954 *array_buffer_fun, pretenure), 1955 JSArrayBuffer); 1956 } 1957 1958 1959 Handle<JSDataView> Factory::NewJSDataView() { 1960 Handle<JSFunction> data_view_fun( 1961 isolate()->native_context()->data_view_fun()); 1962 CALL_HEAP_FUNCTION( 1963 isolate(), 1964 isolate()->heap()->AllocateJSObject(*data_view_fun), 1965 JSDataView); 1966 } 1967 1968 Handle<JSIteratorResult> Factory::NewJSIteratorResult(Handle<Object> value, 1969 bool done) { 1970 Handle<Map> map(isolate()->native_context()->iterator_result_map()); 1971 Handle<JSIteratorResult> js_iter_result = 1972 Handle<JSIteratorResult>::cast(NewJSObjectFromMap(map)); 1973 js_iter_result->set_value(*value); 1974 js_iter_result->set_done(*ToBoolean(done)); 1975 return js_iter_result; 1976 } 1977 1978 Handle<JSAsyncFromSyncIterator> Factory::NewJSAsyncFromSyncIterator( 1979 Handle<JSReceiver> sync_iterator) { 1980 Handle<Map> map(isolate()->native_context()->async_from_sync_iterator_map()); 1981 Handle<JSAsyncFromSyncIterator> iterator = 1982 Handle<JSAsyncFromSyncIterator>::cast(NewJSObjectFromMap(map)); 1983 1984 iterator->set_sync_iterator(*sync_iterator); 1985 return iterator; 1986 } 1987 1988 Handle<JSMap> Factory::NewJSMap() { 1989 Handle<Map> map(isolate()->native_context()->js_map_map()); 1990 Handle<JSMap> js_map = Handle<JSMap>::cast(NewJSObjectFromMap(map)); 1991 JSMap::Initialize(js_map, isolate()); 1992 return js_map; 1993 } 1994 1995 1996 Handle<JSSet> Factory::NewJSSet() { 1997 Handle<Map> map(isolate()->native_context()->js_set_map()); 1998 Handle<JSSet> js_set = Handle<JSSet>::cast(NewJSObjectFromMap(map)); 1999 JSSet::Initialize(js_set, isolate()); 2000 return js_set; 2001 } 2002 2003 2004 Handle<JSMapIterator> Factory::NewJSMapIterator() { 2005 Handle<Map> map(isolate()->native_context()->map_iterator_map()); 2006 CALL_HEAP_FUNCTION(isolate(), 2007 isolate()->heap()->AllocateJSObjectFromMap(*map), 2008 JSMapIterator); 2009 } 2010 2011 2012 Handle<JSSetIterator> Factory::NewJSSetIterator() { 2013 Handle<Map> map(isolate()->native_context()->set_iterator_map()); 2014 CALL_HEAP_FUNCTION(isolate(), 2015 isolate()->heap()->AllocateJSObjectFromMap(*map), 2016 JSSetIterator); 2017 } 2018 2019 2020 namespace { 2021 2022 ElementsKind GetExternalArrayElementsKind(ExternalArrayType type) { 2023 switch (type) { 2024 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 2025 case kExternal##Type##Array: \ 2026 return TYPE##_ELEMENTS; 2027 TYPED_ARRAYS(TYPED_ARRAY_CASE) 2028 } 2029 UNREACHABLE(); 2030 return FIRST_FIXED_TYPED_ARRAY_ELEMENTS_KIND; 2031 #undef TYPED_ARRAY_CASE 2032 } 2033 2034 2035 size_t GetExternalArrayElementSize(ExternalArrayType type) { 2036 switch (type) { 2037 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 2038 case kExternal##Type##Array: \ 2039 return size; 2040 TYPED_ARRAYS(TYPED_ARRAY_CASE) 2041 default: 2042 UNREACHABLE(); 2043 return 0; 2044 } 2045 #undef TYPED_ARRAY_CASE 2046 } 2047 2048 2049 size_t GetFixedTypedArraysElementSize(ElementsKind kind) { 2050 switch (kind) { 2051 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 2052 case TYPE##_ELEMENTS: \ 2053 return size; 2054 TYPED_ARRAYS(TYPED_ARRAY_CASE) 2055 default: 2056 UNREACHABLE(); 2057 return 0; 2058 } 2059 #undef TYPED_ARRAY_CASE 2060 } 2061 2062 2063 ExternalArrayType GetArrayTypeFromElementsKind(ElementsKind kind) { 2064 switch (kind) { 2065 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 2066 case TYPE##_ELEMENTS: \ 2067 return kExternal##Type##Array; 2068 TYPED_ARRAYS(TYPED_ARRAY_CASE) 2069 default: 2070 UNREACHABLE(); 2071 return kExternalInt8Array; 2072 } 2073 #undef TYPED_ARRAY_CASE 2074 } 2075 2076 2077 JSFunction* GetTypedArrayFun(ExternalArrayType type, Isolate* isolate) { 2078 Context* native_context = isolate->context()->native_context(); 2079 switch (type) { 2080 #define TYPED_ARRAY_FUN(Type, type, TYPE, ctype, size) \ 2081 case kExternal##Type##Array: \ 2082 return native_context->type##_array_fun(); 2083 2084 TYPED_ARRAYS(TYPED_ARRAY_FUN) 2085 #undef TYPED_ARRAY_FUN 2086 2087 default: 2088 UNREACHABLE(); 2089 return NULL; 2090 } 2091 } 2092 2093 2094 JSFunction* GetTypedArrayFun(ElementsKind elements_kind, Isolate* isolate) { 2095 Context* native_context = isolate->context()->native_context(); 2096 switch (elements_kind) { 2097 #define TYPED_ARRAY_FUN(Type, type, TYPE, ctype, size) \ 2098 case TYPE##_ELEMENTS: \ 2099 return native_context->type##_array_fun(); 2100 2101 TYPED_ARRAYS(TYPED_ARRAY_FUN) 2102 #undef TYPED_ARRAY_FUN 2103 2104 default: 2105 UNREACHABLE(); 2106 return NULL; 2107 } 2108 } 2109 2110 2111 void SetupArrayBufferView(i::Isolate* isolate, 2112 i::Handle<i::JSArrayBufferView> obj, 2113 i::Handle<i::JSArrayBuffer> buffer, 2114 size_t byte_offset, size_t byte_length, 2115 PretenureFlag pretenure = NOT_TENURED) { 2116 DCHECK(byte_offset + byte_length <= 2117 static_cast<size_t>(buffer->byte_length()->Number())); 2118 2119 DCHECK_EQ(obj->GetInternalFieldCount(), 2120 v8::ArrayBufferView::kInternalFieldCount); 2121 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { 2122 obj->SetInternalField(i, Smi::kZero); 2123 } 2124 2125 obj->set_buffer(*buffer); 2126 2127 i::Handle<i::Object> byte_offset_object = 2128 isolate->factory()->NewNumberFromSize(byte_offset, pretenure); 2129 obj->set_byte_offset(*byte_offset_object); 2130 2131 i::Handle<i::Object> byte_length_object = 2132 isolate->factory()->NewNumberFromSize(byte_length, pretenure); 2133 obj->set_byte_length(*byte_length_object); 2134 } 2135 2136 2137 } // namespace 2138 2139 2140 Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type, 2141 PretenureFlag pretenure) { 2142 Handle<JSFunction> typed_array_fun_handle(GetTypedArrayFun(type, isolate())); 2143 2144 CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateJSObject( 2145 *typed_array_fun_handle, pretenure), 2146 JSTypedArray); 2147 } 2148 2149 2150 Handle<JSTypedArray> Factory::NewJSTypedArray(ElementsKind elements_kind, 2151 PretenureFlag pretenure) { 2152 Handle<JSFunction> typed_array_fun_handle( 2153 GetTypedArrayFun(elements_kind, isolate())); 2154 2155 CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateJSObject( 2156 *typed_array_fun_handle, pretenure), 2157 JSTypedArray); 2158 } 2159 2160 2161 Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type, 2162 Handle<JSArrayBuffer> buffer, 2163 size_t byte_offset, size_t length, 2164 PretenureFlag pretenure) { 2165 Handle<JSTypedArray> obj = NewJSTypedArray(type, pretenure); 2166 2167 size_t element_size = GetExternalArrayElementSize(type); 2168 ElementsKind elements_kind = GetExternalArrayElementsKind(type); 2169 2170 CHECK(byte_offset % element_size == 0); 2171 2172 CHECK(length <= (std::numeric_limits<size_t>::max() / element_size)); 2173 CHECK(length <= static_cast<size_t>(Smi::kMaxValue)); 2174 size_t byte_length = length * element_size; 2175 SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length, 2176 pretenure); 2177 2178 Handle<Object> length_object = NewNumberFromSize(length, pretenure); 2179 obj->set_length(*length_object); 2180 2181 Handle<FixedTypedArrayBase> elements = NewFixedTypedArrayWithExternalPointer( 2182 static_cast<int>(length), type, 2183 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset, pretenure); 2184 Handle<Map> map = JSObject::GetElementsTransitionMap(obj, elements_kind); 2185 JSObject::SetMapAndElements(obj, map, elements); 2186 return obj; 2187 } 2188 2189 2190 Handle<JSTypedArray> Factory::NewJSTypedArray(ElementsKind elements_kind, 2191 size_t number_of_elements, 2192 PretenureFlag pretenure) { 2193 Handle<JSTypedArray> obj = NewJSTypedArray(elements_kind, pretenure); 2194 DCHECK_EQ(obj->GetInternalFieldCount(), 2195 v8::ArrayBufferView::kInternalFieldCount); 2196 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { 2197 obj->SetInternalField(i, Smi::kZero); 2198 } 2199 2200 size_t element_size = GetFixedTypedArraysElementSize(elements_kind); 2201 ExternalArrayType array_type = GetArrayTypeFromElementsKind(elements_kind); 2202 2203 CHECK(number_of_elements <= 2204 (std::numeric_limits<size_t>::max() / element_size)); 2205 CHECK(number_of_elements <= static_cast<size_t>(Smi::kMaxValue)); 2206 size_t byte_length = number_of_elements * element_size; 2207 2208 obj->set_byte_offset(Smi::kZero); 2209 i::Handle<i::Object> byte_length_object = 2210 NewNumberFromSize(byte_length, pretenure); 2211 obj->set_byte_length(*byte_length_object); 2212 Handle<Object> length_object = 2213 NewNumberFromSize(number_of_elements, pretenure); 2214 obj->set_length(*length_object); 2215 2216 Handle<JSArrayBuffer> buffer = 2217 NewJSArrayBuffer(SharedFlag::kNotShared, pretenure); 2218 JSArrayBuffer::Setup(buffer, isolate(), true, NULL, byte_length, 2219 SharedFlag::kNotShared); 2220 obj->set_buffer(*buffer); 2221 Handle<FixedTypedArrayBase> elements = NewFixedTypedArray( 2222 static_cast<int>(number_of_elements), array_type, true, pretenure); 2223 obj->set_elements(*elements); 2224 return obj; 2225 } 2226 2227 2228 Handle<JSDataView> Factory::NewJSDataView(Handle<JSArrayBuffer> buffer, 2229 size_t byte_offset, 2230 size_t byte_length) { 2231 Handle<JSDataView> obj = NewJSDataView(); 2232 SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length); 2233 return obj; 2234 } 2235 2236 2237 MaybeHandle<JSBoundFunction> Factory::NewJSBoundFunction( 2238 Handle<JSReceiver> target_function, Handle<Object> bound_this, 2239 Vector<Handle<Object>> bound_args) { 2240 DCHECK(target_function->IsCallable()); 2241 STATIC_ASSERT(Code::kMaxArguments <= FixedArray::kMaxLength); 2242 if (bound_args.length() >= Code::kMaxArguments) { 2243 THROW_NEW_ERROR(isolate(), 2244 NewRangeError(MessageTemplate::kTooManyArguments), 2245 JSBoundFunction); 2246 } 2247 2248 // Determine the prototype of the {target_function}. 2249 Handle<Object> prototype; 2250 ASSIGN_RETURN_ON_EXCEPTION( 2251 isolate(), prototype, 2252 JSReceiver::GetPrototype(isolate(), target_function), JSBoundFunction); 2253 2254 // Create the [[BoundArguments]] for the result. 2255 Handle<FixedArray> bound_arguments; 2256 if (bound_args.length() == 0) { 2257 bound_arguments = empty_fixed_array(); 2258 } else { 2259 bound_arguments = NewFixedArray(bound_args.length()); 2260 for (int i = 0; i < bound_args.length(); ++i) { 2261 bound_arguments->set(i, *bound_args[i]); 2262 } 2263 } 2264 2265 // Setup the map for the JSBoundFunction instance. 2266 Handle<Map> map = target_function->IsConstructor() 2267 ? isolate()->bound_function_with_constructor_map() 2268 : isolate()->bound_function_without_constructor_map(); 2269 if (map->prototype() != *prototype) { 2270 map = Map::TransitionToPrototype(map, prototype, REGULAR_PROTOTYPE); 2271 } 2272 DCHECK_EQ(target_function->IsConstructor(), map->is_constructor()); 2273 2274 // Setup the JSBoundFunction instance. 2275 Handle<JSBoundFunction> result = 2276 Handle<JSBoundFunction>::cast(NewJSObjectFromMap(map)); 2277 result->set_bound_target_function(*target_function); 2278 result->set_bound_this(*bound_this); 2279 result->set_bound_arguments(*bound_arguments); 2280 return result; 2281 } 2282 2283 2284 // ES6 section 9.5.15 ProxyCreate (target, handler) 2285 Handle<JSProxy> Factory::NewJSProxy(Handle<JSReceiver> target, 2286 Handle<JSReceiver> handler) { 2287 // Allocate the proxy object. 2288 Handle<Map> map; 2289 if (target->IsCallable()) { 2290 if (target->IsConstructor()) { 2291 map = Handle<Map>(isolate()->proxy_constructor_map()); 2292 } else { 2293 map = Handle<Map>(isolate()->proxy_callable_map()); 2294 } 2295 } else { 2296 map = Handle<Map>(isolate()->proxy_map()); 2297 } 2298 DCHECK(map->prototype()->IsNull(isolate())); 2299 Handle<JSProxy> result = New<JSProxy>(map, NEW_SPACE); 2300 result->initialize_properties(); 2301 result->set_target(*target); 2302 result->set_handler(*handler); 2303 result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER); 2304 return result; 2305 } 2306 2307 Handle<JSGlobalProxy> Factory::NewUninitializedJSGlobalProxy(int size) { 2308 // Create an empty shell of a JSGlobalProxy that needs to be reinitialized 2309 // via ReinitializeJSGlobalProxy later. 2310 Handle<Map> map = NewMap(JS_GLOBAL_PROXY_TYPE, size); 2311 // Maintain invariant expected from any JSGlobalProxy. 2312 map->set_is_access_check_needed(true); 2313 CALL_HEAP_FUNCTION( 2314 isolate(), isolate()->heap()->AllocateJSObjectFromMap(*map, NOT_TENURED), 2315 JSGlobalProxy); 2316 } 2317 2318 2319 void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object, 2320 Handle<JSFunction> constructor) { 2321 DCHECK(constructor->has_initial_map()); 2322 Handle<Map> map(constructor->initial_map(), isolate()); 2323 Handle<Map> old_map(object->map(), isolate()); 2324 2325 // The proxy's hash should be retained across reinitialization. 2326 Handle<Object> hash(object->hash(), isolate()); 2327 2328 if (old_map->is_prototype_map()) { 2329 map = Map::Copy(map, "CopyAsPrototypeForJSGlobalProxy"); 2330 map->set_is_prototype_map(true); 2331 } 2332 JSObject::NotifyMapChange(old_map, map, isolate()); 2333 old_map->NotifyLeafMapLayoutChange(); 2334 2335 // Check that the already allocated object has the same size and type as 2336 // objects allocated using the constructor. 2337 DCHECK(map->instance_size() == old_map->instance_size()); 2338 DCHECK(map->instance_type() == old_map->instance_type()); 2339 2340 // Allocate the backing storage for the properties. 2341 Handle<FixedArray> properties = empty_fixed_array(); 2342 2343 // In order to keep heap in consistent state there must be no allocations 2344 // before object re-initialization is finished. 2345 DisallowHeapAllocation no_allocation; 2346 2347 // Reset the map for the object. 2348 object->synchronized_set_map(*map); 2349 2350 Heap* heap = isolate()->heap(); 2351 // Reinitialize the object from the constructor map. 2352 heap->InitializeJSObjectFromMap(*object, *properties, *map); 2353 2354 // Restore the saved hash. 2355 object->set_hash(*hash); 2356 } 2357 2358 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( 2359 Handle<String> name, FunctionKind kind, Handle<Code> code, 2360 Handle<ScopeInfo> scope_info) { 2361 DCHECK(IsValidFunctionKind(kind)); 2362 Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo( 2363 name, code, IsConstructable(kind, scope_info->language_mode())); 2364 shared->set_scope_info(*scope_info); 2365 shared->set_outer_scope_info(*the_hole_value()); 2366 shared->set_kind(kind); 2367 if (IsGeneratorFunction(kind)) { 2368 shared->set_instance_class_name(isolate()->heap()->Generator_string()); 2369 } 2370 return shared; 2371 } 2372 2373 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForLiteral( 2374 FunctionLiteral* literal, Handle<Script> script) { 2375 Handle<Code> code = isolate()->builtins()->CompileLazy(); 2376 Handle<ScopeInfo> scope_info(ScopeInfo::Empty(isolate())); 2377 Handle<SharedFunctionInfo> result = 2378 NewSharedFunctionInfo(literal->name(), literal->kind(), code, scope_info); 2379 SharedFunctionInfo::InitFromFunctionLiteral(result, literal); 2380 SharedFunctionInfo::SetScript(result, script); 2381 return result; 2382 } 2383 2384 Handle<JSMessageObject> Factory::NewJSMessageObject( 2385 MessageTemplate::Template message, Handle<Object> argument, 2386 int start_position, int end_position, Handle<Object> script, 2387 Handle<Object> stack_frames) { 2388 Handle<Map> map = message_object_map(); 2389 Handle<JSMessageObject> message_obj = New<JSMessageObject>(map, NEW_SPACE); 2390 message_obj->set_properties(*empty_fixed_array(), SKIP_WRITE_BARRIER); 2391 message_obj->initialize_elements(); 2392 message_obj->set_elements(*empty_fixed_array(), SKIP_WRITE_BARRIER); 2393 message_obj->set_type(message); 2394 message_obj->set_argument(*argument); 2395 message_obj->set_start_position(start_position); 2396 message_obj->set_end_position(end_position); 2397 message_obj->set_script(*script); 2398 message_obj->set_stack_frames(*stack_frames); 2399 message_obj->set_error_level(v8::Isolate::kMessageError); 2400 return message_obj; 2401 } 2402 2403 2404 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( 2405 Handle<String> name, MaybeHandle<Code> maybe_code, bool is_constructor) { 2406 // Function names are assumed to be flat elsewhere. Must flatten before 2407 // allocating SharedFunctionInfo to avoid GC seeing the uninitialized SFI. 2408 name = String::Flatten(name, TENURED); 2409 2410 Handle<Map> map = shared_function_info_map(); 2411 Handle<SharedFunctionInfo> share = New<SharedFunctionInfo>(map, OLD_SPACE); 2412 2413 // Set pointer fields. 2414 share->set_name(*name); 2415 share->set_function_data(*undefined_value(), SKIP_WRITE_BARRIER); 2416 Handle<Code> code; 2417 if (!maybe_code.ToHandle(&code)) { 2418 code = isolate()->builtins()->Illegal(); 2419 } 2420 share->set_code(*code); 2421 share->set_optimized_code_map(*empty_fixed_array()); 2422 share->set_scope_info(ScopeInfo::Empty(isolate())); 2423 share->set_outer_scope_info(*the_hole_value()); 2424 Handle<Code> construct_stub = 2425 is_constructor ? isolate()->builtins()->JSConstructStubGeneric() 2426 : isolate()->builtins()->ConstructedNonConstructable(); 2427 share->SetConstructStub(*construct_stub); 2428 share->set_instance_class_name(*Object_string()); 2429 share->set_script(*undefined_value(), SKIP_WRITE_BARRIER); 2430 share->set_debug_info(Smi::kZero, SKIP_WRITE_BARRIER); 2431 share->set_function_identifier(*undefined_value(), SKIP_WRITE_BARRIER); 2432 StaticFeedbackVectorSpec empty_spec; 2433 Handle<FeedbackMetadata> feedback_metadata = 2434 FeedbackMetadata::New(isolate(), &empty_spec); 2435 share->set_feedback_metadata(*feedback_metadata, SKIP_WRITE_BARRIER); 2436 share->set_function_literal_id(FunctionLiteral::kIdTypeInvalid); 2437 #if TRACE_MAPS 2438 share->set_unique_id(isolate()->GetNextUniqueSharedFunctionInfoId()); 2439 #endif 2440 share->set_profiler_ticks(0); 2441 share->set_ast_node_count(0); 2442 share->set_counters(0); 2443 2444 // Set integer fields (smi or int, depending on the architecture). 2445 share->set_length(0); 2446 share->set_internal_formal_parameter_count(0); 2447 share->set_expected_nof_properties(0); 2448 share->set_start_position_and_type(0); 2449 share->set_end_position(0); 2450 share->set_function_token_position(0); 2451 // All compiler hints default to false or 0. 2452 share->set_compiler_hints(0); 2453 share->set_opt_count_and_bailout_reason(0); 2454 2455 // Link into the list. 2456 Handle<Object> new_noscript_list = 2457 WeakFixedArray::Add(noscript_shared_function_infos(), share); 2458 isolate()->heap()->set_noscript_shared_function_infos(*new_noscript_list); 2459 2460 return share; 2461 } 2462 2463 2464 static inline int NumberCacheHash(Handle<FixedArray> cache, 2465 Handle<Object> number) { 2466 int mask = (cache->length() >> 1) - 1; 2467 if (number->IsSmi()) { 2468 return Handle<Smi>::cast(number)->value() & mask; 2469 } else { 2470 int64_t bits = bit_cast<int64_t>(number->Number()); 2471 return (static_cast<int>(bits) ^ static_cast<int>(bits >> 32)) & mask; 2472 } 2473 } 2474 2475 2476 Handle<Object> Factory::GetNumberStringCache(Handle<Object> number) { 2477 DisallowHeapAllocation no_gc; 2478 int hash = NumberCacheHash(number_string_cache(), number); 2479 Object* key = number_string_cache()->get(hash * 2); 2480 if (key == *number || (key->IsHeapNumber() && number->IsHeapNumber() && 2481 key->Number() == number->Number())) { 2482 return Handle<String>( 2483 String::cast(number_string_cache()->get(hash * 2 + 1)), isolate()); 2484 } 2485 return undefined_value(); 2486 } 2487 2488 2489 void Factory::SetNumberStringCache(Handle<Object> number, 2490 Handle<String> string) { 2491 int hash = NumberCacheHash(number_string_cache(), number); 2492 if (number_string_cache()->get(hash * 2) != *undefined_value()) { 2493 int full_size = isolate()->heap()->FullSizeNumberStringCacheLength(); 2494 if (number_string_cache()->length() != full_size) { 2495 Handle<FixedArray> new_cache = NewFixedArray(full_size, TENURED); 2496 isolate()->heap()->set_number_string_cache(*new_cache); 2497 return; 2498 } 2499 } 2500 number_string_cache()->set(hash * 2, *number); 2501 number_string_cache()->set(hash * 2 + 1, *string); 2502 } 2503 2504 2505 Handle<String> Factory::NumberToString(Handle<Object> number, 2506 bool check_number_string_cache) { 2507 isolate()->counters()->number_to_string_runtime()->Increment(); 2508 if (check_number_string_cache) { 2509 Handle<Object> cached = GetNumberStringCache(number); 2510 if (!cached->IsUndefined(isolate())) return Handle<String>::cast(cached); 2511 } 2512 2513 char arr[100]; 2514 Vector<char> buffer(arr, arraysize(arr)); 2515 const char* str; 2516 if (number->IsSmi()) { 2517 int num = Handle<Smi>::cast(number)->value(); 2518 str = IntToCString(num, buffer); 2519 } else { 2520 double num = Handle<HeapNumber>::cast(number)->value(); 2521 str = DoubleToCString(num, buffer); 2522 } 2523 2524 // We tenure the allocated string since it is referenced from the 2525 // number-string cache which lives in the old space. 2526 Handle<String> js_string = NewStringFromAsciiChecked(str, TENURED); 2527 SetNumberStringCache(number, js_string); 2528 return js_string; 2529 } 2530 2531 2532 Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) { 2533 DCHECK(!shared->HasDebugInfo()); 2534 // Allocate initial fixed array for active break points before allocating the 2535 // debug info object to avoid allocation while setting up the debug info 2536 // object. 2537 Handle<FixedArray> break_points( 2538 NewFixedArray(DebugInfo::kEstimatedNofBreakPointsInFunction)); 2539 2540 // Make a copy of the bytecode array if available. 2541 Handle<Object> maybe_debug_bytecode_array = undefined_value(); 2542 if (shared->HasBytecodeArray()) { 2543 Handle<BytecodeArray> original(shared->bytecode_array()); 2544 maybe_debug_bytecode_array = CopyBytecodeArray(original); 2545 } 2546 2547 // Create and set up the debug info object. Debug info contains function, a 2548 // copy of the original code, the executing code and initial fixed array for 2549 // active break points. 2550 Handle<DebugInfo> debug_info = 2551 Handle<DebugInfo>::cast(NewStruct(DEBUG_INFO_TYPE)); 2552 debug_info->set_shared(*shared); 2553 debug_info->set_debugger_hints(shared->debugger_hints()); 2554 debug_info->set_debug_bytecode_array(*maybe_debug_bytecode_array); 2555 debug_info->set_break_points(*break_points); 2556 2557 // Link debug info to function. 2558 shared->set_debug_info(*debug_info); 2559 2560 return debug_info; 2561 } 2562 2563 Handle<BreakPointInfo> Factory::NewBreakPointInfo(int source_position) { 2564 Handle<BreakPointInfo> new_break_point_info = 2565 Handle<BreakPointInfo>::cast(NewStruct(BREAK_POINT_INFO_TYPE)); 2566 new_break_point_info->set_source_position(source_position); 2567 new_break_point_info->set_break_point_objects(*undefined_value()); 2568 return new_break_point_info; 2569 } 2570 2571 Handle<JSObject> Factory::NewArgumentsObject(Handle<JSFunction> callee, 2572 int length) { 2573 bool strict_mode_callee = is_strict(callee->shared()->language_mode()) || 2574 !callee->shared()->has_simple_parameters(); 2575 Handle<Map> map = strict_mode_callee ? isolate()->strict_arguments_map() 2576 : isolate()->sloppy_arguments_map(); 2577 AllocationSiteUsageContext context(isolate(), Handle<AllocationSite>(), 2578 false); 2579 DCHECK(!isolate()->has_pending_exception()); 2580 Handle<JSObject> result = NewJSObjectFromMap(map); 2581 Handle<Smi> value(Smi::FromInt(length), isolate()); 2582 Object::SetProperty(result, length_string(), value, STRICT).Assert(); 2583 if (!strict_mode_callee) { 2584 Object::SetProperty(result, callee_string(), callee, STRICT).Assert(); 2585 } 2586 return result; 2587 } 2588 2589 2590 Handle<JSWeakMap> Factory::NewJSWeakMap() { 2591 // TODO(adamk): Currently the map is only created three times per 2592 // isolate. If it's created more often, the map should be moved into the 2593 // strong root list. 2594 Handle<Map> map = NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize); 2595 return Handle<JSWeakMap>::cast(NewJSObjectFromMap(map)); 2596 } 2597 2598 2599 Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context, 2600 int number_of_properties, 2601 bool* is_result_from_cache) { 2602 const int kMapCacheSize = 128; 2603 2604 // We do not cache maps for too many properties or when running builtin code. 2605 if (number_of_properties > kMapCacheSize || 2606 isolate()->bootstrapper()->IsActive()) { 2607 *is_result_from_cache = false; 2608 Handle<Map> map = Map::Create(isolate(), number_of_properties); 2609 return map; 2610 } 2611 *is_result_from_cache = true; 2612 if (number_of_properties == 0) { 2613 // Reuse the initial map of the Object function if the literal has no 2614 // predeclared properties. 2615 return handle(context->object_function()->initial_map(), isolate()); 2616 } 2617 2618 int cache_index = number_of_properties - 1; 2619 Handle<Object> maybe_cache(context->map_cache(), isolate()); 2620 if (maybe_cache->IsUndefined(isolate())) { 2621 // Allocate the new map cache for the native context. 2622 maybe_cache = NewFixedArray(kMapCacheSize, TENURED); 2623 context->set_map_cache(*maybe_cache); 2624 } else { 2625 // Check to see whether there is a matching element in the cache. 2626 Handle<FixedArray> cache = Handle<FixedArray>::cast(maybe_cache); 2627 Object* result = cache->get(cache_index); 2628 if (result->IsWeakCell()) { 2629 WeakCell* cell = WeakCell::cast(result); 2630 if (!cell->cleared()) { 2631 return handle(Map::cast(cell->value()), isolate()); 2632 } 2633 } 2634 } 2635 // Create a new map and add it to the cache. 2636 Handle<FixedArray> cache = Handle<FixedArray>::cast(maybe_cache); 2637 Handle<Map> map = Map::Create(isolate(), number_of_properties); 2638 Handle<WeakCell> cell = NewWeakCell(map); 2639 cache->set(cache_index, *cell); 2640 return map; 2641 } 2642 2643 2644 void Factory::SetRegExpAtomData(Handle<JSRegExp> regexp, 2645 JSRegExp::Type type, 2646 Handle<String> source, 2647 JSRegExp::Flags flags, 2648 Handle<Object> data) { 2649 Handle<FixedArray> store = NewFixedArray(JSRegExp::kAtomDataSize); 2650 2651 store->set(JSRegExp::kTagIndex, Smi::FromInt(type)); 2652 store->set(JSRegExp::kSourceIndex, *source); 2653 store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags)); 2654 store->set(JSRegExp::kAtomPatternIndex, *data); 2655 regexp->set_data(*store); 2656 } 2657 2658 2659 void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp, 2660 JSRegExp::Type type, 2661 Handle<String> source, 2662 JSRegExp::Flags flags, 2663 int capture_count) { 2664 Handle<FixedArray> store = NewFixedArray(JSRegExp::kIrregexpDataSize); 2665 Smi* uninitialized = Smi::FromInt(JSRegExp::kUninitializedValue); 2666 store->set(JSRegExp::kTagIndex, Smi::FromInt(type)); 2667 store->set(JSRegExp::kSourceIndex, *source); 2668 store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags)); 2669 store->set(JSRegExp::kIrregexpLatin1CodeIndex, uninitialized); 2670 store->set(JSRegExp::kIrregexpUC16CodeIndex, uninitialized); 2671 store->set(JSRegExp::kIrregexpLatin1CodeSavedIndex, uninitialized); 2672 store->set(JSRegExp::kIrregexpUC16CodeSavedIndex, uninitialized); 2673 store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::kZero); 2674 store->set(JSRegExp::kIrregexpCaptureCountIndex, 2675 Smi::FromInt(capture_count)); 2676 store->set(JSRegExp::kIrregexpCaptureNameMapIndex, uninitialized); 2677 regexp->set_data(*store); 2678 } 2679 2680 Handle<RegExpMatchInfo> Factory::NewRegExpMatchInfo() { 2681 // Initially, the last match info consists of all fixed fields plus space for 2682 // the match itself (i.e., 2 capture indices). 2683 static const int kInitialSize = RegExpMatchInfo::kFirstCaptureIndex + 2684 RegExpMatchInfo::kInitialCaptureIndices; 2685 2686 Handle<FixedArray> elems = NewFixedArray(kInitialSize); 2687 Handle<RegExpMatchInfo> result = Handle<RegExpMatchInfo>::cast(elems); 2688 2689 result->SetNumberOfCaptureRegisters(RegExpMatchInfo::kInitialCaptureIndices); 2690 result->SetLastSubject(*empty_string()); 2691 result->SetLastInput(*undefined_value()); 2692 result->SetCapture(0, 0); 2693 result->SetCapture(1, 0); 2694 2695 return result; 2696 } 2697 2698 Handle<Object> Factory::GlobalConstantFor(Handle<Name> name) { 2699 if (Name::Equals(name, undefined_string())) return undefined_value(); 2700 if (Name::Equals(name, nan_string())) return nan_value(); 2701 if (Name::Equals(name, infinity_string())) return infinity_value(); 2702 return Handle<Object>::null(); 2703 } 2704 2705 2706 Handle<Object> Factory::ToBoolean(bool value) { 2707 return value ? true_value() : false_value(); 2708 } 2709 2710 Handle<String> Factory::ToPrimitiveHintString(ToPrimitiveHint hint) { 2711 switch (hint) { 2712 case ToPrimitiveHint::kDefault: 2713 return default_string(); 2714 case ToPrimitiveHint::kNumber: 2715 return number_string(); 2716 case ToPrimitiveHint::kString: 2717 return string_string(); 2718 } 2719 UNREACHABLE(); 2720 return Handle<String>::null(); 2721 } 2722 2723 Handle<Map> Factory::CreateSloppyFunctionMap(FunctionMode function_mode) { 2724 Handle<Map> map = NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); 2725 SetFunctionInstanceDescriptor(map, function_mode); 2726 map->set_is_constructor(IsFunctionModeWithPrototype(function_mode)); 2727 map->set_is_callable(); 2728 return map; 2729 } 2730 2731 void Factory::SetFunctionInstanceDescriptor(Handle<Map> map, 2732 FunctionMode function_mode) { 2733 int size = IsFunctionModeWithPrototype(function_mode) ? 5 : 4; 2734 Map::EnsureDescriptorSlack(map, size); 2735 2736 PropertyAttributes ro_attribs = 2737 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); 2738 PropertyAttributes roc_attribs = 2739 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); 2740 2741 STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0); 2742 Handle<AccessorInfo> length = 2743 Accessors::FunctionLengthInfo(isolate(), roc_attribs); 2744 { // Add length. 2745 Descriptor d = Descriptor::AccessorConstant( 2746 Handle<Name>(Name::cast(length->name())), length, roc_attribs); 2747 map->AppendDescriptor(&d); 2748 } 2749 2750 STATIC_ASSERT(JSFunction::kNameDescriptorIndex == 1); 2751 Handle<AccessorInfo> name = 2752 Accessors::FunctionNameInfo(isolate(), roc_attribs); 2753 { // Add name. 2754 Descriptor d = Descriptor::AccessorConstant( 2755 Handle<Name>(Name::cast(name->name())), name, roc_attribs); 2756 map->AppendDescriptor(&d); 2757 } 2758 Handle<AccessorInfo> args = 2759 Accessors::FunctionArgumentsInfo(isolate(), ro_attribs); 2760 { // Add arguments. 2761 Descriptor d = Descriptor::AccessorConstant( 2762 Handle<Name>(Name::cast(args->name())), args, ro_attribs); 2763 map->AppendDescriptor(&d); 2764 } 2765 Handle<AccessorInfo> caller = 2766 Accessors::FunctionCallerInfo(isolate(), ro_attribs); 2767 { // Add caller. 2768 Descriptor d = Descriptor::AccessorConstant( 2769 Handle<Name>(Name::cast(caller->name())), caller, ro_attribs); 2770 map->AppendDescriptor(&d); 2771 } 2772 if (IsFunctionModeWithPrototype(function_mode)) { 2773 if (function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE) { 2774 ro_attribs = static_cast<PropertyAttributes>(ro_attribs & ~READ_ONLY); 2775 } 2776 Handle<AccessorInfo> prototype = 2777 Accessors::FunctionPrototypeInfo(isolate(), ro_attribs); 2778 Descriptor d = Descriptor::AccessorConstant( 2779 Handle<Name>(Name::cast(prototype->name())), prototype, ro_attribs); 2780 map->AppendDescriptor(&d); 2781 } 2782 } 2783 2784 Handle<Map> Factory::CreateStrictFunctionMap( 2785 FunctionMode function_mode, Handle<JSFunction> empty_function) { 2786 Handle<Map> map = NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); 2787 SetStrictFunctionInstanceDescriptor(map, function_mode); 2788 map->set_is_constructor(IsFunctionModeWithPrototype(function_mode)); 2789 map->set_is_callable(); 2790 Map::SetPrototype(map, empty_function); 2791 return map; 2792 } 2793 2794 void Factory::SetStrictFunctionInstanceDescriptor(Handle<Map> map, 2795 FunctionMode function_mode) { 2796 int size = IsFunctionModeWithPrototype(function_mode) ? 3 : 2; 2797 Map::EnsureDescriptorSlack(map, size); 2798 2799 PropertyAttributes rw_attribs = 2800 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); 2801 PropertyAttributes ro_attribs = 2802 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); 2803 PropertyAttributes roc_attribs = 2804 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); 2805 2806 DCHECK(function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE || 2807 function_mode == FUNCTION_WITH_READONLY_PROTOTYPE || 2808 function_mode == FUNCTION_WITHOUT_PROTOTYPE); 2809 STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0); 2810 { // Add length. 2811 Handle<AccessorInfo> length = 2812 Accessors::FunctionLengthInfo(isolate(), roc_attribs); 2813 Descriptor d = Descriptor::AccessorConstant( 2814 handle(Name::cast(length->name())), length, roc_attribs); 2815 map->AppendDescriptor(&d); 2816 } 2817 2818 STATIC_ASSERT(JSFunction::kNameDescriptorIndex == 1); 2819 { // Add name. 2820 Handle<AccessorInfo> name = 2821 Accessors::FunctionNameInfo(isolate(), roc_attribs); 2822 Descriptor d = Descriptor::AccessorConstant( 2823 handle(Name::cast(name->name())), name, roc_attribs); 2824 map->AppendDescriptor(&d); 2825 } 2826 if (IsFunctionModeWithPrototype(function_mode)) { 2827 // Add prototype. 2828 PropertyAttributes attribs = 2829 function_mode == FUNCTION_WITH_WRITEABLE_PROTOTYPE ? rw_attribs 2830 : ro_attribs; 2831 Handle<AccessorInfo> prototype = 2832 Accessors::FunctionPrototypeInfo(isolate(), attribs); 2833 Descriptor d = Descriptor::AccessorConstant( 2834 Handle<Name>(Name::cast(prototype->name())), prototype, attribs); 2835 map->AppendDescriptor(&d); 2836 } 2837 } 2838 2839 Handle<Map> Factory::CreateClassFunctionMap(Handle<JSFunction> empty_function) { 2840 Handle<Map> map = NewMap(JS_FUNCTION_TYPE, JSFunction::kSize); 2841 SetClassFunctionInstanceDescriptor(map); 2842 map->set_is_constructor(true); 2843 map->set_is_callable(); 2844 Map::SetPrototype(map, empty_function); 2845 return map; 2846 } 2847 2848 void Factory::SetClassFunctionInstanceDescriptor(Handle<Map> map) { 2849 Map::EnsureDescriptorSlack(map, 2); 2850 2851 PropertyAttributes rw_attribs = 2852 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); 2853 PropertyAttributes roc_attribs = 2854 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); 2855 2856 STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0); 2857 { // Add length. 2858 Handle<AccessorInfo> length = 2859 Accessors::FunctionLengthInfo(isolate(), roc_attribs); 2860 Descriptor d = Descriptor::AccessorConstant( 2861 handle(Name::cast(length->name())), length, roc_attribs); 2862 map->AppendDescriptor(&d); 2863 } 2864 2865 { 2866 // Add prototype. 2867 Handle<AccessorInfo> prototype = 2868 Accessors::FunctionPrototypeInfo(isolate(), rw_attribs); 2869 Descriptor d = Descriptor::AccessorConstant( 2870 Handle<Name>(Name::cast(prototype->name())), prototype, rw_attribs); 2871 map->AppendDescriptor(&d); 2872 } 2873 } 2874 2875 } // namespace internal 2876 } // namespace v8 2877