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
SetupHeapInternal(Heap * heap)38 bool SetupIsolateDelegate::SetupHeapInternal(Heap* heap) {
39 return heap->CreateHeapObjects();
40 }
41
CreateHeapObjects()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
AllocateMap(InstanceType instance_type,int instance_size,ElementsKind elements_kind,int inobject_properties)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
AllocatePartialMap(InstanceType instance_type,int instance_size)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
FinalizePartialMap(Map * map)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
Allocate(Map * map,AllocationSpace space)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
AllocateEmptyFixedTypedArray(ExternalArrayType array_type)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
CreateInitialMaps()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
CreateApiObjects()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
CreateInitialObjects()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
CreateInternalAccessorInfoObjects()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