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