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