1 // Copyright 2017 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/setup-isolate.h" 6 7 #include "src/accessors.h" 8 #include "src/ast/context-slot-cache.h" 9 #include "src/compilation-cache.h" 10 #include "src/contexts.h" 11 #include "src/heap-symbols.h" 12 #include "src/heap/factory.h" 13 #include "src/heap/heap.h" 14 #include "src/interpreter/interpreter.h" 15 #include "src/isolate.h" 16 #include "src/layout-descriptor.h" 17 #include "src/lookup-cache.h" 18 #include "src/objects-inl.h" 19 #include "src/objects/arguments.h" 20 #include "src/objects/data-handler.h" 21 #include "src/objects/debug-objects.h" 22 #include "src/objects/descriptor-array.h" 23 #include "src/objects/dictionary.h" 24 #include "src/objects/literal-objects-inl.h" 25 #include "src/objects/map.h" 26 #include "src/objects/microtask.h" 27 #include "src/objects/module.h" 28 #include "src/objects/promise.h" 29 #include "src/objects/script.h" 30 #include "src/objects/shared-function-info.h" 31 #include "src/objects/string.h" 32 #include "src/regexp/jsregexp.h" 33 #include "src/wasm/wasm-objects.h" 34 35 namespace v8 { 36 namespace internal { 37 38 bool SetupIsolateDelegate::SetupHeapInternal(Heap* heap) { 39 return heap->CreateHeapObjects(); 40 } 41 42 bool Heap::CreateHeapObjects() { 43 // Create initial maps. 44 if (!CreateInitialMaps()) return false; 45 CreateApiObjects(); 46 47 // Create initial objects 48 CreateInitialObjects(); 49 CreateInternalAccessorInfoObjects(); 50 CHECK_EQ(0u, gc_count_); 51 52 set_native_contexts_list(ReadOnlyRoots(this).undefined_value()); 53 set_allocation_sites_list(ReadOnlyRoots(this).undefined_value()); 54 55 return true; 56 } 57 58 const Heap::StringTypeTable Heap::string_type_table[] = { 59 #define STRING_TYPE_ELEMENT(type, size, name, camel_name) \ 60 {type, size, k##camel_name##MapRootIndex}, 61 STRING_TYPE_LIST(STRING_TYPE_ELEMENT) 62 #undef STRING_TYPE_ELEMENT 63 }; 64 65 const Heap::ConstantStringTable Heap::constant_string_table[] = { 66 {"", kempty_stringRootIndex}, 67 #define CONSTANT_STRING_ELEMENT(name, contents) {contents, k##name##RootIndex}, 68 INTERNALIZED_STRING_LIST(CONSTANT_STRING_ELEMENT) 69 #undef CONSTANT_STRING_ELEMENT 70 }; 71 72 const Heap::StructTable Heap::struct_table[] = { 73 #define STRUCT_TABLE_ELEMENT(NAME, Name, name) \ 74 {NAME##_TYPE, Name::kSize, k##Name##MapRootIndex}, 75 STRUCT_LIST(STRUCT_TABLE_ELEMENT) 76 #undef STRUCT_TABLE_ELEMENT 77 78 #define ALLOCATION_SITE_ELEMENT(NAME, Name, Size, name) \ 79 {NAME##_TYPE, Name::kSize##Size, k##Name##Size##MapRootIndex}, 80 ALLOCATION_SITE_LIST(ALLOCATION_SITE_ELEMENT) 81 #undef ALLOCATION_SITE_ELEMENT 82 83 #define DATA_HANDLER_ELEMENT(NAME, Name, Size, name) \ 84 {NAME##_TYPE, Name::kSizeWithData##Size, k##Name##Size##MapRootIndex}, 85 DATA_HANDLER_LIST(DATA_HANDLER_ELEMENT) 86 #undef DATA_HANDLER_ELEMENT 87 }; 88 89 AllocationResult Heap::AllocateMap(InstanceType instance_type, 90 int instance_size, 91 ElementsKind elements_kind, 92 int inobject_properties) { 93 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); 94 bool is_js_object = Map::IsJSObject(instance_type); 95 DCHECK_IMPLIES(is_js_object && 96 !Map::CanHaveFastTransitionableElementsKind(instance_type), 97 IsDictionaryElementsKind(elements_kind) || 98 IsTerminalElementsKind(elements_kind)); 99 HeapObject* result = nullptr; 100 // JSObjects have maps with a mutable prototype_validity_cell, so they cannot 101 // go in RO_SPACE. 102 AllocationResult allocation = 103 AllocateRaw(Map::kSize, is_js_object ? MAP_SPACE : RO_SPACE); 104 if (!allocation.To(&result)) return allocation; 105 106 result->set_map_after_allocation(ReadOnlyRoots(this).meta_map(), 107 SKIP_WRITE_BARRIER); 108 Map* map = isolate()->factory()->InitializeMap( 109 Map::cast(result), instance_type, instance_size, elements_kind, 110 inobject_properties); 111 112 return map; 113 } 114 115 AllocationResult Heap::AllocatePartialMap(InstanceType instance_type, 116 int instance_size) { 117 Object* result = nullptr; 118 AllocationResult allocation = AllocateRaw(Map::kSize, RO_SPACE); 119 if (!allocation.To(&result)) return allocation; 120 // Map::cast cannot be used due to uninitialized map field. 121 Map* map = reinterpret_cast<Map*>(result); 122 map->set_map_after_allocation(reinterpret_cast<Map*>(root(kMetaMapRootIndex)), 123 SKIP_WRITE_BARRIER); 124 map->set_instance_type(instance_type); 125 map->set_instance_size(instance_size); 126 // Initialize to only containing tagged fields. 127 if (FLAG_unbox_double_fields) { 128 map->set_layout_descriptor(LayoutDescriptor::FastPointerLayout()); 129 } 130 // GetVisitorId requires a properly initialized LayoutDescriptor. 131 map->set_visitor_id(Map::GetVisitorId(map)); 132 map->set_inobject_properties_start_or_constructor_function_index(0); 133 DCHECK(!map->IsJSObjectMap()); 134 map->set_prototype_validity_cell(Smi::FromInt(Map::kPrototypeChainValid)); 135 map->SetInObjectUnusedPropertyFields(0); 136 map->set_bit_field(0); 137 map->set_bit_field2(0); 138 DCHECK(!map->is_in_retained_map_list()); 139 int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) | 140 Map::OwnsDescriptorsBit::encode(true) | 141 Map::ConstructionCounterBits::encode(Map::kNoSlackTracking); 142 map->set_bit_field3(bit_field3); 143 map->set_elements_kind(TERMINAL_FAST_ELEMENTS_KIND); 144 return map; 145 } 146 147 void Heap::FinalizePartialMap(Map* map) { 148 ReadOnlyRoots roots(this); 149 map->set_dependent_code(DependentCode::cast(roots.empty_weak_fixed_array())); 150 map->set_raw_transitions(MaybeObject::FromSmi(Smi::kZero)); 151 map->set_instance_descriptors(roots.empty_descriptor_array()); 152 if (FLAG_unbox_double_fields) { 153 map->set_layout_descriptor(LayoutDescriptor::FastPointerLayout()); 154 } 155 map->set_prototype(roots.null_value()); 156 map->set_constructor_or_backpointer(roots.null_value()); 157 } 158 159 AllocationResult Heap::Allocate(Map* map, AllocationSpace space) { 160 DCHECK(map->instance_type() != MAP_TYPE); 161 int size = map->instance_size(); 162 HeapObject* result = nullptr; 163 AllocationResult allocation = AllocateRaw(size, space); 164 if (!allocation.To(&result)) return allocation; 165 // New space objects are allocated white. 166 WriteBarrierMode write_barrier_mode = 167 space == NEW_SPACE ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; 168 result->set_map_after_allocation(map, write_barrier_mode); 169 return result; 170 } 171 172 AllocationResult Heap::AllocateEmptyFixedTypedArray( 173 ExternalArrayType array_type) { 174 int size = OBJECT_POINTER_ALIGN(FixedTypedArrayBase::kDataOffset); 175 176 HeapObject* object = nullptr; 177 AllocationResult allocation = AllocateRaw( 178 size, RO_SPACE, 179 array_type == kExternalFloat64Array ? kDoubleAligned : kWordAligned); 180 if (!allocation.To(&object)) return allocation; 181 182 object->set_map_after_allocation(MapForFixedTypedArray(array_type), 183 SKIP_WRITE_BARRIER); 184 FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(object); 185 elements->set_base_pointer(elements, SKIP_WRITE_BARRIER); 186 elements->set_external_pointer( 187 reinterpret_cast<void*>( 188 ExternalReference::fixed_typed_array_base_data_offset().address()), 189 SKIP_WRITE_BARRIER); 190 elements->set_length(0); 191 return elements; 192 } 193 194 bool Heap::CreateInitialMaps() { 195 HeapObject* obj = nullptr; 196 { 197 AllocationResult allocation = AllocatePartialMap(MAP_TYPE, Map::kSize); 198 if (!allocation.To(&obj)) return false; 199 } 200 // Map::cast cannot be used due to uninitialized map field. 201 Map* new_meta_map = reinterpret_cast<Map*>(obj); 202 set_meta_map(new_meta_map); 203 new_meta_map->set_map_after_allocation(new_meta_map); 204 205 ReadOnlyRoots roots(this); 206 { // Partial map allocation 207 #define ALLOCATE_PARTIAL_MAP(instance_type, size, field_name) \ 208 { \ 209 Map* map; \ 210 if (!AllocatePartialMap((instance_type), (size)).To(&map)) return false; \ 211 set_##field_name##_map(map); \ 212 } 213 214 ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel, fixed_array); 215 ALLOCATE_PARTIAL_MAP(WEAK_FIXED_ARRAY_TYPE, kVariableSizeSentinel, 216 weak_fixed_array); 217 ALLOCATE_PARTIAL_MAP(WEAK_ARRAY_LIST_TYPE, kVariableSizeSentinel, 218 weak_array_list); 219 ALLOCATE_PARTIAL_MAP(FIXED_ARRAY_TYPE, kVariableSizeSentinel, 220 fixed_cow_array) 221 DCHECK_NE(roots.fixed_array_map(), roots.fixed_cow_array_map()); 222 223 ALLOCATE_PARTIAL_MAP(DESCRIPTOR_ARRAY_TYPE, kVariableSizeSentinel, 224 descriptor_array) 225 226 ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, undefined); 227 ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, null); 228 ALLOCATE_PARTIAL_MAP(ODDBALL_TYPE, Oddball::kSize, the_hole); 229 230 #undef ALLOCATE_PARTIAL_MAP 231 } 232 233 // Allocate the empty array. 234 { 235 AllocationResult alloc = AllocateRaw(FixedArray::SizeFor(0), RO_SPACE); 236 if (!alloc.To(&obj)) return false; 237 obj->set_map_after_allocation(roots.fixed_array_map(), SKIP_WRITE_BARRIER); 238 FixedArray::cast(obj)->set_length(0); 239 } 240 set_empty_fixed_array(FixedArray::cast(obj)); 241 242 { 243 AllocationResult alloc = AllocateRaw(WeakFixedArray::SizeFor(0), RO_SPACE); 244 if (!alloc.To(&obj)) return false; 245 obj->set_map_after_allocation(roots.weak_fixed_array_map(), 246 SKIP_WRITE_BARRIER); 247 WeakFixedArray::cast(obj)->set_length(0); 248 } 249 set_empty_weak_fixed_array(WeakFixedArray::cast(obj)); 250 251 { 252 AllocationResult allocation = 253 AllocateRaw(WeakArrayList::SizeForCapacity(0), RO_SPACE); 254 if (!allocation.To(&obj)) return false; 255 obj->set_map_after_allocation(roots.weak_array_list_map(), 256 SKIP_WRITE_BARRIER); 257 WeakArrayList::cast(obj)->set_capacity(0); 258 WeakArrayList::cast(obj)->set_length(0); 259 } 260 set_empty_weak_array_list(WeakArrayList::cast(obj)); 261 262 { 263 AllocationResult allocation = Allocate(roots.null_map(), RO_SPACE); 264 if (!allocation.To(&obj)) return false; 265 } 266 set_null_value(Oddball::cast(obj)); 267 Oddball::cast(obj)->set_kind(Oddball::kNull); 268 269 { 270 AllocationResult allocation = Allocate(roots.undefined_map(), RO_SPACE); 271 if (!allocation.To(&obj)) return false; 272 } 273 set_undefined_value(Oddball::cast(obj)); 274 Oddball::cast(obj)->set_kind(Oddball::kUndefined); 275 DCHECK(!InNewSpace(roots.undefined_value())); 276 { 277 AllocationResult allocation = Allocate(roots.the_hole_map(), RO_SPACE); 278 if (!allocation.To(&obj)) return false; 279 } 280 set_the_hole_value(Oddball::cast(obj)); 281 Oddball::cast(obj)->set_kind(Oddball::kTheHole); 282 283 // Set preliminary exception sentinel value before actually initializing it. 284 set_exception(roots.null_value()); 285 286 // Setup the struct maps first (needed for the EnumCache). 287 for (unsigned i = 0; i < arraysize(struct_table); i++) { 288 const StructTable& entry = struct_table[i]; 289 Map* map; 290 if (!AllocatePartialMap(entry.type, entry.size).To(&map)) return false; 291 roots_[entry.index] = map; 292 } 293 294 // Allocate the empty enum cache. 295 { 296 AllocationResult allocation = Allocate(roots.tuple2_map(), RO_SPACE); 297 if (!allocation.To(&obj)) return false; 298 } 299 set_empty_enum_cache(EnumCache::cast(obj)); 300 EnumCache::cast(obj)->set_keys(roots.empty_fixed_array()); 301 EnumCache::cast(obj)->set_indices(roots.empty_fixed_array()); 302 303 // Allocate the empty descriptor array. 304 { 305 STATIC_ASSERT(DescriptorArray::kFirstIndex != 0); 306 int length = DescriptorArray::kFirstIndex; 307 int size = WeakFixedArray::SizeFor(length); 308 if (!AllocateRaw(size, RO_SPACE).To(&obj)) return false; 309 obj->set_map_after_allocation(roots.descriptor_array_map(), 310 SKIP_WRITE_BARRIER); 311 DescriptorArray::cast(obj)->set_length(length); 312 } 313 set_empty_descriptor_array(DescriptorArray::cast(obj)); 314 DescriptorArray::cast(obj)->SetNumberOfDescriptors(0); 315 WeakFixedArray::cast(obj)->Set( 316 DescriptorArray::kEnumCacheIndex, 317 MaybeObject::FromObject(roots.empty_enum_cache())); 318 319 // Fix the instance_descriptors for the existing maps. 320 FinalizePartialMap(roots.meta_map()); 321 FinalizePartialMap(roots.fixed_array_map()); 322 FinalizePartialMap(roots.weak_fixed_array_map()); 323 FinalizePartialMap(roots.weak_array_list_map()); 324 FinalizePartialMap(roots.fixed_cow_array_map()); 325 FinalizePartialMap(roots.descriptor_array_map()); 326 FinalizePartialMap(roots.undefined_map()); 327 roots.undefined_map()->set_is_undetectable(true); 328 FinalizePartialMap(roots.null_map()); 329 roots.null_map()->set_is_undetectable(true); 330 FinalizePartialMap(roots.the_hole_map()); 331 for (unsigned i = 0; i < arraysize(struct_table); ++i) { 332 const StructTable& entry = struct_table[i]; 333 FinalizePartialMap(Map::cast(roots_[entry.index])); 334 } 335 336 { // Map allocation 337 #define ALLOCATE_MAP(instance_type, size, field_name) \ 338 { \ 339 Map* map; \ 340 if (!AllocateMap((instance_type), size).To(&map)) return false; \ 341 set_##field_name##_map(map); \ 342 } 343 344 #define ALLOCATE_VARSIZE_MAP(instance_type, field_name) \ 345 ALLOCATE_MAP(instance_type, kVariableSizeSentinel, field_name) 346 347 #define ALLOCATE_PRIMITIVE_MAP(instance_type, size, field_name, \ 348 constructor_function_index) \ 349 { \ 350 ALLOCATE_MAP((instance_type), (size), field_name); \ 351 roots.field_name##_map()->SetConstructorFunctionIndex( \ 352 (constructor_function_index)); \ 353 } 354 355 ALLOCATE_VARSIZE_MAP(SCOPE_INFO_TYPE, scope_info) 356 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_info) 357 ALLOCATE_VARSIZE_MAP(FEEDBACK_VECTOR_TYPE, feedback_vector) 358 ALLOCATE_PRIMITIVE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number, 359 Context::NUMBER_FUNCTION_INDEX) 360 ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, MutableHeapNumber::kSize, 361 mutable_heap_number) 362 ALLOCATE_PRIMITIVE_MAP(SYMBOL_TYPE, Symbol::kSize, symbol, 363 Context::SYMBOL_FUNCTION_INDEX) 364 ALLOCATE_MAP(FOREIGN_TYPE, Foreign::kSize, foreign) 365 366 ALLOCATE_PRIMITIVE_MAP(ODDBALL_TYPE, Oddball::kSize, boolean, 367 Context::BOOLEAN_FUNCTION_INDEX); 368 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, uninitialized); 369 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, arguments_marker); 370 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, exception); 371 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, termination_exception); 372 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, optimized_out); 373 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, stale_register); 374 ALLOCATE_MAP(ODDBALL_TYPE, Oddball::kSize, self_reference_marker); 375 ALLOCATE_VARSIZE_MAP(BIGINT_TYPE, bigint); 376 377 for (unsigned i = 0; i < arraysize(string_type_table); i++) { 378 const StringTypeTable& entry = string_type_table[i]; 379 { 380 AllocationResult allocation = AllocateMap(entry.type, entry.size); 381 if (!allocation.To(&obj)) return false; 382 } 383 Map* map = Map::cast(obj); 384 map->SetConstructorFunctionIndex(Context::STRING_FUNCTION_INDEX); 385 // Mark cons string maps as unstable, because their objects can change 386 // maps during GC. 387 if (StringShape(entry.type).IsCons()) map->mark_unstable(); 388 roots_[entry.index] = map; 389 } 390 391 { // Create a separate external one byte string map for native sources. 392 AllocationResult allocation = 393 AllocateMap(SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE, 394 ExternalOneByteString::kShortSize); 395 if (!allocation.To(&obj)) return false; 396 Map* map = Map::cast(obj); 397 map->SetConstructorFunctionIndex(Context::STRING_FUNCTION_INDEX); 398 set_native_source_string_map(map); 399 } 400 401 ALLOCATE_VARSIZE_MAP(FIXED_DOUBLE_ARRAY_TYPE, fixed_double_array) 402 roots.fixed_double_array_map()->set_elements_kind(HOLEY_DOUBLE_ELEMENTS); 403 ALLOCATE_VARSIZE_MAP(FEEDBACK_METADATA_TYPE, feedback_metadata) 404 ALLOCATE_VARSIZE_MAP(BYTE_ARRAY_TYPE, byte_array) 405 ALLOCATE_VARSIZE_MAP(BYTECODE_ARRAY_TYPE, bytecode_array) 406 ALLOCATE_VARSIZE_MAP(FREE_SPACE_TYPE, free_space) 407 ALLOCATE_VARSIZE_MAP(PROPERTY_ARRAY_TYPE, property_array) 408 ALLOCATE_VARSIZE_MAP(SMALL_ORDERED_HASH_MAP_TYPE, small_ordered_hash_map) 409 ALLOCATE_VARSIZE_MAP(SMALL_ORDERED_HASH_SET_TYPE, small_ordered_hash_set) 410 411 #define ALLOCATE_FIXED_TYPED_ARRAY_MAP(Type, type, TYPE, ctype) \ 412 ALLOCATE_VARSIZE_MAP(FIXED_##TYPE##_ARRAY_TYPE, fixed_##type##_array) 413 414 TYPED_ARRAYS(ALLOCATE_FIXED_TYPED_ARRAY_MAP) 415 #undef ALLOCATE_FIXED_TYPED_ARRAY_MAP 416 417 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, sloppy_arguments_elements) 418 419 ALLOCATE_VARSIZE_MAP(CODE_TYPE, code) 420 421 ALLOCATE_MAP(CELL_TYPE, Cell::kSize, cell); 422 { 423 // The invalid_prototype_validity_cell is needed for JSObject maps. 424 Smi* value = Smi::FromInt(Map::kPrototypeChainInvalid); 425 AllocationResult alloc = AllocateRaw(Cell::kSize, OLD_SPACE); 426 if (!alloc.To(&obj)) return false; 427 obj->set_map_after_allocation(roots.cell_map(), SKIP_WRITE_BARRIER); 428 Cell::cast(obj)->set_value(value); 429 set_invalid_prototype_validity_cell(Cell::cast(obj)); 430 } 431 432 ALLOCATE_MAP(PROPERTY_CELL_TYPE, PropertyCell::kSize, global_property_cell) 433 ALLOCATE_MAP(FILLER_TYPE, kPointerSize, one_pointer_filler) 434 ALLOCATE_MAP(FILLER_TYPE, 2 * kPointerSize, two_pointer_filler) 435 436 // The "no closures" and "one closure" FeedbackCell maps need 437 // to be marked unstable because their objects can change maps. 438 ALLOCATE_MAP(FEEDBACK_CELL_TYPE, FeedbackCell::kSize, no_closures_cell) 439 roots.no_closures_cell_map()->mark_unstable(); 440 ALLOCATE_MAP(FEEDBACK_CELL_TYPE, FeedbackCell::kSize, one_closure_cell) 441 roots.one_closure_cell_map()->mark_unstable(); 442 ALLOCATE_MAP(FEEDBACK_CELL_TYPE, FeedbackCell::kSize, many_closures_cell) 443 444 ALLOCATE_VARSIZE_MAP(TRANSITION_ARRAY_TYPE, transition_array) 445 446 ALLOCATE_VARSIZE_MAP(HASH_TABLE_TYPE, hash_table) 447 ALLOCATE_VARSIZE_MAP(ORDERED_HASH_MAP_TYPE, ordered_hash_map) 448 ALLOCATE_VARSIZE_MAP(ORDERED_HASH_SET_TYPE, ordered_hash_set) 449 ALLOCATE_VARSIZE_MAP(NAME_DICTIONARY_TYPE, name_dictionary) 450 ALLOCATE_VARSIZE_MAP(GLOBAL_DICTIONARY_TYPE, global_dictionary) 451 ALLOCATE_VARSIZE_MAP(NUMBER_DICTIONARY_TYPE, number_dictionary) 452 ALLOCATE_VARSIZE_MAP(SIMPLE_NUMBER_DICTIONARY_TYPE, 453 simple_number_dictionary) 454 ALLOCATE_VARSIZE_MAP(STRING_TABLE_TYPE, string_table) 455 456 ALLOCATE_VARSIZE_MAP(EPHEMERON_HASH_TABLE_TYPE, ephemeron_hash_table) 457 458 ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, array_list) 459 460 ALLOCATE_VARSIZE_MAP(FUNCTION_CONTEXT_TYPE, function_context) 461 ALLOCATE_VARSIZE_MAP(CATCH_CONTEXT_TYPE, catch_context) 462 ALLOCATE_VARSIZE_MAP(WITH_CONTEXT_TYPE, with_context) 463 ALLOCATE_VARSIZE_MAP(DEBUG_EVALUATE_CONTEXT_TYPE, debug_evaluate_context) 464 ALLOCATE_VARSIZE_MAP(BLOCK_CONTEXT_TYPE, block_context) 465 ALLOCATE_VARSIZE_MAP(MODULE_CONTEXT_TYPE, module_context) 466 ALLOCATE_VARSIZE_MAP(EVAL_CONTEXT_TYPE, eval_context) 467 ALLOCATE_VARSIZE_MAP(SCRIPT_CONTEXT_TYPE, script_context) 468 ALLOCATE_VARSIZE_MAP(SCRIPT_CONTEXT_TABLE_TYPE, script_context_table) 469 470 ALLOCATE_VARSIZE_MAP(OBJECT_BOILERPLATE_DESCRIPTION_TYPE, 471 object_boilerplate_description) 472 473 ALLOCATE_VARSIZE_MAP(NATIVE_CONTEXT_TYPE, native_context) 474 roots.native_context_map()->set_visitor_id(kVisitNativeContext); 475 476 ALLOCATE_MAP(CALL_HANDLER_INFO_TYPE, CallHandlerInfo::kSize, 477 side_effect_call_handler_info) 478 ALLOCATE_MAP(CALL_HANDLER_INFO_TYPE, CallHandlerInfo::kSize, 479 side_effect_free_call_handler_info) 480 ALLOCATE_MAP(CALL_HANDLER_INFO_TYPE, CallHandlerInfo::kSize, 481 next_call_side_effect_free_call_handler_info) 482 483 ALLOCATE_VARSIZE_MAP(PRE_PARSED_SCOPE_DATA_TYPE, pre_parsed_scope_data) 484 ALLOCATE_MAP(UNCOMPILED_DATA_WITHOUT_PRE_PARSED_SCOPE_TYPE, 485 UncompiledDataWithoutPreParsedScope::kSize, 486 uncompiled_data_without_pre_parsed_scope) 487 ALLOCATE_MAP(UNCOMPILED_DATA_WITH_PRE_PARSED_SCOPE_TYPE, 488 UncompiledDataWithPreParsedScope::kSize, 489 uncompiled_data_with_pre_parsed_scope) 490 ALLOCATE_MAP(SHARED_FUNCTION_INFO_TYPE, SharedFunctionInfo::kAlignedSize, 491 shared_function_info) 492 493 ALLOCATE_MAP(CODE_DATA_CONTAINER_TYPE, CodeDataContainer::kSize, 494 code_data_container) 495 496 ALLOCATE_MAP(JS_MESSAGE_OBJECT_TYPE, JSMessageObject::kSize, message_object) 497 ALLOCATE_MAP(JS_OBJECT_TYPE, JSObject::kHeaderSize + kPointerSize, external) 498 external_map()->set_is_extensible(false); 499 #undef ALLOCATE_PRIMITIVE_MAP 500 #undef ALLOCATE_VARSIZE_MAP 501 #undef ALLOCATE_MAP 502 } 503 504 { 505 AllocationResult alloc = AllocateRaw(FixedArray::SizeFor(0), RO_SPACE); 506 if (!alloc.To(&obj)) return false; 507 obj->set_map_after_allocation(roots.scope_info_map(), SKIP_WRITE_BARRIER); 508 FixedArray::cast(obj)->set_length(0); 509 } 510 set_empty_scope_info(ScopeInfo::cast(obj)); 511 512 { 513 // Empty boilerplate needs a field for literal_flags 514 AllocationResult alloc = AllocateRaw(FixedArray::SizeFor(1), RO_SPACE); 515 if (!alloc.To(&obj)) return false; 516 obj->set_map_after_allocation(roots.object_boilerplate_description_map(), 517 SKIP_WRITE_BARRIER); 518 519 FixedArray::cast(obj)->set_length(1); 520 FixedArray::cast(obj)->set(ObjectBoilerplateDescription::kLiteralTypeOffset, 521 Smi::kZero); 522 } 523 set_empty_object_boilerplate_description( 524 ObjectBoilerplateDescription::cast(obj)); 525 526 { 527 // Empty array boilerplate description 528 AllocationResult alloc = 529 Allocate(roots.array_boilerplate_description_map(), RO_SPACE); 530 if (!alloc.To(&obj)) return false; 531 532 ArrayBoilerplateDescription::cast(obj)->set_constant_elements( 533 roots.empty_fixed_array()); 534 ArrayBoilerplateDescription::cast(obj)->set_elements_kind( 535 ElementsKind::PACKED_SMI_ELEMENTS); 536 } 537 set_empty_array_boilerplate_description( 538 ArrayBoilerplateDescription::cast(obj)); 539 540 { 541 AllocationResult allocation = Allocate(roots.boolean_map(), RO_SPACE); 542 if (!allocation.To(&obj)) return false; 543 } 544 set_true_value(Oddball::cast(obj)); 545 Oddball::cast(obj)->set_kind(Oddball::kTrue); 546 547 { 548 AllocationResult allocation = Allocate(roots.boolean_map(), RO_SPACE); 549 if (!allocation.To(&obj)) return false; 550 } 551 set_false_value(Oddball::cast(obj)); 552 Oddball::cast(obj)->set_kind(Oddball::kFalse); 553 554 // Empty arrays. 555 { 556 if (!AllocateRaw(ByteArray::SizeFor(0), RO_SPACE).To(&obj)) return false; 557 obj->set_map_after_allocation(roots.byte_array_map(), SKIP_WRITE_BARRIER); 558 ByteArray::cast(obj)->set_length(0); 559 set_empty_byte_array(ByteArray::cast(obj)); 560 } 561 562 { 563 if (!AllocateRaw(FixedArray::SizeFor(0), RO_SPACE).To(&obj)) { 564 return false; 565 } 566 obj->set_map_after_allocation(roots.property_array_map(), 567 SKIP_WRITE_BARRIER); 568 PropertyArray::cast(obj)->initialize_length(0); 569 set_empty_property_array(PropertyArray::cast(obj)); 570 } 571 572 #define ALLOCATE_EMPTY_FIXED_TYPED_ARRAY(Type, type, TYPE, ctype) \ 573 { \ 574 FixedTypedArrayBase* obj; \ 575 if (!AllocateEmptyFixedTypedArray(kExternal##Type##Array).To(&obj)) \ 576 return false; \ 577 set_empty_fixed_##type##_array(obj); \ 578 } 579 580 TYPED_ARRAYS(ALLOCATE_EMPTY_FIXED_TYPED_ARRAY) 581 #undef ALLOCATE_EMPTY_FIXED_TYPED_ARRAY 582 583 DCHECK(!InNewSpace(roots.empty_fixed_array())); 584 585 roots.bigint_map()->SetConstructorFunctionIndex( 586 Context::BIGINT_FUNCTION_INDEX); 587 588 return true; 589 } 590 591 void Heap::CreateApiObjects() { 592 Isolate* isolate = this->isolate(); 593 HandleScope scope(isolate); 594 595 set_message_listeners(*TemplateList::New(isolate, 2)); 596 597 Handle<InterceptorInfo> info = Handle<InterceptorInfo>::cast( 598 isolate->factory()->NewStruct(INTERCEPTOR_INFO_TYPE, TENURED_READ_ONLY)); 599 info->set_flags(0); 600 set_noop_interceptor_info(*info); 601 } 602 603 void Heap::CreateInitialObjects() { 604 HandleScope scope(isolate()); 605 Factory* factory = isolate()->factory(); 606 ReadOnlyRoots roots(this); 607 608 // The -0 value must be set before NewNumber works. 609 set_minus_zero_value(*factory->NewHeapNumber(-0.0, TENURED_READ_ONLY)); 610 DCHECK(std::signbit(roots.minus_zero_value()->Number())); 611 612 set_nan_value(*factory->NewHeapNumber( 613 std::numeric_limits<double>::quiet_NaN(), TENURED_READ_ONLY)); 614 set_hole_nan_value( 615 *factory->NewHeapNumberFromBits(kHoleNanInt64, TENURED_READ_ONLY)); 616 set_infinity_value(*factory->NewHeapNumber(V8_INFINITY, TENURED_READ_ONLY)); 617 set_minus_infinity_value( 618 *factory->NewHeapNumber(-V8_INFINITY, TENURED_READ_ONLY)); 619 620 set_hash_seed(*factory->NewByteArray(kInt64Size, TENURED)); 621 InitializeHashSeed(); 622 623 // Allocate cache for single character one byte strings. 624 set_single_character_string_cache( 625 *factory->NewFixedArray(String::kMaxOneByteCharCode + 1, TENURED)); 626 627 // Allocate initial string table. 628 set_string_table(*StringTable::New(isolate(), kInitialStringTableSize)); 629 630 for (unsigned i = 0; i < arraysize(constant_string_table); i++) { 631 Handle<String> str = 632 factory->InternalizeUtf8String(constant_string_table[i].contents); 633 roots_[constant_string_table[i].index] = *str; 634 } 635 636 // Allocate 637 638 // Finish initializing oddballs after creating the string table. 639 Oddball::Initialize(isolate(), factory->undefined_value(), "undefined", 640 factory->nan_value(), "undefined", Oddball::kUndefined); 641 642 // Initialize the null_value. 643 Oddball::Initialize(isolate(), factory->null_value(), "null", 644 handle(Smi::kZero, isolate()), "object", Oddball::kNull); 645 646 // Initialize the_hole_value. 647 Oddball::Initialize(isolate(), factory->the_hole_value(), "hole", 648 factory->hole_nan_value(), "undefined", 649 Oddball::kTheHole); 650 651 // Initialize the true_value. 652 Oddball::Initialize(isolate(), factory->true_value(), "true", 653 handle(Smi::FromInt(1), isolate()), "boolean", 654 Oddball::kTrue); 655 656 // Initialize the false_value. 657 Oddball::Initialize(isolate(), factory->false_value(), "false", 658 handle(Smi::kZero, isolate()), "boolean", 659 Oddball::kFalse); 660 661 set_uninitialized_value( 662 *factory->NewOddball(factory->uninitialized_map(), "uninitialized", 663 handle(Smi::FromInt(-1), isolate()), "undefined", 664 Oddball::kUninitialized)); 665 666 set_arguments_marker( 667 *factory->NewOddball(factory->arguments_marker_map(), "arguments_marker", 668 handle(Smi::FromInt(-4), isolate()), "undefined", 669 Oddball::kArgumentsMarker)); 670 671 set_termination_exception(*factory->NewOddball( 672 factory->termination_exception_map(), "termination_exception", 673 handle(Smi::FromInt(-3), isolate()), "undefined", Oddball::kOther)); 674 675 set_exception(*factory->NewOddball(factory->exception_map(), "exception", 676 handle(Smi::FromInt(-5), isolate()), 677 "undefined", Oddball::kException)); 678 679 set_optimized_out(*factory->NewOddball(factory->optimized_out_map(), 680 "optimized_out", 681 handle(Smi::FromInt(-6), isolate()), 682 "undefined", Oddball::kOptimizedOut)); 683 684 set_stale_register( 685 *factory->NewOddball(factory->stale_register_map(), "stale_register", 686 handle(Smi::FromInt(-7), isolate()), "undefined", 687 Oddball::kStaleRegister)); 688 689 // Initialize the self-reference marker. 690 set_self_reference_marker( 691 *factory->NewSelfReferenceMarker(TENURED_READ_ONLY)); 692 693 // Create the code_stubs dictionary. The initial size is set to avoid 694 // expanding the dictionary during bootstrapping. 695 set_code_stubs(*SimpleNumberDictionary::New(isolate(), 128)); 696 697 { 698 HandleScope scope(isolate()); 699 #define SYMBOL_INIT(name) \ 700 { \ 701 Handle<Symbol> symbol( \ 702 isolate()->factory()->NewPrivateSymbol(TENURED_READ_ONLY)); \ 703 roots_[k##name##RootIndex] = *symbol; \ 704 } 705 PRIVATE_SYMBOL_LIST(SYMBOL_INIT) 706 #undef SYMBOL_INIT 707 } 708 709 { 710 HandleScope scope(isolate()); 711 #define SYMBOL_INIT(name, description) \ 712 Handle<Symbol> name = factory->NewSymbol(TENURED_READ_ONLY); \ 713 Handle<String> name##d = \ 714 factory->NewStringFromStaticChars(#description, TENURED_READ_ONLY); \ 715 name->set_name(*name##d); \ 716 roots_[k##name##RootIndex] = *name; 717 PUBLIC_SYMBOL_LIST(SYMBOL_INIT) 718 #undef SYMBOL_INIT 719 720 #define SYMBOL_INIT(name, description) \ 721 Handle<Symbol> name = factory->NewSymbol(TENURED_READ_ONLY); \ 722 Handle<String> name##d = \ 723 factory->NewStringFromStaticChars(#description, TENURED_READ_ONLY); \ 724 name->set_is_well_known_symbol(true); \ 725 name->set_name(*name##d); \ 726 roots_[k##name##RootIndex] = *name; 727 WELL_KNOWN_SYMBOL_LIST(SYMBOL_INIT) 728 #undef SYMBOL_INIT 729 730 // Mark "Interesting Symbols" appropriately. 731 to_string_tag_symbol->set_is_interesting_symbol(true); 732 } 733 734 Handle<NameDictionary> empty_property_dictionary = 735 NameDictionary::New(isolate(), 1, TENURED, USE_CUSTOM_MINIMUM_CAPACITY); 736 DCHECK(!empty_property_dictionary->HasSufficientCapacityToAdd(1)); 737 set_empty_property_dictionary(*empty_property_dictionary); 738 739 set_public_symbol_table(*empty_property_dictionary); 740 set_api_symbol_table(*empty_property_dictionary); 741 set_api_private_symbol_table(*empty_property_dictionary); 742 743 set_number_string_cache( 744 *factory->NewFixedArray(kInitialNumberStringCacheSize * 2, TENURED)); 745 746 // Allocate cache for string split and regexp-multiple. 747 set_string_split_cache(*factory->NewFixedArray( 748 RegExpResultsCache::kRegExpResultsCacheSize, TENURED)); 749 set_regexp_multiple_cache(*factory->NewFixedArray( 750 RegExpResultsCache::kRegExpResultsCacheSize, TENURED)); 751 752 // Allocate FeedbackCell for builtins. 753 Handle<FeedbackCell> many_closures_cell = 754 factory->NewManyClosuresCell(factory->undefined_value()); 755 set_many_closures_cell(*many_closures_cell); 756 757 // Microtask queue uses the empty fixed array as a sentinel for "empty". 758 // Number of queued microtasks stored in Isolate::pending_microtask_count(). 759 set_microtask_queue(roots.empty_fixed_array()); 760 761 { 762 Handle<FixedArray> empty_sloppy_arguments_elements = 763 factory->NewFixedArray(2, TENURED_READ_ONLY); 764 empty_sloppy_arguments_elements->set_map_after_allocation( 765 roots.sloppy_arguments_elements_map(), SKIP_WRITE_BARRIER); 766 set_empty_sloppy_arguments_elements(*empty_sloppy_arguments_elements); 767 } 768 769 set_detached_contexts(roots.empty_weak_array_list()); 770 set_retained_maps(roots.empty_weak_array_list()); 771 set_retaining_path_targets(roots.empty_weak_array_list()); 772 773 set_feedback_vectors_for_profiling_tools(roots.undefined_value()); 774 775 set_script_list(roots.empty_weak_array_list()); 776 777 Handle<NumberDictionary> slow_element_dictionary = NumberDictionary::New( 778 isolate(), 1, TENURED_READ_ONLY, USE_CUSTOM_MINIMUM_CAPACITY); 779 DCHECK(!slow_element_dictionary->HasSufficientCapacityToAdd(1)); 780 slow_element_dictionary->set_requires_slow_elements(); 781 set_empty_slow_element_dictionary(*slow_element_dictionary); 782 783 set_materialized_objects(*factory->NewFixedArray(0, TENURED)); 784 785 // Handling of script id generation is in Heap::NextScriptId(). 786 set_last_script_id(Smi::FromInt(v8::UnboundScript::kNoScriptId)); 787 set_last_debugging_id(Smi::FromInt(DebugInfo::kNoDebuggingId)); 788 set_next_template_serial_number(Smi::kZero); 789 790 // Allocate the empty OrderedHashMap. 791 Handle<FixedArray> empty_ordered_hash_map = factory->NewFixedArray( 792 OrderedHashMap::kHashTableStartIndex, TENURED_READ_ONLY); 793 empty_ordered_hash_map->set_map_no_write_barrier( 794 *factory->ordered_hash_map_map()); 795 for (int i = 0; i < empty_ordered_hash_map->length(); ++i) { 796 empty_ordered_hash_map->set(i, Smi::kZero); 797 } 798 set_empty_ordered_hash_map(*empty_ordered_hash_map); 799 800 // Allocate the empty OrderedHashSet. 801 Handle<FixedArray> empty_ordered_hash_set = factory->NewFixedArray( 802 OrderedHashSet::kHashTableStartIndex, TENURED_READ_ONLY); 803 empty_ordered_hash_set->set_map_no_write_barrier( 804 *factory->ordered_hash_set_map()); 805 for (int i = 0; i < empty_ordered_hash_set->length(); ++i) { 806 empty_ordered_hash_set->set(i, Smi::kZero); 807 } 808 set_empty_ordered_hash_set(*empty_ordered_hash_set); 809 810 // Allocate the empty FeedbackMetadata. 811 Handle<FeedbackMetadata> empty_feedback_metadata = 812 factory->NewFeedbackMetadata(0, TENURED_READ_ONLY); 813 set_empty_feedback_metadata(*empty_feedback_metadata); 814 815 // Allocate the empty script. 816 Handle<Script> script = factory->NewScript(factory->empty_string()); 817 script->set_type(Script::TYPE_NATIVE); 818 set_empty_script(*script); 819 820 Handle<Cell> array_constructor_cell = factory->NewCell( 821 handle(Smi::FromInt(Isolate::kProtectorValid), isolate())); 822 set_array_constructor_protector(*array_constructor_cell); 823 824 Handle<PropertyCell> cell = factory->NewPropertyCell(factory->empty_string()); 825 cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); 826 set_no_elements_protector(*cell); 827 828 cell = factory->NewPropertyCell(factory->empty_string(), TENURED_READ_ONLY); 829 cell->set_value(roots.the_hole_value()); 830 set_empty_property_cell(*cell); 831 832 cell = factory->NewPropertyCell(factory->empty_string()); 833 cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); 834 set_array_iterator_protector(*cell); 835 836 Handle<Cell> is_concat_spreadable_cell = factory->NewCell( 837 handle(Smi::FromInt(Isolate::kProtectorValid), isolate())); 838 set_is_concat_spreadable_protector(*is_concat_spreadable_cell); 839 840 cell = factory->NewPropertyCell(factory->empty_string()); 841 cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); 842 set_array_species_protector(*cell); 843 844 cell = factory->NewPropertyCell(factory->empty_string()); 845 cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); 846 set_typed_array_species_protector(*cell); 847 848 cell = factory->NewPropertyCell(factory->empty_string()); 849 cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); 850 set_promise_species_protector(*cell); 851 852 Handle<Cell> string_length_overflow_cell = factory->NewCell( 853 handle(Smi::FromInt(Isolate::kProtectorValid), isolate())); 854 set_string_length_protector(*string_length_overflow_cell); 855 856 cell = factory->NewPropertyCell(factory->empty_string()); 857 cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); 858 set_array_buffer_neutering_protector(*cell); 859 860 cell = factory->NewPropertyCell(factory->empty_string()); 861 cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); 862 set_promise_hook_protector(*cell); 863 864 Handle<Cell> promise_resolve_cell = factory->NewCell( 865 handle(Smi::FromInt(Isolate::kProtectorValid), isolate())); 866 set_promise_resolve_protector(*promise_resolve_cell); 867 868 cell = factory->NewPropertyCell(factory->empty_string()); 869 cell->set_value(Smi::FromInt(Isolate::kProtectorValid)); 870 set_promise_then_protector(*cell); 871 872 set_serialized_objects(roots.empty_fixed_array()); 873 set_serialized_global_proxy_sizes(roots.empty_fixed_array()); 874 875 set_noscript_shared_function_infos(roots.empty_weak_array_list()); 876 877 STATIC_ASSERT(interpreter::BytecodeOperands::kOperandScaleCount == 3); 878 set_deserialize_lazy_handler(Smi::kZero); 879 set_deserialize_lazy_handler_wide(Smi::kZero); 880 set_deserialize_lazy_handler_extra_wide(Smi::kZero); 881 882 // Evaluate the hash values which will then be cached in the strings. 883 isolate()->factory()->zero_string()->Hash(); 884 isolate()->factory()->one_string()->Hash(); 885 886 // Initialize builtins constants table. 887 set_builtins_constants_table(roots.empty_fixed_array()); 888 889 // Initialize context slot cache. 890 isolate_->context_slot_cache()->Clear(); 891 892 // Initialize descriptor cache. 893 isolate_->descriptor_lookup_cache()->Clear(); 894 895 // Initialize compilation cache. 896 isolate_->compilation_cache()->Clear(); 897 } 898 899 void Heap::CreateInternalAccessorInfoObjects() { 900 Isolate* isolate = this->isolate(); 901 HandleScope scope(isolate); 902 Handle<AccessorInfo> acessor_info; 903 904 #define INIT_ACCESSOR_INFO(accessor_name, AccessorName) \ 905 acessor_info = Accessors::Make##AccessorName##Info(isolate); \ 906 roots_[k##AccessorName##AccessorRootIndex] = *acessor_info; 907 ACCESSOR_INFO_LIST(INIT_ACCESSOR_INFO) 908 #undef INIT_ACCESSOR_INFO 909 910 #define INIT_SIDE_EFFECT_FLAG(AccessorName) \ 911 AccessorInfo::cast(roots_[k##AccessorName##AccessorRootIndex]) \ 912 ->set_has_no_side_effect(true); 913 SIDE_EFFECT_FREE_ACCESSOR_INFO_LIST(INIT_SIDE_EFFECT_FLAG) 914 #undef INIT_SIDE_EFFECT_FLAG 915 } 916 917 } // namespace internal 918 } // namespace v8 919