5 #include "src/compiler/js-create-lowering.h" 7 #include "src/code-factory.h" 8 #include "src/compiler/access-builder.h" 9 #include "src/compiler/allocation-builder-inl.h" 10 #include "src/compiler/common-operator.h" 11 #include "src/compiler/compilation-dependencies.h" 12 #include "src/compiler/js-graph.h" 13 #include "src/compiler/js-operator.h" 14 #include "src/compiler/linkage.h" 15 #include "src/compiler/node-matchers.h" 16 #include "src/compiler/node-properties.h" 17 #include "src/compiler/node.h" 18 #include "src/compiler/operator-properties.h" 19 #include "src/compiler/simplified-operator.h" 20 #include "src/compiler/state-values-utils.h" 21 #include "src/objects-inl.h" 22 #include "src/objects/arguments.h" 23 #include "src/objects/hash-table-inl.h" 24 #include "src/objects/js-generator.h" 25 #include "src/objects/js-promise.h" 26 #include "src/objects/js-regexp-inl.h" 35 Node* GetArgumentsFrameState(Node* frame_state) {
36 Node*
const outer_state = NodeProperties::GetFrameStateInput(frame_state);
37 FrameStateInfo outer_state_info = FrameStateInfoOf(outer_state->op());
38 return outer_state_info.type() == FrameStateType::kArgumentsAdaptor
45 bool IsAllocationInlineable(
const JSFunctionRef& target,
46 const JSFunctionRef& new_target) {
47 CHECK_IMPLIES(new_target.has_initial_map(),
48 !new_target.initial_map().is_dictionary_map());
49 return new_target.has_initial_map() &&
50 new_target.initial_map().GetConstructor().equals(target);
55 const int kElementLoopUnrollLimit = 16;
58 const int kFunctionContextAllocationLimit = 16;
59 const int kBlockContextAllocationLimit = 16;
63 Reduction JSCreateLowering::Reduce(Node* node) {
64 DisallowHeapAccess disallow_heap_access;
65 switch (node->opcode()) {
66 case IrOpcode::kJSCreate:
67 return ReduceJSCreate(node);
68 case IrOpcode::kJSCreateArguments:
69 return ReduceJSCreateArguments(node);
70 case IrOpcode::kJSCreateArray:
71 return ReduceJSCreateArray(node);
72 case IrOpcode::kJSCreateArrayIterator:
73 return ReduceJSCreateArrayIterator(node);
74 case IrOpcode::kJSCreateAsyncFunctionObject:
75 return ReduceJSCreateAsyncFunctionObject(node);
76 case IrOpcode::kJSCreateBoundFunction:
77 return ReduceJSCreateBoundFunction(node);
78 case IrOpcode::kJSCreateClosure:
79 return ReduceJSCreateClosure(node);
80 case IrOpcode::kJSCreateCollectionIterator:
81 return ReduceJSCreateCollectionIterator(node);
82 case IrOpcode::kJSCreateIterResultObject:
83 return ReduceJSCreateIterResultObject(node);
84 case IrOpcode::kJSCreateStringIterator:
85 return ReduceJSCreateStringIterator(node);
86 case IrOpcode::kJSCreateKeyValueArray:
87 return ReduceJSCreateKeyValueArray(node);
88 case IrOpcode::kJSCreatePromise:
89 return ReduceJSCreatePromise(node);
90 case IrOpcode::kJSCreateLiteralArray:
91 case IrOpcode::kJSCreateLiteralObject:
92 return ReduceJSCreateLiteralArrayOrObject(node);
93 case IrOpcode::kJSCreateLiteralRegExp:
94 return ReduceJSCreateLiteralRegExp(node);
95 case IrOpcode::kJSCreateEmptyLiteralArray:
96 return ReduceJSCreateEmptyLiteralArray(node);
97 case IrOpcode::kJSCreateEmptyLiteralObject:
98 return ReduceJSCreateEmptyLiteralObject(node);
99 case IrOpcode::kJSCreateFunctionContext:
100 return ReduceJSCreateFunctionContext(node);
101 case IrOpcode::kJSCreateWithContext:
102 return ReduceJSCreateWithContext(node);
103 case IrOpcode::kJSCreateCatchContext:
104 return ReduceJSCreateCatchContext(node);
105 case IrOpcode::kJSCreateBlockContext:
106 return ReduceJSCreateBlockContext(node);
107 case IrOpcode::kJSCreateGeneratorObject:
108 return ReduceJSCreateGeneratorObject(node);
109 case IrOpcode::kJSCreateObject:
110 return ReduceJSCreateObject(node);
117 Reduction JSCreateLowering::ReduceJSCreate(Node* node) {
118 DCHECK_EQ(IrOpcode::kJSCreate, node->opcode());
119 Node*
const target = NodeProperties::GetValueInput(node, 0);
120 Type const target_type = NodeProperties::GetType(target);
121 Node*
const new_target = NodeProperties::GetValueInput(node, 1);
122 Type const new_target_type = NodeProperties::GetType(new_target);
123 Node*
const effect = NodeProperties::GetEffectInput(node);
124 Node*
const control = NodeProperties::GetControlInput(node);
126 if (!target_type.IsHeapConstant() || !new_target_type.IsHeapConstant() ||
127 !target_type.AsHeapConstant()->Ref().IsJSFunction() ||
128 !new_target_type.AsHeapConstant()->Ref().IsJSFunction()) {
132 JSFunctionRef constructor =
133 target_type.AsHeapConstant()->Ref().AsJSFunction();
134 if (!constructor.map().is_constructor())
return NoChange();
135 JSFunctionRef original_constructor =
136 new_target_type.AsHeapConstant()->Ref().AsJSFunction();
137 if (!original_constructor.map().is_constructor())
return NoChange();
140 if (!IsAllocationInlineable(constructor, original_constructor)) {
144 SlackTrackingPrediction slack_tracking_prediction =
145 dependencies()->DependOnInitialMapInstanceSizePrediction(
146 original_constructor);
147 MapRef initial_map = original_constructor.initial_map();
151 AllocationBuilder a(jsgraph(), effect, control);
152 a.Allocate(slack_tracking_prediction.instance_size());
153 a.Store(AccessBuilder::ForMap(), initial_map);
154 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
155 jsgraph()->EmptyFixedArrayConstant());
156 a.Store(AccessBuilder::ForJSObjectElements(),
157 jsgraph()->EmptyFixedArrayConstant());
158 for (
int i = 0;
i < slack_tracking_prediction.inobject_property_count();
160 a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map,
i),
161 jsgraph()->UndefinedConstant());
165 a.FinishAndChange(node);
166 return Changed(node);
169 Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) {
170 DCHECK_EQ(IrOpcode::kJSCreateArguments, node->opcode());
171 CreateArgumentsType type = CreateArgumentsTypeOf(node->op());
172 Node*
const frame_state = NodeProperties::GetFrameStateInput(node);
173 Node*
const outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
174 Node*
const control = graph()->start();
175 FrameStateInfo state_info = FrameStateInfoOf(frame_state->op());
176 SharedFunctionInfoRef shared(broker(),
177 state_info.shared_info().ToHandleChecked());
181 if (outer_state->opcode() != IrOpcode::kFrameState) {
183 case CreateArgumentsType::kMappedArguments: {
185 if (shared.has_duplicate_parameters())
return NoChange();
186 Node*
const callee = NodeProperties::GetValueInput(node, 0);
187 Node*
const context = NodeProperties::GetContextInput(node);
188 Node* effect = NodeProperties::GetEffectInput(node);
189 Node*
const arguments_frame =
190 graph()->NewNode(simplified()->ArgumentsFrame());
191 Node*
const arguments_length = graph()->NewNode(
192 simplified()->ArgumentsLength(
193 shared.internal_formal_parameter_count(),
false),
196 bool has_aliased_arguments =
false;
197 Node*
const elements = effect = AllocateAliasedArguments(
198 effect, control, context, arguments_frame, arguments_length, shared,
199 &has_aliased_arguments);
201 Node*
const arguments_map = jsgraph()->Constant(
202 has_aliased_arguments
203 ? native_context().fast_aliased_arguments_map()
204 : native_context().sloppy_arguments_map());
206 AllocationBuilder a(jsgraph(), effect, control);
207 Node* properties = jsgraph()->EmptyFixedArrayConstant();
208 STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kPointerSize);
209 a.Allocate(JSSloppyArgumentsObject::kSize);
210 a.Store(AccessBuilder::ForMap(), arguments_map);
211 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
212 a.Store(AccessBuilder::ForJSObjectElements(), elements);
213 a.Store(AccessBuilder::ForArgumentsLength(), arguments_length);
214 a.Store(AccessBuilder::ForArgumentsCallee(), callee);
216 a.FinishAndChange(node);
217 return Changed(node);
219 case CreateArgumentsType::kUnmappedArguments: {
220 Node* effect = NodeProperties::GetEffectInput(node);
221 Node*
const arguments_frame =
222 graph()->NewNode(simplified()->ArgumentsFrame());
223 Node*
const arguments_length = graph()->NewNode(
224 simplified()->ArgumentsLength(
225 shared.internal_formal_parameter_count(),
false),
228 Node*
const elements = effect =
229 graph()->NewNode(simplified()->NewArgumentsElements(0),
230 arguments_frame, arguments_length, effect);
232 Node*
const arguments_map =
233 jsgraph()->Constant(native_context().strict_arguments_map());
235 AllocationBuilder a(jsgraph(), effect, control);
236 Node* properties = jsgraph()->EmptyFixedArrayConstant();
237 STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize);
238 a.Allocate(JSStrictArgumentsObject::kSize);
239 a.Store(AccessBuilder::ForMap(), arguments_map);
240 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
241 a.Store(AccessBuilder::ForJSObjectElements(), elements);
242 a.Store(AccessBuilder::ForArgumentsLength(), arguments_length);
244 a.FinishAndChange(node);
245 return Changed(node);
247 case CreateArgumentsType::kRestParameter: {
248 Node* effect = NodeProperties::GetEffectInput(node);
249 Node*
const arguments_frame =
250 graph()->NewNode(simplified()->ArgumentsFrame());
251 Node*
const rest_length = graph()->NewNode(
252 simplified()->ArgumentsLength(
253 shared.internal_formal_parameter_count(),
true),
258 Node*
const elements = effect =
259 graph()->NewNode(simplified()->NewArgumentsElements(0),
260 arguments_frame, rest_length, effect);
262 Node*
const jsarray_map = jsgraph()->Constant(
263 native_context().js_array_packed_elements_map());
265 AllocationBuilder a(jsgraph(), effect, control);
266 Node* properties = jsgraph()->EmptyFixedArrayConstant();
267 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
268 a.Allocate(JSArray::kSize);
269 a.Store(AccessBuilder::ForMap(), jsarray_map);
270 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
271 a.Store(AccessBuilder::ForJSObjectElements(), elements);
272 a.Store(AccessBuilder::ForJSArrayLength(PACKED_ELEMENTS), rest_length);
274 a.FinishAndChange(node);
275 return Changed(node);
279 }
else if (outer_state->opcode() == IrOpcode::kFrameState) {
282 if (type == CreateArgumentsType::kMappedArguments) {
283 Node*
const callee = NodeProperties::GetValueInput(node, 0);
284 Node*
const context = NodeProperties::GetContextInput(node);
285 Node* effect = NodeProperties::GetEffectInput(node);
287 if (shared.has_duplicate_parameters())
return NoChange();
291 Node*
const args_state = GetArgumentsFrameState(frame_state);
292 if (args_state->InputAt(kFrameStateParametersInput)->opcode() ==
293 IrOpcode::kDeadValue) {
299 FrameStateInfo args_state_info = FrameStateInfoOf(args_state->op());
301 bool has_aliased_arguments =
false;
302 Node*
const elements = AllocateAliasedArguments(
303 effect, control, args_state, context, shared, &has_aliased_arguments);
304 effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
306 Node*
const arguments_map = jsgraph()->Constant(
307 has_aliased_arguments ? native_context().fast_aliased_arguments_map()
308 : native_context().sloppy_arguments_map());
310 AllocationBuilder a(jsgraph(), effect, control);
311 Node* properties = jsgraph()->EmptyFixedArrayConstant();
312 int length = args_state_info.parameter_count() - 1;
313 STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kPointerSize);
314 a.Allocate(JSSloppyArgumentsObject::kSize);
315 a.Store(AccessBuilder::ForMap(), arguments_map);
316 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
317 a.Store(AccessBuilder::ForJSObjectElements(), elements);
318 a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length));
319 a.Store(AccessBuilder::ForArgumentsCallee(), callee);
321 a.FinishAndChange(node);
322 return Changed(node);
323 }
else if (type == CreateArgumentsType::kUnmappedArguments) {
326 Node* effect = NodeProperties::GetEffectInput(node);
330 Node*
const args_state = GetArgumentsFrameState(frame_state);
331 if (args_state->InputAt(kFrameStateParametersInput)->opcode() ==
332 IrOpcode::kDeadValue) {
338 FrameStateInfo args_state_info = FrameStateInfoOf(args_state->op());
340 Node*
const elements = AllocateArguments(effect, control, args_state);
341 effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
343 Node*
const arguments_map =
344 jsgraph()->Constant(native_context().strict_arguments_map());
346 AllocationBuilder a(jsgraph(), effect, control);
347 Node* properties = jsgraph()->EmptyFixedArrayConstant();
348 int length = args_state_info.parameter_count() - 1;
349 STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize);
350 a.Allocate(JSStrictArgumentsObject::kSize);
351 a.Store(AccessBuilder::ForMap(), arguments_map);
352 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
353 a.Store(AccessBuilder::ForJSObjectElements(), elements);
354 a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length));
356 a.FinishAndChange(node);
357 return Changed(node);
358 }
else if (type == CreateArgumentsType::kRestParameter) {
359 int start_index = shared.internal_formal_parameter_count();
362 Node* effect = NodeProperties::GetEffectInput(node);
366 Node*
const args_state = GetArgumentsFrameState(frame_state);
367 if (args_state->InputAt(kFrameStateParametersInput)->opcode() ==
368 IrOpcode::kDeadValue) {
374 FrameStateInfo args_state_info = FrameStateInfoOf(args_state->op());
376 Node*
const elements =
377 AllocateRestArguments(effect, control, args_state, start_index);
378 effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
380 Node*
const jsarray_map =
381 jsgraph()->Constant(native_context().js_array_packed_elements_map());
383 AllocationBuilder a(jsgraph(), effect, control);
384 Node* properties = jsgraph()->EmptyFixedArrayConstant();
387 int argument_count = args_state_info.parameter_count() - 1;
388 int length = std::max(0, argument_count - start_index);
389 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
390 a.Allocate(JSArray::kSize);
391 a.Store(AccessBuilder::ForMap(), jsarray_map);
392 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
393 a.Store(AccessBuilder::ForJSObjectElements(), elements);
394 a.Store(AccessBuilder::ForJSArrayLength(PACKED_ELEMENTS),
395 jsgraph()->Constant(length));
397 a.FinishAndChange(node);
398 return Changed(node);
405 Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
406 DCHECK_EQ(IrOpcode::kJSCreateGeneratorObject, node->opcode());
407 Node*
const closure = NodeProperties::GetValueInput(node, 0);
408 Node*
const receiver = NodeProperties::GetValueInput(node, 1);
409 Node*
const context = NodeProperties::GetContextInput(node);
410 Type const closure_type = NodeProperties::GetType(closure);
411 Node* effect = NodeProperties::GetEffectInput(node);
412 Node*
const control = NodeProperties::GetControlInput(node);
413 if (closure_type.IsHeapConstant()) {
414 DCHECK(closure_type.AsHeapConstant()->Ref().IsJSFunction());
415 JSFunctionRef js_function =
416 closure_type.AsHeapConstant()->Ref().AsJSFunction();
417 if (!js_function.has_initial_map())
return NoChange();
419 SlackTrackingPrediction slack_tracking_prediction =
420 dependencies()->DependOnInitialMapInstanceSizePrediction(js_function);
422 MapRef initial_map = js_function.initial_map();
423 DCHECK(initial_map.instance_type() == JS_GENERATOR_OBJECT_TYPE ||
424 initial_map.instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE);
427 SharedFunctionInfoRef shared = js_function.shared();
428 DCHECK(shared.HasBytecodeArray());
429 int parameter_count_no_receiver = shared.internal_formal_parameter_count();
430 int size = parameter_count_no_receiver +
431 shared.GetBytecodeArray().register_count();
432 AllocationBuilder ab(jsgraph(), effect, control);
433 ab.AllocateArray(size, factory()->fixed_array_map());
434 for (
int i = 0;
i < size; ++
i) {
435 ab.Store(AccessBuilder::ForFixedArraySlot(
i),
436 jsgraph()->UndefinedConstant());
438 Node* parameters_and_registers = effect = ab.Finish();
441 AllocationBuilder a(jsgraph(), effect, control);
442 a.Allocate(slack_tracking_prediction.instance_size());
443 Node* empty_fixed_array = jsgraph()->EmptyFixedArrayConstant();
444 Node* undefined = jsgraph()->UndefinedConstant();
445 a.Store(AccessBuilder::ForMap(), initial_map);
446 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), empty_fixed_array);
447 a.Store(AccessBuilder::ForJSObjectElements(), empty_fixed_array);
448 a.Store(AccessBuilder::ForJSGeneratorObjectContext(), context);
449 a.Store(AccessBuilder::ForJSGeneratorObjectFunction(), closure);
450 a.Store(AccessBuilder::ForJSGeneratorObjectReceiver(), receiver);
451 a.Store(AccessBuilder::ForJSGeneratorObjectInputOrDebugPos(), undefined);
452 a.Store(AccessBuilder::ForJSGeneratorObjectResumeMode(),
453 jsgraph()->Constant(JSGeneratorObject::kNext));
454 a.Store(AccessBuilder::ForJSGeneratorObjectContinuation(),
455 jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting));
456 a.Store(AccessBuilder::ForJSGeneratorObjectParametersAndRegisters(),
457 parameters_and_registers);
459 if (initial_map.instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE) {
460 a.Store(AccessBuilder::ForJSAsyncGeneratorObjectQueue(), undefined);
461 a.Store(AccessBuilder::ForJSAsyncGeneratorObjectIsAwaiting(),
462 jsgraph()->ZeroConstant());
466 for (
int i = 0;
i < slack_tracking_prediction.inobject_property_count();
468 a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map,
i),
471 a.FinishAndChange(node);
472 return Changed(node);
479 Reduction JSCreateLowering::ReduceNewArray(
480 Node* node, Node* length, MapRef initial_map, ElementsKind elements_kind,
481 PretenureFlag pretenure,
482 const SlackTrackingPrediction& slack_tracking_prediction) {
483 DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
484 Node* effect = NodeProperties::GetEffectInput(node);
485 Node* control = NodeProperties::GetControlInput(node);
489 ASSIGN_RETURN_NO_CHANGE_IF_DATA_MISSING(
491 initial_map.AsElementsKind(GetHoleyElementsKind(elements_kind)));
496 length = effect = graph()->NewNode(
497 simplified()->CheckBounds(VectorSlotPair()), length,
498 jsgraph()->Constant(JSArray::kInitialMaxFastElementArray), effect,
502 Node* elements = effect =
503 graph()->NewNode(IsDoubleElementsKind(initial_map.elements_kind())
504 ? simplified()->NewDoubleElements(pretenure)
505 : simplified()->NewSmiOrObjectElements(pretenure),
506 length, effect, control);
507 Node* properties = jsgraph()->EmptyFixedArrayConstant();
510 AllocationBuilder a(jsgraph(), effect, control);
511 a.Allocate(slack_tracking_prediction.instance_size(), pretenure);
512 a.Store(AccessBuilder::ForMap(), initial_map);
513 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
514 a.Store(AccessBuilder::ForJSObjectElements(), elements);
515 a.Store(AccessBuilder::ForJSArrayLength(initial_map.elements_kind()), length);
516 for (
int i = 0;
i < slack_tracking_prediction.inobject_property_count();
518 a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map,
i),
519 jsgraph()->UndefinedConstant());
522 a.FinishAndChange(node);
523 return Changed(node);
528 Reduction JSCreateLowering::ReduceNewArray(
529 Node* node, Node* length,
int capacity, MapRef initial_map,
530 ElementsKind elements_kind, PretenureFlag pretenure,
531 const SlackTrackingPrediction& slack_tracking_prediction) {
532 DCHECK(node->opcode() == IrOpcode::kJSCreateArray ||
533 node->opcode() == IrOpcode::kJSCreateEmptyLiteralArray);
534 Node* effect = NodeProperties::GetEffectInput(node);
535 Node* control = NodeProperties::GetControlInput(node);
538 if (NodeProperties::GetType(length).Max() > 0.0) {
539 elements_kind = GetHoleyElementsKind(elements_kind);
541 ASSIGN_RETURN_NO_CHANGE_IF_DATA_MISSING(
542 initial_map, initial_map.AsElementsKind(elements_kind));
543 DCHECK(IsFastElementsKind(elements_kind));
548 elements = jsgraph()->EmptyFixedArrayConstant();
551 AllocateElements(effect, control, elements_kind, capacity, pretenure);
553 Node* properties = jsgraph()->EmptyFixedArrayConstant();
556 AllocationBuilder a(jsgraph(), effect, control);
557 a.Allocate(slack_tracking_prediction.instance_size(), pretenure);
558 a.Store(AccessBuilder::ForMap(), initial_map);
559 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
560 a.Store(AccessBuilder::ForJSObjectElements(), elements);
561 a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
562 for (
int i = 0;
i < slack_tracking_prediction.inobject_property_count();
564 a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map,
i),
565 jsgraph()->UndefinedConstant());
568 a.FinishAndChange(node);
569 return Changed(node);
572 Reduction JSCreateLowering::ReduceNewArray(
573 Node* node, std::vector<Node*> values, MapRef initial_map,
574 ElementsKind elements_kind, PretenureFlag pretenure,
575 const SlackTrackingPrediction& slack_tracking_prediction) {
576 DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
577 Node* effect = NodeProperties::GetEffectInput(node);
578 Node* control = NodeProperties::GetControlInput(node);
581 DCHECK(IsFastElementsKind(elements_kind));
582 ASSIGN_RETURN_NO_CHANGE_IF_DATA_MISSING(
583 initial_map, initial_map.AsElementsKind(elements_kind));
588 if (IsSmiElementsKind(elements_kind)) {
589 for (
auto& value : values) {
590 if (!NodeProperties::GetType(value).Is(Type::SignedSmall())) {
591 value = effect = graph()->NewNode(
592 simplified()->CheckSmi(VectorSlotPair()), value, effect, control);
595 }
else if (IsDoubleElementsKind(elements_kind)) {
596 for (
auto& value : values) {
597 if (!NodeProperties::GetType(value).Is(Type::Number())) {
599 graph()->NewNode(simplified()->CheckNumber(VectorSlotPair()), value,
603 value = graph()->NewNode(simplified()->NumberSilenceNaN(), value);
608 Node* elements = effect =
609 AllocateElements(effect, control, elements_kind, values, pretenure);
610 Node* properties = jsgraph()->EmptyFixedArrayConstant();
611 Node* length = jsgraph()->Constant(static_cast<int>(values.size()));
614 AllocationBuilder a(jsgraph(), effect, control);
615 a.Allocate(slack_tracking_prediction.instance_size(), pretenure);
616 a.Store(AccessBuilder::ForMap(), initial_map);
617 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
618 a.Store(AccessBuilder::ForJSObjectElements(), elements);
619 a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
620 for (
int i = 0;
i < slack_tracking_prediction.inobject_property_count();
622 a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map,
i),
623 jsgraph()->UndefinedConstant());
626 a.FinishAndChange(node);
627 return Changed(node);
630 Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) {
631 DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
632 CreateArrayParameters
const& p = CreateArrayParametersOf(node->op());
633 int const arity =
static_cast<int>(p.arity());
634 base::Optional<AllocationSiteRef> site_ref;
636 Handle<AllocationSite> site;
637 if (p.site().ToHandle(&site)) {
638 site_ref = AllocationSiteRef(broker(), site);
641 PretenureFlag pretenure = NOT_TENURED;
642 JSFunctionRef constructor = native_context().array_function();
643 Node* target = NodeProperties::GetValueInput(node, 0);
644 Node* new_target = NodeProperties::GetValueInput(node, 1);
645 Type new_target_type = (target == new_target)
646 ? Type::HeapConstant(constructor, zone())
647 : NodeProperties::GetType(new_target);
650 if (new_target_type.IsHeapConstant() &&
651 new_target_type.AsHeapConstant()->Ref().IsJSFunction()) {
652 JSFunctionRef original_constructor =
653 new_target_type.AsHeapConstant()->Ref().AsJSFunction();
654 DCHECK(constructor.map().is_constructor());
655 DCHECK(original_constructor.map().is_constructor());
658 if (IsAllocationInlineable(constructor, original_constructor)) {
659 SlackTrackingPrediction slack_tracking_prediction =
660 dependencies()->DependOnInitialMapInstanceSizePrediction(
661 original_constructor);
662 MapRef initial_map = original_constructor.initial_map();
666 bool can_inline_call =
false;
669 ElementsKind elements_kind = initial_map.elements_kind();
671 elements_kind = site_ref->GetElementsKind();
672 can_inline_call = site_ref->CanInlineCall();
673 pretenure = dependencies()->DependOnPretenureMode(*site_ref);
674 dependencies()->DependOnElementsKind(*site_ref);
676 CellRef array_constructor_protector(
677 broker(), factory()->array_constructor_protector());
678 can_inline_call = array_constructor_protector.value().AsSmi() ==
679 Isolate::kProtectorValid;
683 Node* length = jsgraph()->ZeroConstant();
684 int capacity = JSArray::kPreallocatedArrayElements;
685 return ReduceNewArray(node, length, capacity, initial_map,
686 elements_kind, pretenure,
687 slack_tracking_prediction);
688 }
else if (arity == 1) {
689 Node* length = NodeProperties::GetValueInput(node, 2);
690 Type length_type = NodeProperties::GetType(length);
691 if (!length_type.Maybe(Type::Number())) {
694 elements_kind = GetMoreGeneralElementsKind(
695 elements_kind, IsHoleyElementsKind(elements_kind)
698 return ReduceNewArray(node, std::vector<Node*>{length}, initial_map,
699 elements_kind, pretenure,
700 slack_tracking_prediction);
702 if (length_type.Is(Type::SignedSmall()) && length_type.Min() >= 0 &&
703 length_type.Max() <= kElementLoopUnrollLimit &&
704 length_type.Min() == length_type.Max()) {
705 int capacity =
static_cast<int>(length_type.Max());
706 return ReduceNewArray(node, length, capacity, initial_map,
707 elements_kind, pretenure,
708 slack_tracking_prediction);
710 if (length_type.Maybe(Type::UnsignedSmall()) && can_inline_call) {
711 return ReduceNewArray(node, length, initial_map, elements_kind,
712 pretenure, slack_tracking_prediction);
714 }
else if (arity <= JSArray::kInitialMaxFastElementArray) {
716 bool values_all_smis =
true, values_all_numbers =
true,
717 values_any_nonnumber =
false;
718 std::vector<Node*> values;
719 values.reserve(p.arity());
720 for (
int i = 0;
i < arity; ++
i) {
721 Node* value = NodeProperties::GetValueInput(node, 2 +
i);
722 Type value_type = NodeProperties::GetType(value);
723 if (!value_type.Is(Type::SignedSmall())) {
724 values_all_smis =
false;
726 if (!value_type.Is(Type::Number())) {
727 values_all_numbers =
false;
729 if (!value_type.Maybe(Type::Number())) {
730 values_any_nonnumber =
true;
732 values.push_back(value);
736 if (values_all_smis) {
738 }
else if (values_all_numbers) {
739 elements_kind = GetMoreGeneralElementsKind(
740 elements_kind, IsHoleyElementsKind(elements_kind)
741 ? HOLEY_DOUBLE_ELEMENTS
742 : PACKED_DOUBLE_ELEMENTS);
743 }
else if (values_any_nonnumber) {
744 elements_kind = GetMoreGeneralElementsKind(
745 elements_kind, IsHoleyElementsKind(elements_kind)
748 }
else if (!can_inline_call) {
756 return ReduceNewArray(node, values, initial_map, elements_kind,
757 pretenure, slack_tracking_prediction);
764 Reduction JSCreateLowering::ReduceJSCreateArrayIterator(Node* node) {
765 DCHECK_EQ(IrOpcode::kJSCreateArrayIterator, node->opcode());
766 CreateArrayIteratorParameters
const& p =
767 CreateArrayIteratorParametersOf(node->op());
768 Node* iterated_object = NodeProperties::GetValueInput(node, 0);
769 Node* effect = NodeProperties::GetEffectInput(node);
770 Node* control = NodeProperties::GetControlInput(node);
773 AllocationBuilder a(jsgraph(), effect, control);
774 a.Allocate(JSArrayIterator::kSize, NOT_TENURED, Type::OtherObject());
775 a.Store(AccessBuilder::ForMap(),
776 native_context().initial_array_iterator_map());
777 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
778 jsgraph()->EmptyFixedArrayConstant());
779 a.Store(AccessBuilder::ForJSObjectElements(),
780 jsgraph()->EmptyFixedArrayConstant());
781 a.Store(AccessBuilder::ForJSArrayIteratorIteratedObject(), iterated_object);
782 a.Store(AccessBuilder::ForJSArrayIteratorNextIndex(),
783 jsgraph()->ZeroConstant());
784 a.Store(AccessBuilder::ForJSArrayIteratorKind(),
785 jsgraph()->Constant(static_cast<int>(p.kind())));
787 a.FinishAndChange(node);
788 return Changed(node);
791 Reduction JSCreateLowering::ReduceJSCreateAsyncFunctionObject(Node* node) {
792 DCHECK_EQ(IrOpcode::kJSCreateAsyncFunctionObject, node->opcode());
793 int const register_count = RegisterCountOf(node->op());
794 Node* closure = NodeProperties::GetValueInput(node, 0);
795 Node* receiver = NodeProperties::GetValueInput(node, 1);
796 Node* promise = NodeProperties::GetValueInput(node, 2);
797 Node* context = NodeProperties::GetContextInput(node);
798 Node* effect = NodeProperties::GetEffectInput(node);
799 Node* control = NodeProperties::GetControlInput(node);
802 AllocationBuilder ab(jsgraph(), effect, control);
803 ab.AllocateArray(register_count, factory()->fixed_array_map());
804 for (
int i = 0;
i < register_count; ++
i) {
805 ab.Store(AccessBuilder::ForFixedArraySlot(
i),
806 jsgraph()->UndefinedConstant());
808 Node* parameters_and_registers = effect = ab.Finish();
811 AllocationBuilder a(jsgraph(), effect, control);
812 a.Allocate(JSAsyncFunctionObject::kSize);
813 Node* empty_fixed_array = jsgraph()->EmptyFixedArrayConstant();
814 a.Store(AccessBuilder::ForMap(),
815 native_context().async_function_object_map());
816 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), empty_fixed_array);
817 a.Store(AccessBuilder::ForJSObjectElements(), empty_fixed_array);
818 a.Store(AccessBuilder::ForJSGeneratorObjectContext(), context);
819 a.Store(AccessBuilder::ForJSGeneratorObjectFunction(), closure);
820 a.Store(AccessBuilder::ForJSGeneratorObjectReceiver(), receiver);
821 a.Store(AccessBuilder::ForJSGeneratorObjectInputOrDebugPos(),
822 jsgraph()->UndefinedConstant());
823 a.Store(AccessBuilder::ForJSGeneratorObjectResumeMode(),
824 jsgraph()->Constant(JSGeneratorObject::kNext));
825 a.Store(AccessBuilder::ForJSGeneratorObjectContinuation(),
826 jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting));
827 a.Store(AccessBuilder::ForJSGeneratorObjectParametersAndRegisters(),
828 parameters_and_registers);
829 a.Store(AccessBuilder::ForJSAsyncFunctionObjectPromise(), promise);
830 a.FinishAndChange(node);
831 return Changed(node);
836 MapRef MapForCollectionIterationKind(
const NativeContextRef& native_context,
837 CollectionKind collection_kind,
838 IterationKind iteration_kind) {
839 switch (collection_kind) {
840 case CollectionKind::kSet:
841 switch (iteration_kind) {
842 case IterationKind::kKeys:
844 case IterationKind::kValues:
845 return native_context.set_value_iterator_map();
846 case IterationKind::kEntries:
847 return native_context.set_key_value_iterator_map();
850 case CollectionKind::kMap:
851 switch (iteration_kind) {
852 case IterationKind::kKeys:
853 return native_context.map_key_iterator_map();
854 case IterationKind::kValues:
855 return native_context.map_value_iterator_map();
856 case IterationKind::kEntries:
857 return native_context.map_key_value_iterator_map();
866 Reduction JSCreateLowering::ReduceJSCreateCollectionIterator(Node* node) {
867 DCHECK_EQ(IrOpcode::kJSCreateCollectionIterator, node->opcode());
868 CreateCollectionIteratorParameters
const& p =
869 CreateCollectionIteratorParametersOf(node->op());
870 Node* iterated_object = NodeProperties::GetValueInput(node, 0);
871 Node* effect = NodeProperties::GetEffectInput(node);
872 Node* control = NodeProperties::GetControlInput(node);
875 Node* table = effect = graph()->NewNode(
876 simplified()->LoadField(AccessBuilder::ForJSCollectionTable()),
877 iterated_object, effect, control);
880 AllocationBuilder a(jsgraph(), effect, control);
881 a.Allocate(JSCollectionIterator::kSize, NOT_TENURED, Type::OtherObject());
882 a.Store(AccessBuilder::ForMap(),
883 MapForCollectionIterationKind(native_context(), p.collection_kind(),
884 p.iteration_kind()));
885 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
886 jsgraph()->EmptyFixedArrayConstant());
887 a.Store(AccessBuilder::ForJSObjectElements(),
888 jsgraph()->EmptyFixedArrayConstant());
889 a.Store(AccessBuilder::ForJSCollectionIteratorTable(), table);
890 a.Store(AccessBuilder::ForJSCollectionIteratorIndex(),
891 jsgraph()->ZeroConstant());
893 a.FinishAndChange(node);
894 return Changed(node);
897 Reduction JSCreateLowering::ReduceJSCreateBoundFunction(Node* node) {
898 DCHECK_EQ(IrOpcode::kJSCreateBoundFunction, node->opcode());
899 CreateBoundFunctionParameters
const& p =
900 CreateBoundFunctionParametersOf(node->op());
901 int const arity =
static_cast<int>(p.arity());
902 MapRef
const map(broker(), p.map());
903 Node* bound_target_function = NodeProperties::GetValueInput(node, 0);
904 Node* bound_this = NodeProperties::GetValueInput(node, 1);
905 Node* effect = NodeProperties::GetEffectInput(node);
906 Node* control = NodeProperties::GetControlInput(node);
909 Node* bound_arguments = jsgraph()->EmptyFixedArrayConstant();
911 AllocationBuilder a(jsgraph(), effect, control);
912 a.AllocateArray(arity, factory()->fixed_array_map());
913 for (
int i = 0;
i < arity; ++
i) {
914 a.Store(AccessBuilder::ForFixedArraySlot(
i),
915 NodeProperties::GetValueInput(node, 2 +
i));
917 bound_arguments = effect = a.Finish();
921 AllocationBuilder a(jsgraph(), effect, control);
922 a.Allocate(JSBoundFunction::kSize, NOT_TENURED, Type::BoundFunction());
923 a.Store(AccessBuilder::ForMap(), map);
924 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
925 jsgraph()->EmptyFixedArrayConstant());
926 a.Store(AccessBuilder::ForJSObjectElements(),
927 jsgraph()->EmptyFixedArrayConstant());
928 a.Store(AccessBuilder::ForJSBoundFunctionBoundTargetFunction(),
929 bound_target_function);
930 a.Store(AccessBuilder::ForJSBoundFunctionBoundThis(), bound_this);
931 a.Store(AccessBuilder::ForJSBoundFunctionBoundArguments(), bound_arguments);
933 a.FinishAndChange(node);
934 return Changed(node);
937 Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
938 DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode());
939 CreateClosureParameters
const& p = CreateClosureParametersOf(node->op());
940 SharedFunctionInfoRef shared(broker(), p.shared_info());
941 HeapObjectRef feedback_cell(broker(), p.feedback_cell());
942 HeapObjectRef code(broker(), p.code());
943 Node* effect = NodeProperties::GetEffectInput(node);
944 Node* control = NodeProperties::GetControlInput(node);
945 Node* context = NodeProperties::GetContextInput(node);
950 if (!feedback_cell.map().equals(
951 MapRef(broker(), factory()->many_closures_cell_map()))) {
955 MapRef function_map =
956 native_context().GetFunctionMapFromIndex(shared.function_map_index());
957 DCHECK(!function_map.IsInobjectSlackTrackingInProgress());
958 DCHECK(!function_map.is_dictionary_map());
969 PretenureFlag pretenure = NOT_TENURED;
972 STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kPointerSize);
973 AllocationBuilder a(jsgraph(), effect, control);
974 a.Allocate(function_map.instance_size(), pretenure, Type::Function());
975 a.Store(AccessBuilder::ForMap(), function_map);
976 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
977 jsgraph()->EmptyFixedArrayConstant());
978 a.Store(AccessBuilder::ForJSObjectElements(),
979 jsgraph()->EmptyFixedArrayConstant());
980 a.Store(AccessBuilder::ForJSFunctionSharedFunctionInfo(), shared);
981 a.Store(AccessBuilder::ForJSFunctionContext(), context);
982 a.Store(AccessBuilder::ForJSFunctionFeedbackCell(), feedback_cell);
983 a.Store(AccessBuilder::ForJSFunctionCode(), code);
984 STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kPointerSize);
985 if (function_map.has_prototype_slot()) {
986 a.Store(AccessBuilder::ForJSFunctionPrototypeOrInitialMap(),
987 jsgraph()->TheHoleConstant());
988 STATIC_ASSERT(JSFunction::kSizeWithPrototype == 8 * kPointerSize);
990 for (
int i = 0;
i < function_map.GetInObjectProperties();
i++) {
991 a.Store(AccessBuilder::ForJSObjectInObjectProperty(function_map,
i),
992 jsgraph()->UndefinedConstant());
995 a.FinishAndChange(node);
996 return Changed(node);
999 Reduction JSCreateLowering::ReduceJSCreateIterResultObject(Node* node) {
1000 DCHECK_EQ(IrOpcode::kJSCreateIterResultObject, node->opcode());
1001 Node* value = NodeProperties::GetValueInput(node, 0);
1002 Node* done = NodeProperties::GetValueInput(node, 1);
1003 Node* effect = NodeProperties::GetEffectInput(node);
1005 Node* iterator_result_map =
1006 jsgraph()->Constant(native_context().iterator_result_map());
1009 AllocationBuilder a(jsgraph(), effect, graph()->start());
1010 a.Allocate(JSIteratorResult::kSize);
1011 a.Store(AccessBuilder::ForMap(), iterator_result_map);
1012 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
1013 jsgraph()->EmptyFixedArrayConstant());
1014 a.Store(AccessBuilder::ForJSObjectElements(),
1015 jsgraph()->EmptyFixedArrayConstant());
1016 a.Store(AccessBuilder::ForJSIteratorResultValue(), value);
1017 a.Store(AccessBuilder::ForJSIteratorResultDone(), done);
1018 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
1019 a.FinishAndChange(node);
1020 return Changed(node);
1023 Reduction JSCreateLowering::ReduceJSCreateStringIterator(Node* node) {
1024 DCHECK_EQ(IrOpcode::kJSCreateStringIterator, node->opcode());
1025 Node*
string = NodeProperties::GetValueInput(node, 0);
1026 Node* effect = NodeProperties::GetEffectInput(node);
1029 jsgraph()->Constant(native_context().initial_string_iterator_map());
1031 AllocationBuilder a(jsgraph(), effect, graph()->start());
1032 a.Allocate(JSStringIterator::kSize, NOT_TENURED, Type::OtherObject());
1033 a.Store(AccessBuilder::ForMap(), map);
1034 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
1035 jsgraph()->EmptyFixedArrayConstant());
1036 a.Store(AccessBuilder::ForJSObjectElements(),
1037 jsgraph()->EmptyFixedArrayConstant());
1038 a.Store(AccessBuilder::ForJSStringIteratorString(),
string);
1039 a.Store(AccessBuilder::ForJSStringIteratorIndex(), jsgraph()->SmiConstant(0));
1040 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize);
1041 a.FinishAndChange(node);
1042 return Changed(node);
1045 Reduction JSCreateLowering::ReduceJSCreateKeyValueArray(Node* node) {
1046 DCHECK_EQ(IrOpcode::kJSCreateKeyValueArray, node->opcode());
1047 Node* key = NodeProperties::GetValueInput(node, 0);
1048 Node* value = NodeProperties::GetValueInput(node, 1);
1049 Node* effect = NodeProperties::GetEffectInput(node);
1052 jsgraph()->Constant(native_context().js_array_packed_elements_map());
1053 Node* properties = jsgraph()->EmptyFixedArrayConstant();
1054 Node* length = jsgraph()->Constant(2);
1056 AllocationBuilder aa(jsgraph(), effect, graph()->start());
1057 aa.AllocateArray(2, factory()->fixed_array_map());
1058 aa.Store(AccessBuilder::ForFixedArrayElement(PACKED_ELEMENTS),
1059 jsgraph()->ZeroConstant(), key);
1060 aa.Store(AccessBuilder::ForFixedArrayElement(PACKED_ELEMENTS),
1061 jsgraph()->OneConstant(), value);
1062 Node* elements = aa.Finish();
1064 AllocationBuilder a(jsgraph(), elements, graph()->start());
1065 a.Allocate(JSArray::kSize);
1066 a.Store(AccessBuilder::ForMap(), array_map);
1067 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
1068 a.Store(AccessBuilder::ForJSObjectElements(), elements);
1069 a.Store(AccessBuilder::ForJSArrayLength(PACKED_ELEMENTS), length);
1070 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
1071 a.FinishAndChange(node);
1072 return Changed(node);
1075 Reduction JSCreateLowering::ReduceJSCreatePromise(Node* node) {
1076 DCHECK_EQ(IrOpcode::kJSCreatePromise, node->opcode());
1077 Node* effect = NodeProperties::GetEffectInput(node);
1079 MapRef promise_map = native_context().promise_function().initial_map();
1081 AllocationBuilder a(jsgraph(), effect, graph()->start());
1082 a.Allocate(promise_map.instance_size());
1083 a.Store(AccessBuilder::ForMap(), promise_map);
1084 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
1085 jsgraph()->EmptyFixedArrayConstant());
1086 a.Store(AccessBuilder::ForJSObjectElements(),
1087 jsgraph()->EmptyFixedArrayConstant());
1088 a.Store(AccessBuilder::ForJSObjectOffset(JSPromise::kReactionsOrResultOffset),
1089 jsgraph()->ZeroConstant());
1090 STATIC_ASSERT(v8::Promise::kPending == 0);
1091 a.Store(AccessBuilder::ForJSObjectOffset(JSPromise::kFlagsOffset),
1092 jsgraph()->ZeroConstant());
1093 STATIC_ASSERT(JSPromise::kSize == 5 * kPointerSize);
1094 for (
int offset = JSPromise::kSize;
1095 offset < JSPromise::kSizeWithEmbedderFields; offset += kTaggedSize) {
1096 a.Store(AccessBuilder::ForJSObjectOffset(offset),
1097 jsgraph()->ZeroConstant());
1099 a.FinishAndChange(node);
1100 return Changed(node);
1103 Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
1104 DCHECK(node->opcode() == IrOpcode::kJSCreateLiteralArray ||
1105 node->opcode() == IrOpcode::kJSCreateLiteralObject);
1106 CreateLiteralParameters
const& p = CreateLiteralParametersOf(node->op());
1107 Node* effect = NodeProperties::GetEffectInput(node);
1108 Node* control = NodeProperties::GetControlInput(node);
1110 FeedbackVectorRef feedback_vector(broker(), p.feedback().vector());
1111 ObjectRef feedback = feedback_vector.get(p.feedback().slot());
1112 if (feedback.IsAllocationSite()) {
1113 AllocationSiteRef site = feedback.AsAllocationSite();
1114 if (site.IsFastLiteral()) {
1115 PretenureFlag pretenure = NOT_TENURED;
1116 if (FLAG_allocation_site_pretenuring) {
1117 pretenure = dependencies()->DependOnPretenureMode(site);
1119 dependencies()->DependOnElementsKinds(site);
1120 JSObjectRef boilerplate = site.boilerplate().value();
1121 Node* value = effect =
1122 AllocateFastLiteral(effect, control, boilerplate, pretenure);
1123 ReplaceWithValue(node, value, effect, control);
1124 return Replace(value);
1130 Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) {
1131 DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralArray, node->opcode());
1132 FeedbackParameter
const& p = FeedbackParameterOf(node->op());
1133 FeedbackVectorRef fv(broker(), p.feedback().vector());
1134 ObjectRef feedback = fv.get(p.feedback().slot());
1135 if (feedback.IsAllocationSite()) {
1136 AllocationSiteRef site = feedback.AsAllocationSite();
1137 DCHECK(!site.PointsToLiteral());
1138 MapRef initial_map =
1139 native_context().GetInitialJSArrayMap(site.GetElementsKind());
1140 PretenureFlag
const pretenure = dependencies()->DependOnPretenureMode(site);
1141 dependencies()->DependOnElementsKind(site);
1142 Node* length = jsgraph()->ZeroConstant();
1143 DCHECK(!initial_map.IsInobjectSlackTrackingInProgress());
1144 SlackTrackingPrediction slack_tracking_prediction(
1145 initial_map, initial_map.instance_size());
1146 return ReduceNewArray(node, length, 0, initial_map,
1147 initial_map.elements_kind(), pretenure,
1148 slack_tracking_prediction);
1153 Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralObject(Node* node) {
1154 DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralObject, node->opcode());
1155 Node* effect = NodeProperties::GetEffectInput(node);
1156 Node* control = NodeProperties::GetControlInput(node);
1159 MapRef map = native_context().object_function().initial_map();
1160 DCHECK(!map.is_dictionary_map());
1161 DCHECK(!map.IsInobjectSlackTrackingInProgress());
1162 Node* js_object_map = jsgraph()->Constant(map);
1165 Node* elements = jsgraph()->EmptyFixedArrayConstant();
1166 Node* properties = jsgraph()->EmptyFixedArrayConstant();
1169 AllocationBuilder a(jsgraph(), effect, control);
1170 a.Allocate(map.instance_size());
1171 a.Store(AccessBuilder::ForMap(), js_object_map);
1172 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
1173 a.Store(AccessBuilder::ForJSObjectElements(), elements);
1174 for (
int i = 0;
i < map.GetInObjectProperties();
i++) {
1175 a.Store(AccessBuilder::ForJSObjectInObjectProperty(map,
i),
1176 jsgraph()->UndefinedConstant());
1179 RelaxControls(node);
1180 a.FinishAndChange(node);
1181 return Changed(node);
1184 Reduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) {
1185 DCHECK_EQ(IrOpcode::kJSCreateLiteralRegExp, node->opcode());
1186 CreateLiteralParameters
const& p = CreateLiteralParametersOf(node->op());
1187 Node* effect = NodeProperties::GetEffectInput(node);
1188 Node* control = NodeProperties::GetControlInput(node);
1190 FeedbackVectorRef feedback_vector(broker(), p.feedback().vector());
1191 ObjectRef feedback = feedback_vector.get(p.feedback().slot());
1192 if (feedback.IsJSRegExp()) {
1193 JSRegExpRef boilerplate = feedback.AsJSRegExp();
1194 Node* value = effect = AllocateLiteralRegExp(effect, control, boilerplate);
1195 ReplaceWithValue(node, value, effect, control);
1196 return Replace(value);
1201 Reduction JSCreateLowering::ReduceJSCreateFunctionContext(Node* node) {
1202 DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode());
1203 const CreateFunctionContextParameters& parameters =
1204 CreateFunctionContextParametersOf(node->op());
1205 ScopeInfoRef scope_info(broker(), parameters.scope_info());
1206 int slot_count = parameters.slot_count();
1207 ScopeType scope_type = parameters.scope_type();
1210 if (slot_count < kFunctionContextAllocationLimit) {
1212 Node* effect = NodeProperties::GetEffectInput(node);
1213 Node* control = NodeProperties::GetControlInput(node);
1214 Node* context = NodeProperties::GetContextInput(node);
1215 Node* extension = jsgraph()->TheHoleConstant();
1216 AllocationBuilder a(jsgraph(), effect, control);
1217 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);
1218 int context_length = slot_count + Context::MIN_CONTEXT_SLOTS;
1220 switch (scope_type) {
1222 map = factory()->eval_context_map();
1224 case FUNCTION_SCOPE:
1225 map = factory()->function_context_map();
1230 a.AllocateContext(context_length, map);
1231 a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX),
1233 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
1234 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
1235 a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
1236 jsgraph()->Constant(native_context()));
1237 for (
int i = Context::MIN_CONTEXT_SLOTS;
i < context_length; ++
i) {
1238 a.Store(AccessBuilder::ForContextSlot(
i), jsgraph()->UndefinedConstant());
1240 RelaxControls(node);
1241 a.FinishAndChange(node);
1242 return Changed(node);
1248 Reduction JSCreateLowering::ReduceJSCreateWithContext(Node* node) {
1249 DCHECK_EQ(IrOpcode::kJSCreateWithContext, node->opcode());
1250 ScopeInfoRef scope_info(broker(), ScopeInfoOf(node->op()));
1251 Node* extension = NodeProperties::GetValueInput(node, 0);
1252 Node* effect = NodeProperties::GetEffectInput(node);
1253 Node* control = NodeProperties::GetControlInput(node);
1254 Node* context = NodeProperties::GetContextInput(node);
1256 AllocationBuilder a(jsgraph(), effect, control);
1257 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);
1258 a.AllocateContext(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map());
1259 a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX), scope_info);
1260 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
1261 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
1262 a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
1263 jsgraph()->Constant(native_context()));
1264 RelaxControls(node);
1265 a.FinishAndChange(node);
1266 return Changed(node);
1269 Reduction JSCreateLowering::ReduceJSCreateCatchContext(Node* node) {
1270 DCHECK_EQ(IrOpcode::kJSCreateCatchContext, node->opcode());
1271 ScopeInfoRef scope_info(broker(), ScopeInfoOf(node->op()));
1272 Node* exception = NodeProperties::GetValueInput(node, 0);
1273 Node* effect = NodeProperties::GetEffectInput(node);
1274 Node* control = NodeProperties::GetControlInput(node);
1275 Node* context = NodeProperties::GetContextInput(node);
1276 Node* extension = jsgraph()->TheHoleConstant();
1278 AllocationBuilder a(jsgraph(), effect, control);
1279 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);
1280 a.AllocateContext(Context::MIN_CONTEXT_SLOTS + 1,
1281 factory()->catch_context_map());
1282 a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX), scope_info);
1283 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
1284 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
1285 a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
1286 jsgraph()->Constant(native_context()));
1287 a.Store(AccessBuilder::ForContextSlot(Context::THROWN_OBJECT_INDEX),
1289 RelaxControls(node);
1290 a.FinishAndChange(node);
1291 return Changed(node);
1294 Reduction JSCreateLowering::ReduceJSCreateBlockContext(Node* node) {
1295 DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode());
1296 ScopeInfoRef scope_info(broker(), ScopeInfoOf(node->op()));
1297 int const context_length = scope_info.ContextLength();
1300 if (context_length < kBlockContextAllocationLimit) {
1302 Node* effect = NodeProperties::GetEffectInput(node);
1303 Node* control = NodeProperties::GetControlInput(node);
1304 Node* context = NodeProperties::GetContextInput(node);
1305 Node* extension = jsgraph()->TheHoleConstant();
1307 AllocationBuilder a(jsgraph(), effect, control);
1308 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);
1309 a.AllocateContext(context_length, factory()->block_context_map());
1310 a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX),
1312 a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
1313 a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
1314 a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
1315 jsgraph()->Constant(native_context()));
1316 for (
int i = Context::MIN_CONTEXT_SLOTS;
i < context_length; ++
i) {
1317 a.Store(AccessBuilder::ForContextSlot(
i), jsgraph()->UndefinedConstant());
1319 RelaxControls(node);
1320 a.FinishAndChange(node);
1321 return Changed(node);
1328 base::Optional<MapRef> GetObjectCreateMap(JSHeapBroker* broker,
1329 HeapObjectRef prototype) {
1330 MapRef standard_map =
1331 broker->native_context().object_function().initial_map();
1332 if (prototype.equals(standard_map.prototype())) {
1333 return standard_map;
1335 if (prototype.map().oddball_type() == OddballType::kNull) {
1336 return broker->native_context().slow_object_with_null_prototype_map();
1338 if (prototype.IsJSObject()) {
1339 return prototype.AsJSObject().GetObjectCreateMap();
1341 return base::Optional<MapRef>();
1345 Reduction JSCreateLowering::ReduceJSCreateObject(Node* node) {
1346 DCHECK_EQ(IrOpcode::kJSCreateObject, node->opcode());
1347 Node* effect = NodeProperties::GetEffectInput(node);
1348 Node* control = NodeProperties::GetControlInput(node);
1349 Node* prototype = NodeProperties::GetValueInput(node, 0);
1350 Type prototype_type = NodeProperties::GetType(prototype);
1351 if (!prototype_type.IsHeapConstant())
return NoChange();
1353 HeapObjectRef prototype_const = prototype_type.AsHeapConstant()->Ref();
1354 auto maybe_instance_map = GetObjectCreateMap(broker(), prototype_const);
1355 if (!maybe_instance_map)
return NoChange();
1356 MapRef instance_map = maybe_instance_map.value();
1358 Node* properties = jsgraph()->EmptyFixedArrayConstant();
1359 if (instance_map.is_dictionary_map()) {
1360 DCHECK_EQ(prototype_const.map().oddball_type(), OddballType::kNull);
1362 MapRef map(broker(), factory()->name_dictionary_map());
1364 NameDictionary::ComputeCapacity(NameDictionary::kInitialCapacity);
1365 DCHECK(base::bits::IsPowerOfTwo(capacity));
1366 int length = NameDictionary::EntryToIndex(capacity);
1367 int size = NameDictionary::SizeFor(length);
1369 AllocationBuilder a(jsgraph(), effect, control);
1370 a.Allocate(size, NOT_TENURED, Type::Any());
1371 a.Store(AccessBuilder::ForMap(), map);
1373 a.Store(AccessBuilder::ForFixedArrayLength(),
1374 jsgraph()->SmiConstant(length));
1376 a.Store(AccessBuilder::ForHashTableBaseNumberOfElements(),
1377 jsgraph()->SmiConstant(0));
1378 a.Store(AccessBuilder::ForHashTableBaseNumberOfDeletedElement(),
1379 jsgraph()->SmiConstant(0));
1380 a.Store(AccessBuilder::ForHashTableBaseCapacity(),
1381 jsgraph()->SmiConstant(capacity));
1383 a.Store(AccessBuilder::ForDictionaryNextEnumerationIndex(),
1384 jsgraph()->SmiConstant(PropertyDetails::kInitialIndex));
1385 a.Store(AccessBuilder::ForDictionaryObjectHashIndex(),
1386 jsgraph()->SmiConstant(PropertyArray::kNoHashSentinel));
1388 Node* undefined = jsgraph()->UndefinedConstant();
1389 STATIC_ASSERT(NameDictionary::kElementsStartIndex ==
1390 NameDictionary::kObjectHashIndex + 1);
1391 for (
int index = NameDictionary::kElementsStartIndex; index < length;
1393 a.Store(AccessBuilder::ForFixedArraySlot(index, kNoWriteBarrier),
1396 properties = effect = a.Finish();
1399 int const instance_size = instance_map.instance_size();
1400 if (instance_size > kMaxRegularHeapObjectSize)
return NoChange();
1401 CHECK(!instance_map.IsInobjectSlackTrackingInProgress());
1405 AllocationBuilder a(jsgraph(), effect, control);
1406 a.Allocate(instance_size, NOT_TENURED, Type::Any());
1407 a.Store(AccessBuilder::ForMap(), instance_map);
1408 a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
1409 a.Store(AccessBuilder::ForJSObjectElements(),
1410 jsgraph()->EmptyFixedArrayConstant());
1412 Node* undefined = jsgraph()->UndefinedConstant();
1413 for (
int offset = JSObject::kHeaderSize; offset < instance_size;
1414 offset += kPointerSize) {
1415 a.Store(AccessBuilder::ForJSObjectOffset(offset, kNoWriteBarrier),
1418 Node* value = effect = a.Finish();
1420 ReplaceWithValue(node, value, effect, control);
1421 return Replace(value);
1426 Node* JSCreateLowering::AllocateArguments(Node* effect, Node* control,
1427 Node* frame_state) {
1428 FrameStateInfo state_info = FrameStateInfoOf(frame_state->op());
1429 int argument_count = state_info.parameter_count() - 1;
1430 if (argument_count == 0)
return jsgraph()->EmptyFixedArrayConstant();
1433 Node*
const parameters = frame_state->InputAt(kFrameStateParametersInput);
1434 StateValuesAccess parameters_access(parameters);
1435 auto parameters_it = ++parameters_access.begin();
1438 AllocationBuilder a(jsgraph(), effect, control);
1439 a.AllocateArray(argument_count, factory()->fixed_array_map());
1440 for (
int i = 0;
i < argument_count; ++
i, ++parameters_it) {
1441 DCHECK_NOT_NULL((*parameters_it).node);
1442 a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(
i),
1443 (*parameters_it).node);
1450 Node* JSCreateLowering::AllocateRestArguments(Node* effect, Node* control,
1453 FrameStateInfo state_info = FrameStateInfoOf(frame_state->op());
1454 int argument_count = state_info.parameter_count() - 1;
1455 int num_elements = std::max(0, argument_count - start_index);
1456 if (num_elements == 0)
return jsgraph()->EmptyFixedArrayConstant();
1459 Node*
const parameters = frame_state->InputAt(kFrameStateParametersInput);
1460 StateValuesAccess parameters_access(parameters);
1461 auto parameters_it = ++parameters_access.begin();
1464 for (
int i = 0;
i < start_index;
i++) {
1469 AllocationBuilder a(jsgraph(), effect, control);
1470 a.AllocateArray(num_elements, factory()->fixed_array_map());
1471 for (
int i = 0;
i < num_elements; ++
i, ++parameters_it) {
1472 DCHECK_NOT_NULL((*parameters_it).node);
1473 a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(
i),
1474 (*parameters_it).node);
1482 Node* JSCreateLowering::AllocateAliasedArguments(
1483 Node* effect, Node* control, Node* frame_state, Node* context,
1484 const SharedFunctionInfoRef& shared,
bool* has_aliased_arguments) {
1485 FrameStateInfo state_info = FrameStateInfoOf(frame_state->op());
1486 int argument_count = state_info.parameter_count() - 1;
1487 if (argument_count == 0)
return jsgraph()->EmptyFixedArrayConstant();
1491 int parameter_count = shared.internal_formal_parameter_count();
1492 if (parameter_count == 0) {
1493 return AllocateArguments(effect, control, frame_state);
1497 int mapped_count = Min(argument_count, parameter_count);
1498 *has_aliased_arguments =
true;
1501 Node*
const parameters = frame_state->InputAt(kFrameStateParametersInput);
1502 StateValuesAccess parameters_access(parameters);
1503 auto parameters_it = ++parameters_access.begin();
1508 AllocationBuilder aa(jsgraph(), effect, control);
1509 aa.AllocateArray(argument_count, factory()->fixed_array_map());
1510 for (
int i = 0;
i < mapped_count; ++
i, ++parameters_it) {
1511 aa.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(
i),
1512 jsgraph()->TheHoleConstant());
1514 for (
int i = mapped_count;
i < argument_count; ++
i, ++parameters_it) {
1515 DCHECK_NOT_NULL((*parameters_it).node);
1516 aa.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(
i),
1517 (*parameters_it).node);
1519 Node* arguments = aa.Finish();
1522 AllocationBuilder a(jsgraph(), arguments, control);
1523 a.AllocateArray(mapped_count + 2, factory()->sloppy_arguments_elements_map());
1524 a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(0),
1526 a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(1),
1528 for (
int i = 0;
i < mapped_count; ++
i) {
1529 int idx = Context::MIN_CONTEXT_SLOTS + parameter_count - 1 -
i;
1530 a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(
i + 2),
1531 jsgraph()->Constant(idx));
1540 Node* JSCreateLowering::AllocateAliasedArguments(
1541 Node* effect, Node* control, Node* context, Node* arguments_frame,
1542 Node* arguments_length,
const SharedFunctionInfoRef& shared,
1543 bool* has_aliased_arguments) {
1546 int parameter_count = shared.internal_formal_parameter_count();
1547 if (parameter_count == 0) {
1548 return graph()->NewNode(simplified()->NewArgumentsElements(0),
1549 arguments_frame, arguments_length, effect);
1556 int mapped_count = parameter_count;
1557 *has_aliased_arguments =
true;
1563 graph()->NewNode(simplified()->NewArgumentsElements(mapped_count),
1564 arguments_frame, arguments_length, effect);
1567 AllocationBuilder a(jsgraph(), arguments, control);
1568 a.AllocateArray(mapped_count + 2, factory()->sloppy_arguments_elements_map());
1569 a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(0),
1571 a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(1),
1573 for (
int i = 0;
i < mapped_count; ++
i) {
1574 int idx = Context::MIN_CONTEXT_SLOTS + parameter_count - 1 -
i;
1575 Node* value = graph()->NewNode(
1576 common()->Select(MachineRepresentation::kTagged),
1577 graph()->NewNode(simplified()->NumberLessThan(), jsgraph()->Constant(
i),
1579 jsgraph()->Constant(idx), jsgraph()->TheHoleConstant());
1580 a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(
i + 2),
1586 Node* JSCreateLowering::AllocateElements(Node* effect, Node* control,
1587 ElementsKind elements_kind,
1589 PretenureFlag pretenure) {
1590 DCHECK_LE(1, capacity);
1591 DCHECK_LE(capacity, JSArray::kInitialMaxFastElementArray);
1593 Handle<Map> elements_map = IsDoubleElementsKind(elements_kind)
1594 ? factory()->fixed_double_array_map()
1595 : factory()->fixed_array_map();
1596 ElementAccess access = IsDoubleElementsKind(elements_kind)
1597 ? AccessBuilder::ForFixedDoubleArrayElement()
1598 : AccessBuilder::ForFixedArrayElement();
1599 Node* value = jsgraph()->TheHoleConstant();
1602 AllocationBuilder a(jsgraph(), effect, control);
1603 a.AllocateArray(capacity, elements_map, pretenure);
1604 for (
int i = 0;
i < capacity; ++
i) {
1605 Node* index = jsgraph()->Constant(
i);
1606 a.Store(access, index, value);
1611 Node* JSCreateLowering::AllocateElements(Node* effect, Node* control,
1612 ElementsKind elements_kind,
1613 std::vector<Node*>
const& values,
1614 PretenureFlag pretenure) {
1615 int const capacity =
static_cast<int>(values.size());
1616 DCHECK_LE(1, capacity);
1617 DCHECK_LE(capacity, JSArray::kInitialMaxFastElementArray);
1619 Handle<Map> elements_map = IsDoubleElementsKind(elements_kind)
1620 ? factory()->fixed_double_array_map()
1621 : factory()->fixed_array_map();
1622 ElementAccess access = IsDoubleElementsKind(elements_kind)
1623 ? AccessBuilder::ForFixedDoubleArrayElement()
1624 : AccessBuilder::ForFixedArrayElement();
1627 AllocationBuilder a(jsgraph(), effect, control);
1628 a.AllocateArray(capacity, elements_map, pretenure);
1629 for (
int i = 0;
i < capacity; ++
i) {
1630 Node* index = jsgraph()->Constant(
i);
1631 a.Store(access, index, values[
i]);
1636 Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control,
1637 JSObjectRef boilerplate,
1638 PretenureFlag pretenure) {
1640 Node* properties = jsgraph()->EmptyFixedArrayConstant();
1643 MapRef boilerplate_map = boilerplate.map();
1644 ZoneVector<std::pair<FieldAccess, Node*>> inobject_fields(zone());
1645 inobject_fields.reserve(boilerplate_map.GetInObjectProperties());
1646 int const boilerplate_nof = boilerplate_map.NumberOfOwnDescriptors();
1647 for (
int i = 0;
i < boilerplate_nof; ++
i) {
1648 PropertyDetails
const property_details =
1649 boilerplate_map.GetPropertyDetails(
i);
1650 if (property_details.location() != kField)
continue;
1651 DCHECK_EQ(kData, property_details.kind());
1652 NameRef property_name = boilerplate_map.GetPropertyKey(
i);
1653 FieldIndex index = boilerplate_map.GetFieldIndexFor(
i);
1654 FieldAccess access = {
1655 kTaggedBase, index.offset(), property_name.object(),
1656 MaybeHandle<Map>(), Type::Any(), MachineType::AnyTagged(),
1659 if (boilerplate_map.IsUnboxedDoubleField(
i)) {
1660 access.machine_type = MachineType::Float64();
1661 access.type = Type::Number();
1662 value = jsgraph()->Constant(boilerplate.RawFastDoublePropertyAt(index));
1664 ObjectRef boilerplate_value = boilerplate.RawFastPropertyAt(index);
1665 if (boilerplate_value.IsJSObject()) {
1666 JSObjectRef boilerplate_object = boilerplate_value.AsJSObject();
1668 AllocateFastLiteral(effect, control, boilerplate_object, pretenure);
1669 }
else if (property_details.representation().IsDouble()) {
1670 double number = boilerplate_value.AsMutableHeapNumber().value();
1672 AllocationBuilder builder(jsgraph(), effect, control);
1673 builder.Allocate(HeapNumber::kSize, pretenure);
1674 builder.Store(AccessBuilder::ForMap(),
1675 factory()->mutable_heap_number_map());
1676 builder.Store(AccessBuilder::ForHeapNumberValue(),
1677 jsgraph()->Constant(number));
1678 value = effect = builder.Finish();
1679 }
else if (property_details.representation().IsSmi()) {
1681 bool is_uninitialized =
1682 boilerplate_value.IsHeapObject() &&
1683 boilerplate_value.AsHeapObject().map().oddball_type() ==
1684 OddballType::kUninitialized;
1685 value = is_uninitialized
1686 ? jsgraph()->ZeroConstant()
1687 : jsgraph()->Constant(boilerplate_value.AsSmi());
1689 value = jsgraph()->Constant(boilerplate_value);
1692 inobject_fields.push_back(std::make_pair(access, value));
1696 int const boilerplate_length = boilerplate_map.GetInObjectProperties();
1697 for (
int index = static_cast<int>(inobject_fields.size());
1698 index < boilerplate_length; ++index) {
1699 FieldAccess access =
1700 AccessBuilder::ForJSObjectInObjectProperty(boilerplate_map, index);
1701 Node* value = jsgraph()->HeapConstant(factory()->one_pointer_filler_map());
1702 inobject_fields.push_back(std::make_pair(access, value));
1707 AllocateFastLiteralElements(effect, control, boilerplate, pretenure);
1708 if (elements->op()->EffectOutputCount() > 0) effect = elements;
1711 AllocationBuilder builder(jsgraph(), effect, control);
1712 builder.Allocate(boilerplate_map.instance_size(), pretenure,
1713 Type::For(boilerplate_map));
1714 builder.Store(AccessBuilder::ForMap(), boilerplate_map);
1715 builder.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
1716 builder.Store(AccessBuilder::ForJSObjectElements(), elements);
1717 if (boilerplate.IsJSArray()) {
1718 JSArrayRef boilerplate_array = boilerplate.AsJSArray();
1720 AccessBuilder::ForJSArrayLength(boilerplate_array.GetElementsKind()),
1721 boilerplate_array.length());
1723 for (
auto const& inobject_field : inobject_fields) {
1724 builder.Store(inobject_field.first, inobject_field.second);
1726 return builder.Finish();
1729 Node* JSCreateLowering::AllocateFastLiteralElements(Node* effect, Node* control,
1730 JSObjectRef boilerplate,
1731 PretenureFlag pretenure) {
1732 FixedArrayBaseRef boilerplate_elements = boilerplate.elements();
1735 int const elements_length = boilerplate_elements.length();
1736 MapRef elements_map = boilerplate_elements.map();
1737 if (boilerplate_elements.length() == 0 || elements_map.IsFixedCowArrayMap()) {
1738 if (pretenure == TENURED) {
1739 boilerplate.EnsureElementsTenured();
1740 boilerplate_elements = boilerplate.elements();
1742 return jsgraph()->HeapConstant(boilerplate_elements.object());
1746 ZoneVector<Node*> elements_values(elements_length, zone());
1747 if (elements_map.instance_type() == FIXED_DOUBLE_ARRAY_TYPE) {
1748 FixedDoubleArrayRef elements = boilerplate_elements.AsFixedDoubleArray();
1749 for (
int i = 0;
i < elements_length; ++
i) {
1750 if (elements.is_the_hole(
i)) {
1751 elements_values[
i] = jsgraph()->TheHoleConstant();
1753 elements_values[
i] = jsgraph()->Constant(elements.get_scalar(
i));
1757 FixedArrayRef elements = boilerplate_elements.AsFixedArray();
1758 for (
int i = 0;
i < elements_length; ++
i) {
1759 ObjectRef element_value = elements.get(
i);
1760 if (element_value.IsJSObject()) {
1761 elements_values[
i] = effect = AllocateFastLiteral(
1762 effect, control, element_value.AsJSObject(), pretenure);
1764 elements_values[
i] = jsgraph()->Constant(element_value);
1770 AllocationBuilder builder(jsgraph(), effect, control);
1771 builder.AllocateArray(elements_length, elements_map.object(), pretenure);
1772 ElementAccess
const access =
1773 (elements_map.instance_type() == FIXED_DOUBLE_ARRAY_TYPE)
1774 ? AccessBuilder::ForFixedDoubleArrayElement()
1775 : AccessBuilder::ForFixedArrayElement();
1776 for (
int i = 0;
i < elements_length; ++
i) {
1777 builder.Store(access, jsgraph()->Constant(
i), elements_values[
i]);
1779 return builder.Finish();
1782 Node* JSCreateLowering::AllocateLiteralRegExp(Node* effect, Node* control,
1783 JSRegExpRef boilerplate) {
1784 MapRef boilerplate_map = boilerplate.map();
1787 STATIC_ASSERT(JSRegExp::kDataOffset == JSObject::kHeaderSize);
1788 STATIC_ASSERT(JSRegExp::kSourceOffset ==
1789 JSRegExp::kDataOffset + kPointerSize);
1790 STATIC_ASSERT(JSRegExp::kFlagsOffset ==
1791 JSRegExp::kSourceOffset + kPointerSize);
1792 STATIC_ASSERT(JSRegExp::kSize == JSRegExp::kFlagsOffset + kPointerSize);
1793 STATIC_ASSERT(JSRegExp::kLastIndexOffset == JSRegExp::kSize);
1794 STATIC_ASSERT(JSRegExp::kInObjectFieldCount == 1);
1796 const PretenureFlag pretenure = NOT_TENURED;
1798 JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
1800 AllocationBuilder builder(jsgraph(), effect, control);
1801 builder.Allocate(size, pretenure, Type::For(boilerplate_map));
1802 builder.Store(AccessBuilder::ForMap(), boilerplate_map);
1803 builder.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
1804 boilerplate.raw_properties_or_hash());
1805 builder.Store(AccessBuilder::ForJSObjectElements(), boilerplate.elements());
1807 builder.Store(AccessBuilder::ForJSRegExpData(), boilerplate.data());
1808 builder.Store(AccessBuilder::ForJSRegExpSource(), boilerplate.source());
1809 builder.Store(AccessBuilder::ForJSRegExpFlags(), boilerplate.flags());
1810 builder.Store(AccessBuilder::ForJSRegExpLastIndex(),
1811 boilerplate.last_index());
1813 return builder.Finish();
1816 Factory* JSCreateLowering::factory()
const {
1817 return jsgraph()->isolate()->factory();
1820 Graph* JSCreateLowering::graph()
const {
return jsgraph()->graph(); }
1822 CommonOperatorBuilder* JSCreateLowering::common()
const {
1823 return jsgraph()->common();
1826 SimplifiedOperatorBuilder* JSCreateLowering::simplified()
const {
1827 return jsgraph()->simplified();
1830 NativeContextRef JSCreateLowering::native_context()
const {
1831 return broker()->native_context();