1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/heap/factory.h"
6
7 #include "src/accessors.h"
8 #include "src/allocation-site-scopes.h"
9 #include "src/ast/ast-source-ranges.h"
10 #include "src/ast/ast.h"
11 #include "src/base/bits.h"
12 #include "src/bootstrapper.h"
13 #include "src/builtins/constants-table-builder.h"
14 #include "src/compiler.h"
15 #include "src/conversions.h"
16 #include "src/interpreter/interpreter.h"
17 #include "src/isolate-inl.h"
18 #include "src/macro-assembler.h"
19 #include "src/objects/api-callbacks.h"
20 #include "src/objects/arguments-inl.h"
21 #include "src/objects/bigint.h"
22 #include "src/objects/debug-objects-inl.h"
23 #include "src/objects/frame-array-inl.h"
24 #include "src/objects/js-array-inl.h"
25 #include "src/objects/js-collection-inl.h"
26 #include "src/objects/js-generator-inl.h"
27 #include "src/objects/js-regexp-inl.h"
28 #include "src/objects/literal-objects-inl.h"
29 #include "src/objects/microtask-inl.h"
30 #include "src/objects/module-inl.h"
31 #include "src/objects/promise-inl.h"
32 #include "src/objects/scope-info.h"
33 #include "src/unicode-cache.h"
34 #include "src/unicode-decoder.h"
35
36 namespace v8 {
37 namespace internal {
38
39 namespace {
40
ComputeCodeObjectSize(const CodeDesc & desc)41 int ComputeCodeObjectSize(const CodeDesc& desc) {
42 bool has_unwinding_info = desc.unwinding_info != nullptr;
43 DCHECK((has_unwinding_info && desc.unwinding_info_size > 0) ||
44 (!has_unwinding_info && desc.unwinding_info_size == 0));
45 int body_size = desc.instr_size;
46 int unwinding_info_size_field_size = kInt64Size;
47 if (has_unwinding_info) {
48 body_size = RoundUp(body_size, kInt64Size) + desc.unwinding_info_size +
49 unwinding_info_size_field_size;
50 }
51 int object_size = Code::SizeFor(RoundUp(body_size, kObjectAlignment));
52 DCHECK(IsAligned(static_cast<intptr_t>(object_size), kCodeAlignment));
53 return object_size;
54 }
55
InitializeCode(Heap * heap,Handle<Code> code,int object_size,const CodeDesc & desc,Code::Kind kind,Handle<Object> self_ref,int32_t builtin_index,Handle<ByteArray> source_position_table,Handle<DeoptimizationData> deopt_data,Handle<ByteArray> reloc_info,Handle<CodeDataContainer> data_container,uint32_t stub_key,bool is_turbofanned,int stack_slots,int safepoint_table_offset,int handler_table_offset)56 void InitializeCode(Heap* heap, Handle<Code> code, int object_size,
57 const CodeDesc& desc, Code::Kind kind,
58 Handle<Object> self_ref, int32_t builtin_index,
59 Handle<ByteArray> source_position_table,
60 Handle<DeoptimizationData> deopt_data,
61 Handle<ByteArray> reloc_info,
62 Handle<CodeDataContainer> data_container, uint32_t stub_key,
63 bool is_turbofanned, int stack_slots,
64 int safepoint_table_offset, int handler_table_offset) {
65 DCHECK(IsAligned(code->address(), kCodeAlignment));
66 DCHECK(!heap->memory_allocator()->code_range()->valid() ||
67 heap->memory_allocator()->code_range()->contains(code->address()) ||
68 object_size <= heap->code_space()->AreaSize());
69
70 bool has_unwinding_info = desc.unwinding_info != nullptr;
71
72 code->set_raw_instruction_size(desc.instr_size);
73 code->set_relocation_info(*reloc_info);
74 const bool is_off_heap_trampoline = false;
75 code->initialize_flags(kind, has_unwinding_info, is_turbofanned, stack_slots,
76 is_off_heap_trampoline);
77 code->set_safepoint_table_offset(safepoint_table_offset);
78 code->set_handler_table_offset(handler_table_offset);
79 code->set_code_data_container(*data_container);
80 code->set_deoptimization_data(*deopt_data);
81 code->set_stub_key(stub_key);
82 code->set_source_position_table(*source_position_table);
83 code->set_constant_pool_offset(desc.instr_size - desc.constant_pool_size);
84 code->set_builtin_index(builtin_index);
85
86 // Allow self references to created code object by patching the handle to
87 // point to the newly allocated Code object.
88 if (!self_ref.is_null()) {
89 DCHECK(self_ref->IsOddball());
90 DCHECK(Oddball::cast(*self_ref)->kind() == Oddball::kSelfReferenceMarker);
91 if (FLAG_embedded_builtins) {
92 auto builder = heap->isolate()->builtins_constants_table_builder();
93 if (builder != nullptr) builder->PatchSelfReference(self_ref, code);
94 }
95 *(self_ref.location()) = *code;
96 }
97
98 // Migrate generated code.
99 // The generated code can contain Object** values (typically from handles)
100 // that are dereferenced during the copy to point directly to the actual heap
101 // objects. These pointers can include references to the code object itself,
102 // through the self_reference parameter.
103 code->CopyFromNoFlush(heap, desc);
104
105 code->clear_padding();
106
107 #ifdef VERIFY_HEAP
108 if (FLAG_verify_heap) code->ObjectVerify(heap->isolate());
109 #endif
110 }
111
112 } // namespace
113
AllocateRawWithImmortalMap(int size,PretenureFlag pretenure,Map * map,AllocationAlignment alignment)114 HeapObject* Factory::AllocateRawWithImmortalMap(int size,
115 PretenureFlag pretenure,
116 Map* map,
117 AllocationAlignment alignment) {
118 HeapObject* result = isolate()->heap()->AllocateRawWithRetryOrFail(
119 size, Heap::SelectSpace(pretenure), alignment);
120 result->set_map_after_allocation(map, SKIP_WRITE_BARRIER);
121 return result;
122 }
123
AllocateRawWithAllocationSite(Handle<Map> map,PretenureFlag pretenure,Handle<AllocationSite> allocation_site)124 HeapObject* Factory::AllocateRawWithAllocationSite(
125 Handle<Map> map, PretenureFlag pretenure,
126 Handle<AllocationSite> allocation_site) {
127 DCHECK(map->instance_type() != MAP_TYPE);
128 int size = map->instance_size();
129 if (!allocation_site.is_null()) size += AllocationMemento::kSize;
130 AllocationSpace space = Heap::SelectSpace(pretenure);
131 HeapObject* result =
132 isolate()->heap()->AllocateRawWithRetryOrFail(size, space);
133 WriteBarrierMode write_barrier_mode =
134 space == NEW_SPACE ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
135 result->set_map_after_allocation(*map, write_barrier_mode);
136 if (!allocation_site.is_null()) {
137 AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
138 reinterpret_cast<Address>(result) + map->instance_size());
139 InitializeAllocationMemento(alloc_memento, *allocation_site);
140 }
141 return result;
142 }
143
InitializeAllocationMemento(AllocationMemento * memento,AllocationSite * allocation_site)144 void Factory::InitializeAllocationMemento(AllocationMemento* memento,
145 AllocationSite* allocation_site) {
146 memento->set_map_after_allocation(*allocation_memento_map(),
147 SKIP_WRITE_BARRIER);
148 memento->set_allocation_site(allocation_site, SKIP_WRITE_BARRIER);
149 if (FLAG_allocation_site_pretenuring) {
150 allocation_site->IncrementMementoCreateCount();
151 }
152 }
153
AllocateRawArray(int size,PretenureFlag pretenure)154 HeapObject* Factory::AllocateRawArray(int size, PretenureFlag pretenure) {
155 AllocationSpace space = Heap::SelectSpace(pretenure);
156 HeapObject* result =
157 isolate()->heap()->AllocateRawWithRetryOrFail(size, space);
158 if (size > kMaxRegularHeapObjectSize && FLAG_use_marking_progress_bar) {
159 MemoryChunk* chunk = MemoryChunk::FromAddress(result->address());
160 chunk->SetFlag<AccessMode::ATOMIC>(MemoryChunk::HAS_PROGRESS_BAR);
161 }
162 return result;
163 }
164
AllocateRawFixedArray(int length,PretenureFlag pretenure)165 HeapObject* Factory::AllocateRawFixedArray(int length,
166 PretenureFlag pretenure) {
167 if (length < 0 || length > FixedArray::kMaxLength) {
168 isolate()->heap()->FatalProcessOutOfMemory("invalid array length");
169 }
170 return AllocateRawArray(FixedArray::SizeFor(length), pretenure);
171 }
172
AllocateRawWeakArrayList(int capacity,PretenureFlag pretenure)173 HeapObject* Factory::AllocateRawWeakArrayList(int capacity,
174 PretenureFlag pretenure) {
175 if (capacity < 0 || capacity > WeakArrayList::kMaxCapacity) {
176 isolate()->heap()->FatalProcessOutOfMemory("invalid array length");
177 }
178 return AllocateRawArray(WeakArrayList::SizeForCapacity(capacity), pretenure);
179 }
180
New(Handle<Map> map,PretenureFlag pretenure)181 HeapObject* Factory::New(Handle<Map> map, PretenureFlag pretenure) {
182 DCHECK(map->instance_type() != MAP_TYPE);
183 int size = map->instance_size();
184 AllocationSpace space = Heap::SelectSpace(pretenure);
185 HeapObject* result =
186 isolate()->heap()->AllocateRawWithRetryOrFail(size, space);
187 // New space objects are allocated white.
188 WriteBarrierMode write_barrier_mode =
189 space == NEW_SPACE ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
190 result->set_map_after_allocation(*map, write_barrier_mode);
191 return result;
192 }
193
NewFillerObject(int size,bool double_align,AllocationSpace space)194 Handle<HeapObject> Factory::NewFillerObject(int size, bool double_align,
195 AllocationSpace space) {
196 AllocationAlignment alignment = double_align ? kDoubleAligned : kWordAligned;
197 Heap* heap = isolate()->heap();
198 HeapObject* result = heap->AllocateRawWithRetryOrFail(size, space, alignment);
199 #ifdef DEBUG
200 MemoryChunk* chunk = MemoryChunk::FromAddress(result->address());
201 DCHECK(chunk->owner()->identity() == space);
202 #endif
203 heap->CreateFillerObjectAt(result->address(), size, ClearRecordedSlots::kNo);
204 return Handle<HeapObject>(result, isolate());
205 }
206
NewPrototypeInfo()207 Handle<PrototypeInfo> Factory::NewPrototypeInfo() {
208 Handle<PrototypeInfo> result =
209 Handle<PrototypeInfo>::cast(NewStruct(PROTOTYPE_INFO_TYPE, TENURED));
210 result->set_prototype_users(*empty_weak_array_list());
211 result->set_registry_slot(PrototypeInfo::UNREGISTERED);
212 result->set_bit_field(0);
213 result->set_module_namespace(*undefined_value());
214 return result;
215 }
216
NewEnumCache(Handle<FixedArray> keys,Handle<FixedArray> indices)217 Handle<EnumCache> Factory::NewEnumCache(Handle<FixedArray> keys,
218 Handle<FixedArray> indices) {
219 return Handle<EnumCache>::cast(NewTuple2(keys, indices, TENURED));
220 }
221
NewTuple2(Handle<Object> value1,Handle<Object> value2,PretenureFlag pretenure)222 Handle<Tuple2> Factory::NewTuple2(Handle<Object> value1, Handle<Object> value2,
223 PretenureFlag pretenure) {
224 Handle<Tuple2> result =
225 Handle<Tuple2>::cast(NewStruct(TUPLE2_TYPE, pretenure));
226 result->set_value1(*value1);
227 result->set_value2(*value2);
228 return result;
229 }
230
NewTuple3(Handle<Object> value1,Handle<Object> value2,Handle<Object> value3,PretenureFlag pretenure)231 Handle<Tuple3> Factory::NewTuple3(Handle<Object> value1, Handle<Object> value2,
232 Handle<Object> value3,
233 PretenureFlag pretenure) {
234 Handle<Tuple3> result =
235 Handle<Tuple3>::cast(NewStruct(TUPLE3_TYPE, pretenure));
236 result->set_value1(*value1);
237 result->set_value2(*value2);
238 result->set_value3(*value3);
239 return result;
240 }
241
NewArrayBoilerplateDescription(ElementsKind elements_kind,Handle<FixedArrayBase> constant_values)242 Handle<ArrayBoilerplateDescription> Factory::NewArrayBoilerplateDescription(
243 ElementsKind elements_kind, Handle<FixedArrayBase> constant_values) {
244 Handle<ArrayBoilerplateDescription> result =
245 Handle<ArrayBoilerplateDescription>::cast(
246 NewStruct(ARRAY_BOILERPLATE_DESCRIPTION_TYPE, TENURED));
247 result->set_elements_kind(elements_kind);
248 result->set_constant_elements(*constant_values);
249 return result;
250 }
251
NewTemplateObjectDescription(Handle<FixedArray> raw_strings,Handle<FixedArray> cooked_strings)252 Handle<TemplateObjectDescription> Factory::NewTemplateObjectDescription(
253 Handle<FixedArray> raw_strings, Handle<FixedArray> cooked_strings) {
254 DCHECK_EQ(raw_strings->length(), cooked_strings->length());
255 DCHECK_LT(0, raw_strings->length());
256 Handle<TemplateObjectDescription> result =
257 Handle<TemplateObjectDescription>::cast(NewStruct(TUPLE2_TYPE, TENURED));
258 result->set_raw_strings(*raw_strings);
259 result->set_cooked_strings(*cooked_strings);
260 return result;
261 }
262
NewOddball(Handle<Map> map,const char * to_string,Handle<Object> to_number,const char * type_of,byte kind,PretenureFlag pretenure)263 Handle<Oddball> Factory::NewOddball(Handle<Map> map, const char* to_string,
264 Handle<Object> to_number,
265 const char* type_of, byte kind,
266 PretenureFlag pretenure) {
267 Handle<Oddball> oddball(Oddball::cast(New(map, pretenure)), isolate());
268 Oddball::Initialize(isolate(), oddball, to_string, to_number, type_of, kind);
269 return oddball;
270 }
271
NewSelfReferenceMarker(PretenureFlag pretenure)272 Handle<Oddball> Factory::NewSelfReferenceMarker(PretenureFlag pretenure) {
273 return NewOddball(self_reference_marker_map(), "self_reference_marker",
274 handle(Smi::FromInt(-1), isolate()), "undefined",
275 Oddball::kSelfReferenceMarker, pretenure);
276 }
277
NewPropertyArray(int length,PretenureFlag pretenure)278 Handle<PropertyArray> Factory::NewPropertyArray(int length,
279 PretenureFlag pretenure) {
280 DCHECK_LE(0, length);
281 if (length == 0) return empty_property_array();
282 HeapObject* result = AllocateRawFixedArray(length, pretenure);
283 result->set_map_after_allocation(*property_array_map(), SKIP_WRITE_BARRIER);
284 Handle<PropertyArray> array(PropertyArray::cast(result), isolate());
285 array->initialize_length(length);
286 MemsetPointer(array->data_start(), *undefined_value(), length);
287 return array;
288 }
289
NewFixedArrayWithFiller(Heap::RootListIndex map_root_index,int length,Object * filler,PretenureFlag pretenure)290 Handle<FixedArray> Factory::NewFixedArrayWithFiller(
291 Heap::RootListIndex map_root_index, int length, Object* filler,
292 PretenureFlag pretenure) {
293 HeapObject* result = AllocateRawFixedArray(length, pretenure);
294 DCHECK(Heap::RootIsImmortalImmovable(map_root_index));
295 Map* map = Map::cast(isolate()->heap()->root(map_root_index));
296 result->set_map_after_allocation(map, SKIP_WRITE_BARRIER);
297 Handle<FixedArray> array(FixedArray::cast(result), isolate());
298 array->set_length(length);
299 MemsetPointer(array->data_start(), filler, length);
300 return array;
301 }
302
303 template <typename T>
NewFixedArrayWithMap(Heap::RootListIndex map_root_index,int length,PretenureFlag pretenure)304 Handle<T> Factory::NewFixedArrayWithMap(Heap::RootListIndex map_root_index,
305 int length, PretenureFlag pretenure) {
306 static_assert(std::is_base_of<FixedArray, T>::value,
307 "T must be a descendant of FixedArray");
308 // Zero-length case must be handled outside, where the knowledge about
309 // the map is.
310 DCHECK_LT(0, length);
311 return Handle<T>::cast(NewFixedArrayWithFiller(
312 map_root_index, length, *undefined_value(), pretenure));
313 }
314
315 template <typename T>
NewWeakFixedArrayWithMap(Heap::RootListIndex map_root_index,int length,PretenureFlag pretenure)316 Handle<T> Factory::NewWeakFixedArrayWithMap(Heap::RootListIndex map_root_index,
317 int length,
318 PretenureFlag pretenure) {
319 static_assert(std::is_base_of<WeakFixedArray, T>::value,
320 "T must be a descendant of WeakFixedArray");
321
322 // Zero-length case must be handled outside.
323 DCHECK_LT(0, length);
324
325 HeapObject* result =
326 AllocateRawArray(WeakFixedArray::SizeFor(length), pretenure);
327 Map* map = Map::cast(isolate()->heap()->root(map_root_index));
328 result->set_map_after_allocation(map, SKIP_WRITE_BARRIER);
329
330 Handle<WeakFixedArray> array(WeakFixedArray::cast(result), isolate());
331 array->set_length(length);
332 MemsetPointer(array->data_start(),
333 HeapObjectReference::Strong(*undefined_value()), length);
334
335 return Handle<T>::cast(array);
336 }
337
338 template Handle<FixedArray> Factory::NewFixedArrayWithMap<FixedArray>(
339 Heap::RootListIndex, int, PretenureFlag);
340
341 template Handle<DescriptorArray>
342 Factory::NewWeakFixedArrayWithMap<DescriptorArray>(Heap::RootListIndex, int,
343 PretenureFlag);
344
NewFixedArray(int length,PretenureFlag pretenure)345 Handle<FixedArray> Factory::NewFixedArray(int length, PretenureFlag pretenure) {
346 DCHECK_LE(0, length);
347 if (length == 0) return empty_fixed_array();
348 return NewFixedArrayWithFiller(Heap::kFixedArrayMapRootIndex, length,
349 *undefined_value(), pretenure);
350 }
351
NewWeakFixedArray(int length,PretenureFlag pretenure)352 Handle<WeakFixedArray> Factory::NewWeakFixedArray(int length,
353 PretenureFlag pretenure) {
354 DCHECK_LE(0, length);
355 if (length == 0) return empty_weak_fixed_array();
356 HeapObject* result =
357 AllocateRawArray(WeakFixedArray::SizeFor(length), pretenure);
358 DCHECK(Heap::RootIsImmortalImmovable(Heap::kWeakFixedArrayMapRootIndex));
359 result->set_map_after_allocation(*weak_fixed_array_map(), SKIP_WRITE_BARRIER);
360 Handle<WeakFixedArray> array(WeakFixedArray::cast(result), isolate());
361 array->set_length(length);
362 MemsetPointer(array->data_start(),
363 HeapObjectReference::Strong(*undefined_value()), length);
364 return array;
365 }
366
TryNewFixedArray(int length,PretenureFlag pretenure)367 MaybeHandle<FixedArray> Factory::TryNewFixedArray(int length,
368 PretenureFlag pretenure) {
369 DCHECK_LE(0, length);
370 if (length == 0) return empty_fixed_array();
371
372 int size = FixedArray::SizeFor(length);
373 AllocationSpace space = Heap::SelectSpace(pretenure);
374 Heap* heap = isolate()->heap();
375 AllocationResult allocation = heap->AllocateRaw(size, space);
376 HeapObject* result = nullptr;
377 if (!allocation.To(&result)) return MaybeHandle<FixedArray>();
378 if (size > kMaxRegularHeapObjectSize && FLAG_use_marking_progress_bar) {
379 MemoryChunk* chunk = MemoryChunk::FromAddress(result->address());
380 chunk->SetFlag<AccessMode::ATOMIC>(MemoryChunk::HAS_PROGRESS_BAR);
381 }
382 result->set_map_after_allocation(*fixed_array_map(), SKIP_WRITE_BARRIER);
383 Handle<FixedArray> array(FixedArray::cast(result), isolate());
384 array->set_length(length);
385 MemsetPointer(array->data_start(), ReadOnlyRoots(heap).undefined_value(),
386 length);
387 return array;
388 }
389
NewFixedArrayWithHoles(int length,PretenureFlag pretenure)390 Handle<FixedArray> Factory::NewFixedArrayWithHoles(int length,
391 PretenureFlag pretenure) {
392 DCHECK_LE(0, length);
393 if (length == 0) return empty_fixed_array();
394 return NewFixedArrayWithFiller(Heap::kFixedArrayMapRootIndex, length,
395 *the_hole_value(), pretenure);
396 }
397
NewUninitializedFixedArray(int length,PretenureFlag pretenure)398 Handle<FixedArray> Factory::NewUninitializedFixedArray(
399 int length, PretenureFlag pretenure) {
400 DCHECK_LE(0, length);
401 if (length == 0) return empty_fixed_array();
402
403 // TODO(ulan): As an experiment this temporarily returns an initialized fixed
404 // array. After getting canary/performance coverage, either remove the
405 // function or revert to returning uninitilized array.
406 return NewFixedArrayWithFiller(Heap::kFixedArrayMapRootIndex, length,
407 *undefined_value(), pretenure);
408 }
409
NewFeedbackVector(Handle<SharedFunctionInfo> shared,PretenureFlag pretenure)410 Handle<FeedbackVector> Factory::NewFeedbackVector(
411 Handle<SharedFunctionInfo> shared, PretenureFlag pretenure) {
412 int length = shared->feedback_metadata()->slot_count();
413 DCHECK_LE(0, length);
414 int size = FeedbackVector::SizeFor(length);
415
416 HeapObject* result =
417 AllocateRawWithImmortalMap(size, pretenure, *feedback_vector_map());
418 Handle<FeedbackVector> vector(FeedbackVector::cast(result), isolate());
419 vector->set_shared_function_info(*shared);
420 vector->set_optimized_code_weak_or_smi(MaybeObject::FromSmi(Smi::FromEnum(
421 FLAG_log_function_events ? OptimizationMarker::kLogFirstExecution
422 : OptimizationMarker::kNone)));
423 vector->set_length(length);
424 vector->set_invocation_count(0);
425 vector->set_profiler_ticks(0);
426 vector->set_deopt_count(0);
427 // TODO(leszeks): Initialize based on the feedback metadata.
428 MemsetPointer(vector->slots_start(),
429 MaybeObject::FromObject(*undefined_value()), length);
430 return vector;
431 }
432
NewObjectBoilerplateDescription(int boilerplate,int all_properties,int index_keys,bool has_seen_proto)433 Handle<ObjectBoilerplateDescription> Factory::NewObjectBoilerplateDescription(
434 int boilerplate, int all_properties, int index_keys, bool has_seen_proto) {
435 DCHECK_GE(boilerplate, 0);
436 DCHECK_GE(all_properties, index_keys);
437 DCHECK_GE(index_keys, 0);
438
439 int backing_store_size =
440 all_properties - index_keys - (has_seen_proto ? 1 : 0);
441 DCHECK_GE(backing_store_size, 0);
442 bool has_different_size_backing_store = boilerplate != backing_store_size;
443
444 // Space for name and value for every boilerplate property + LiteralType flag.
445 int size =
446 2 * boilerplate + ObjectBoilerplateDescription::kDescriptionStartIndex;
447
448 if (has_different_size_backing_store) {
449 // An extra entry for the backing store size.
450 size++;
451 }
452
453 Handle<ObjectBoilerplateDescription> description =
454 Handle<ObjectBoilerplateDescription>::cast(NewFixedArrayWithMap(
455 Heap::kObjectBoilerplateDescriptionMapRootIndex, size, TENURED));
456
457 if (has_different_size_backing_store) {
458 DCHECK_IMPLIES((boilerplate == (all_properties - index_keys)),
459 has_seen_proto);
460 description->set_backing_store_size(isolate(), backing_store_size);
461 }
462
463 description->set_flags(0);
464
465 return description;
466 }
467
NewFixedDoubleArray(int length,PretenureFlag pretenure)468 Handle<FixedArrayBase> Factory::NewFixedDoubleArray(int length,
469 PretenureFlag pretenure) {
470 DCHECK_LE(0, length);
471 if (length == 0) return empty_fixed_array();
472 if (length < 0 || length > FixedDoubleArray::kMaxLength) {
473 isolate()->heap()->FatalProcessOutOfMemory("invalid array length");
474 }
475 int size = FixedDoubleArray::SizeFor(length);
476 Map* map = *fixed_double_array_map();
477 HeapObject* result =
478 AllocateRawWithImmortalMap(size, pretenure, map, kDoubleAligned);
479 Handle<FixedDoubleArray> array(FixedDoubleArray::cast(result), isolate());
480 array->set_length(length);
481 return array;
482 }
483
NewFixedDoubleArrayWithHoles(int length,PretenureFlag pretenure)484 Handle<FixedArrayBase> Factory::NewFixedDoubleArrayWithHoles(
485 int length, PretenureFlag pretenure) {
486 DCHECK_LE(0, length);
487 Handle<FixedArrayBase> array = NewFixedDoubleArray(length, pretenure);
488 if (length > 0) {
489 Handle<FixedDoubleArray>::cast(array)->FillWithHoles(0, length);
490 }
491 return array;
492 }
493
NewFeedbackMetadata(int slot_count,PretenureFlag tenure)494 Handle<FeedbackMetadata> Factory::NewFeedbackMetadata(int slot_count,
495 PretenureFlag tenure) {
496 DCHECK_LE(0, slot_count);
497 int size = FeedbackMetadata::SizeFor(slot_count);
498 HeapObject* result =
499 AllocateRawWithImmortalMap(size, tenure, *feedback_metadata_map());
500 Handle<FeedbackMetadata> data(FeedbackMetadata::cast(result), isolate());
501 data->set_slot_count(slot_count);
502
503 // Initialize the data section to 0.
504 int data_size = size - FeedbackMetadata::kHeaderSize;
505 Address data_start = data->address() + FeedbackMetadata::kHeaderSize;
506 memset(reinterpret_cast<byte*>(data_start), 0, data_size);
507 // Fields have been zeroed out but not initialized, so this object will not
508 // pass object verification at this point.
509 return data;
510 }
511
NewFrameArray(int number_of_frames,PretenureFlag pretenure)512 Handle<FrameArray> Factory::NewFrameArray(int number_of_frames,
513 PretenureFlag pretenure) {
514 DCHECK_LE(0, number_of_frames);
515 Handle<FixedArray> result = NewFixedArrayWithHoles(
516 FrameArray::LengthFor(number_of_frames), pretenure);
517 result->set(FrameArray::kFrameCountIndex, Smi::kZero);
518 return Handle<FrameArray>::cast(result);
519 }
520
NewSmallOrderedHashSet(int capacity,PretenureFlag pretenure)521 Handle<SmallOrderedHashSet> Factory::NewSmallOrderedHashSet(
522 int capacity, PretenureFlag pretenure) {
523 DCHECK_LE(0, capacity);
524 CHECK_LE(capacity, SmallOrderedHashSet::kMaxCapacity);
525 DCHECK_EQ(0, capacity % SmallOrderedHashSet::kLoadFactor);
526
527 int size = SmallOrderedHashSet::SizeFor(capacity);
528 Map* map = *small_ordered_hash_set_map();
529 HeapObject* result = AllocateRawWithImmortalMap(size, pretenure, map);
530 Handle<SmallOrderedHashSet> table(SmallOrderedHashSet::cast(result),
531 isolate());
532 table->Initialize(isolate(), capacity);
533 return table;
534 }
535
NewSmallOrderedHashMap(int capacity,PretenureFlag pretenure)536 Handle<SmallOrderedHashMap> Factory::NewSmallOrderedHashMap(
537 int capacity, PretenureFlag pretenure) {
538 DCHECK_LE(0, capacity);
539 CHECK_LE(capacity, SmallOrderedHashMap::kMaxCapacity);
540 DCHECK_EQ(0, capacity % SmallOrderedHashMap::kLoadFactor);
541
542 int size = SmallOrderedHashMap::SizeFor(capacity);
543 Map* map = *small_ordered_hash_map_map();
544 HeapObject* result = AllocateRawWithImmortalMap(size, pretenure, map);
545 Handle<SmallOrderedHashMap> table(SmallOrderedHashMap::cast(result),
546 isolate());
547 table->Initialize(isolate(), capacity);
548 return table;
549 }
550
NewOrderedHashSet()551 Handle<OrderedHashSet> Factory::NewOrderedHashSet() {
552 return OrderedHashSet::Allocate(isolate(), OrderedHashSet::kMinCapacity);
553 }
554
NewOrderedHashMap()555 Handle<OrderedHashMap> Factory::NewOrderedHashMap() {
556 return OrderedHashMap::Allocate(isolate(), OrderedHashMap::kMinCapacity);
557 }
558
NewAccessorPair()559 Handle<AccessorPair> Factory::NewAccessorPair() {
560 Handle<AccessorPair> accessors =
561 Handle<AccessorPair>::cast(NewStruct(ACCESSOR_PAIR_TYPE, TENURED));
562 accessors->set_getter(*null_value(), SKIP_WRITE_BARRIER);
563 accessors->set_setter(*null_value(), SKIP_WRITE_BARRIER);
564 return accessors;
565 }
566
567 // Internalized strings are created in the old generation (data space).
InternalizeUtf8String(Vector<const char> string)568 Handle<String> Factory::InternalizeUtf8String(Vector<const char> string) {
569 Utf8StringKey key(string, isolate()->heap()->HashSeed());
570 return InternalizeStringWithKey(&key);
571 }
572
InternalizeOneByteString(Vector<const uint8_t> string)573 Handle<String> Factory::InternalizeOneByteString(Vector<const uint8_t> string) {
574 OneByteStringKey key(string, isolate()->heap()->HashSeed());
575 return InternalizeStringWithKey(&key);
576 }
577
InternalizeOneByteString(Handle<SeqOneByteString> string,int from,int length)578 Handle<String> Factory::InternalizeOneByteString(
579 Handle<SeqOneByteString> string, int from, int length) {
580 SeqOneByteSubStringKey key(isolate(), string, from, length);
581 return InternalizeStringWithKey(&key);
582 }
583
InternalizeTwoByteString(Vector<const uc16> string)584 Handle<String> Factory::InternalizeTwoByteString(Vector<const uc16> string) {
585 TwoByteStringKey key(string, isolate()->heap()->HashSeed());
586 return InternalizeStringWithKey(&key);
587 }
588
589 template <class StringTableKey>
InternalizeStringWithKey(StringTableKey * key)590 Handle<String> Factory::InternalizeStringWithKey(StringTableKey* key) {
591 return StringTable::LookupKey(isolate(), key);
592 }
593
NewStringFromOneByte(Vector<const uint8_t> string,PretenureFlag pretenure)594 MaybeHandle<String> Factory::NewStringFromOneByte(Vector<const uint8_t> string,
595 PretenureFlag pretenure) {
596 int length = string.length();
597 if (length == 0) return empty_string();
598 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]);
599 Handle<SeqOneByteString> result;
600 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
601 NewRawOneByteString(string.length(), pretenure),
602 String);
603
604 DisallowHeapAllocation no_gc;
605 // Copy the characters into the new object.
606 CopyChars(SeqOneByteString::cast(*result)->GetChars(), string.start(),
607 length);
608 return result;
609 }
610
NewStringFromUtf8(Vector<const char> string,PretenureFlag pretenure)611 MaybeHandle<String> Factory::NewStringFromUtf8(Vector<const char> string,
612 PretenureFlag pretenure) {
613 // Check for ASCII first since this is the common case.
614 const char* ascii_data = string.start();
615 int length = string.length();
616 int non_ascii_start = String::NonAsciiStart(ascii_data, length);
617 if (non_ascii_start >= length) {
618 // If the string is ASCII, we do not need to convert the characters
619 // since UTF8 is backwards compatible with ASCII.
620 return NewStringFromOneByte(Vector<const uint8_t>::cast(string), pretenure);
621 }
622
623 // Non-ASCII and we need to decode.
624 auto non_ascii = string.SubVector(non_ascii_start, length);
625 Access<UnicodeCache::Utf8Decoder> decoder(
626 isolate()->unicode_cache()->utf8_decoder());
627 decoder->Reset(non_ascii);
628
629 int utf16_length = static_cast<int>(decoder->Utf16Length());
630 DCHECK_GT(utf16_length, 0);
631
632 // Allocate string.
633 Handle<SeqTwoByteString> result;
634 ASSIGN_RETURN_ON_EXCEPTION(
635 isolate(), result,
636 NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), String);
637
638 // Copy ASCII portion.
639 uint16_t* data = result->GetChars();
640 for (int i = 0; i < non_ascii_start; i++) {
641 *data++ = *ascii_data++;
642 }
643
644 // Now write the remainder.
645 decoder->WriteUtf16(data, utf16_length, non_ascii);
646 return result;
647 }
648
NewStringFromUtf8SubString(Handle<SeqOneByteString> str,int begin,int length,PretenureFlag pretenure)649 MaybeHandle<String> Factory::NewStringFromUtf8SubString(
650 Handle<SeqOneByteString> str, int begin, int length,
651 PretenureFlag pretenure) {
652 const char* ascii_data =
653 reinterpret_cast<const char*>(str->GetChars() + begin);
654 int non_ascii_start = String::NonAsciiStart(ascii_data, length);
655 if (non_ascii_start >= length) {
656 // If the string is ASCII, we can just make a substring.
657 // TODO(v8): the pretenure flag is ignored in this case.
658 return NewSubString(str, begin, begin + length);
659 }
660
661 // Non-ASCII and we need to decode.
662 auto non_ascii = Vector<const char>(ascii_data + non_ascii_start,
663 length - non_ascii_start);
664 Access<UnicodeCache::Utf8Decoder> decoder(
665 isolate()->unicode_cache()->utf8_decoder());
666 decoder->Reset(non_ascii);
667
668 int utf16_length = static_cast<int>(decoder->Utf16Length());
669 DCHECK_GT(utf16_length, 0);
670
671 // Allocate string.
672 Handle<SeqTwoByteString> result;
673 ASSIGN_RETURN_ON_EXCEPTION(
674 isolate(), result,
675 NewRawTwoByteString(non_ascii_start + utf16_length, pretenure), String);
676
677 // Update pointer references, since the original string may have moved after
678 // allocation.
679 ascii_data = reinterpret_cast<const char*>(str->GetChars() + begin);
680 non_ascii = Vector<const char>(ascii_data + non_ascii_start,
681 length - non_ascii_start);
682
683 // Copy ASCII portion.
684 uint16_t* data = result->GetChars();
685 for (int i = 0; i < non_ascii_start; i++) {
686 *data++ = *ascii_data++;
687 }
688
689 // Now write the remainder.
690 decoder->WriteUtf16(data, utf16_length, non_ascii);
691 return result;
692 }
693
NewStringFromTwoByte(const uc16 * string,int length,PretenureFlag pretenure)694 MaybeHandle<String> Factory::NewStringFromTwoByte(const uc16* string,
695 int length,
696 PretenureFlag pretenure) {
697 if (length == 0) return empty_string();
698 if (String::IsOneByte(string, length)) {
699 if (length == 1) return LookupSingleCharacterStringFromCode(string[0]);
700 Handle<SeqOneByteString> result;
701 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
702 NewRawOneByteString(length, pretenure), String);
703 CopyChars(result->GetChars(), string, length);
704 return result;
705 } else {
706 Handle<SeqTwoByteString> result;
707 ASSIGN_RETURN_ON_EXCEPTION(isolate(), result,
708 NewRawTwoByteString(length, pretenure), String);
709 CopyChars(result->GetChars(), string, length);
710 return result;
711 }
712 }
713
NewStringFromTwoByte(Vector<const uc16> string,PretenureFlag pretenure)714 MaybeHandle<String> Factory::NewStringFromTwoByte(Vector<const uc16> string,
715 PretenureFlag pretenure) {
716 return NewStringFromTwoByte(string.start(), string.length(), pretenure);
717 }
718
NewStringFromTwoByte(const ZoneVector<uc16> * string,PretenureFlag pretenure)719 MaybeHandle<String> Factory::NewStringFromTwoByte(
720 const ZoneVector<uc16>* string, PretenureFlag pretenure) {
721 return NewStringFromTwoByte(string->data(), static_cast<int>(string->size()),
722 pretenure);
723 }
724
725 namespace {
726
IsOneByte(Vector<const char> str,int chars)727 bool inline IsOneByte(Vector<const char> str, int chars) {
728 // TODO(dcarney): incorporate Latin-1 check when Latin-1 is supported?
729 return chars == str.length();
730 }
731
IsOneByte(Handle<String> str)732 bool inline IsOneByte(Handle<String> str) {
733 return str->IsOneByteRepresentation();
734 }
735
WriteOneByteData(Vector<const char> vector,uint8_t * chars,int len)736 inline void WriteOneByteData(Vector<const char> vector, uint8_t* chars,
737 int len) {
738 // Only works for one byte strings.
739 DCHECK(vector.length() == len);
740 MemCopy(chars, vector.start(), len);
741 }
742
WriteTwoByteData(Vector<const char> vector,uint16_t * chars,int len)743 inline void WriteTwoByteData(Vector<const char> vector, uint16_t* chars,
744 int len) {
745 unibrow::Utf8Iterator it = unibrow::Utf8Iterator(vector);
746 while (!it.Done()) {
747 DCHECK_GT(len, 0);
748 len -= 1;
749
750 uint16_t c = *it;
751 ++it;
752 DCHECK_NE(unibrow::Utf8::kBadChar, c);
753 *chars++ = c;
754 }
755 DCHECK_EQ(len, 0);
756 }
757
WriteOneByteData(Handle<String> s,uint8_t * chars,int len)758 inline void WriteOneByteData(Handle<String> s, uint8_t* chars, int len) {
759 DCHECK(s->length() == len);
760 String::WriteToFlat(*s, chars, 0, len);
761 }
762
WriteTwoByteData(Handle<String> s,uint16_t * chars,int len)763 inline void WriteTwoByteData(Handle<String> s, uint16_t* chars, int len) {
764 DCHECK(s->length() == len);
765 String::WriteToFlat(*s, chars, 0, len);
766 }
767
768 } // namespace
769
AllocateRawOneByteInternalizedString(int length,uint32_t hash_field)770 Handle<SeqOneByteString> Factory::AllocateRawOneByteInternalizedString(
771 int length, uint32_t hash_field) {
772 CHECK_GE(String::kMaxLength, length);
773 // The canonical empty_string is the only zero-length string we allow.
774 DCHECK_IMPLIES(
775 length == 0,
776 isolate()->heap()->roots_[Heap::kempty_stringRootIndex] == nullptr);
777
778 Map* map = *one_byte_internalized_string_map();
779 int size = SeqOneByteString::SizeFor(length);
780 HeapObject* result = AllocateRawWithImmortalMap(
781 size,
782 isolate()->heap()->CanAllocateInReadOnlySpace() ? TENURED_READ_ONLY
783 : TENURED,
784 map);
785 Handle<SeqOneByteString> answer(SeqOneByteString::cast(result), isolate());
786 answer->set_length(length);
787 answer->set_hash_field(hash_field);
788 DCHECK_EQ(size, answer->Size());
789 return answer;
790 }
791
AllocateTwoByteInternalizedString(Vector<const uc16> str,uint32_t hash_field)792 Handle<String> Factory::AllocateTwoByteInternalizedString(
793 Vector<const uc16> str, uint32_t hash_field) {
794 CHECK_GE(String::kMaxLength, str.length());
795 DCHECK_NE(0, str.length()); // Use Heap::empty_string() instead.
796
797 Map* map = *internalized_string_map();
798 int size = SeqTwoByteString::SizeFor(str.length());
799 HeapObject* result = AllocateRawWithImmortalMap(size, TENURED, map);
800 Handle<SeqTwoByteString> answer(SeqTwoByteString::cast(result), isolate());
801 answer->set_length(str.length());
802 answer->set_hash_field(hash_field);
803 DCHECK_EQ(size, answer->Size());
804
805 // Fill in the characters.
806 MemCopy(answer->GetChars(), str.start(), str.length() * kUC16Size);
807
808 return answer;
809 }
810
811 template <bool is_one_byte, typename T>
AllocateInternalizedStringImpl(T t,int chars,uint32_t hash_field)812 Handle<String> Factory::AllocateInternalizedStringImpl(T t, int chars,
813 uint32_t hash_field) {
814 DCHECK_LE(0, chars);
815 DCHECK_GE(String::kMaxLength, chars);
816
817 // Compute map and object size.
818 int size;
819 Map* map;
820 if (is_one_byte) {
821 map = *one_byte_internalized_string_map();
822 size = SeqOneByteString::SizeFor(chars);
823 } else {
824 map = *internalized_string_map();
825 size = SeqTwoByteString::SizeFor(chars);
826 }
827
828 HeapObject* result = AllocateRawWithImmortalMap(
829 size,
830 isolate()->heap()->CanAllocateInReadOnlySpace() ? TENURED_READ_ONLY
831 : TENURED,
832 map);
833 Handle<String> answer(String::cast(result), isolate());
834 answer->set_length(chars);
835 answer->set_hash_field(hash_field);
836 DCHECK_EQ(size, answer->Size());
837
838 if (is_one_byte) {
839 WriteOneByteData(t, SeqOneByteString::cast(*answer)->GetChars(), chars);
840 } else {
841 WriteTwoByteData(t, SeqTwoByteString::cast(*answer)->GetChars(), chars);
842 }
843 return answer;
844 }
845
NewInternalizedStringFromUtf8(Vector<const char> str,int chars,uint32_t hash_field)846 Handle<String> Factory::NewInternalizedStringFromUtf8(Vector<const char> str,
847 int chars,
848 uint32_t hash_field) {
849 if (IsOneByte(str, chars)) {
850 Handle<SeqOneByteString> result =
851 AllocateRawOneByteInternalizedString(str.length(), hash_field);
852 MemCopy(result->GetChars(), str.start(), str.length());
853 return result;
854 }
855 return AllocateInternalizedStringImpl<false>(str, chars, hash_field);
856 }
857
NewOneByteInternalizedString(Vector<const uint8_t> str,uint32_t hash_field)858 Handle<String> Factory::NewOneByteInternalizedString(Vector<const uint8_t> str,
859 uint32_t hash_field) {
860 Handle<SeqOneByteString> result =
861 AllocateRawOneByteInternalizedString(str.length(), hash_field);
862 MemCopy(result->GetChars(), str.start(), str.length());
863 return result;
864 }
865
NewOneByteInternalizedSubString(Handle<SeqOneByteString> string,int offset,int length,uint32_t hash_field)866 Handle<String> Factory::NewOneByteInternalizedSubString(
867 Handle<SeqOneByteString> string, int offset, int length,
868 uint32_t hash_field) {
869 Handle<SeqOneByteString> result =
870 AllocateRawOneByteInternalizedString(length, hash_field);
871 MemCopy(result->GetChars(), string->GetChars() + offset, length);
872 return result;
873 }
874
NewTwoByteInternalizedString(Vector<const uc16> str,uint32_t hash_field)875 Handle<String> Factory::NewTwoByteInternalizedString(Vector<const uc16> str,
876 uint32_t hash_field) {
877 return AllocateTwoByteInternalizedString(str, hash_field);
878 }
879
NewInternalizedStringImpl(Handle<String> string,int chars,uint32_t hash_field)880 Handle<String> Factory::NewInternalizedStringImpl(Handle<String> string,
881 int chars,
882 uint32_t hash_field) {
883 if (IsOneByte(string)) {
884 return AllocateInternalizedStringImpl<true>(string, chars, hash_field);
885 }
886 return AllocateInternalizedStringImpl<false>(string, chars, hash_field);
887 }
888
889 namespace {
890
GetInternalizedStringMap(Factory * f,Handle<String> string)891 MaybeHandle<Map> GetInternalizedStringMap(Factory* f, Handle<String> string) {
892 switch (string->map()->instance_type()) {
893 case STRING_TYPE:
894 return f->internalized_string_map();
895 case ONE_BYTE_STRING_TYPE:
896 return f->one_byte_internalized_string_map();
897 case EXTERNAL_STRING_TYPE:
898 return f->external_internalized_string_map();
899 case EXTERNAL_ONE_BYTE_STRING_TYPE:
900 return f->external_one_byte_internalized_string_map();
901 case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
902 return f->external_internalized_string_with_one_byte_data_map();
903 case SHORT_EXTERNAL_STRING_TYPE:
904 return f->short_external_internalized_string_map();
905 case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE:
906 return f->short_external_one_byte_internalized_string_map();
907 case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
908 return f->short_external_internalized_string_with_one_byte_data_map();
909 default:
910 return MaybeHandle<Map>(); // No match found.
911 }
912 }
913
914 } // namespace
915
InternalizedStringMapForString(Handle<String> string)916 MaybeHandle<Map> Factory::InternalizedStringMapForString(
917 Handle<String> string) {
918 // If the string is in new space it cannot be used as internalized.
919 if (Heap::InNewSpace(*string)) return MaybeHandle<Map>();
920
921 return GetInternalizedStringMap(this, string);
922 }
923
924 template <class StringClass>
InternalizeExternalString(Handle<String> string)925 Handle<StringClass> Factory::InternalizeExternalString(Handle<String> string) {
926 Handle<StringClass> cast_string = Handle<StringClass>::cast(string);
927 Handle<Map> map = GetInternalizedStringMap(this, string).ToHandleChecked();
928 Handle<StringClass> external_string(StringClass::cast(New(map, TENURED)),
929 isolate());
930 external_string->set_length(cast_string->length());
931 external_string->set_hash_field(cast_string->hash_field());
932 external_string->SetResource(isolate(), nullptr);
933 isolate()->heap()->RegisterExternalString(*external_string);
934 return external_string;
935 }
936
937 template Handle<ExternalOneByteString>
938 Factory::InternalizeExternalString<ExternalOneByteString>(Handle<String>);
939 template Handle<ExternalTwoByteString>
940 Factory::InternalizeExternalString<ExternalTwoByteString>(Handle<String>);
941
NewRawOneByteString(int length,PretenureFlag pretenure)942 MaybeHandle<SeqOneByteString> Factory::NewRawOneByteString(
943 int length, PretenureFlag pretenure) {
944 if (length > String::kMaxLength || length < 0) {
945 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqOneByteString);
946 }
947 DCHECK_GT(length, 0); // Use Factory::empty_string() instead.
948 int size = SeqOneByteString::SizeFor(length);
949 DCHECK_GE(SeqOneByteString::kMaxSize, size);
950
951 HeapObject* result =
952 AllocateRawWithImmortalMap(size, pretenure, *one_byte_string_map());
953 Handle<SeqOneByteString> string(SeqOneByteString::cast(result), isolate());
954 string->set_length(length);
955 string->set_hash_field(String::kEmptyHashField);
956 DCHECK_EQ(size, string->Size());
957 return string;
958 }
959
NewRawTwoByteString(int length,PretenureFlag pretenure)960 MaybeHandle<SeqTwoByteString> Factory::NewRawTwoByteString(
961 int length, PretenureFlag pretenure) {
962 if (length > String::kMaxLength || length < 0) {
963 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), SeqTwoByteString);
964 }
965 DCHECK_GT(length, 0); // Use Factory::empty_string() instead.
966 int size = SeqTwoByteString::SizeFor(length);
967 DCHECK_GE(SeqTwoByteString::kMaxSize, size);
968
969 HeapObject* result =
970 AllocateRawWithImmortalMap(size, pretenure, *string_map());
971 Handle<SeqTwoByteString> string(SeqTwoByteString::cast(result), isolate());
972 string->set_length(length);
973 string->set_hash_field(String::kEmptyHashField);
974 DCHECK_EQ(size, string->Size());
975 return string;
976 }
977
LookupSingleCharacterStringFromCode(uint32_t code)978 Handle<String> Factory::LookupSingleCharacterStringFromCode(uint32_t code) {
979 if (code <= String::kMaxOneByteCharCodeU) {
980 {
981 DisallowHeapAllocation no_allocation;
982 Object* value = single_character_string_cache()->get(code);
983 if (value != *undefined_value()) {
984 return handle(String::cast(value), isolate());
985 }
986 }
987 uint8_t buffer[1];
988 buffer[0] = static_cast<uint8_t>(code);
989 Handle<String> result =
990 InternalizeOneByteString(Vector<const uint8_t>(buffer, 1));
991 single_character_string_cache()->set(code, *result);
992 return result;
993 }
994 DCHECK_LE(code, String::kMaxUtf16CodeUnitU);
995
996 Handle<SeqTwoByteString> result = NewRawTwoByteString(1).ToHandleChecked();
997 result->SeqTwoByteStringSet(0, static_cast<uint16_t>(code));
998 return result;
999 }
1000
1001 // Returns true for a character in a range. Both limits are inclusive.
Between(uint32_t character,uint32_t from,uint32_t to)1002 static inline bool Between(uint32_t character, uint32_t from, uint32_t to) {
1003 // This makes uses of the the unsigned wraparound.
1004 return character - from <= to - from;
1005 }
1006
MakeOrFindTwoCharacterString(Isolate * isolate,uint16_t c1,uint16_t c2)1007 static inline Handle<String> MakeOrFindTwoCharacterString(Isolate* isolate,
1008 uint16_t c1,
1009 uint16_t c2) {
1010 // Numeric strings have a different hash algorithm not known by
1011 // LookupTwoCharsStringIfExists, so we skip this step for such strings.
1012 if (!Between(c1, '0', '9') || !Between(c2, '0', '9')) {
1013 Handle<String> result;
1014 if (StringTable::LookupTwoCharsStringIfExists(isolate, c1, c2)
1015 .ToHandle(&result)) {
1016 return result;
1017 }
1018 }
1019
1020 // Now we know the length is 2, we might as well make use of that fact
1021 // when building the new string.
1022 if (static_cast<unsigned>(c1 | c2) <= String::kMaxOneByteCharCodeU) {
1023 // We can do this.
1024 DCHECK(base::bits::IsPowerOfTwo(String::kMaxOneByteCharCodeU +
1025 1)); // because of this.
1026 Handle<SeqOneByteString> str =
1027 isolate->factory()->NewRawOneByteString(2).ToHandleChecked();
1028 uint8_t* dest = str->GetChars();
1029 dest[0] = static_cast<uint8_t>(c1);
1030 dest[1] = static_cast<uint8_t>(c2);
1031 return str;
1032 } else {
1033 Handle<SeqTwoByteString> str =
1034 isolate->factory()->NewRawTwoByteString(2).ToHandleChecked();
1035 uc16* dest = str->GetChars();
1036 dest[0] = c1;
1037 dest[1] = c2;
1038 return str;
1039 }
1040 }
1041
1042 template <typename SinkChar, typename StringType>
ConcatStringContent(Handle<StringType> result,Handle<String> first,Handle<String> second)1043 Handle<String> ConcatStringContent(Handle<StringType> result,
1044 Handle<String> first,
1045 Handle<String> second) {
1046 DisallowHeapAllocation pointer_stays_valid;
1047 SinkChar* sink = result->GetChars();
1048 String::WriteToFlat(*first, sink, 0, first->length());
1049 String::WriteToFlat(*second, sink + first->length(), 0, second->length());
1050 return result;
1051 }
1052
NewConsString(Handle<String> left,Handle<String> right)1053 MaybeHandle<String> Factory::NewConsString(Handle<String> left,
1054 Handle<String> right) {
1055 if (left->IsThinString()) {
1056 left = handle(Handle<ThinString>::cast(left)->actual(), isolate());
1057 }
1058 if (right->IsThinString()) {
1059 right = handle(Handle<ThinString>::cast(right)->actual(), isolate());
1060 }
1061 int left_length = left->length();
1062 if (left_length == 0) return right;
1063 int right_length = right->length();
1064 if (right_length == 0) return left;
1065
1066 int length = left_length + right_length;
1067
1068 if (length == 2) {
1069 uint16_t c1 = left->Get(0);
1070 uint16_t c2 = right->Get(0);
1071 return MakeOrFindTwoCharacterString(isolate(), c1, c2);
1072 }
1073
1074 // Make sure that an out of memory exception is thrown if the length
1075 // of the new cons string is too large.
1076 if (length > String::kMaxLength || length < 0) {
1077 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String);
1078 }
1079
1080 bool left_is_one_byte = left->IsOneByteRepresentation();
1081 bool right_is_one_byte = right->IsOneByteRepresentation();
1082 bool is_one_byte = left_is_one_byte && right_is_one_byte;
1083 bool is_one_byte_data_in_two_byte_string = false;
1084 if (!is_one_byte) {
1085 // At least one of the strings uses two-byte representation so we
1086 // can't use the fast case code for short one-byte strings below, but
1087 // we can try to save memory if all chars actually fit in one-byte.
1088 is_one_byte_data_in_two_byte_string =
1089 left->HasOnlyOneByteChars() && right->HasOnlyOneByteChars();
1090 if (is_one_byte_data_in_two_byte_string) {
1091 isolate()->counters()->string_add_runtime_ext_to_one_byte()->Increment();
1092 }
1093 }
1094
1095 // If the resulting string is small make a flat string.
1096 if (length < ConsString::kMinLength) {
1097 // Note that neither of the two inputs can be a slice because:
1098 STATIC_ASSERT(ConsString::kMinLength <= SlicedString::kMinLength);
1099 DCHECK(left->IsFlat());
1100 DCHECK(right->IsFlat());
1101
1102 STATIC_ASSERT(ConsString::kMinLength <= String::kMaxLength);
1103 if (is_one_byte) {
1104 Handle<SeqOneByteString> result =
1105 NewRawOneByteString(length).ToHandleChecked();
1106 DisallowHeapAllocation no_gc;
1107 uint8_t* dest = result->GetChars();
1108 // Copy left part.
1109 const uint8_t* src =
1110 left->IsExternalString()
1111 ? Handle<ExternalOneByteString>::cast(left)->GetChars()
1112 : Handle<SeqOneByteString>::cast(left)->GetChars();
1113 for (int i = 0; i < left_length; i++) *dest++ = src[i];
1114 // Copy right part.
1115 src = right->IsExternalString()
1116 ? Handle<ExternalOneByteString>::cast(right)->GetChars()
1117 : Handle<SeqOneByteString>::cast(right)->GetChars();
1118 for (int i = 0; i < right_length; i++) *dest++ = src[i];
1119 return result;
1120 }
1121
1122 return (is_one_byte_data_in_two_byte_string)
1123 ? ConcatStringContent<uint8_t>(
1124 NewRawOneByteString(length).ToHandleChecked(), left, right)
1125 : ConcatStringContent<uc16>(
1126 NewRawTwoByteString(length).ToHandleChecked(), left,
1127 right);
1128 }
1129
1130 bool one_byte = (is_one_byte || is_one_byte_data_in_two_byte_string);
1131 return NewConsString(left, right, length, one_byte);
1132 }
1133
NewConsString(Handle<String> left,Handle<String> right,int length,bool one_byte)1134 Handle<String> Factory::NewConsString(Handle<String> left, Handle<String> right,
1135 int length, bool one_byte) {
1136 DCHECK(!left->IsThinString());
1137 DCHECK(!right->IsThinString());
1138 DCHECK_GE(length, ConsString::kMinLength);
1139 DCHECK_LE(length, String::kMaxLength);
1140
1141 Handle<ConsString> result(
1142 ConsString::cast(one_byte ? New(cons_one_byte_string_map(), NOT_TENURED)
1143 : New(cons_string_map(), NOT_TENURED)),
1144 isolate());
1145
1146 DisallowHeapAllocation no_gc;
1147 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
1148
1149 result->set_hash_field(String::kEmptyHashField);
1150 result->set_length(length);
1151 result->set_first(isolate(), *left, mode);
1152 result->set_second(isolate(), *right, mode);
1153 return result;
1154 }
1155
NewSurrogatePairString(uint16_t lead,uint16_t trail)1156 Handle<String> Factory::NewSurrogatePairString(uint16_t lead, uint16_t trail) {
1157 DCHECK_GE(lead, 0xD800);
1158 DCHECK_LE(lead, 0xDBFF);
1159 DCHECK_GE(trail, 0xDC00);
1160 DCHECK_LE(trail, 0xDFFF);
1161
1162 Handle<SeqTwoByteString> str =
1163 isolate()->factory()->NewRawTwoByteString(2).ToHandleChecked();
1164 uc16* dest = str->GetChars();
1165 dest[0] = lead;
1166 dest[1] = trail;
1167 return str;
1168 }
1169
NewProperSubString(Handle<String> str,int begin,int end)1170 Handle<String> Factory::NewProperSubString(Handle<String> str, int begin,
1171 int end) {
1172 #if VERIFY_HEAP
1173 if (FLAG_verify_heap) str->StringVerify(isolate());
1174 #endif
1175 DCHECK(begin > 0 || end < str->length());
1176
1177 str = String::Flatten(isolate(), str);
1178
1179 int length = end - begin;
1180 if (length <= 0) return empty_string();
1181 if (length == 1) {
1182 return LookupSingleCharacterStringFromCode(str->Get(begin));
1183 }
1184 if (length == 2) {
1185 // Optimization for 2-byte strings often used as keys in a decompression
1186 // dictionary. Check whether we already have the string in the string
1187 // table to prevent creation of many unnecessary strings.
1188 uint16_t c1 = str->Get(begin);
1189 uint16_t c2 = str->Get(begin + 1);
1190 return MakeOrFindTwoCharacterString(isolate(), c1, c2);
1191 }
1192
1193 if (!FLAG_string_slices || length < SlicedString::kMinLength) {
1194 if (str->IsOneByteRepresentation()) {
1195 Handle<SeqOneByteString> result =
1196 NewRawOneByteString(length).ToHandleChecked();
1197 uint8_t* dest = result->GetChars();
1198 DisallowHeapAllocation no_gc;
1199 String::WriteToFlat(*str, dest, begin, end);
1200 return result;
1201 } else {
1202 Handle<SeqTwoByteString> result =
1203 NewRawTwoByteString(length).ToHandleChecked();
1204 uc16* dest = result->GetChars();
1205 DisallowHeapAllocation no_gc;
1206 String::WriteToFlat(*str, dest, begin, end);
1207 return result;
1208 }
1209 }
1210
1211 int offset = begin;
1212
1213 if (str->IsSlicedString()) {
1214 Handle<SlicedString> slice = Handle<SlicedString>::cast(str);
1215 str = Handle<String>(slice->parent(), isolate());
1216 offset += slice->offset();
1217 }
1218 if (str->IsThinString()) {
1219 Handle<ThinString> thin = Handle<ThinString>::cast(str);
1220 str = handle(thin->actual(), isolate());
1221 }
1222
1223 DCHECK(str->IsSeqString() || str->IsExternalString());
1224 Handle<Map> map = str->IsOneByteRepresentation()
1225 ? sliced_one_byte_string_map()
1226 : sliced_string_map();
1227 Handle<SlicedString> slice(SlicedString::cast(New(map, NOT_TENURED)),
1228 isolate());
1229
1230 slice->set_hash_field(String::kEmptyHashField);
1231 slice->set_length(length);
1232 slice->set_parent(isolate(), *str);
1233 slice->set_offset(offset);
1234 return slice;
1235 }
1236
NewExternalStringFromOneByte(const ExternalOneByteString::Resource * resource)1237 MaybeHandle<String> Factory::NewExternalStringFromOneByte(
1238 const ExternalOneByteString::Resource* resource) {
1239 size_t length = resource->length();
1240 if (length > static_cast<size_t>(String::kMaxLength)) {
1241 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String);
1242 }
1243 if (length == 0) return empty_string();
1244
1245 Handle<Map> map;
1246 if (resource->IsCompressible()) {
1247 // TODO(hajimehoshi): Rename this to 'uncached_external_one_byte_string_map'
1248 map = short_external_one_byte_string_map();
1249 } else {
1250 map = external_one_byte_string_map();
1251 }
1252 Handle<ExternalOneByteString> external_string(
1253 ExternalOneByteString::cast(New(map, TENURED)), isolate());
1254 external_string->set_length(static_cast<int>(length));
1255 external_string->set_hash_field(String::kEmptyHashField);
1256 external_string->SetResource(isolate(), resource);
1257 isolate()->heap()->RegisterExternalString(*external_string);
1258
1259 return external_string;
1260 }
1261
NewExternalStringFromTwoByte(const ExternalTwoByteString::Resource * resource)1262 MaybeHandle<String> Factory::NewExternalStringFromTwoByte(
1263 const ExternalTwoByteString::Resource* resource) {
1264 size_t length = resource->length();
1265 if (length > static_cast<size_t>(String::kMaxLength)) {
1266 THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError(), String);
1267 }
1268 if (length == 0) return empty_string();
1269
1270 // For small strings we check whether the resource contains only
1271 // one byte characters. If yes, we use a different string map.
1272 static const size_t kOneByteCheckLengthLimit = 32;
1273 bool is_one_byte =
1274 length <= kOneByteCheckLengthLimit &&
1275 String::IsOneByte(resource->data(), static_cast<int>(length));
1276 Handle<Map> map;
1277 if (resource->IsCompressible()) {
1278 // TODO(hajimehoshi): Rename these to 'uncached_external_string_...'.
1279 map = is_one_byte ? short_external_string_with_one_byte_data_map()
1280 : short_external_string_map();
1281 } else {
1282 map = is_one_byte ? external_string_with_one_byte_data_map()
1283 : external_string_map();
1284 }
1285 Handle<ExternalTwoByteString> external_string(
1286 ExternalTwoByteString::cast(New(map, TENURED)), isolate());
1287 external_string->set_length(static_cast<int>(length));
1288 external_string->set_hash_field(String::kEmptyHashField);
1289 external_string->SetResource(isolate(), resource);
1290 isolate()->heap()->RegisterExternalString(*external_string);
1291
1292 return external_string;
1293 }
1294
NewNativeSourceString(const ExternalOneByteString::Resource * resource)1295 Handle<ExternalOneByteString> Factory::NewNativeSourceString(
1296 const ExternalOneByteString::Resource* resource) {
1297 size_t length = resource->length();
1298 DCHECK_LE(length, static_cast<size_t>(String::kMaxLength));
1299
1300 Handle<Map> map = native_source_string_map();
1301 Handle<ExternalOneByteString> external_string(
1302 ExternalOneByteString::cast(New(map, TENURED)), isolate());
1303 external_string->set_length(static_cast<int>(length));
1304 external_string->set_hash_field(String::kEmptyHashField);
1305 external_string->SetResource(isolate(), resource);
1306 isolate()->heap()->RegisterExternalString(*external_string);
1307
1308 return external_string;
1309 }
1310
NewJSStringIterator(Handle<String> string)1311 Handle<JSStringIterator> Factory::NewJSStringIterator(Handle<String> string) {
1312 Handle<Map> map(isolate()->native_context()->string_iterator_map(),
1313 isolate());
1314 Handle<String> flat_string = String::Flatten(isolate(), string);
1315 Handle<JSStringIterator> iterator =
1316 Handle<JSStringIterator>::cast(NewJSObjectFromMap(map));
1317 iterator->set_string(*flat_string);
1318 iterator->set_index(0);
1319
1320 return iterator;
1321 }
1322
NewSymbol(PretenureFlag flag)1323 Handle<Symbol> Factory::NewSymbol(PretenureFlag flag) {
1324 DCHECK(flag != NOT_TENURED);
1325 // Statically ensure that it is safe to allocate symbols in paged spaces.
1326 STATIC_ASSERT(Symbol::kSize <= kMaxRegularHeapObjectSize);
1327
1328 HeapObject* result =
1329 AllocateRawWithImmortalMap(Symbol::kSize, flag, *symbol_map());
1330
1331 // Generate a random hash value.
1332 int hash = isolate()->GenerateIdentityHash(Name::kHashBitMask);
1333
1334 Handle<Symbol> symbol(Symbol::cast(result), isolate());
1335 symbol->set_hash_field(Name::kIsNotArrayIndexMask |
1336 (hash << Name::kHashShift));
1337 symbol->set_name(*undefined_value());
1338 symbol->set_flags(0);
1339 DCHECK(!symbol->is_private());
1340 return symbol;
1341 }
1342
NewPrivateSymbol(PretenureFlag flag)1343 Handle<Symbol> Factory::NewPrivateSymbol(PretenureFlag flag) {
1344 DCHECK(flag != NOT_TENURED);
1345 Handle<Symbol> symbol = NewSymbol(flag);
1346 symbol->set_is_private(true);
1347 return symbol;
1348 }
1349
NewPrivateFieldSymbol()1350 Handle<Symbol> Factory::NewPrivateFieldSymbol() {
1351 Handle<Symbol> symbol = NewSymbol();
1352 symbol->set_is_private_field();
1353 return symbol;
1354 }
1355
NewNativeContext()1356 Handle<NativeContext> Factory::NewNativeContext() {
1357 Handle<NativeContext> context = NewFixedArrayWithMap<NativeContext>(
1358 Heap::kNativeContextMapRootIndex, Context::NATIVE_CONTEXT_SLOTS, TENURED);
1359 context->set_native_context(*context);
1360 context->set_errors_thrown(Smi::kZero);
1361 context->set_math_random_index(Smi::kZero);
1362 context->set_serialized_objects(*empty_fixed_array());
1363 return context;
1364 }
1365
NewScriptContext(Handle<NativeContext> outer,Handle<ScopeInfo> scope_info)1366 Handle<Context> Factory::NewScriptContext(Handle<NativeContext> outer,
1367 Handle<ScopeInfo> scope_info) {
1368 DCHECK_EQ(scope_info->scope_type(), SCRIPT_SCOPE);
1369 Handle<Context> context = NewFixedArrayWithMap<Context>(
1370 Heap::kScriptContextMapRootIndex, scope_info->ContextLength(), TENURED);
1371 context->set_scope_info(*scope_info);
1372 context->set_previous(*outer);
1373 context->set_extension(*the_hole_value());
1374 context->set_native_context(*outer);
1375 DCHECK(context->IsScriptContext());
1376 return context;
1377 }
1378
NewScriptContextTable()1379 Handle<ScriptContextTable> Factory::NewScriptContextTable() {
1380 Handle<ScriptContextTable> context_table =
1381 NewFixedArrayWithMap<ScriptContextTable>(
1382 Heap::kScriptContextTableMapRootIndex,
1383 ScriptContextTable::kMinLength);
1384 context_table->set_used(0);
1385 return context_table;
1386 }
1387
NewModuleContext(Handle<Module> module,Handle<NativeContext> outer,Handle<ScopeInfo> scope_info)1388 Handle<Context> Factory::NewModuleContext(Handle<Module> module,
1389 Handle<NativeContext> outer,
1390 Handle<ScopeInfo> scope_info) {
1391 DCHECK_EQ(scope_info->scope_type(), MODULE_SCOPE);
1392 Handle<Context> context = NewFixedArrayWithMap<Context>(
1393 Heap::kModuleContextMapRootIndex, scope_info->ContextLength(), TENURED);
1394 context->set_scope_info(*scope_info);
1395 context->set_previous(*outer);
1396 context->set_extension(*module);
1397 context->set_native_context(*outer);
1398 DCHECK(context->IsModuleContext());
1399 return context;
1400 }
1401
NewFunctionContext(Handle<Context> outer,Handle<ScopeInfo> scope_info)1402 Handle<Context> Factory::NewFunctionContext(Handle<Context> outer,
1403 Handle<ScopeInfo> scope_info) {
1404 int length = scope_info->ContextLength();
1405 DCHECK_LE(Context::MIN_CONTEXT_SLOTS, length);
1406 Heap::RootListIndex mapRootIndex;
1407 switch (scope_info->scope_type()) {
1408 case EVAL_SCOPE:
1409 mapRootIndex = Heap::kEvalContextMapRootIndex;
1410 break;
1411 case FUNCTION_SCOPE:
1412 mapRootIndex = Heap::kFunctionContextMapRootIndex;
1413 break;
1414 default:
1415 UNREACHABLE();
1416 }
1417 Handle<Context> context = NewFixedArrayWithMap<Context>(mapRootIndex, length);
1418 context->set_scope_info(*scope_info);
1419 context->set_previous(*outer);
1420 context->set_extension(*the_hole_value());
1421 context->set_native_context(outer->native_context());
1422 return context;
1423 }
1424
NewCatchContext(Handle<Context> previous,Handle<ScopeInfo> scope_info,Handle<Object> thrown_object)1425 Handle<Context> Factory::NewCatchContext(Handle<Context> previous,
1426 Handle<ScopeInfo> scope_info,
1427 Handle<Object> thrown_object) {
1428 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == Context::THROWN_OBJECT_INDEX);
1429 Handle<Context> context = NewFixedArrayWithMap<Context>(
1430 Heap::kCatchContextMapRootIndex, Context::MIN_CONTEXT_SLOTS + 1);
1431 context->set_scope_info(*scope_info);
1432 context->set_previous(*previous);
1433 context->set_extension(*the_hole_value());
1434 context->set_native_context(previous->native_context());
1435 context->set(Context::THROWN_OBJECT_INDEX, *thrown_object);
1436 return context;
1437 }
1438
NewDebugEvaluateContext(Handle<Context> previous,Handle<ScopeInfo> scope_info,Handle<JSReceiver> extension,Handle<Context> wrapped,Handle<StringSet> whitelist)1439 Handle<Context> Factory::NewDebugEvaluateContext(Handle<Context> previous,
1440 Handle<ScopeInfo> scope_info,
1441 Handle<JSReceiver> extension,
1442 Handle<Context> wrapped,
1443 Handle<StringSet> whitelist) {
1444 STATIC_ASSERT(Context::WHITE_LIST_INDEX == Context::MIN_CONTEXT_SLOTS + 1);
1445 DCHECK(scope_info->IsDebugEvaluateScope());
1446 Handle<HeapObject> ext = extension.is_null()
1447 ? Handle<HeapObject>::cast(the_hole_value())
1448 : Handle<HeapObject>::cast(extension);
1449 Handle<Context> c = NewFixedArrayWithMap<Context>(
1450 Heap::kDebugEvaluateContextMapRootIndex, Context::MIN_CONTEXT_SLOTS + 2);
1451 c->set_scope_info(*scope_info);
1452 c->set_previous(*previous);
1453 c->set_native_context(previous->native_context());
1454 c->set_extension(*ext);
1455 if (!wrapped.is_null()) c->set(Context::WRAPPED_CONTEXT_INDEX, *wrapped);
1456 if (!whitelist.is_null()) c->set(Context::WHITE_LIST_INDEX, *whitelist);
1457 return c;
1458 }
1459
NewWithContext(Handle<Context> previous,Handle<ScopeInfo> scope_info,Handle<JSReceiver> extension)1460 Handle<Context> Factory::NewWithContext(Handle<Context> previous,
1461 Handle<ScopeInfo> scope_info,
1462 Handle<JSReceiver> extension) {
1463 Handle<Context> context = NewFixedArrayWithMap<Context>(
1464 Heap::kWithContextMapRootIndex, Context::MIN_CONTEXT_SLOTS);
1465 context->set_scope_info(*scope_info);
1466 context->set_previous(*previous);
1467 context->set_extension(*extension);
1468 context->set_native_context(previous->native_context());
1469 return context;
1470 }
1471
NewBlockContext(Handle<Context> previous,Handle<ScopeInfo> scope_info)1472 Handle<Context> Factory::NewBlockContext(Handle<Context> previous,
1473 Handle<ScopeInfo> scope_info) {
1474 DCHECK_EQ(scope_info->scope_type(), BLOCK_SCOPE);
1475 Handle<Context> context = NewFixedArrayWithMap<Context>(
1476 Heap::kBlockContextMapRootIndex, scope_info->ContextLength());
1477 context->set_scope_info(*scope_info);
1478 context->set_previous(*previous);
1479 context->set_extension(*the_hole_value());
1480 context->set_native_context(previous->native_context());
1481 return context;
1482 }
1483
NewBuiltinContext(Handle<NativeContext> native_context,int length)1484 Handle<Context> Factory::NewBuiltinContext(Handle<NativeContext> native_context,
1485 int length) {
1486 DCHECK_GE(length, Context::MIN_CONTEXT_SLOTS);
1487 Handle<Context> context =
1488 NewFixedArrayWithMap<Context>(Heap::kFunctionContextMapRootIndex, length);
1489 context->set_scope_info(ReadOnlyRoots(isolate()).empty_scope_info());
1490 context->set_extension(*the_hole_value());
1491 context->set_native_context(*native_context);
1492 return context;
1493 }
1494
NewStruct(InstanceType type,PretenureFlag pretenure)1495 Handle<Struct> Factory::NewStruct(InstanceType type, PretenureFlag pretenure) {
1496 Map* map;
1497 switch (type) {
1498 #define MAKE_CASE(NAME, Name, name) \
1499 case NAME##_TYPE: \
1500 map = *name##_map(); \
1501 break;
1502 STRUCT_LIST(MAKE_CASE)
1503 #undef MAKE_CASE
1504 default:
1505 UNREACHABLE();
1506 }
1507 int size = map->instance_size();
1508 HeapObject* result = AllocateRawWithImmortalMap(size, pretenure, map);
1509 Handle<Struct> str(Struct::cast(result), isolate());
1510 str->InitializeBody(size);
1511 return str;
1512 }
1513
NewAliasedArgumentsEntry(int aliased_context_slot)1514 Handle<AliasedArgumentsEntry> Factory::NewAliasedArgumentsEntry(
1515 int aliased_context_slot) {
1516 Handle<AliasedArgumentsEntry> entry = Handle<AliasedArgumentsEntry>::cast(
1517 NewStruct(ALIASED_ARGUMENTS_ENTRY_TYPE, NOT_TENURED));
1518 entry->set_aliased_context_slot(aliased_context_slot);
1519 return entry;
1520 }
1521
NewAccessorInfo()1522 Handle<AccessorInfo> Factory::NewAccessorInfo() {
1523 Handle<AccessorInfo> info =
1524 Handle<AccessorInfo>::cast(NewStruct(ACCESSOR_INFO_TYPE, TENURED));
1525 info->set_name(*empty_string());
1526 info->set_flags(0); // Must clear the flags, it was initialized as undefined.
1527 info->set_is_sloppy(true);
1528 info->set_initial_property_attributes(NONE);
1529 return info;
1530 }
1531
NewScript(Handle<String> source,PretenureFlag tenure)1532 Handle<Script> Factory::NewScript(Handle<String> source, PretenureFlag tenure) {
1533 return NewScriptWithId(source, isolate()->heap()->NextScriptId(), tenure);
1534 }
1535
NewScriptWithId(Handle<String> source,int script_id,PretenureFlag tenure)1536 Handle<Script> Factory::NewScriptWithId(Handle<String> source, int script_id,
1537 PretenureFlag tenure) {
1538 DCHECK(tenure == TENURED || tenure == TENURED_READ_ONLY);
1539 // Create and initialize script object.
1540 Heap* heap = isolate()->heap();
1541 ReadOnlyRoots roots(heap);
1542 Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE, tenure));
1543 script->set_source(*source);
1544 script->set_name(roots.undefined_value());
1545 script->set_id(script_id);
1546 script->set_line_offset(0);
1547 script->set_column_offset(0);
1548 script->set_context_data(roots.undefined_value());
1549 script->set_type(Script::TYPE_NORMAL);
1550 script->set_line_ends(roots.undefined_value());
1551 script->set_eval_from_shared_or_wrapped_arguments(roots.undefined_value());
1552 script->set_eval_from_position(0);
1553 script->set_shared_function_infos(*empty_weak_fixed_array(),
1554 SKIP_WRITE_BARRIER);
1555 script->set_flags(0);
1556 script->set_host_defined_options(*empty_fixed_array());
1557 Handle<WeakArrayList> scripts = script_list();
1558 scripts = WeakArrayList::AddToEnd(isolate(), scripts,
1559 MaybeObjectHandle::Weak(script));
1560 heap->set_script_list(*scripts);
1561 LOG(isolate(), ScriptEvent(Logger::ScriptEventType::kCreate, script_id));
1562 return script;
1563 }
1564
CloneScript(Handle<Script> script)1565 Handle<Script> Factory::CloneScript(Handle<Script> script) {
1566 Heap* heap = isolate()->heap();
1567 int script_id = isolate()->heap()->NextScriptId();
1568 Handle<Script> new_script =
1569 Handle<Script>::cast(NewStruct(SCRIPT_TYPE, TENURED));
1570 new_script->set_source(script->source());
1571 new_script->set_name(script->name());
1572 new_script->set_id(script_id);
1573 new_script->set_line_offset(script->line_offset());
1574 new_script->set_column_offset(script->column_offset());
1575 new_script->set_context_data(script->context_data());
1576 new_script->set_type(script->type());
1577 new_script->set_line_ends(ReadOnlyRoots(heap).undefined_value());
1578 new_script->set_eval_from_shared_or_wrapped_arguments(
1579 script->eval_from_shared_or_wrapped_arguments());
1580 new_script->set_shared_function_infos(*empty_weak_fixed_array(),
1581 SKIP_WRITE_BARRIER);
1582 new_script->set_eval_from_position(script->eval_from_position());
1583 new_script->set_flags(script->flags());
1584 new_script->set_host_defined_options(script->host_defined_options());
1585 Handle<WeakArrayList> scripts = script_list();
1586 scripts = WeakArrayList::AddToEnd(isolate(), scripts,
1587 MaybeObjectHandle::Weak(new_script));
1588 heap->set_script_list(*scripts);
1589 LOG(isolate(), ScriptEvent(Logger::ScriptEventType::kCreate, script_id));
1590 return new_script;
1591 }
1592
NewCallableTask(Handle<JSReceiver> callable,Handle<Context> context)1593 Handle<CallableTask> Factory::NewCallableTask(Handle<JSReceiver> callable,
1594 Handle<Context> context) {
1595 DCHECK(callable->IsCallable());
1596 Handle<CallableTask> microtask =
1597 Handle<CallableTask>::cast(NewStruct(CALLABLE_TASK_TYPE));
1598 microtask->set_callable(*callable);
1599 microtask->set_context(*context);
1600 return microtask;
1601 }
1602
NewCallbackTask(Handle<Foreign> callback,Handle<Foreign> data)1603 Handle<CallbackTask> Factory::NewCallbackTask(Handle<Foreign> callback,
1604 Handle<Foreign> data) {
1605 Handle<CallbackTask> microtask =
1606 Handle<CallbackTask>::cast(NewStruct(CALLBACK_TASK_TYPE));
1607 microtask->set_callback(*callback);
1608 microtask->set_data(*data);
1609 return microtask;
1610 }
1611
NewPromiseResolveThenableJobTask(Handle<JSPromise> promise_to_resolve,Handle<JSReceiver> then,Handle<JSReceiver> thenable,Handle<Context> context)1612 Handle<PromiseResolveThenableJobTask> Factory::NewPromiseResolveThenableJobTask(
1613 Handle<JSPromise> promise_to_resolve, Handle<JSReceiver> then,
1614 Handle<JSReceiver> thenable, Handle<Context> context) {
1615 DCHECK(then->IsCallable());
1616 Handle<PromiseResolveThenableJobTask> microtask =
1617 Handle<PromiseResolveThenableJobTask>::cast(
1618 NewStruct(PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE));
1619 microtask->set_promise_to_resolve(*promise_to_resolve);
1620 microtask->set_then(*then);
1621 microtask->set_thenable(*thenable);
1622 microtask->set_context(*context);
1623 return microtask;
1624 }
1625
NewForeign(Address addr,PretenureFlag pretenure)1626 Handle<Foreign> Factory::NewForeign(Address addr, PretenureFlag pretenure) {
1627 // Statically ensure that it is safe to allocate foreigns in paged spaces.
1628 STATIC_ASSERT(Foreign::kSize <= kMaxRegularHeapObjectSize);
1629 Map* map = *foreign_map();
1630 HeapObject* result =
1631 AllocateRawWithImmortalMap(map->instance_size(), pretenure, map);
1632 Handle<Foreign> foreign(Foreign::cast(result), isolate());
1633 foreign->set_foreign_address(addr);
1634 return foreign;
1635 }
1636
NewByteArray(int length,PretenureFlag pretenure)1637 Handle<ByteArray> Factory::NewByteArray(int length, PretenureFlag pretenure) {
1638 DCHECK_LE(0, length);
1639 if (length > ByteArray::kMaxLength) {
1640 isolate()->heap()->FatalProcessOutOfMemory("invalid array length");
1641 }
1642 int size = ByteArray::SizeFor(length);
1643 HeapObject* result =
1644 AllocateRawWithImmortalMap(size, pretenure, *byte_array_map());
1645 Handle<ByteArray> array(ByteArray::cast(result), isolate());
1646 array->set_length(length);
1647 array->clear_padding();
1648 return array;
1649 }
1650
NewBytecodeArray(int length,const byte * raw_bytecodes,int frame_size,int parameter_count,Handle<FixedArray> constant_pool)1651 Handle<BytecodeArray> Factory::NewBytecodeArray(
1652 int length, const byte* raw_bytecodes, int frame_size, int parameter_count,
1653 Handle<FixedArray> constant_pool) {
1654 DCHECK_LE(0, length);
1655 if (length > BytecodeArray::kMaxLength) {
1656 isolate()->heap()->FatalProcessOutOfMemory("invalid array length");
1657 }
1658 // Bytecode array is pretenured, so constant pool array should be too.
1659 DCHECK(!Heap::InNewSpace(*constant_pool));
1660
1661 int size = BytecodeArray::SizeFor(length);
1662 HeapObject* result =
1663 AllocateRawWithImmortalMap(size, TENURED, *bytecode_array_map());
1664 Handle<BytecodeArray> instance(BytecodeArray::cast(result), isolate());
1665 instance->set_length(length);
1666 instance->set_frame_size(frame_size);
1667 instance->set_parameter_count(parameter_count);
1668 instance->set_incoming_new_target_or_generator_register(
1669 interpreter::Register::invalid_value());
1670 instance->set_interrupt_budget(interpreter::Interpreter::InterruptBudget());
1671 instance->set_osr_loop_nesting_level(0);
1672 instance->set_bytecode_age(BytecodeArray::kNoAgeBytecodeAge);
1673 instance->set_constant_pool(*constant_pool);
1674 instance->set_handler_table(*empty_byte_array());
1675 instance->set_source_position_table(*empty_byte_array());
1676 CopyBytes(reinterpret_cast<byte*>(instance->GetFirstBytecodeAddress()),
1677 raw_bytecodes, length);
1678 instance->clear_padding();
1679
1680 return instance;
1681 }
1682
NewFixedTypedArrayWithExternalPointer(int length,ExternalArrayType array_type,void * external_pointer,PretenureFlag pretenure)1683 Handle<FixedTypedArrayBase> Factory::NewFixedTypedArrayWithExternalPointer(
1684 int length, ExternalArrayType array_type, void* external_pointer,
1685 PretenureFlag pretenure) {
1686 // TODO(7881): Smi length check
1687 DCHECK(0 <= length && length <= Smi::kMaxValue);
1688 int size = FixedTypedArrayBase::kHeaderSize;
1689 HeapObject* result = AllocateRawWithImmortalMap(
1690 size, pretenure, isolate()->heap()->MapForFixedTypedArray(array_type));
1691 Handle<FixedTypedArrayBase> elements(FixedTypedArrayBase::cast(result),
1692 isolate());
1693 elements->set_base_pointer(Smi::kZero, SKIP_WRITE_BARRIER);
1694 elements->set_external_pointer(external_pointer, SKIP_WRITE_BARRIER);
1695 elements->set_length(length);
1696 return elements;
1697 }
1698
NewFixedTypedArray(size_t length,size_t byte_length,ExternalArrayType array_type,bool initialize,PretenureFlag pretenure)1699 Handle<FixedTypedArrayBase> Factory::NewFixedTypedArray(
1700 size_t length, size_t byte_length, ExternalArrayType array_type,
1701 bool initialize, PretenureFlag pretenure) {
1702 // TODO(7881): Smi length check
1703 DCHECK(0 <= length && length <= Smi::kMaxValue);
1704 CHECK(byte_length <= kMaxInt - FixedTypedArrayBase::kDataOffset);
1705 size_t size =
1706 OBJECT_POINTER_ALIGN(byte_length + FixedTypedArrayBase::kDataOffset);
1707 Map* map = isolate()->heap()->MapForFixedTypedArray(array_type);
1708 AllocationAlignment alignment =
1709 array_type == kExternalFloat64Array ? kDoubleAligned : kWordAligned;
1710 HeapObject* object = AllocateRawWithImmortalMap(static_cast<int>(size),
1711 pretenure, map, alignment);
1712
1713 Handle<FixedTypedArrayBase> elements(FixedTypedArrayBase::cast(object),
1714 isolate());
1715 elements->set_base_pointer(*elements, SKIP_WRITE_BARRIER);
1716 elements->set_external_pointer(
1717 reinterpret_cast<void*>(
1718 ExternalReference::fixed_typed_array_base_data_offset().address()),
1719 SKIP_WRITE_BARRIER);
1720 elements->set_length(static_cast<int>(length));
1721 if (initialize) memset(elements->DataPtr(), 0, elements->DataSize());
1722 return elements;
1723 }
1724
NewCell(Handle<Object> value)1725 Handle<Cell> Factory::NewCell(Handle<Object> value) {
1726 AllowDeferredHandleDereference convert_to_cell;
1727 STATIC_ASSERT(Cell::kSize <= kMaxRegularHeapObjectSize);
1728 HeapObject* result =
1729 AllocateRawWithImmortalMap(Cell::kSize, TENURED, *cell_map());
1730 Handle<Cell> cell(Cell::cast(result), isolate());
1731 cell->set_value(*value);
1732 return cell;
1733 }
1734
NewNoClosuresCell(Handle<HeapObject> value)1735 Handle<FeedbackCell> Factory::NewNoClosuresCell(Handle<HeapObject> value) {
1736 AllowDeferredHandleDereference convert_to_cell;
1737 HeapObject* result = AllocateRawWithImmortalMap(FeedbackCell::kSize, TENURED,
1738 *no_closures_cell_map());
1739 Handle<FeedbackCell> cell(FeedbackCell::cast(result), isolate());
1740 cell->set_value(*value);
1741 return cell;
1742 }
1743
NewOneClosureCell(Handle<HeapObject> value)1744 Handle<FeedbackCell> Factory::NewOneClosureCell(Handle<HeapObject> value) {
1745 AllowDeferredHandleDereference convert_to_cell;
1746 HeapObject* result = AllocateRawWithImmortalMap(FeedbackCell::kSize, TENURED,
1747 *one_closure_cell_map());
1748 Handle<FeedbackCell> cell(FeedbackCell::cast(result), isolate());
1749 cell->set_value(*value);
1750 return cell;
1751 }
1752
NewManyClosuresCell(Handle<HeapObject> value)1753 Handle<FeedbackCell> Factory::NewManyClosuresCell(Handle<HeapObject> value) {
1754 AllowDeferredHandleDereference convert_to_cell;
1755 HeapObject* result = AllocateRawWithImmortalMap(FeedbackCell::kSize, TENURED,
1756 *many_closures_cell_map());
1757 Handle<FeedbackCell> cell(FeedbackCell::cast(result), isolate());
1758 cell->set_value(*value);
1759 return cell;
1760 }
1761
NewPropertyCell(Handle<Name> name,PretenureFlag pretenure)1762 Handle<PropertyCell> Factory::NewPropertyCell(Handle<Name> name,
1763 PretenureFlag pretenure) {
1764 DCHECK(name->IsUniqueName());
1765 STATIC_ASSERT(PropertyCell::kSize <= kMaxRegularHeapObjectSize);
1766 HeapObject* result = AllocateRawWithImmortalMap(
1767 PropertyCell::kSize, pretenure, *global_property_cell_map());
1768 Handle<PropertyCell> cell(PropertyCell::cast(result), isolate());
1769 cell->set_dependent_code(DependentCode::cast(*empty_weak_fixed_array()),
1770 SKIP_WRITE_BARRIER);
1771 cell->set_property_details(PropertyDetails(Smi::kZero));
1772 cell->set_name(*name);
1773 cell->set_value(*the_hole_value());
1774 return cell;
1775 }
1776
NewTransitionArray(int number_of_transitions,int slack)1777 Handle<TransitionArray> Factory::NewTransitionArray(int number_of_transitions,
1778 int slack) {
1779 int capacity = TransitionArray::LengthFor(number_of_transitions + slack);
1780 Handle<TransitionArray> array = NewWeakFixedArrayWithMap<TransitionArray>(
1781 Heap::kTransitionArrayMapRootIndex, capacity, TENURED);
1782 // Transition arrays are tenured. When black allocation is on we have to
1783 // add the transition array to the list of encountered_transition_arrays.
1784 Heap* heap = isolate()->heap();
1785 if (heap->incremental_marking()->black_allocation()) {
1786 heap->mark_compact_collector()->AddTransitionArray(*array);
1787 }
1788 array->WeakFixedArray::Set(TransitionArray::kPrototypeTransitionsIndex,
1789 MaybeObject::FromObject(Smi::kZero));
1790 array->WeakFixedArray::Set(
1791 TransitionArray::kTransitionLengthIndex,
1792 MaybeObject::FromObject(Smi::FromInt(number_of_transitions)));
1793 return array;
1794 }
1795
NewAllocationSite(bool with_weak_next)1796 Handle<AllocationSite> Factory::NewAllocationSite(bool with_weak_next) {
1797 Handle<Map> map = with_weak_next ? allocation_site_map()
1798 : allocation_site_without_weaknext_map();
1799 Handle<AllocationSite> site(AllocationSite::cast(New(map, TENURED)),
1800 isolate());
1801 site->Initialize();
1802
1803 if (with_weak_next) {
1804 // Link the site
1805 site->set_weak_next(isolate()->heap()->allocation_sites_list());
1806 isolate()->heap()->set_allocation_sites_list(*site);
1807 }
1808 return site;
1809 }
1810
NewMap(InstanceType type,int instance_size,ElementsKind elements_kind,int inobject_properties)1811 Handle<Map> Factory::NewMap(InstanceType type, int instance_size,
1812 ElementsKind elements_kind,
1813 int inobject_properties) {
1814 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
1815 DCHECK_IMPLIES(Map::IsJSObject(type) &&
1816 !Map::CanHaveFastTransitionableElementsKind(type),
1817 IsDictionaryElementsKind(elements_kind) ||
1818 IsTerminalElementsKind(elements_kind));
1819 HeapObject* result =
1820 isolate()->heap()->AllocateRawWithRetryOrFail(Map::kSize, MAP_SPACE);
1821 result->set_map_after_allocation(*meta_map(), SKIP_WRITE_BARRIER);
1822 return handle(InitializeMap(Map::cast(result), type, instance_size,
1823 elements_kind, inobject_properties),
1824 isolate());
1825 }
1826
InitializeMap(Map * map,InstanceType type,int instance_size,ElementsKind elements_kind,int inobject_properties)1827 Map* Factory::InitializeMap(Map* map, InstanceType type, int instance_size,
1828 ElementsKind elements_kind,
1829 int inobject_properties) {
1830 map->set_instance_type(type);
1831 map->set_prototype(*null_value(), SKIP_WRITE_BARRIER);
1832 map->set_constructor_or_backpointer(*null_value(), SKIP_WRITE_BARRIER);
1833 map->set_instance_size(instance_size);
1834 if (map->IsJSObjectMap()) {
1835 DCHECK(!isolate()->heap()->InReadOnlySpace(map));
1836 map->SetInObjectPropertiesStartInWords(instance_size / kPointerSize -
1837 inobject_properties);
1838 DCHECK_EQ(map->GetInObjectProperties(), inobject_properties);
1839 map->set_prototype_validity_cell(*invalid_prototype_validity_cell());
1840 } else {
1841 DCHECK_EQ(inobject_properties, 0);
1842 map->set_inobject_properties_start_or_constructor_function_index(0);
1843 map->set_prototype_validity_cell(Smi::FromInt(Map::kPrototypeChainValid));
1844 }
1845 map->set_dependent_code(DependentCode::cast(*empty_weak_fixed_array()),
1846 SKIP_WRITE_BARRIER);
1847 map->set_raw_transitions(MaybeObject::FromSmi(Smi::kZero));
1848 map->SetInObjectUnusedPropertyFields(inobject_properties);
1849 map->set_instance_descriptors(*empty_descriptor_array());
1850 if (FLAG_unbox_double_fields) {
1851 map->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
1852 }
1853 // Must be called only after |instance_type|, |instance_size| and
1854 // |layout_descriptor| are set.
1855 map->set_visitor_id(Map::GetVisitorId(map));
1856 map->set_bit_field(0);
1857 map->set_bit_field2(Map::IsExtensibleBit::kMask);
1858 DCHECK(!map->is_in_retained_map_list());
1859 int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
1860 Map::OwnsDescriptorsBit::encode(true) |
1861 Map::ConstructionCounterBits::encode(Map::kNoSlackTracking);
1862 map->set_bit_field3(bit_field3);
1863 map->set_elements_kind(elements_kind);
1864 map->set_new_target_is_base(true);
1865 isolate()->counters()->maps_created()->Increment();
1866 if (FLAG_trace_maps) LOG(isolate(), MapCreate(map));
1867 return map;
1868 }
1869
CopyJSObject(Handle<JSObject> source)1870 Handle<JSObject> Factory::CopyJSObject(Handle<JSObject> source) {
1871 return CopyJSObjectWithAllocationSite(source, Handle<AllocationSite>());
1872 }
1873
CopyJSObjectWithAllocationSite(Handle<JSObject> source,Handle<AllocationSite> site)1874 Handle<JSObject> Factory::CopyJSObjectWithAllocationSite(
1875 Handle<JSObject> source, Handle<AllocationSite> site) {
1876 Handle<Map> map(source->map(), isolate());
1877
1878 // We can only clone regexps, normal objects, api objects, errors or arrays.
1879 // Copying anything else will break invariants.
1880 CHECK(map->instance_type() == JS_REGEXP_TYPE ||
1881 map->instance_type() == JS_OBJECT_TYPE ||
1882 map->instance_type() == JS_ERROR_TYPE ||
1883 map->instance_type() == JS_ARRAY_TYPE ||
1884 map->instance_type() == JS_API_OBJECT_TYPE ||
1885 map->instance_type() == WASM_GLOBAL_TYPE ||
1886 map->instance_type() == WASM_INSTANCE_TYPE ||
1887 map->instance_type() == WASM_MEMORY_TYPE ||
1888 map->instance_type() == WASM_MODULE_TYPE ||
1889 map->instance_type() == WASM_TABLE_TYPE ||
1890 map->instance_type() == JS_SPECIAL_API_OBJECT_TYPE);
1891 DCHECK(site.is_null() || AllocationSite::CanTrack(map->instance_type()));
1892
1893 int object_size = map->instance_size();
1894 int adjusted_object_size =
1895 site.is_null() ? object_size : object_size + AllocationMemento::kSize;
1896 HeapObject* raw_clone = isolate()->heap()->AllocateRawWithRetryOrFail(
1897 adjusted_object_size, NEW_SPACE);
1898
1899 SLOW_DCHECK(Heap::InNewSpace(raw_clone));
1900 // Since we know the clone is allocated in new space, we can copy
1901 // the contents without worrying about updating the write barrier.
1902 Heap::CopyBlock(raw_clone->address(), source->address(), object_size);
1903 Handle<JSObject> clone(JSObject::cast(raw_clone), isolate());
1904
1905 if (!site.is_null()) {
1906 AllocationMemento* alloc_memento = reinterpret_cast<AllocationMemento*>(
1907 reinterpret_cast<Address>(raw_clone) + object_size);
1908 InitializeAllocationMemento(alloc_memento, *site);
1909 }
1910
1911 SLOW_DCHECK(clone->GetElementsKind() == source->GetElementsKind());
1912 FixedArrayBase* elements = FixedArrayBase::cast(source->elements());
1913 // Update elements if necessary.
1914 if (elements->length() > 0) {
1915 FixedArrayBase* elem = nullptr;
1916 if (elements->map() == *fixed_cow_array_map()) {
1917 elem = elements;
1918 } else if (source->HasDoubleElements()) {
1919 elem = *CopyFixedDoubleArray(
1920 handle(FixedDoubleArray::cast(elements), isolate()));
1921 } else {
1922 elem = *CopyFixedArray(handle(FixedArray::cast(elements), isolate()));
1923 }
1924 clone->set_elements(elem);
1925 }
1926
1927 // Update properties if necessary.
1928 if (source->HasFastProperties()) {
1929 PropertyArray* properties = source->property_array();
1930 if (properties->length() > 0) {
1931 // TODO(gsathya): Do not copy hash code.
1932 Handle<PropertyArray> prop = CopyArrayWithMap(
1933 handle(properties, isolate()), handle(properties->map(), isolate()));
1934 clone->set_raw_properties_or_hash(*prop);
1935 }
1936 } else {
1937 Handle<FixedArray> properties(
1938 FixedArray::cast(source->property_dictionary()), isolate());
1939 Handle<FixedArray> prop = CopyFixedArray(properties);
1940 clone->set_raw_properties_or_hash(*prop);
1941 }
1942 return clone;
1943 }
1944
1945 namespace {
1946 template <typename T>
initialize_length(T * array,int length)1947 void initialize_length(T* array, int length) {
1948 array->set_length(length);
1949 }
1950
1951 template <>
initialize_length(PropertyArray * array,int length)1952 void initialize_length<PropertyArray>(PropertyArray* array, int length) {
1953 array->initialize_length(length);
1954 }
1955
1956 } // namespace
1957
1958 template <typename T>
CopyArrayWithMap(Handle<T> src,Handle<Map> map)1959 Handle<T> Factory::CopyArrayWithMap(Handle<T> src, Handle<Map> map) {
1960 int len = src->length();
1961 HeapObject* obj = AllocateRawFixedArray(len, NOT_TENURED);
1962 obj->set_map_after_allocation(*map, SKIP_WRITE_BARRIER);
1963
1964 T* result = T::cast(obj);
1965 DisallowHeapAllocation no_gc;
1966 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
1967
1968 if (mode == SKIP_WRITE_BARRIER) {
1969 // Eliminate the write barrier if possible.
1970 Heap::CopyBlock(obj->address() + kPointerSize,
1971 src->address() + kPointerSize,
1972 T::SizeFor(len) - kPointerSize);
1973 } else {
1974 // Slow case: Just copy the content one-by-one.
1975 initialize_length(result, len);
1976 for (int i = 0; i < len; i++) result->set(i, src->get(i), mode);
1977 }
1978 return Handle<T>(result, isolate());
1979 }
1980
1981 template <typename T>
CopyArrayAndGrow(Handle<T> src,int grow_by,PretenureFlag pretenure)1982 Handle<T> Factory::CopyArrayAndGrow(Handle<T> src, int grow_by,
1983 PretenureFlag pretenure) {
1984 DCHECK_LT(0, grow_by);
1985 DCHECK_LE(grow_by, kMaxInt - src->length());
1986 int old_len = src->length();
1987 int new_len = old_len + grow_by;
1988 HeapObject* obj = AllocateRawFixedArray(new_len, pretenure);
1989 obj->set_map_after_allocation(src->map(), SKIP_WRITE_BARRIER);
1990
1991 T* result = T::cast(obj);
1992 initialize_length(result, new_len);
1993
1994 // Copy the content.
1995 DisallowHeapAllocation no_gc;
1996 WriteBarrierMode mode = obj->GetWriteBarrierMode(no_gc);
1997 for (int i = 0; i < old_len; i++) result->set(i, src->get(i), mode);
1998 MemsetPointer(result->data_start() + old_len, *undefined_value(), grow_by);
1999 return Handle<T>(result, isolate());
2000 }
2001
CopyFixedArrayWithMap(Handle<FixedArray> array,Handle<Map> map)2002 Handle<FixedArray> Factory::CopyFixedArrayWithMap(Handle<FixedArray> array,
2003 Handle<Map> map) {
2004 return CopyArrayWithMap(array, map);
2005 }
2006
CopyFixedArrayAndGrow(Handle<FixedArray> array,int grow_by,PretenureFlag pretenure)2007 Handle<FixedArray> Factory::CopyFixedArrayAndGrow(Handle<FixedArray> array,
2008 int grow_by,
2009 PretenureFlag pretenure) {
2010 return CopyArrayAndGrow(array, grow_by, pretenure);
2011 }
2012
CopyWeakFixedArrayAndGrow(Handle<WeakFixedArray> src,int grow_by,PretenureFlag pretenure)2013 Handle<WeakFixedArray> Factory::CopyWeakFixedArrayAndGrow(
2014 Handle<WeakFixedArray> src, int grow_by, PretenureFlag pretenure) {
2015 DCHECK(
2016 !src->IsTransitionArray()); // Compacted by GC, this code doesn't work.
2017 int old_len = src->length();
2018 int new_len = old_len + grow_by;
2019 DCHECK_GE(new_len, old_len);
2020 HeapObject* obj = AllocateRawFixedArray(new_len, pretenure);
2021 DCHECK_EQ(old_len, src->length());
2022 obj->set_map_after_allocation(src->map(), SKIP_WRITE_BARRIER);
2023
2024 WeakFixedArray* result = WeakFixedArray::cast(obj);
2025 result->set_length(new_len);
2026
2027 // Copy the content.
2028 DisallowHeapAllocation no_gc;
2029 WriteBarrierMode mode = obj->GetWriteBarrierMode(no_gc);
2030 for (int i = 0; i < old_len; i++) result->Set(i, src->Get(i), mode);
2031 HeapObjectReference* undefined_reference =
2032 HeapObjectReference::Strong(ReadOnlyRoots(isolate()).undefined_value());
2033 MemsetPointer(result->data_start() + old_len, undefined_reference, grow_by);
2034 return Handle<WeakFixedArray>(result, isolate());
2035 }
2036
CopyWeakArrayListAndGrow(Handle<WeakArrayList> src,int grow_by,PretenureFlag pretenure)2037 Handle<WeakArrayList> Factory::CopyWeakArrayListAndGrow(
2038 Handle<WeakArrayList> src, int grow_by, PretenureFlag pretenure) {
2039 int old_capacity = src->capacity();
2040 int new_capacity = old_capacity + grow_by;
2041 DCHECK_GE(new_capacity, old_capacity);
2042 HeapObject* obj = AllocateRawWeakArrayList(new_capacity, pretenure);
2043 obj->set_map_after_allocation(src->map(), SKIP_WRITE_BARRIER);
2044
2045 WeakArrayList* result = WeakArrayList::cast(obj);
2046 result->set_length(src->length());
2047 result->set_capacity(new_capacity);
2048
2049 // Copy the content.
2050 DisallowHeapAllocation no_gc;
2051 WriteBarrierMode mode = obj->GetWriteBarrierMode(no_gc);
2052 for (int i = 0; i < old_capacity; i++) result->Set(i, src->Get(i), mode);
2053 HeapObjectReference* undefined_reference =
2054 HeapObjectReference::Strong(ReadOnlyRoots(isolate()).undefined_value());
2055 MemsetPointer(result->data_start() + old_capacity, undefined_reference,
2056 grow_by);
2057 return Handle<WeakArrayList>(result, isolate());
2058 }
2059
CopyPropertyArrayAndGrow(Handle<PropertyArray> array,int grow_by,PretenureFlag pretenure)2060 Handle<PropertyArray> Factory::CopyPropertyArrayAndGrow(
2061 Handle<PropertyArray> array, int grow_by, PretenureFlag pretenure) {
2062 return CopyArrayAndGrow(array, grow_by, pretenure);
2063 }
2064
CopyFixedArrayUpTo(Handle<FixedArray> array,int new_len,PretenureFlag pretenure)2065 Handle<FixedArray> Factory::CopyFixedArrayUpTo(Handle<FixedArray> array,
2066 int new_len,
2067 PretenureFlag pretenure) {
2068 DCHECK_LE(0, new_len);
2069 DCHECK_LE(new_len, array->length());
2070 if (new_len == 0) return empty_fixed_array();
2071
2072 HeapObject* obj = AllocateRawFixedArray(new_len, pretenure);
2073 obj->set_map_after_allocation(*fixed_array_map(), SKIP_WRITE_BARRIER);
2074 Handle<FixedArray> result(FixedArray::cast(obj), isolate());
2075 result->set_length(new_len);
2076
2077 // Copy the content.
2078 DisallowHeapAllocation no_gc;
2079 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
2080 for (int i = 0; i < new_len; i++) result->set(i, array->get(i), mode);
2081 return result;
2082 }
2083
CopyFixedArray(Handle<FixedArray> array)2084 Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) {
2085 if (array->length() == 0) return array;
2086 return CopyArrayWithMap(array, handle(array->map(), isolate()));
2087 }
2088
CopyAndTenureFixedCOWArray(Handle<FixedArray> array)2089 Handle<FixedArray> Factory::CopyAndTenureFixedCOWArray(
2090 Handle<FixedArray> array) {
2091 DCHECK(Heap::InNewSpace(*array));
2092 Handle<FixedArray> result =
2093 CopyFixedArrayUpTo(array, array->length(), TENURED);
2094
2095 // TODO(mvstanton): The map is set twice because of protection against calling
2096 // set() on a COW FixedArray. Issue v8:3221 created to track this, and
2097 // we might then be able to remove this whole method.
2098 result->set_map_after_allocation(*fixed_cow_array_map(), SKIP_WRITE_BARRIER);
2099 return result;
2100 }
2101
CopyFixedDoubleArray(Handle<FixedDoubleArray> array)2102 Handle<FixedDoubleArray> Factory::CopyFixedDoubleArray(
2103 Handle<FixedDoubleArray> array) {
2104 int len = array->length();
2105 if (len == 0) return array;
2106 Handle<FixedDoubleArray> result =
2107 Handle<FixedDoubleArray>::cast(NewFixedDoubleArray(len, NOT_TENURED));
2108 Heap::CopyBlock(
2109 result->address() + FixedDoubleArray::kLengthOffset,
2110 array->address() + FixedDoubleArray::kLengthOffset,
2111 FixedDoubleArray::SizeFor(len) - FixedDoubleArray::kLengthOffset);
2112 return result;
2113 }
2114
CopyFeedbackVector(Handle<FeedbackVector> array)2115 Handle<FeedbackVector> Factory::CopyFeedbackVector(
2116 Handle<FeedbackVector> array) {
2117 int len = array->length();
2118 HeapObject* obj = AllocateRawWithImmortalMap(
2119 FeedbackVector::SizeFor(len), NOT_TENURED, *feedback_vector_map());
2120 Handle<FeedbackVector> result(FeedbackVector::cast(obj), isolate());
2121
2122 DisallowHeapAllocation no_gc;
2123 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
2124
2125 // Eliminate the write barrier if possible.
2126 if (mode == SKIP_WRITE_BARRIER) {
2127 Heap::CopyBlock(result->address() + kPointerSize,
2128 result->address() + kPointerSize,
2129 FeedbackVector::SizeFor(len) - kPointerSize);
2130 } else {
2131 // Slow case: Just copy the content one-by-one.
2132 result->set_shared_function_info(array->shared_function_info());
2133 result->set_optimized_code_weak_or_smi(array->optimized_code_weak_or_smi());
2134 result->set_invocation_count(array->invocation_count());
2135 result->set_profiler_ticks(array->profiler_ticks());
2136 result->set_deopt_count(array->deopt_count());
2137 for (int i = 0; i < len; i++) result->set(i, array->get(i), mode);
2138 }
2139 return result;
2140 }
2141
NewNumber(double value,PretenureFlag pretenure)2142 Handle<Object> Factory::NewNumber(double value, PretenureFlag pretenure) {
2143 // Materialize as a SMI if possible.
2144 int32_t int_value;
2145 if (DoubleToSmiInteger(value, &int_value)) {
2146 return handle(Smi::FromInt(int_value), isolate());
2147 }
2148 return NewHeapNumber(value, pretenure);
2149 }
2150
NewNumberFromInt(int32_t value,PretenureFlag pretenure)2151 Handle<Object> Factory::NewNumberFromInt(int32_t value,
2152 PretenureFlag pretenure) {
2153 if (Smi::IsValid(value)) return handle(Smi::FromInt(value), isolate());
2154 // Bypass NewNumber to avoid various redundant checks.
2155 return NewHeapNumber(FastI2D(value), pretenure);
2156 }
2157
NewNumberFromUint(uint32_t value,PretenureFlag pretenure)2158 Handle<Object> Factory::NewNumberFromUint(uint32_t value,
2159 PretenureFlag pretenure) {
2160 int32_t int32v = static_cast<int32_t>(value);
2161 if (int32v >= 0 && Smi::IsValid(int32v)) {
2162 return handle(Smi::FromInt(int32v), isolate());
2163 }
2164 return NewHeapNumber(FastUI2D(value), pretenure);
2165 }
2166
NewHeapNumber(PretenureFlag pretenure)2167 Handle<HeapNumber> Factory::NewHeapNumber(PretenureFlag pretenure) {
2168 STATIC_ASSERT(HeapNumber::kSize <= kMaxRegularHeapObjectSize);
2169 Map* map = *heap_number_map();
2170 HeapObject* result = AllocateRawWithImmortalMap(HeapNumber::kSize, pretenure,
2171 map, kDoubleUnaligned);
2172 return handle(HeapNumber::cast(result), isolate());
2173 }
2174
NewMutableHeapNumber(PretenureFlag pretenure)2175 Handle<MutableHeapNumber> Factory::NewMutableHeapNumber(
2176 PretenureFlag pretenure) {
2177 STATIC_ASSERT(HeapNumber::kSize <= kMaxRegularHeapObjectSize);
2178 Map* map = *mutable_heap_number_map();
2179 HeapObject* result = AllocateRawWithImmortalMap(
2180 MutableHeapNumber::kSize, pretenure, map, kDoubleUnaligned);
2181 return handle(MutableHeapNumber::cast(result), isolate());
2182 }
2183
NewBigInt(int length,PretenureFlag pretenure)2184 Handle<FreshlyAllocatedBigInt> Factory::NewBigInt(int length,
2185 PretenureFlag pretenure) {
2186 if (length < 0 || length > BigInt::kMaxLength) {
2187 isolate()->heap()->FatalProcessOutOfMemory("invalid BigInt length");
2188 }
2189 HeapObject* result = AllocateRawWithImmortalMap(BigInt::SizeFor(length),
2190 pretenure, *bigint_map());
2191 return handle(FreshlyAllocatedBigInt::cast(result), isolate());
2192 }
2193
NewError(Handle<JSFunction> constructor,MessageTemplate::Template template_index,Handle<Object> arg0,Handle<Object> arg1,Handle<Object> arg2)2194 Handle<Object> Factory::NewError(Handle<JSFunction> constructor,
2195 MessageTemplate::Template template_index,
2196 Handle<Object> arg0, Handle<Object> arg1,
2197 Handle<Object> arg2) {
2198 HandleScope scope(isolate());
2199 if (isolate()->bootstrapper()->IsActive()) {
2200 // During bootstrapping we cannot construct error objects.
2201 return scope.CloseAndEscape(NewStringFromAsciiChecked(
2202 MessageTemplate::TemplateString(template_index)));
2203 }
2204
2205 if (arg0.is_null()) arg0 = undefined_value();
2206 if (arg1.is_null()) arg1 = undefined_value();
2207 if (arg2.is_null()) arg2 = undefined_value();
2208
2209 Handle<Object> result;
2210 if (!ErrorUtils::MakeGenericError(isolate(), constructor, template_index,
2211 arg0, arg1, arg2, SKIP_NONE)
2212 .ToHandle(&result)) {
2213 // If an exception is thrown while
2214 // running the factory method, use the exception as the result.
2215 DCHECK(isolate()->has_pending_exception());
2216 result = handle(isolate()->pending_exception(), isolate());
2217 isolate()->clear_pending_exception();
2218 }
2219
2220 return scope.CloseAndEscape(result);
2221 }
2222
NewError(Handle<JSFunction> constructor,Handle<String> message)2223 Handle<Object> Factory::NewError(Handle<JSFunction> constructor,
2224 Handle<String> message) {
2225 // Construct a new error object. If an exception is thrown, use the exception
2226 // as the result.
2227
2228 Handle<Object> no_caller;
2229 MaybeHandle<Object> maybe_error =
2230 ErrorUtils::Construct(isolate(), constructor, constructor, message,
2231 SKIP_NONE, no_caller, false);
2232 if (maybe_error.is_null()) {
2233 DCHECK(isolate()->has_pending_exception());
2234 maybe_error = handle(isolate()->pending_exception(), isolate());
2235 isolate()->clear_pending_exception();
2236 }
2237
2238 return maybe_error.ToHandleChecked();
2239 }
2240
NewInvalidStringLengthError()2241 Handle<Object> Factory::NewInvalidStringLengthError() {
2242 if (FLAG_abort_on_stack_or_string_length_overflow) {
2243 FATAL("Aborting on invalid string length");
2244 }
2245 // Invalidate the "string length" protector.
2246 if (isolate()->IsStringLengthOverflowIntact()) {
2247 isolate()->InvalidateStringLengthOverflowProtector();
2248 }
2249 return NewRangeError(MessageTemplate::kInvalidStringLength);
2250 }
2251
2252 #define DEFINE_ERROR(NAME, name) \
2253 Handle<Object> Factory::New##NAME(MessageTemplate::Template template_index, \
2254 Handle<Object> arg0, Handle<Object> arg1, \
2255 Handle<Object> arg2) { \
2256 return NewError(isolate()->name##_function(), template_index, arg0, arg1, \
2257 arg2); \
2258 }
DEFINE_ERROR(Error,error)2259 DEFINE_ERROR(Error, error)
2260 DEFINE_ERROR(EvalError, eval_error)
2261 DEFINE_ERROR(RangeError, range_error)
2262 DEFINE_ERROR(ReferenceError, reference_error)
2263 DEFINE_ERROR(SyntaxError, syntax_error)
2264 DEFINE_ERROR(TypeError, type_error)
2265 DEFINE_ERROR(WasmCompileError, wasm_compile_error)
2266 DEFINE_ERROR(WasmLinkError, wasm_link_error)
2267 DEFINE_ERROR(WasmRuntimeError, wasm_runtime_error)
2268 #undef DEFINE_ERROR
2269
2270 Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
2271 Handle<SharedFunctionInfo> info,
2272 Handle<Context> context,
2273 PretenureFlag pretenure) {
2274 Handle<JSFunction> function(JSFunction::cast(New(map, pretenure)), isolate());
2275
2276 function->initialize_properties();
2277 function->initialize_elements();
2278 function->set_shared(*info);
2279 function->set_code(info->GetCode());
2280 function->set_context(*context);
2281 function->set_feedback_cell(*many_closures_cell());
2282 int header_size;
2283 if (map->has_prototype_slot()) {
2284 header_size = JSFunction::kSizeWithPrototype;
2285 function->set_prototype_or_initial_map(*the_hole_value());
2286 } else {
2287 header_size = JSFunction::kSizeWithoutPrototype;
2288 }
2289 InitializeJSObjectBody(function, map, header_size);
2290 return function;
2291 }
2292
NewFunctionForTest(Handle<String> name)2293 Handle<JSFunction> Factory::NewFunctionForTest(Handle<String> name) {
2294 NewFunctionArgs args = NewFunctionArgs::ForFunctionWithoutCode(
2295 name, isolate()->sloppy_function_map(), LanguageMode::kSloppy);
2296 Handle<JSFunction> result = NewFunction(args);
2297 DCHECK(is_sloppy(result->shared()->language_mode()));
2298 return result;
2299 }
2300
NewFunction(const NewFunctionArgs & args)2301 Handle<JSFunction> Factory::NewFunction(const NewFunctionArgs& args) {
2302 DCHECK(!args.name_.is_null());
2303
2304 // Create the SharedFunctionInfo.
2305 Handle<NativeContext> context(isolate()->native_context());
2306 Handle<Map> map = args.GetMap(isolate());
2307 Handle<SharedFunctionInfo> info =
2308 NewSharedFunctionInfo(args.name_, args.maybe_exported_function_data_,
2309 args.maybe_builtin_id_, kNormalFunction);
2310
2311 // Proper language mode in shared function info will be set later.
2312 DCHECK(is_sloppy(info->language_mode()));
2313 DCHECK(!map->IsUndefined(isolate()));
2314
2315 #ifdef DEBUG
2316 if (isolate()->bootstrapper()->IsActive()) {
2317 Handle<Code> code;
2318 DCHECK(
2319 // During bootstrapping some of these maps could be not created yet.
2320 (*map == context->get(Context::STRICT_FUNCTION_MAP_INDEX)) ||
2321 (*map ==
2322 context->get(Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX)) ||
2323 (*map ==
2324 context->get(
2325 Context::STRICT_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX)) ||
2326 // Check if it's a creation of an empty or Proxy function during
2327 // bootstrapping.
2328 (args.maybe_builtin_id_ == Builtins::kEmptyFunction ||
2329 args.maybe_builtin_id_ == Builtins::kProxyConstructor));
2330 } else {
2331 DCHECK(
2332 (*map == *isolate()->sloppy_function_map()) ||
2333 (*map == *isolate()->sloppy_function_without_prototype_map()) ||
2334 (*map == *isolate()->sloppy_function_with_readonly_prototype_map()) ||
2335 (*map == *isolate()->strict_function_map()) ||
2336 (*map == *isolate()->strict_function_without_prototype_map()) ||
2337 (*map == *isolate()->native_function_map()));
2338 }
2339 #endif
2340
2341 Handle<JSFunction> result = NewFunction(map, info, context);
2342
2343 if (args.should_set_prototype_) {
2344 result->set_prototype_or_initial_map(
2345 *args.maybe_prototype_.ToHandleChecked());
2346 }
2347
2348 if (args.should_set_language_mode_) {
2349 result->shared()->set_language_mode(args.language_mode_);
2350 }
2351
2352 if (args.should_create_and_set_initial_map_) {
2353 ElementsKind elements_kind;
2354 switch (args.type_) {
2355 case JS_ARRAY_TYPE:
2356 elements_kind = PACKED_SMI_ELEMENTS;
2357 break;
2358 case JS_ARGUMENTS_TYPE:
2359 elements_kind = PACKED_ELEMENTS;
2360 break;
2361 default:
2362 elements_kind = TERMINAL_FAST_ELEMENTS_KIND;
2363 break;
2364 }
2365 Handle<Map> initial_map = NewMap(args.type_, args.instance_size_,
2366 elements_kind, args.inobject_properties_);
2367 result->shared()->set_expected_nof_properties(args.inobject_properties_);
2368 // TODO(littledan): Why do we have this is_generator test when
2369 // NewFunctionPrototype already handles finding an appropriately
2370 // shared prototype?
2371 Handle<Object> prototype = args.maybe_prototype_.ToHandleChecked();
2372 if (!IsResumableFunction(result->shared()->kind())) {
2373 if (prototype->IsTheHole(isolate())) {
2374 prototype = NewFunctionPrototype(result);
2375 }
2376 }
2377 JSFunction::SetInitialMap(result, initial_map, prototype);
2378 }
2379
2380 return result;
2381 }
2382
NewFunctionPrototype(Handle<JSFunction> function)2383 Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
2384 // Make sure to use globals from the function's context, since the function
2385 // can be from a different context.
2386 Handle<NativeContext> native_context(function->context()->native_context(),
2387 isolate());
2388 Handle<Map> new_map;
2389 if (V8_UNLIKELY(IsAsyncGeneratorFunction(function->shared()->kind()))) {
2390 new_map = handle(native_context->async_generator_object_prototype_map(),
2391 isolate());
2392 } else if (IsResumableFunction(function->shared()->kind())) {
2393 // Generator and async function prototypes can share maps since they
2394 // don't have "constructor" properties.
2395 new_map =
2396 handle(native_context->generator_object_prototype_map(), isolate());
2397 } else {
2398 // Each function prototype gets a fresh map to avoid unwanted sharing of
2399 // maps between prototypes of different constructors.
2400 Handle<JSFunction> object_function(native_context->object_function(),
2401 isolate());
2402 DCHECK(object_function->has_initial_map());
2403 new_map = handle(object_function->initial_map(), isolate());
2404 }
2405
2406 DCHECK(!new_map->is_prototype_map());
2407 Handle<JSObject> prototype = NewJSObjectFromMap(new_map);
2408
2409 if (!IsResumableFunction(function->shared()->kind())) {
2410 JSObject::AddProperty(isolate(), prototype, constructor_string(), function,
2411 DONT_ENUM);
2412 }
2413
2414 return prototype;
2415 }
2416
NewFunctionFromSharedFunctionInfo(Handle<SharedFunctionInfo> info,Handle<Context> context,PretenureFlag pretenure)2417 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
2418 Handle<SharedFunctionInfo> info, Handle<Context> context,
2419 PretenureFlag pretenure) {
2420 Handle<Map> initial_map(
2421 Map::cast(context->native_context()->get(info->function_map_index())),
2422 isolate());
2423 return NewFunctionFromSharedFunctionInfo(initial_map, info, context,
2424 pretenure);
2425 }
2426
NewFunctionFromSharedFunctionInfo(Handle<SharedFunctionInfo> info,Handle<Context> context,Handle<FeedbackCell> feedback_cell,PretenureFlag pretenure)2427 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
2428 Handle<SharedFunctionInfo> info, Handle<Context> context,
2429 Handle<FeedbackCell> feedback_cell, PretenureFlag pretenure) {
2430 Handle<Map> initial_map(
2431 Map::cast(context->native_context()->get(info->function_map_index())),
2432 isolate());
2433 return NewFunctionFromSharedFunctionInfo(initial_map, info, context,
2434 feedback_cell, pretenure);
2435 }
2436
NewFunctionFromSharedFunctionInfo(Handle<Map> initial_map,Handle<SharedFunctionInfo> info,Handle<Context> context,PretenureFlag pretenure)2437 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
2438 Handle<Map> initial_map, Handle<SharedFunctionInfo> info,
2439 Handle<Context> context, PretenureFlag pretenure) {
2440 DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type());
2441 Handle<JSFunction> result =
2442 NewFunction(initial_map, info, context, pretenure);
2443
2444 // Give compiler a chance to pre-initialize.
2445 Compiler::PostInstantiation(result, pretenure);
2446
2447 return result;
2448 }
2449
NewFunctionFromSharedFunctionInfo(Handle<Map> initial_map,Handle<SharedFunctionInfo> info,Handle<Context> context,Handle<FeedbackCell> feedback_cell,PretenureFlag pretenure)2450 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
2451 Handle<Map> initial_map, Handle<SharedFunctionInfo> info,
2452 Handle<Context> context, Handle<FeedbackCell> feedback_cell,
2453 PretenureFlag pretenure) {
2454 DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type());
2455 Handle<JSFunction> result =
2456 NewFunction(initial_map, info, context, pretenure);
2457
2458 // Bump the closure count that is encoded in the feedback cell's map.
2459 if (feedback_cell->map() == *no_closures_cell_map()) {
2460 feedback_cell->set_map(*one_closure_cell_map());
2461 } else if (feedback_cell->map() == *one_closure_cell_map()) {
2462 feedback_cell->set_map(*many_closures_cell_map());
2463 } else {
2464 DCHECK_EQ(feedback_cell->map(), *many_closures_cell_map());
2465 }
2466
2467 // Check that the optimized code in the feedback cell wasn't marked for
2468 // deoptimization while not pointed to by any live JSFunction.
2469 if (feedback_cell->value()->IsFeedbackVector()) {
2470 FeedbackVector::cast(feedback_cell->value())
2471 ->EvictOptimizedCodeMarkedForDeoptimization(
2472 *info, "new function from shared function info");
2473 }
2474 result->set_feedback_cell(*feedback_cell);
2475
2476 // Give compiler a chance to pre-initialize.
2477 Compiler::PostInstantiation(result, pretenure);
2478
2479 return result;
2480 }
2481
NewScopeInfo(int length)2482 Handle<ScopeInfo> Factory::NewScopeInfo(int length) {
2483 return NewFixedArrayWithMap<ScopeInfo>(Heap::kScopeInfoMapRootIndex, length,
2484 TENURED);
2485 }
2486
NewModuleInfo()2487 Handle<ModuleInfo> Factory::NewModuleInfo() {
2488 return NewFixedArrayWithMap<ModuleInfo>(Heap::kModuleInfoMapRootIndex,
2489 ModuleInfo::kLength, TENURED);
2490 }
2491
NewPreParsedScopeData(int length)2492 Handle<PreParsedScopeData> Factory::NewPreParsedScopeData(int length) {
2493 int size = PreParsedScopeData::SizeFor(length);
2494 Handle<PreParsedScopeData> result(
2495 PreParsedScopeData::cast(AllocateRawWithImmortalMap(
2496 size, TENURED, *pre_parsed_scope_data_map())),
2497 isolate());
2498 result->set_scope_data(PodArray<uint8_t>::cast(*empty_byte_array()));
2499 result->set_length(length);
2500 MemsetPointer(result->child_data_start(), *null_value(), length);
2501
2502 result->clear_padding();
2503 return result;
2504 }
2505
2506 Handle<UncompiledDataWithoutPreParsedScope>
NewUncompiledDataWithoutPreParsedScope(Handle<String> inferred_name,int32_t start_position,int32_t end_position,int32_t function_literal_id)2507 Factory::NewUncompiledDataWithoutPreParsedScope(Handle<String> inferred_name,
2508 int32_t start_position,
2509 int32_t end_position,
2510 int32_t function_literal_id) {
2511 Handle<UncompiledDataWithoutPreParsedScope> result(
2512 UncompiledDataWithoutPreParsedScope::cast(
2513 New(uncompiled_data_without_pre_parsed_scope_map(), TENURED)),
2514 isolate());
2515 result->set_inferred_name(*inferred_name);
2516 result->set_start_position(start_position);
2517 result->set_end_position(end_position);
2518 result->set_function_literal_id(function_literal_id);
2519
2520 result->clear_padding();
2521 return result;
2522 }
2523
2524 Handle<UncompiledDataWithPreParsedScope>
NewUncompiledDataWithPreParsedScope(Handle<String> inferred_name,int32_t start_position,int32_t end_position,int32_t function_literal_id,Handle<PreParsedScopeData> pre_parsed_scope_data)2525 Factory::NewUncompiledDataWithPreParsedScope(
2526 Handle<String> inferred_name, int32_t start_position, int32_t end_position,
2527 int32_t function_literal_id,
2528 Handle<PreParsedScopeData> pre_parsed_scope_data) {
2529 Handle<UncompiledDataWithPreParsedScope> result(
2530 UncompiledDataWithPreParsedScope::cast(
2531 New(uncompiled_data_with_pre_parsed_scope_map(), TENURED)),
2532 isolate());
2533 result->set_inferred_name(*inferred_name);
2534 result->set_start_position(start_position);
2535 result->set_end_position(end_position);
2536 result->set_function_literal_id(function_literal_id);
2537 result->set_pre_parsed_scope_data(*pre_parsed_scope_data);
2538
2539 result->clear_padding();
2540 return result;
2541 }
2542
NewExternal(void * value)2543 Handle<JSObject> Factory::NewExternal(void* value) {
2544 Handle<Foreign> foreign = NewForeign(reinterpret_cast<Address>(value));
2545 Handle<JSObject> external = NewJSObjectFromMap(external_map());
2546 external->SetEmbedderField(0, *foreign);
2547 return external;
2548 }
2549
NewCodeDataContainer(int flags)2550 Handle<CodeDataContainer> Factory::NewCodeDataContainer(int flags) {
2551 Handle<CodeDataContainer> data_container(
2552 CodeDataContainer::cast(New(code_data_container_map(), TENURED)),
2553 isolate());
2554 data_container->set_next_code_link(*undefined_value(), SKIP_WRITE_BARRIER);
2555 data_container->set_kind_specific_flags(flags);
2556 data_container->clear_padding();
2557 return data_container;
2558 }
2559
TryNewCode(const CodeDesc & desc,Code::Kind kind,Handle<Object> self_ref,int32_t builtin_index,MaybeHandle<ByteArray> maybe_source_position_table,MaybeHandle<DeoptimizationData> maybe_deopt_data,Movability movability,uint32_t stub_key,bool is_turbofanned,int stack_slots,int safepoint_table_offset,int handler_table_offset)2560 MaybeHandle<Code> Factory::TryNewCode(
2561 const CodeDesc& desc, Code::Kind kind, Handle<Object> self_ref,
2562 int32_t builtin_index, MaybeHandle<ByteArray> maybe_source_position_table,
2563 MaybeHandle<DeoptimizationData> maybe_deopt_data, Movability movability,
2564 uint32_t stub_key, bool is_turbofanned, int stack_slots,
2565 int safepoint_table_offset, int handler_table_offset) {
2566 // Allocate objects needed for code initialization.
2567 Handle<ByteArray> reloc_info = NewByteArray(desc.reloc_size, TENURED);
2568 Handle<CodeDataContainer> data_container = NewCodeDataContainer(0);
2569 Handle<ByteArray> source_position_table =
2570 maybe_source_position_table.is_null()
2571 ? empty_byte_array()
2572 : maybe_source_position_table.ToHandleChecked();
2573 Handle<DeoptimizationData> deopt_data =
2574 maybe_deopt_data.is_null() ? DeoptimizationData::Empty(isolate())
2575 : maybe_deopt_data.ToHandleChecked();
2576 Handle<Code> code;
2577 {
2578 int object_size = ComputeCodeObjectSize(desc);
2579
2580 Heap* heap = isolate()->heap();
2581 CodePageCollectionMemoryModificationScope code_allocation(heap);
2582 HeapObject* result =
2583 heap->AllocateRawWithLightRetry(object_size, CODE_SPACE);
2584
2585 // Return an empty handle if we cannot allocate the code object.
2586 if (!result) return MaybeHandle<Code>();
2587
2588 if (movability == kImmovable) {
2589 result = heap->EnsureImmovableCode(result, object_size);
2590 }
2591
2592 // The code object has not been fully initialized yet. We rely on the
2593 // fact that no allocation will happen from this point on.
2594 DisallowHeapAllocation no_gc;
2595
2596 result->set_map_after_allocation(*code_map(), SKIP_WRITE_BARRIER);
2597 code = handle(Code::cast(result), isolate());
2598
2599 InitializeCode(heap, code, object_size, desc, kind, self_ref, builtin_index,
2600 source_position_table, deopt_data, reloc_info,
2601 data_container, stub_key, is_turbofanned, stack_slots,
2602 safepoint_table_offset, handler_table_offset);
2603 }
2604 // Flush the instruction cache after changing the permissions.
2605 code->FlushICache();
2606
2607 return code;
2608 }
2609
NewCode(const CodeDesc & desc,Code::Kind kind,Handle<Object> self_ref,int32_t builtin_index,MaybeHandle<ByteArray> maybe_source_position_table,MaybeHandle<DeoptimizationData> maybe_deopt_data,Movability movability,uint32_t stub_key,bool is_turbofanned,int stack_slots,int safepoint_table_offset,int handler_table_offset)2610 Handle<Code> Factory::NewCode(
2611 const CodeDesc& desc, Code::Kind kind, Handle<Object> self_ref,
2612 int32_t builtin_index, MaybeHandle<ByteArray> maybe_source_position_table,
2613 MaybeHandle<DeoptimizationData> maybe_deopt_data, Movability movability,
2614 uint32_t stub_key, bool is_turbofanned, int stack_slots,
2615 int safepoint_table_offset, int handler_table_offset) {
2616 // Allocate objects needed for code initialization.
2617 Handle<ByteArray> reloc_info = NewByteArray(desc.reloc_size, TENURED);
2618 Handle<CodeDataContainer> data_container = NewCodeDataContainer(0);
2619 Handle<ByteArray> source_position_table =
2620 maybe_source_position_table.is_null()
2621 ? empty_byte_array()
2622 : maybe_source_position_table.ToHandleChecked();
2623 Handle<DeoptimizationData> deopt_data =
2624 maybe_deopt_data.is_null() ? DeoptimizationData::Empty(isolate())
2625 : maybe_deopt_data.ToHandleChecked();
2626
2627 Handle<Code> code;
2628 {
2629 int object_size = ComputeCodeObjectSize(desc);
2630
2631 Heap* heap = isolate()->heap();
2632 CodePageCollectionMemoryModificationScope code_allocation(heap);
2633 HeapObject* result =
2634 heap->AllocateRawWithRetryOrFail(object_size, CODE_SPACE);
2635
2636 if (movability == kImmovable) {
2637 result = heap->EnsureImmovableCode(result, object_size);
2638 }
2639
2640 // The code object has not been fully initialized yet. We rely on the
2641 // fact that no allocation will happen from this point on.
2642 DisallowHeapAllocation no_gc;
2643
2644 result->set_map_after_allocation(*code_map(), SKIP_WRITE_BARRIER);
2645 code = handle(Code::cast(result), isolate());
2646
2647 InitializeCode(heap, code, object_size, desc, kind, self_ref, builtin_index,
2648 source_position_table, deopt_data, reloc_info,
2649 data_container, stub_key, is_turbofanned, stack_slots,
2650 safepoint_table_offset, handler_table_offset);
2651 }
2652 // Flush the instruction cache after changing the permissions.
2653 code->FlushICache();
2654
2655 return code;
2656 }
2657
NewCodeForDeserialization(uint32_t size)2658 Handle<Code> Factory::NewCodeForDeserialization(uint32_t size) {
2659 DCHECK(IsAligned(static_cast<intptr_t>(size), kCodeAlignment));
2660 Heap* heap = isolate()->heap();
2661 HeapObject* result = heap->AllocateRawWithRetryOrFail(size, CODE_SPACE);
2662 // Unprotect the memory chunk of the object if it was not unprotected
2663 // already.
2664 heap->UnprotectAndRegisterMemoryChunk(result);
2665 heap->ZapCodeObject(result->address(), size);
2666 result->set_map_after_allocation(*code_map(), SKIP_WRITE_BARRIER);
2667 DCHECK(IsAligned(result->address(), kCodeAlignment));
2668 DCHECK(!heap->memory_allocator()->code_range()->valid() ||
2669 heap->memory_allocator()->code_range()->contains(result->address()) ||
2670 static_cast<int>(size) <= heap->code_space()->AreaSize());
2671 return handle(Code::cast(result), isolate());
2672 }
2673
NewOffHeapTrampolineFor(Handle<Code> code,Address off_heap_entry)2674 Handle<Code> Factory::NewOffHeapTrampolineFor(Handle<Code> code,
2675 Address off_heap_entry) {
2676 CHECK(isolate()->serializer_enabled());
2677 CHECK_NOT_NULL(isolate()->embedded_blob());
2678 CHECK_NE(0, isolate()->embedded_blob_size());
2679 CHECK(Builtins::IsIsolateIndependentBuiltin(*code));
2680
2681 Handle<Code> result =
2682 Builtins::GenerateOffHeapTrampolineFor(isolate(), off_heap_entry);
2683
2684 // The trampoline code object must inherit specific flags from the original
2685 // builtin (e.g. the safepoint-table offset). We set them manually here.
2686
2687 const bool set_is_off_heap_trampoline = true;
2688 const int stack_slots = code->has_safepoint_info() ? code->stack_slots() : 0;
2689 result->initialize_flags(code->kind(), code->has_unwinding_info(),
2690 code->is_turbofanned(), stack_slots,
2691 set_is_off_heap_trampoline);
2692 result->set_builtin_index(code->builtin_index());
2693 result->set_handler_table_offset(code->handler_table_offset());
2694 result->code_data_container()->set_kind_specific_flags(
2695 code->code_data_container()->kind_specific_flags());
2696 result->set_constant_pool_offset(code->constant_pool_offset());
2697 if (code->has_safepoint_info()) {
2698 result->set_safepoint_table_offset(code->safepoint_table_offset());
2699 }
2700
2701 return result;
2702 }
2703
CopyCode(Handle<Code> code)2704 Handle<Code> Factory::CopyCode(Handle<Code> code) {
2705 Handle<CodeDataContainer> data_container =
2706 NewCodeDataContainer(code->code_data_container()->kind_specific_flags());
2707
2708 Heap* heap = isolate()->heap();
2709 int obj_size = code->Size();
2710 HeapObject* result = heap->AllocateRawWithRetryOrFail(obj_size, CODE_SPACE);
2711
2712 // Copy code object.
2713 Address old_addr = code->address();
2714 Address new_addr = result->address();
2715 Heap::CopyBlock(new_addr, old_addr, obj_size);
2716 Handle<Code> new_code(Code::cast(result), isolate());
2717
2718 // Set the {CodeDataContainer}, it cannot be shared.
2719 new_code->set_code_data_container(*data_container);
2720
2721 new_code->Relocate(new_addr - old_addr);
2722 // We have to iterate over the object and process its pointers when black
2723 // allocation is on.
2724 heap->incremental_marking()->ProcessBlackAllocatedObject(*new_code);
2725 // Record all references to embedded objects in the new code object.
2726 WriteBarrierForCode(*new_code);
2727
2728 #ifdef VERIFY_HEAP
2729 if (FLAG_verify_heap) new_code->ObjectVerify(isolate());
2730 #endif
2731 DCHECK(IsAligned(new_code->address(), kCodeAlignment));
2732 DCHECK(
2733 !heap->memory_allocator()->code_range()->valid() ||
2734 heap->memory_allocator()->code_range()->contains(new_code->address()) ||
2735 obj_size <= heap->code_space()->AreaSize());
2736 return new_code;
2737 }
2738
CopyBytecodeArray(Handle<BytecodeArray> bytecode_array)2739 Handle<BytecodeArray> Factory::CopyBytecodeArray(
2740 Handle<BytecodeArray> bytecode_array) {
2741 int size = BytecodeArray::SizeFor(bytecode_array->length());
2742 HeapObject* result =
2743 AllocateRawWithImmortalMap(size, TENURED, *bytecode_array_map());
2744
2745 Handle<BytecodeArray> copy(BytecodeArray::cast(result), isolate());
2746 copy->set_length(bytecode_array->length());
2747 copy->set_frame_size(bytecode_array->frame_size());
2748 copy->set_parameter_count(bytecode_array->parameter_count());
2749 copy->set_incoming_new_target_or_generator_register(
2750 bytecode_array->incoming_new_target_or_generator_register());
2751 copy->set_constant_pool(bytecode_array->constant_pool());
2752 copy->set_handler_table(bytecode_array->handler_table());
2753 copy->set_source_position_table(bytecode_array->source_position_table());
2754 copy->set_interrupt_budget(bytecode_array->interrupt_budget());
2755 copy->set_osr_loop_nesting_level(bytecode_array->osr_loop_nesting_level());
2756 copy->set_bytecode_age(bytecode_array->bytecode_age());
2757 bytecode_array->CopyBytecodesTo(*copy);
2758 return copy;
2759 }
2760
NewJSObject(Handle<JSFunction> constructor,PretenureFlag pretenure)2761 Handle<JSObject> Factory::NewJSObject(Handle<JSFunction> constructor,
2762 PretenureFlag pretenure) {
2763 JSFunction::EnsureHasInitialMap(constructor);
2764 Handle<Map> map(constructor->initial_map(), isolate());
2765 return NewJSObjectFromMap(map, pretenure);
2766 }
2767
NewJSObjectWithNullProto(PretenureFlag pretenure)2768 Handle<JSObject> Factory::NewJSObjectWithNullProto(PretenureFlag pretenure) {
2769 Handle<JSObject> result =
2770 NewJSObject(isolate()->object_function(), pretenure);
2771 Handle<Map> new_map = Map::Copy(
2772 isolate(), Handle<Map>(result->map(), isolate()), "ObjectWithNullProto");
2773 Map::SetPrototype(isolate(), new_map, null_value());
2774 JSObject::MigrateToMap(result, new_map);
2775 return result;
2776 }
2777
NewJSGlobalObject(Handle<JSFunction> constructor)2778 Handle<JSGlobalObject> Factory::NewJSGlobalObject(
2779 Handle<JSFunction> constructor) {
2780 DCHECK(constructor->has_initial_map());
2781 Handle<Map> map(constructor->initial_map(), isolate());
2782 DCHECK(map->is_dictionary_map());
2783
2784 // Make sure no field properties are described in the initial map.
2785 // This guarantees us that normalizing the properties does not
2786 // require us to change property values to PropertyCells.
2787 DCHECK_EQ(map->NextFreePropertyIndex(), 0);
2788
2789 // Make sure we don't have a ton of pre-allocated slots in the
2790 // global objects. They will be unused once we normalize the object.
2791 DCHECK_EQ(map->UnusedPropertyFields(), 0);
2792 DCHECK_EQ(map->GetInObjectProperties(), 0);
2793
2794 // Initial size of the backing store to avoid resize of the storage during
2795 // bootstrapping. The size differs between the JS global object ad the
2796 // builtins object.
2797 int initial_size = 64;
2798
2799 // Allocate a dictionary object for backing storage.
2800 int at_least_space_for = map->NumberOfOwnDescriptors() * 2 + initial_size;
2801 Handle<GlobalDictionary> dictionary =
2802 GlobalDictionary::New(isolate(), at_least_space_for);
2803
2804 // The global object might be created from an object template with accessors.
2805 // Fill these accessors into the dictionary.
2806 Handle<DescriptorArray> descs(map->instance_descriptors(), isolate());
2807 for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
2808 PropertyDetails details = descs->GetDetails(i);
2809 // Only accessors are expected.
2810 DCHECK_EQ(kAccessor, details.kind());
2811 PropertyDetails d(kAccessor, details.attributes(),
2812 PropertyCellType::kMutable);
2813 Handle<Name> name(descs->GetKey(i), isolate());
2814 Handle<PropertyCell> cell = NewPropertyCell(name);
2815 cell->set_value(descs->GetStrongValue(i));
2816 // |dictionary| already contains enough space for all properties.
2817 USE(GlobalDictionary::Add(isolate(), dictionary, name, cell, d));
2818 }
2819
2820 // Allocate the global object and initialize it with the backing store.
2821 Handle<JSGlobalObject> global(JSGlobalObject::cast(New(map, TENURED)),
2822 isolate());
2823 InitializeJSObjectFromMap(global, dictionary, map);
2824
2825 // Create a new map for the global object.
2826 Handle<Map> new_map = Map::CopyDropDescriptors(isolate(), map);
2827 new_map->set_may_have_interesting_symbols(true);
2828 new_map->set_is_dictionary_map(true);
2829
2830 // Set up the global object as a normalized object.
2831 global->set_global_dictionary(*dictionary);
2832 global->synchronized_set_map(*new_map);
2833
2834 // Make sure result is a global object with properties in dictionary.
2835 DCHECK(global->IsJSGlobalObject() && !global->HasFastProperties());
2836 return global;
2837 }
2838
InitializeJSObjectFromMap(Handle<JSObject> obj,Handle<Object> properties,Handle<Map> map)2839 void Factory::InitializeJSObjectFromMap(Handle<JSObject> obj,
2840 Handle<Object> properties,
2841 Handle<Map> map) {
2842 obj->set_raw_properties_or_hash(*properties);
2843 obj->initialize_elements();
2844 // TODO(1240798): Initialize the object's body using valid initial values
2845 // according to the object's initial map. For example, if the map's
2846 // instance type is JS_ARRAY_TYPE, the length field should be initialized
2847 // to a number (e.g. Smi::kZero) and the elements initialized to a
2848 // fixed array (e.g. Heap::empty_fixed_array()). Currently, the object
2849 // verification code has to cope with (temporarily) invalid objects. See
2850 // for example, JSArray::JSArrayVerify).
2851 InitializeJSObjectBody(obj, map, JSObject::kHeaderSize);
2852 }
2853
InitializeJSObjectBody(Handle<JSObject> obj,Handle<Map> map,int start_offset)2854 void Factory::InitializeJSObjectBody(Handle<JSObject> obj, Handle<Map> map,
2855 int start_offset) {
2856 if (start_offset == map->instance_size()) return;
2857 DCHECK_LT(start_offset, map->instance_size());
2858
2859 // We cannot always fill with one_pointer_filler_map because objects
2860 // created from API functions expect their embedder fields to be initialized
2861 // with undefined_value.
2862 // Pre-allocated fields need to be initialized with undefined_value as well
2863 // so that object accesses before the constructor completes (e.g. in the
2864 // debugger) will not cause a crash.
2865
2866 // In case of Array subclassing the |map| could already be transitioned
2867 // to different elements kind from the initial map on which we track slack.
2868 bool in_progress = map->IsInobjectSlackTrackingInProgress();
2869 Object* filler;
2870 if (in_progress) {
2871 filler = *one_pointer_filler_map();
2872 } else {
2873 filler = *undefined_value();
2874 }
2875 obj->InitializeBody(*map, start_offset, *undefined_value(), filler);
2876 if (in_progress) {
2877 map->FindRootMap(isolate())->InobjectSlackTrackingStep(isolate());
2878 }
2879 }
2880
NewJSObjectFromMap(Handle<Map> map,PretenureFlag pretenure,Handle<AllocationSite> allocation_site)2881 Handle<JSObject> Factory::NewJSObjectFromMap(
2882 Handle<Map> map, PretenureFlag pretenure,
2883 Handle<AllocationSite> allocation_site) {
2884 // JSFunctions should be allocated using AllocateFunction to be
2885 // properly initialized.
2886 DCHECK(map->instance_type() != JS_FUNCTION_TYPE);
2887
2888 // Both types of global objects should be allocated using
2889 // AllocateGlobalObject to be properly initialized.
2890 DCHECK(map->instance_type() != JS_GLOBAL_OBJECT_TYPE);
2891
2892 HeapObject* obj =
2893 AllocateRawWithAllocationSite(map, pretenure, allocation_site);
2894 Handle<JSObject> js_obj(JSObject::cast(obj), isolate());
2895
2896 InitializeJSObjectFromMap(js_obj, empty_fixed_array(), map);
2897
2898 DCHECK(js_obj->HasFastElements() || js_obj->HasFixedTypedArrayElements() ||
2899 js_obj->HasFastStringWrapperElements() ||
2900 js_obj->HasFastArgumentsElements());
2901 return js_obj;
2902 }
2903
NewSlowJSObjectFromMap(Handle<Map> map,int capacity,PretenureFlag pretenure)2904 Handle<JSObject> Factory::NewSlowJSObjectFromMap(Handle<Map> map, int capacity,
2905 PretenureFlag pretenure) {
2906 DCHECK(map->is_dictionary_map());
2907 Handle<NameDictionary> object_properties =
2908 NameDictionary::New(isolate(), capacity);
2909 Handle<JSObject> js_object = NewJSObjectFromMap(map, pretenure);
2910 js_object->set_raw_properties_or_hash(*object_properties);
2911 return js_object;
2912 }
2913
NewJSArray(ElementsKind elements_kind,PretenureFlag pretenure)2914 Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind,
2915 PretenureFlag pretenure) {
2916 NativeContext* native_context = isolate()->raw_native_context();
2917 Map* map = native_context->GetInitialJSArrayMap(elements_kind);
2918 if (map == nullptr) {
2919 JSFunction* array_function = native_context->array_function();
2920 map = array_function->initial_map();
2921 }
2922 return Handle<JSArray>::cast(
2923 NewJSObjectFromMap(handle(map, isolate()), pretenure));
2924 }
2925
NewJSArray(ElementsKind elements_kind,int length,int capacity,ArrayStorageAllocationMode mode,PretenureFlag pretenure)2926 Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind, int length,
2927 int capacity,
2928 ArrayStorageAllocationMode mode,
2929 PretenureFlag pretenure) {
2930 Handle<JSArray> array = NewJSArray(elements_kind, pretenure);
2931 NewJSArrayStorage(array, length, capacity, mode);
2932 return array;
2933 }
2934
NewJSArrayWithElements(Handle<FixedArrayBase> elements,ElementsKind elements_kind,int length,PretenureFlag pretenure)2935 Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements,
2936 ElementsKind elements_kind,
2937 int length,
2938 PretenureFlag pretenure) {
2939 DCHECK(length <= elements->length());
2940 Handle<JSArray> array = NewJSArray(elements_kind, pretenure);
2941
2942 array->set_elements(*elements);
2943 array->set_length(Smi::FromInt(length));
2944 JSObject::ValidateElements(*array);
2945 return array;
2946 }
2947
NewJSArrayStorage(Handle<JSArray> array,int length,int capacity,ArrayStorageAllocationMode mode)2948 void Factory::NewJSArrayStorage(Handle<JSArray> array, int length, int capacity,
2949 ArrayStorageAllocationMode mode) {
2950 DCHECK(capacity >= length);
2951
2952 if (capacity == 0) {
2953 array->set_length(Smi::kZero);
2954 array->set_elements(*empty_fixed_array());
2955 return;
2956 }
2957
2958 HandleScope inner_scope(isolate());
2959 Handle<FixedArrayBase> elms;
2960 ElementsKind elements_kind = array->GetElementsKind();
2961 if (IsDoubleElementsKind(elements_kind)) {
2962 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
2963 elms = NewFixedDoubleArray(capacity);
2964 } else {
2965 DCHECK(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
2966 elms = NewFixedDoubleArrayWithHoles(capacity);
2967 }
2968 } else {
2969 DCHECK(IsSmiOrObjectElementsKind(elements_kind));
2970 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
2971 elms = NewUninitializedFixedArray(capacity);
2972 } else {
2973 DCHECK(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
2974 elms = NewFixedArrayWithHoles(capacity);
2975 }
2976 }
2977
2978 array->set_elements(*elms);
2979 array->set_length(Smi::FromInt(length));
2980 }
2981
NewJSWeakMap()2982 Handle<JSWeakMap> Factory::NewJSWeakMap() {
2983 NativeContext* native_context = isolate()->raw_native_context();
2984 Handle<Map> map(native_context->js_weak_map_fun()->initial_map(), isolate());
2985 Handle<JSWeakMap> weakmap(JSWeakMap::cast(*NewJSObjectFromMap(map)),
2986 isolate());
2987 {
2988 // Do not leak handles for the hash table, it would make entries strong.
2989 HandleScope scope(isolate());
2990 JSWeakCollection::Initialize(weakmap, isolate());
2991 }
2992 return weakmap;
2993 }
2994
NewJSModuleNamespace()2995 Handle<JSModuleNamespace> Factory::NewJSModuleNamespace() {
2996 Handle<Map> map = isolate()->js_module_namespace_map();
2997 Handle<JSModuleNamespace> module_namespace(
2998 Handle<JSModuleNamespace>::cast(NewJSObjectFromMap(map)));
2999 FieldIndex index = FieldIndex::ForDescriptor(
3000 *map, JSModuleNamespace::kToStringTagFieldIndex);
3001 module_namespace->FastPropertyAtPut(index,
3002 ReadOnlyRoots(isolate()).Module_string());
3003 return module_namespace;
3004 }
3005
NewJSGeneratorObject(Handle<JSFunction> function)3006 Handle<JSGeneratorObject> Factory::NewJSGeneratorObject(
3007 Handle<JSFunction> function) {
3008 DCHECK(IsResumableFunction(function->shared()->kind()));
3009 JSFunction::EnsureHasInitialMap(function);
3010 Handle<Map> map(function->initial_map(), isolate());
3011
3012 DCHECK(map->instance_type() == JS_GENERATOR_OBJECT_TYPE ||
3013 map->instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE);
3014
3015 return Handle<JSGeneratorObject>::cast(NewJSObjectFromMap(map));
3016 }
3017
NewModule(Handle<SharedFunctionInfo> code)3018 Handle<Module> Factory::NewModule(Handle<SharedFunctionInfo> code) {
3019 Handle<ModuleInfo> module_info(code->scope_info()->ModuleDescriptorInfo(),
3020 isolate());
3021 Handle<ObjectHashTable> exports =
3022 ObjectHashTable::New(isolate(), module_info->RegularExportCount());
3023 Handle<FixedArray> regular_exports =
3024 NewFixedArray(module_info->RegularExportCount());
3025 Handle<FixedArray> regular_imports =
3026 NewFixedArray(module_info->regular_imports()->length());
3027 int requested_modules_length = module_info->module_requests()->length();
3028 Handle<FixedArray> requested_modules =
3029 requested_modules_length > 0 ? NewFixedArray(requested_modules_length)
3030 : empty_fixed_array();
3031
3032 ReadOnlyRoots roots(isolate());
3033 Handle<Module> module = Handle<Module>::cast(NewStruct(MODULE_TYPE, TENURED));
3034 module->set_code(*code);
3035 module->set_exports(*exports);
3036 module->set_regular_exports(*regular_exports);
3037 module->set_regular_imports(*regular_imports);
3038 module->set_hash(isolate()->GenerateIdentityHash(Smi::kMaxValue));
3039 module->set_module_namespace(roots.undefined_value());
3040 module->set_requested_modules(*requested_modules);
3041 module->set_script(Script::cast(code->script()));
3042 module->set_status(Module::kUninstantiated);
3043 module->set_exception(roots.the_hole_value());
3044 module->set_import_meta(roots.the_hole_value());
3045 module->set_dfs_index(-1);
3046 module->set_dfs_ancestor_index(-1);
3047 return module;
3048 }
3049
NewJSArrayBuffer(SharedFlag shared,PretenureFlag pretenure)3050 Handle<JSArrayBuffer> Factory::NewJSArrayBuffer(SharedFlag shared,
3051 PretenureFlag pretenure) {
3052 Handle<JSFunction> array_buffer_fun(
3053 shared == SharedFlag::kShared
3054 ? isolate()->native_context()->shared_array_buffer_fun()
3055 : isolate()->native_context()->array_buffer_fun(),
3056 isolate());
3057 Handle<Map> map(array_buffer_fun->initial_map(), isolate());
3058 return Handle<JSArrayBuffer>::cast(NewJSObjectFromMap(map, pretenure));
3059 }
3060
NewJSIteratorResult(Handle<Object> value,bool done)3061 Handle<JSIteratorResult> Factory::NewJSIteratorResult(Handle<Object> value,
3062 bool done) {
3063 Handle<Map> map(isolate()->native_context()->iterator_result_map(),
3064 isolate());
3065 Handle<JSIteratorResult> js_iter_result =
3066 Handle<JSIteratorResult>::cast(NewJSObjectFromMap(map));
3067 js_iter_result->set_value(*value);
3068 js_iter_result->set_done(*ToBoolean(done));
3069 return js_iter_result;
3070 }
3071
NewJSAsyncFromSyncIterator(Handle<JSReceiver> sync_iterator,Handle<Object> next)3072 Handle<JSAsyncFromSyncIterator> Factory::NewJSAsyncFromSyncIterator(
3073 Handle<JSReceiver> sync_iterator, Handle<Object> next) {
3074 Handle<Map> map(isolate()->native_context()->async_from_sync_iterator_map(),
3075 isolate());
3076 Handle<JSAsyncFromSyncIterator> iterator =
3077 Handle<JSAsyncFromSyncIterator>::cast(NewJSObjectFromMap(map));
3078
3079 iterator->set_sync_iterator(*sync_iterator);
3080 iterator->set_next(*next);
3081 return iterator;
3082 }
3083
NewJSMap()3084 Handle<JSMap> Factory::NewJSMap() {
3085 Handle<Map> map(isolate()->native_context()->js_map_map(), isolate());
3086 Handle<JSMap> js_map = Handle<JSMap>::cast(NewJSObjectFromMap(map));
3087 JSMap::Initialize(js_map, isolate());
3088 return js_map;
3089 }
3090
NewJSSet()3091 Handle<JSSet> Factory::NewJSSet() {
3092 Handle<Map> map(isolate()->native_context()->js_set_map(), isolate());
3093 Handle<JSSet> js_set = Handle<JSSet>::cast(NewJSObjectFromMap(map));
3094 JSSet::Initialize(js_set, isolate());
3095 return js_set;
3096 }
3097
NewJSMapIterator(Handle<Map> map,Handle<OrderedHashMap> table,int index)3098 Handle<JSMapIterator> Factory::NewJSMapIterator(Handle<Map> map,
3099 Handle<OrderedHashMap> table,
3100 int index) {
3101 Handle<JSMapIterator> result =
3102 Handle<JSMapIterator>::cast(NewJSObjectFromMap(map));
3103 result->set_table(*table);
3104 result->set_index(Smi::FromInt(index));
3105 return result;
3106 }
3107
NewJSSetIterator(Handle<Map> map,Handle<OrderedHashSet> table,int index)3108 Handle<JSSetIterator> Factory::NewJSSetIterator(Handle<Map> map,
3109 Handle<OrderedHashSet> table,
3110 int index) {
3111 Handle<JSSetIterator> result =
3112 Handle<JSSetIterator>::cast(NewJSObjectFromMap(map));
3113 result->set_table(*table);
3114 result->set_index(Smi::FromInt(index));
3115 return result;
3116 }
3117
TypeAndSizeForElementsKind(ElementsKind kind,ExternalArrayType * array_type,size_t * element_size)3118 void Factory::TypeAndSizeForElementsKind(ElementsKind kind,
3119 ExternalArrayType* array_type,
3120 size_t* element_size) {
3121 switch (kind) {
3122 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
3123 case TYPE##_ELEMENTS: \
3124 *array_type = kExternal##Type##Array; \
3125 *element_size = sizeof(ctype); \
3126 break;
3127 TYPED_ARRAYS(TYPED_ARRAY_CASE)
3128 #undef TYPED_ARRAY_CASE
3129
3130 default:
3131 UNREACHABLE();
3132 }
3133 }
3134
3135 namespace {
3136
ForFixedTypedArray(ExternalArrayType array_type,size_t * element_size,ElementsKind * element_kind)3137 static void ForFixedTypedArray(ExternalArrayType array_type,
3138 size_t* element_size,
3139 ElementsKind* element_kind) {
3140 switch (array_type) {
3141 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
3142 case kExternal##Type##Array: \
3143 *element_size = sizeof(ctype); \
3144 *element_kind = TYPE##_ELEMENTS; \
3145 return;
3146
3147 TYPED_ARRAYS(TYPED_ARRAY_CASE)
3148 #undef TYPED_ARRAY_CASE
3149 }
3150 UNREACHABLE();
3151 }
3152
GetTypedArrayFun(ExternalArrayType type,Isolate * isolate)3153 JSFunction* GetTypedArrayFun(ExternalArrayType type, Isolate* isolate) {
3154 NativeContext* native_context = isolate->context()->native_context();
3155 switch (type) {
3156 #define TYPED_ARRAY_FUN(Type, type, TYPE, ctype) \
3157 case kExternal##Type##Array: \
3158 return native_context->type##_array_fun();
3159
3160 TYPED_ARRAYS(TYPED_ARRAY_FUN)
3161 #undef TYPED_ARRAY_FUN
3162 }
3163 UNREACHABLE();
3164 }
3165
GetTypedArrayFun(ElementsKind elements_kind,Isolate * isolate)3166 JSFunction* GetTypedArrayFun(ElementsKind elements_kind, Isolate* isolate) {
3167 NativeContext* native_context = isolate->context()->native_context();
3168 switch (elements_kind) {
3169 #define TYPED_ARRAY_FUN(Type, type, TYPE, ctype) \
3170 case TYPE##_ELEMENTS: \
3171 return native_context->type##_array_fun();
3172
3173 TYPED_ARRAYS(TYPED_ARRAY_FUN)
3174 #undef TYPED_ARRAY_FUN
3175
3176 default:
3177 UNREACHABLE();
3178 }
3179 }
3180
SetupArrayBufferView(i::Isolate * isolate,i::Handle<i::JSArrayBufferView> obj,i::Handle<i::JSArrayBuffer> buffer,size_t byte_offset,size_t byte_length,PretenureFlag pretenure=NOT_TENURED)3181 void SetupArrayBufferView(i::Isolate* isolate,
3182 i::Handle<i::JSArrayBufferView> obj,
3183 i::Handle<i::JSArrayBuffer> buffer,
3184 size_t byte_offset, size_t byte_length,
3185 PretenureFlag pretenure = NOT_TENURED) {
3186 DCHECK(byte_offset + byte_length <=
3187 static_cast<size_t>(buffer->byte_length()->Number()));
3188
3189 DCHECK_EQ(obj->GetEmbedderFieldCount(),
3190 v8::ArrayBufferView::kEmbedderFieldCount);
3191 for (int i = 0; i < v8::ArrayBufferView::kEmbedderFieldCount; i++) {
3192 obj->SetEmbedderField(i, Smi::kZero);
3193 }
3194
3195 obj->set_buffer(*buffer);
3196
3197 i::Handle<i::Object> byte_offset_object =
3198 isolate->factory()->NewNumberFromSize(byte_offset, pretenure);
3199 obj->set_byte_offset(*byte_offset_object);
3200
3201 i::Handle<i::Object> byte_length_object =
3202 isolate->factory()->NewNumberFromSize(byte_length, pretenure);
3203 obj->set_byte_length(*byte_length_object);
3204 }
3205
3206 } // namespace
3207
NewJSTypedArray(ExternalArrayType type,PretenureFlag pretenure)3208 Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type,
3209 PretenureFlag pretenure) {
3210 Handle<JSFunction> typed_array_fun(GetTypedArrayFun(type, isolate()),
3211 isolate());
3212 Handle<Map> map(typed_array_fun->initial_map(), isolate());
3213 return Handle<JSTypedArray>::cast(NewJSObjectFromMap(map, pretenure));
3214 }
3215
NewJSTypedArray(ElementsKind elements_kind,PretenureFlag pretenure)3216 Handle<JSTypedArray> Factory::NewJSTypedArray(ElementsKind elements_kind,
3217 PretenureFlag pretenure) {
3218 Handle<JSFunction> typed_array_fun(GetTypedArrayFun(elements_kind, isolate()),
3219 isolate());
3220 Handle<Map> map(typed_array_fun->initial_map(), isolate());
3221 return Handle<JSTypedArray>::cast(NewJSObjectFromMap(map, pretenure));
3222 }
3223
NewJSTypedArray(ExternalArrayType type,Handle<JSArrayBuffer> buffer,size_t byte_offset,size_t length,PretenureFlag pretenure)3224 Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type,
3225 Handle<JSArrayBuffer> buffer,
3226 size_t byte_offset, size_t length,
3227 PretenureFlag pretenure) {
3228 Handle<JSTypedArray> obj = NewJSTypedArray(type, pretenure);
3229
3230 size_t element_size;
3231 ElementsKind elements_kind;
3232 ForFixedTypedArray(type, &element_size, &elements_kind);
3233
3234 CHECK_EQ(byte_offset % element_size, 0);
3235
3236 CHECK(length <= (std::numeric_limits<size_t>::max() / element_size));
3237 // TODO(7881): Smi length check
3238 CHECK(length <= static_cast<size_t>(Smi::kMaxValue));
3239 size_t byte_length = length * element_size;
3240 SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length,
3241 pretenure);
3242
3243 Handle<Object> length_object = NewNumberFromSize(length, pretenure);
3244 obj->set_length(*length_object);
3245
3246 Handle<FixedTypedArrayBase> elements = NewFixedTypedArrayWithExternalPointer(
3247 static_cast<int>(length), type,
3248 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset, pretenure);
3249 Handle<Map> map = JSObject::GetElementsTransitionMap(obj, elements_kind);
3250 JSObject::SetMapAndElements(obj, map, elements);
3251 return obj;
3252 }
3253
NewJSTypedArray(ElementsKind elements_kind,size_t number_of_elements,PretenureFlag pretenure)3254 Handle<JSTypedArray> Factory::NewJSTypedArray(ElementsKind elements_kind,
3255 size_t number_of_elements,
3256 PretenureFlag pretenure) {
3257 Handle<JSTypedArray> obj = NewJSTypedArray(elements_kind, pretenure);
3258 DCHECK_EQ(obj->GetEmbedderFieldCount(),
3259 v8::ArrayBufferView::kEmbedderFieldCount);
3260 for (int i = 0; i < v8::ArrayBufferView::kEmbedderFieldCount; i++) {
3261 obj->SetEmbedderField(i, Smi::kZero);
3262 }
3263
3264 size_t element_size;
3265 ExternalArrayType array_type;
3266 TypeAndSizeForElementsKind(elements_kind, &array_type, &element_size);
3267
3268 CHECK(number_of_elements <=
3269 (std::numeric_limits<size_t>::max() / element_size));
3270 // TODO(7881): Smi length check
3271 CHECK(number_of_elements <= static_cast<size_t>(Smi::kMaxValue));
3272 size_t byte_length = number_of_elements * element_size;
3273
3274 obj->set_byte_offset(Smi::kZero);
3275 i::Handle<i::Object> byte_length_object =
3276 NewNumberFromSize(byte_length, pretenure);
3277 obj->set_byte_length(*byte_length_object);
3278 Handle<Object> length_object =
3279 NewNumberFromSize(number_of_elements, pretenure);
3280 obj->set_length(*length_object);
3281
3282 Handle<JSArrayBuffer> buffer =
3283 NewJSArrayBuffer(SharedFlag::kNotShared, pretenure);
3284 JSArrayBuffer::Setup(buffer, isolate(), true, nullptr, byte_length,
3285 SharedFlag::kNotShared);
3286 obj->set_buffer(*buffer);
3287 Handle<FixedTypedArrayBase> elements = NewFixedTypedArray(
3288 number_of_elements, byte_length, array_type, true, pretenure);
3289 obj->set_elements(*elements);
3290 return obj;
3291 }
3292
NewJSDataView(Handle<JSArrayBuffer> buffer,size_t byte_offset,size_t byte_length)3293 Handle<JSDataView> Factory::NewJSDataView(Handle<JSArrayBuffer> buffer,
3294 size_t byte_offset,
3295 size_t byte_length) {
3296 Handle<Map> map(isolate()->native_context()->data_view_fun()->initial_map(),
3297 isolate());
3298 Handle<JSDataView> obj = Handle<JSDataView>::cast(NewJSObjectFromMap(map));
3299 SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length);
3300 return obj;
3301 }
3302
NewJSBoundFunction(Handle<JSReceiver> target_function,Handle<Object> bound_this,Vector<Handle<Object>> bound_args)3303 MaybeHandle<JSBoundFunction> Factory::NewJSBoundFunction(
3304 Handle<JSReceiver> target_function, Handle<Object> bound_this,
3305 Vector<Handle<Object>> bound_args) {
3306 DCHECK(target_function->IsCallable());
3307 STATIC_ASSERT(Code::kMaxArguments <= FixedArray::kMaxLength);
3308 if (bound_args.length() >= Code::kMaxArguments) {
3309 THROW_NEW_ERROR(isolate(),
3310 NewRangeError(MessageTemplate::kTooManyArguments),
3311 JSBoundFunction);
3312 }
3313
3314 // Determine the prototype of the {target_function}.
3315 Handle<Object> prototype;
3316 ASSIGN_RETURN_ON_EXCEPTION(
3317 isolate(), prototype,
3318 JSReceiver::GetPrototype(isolate(), target_function), JSBoundFunction);
3319
3320 SaveContext save(isolate());
3321 isolate()->set_context(*target_function->GetCreationContext());
3322
3323 // Create the [[BoundArguments]] for the result.
3324 Handle<FixedArray> bound_arguments;
3325 if (bound_args.length() == 0) {
3326 bound_arguments = empty_fixed_array();
3327 } else {
3328 bound_arguments = NewFixedArray(bound_args.length());
3329 for (int i = 0; i < bound_args.length(); ++i) {
3330 bound_arguments->set(i, *bound_args[i]);
3331 }
3332 }
3333
3334 // Setup the map for the JSBoundFunction instance.
3335 Handle<Map> map = target_function->IsConstructor()
3336 ? isolate()->bound_function_with_constructor_map()
3337 : isolate()->bound_function_without_constructor_map();
3338 if (map->prototype() != *prototype) {
3339 map = Map::TransitionToPrototype(isolate(), map, prototype);
3340 }
3341 DCHECK_EQ(target_function->IsConstructor(), map->is_constructor());
3342
3343 // Setup the JSBoundFunction instance.
3344 Handle<JSBoundFunction> result =
3345 Handle<JSBoundFunction>::cast(NewJSObjectFromMap(map));
3346 result->set_bound_target_function(*target_function);
3347 result->set_bound_this(*bound_this);
3348 result->set_bound_arguments(*bound_arguments);
3349 return result;
3350 }
3351
3352 // ES6 section 9.5.15 ProxyCreate (target, handler)
NewJSProxy(Handle<JSReceiver> target,Handle<JSReceiver> handler)3353 Handle<JSProxy> Factory::NewJSProxy(Handle<JSReceiver> target,
3354 Handle<JSReceiver> handler) {
3355 // Allocate the proxy object.
3356 Handle<Map> map;
3357 if (target->IsCallable()) {
3358 if (target->IsConstructor()) {
3359 map = Handle<Map>(isolate()->proxy_constructor_map());
3360 } else {
3361 map = Handle<Map>(isolate()->proxy_callable_map());
3362 }
3363 } else {
3364 map = Handle<Map>(isolate()->proxy_map());
3365 }
3366 DCHECK(map->prototype()->IsNull(isolate()));
3367 Handle<JSProxy> result(JSProxy::cast(New(map, NOT_TENURED)), isolate());
3368 result->initialize_properties();
3369 result->set_target(*target);
3370 result->set_handler(*handler);
3371 return result;
3372 }
3373
NewUninitializedJSGlobalProxy(int size)3374 Handle<JSGlobalProxy> Factory::NewUninitializedJSGlobalProxy(int size) {
3375 // Create an empty shell of a JSGlobalProxy that needs to be reinitialized
3376 // via ReinitializeJSGlobalProxy later.
3377 Handle<Map> map = NewMap(JS_GLOBAL_PROXY_TYPE, size);
3378 // Maintain invariant expected from any JSGlobalProxy.
3379 map->set_is_access_check_needed(true);
3380 map->set_may_have_interesting_symbols(true);
3381 return Handle<JSGlobalProxy>::cast(NewJSObjectFromMap(map, NOT_TENURED));
3382 }
3383
ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,Handle<JSFunction> constructor)3384 void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,
3385 Handle<JSFunction> constructor) {
3386 DCHECK(constructor->has_initial_map());
3387 Handle<Map> map(constructor->initial_map(), isolate());
3388 Handle<Map> old_map(object->map(), isolate());
3389
3390 // The proxy's hash should be retained across reinitialization.
3391 Handle<Object> raw_properties_or_hash(object->raw_properties_or_hash(),
3392 isolate());
3393
3394 if (old_map->is_prototype_map()) {
3395 map = Map::Copy(isolate(), map, "CopyAsPrototypeForJSGlobalProxy");
3396 map->set_is_prototype_map(true);
3397 }
3398 JSObject::NotifyMapChange(old_map, map, isolate());
3399 old_map->NotifyLeafMapLayoutChange(isolate());
3400
3401 // Check that the already allocated object has the same size and type as
3402 // objects allocated using the constructor.
3403 DCHECK(map->instance_size() == old_map->instance_size());
3404 DCHECK(map->instance_type() == old_map->instance_type());
3405
3406 // In order to keep heap in consistent state there must be no allocations
3407 // before object re-initialization is finished.
3408 DisallowHeapAllocation no_allocation;
3409
3410 // Reset the map for the object.
3411 object->synchronized_set_map(*map);
3412
3413 // Reinitialize the object from the constructor map.
3414 InitializeJSObjectFromMap(object, raw_properties_or_hash, map);
3415 }
3416
NewSharedFunctionInfoForLiteral(FunctionLiteral * literal,Handle<Script> script,bool is_toplevel)3417 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForLiteral(
3418 FunctionLiteral* literal, Handle<Script> script, bool is_toplevel) {
3419 FunctionKind kind = literal->kind();
3420 Handle<SharedFunctionInfo> shared = NewSharedFunctionInfoForBuiltin(
3421 literal->name(), Builtins::kCompileLazy, kind);
3422 SharedFunctionInfo::InitFromFunctionLiteral(shared, literal, is_toplevel);
3423 SharedFunctionInfo::SetScript(shared, script, literal->function_literal_id(),
3424 false);
3425 return shared;
3426 }
3427
NewJSMessageObject(MessageTemplate::Template message,Handle<Object> argument,int start_position,int end_position,Handle<Script> script,Handle<Object> stack_frames)3428 Handle<JSMessageObject> Factory::NewJSMessageObject(
3429 MessageTemplate::Template message, Handle<Object> argument,
3430 int start_position, int end_position, Handle<Script> script,
3431 Handle<Object> stack_frames) {
3432 Handle<Map> map = message_object_map();
3433 Handle<JSMessageObject> message_obj(
3434 JSMessageObject::cast(New(map, NOT_TENURED)), isolate());
3435 message_obj->set_raw_properties_or_hash(*empty_fixed_array(),
3436 SKIP_WRITE_BARRIER);
3437 message_obj->initialize_elements();
3438 message_obj->set_elements(*empty_fixed_array(), SKIP_WRITE_BARRIER);
3439 message_obj->set_type(message);
3440 message_obj->set_argument(*argument);
3441 message_obj->set_start_position(start_position);
3442 message_obj->set_end_position(end_position);
3443 message_obj->set_script(*script);
3444 message_obj->set_stack_frames(*stack_frames);
3445 message_obj->set_error_level(v8::Isolate::kMessageError);
3446 return message_obj;
3447 }
3448
NewSharedFunctionInfoForApiFunction(MaybeHandle<String> maybe_name,Handle<FunctionTemplateInfo> function_template_info,FunctionKind kind)3449 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForApiFunction(
3450 MaybeHandle<String> maybe_name,
3451 Handle<FunctionTemplateInfo> function_template_info, FunctionKind kind) {
3452 Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(
3453 maybe_name, function_template_info, Builtins::kNoBuiltinId, kind);
3454 return shared;
3455 }
3456
NewSharedFunctionInfoForBuiltin(MaybeHandle<String> maybe_name,int builtin_index,FunctionKind kind)3457 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForBuiltin(
3458 MaybeHandle<String> maybe_name, int builtin_index, FunctionKind kind) {
3459 Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(
3460 maybe_name, MaybeHandle<Code>(), builtin_index, kind);
3461 return shared;
3462 }
3463
NewSharedFunctionInfo(MaybeHandle<String> maybe_name,MaybeHandle<HeapObject> maybe_function_data,int maybe_builtin_index,FunctionKind kind)3464 Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
3465 MaybeHandle<String> maybe_name, MaybeHandle<HeapObject> maybe_function_data,
3466 int maybe_builtin_index, FunctionKind kind) {
3467 // Function names are assumed to be flat elsewhere. Must flatten before
3468 // allocating SharedFunctionInfo to avoid GC seeing the uninitialized SFI.
3469 Handle<String> shared_name;
3470 bool has_shared_name = maybe_name.ToHandle(&shared_name);
3471 if (has_shared_name) {
3472 shared_name = String::Flatten(isolate(), shared_name, TENURED);
3473 }
3474
3475 Handle<Map> map = shared_function_info_map();
3476 Handle<SharedFunctionInfo> share(SharedFunctionInfo::cast(New(map, TENURED)),
3477 isolate());
3478 {
3479 DisallowHeapAllocation no_allocation;
3480
3481 // Set pointer fields.
3482 share->set_name_or_scope_info(
3483 has_shared_name ? *shared_name
3484 : SharedFunctionInfo::kNoSharedNameSentinel);
3485 Handle<HeapObject> function_data;
3486 if (maybe_function_data.ToHandle(&function_data)) {
3487 // If we pass function_data then we shouldn't pass a builtin index, and
3488 // the function_data should not be code with a builtin.
3489 DCHECK(!Builtins::IsBuiltinId(maybe_builtin_index));
3490 DCHECK_IMPLIES(function_data->IsCode(),
3491 !Code::cast(*function_data)->is_builtin());
3492 share->set_function_data(*function_data);
3493 } else if (Builtins::IsBuiltinId(maybe_builtin_index)) {
3494 DCHECK_NE(maybe_builtin_index, Builtins::kDeserializeLazy);
3495 share->set_builtin_id(maybe_builtin_index);
3496 } else {
3497 share->set_builtin_id(Builtins::kIllegal);
3498 }
3499 // Generally functions won't have feedback, unless they have been created
3500 // from a FunctionLiteral. Those can just reset this field to keep the
3501 // SharedFunctionInfo in a consistent state.
3502 if (maybe_builtin_index == Builtins::kCompileLazy) {
3503 share->set_raw_outer_scope_info_or_feedback_metadata(*the_hole_value(),
3504 SKIP_WRITE_BARRIER);
3505 } else {
3506 share->set_raw_outer_scope_info_or_feedback_metadata(
3507 *empty_feedback_metadata(), SKIP_WRITE_BARRIER);
3508 }
3509 share->set_script_or_debug_info(*undefined_value(), SKIP_WRITE_BARRIER);
3510 #if V8_SFI_HAS_UNIQUE_ID
3511 share->set_unique_id(isolate()->GetNextUniqueSharedFunctionInfoId());
3512 #endif
3513
3514 // Set integer fields (smi or int, depending on the architecture).
3515 share->set_length(0);
3516 share->set_internal_formal_parameter_count(0);
3517 share->set_expected_nof_properties(0);
3518 share->set_builtin_function_id(
3519 BuiltinFunctionId::kInvalidBuiltinFunctionId);
3520 share->set_raw_function_token_offset(0);
3521 // All flags default to false or 0.
3522 share->set_flags(0);
3523 share->CalculateConstructAsBuiltin();
3524 share->set_kind(kind);
3525
3526 share->clear_padding();
3527 }
3528 // Link into the list.
3529 Handle<WeakArrayList> noscript_list = noscript_shared_function_infos();
3530 noscript_list = WeakArrayList::AddToEnd(isolate(), noscript_list,
3531 MaybeObjectHandle::Weak(share));
3532 isolate()->heap()->set_noscript_shared_function_infos(*noscript_list);
3533
3534 #ifdef VERIFY_HEAP
3535 share->SharedFunctionInfoVerify(isolate());
3536 #endif
3537 return share;
3538 }
3539
3540 namespace {
NumberToStringCacheHash(Handle<FixedArray> cache,Smi * number)3541 inline int NumberToStringCacheHash(Handle<FixedArray> cache, Smi* number) {
3542 int mask = (cache->length() >> 1) - 1;
3543 return number->value() & mask;
3544 }
NumberToStringCacheHash(Handle<FixedArray> cache,double number)3545 inline int NumberToStringCacheHash(Handle<FixedArray> cache, double number) {
3546 int mask = (cache->length() >> 1) - 1;
3547 int64_t bits = bit_cast<int64_t>(number);
3548 return (static_cast<int>(bits) ^ static_cast<int>(bits >> 32)) & mask;
3549 }
3550 } // namespace
3551
NumberToStringCacheSet(Handle<Object> number,int hash,const char * string,bool check_cache)3552 Handle<String> Factory::NumberToStringCacheSet(Handle<Object> number, int hash,
3553 const char* string,
3554 bool check_cache) {
3555 // We tenure the allocated string since it is referenced from the
3556 // number-string cache which lives in the old space.
3557 Handle<String> js_string =
3558 NewStringFromAsciiChecked(string, check_cache ? TENURED : NOT_TENURED);
3559 if (!check_cache) return js_string;
3560
3561 if (!number_string_cache()->get(hash * 2)->IsUndefined(isolate())) {
3562 int full_size = isolate()->heap()->MaxNumberToStringCacheSize();
3563 if (number_string_cache()->length() != full_size) {
3564 Handle<FixedArray> new_cache = NewFixedArray(full_size, TENURED);
3565 isolate()->heap()->set_number_string_cache(*new_cache);
3566 return js_string;
3567 }
3568 }
3569 number_string_cache()->set(hash * 2, *number);
3570 number_string_cache()->set(hash * 2 + 1, *js_string);
3571 return js_string;
3572 }
3573
NumberToStringCacheGet(Object * number,int hash)3574 Handle<Object> Factory::NumberToStringCacheGet(Object* number, int hash) {
3575 DisallowHeapAllocation no_gc;
3576 Object* key = number_string_cache()->get(hash * 2);
3577 if (key == number || (key->IsHeapNumber() && number->IsHeapNumber() &&
3578 key->Number() == number->Number())) {
3579 return Handle<String>(
3580 String::cast(number_string_cache()->get(hash * 2 + 1)), isolate());
3581 }
3582 return undefined_value();
3583 }
3584
NumberToString(Handle<Object> number,bool check_cache)3585 Handle<String> Factory::NumberToString(Handle<Object> number,
3586 bool check_cache) {
3587 if (number->IsSmi()) return NumberToString(Smi::cast(*number), check_cache);
3588
3589 double double_value = Handle<HeapNumber>::cast(number)->value();
3590 // Try to canonicalize doubles.
3591 int smi_value;
3592 if (DoubleToSmiInteger(double_value, &smi_value)) {
3593 return NumberToString(Smi::FromInt(smi_value), check_cache);
3594 }
3595
3596 int hash = 0;
3597 if (check_cache) {
3598 hash = NumberToStringCacheHash(number_string_cache(), double_value);
3599 Handle<Object> cached = NumberToStringCacheGet(*number, hash);
3600 if (!cached->IsUndefined(isolate())) return Handle<String>::cast(cached);
3601 }
3602
3603 char arr[100];
3604 Vector<char> buffer(arr, arraysize(arr));
3605 const char* string = DoubleToCString(double_value, buffer);
3606
3607 return NumberToStringCacheSet(number, hash, string, check_cache);
3608 }
3609
NumberToString(Smi * number,bool check_cache)3610 Handle<String> Factory::NumberToString(Smi* number, bool check_cache) {
3611 int hash = 0;
3612 if (check_cache) {
3613 hash = NumberToStringCacheHash(number_string_cache(), number);
3614 Handle<Object> cached = NumberToStringCacheGet(number, hash);
3615 if (!cached->IsUndefined(isolate())) return Handle<String>::cast(cached);
3616 }
3617
3618 char arr[100];
3619 Vector<char> buffer(arr, arraysize(arr));
3620 const char* string = IntToCString(number->value(), buffer);
3621
3622 return NumberToStringCacheSet(handle(number, isolate()), hash, string,
3623 check_cache);
3624 }
3625
NewDebugInfo(Handle<SharedFunctionInfo> shared)3626 Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
3627 DCHECK(!shared->HasDebugInfo());
3628 Heap* heap = isolate()->heap();
3629
3630 Handle<DebugInfo> debug_info =
3631 Handle<DebugInfo>::cast(NewStruct(DEBUG_INFO_TYPE, TENURED));
3632 debug_info->set_flags(DebugInfo::kNone);
3633 debug_info->set_shared(*shared);
3634 debug_info->set_debugger_hints(0);
3635 DCHECK_EQ(DebugInfo::kNoDebuggingId, debug_info->debugging_id());
3636 DCHECK(!shared->HasDebugInfo());
3637 debug_info->set_script(shared->script_or_debug_info());
3638 debug_info->set_original_bytecode_array(
3639 ReadOnlyRoots(heap).undefined_value());
3640 debug_info->set_break_points(ReadOnlyRoots(heap).empty_fixed_array());
3641
3642 // Link debug info to function.
3643 shared->SetDebugInfo(*debug_info);
3644
3645 return debug_info;
3646 }
3647
NewCoverageInfo(const ZoneVector<SourceRange> & slots)3648 Handle<CoverageInfo> Factory::NewCoverageInfo(
3649 const ZoneVector<SourceRange>& slots) {
3650 const int slot_count = static_cast<int>(slots.size());
3651
3652 const int length = CoverageInfo::FixedArrayLengthForSlotCount(slot_count);
3653 Handle<CoverageInfo> info =
3654 Handle<CoverageInfo>::cast(NewUninitializedFixedArray(length));
3655
3656 for (int i = 0; i < slot_count; i++) {
3657 SourceRange range = slots[i];
3658 info->InitializeSlot(i, range.start, range.end);
3659 }
3660
3661 return info;
3662 }
3663
NewBreakPointInfo(int source_position)3664 Handle<BreakPointInfo> Factory::NewBreakPointInfo(int source_position) {
3665 Handle<BreakPointInfo> new_break_point_info =
3666 Handle<BreakPointInfo>::cast(NewStruct(TUPLE2_TYPE, TENURED));
3667 new_break_point_info->set_source_position(source_position);
3668 new_break_point_info->set_break_points(*undefined_value());
3669 return new_break_point_info;
3670 }
3671
NewBreakPoint(int id,Handle<String> condition)3672 Handle<BreakPoint> Factory::NewBreakPoint(int id, Handle<String> condition) {
3673 Handle<BreakPoint> new_break_point =
3674 Handle<BreakPoint>::cast(NewStruct(TUPLE2_TYPE, TENURED));
3675 new_break_point->set_id(id);
3676 new_break_point->set_condition(*condition);
3677 return new_break_point;
3678 }
3679
NewStackFrameInfo()3680 Handle<StackFrameInfo> Factory::NewStackFrameInfo() {
3681 Handle<StackFrameInfo> stack_frame_info = Handle<StackFrameInfo>::cast(
3682 NewStruct(STACK_FRAME_INFO_TYPE, NOT_TENURED));
3683 stack_frame_info->set_line_number(0);
3684 stack_frame_info->set_column_number(0);
3685 stack_frame_info->set_script_id(0);
3686 stack_frame_info->set_script_name(Smi::kZero);
3687 stack_frame_info->set_script_name_or_source_url(Smi::kZero);
3688 stack_frame_info->set_function_name(Smi::kZero);
3689 stack_frame_info->set_flag(0);
3690 return stack_frame_info;
3691 }
3692
3693 Handle<SourcePositionTableWithFrameCache>
NewSourcePositionTableWithFrameCache(Handle<ByteArray> source_position_table,Handle<SimpleNumberDictionary> stack_frame_cache)3694 Factory::NewSourcePositionTableWithFrameCache(
3695 Handle<ByteArray> source_position_table,
3696 Handle<SimpleNumberDictionary> stack_frame_cache) {
3697 Handle<SourcePositionTableWithFrameCache>
3698 source_position_table_with_frame_cache =
3699 Handle<SourcePositionTableWithFrameCache>::cast(
3700 NewStruct(TUPLE2_TYPE, TENURED));
3701 source_position_table_with_frame_cache->set_source_position_table(
3702 *source_position_table);
3703 source_position_table_with_frame_cache->set_stack_frame_cache(
3704 *stack_frame_cache);
3705 return source_position_table_with_frame_cache;
3706 }
3707
NewArgumentsObject(Handle<JSFunction> callee,int length)3708 Handle<JSObject> Factory::NewArgumentsObject(Handle<JSFunction> callee,
3709 int length) {
3710 bool strict_mode_callee = is_strict(callee->shared()->language_mode()) ||
3711 !callee->shared()->has_simple_parameters();
3712 Handle<Map> map = strict_mode_callee ? isolate()->strict_arguments_map()
3713 : isolate()->sloppy_arguments_map();
3714 AllocationSiteUsageContext context(isolate(), Handle<AllocationSite>(),
3715 false);
3716 DCHECK(!isolate()->has_pending_exception());
3717 Handle<JSObject> result = NewJSObjectFromMap(map);
3718 Handle<Smi> value(Smi::FromInt(length), isolate());
3719 Object::SetProperty(isolate(), result, length_string(), value,
3720 LanguageMode::kStrict)
3721 .Assert();
3722 if (!strict_mode_callee) {
3723 Object::SetProperty(isolate(), result, callee_string(), callee,
3724 LanguageMode::kStrict)
3725 .Assert();
3726 }
3727 return result;
3728 }
3729
ObjectLiteralMapFromCache(Handle<NativeContext> context,int number_of_properties)3730 Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<NativeContext> context,
3731 int number_of_properties) {
3732 if (number_of_properties == 0) {
3733 // Reuse the initial map of the Object function if the literal has no
3734 // predeclared properties.
3735 return handle(context->object_function()->initial_map(), isolate());
3736 }
3737
3738 // We do not cache maps for too many properties or when running builtin code.
3739 if (isolate()->bootstrapper()->IsActive()) {
3740 return Map::Create(isolate(), number_of_properties);
3741 }
3742
3743 // Use initial slow object proto map for too many properties.
3744 const int kMapCacheSize = 128;
3745 if (number_of_properties > kMapCacheSize) {
3746 return handle(context->slow_object_with_object_prototype_map(), isolate());
3747 }
3748
3749 int cache_index = number_of_properties - 1;
3750 Handle<Object> maybe_cache(context->map_cache(), isolate());
3751 if (maybe_cache->IsUndefined(isolate())) {
3752 // Allocate the new map cache for the native context.
3753 maybe_cache = NewWeakFixedArray(kMapCacheSize, TENURED);
3754 context->set_map_cache(*maybe_cache);
3755 } else {
3756 // Check to see whether there is a matching element in the cache.
3757 Handle<WeakFixedArray> cache = Handle<WeakFixedArray>::cast(maybe_cache);
3758 MaybeObject* result = cache->Get(cache_index);
3759 HeapObject* heap_object;
3760 if (result->ToWeakHeapObject(&heap_object)) {
3761 Map* map = Map::cast(heap_object);
3762 DCHECK(!map->is_dictionary_map());
3763 return handle(map, isolate());
3764 }
3765 }
3766
3767 // Create a new map and add it to the cache.
3768 Handle<WeakFixedArray> cache = Handle<WeakFixedArray>::cast(maybe_cache);
3769 Handle<Map> map = Map::Create(isolate(), number_of_properties);
3770 DCHECK(!map->is_dictionary_map());
3771 cache->Set(cache_index, HeapObjectReference::Weak(*map));
3772 return map;
3773 }
3774
NewLoadHandler(int data_count)3775 Handle<LoadHandler> Factory::NewLoadHandler(int data_count) {
3776 Handle<Map> map;
3777 switch (data_count) {
3778 case 1:
3779 map = load_handler1_map();
3780 break;
3781 case 2:
3782 map = load_handler2_map();
3783 break;
3784 case 3:
3785 map = load_handler3_map();
3786 break;
3787 default:
3788 UNREACHABLE();
3789 break;
3790 }
3791 return handle(LoadHandler::cast(New(map, TENURED)), isolate());
3792 }
3793
NewStoreHandler(int data_count)3794 Handle<StoreHandler> Factory::NewStoreHandler(int data_count) {
3795 Handle<Map> map;
3796 switch (data_count) {
3797 case 0:
3798 map = store_handler0_map();
3799 break;
3800 case 1:
3801 map = store_handler1_map();
3802 break;
3803 case 2:
3804 map = store_handler2_map();
3805 break;
3806 case 3:
3807 map = store_handler3_map();
3808 break;
3809 default:
3810 UNREACHABLE();
3811 break;
3812 }
3813 return handle(StoreHandler::cast(New(map, TENURED)), isolate());
3814 }
3815
SetRegExpAtomData(Handle<JSRegExp> regexp,JSRegExp::Type type,Handle<String> source,JSRegExp::Flags flags,Handle<Object> data)3816 void Factory::SetRegExpAtomData(Handle<JSRegExp> regexp, JSRegExp::Type type,
3817 Handle<String> source, JSRegExp::Flags flags,
3818 Handle<Object> data) {
3819 Handle<FixedArray> store = NewFixedArray(JSRegExp::kAtomDataSize);
3820
3821 store->set(JSRegExp::kTagIndex, Smi::FromInt(type));
3822 store->set(JSRegExp::kSourceIndex, *source);
3823 store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags));
3824 store->set(JSRegExp::kAtomPatternIndex, *data);
3825 regexp->set_data(*store);
3826 }
3827
SetRegExpIrregexpData(Handle<JSRegExp> regexp,JSRegExp::Type type,Handle<String> source,JSRegExp::Flags flags,int capture_count)3828 void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp,
3829 JSRegExp::Type type, Handle<String> source,
3830 JSRegExp::Flags flags, int capture_count) {
3831 Handle<FixedArray> store = NewFixedArray(JSRegExp::kIrregexpDataSize);
3832 Smi* uninitialized = Smi::FromInt(JSRegExp::kUninitializedValue);
3833 store->set(JSRegExp::kTagIndex, Smi::FromInt(type));
3834 store->set(JSRegExp::kSourceIndex, *source);
3835 store->set(JSRegExp::kFlagsIndex, Smi::FromInt(flags));
3836 store->set(JSRegExp::kIrregexpLatin1CodeIndex, uninitialized);
3837 store->set(JSRegExp::kIrregexpUC16CodeIndex, uninitialized);
3838 store->set(JSRegExp::kIrregexpMaxRegisterCountIndex, Smi::kZero);
3839 store->set(JSRegExp::kIrregexpCaptureCountIndex, Smi::FromInt(capture_count));
3840 store->set(JSRegExp::kIrregexpCaptureNameMapIndex, uninitialized);
3841 regexp->set_data(*store);
3842 }
3843
NewRegExpMatchInfo()3844 Handle<RegExpMatchInfo> Factory::NewRegExpMatchInfo() {
3845 // Initially, the last match info consists of all fixed fields plus space for
3846 // the match itself (i.e., 2 capture indices).
3847 static const int kInitialSize = RegExpMatchInfo::kFirstCaptureIndex +
3848 RegExpMatchInfo::kInitialCaptureIndices;
3849
3850 Handle<FixedArray> elems = NewFixedArray(kInitialSize);
3851 Handle<RegExpMatchInfo> result = Handle<RegExpMatchInfo>::cast(elems);
3852
3853 result->SetNumberOfCaptureRegisters(RegExpMatchInfo::kInitialCaptureIndices);
3854 result->SetLastSubject(*empty_string());
3855 result->SetLastInput(*undefined_value());
3856 result->SetCapture(0, 0);
3857 result->SetCapture(1, 0);
3858
3859 return result;
3860 }
3861
GlobalConstantFor(Handle<Name> name)3862 Handle<Object> Factory::GlobalConstantFor(Handle<Name> name) {
3863 if (Name::Equals(isolate(), name, undefined_string())) {
3864 return undefined_value();
3865 }
3866 if (Name::Equals(isolate(), name, NaN_string())) return nan_value();
3867 if (Name::Equals(isolate(), name, Infinity_string())) return infinity_value();
3868 return Handle<Object>::null();
3869 }
3870
ToBoolean(bool value)3871 Handle<Object> Factory::ToBoolean(bool value) {
3872 return value ? true_value() : false_value();
3873 }
3874
ToPrimitiveHintString(ToPrimitiveHint hint)3875 Handle<String> Factory::ToPrimitiveHintString(ToPrimitiveHint hint) {
3876 switch (hint) {
3877 case ToPrimitiveHint::kDefault:
3878 return default_string();
3879 case ToPrimitiveHint::kNumber:
3880 return number_string();
3881 case ToPrimitiveHint::kString:
3882 return string_string();
3883 }
3884 UNREACHABLE();
3885 }
3886
CreateSloppyFunctionMap(FunctionMode function_mode,MaybeHandle<JSFunction> maybe_empty_function)3887 Handle<Map> Factory::CreateSloppyFunctionMap(
3888 FunctionMode function_mode, MaybeHandle<JSFunction> maybe_empty_function) {
3889 bool has_prototype = IsFunctionModeWithPrototype(function_mode);
3890 int header_size = has_prototype ? JSFunction::kSizeWithPrototype
3891 : JSFunction::kSizeWithoutPrototype;
3892 int descriptors_count = has_prototype ? 5 : 4;
3893 int inobject_properties_count = 0;
3894 if (IsFunctionModeWithName(function_mode)) ++inobject_properties_count;
3895
3896 Handle<Map> map = NewMap(
3897 JS_FUNCTION_TYPE, header_size + inobject_properties_count * kPointerSize,
3898 TERMINAL_FAST_ELEMENTS_KIND, inobject_properties_count);
3899 map->set_has_prototype_slot(has_prototype);
3900 map->set_is_constructor(has_prototype);
3901 map->set_is_callable(true);
3902 Handle<JSFunction> empty_function;
3903 if (maybe_empty_function.ToHandle(&empty_function)) {
3904 Map::SetPrototype(isolate(), map, empty_function);
3905 }
3906
3907 //
3908 // Setup descriptors array.
3909 //
3910 Map::EnsureDescriptorSlack(isolate(), map, descriptors_count);
3911
3912 PropertyAttributes ro_attribs =
3913 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
3914 PropertyAttributes rw_attribs =
3915 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
3916 PropertyAttributes roc_attribs =
3917 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
3918
3919 int field_index = 0;
3920 STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0);
3921 { // Add length accessor.
3922 Descriptor d = Descriptor::AccessorConstant(
3923 length_string(), function_length_accessor(), roc_attribs);
3924 map->AppendDescriptor(&d);
3925 }
3926
3927 STATIC_ASSERT(JSFunction::kNameDescriptorIndex == 1);
3928 if (IsFunctionModeWithName(function_mode)) {
3929 // Add name field.
3930 Handle<Name> name = isolate()->factory()->name_string();
3931 Descriptor d = Descriptor::DataField(isolate(), name, field_index++,
3932 roc_attribs, Representation::Tagged());
3933 map->AppendDescriptor(&d);
3934
3935 } else {
3936 // Add name accessor.
3937 Descriptor d = Descriptor::AccessorConstant(
3938 name_string(), function_name_accessor(), roc_attribs);
3939 map->AppendDescriptor(&d);
3940 }
3941 { // Add arguments accessor.
3942 Descriptor d = Descriptor::AccessorConstant(
3943 arguments_string(), function_arguments_accessor(), ro_attribs);
3944 map->AppendDescriptor(&d);
3945 }
3946 { // Add caller accessor.
3947 Descriptor d = Descriptor::AccessorConstant(
3948 caller_string(), function_caller_accessor(), ro_attribs);
3949 map->AppendDescriptor(&d);
3950 }
3951 if (IsFunctionModeWithPrototype(function_mode)) {
3952 // Add prototype accessor.
3953 PropertyAttributes attribs =
3954 IsFunctionModeWithWritablePrototype(function_mode) ? rw_attribs
3955 : ro_attribs;
3956 Descriptor d = Descriptor::AccessorConstant(
3957 prototype_string(), function_prototype_accessor(), attribs);
3958 map->AppendDescriptor(&d);
3959 }
3960 DCHECK_EQ(inobject_properties_count, field_index);
3961 return map;
3962 }
3963
CreateStrictFunctionMap(FunctionMode function_mode,Handle<JSFunction> empty_function)3964 Handle<Map> Factory::CreateStrictFunctionMap(
3965 FunctionMode function_mode, Handle<JSFunction> empty_function) {
3966 bool has_prototype = IsFunctionModeWithPrototype(function_mode);
3967 int header_size = has_prototype ? JSFunction::kSizeWithPrototype
3968 : JSFunction::kSizeWithoutPrototype;
3969 int inobject_properties_count = 0;
3970 if (IsFunctionModeWithName(function_mode)) ++inobject_properties_count;
3971 if (IsFunctionModeWithHomeObject(function_mode)) ++inobject_properties_count;
3972 int descriptors_count = (IsFunctionModeWithPrototype(function_mode) ? 3 : 2) +
3973 inobject_properties_count;
3974
3975 Handle<Map> map = NewMap(
3976 JS_FUNCTION_TYPE, header_size + inobject_properties_count * kPointerSize,
3977 TERMINAL_FAST_ELEMENTS_KIND, inobject_properties_count);
3978 map->set_has_prototype_slot(has_prototype);
3979 map->set_is_constructor(has_prototype);
3980 map->set_is_callable(true);
3981 Map::SetPrototype(isolate(), map, empty_function);
3982
3983 //
3984 // Setup descriptors array.
3985 //
3986 Map::EnsureDescriptorSlack(isolate(), map, descriptors_count);
3987
3988 PropertyAttributes rw_attribs =
3989 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
3990 PropertyAttributes ro_attribs =
3991 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
3992 PropertyAttributes roc_attribs =
3993 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
3994
3995 int field_index = 0;
3996 STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0);
3997 { // Add length accessor.
3998 Descriptor d = Descriptor::AccessorConstant(
3999 length_string(), function_length_accessor(), roc_attribs);
4000 map->AppendDescriptor(&d);
4001 }
4002
4003 STATIC_ASSERT(JSFunction::kNameDescriptorIndex == 1);
4004 if (IsFunctionModeWithName(function_mode)) {
4005 // Add name field.
4006 Handle<Name> name = isolate()->factory()->name_string();
4007 Descriptor d = Descriptor::DataField(isolate(), name, field_index++,
4008 roc_attribs, Representation::Tagged());
4009 map->AppendDescriptor(&d);
4010
4011 } else {
4012 // Add name accessor.
4013 Descriptor d = Descriptor::AccessorConstant(
4014 name_string(), function_name_accessor(), roc_attribs);
4015 map->AppendDescriptor(&d);
4016 }
4017
4018 STATIC_ASSERT(JSFunction::kMaybeHomeObjectDescriptorIndex == 2);
4019 if (IsFunctionModeWithHomeObject(function_mode)) {
4020 // Add home object field.
4021 Handle<Name> name = isolate()->factory()->home_object_symbol();
4022 Descriptor d = Descriptor::DataField(isolate(), name, field_index++,
4023 DONT_ENUM, Representation::Tagged());
4024 map->AppendDescriptor(&d);
4025 }
4026
4027 if (IsFunctionModeWithPrototype(function_mode)) {
4028 // Add prototype accessor.
4029 PropertyAttributes attribs =
4030 IsFunctionModeWithWritablePrototype(function_mode) ? rw_attribs
4031 : ro_attribs;
4032 Descriptor d = Descriptor::AccessorConstant(
4033 prototype_string(), function_prototype_accessor(), attribs);
4034 map->AppendDescriptor(&d);
4035 }
4036 DCHECK_EQ(inobject_properties_count, field_index);
4037 return map;
4038 }
4039
CreateClassFunctionMap(Handle<JSFunction> empty_function)4040 Handle<Map> Factory::CreateClassFunctionMap(Handle<JSFunction> empty_function) {
4041 Handle<Map> map = NewMap(JS_FUNCTION_TYPE, JSFunction::kSizeWithPrototype);
4042 map->set_has_prototype_slot(true);
4043 map->set_is_constructor(true);
4044 map->set_is_prototype_map(true);
4045 map->set_is_callable(true);
4046 Map::SetPrototype(isolate(), map, empty_function);
4047
4048 //
4049 // Setup descriptors array.
4050 //
4051 Map::EnsureDescriptorSlack(isolate(), map, 2);
4052
4053 PropertyAttributes ro_attribs =
4054 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
4055 PropertyAttributes roc_attribs =
4056 static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY);
4057
4058 STATIC_ASSERT(JSFunction::kLengthDescriptorIndex == 0);
4059 { // Add length accessor.
4060 Descriptor d = Descriptor::AccessorConstant(
4061 length_string(), function_length_accessor(), roc_attribs);
4062 map->AppendDescriptor(&d);
4063 }
4064
4065 {
4066 // Add prototype accessor.
4067 Descriptor d = Descriptor::AccessorConstant(
4068 prototype_string(), function_prototype_accessor(), ro_attribs);
4069 map->AppendDescriptor(&d);
4070 }
4071 return map;
4072 }
4073
NewJSPromiseWithoutHook(PretenureFlag pretenure)4074 Handle<JSPromise> Factory::NewJSPromiseWithoutHook(PretenureFlag pretenure) {
4075 Handle<JSPromise> promise = Handle<JSPromise>::cast(
4076 NewJSObject(isolate()->promise_function(), pretenure));
4077 promise->set_reactions_or_result(Smi::kZero);
4078 promise->set_flags(0);
4079 for (int i = 0; i < v8::Promise::kEmbedderFieldCount; i++) {
4080 promise->SetEmbedderField(i, Smi::kZero);
4081 }
4082 return promise;
4083 }
4084
NewJSPromise(PretenureFlag pretenure)4085 Handle<JSPromise> Factory::NewJSPromise(PretenureFlag pretenure) {
4086 Handle<JSPromise> promise = NewJSPromiseWithoutHook(pretenure);
4087 isolate()->RunPromiseHook(PromiseHookType::kInit, promise, undefined_value());
4088 return promise;
4089 }
4090
NewCallHandlerInfo(bool has_no_side_effect)4091 Handle<CallHandlerInfo> Factory::NewCallHandlerInfo(bool has_no_side_effect) {
4092 Handle<Map> map = has_no_side_effect
4093 ? side_effect_free_call_handler_info_map()
4094 : side_effect_call_handler_info_map();
4095 Handle<CallHandlerInfo> info(CallHandlerInfo::cast(New(map, TENURED)),
4096 isolate());
4097 Object* undefined_value = ReadOnlyRoots(isolate()).undefined_value();
4098 info->set_callback(undefined_value);
4099 info->set_js_callback(undefined_value);
4100 info->set_data(undefined_value);
4101 return info;
4102 }
4103
4104 // static
ForWasm(Handle<String> name,Handle<WasmExportedFunctionData> exported_function_data,Handle<Map> map)4105 NewFunctionArgs NewFunctionArgs::ForWasm(
4106 Handle<String> name,
4107 Handle<WasmExportedFunctionData> exported_function_data, Handle<Map> map) {
4108 NewFunctionArgs args;
4109 args.name_ = name;
4110 args.maybe_map_ = map;
4111 args.maybe_exported_function_data_ = exported_function_data;
4112 args.language_mode_ = LanguageMode::kSloppy;
4113 args.prototype_mutability_ = MUTABLE;
4114
4115 return args;
4116 }
4117
4118 // static
ForBuiltin(Handle<String> name,Handle<Map> map,int builtin_id)4119 NewFunctionArgs NewFunctionArgs::ForBuiltin(Handle<String> name,
4120 Handle<Map> map, int builtin_id) {
4121 DCHECK(Builtins::IsBuiltinId(builtin_id));
4122
4123 NewFunctionArgs args;
4124 args.name_ = name;
4125 args.maybe_map_ = map;
4126 args.maybe_builtin_id_ = builtin_id;
4127 args.language_mode_ = LanguageMode::kStrict;
4128 args.prototype_mutability_ = MUTABLE;
4129
4130 args.SetShouldSetLanguageMode();
4131
4132 return args;
4133 }
4134
4135 // static
ForFunctionWithoutCode(Handle<String> name,Handle<Map> map,LanguageMode language_mode)4136 NewFunctionArgs NewFunctionArgs::ForFunctionWithoutCode(
4137 Handle<String> name, Handle<Map> map, LanguageMode language_mode) {
4138 NewFunctionArgs args;
4139 args.name_ = name;
4140 args.maybe_map_ = map;
4141 args.maybe_builtin_id_ = Builtins::kIllegal;
4142 args.language_mode_ = language_mode;
4143 args.prototype_mutability_ = MUTABLE;
4144
4145 args.SetShouldSetLanguageMode();
4146
4147 return args;
4148 }
4149
4150 // static
ForBuiltinWithPrototype(Handle<String> name,Handle<Object> prototype,InstanceType type,int instance_size,int inobject_properties,int builtin_id,MutableMode prototype_mutability)4151 NewFunctionArgs NewFunctionArgs::ForBuiltinWithPrototype(
4152 Handle<String> name, Handle<Object> prototype, InstanceType type,
4153 int instance_size, int inobject_properties, int builtin_id,
4154 MutableMode prototype_mutability) {
4155 DCHECK(Builtins::IsBuiltinId(builtin_id));
4156
4157 NewFunctionArgs args;
4158 args.name_ = name;
4159 args.type_ = type;
4160 args.instance_size_ = instance_size;
4161 args.inobject_properties_ = inobject_properties;
4162 args.maybe_prototype_ = prototype;
4163 args.maybe_builtin_id_ = builtin_id;
4164 args.language_mode_ = LanguageMode::kStrict;
4165 args.prototype_mutability_ = prototype_mutability;
4166
4167 args.SetShouldCreateAndSetInitialMap();
4168 args.SetShouldSetPrototype();
4169 args.SetShouldSetLanguageMode();
4170
4171 return args;
4172 }
4173
4174 // static
ForBuiltinWithoutPrototype(Handle<String> name,int builtin_id,LanguageMode language_mode)4175 NewFunctionArgs NewFunctionArgs::ForBuiltinWithoutPrototype(
4176 Handle<String> name, int builtin_id, LanguageMode language_mode) {
4177 DCHECK(Builtins::IsBuiltinId(builtin_id));
4178
4179 NewFunctionArgs args;
4180 args.name_ = name;
4181 args.maybe_builtin_id_ = builtin_id;
4182 args.language_mode_ = language_mode;
4183 args.prototype_mutability_ = MUTABLE;
4184
4185 args.SetShouldSetLanguageMode();
4186
4187 return args;
4188 }
4189
SetShouldCreateAndSetInitialMap()4190 void NewFunctionArgs::SetShouldCreateAndSetInitialMap() {
4191 // Needed to create the initial map.
4192 maybe_prototype_.Assert();
4193 DCHECK_NE(kUninitialized, instance_size_);
4194 DCHECK_NE(kUninitialized, inobject_properties_);
4195
4196 should_create_and_set_initial_map_ = true;
4197 }
4198
SetShouldSetPrototype()4199 void NewFunctionArgs::SetShouldSetPrototype() {
4200 maybe_prototype_.Assert();
4201 should_set_prototype_ = true;
4202 }
4203
SetShouldSetLanguageMode()4204 void NewFunctionArgs::SetShouldSetLanguageMode() {
4205 DCHECK(language_mode_ == LanguageMode::kStrict ||
4206 language_mode_ == LanguageMode::kSloppy);
4207 should_set_language_mode_ = true;
4208 }
4209
GetMap(Isolate * isolate) const4210 Handle<Map> NewFunctionArgs::GetMap(Isolate* isolate) const {
4211 if (!maybe_map_.is_null()) {
4212 return maybe_map_.ToHandleChecked();
4213 } else if (maybe_prototype_.is_null()) {
4214 return is_strict(language_mode_)
4215 ? isolate->strict_function_without_prototype_map()
4216 : isolate->sloppy_function_without_prototype_map();
4217 } else {
4218 DCHECK(!maybe_prototype_.is_null());
4219 switch (prototype_mutability_) {
4220 case MUTABLE:
4221 return is_strict(language_mode_) ? isolate->strict_function_map()
4222 : isolate->sloppy_function_map();
4223 case IMMUTABLE:
4224 return is_strict(language_mode_)
4225 ? isolate->strict_function_with_readonly_prototype_map()
4226 : isolate->sloppy_function_with_readonly_prototype_map();
4227 }
4228 }
4229 UNREACHABLE();
4230 }
4231
4232 } // namespace internal
4233 } // namespace v8
4234