LCOV - code coverage report
Current view: top level - src/compiler - js-create-lowering.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 831 844 98.5 %
Date: 2019-01-20 Functions: 41 46 89.1 %

          Line data    Source code
       1             : // Copyright 2016 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/compiler/js-create-lowering.h"
       6             : 
       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/heap-number.h"
      25             : #include "src/objects/js-generator.h"
      26             : #include "src/objects/js-promise.h"
      27             : #include "src/objects/js-regexp-inl.h"
      28             : 
      29             : namespace v8 {
      30             : namespace internal {
      31             : namespace compiler {
      32             : 
      33             : namespace {
      34             : 
      35             : // Retrieves the frame state holding actual argument values.
      36        1584 : Node* GetArgumentsFrameState(Node* frame_state) {
      37        1584 :   Node* const outer_state = NodeProperties::GetFrameStateInput(frame_state);
      38        1584 :   FrameStateInfo outer_state_info = FrameStateInfoOf(outer_state->op());
      39             :   return outer_state_info.type() == FrameStateType::kArgumentsAdaptor
      40             :              ? outer_state
      41        1584 :              : frame_state;
      42             : }
      43             : 
      44             : // Checks whether allocation using the given target and new.target can be
      45             : // inlined.
      46        4918 : bool IsAllocationInlineable(const JSFunctionRef& target,
      47             :                             const JSFunctionRef& new_target) {
      48        4918 :   CHECK_IMPLIES(new_target.has_initial_map(),
      49             :                 !new_target.initial_map().is_dictionary_map());
      50        9832 :   return new_target.has_initial_map() &&
      51        9832 :          new_target.initial_map().GetConstructor().equals(target);
      52             : }
      53             : 
      54             : // When initializing arrays, we'll unfold the loop if the number of
      55             : // elements is known to be of this type.
      56             : const int kElementLoopUnrollLimit = 16;
      57             : 
      58             : // Limits up to which context allocations are inlined.
      59             : const int kFunctionContextAllocationLimit = 16;
      60             : const int kBlockContextAllocationLimit = 16;
      61             : 
      62             : }  // namespace
      63             : 
      64    31549552 : Reduction JSCreateLowering::Reduce(Node* node) {
      65             :   DisallowHeapAccess disallow_heap_access;
      66    31549552 :   switch (node->opcode()) {
      67             :     case IrOpcode::kJSCreate:
      68        3733 :       return ReduceJSCreate(node);
      69             :     case IrOpcode::kJSCreateArguments:
      70       19294 :       return ReduceJSCreateArguments(node);
      71             :     case IrOpcode::kJSCreateArray:
      72        1454 :       return ReduceJSCreateArray(node);
      73             :     case IrOpcode::kJSCreateArrayIterator:
      74        1328 :       return ReduceJSCreateArrayIterator(node);
      75             :     case IrOpcode::kJSCreateAsyncFunctionObject:
      76        1082 :       return ReduceJSCreateAsyncFunctionObject(node);
      77             :     case IrOpcode::kJSCreateBoundFunction:
      78         105 :       return ReduceJSCreateBoundFunction(node);
      79             :     case IrOpcode::kJSCreateClosure:
      80      420922 :       return ReduceJSCreateClosure(node);
      81             :     case IrOpcode::kJSCreateCollectionIterator:
      82         164 :       return ReduceJSCreateCollectionIterator(node);
      83             :     case IrOpcode::kJSCreateIterResultObject:
      84        3175 :       return ReduceJSCreateIterResultObject(node);
      85             :     case IrOpcode::kJSCreateStringIterator:
      86          67 :       return ReduceJSCreateStringIterator(node);
      87             :     case IrOpcode::kJSCreateKeyValueArray:
      88          91 :       return ReduceJSCreateKeyValueArray(node);
      89             :     case IrOpcode::kJSCreatePromise:
      90        1403 :       return ReduceJSCreatePromise(node);
      91             :     case IrOpcode::kJSCreateLiteralArray:
      92             :     case IrOpcode::kJSCreateLiteralObject:
      93       23137 :       return ReduceJSCreateLiteralArrayOrObject(node);
      94             :     case IrOpcode::kJSCreateLiteralRegExp:
      95        6464 :       return ReduceJSCreateLiteralRegExp(node);
      96             :     case IrOpcode::kJSCreateEmptyLiteralArray:
      97       21315 :       return ReduceJSCreateEmptyLiteralArray(node);
      98             :     case IrOpcode::kJSCreateEmptyLiteralObject:
      99        5993 :       return ReduceJSCreateEmptyLiteralObject(node);
     100             :     case IrOpcode::kJSCreateFunctionContext:
     101       29355 :       return ReduceJSCreateFunctionContext(node);
     102             :     case IrOpcode::kJSCreateWithContext:
     103         492 :       return ReduceJSCreateWithContext(node);
     104             :     case IrOpcode::kJSCreateCatchContext:
     105       14119 :       return ReduceJSCreateCatchContext(node);
     106             :     case IrOpcode::kJSCreateBlockContext:
     107        8845 :       return ReduceJSCreateBlockContext(node);
     108             :     case IrOpcode::kJSCreateGeneratorObject:
     109        1270 :       return ReduceJSCreateGeneratorObject(node);
     110             :     case IrOpcode::kJSCreateObject:
     111          75 :       return ReduceJSCreateObject(node);
     112             :     default:
     113             :       break;
     114             :   }
     115             :   return NoChange();
     116             : }
     117             : 
     118       24644 : Reduction JSCreateLowering::ReduceJSCreate(Node* node) {
     119             :   DCHECK_EQ(IrOpcode::kJSCreate, node->opcode());
     120        3733 :   Node* const target = NodeProperties::GetValueInput(node, 0);
     121        3733 :   Type const target_type = NodeProperties::GetType(target);
     122        3733 :   Node* const new_target = NodeProperties::GetValueInput(node, 1);
     123        3733 :   Type const new_target_type = NodeProperties::GetType(new_target);
     124        3733 :   Node* const effect = NodeProperties::GetEffectInput(node);
     125        3733 :   Node* const control = NodeProperties::GetControlInput(node);
     126             :   // Extract constructor and original constructor function.
     127       10911 :   if (!target_type.IsHeapConstant() || !new_target_type.IsHeapConstant() ||
     128       10689 :       !target_type.AsHeapConstant()->Ref().IsJSFunction() ||
     129        3478 :       !new_target_type.AsHeapConstant()->Ref().IsJSFunction()) {
     130             :     return NoChange();
     131             :   }
     132             : 
     133             :   JSFunctionRef constructor =
     134        3471 :       target_type.AsHeapConstant()->Ref().AsJSFunction();
     135        3471 :   if (!constructor.map().is_constructor()) return NoChange();
     136             :   JSFunctionRef original_constructor =
     137        3471 :       new_target_type.AsHeapConstant()->Ref().AsJSFunction();
     138        3471 :   if (!original_constructor.map().is_constructor()) return NoChange();
     139             : 
     140             :   // Check if we can inline the allocation.
     141        3464 :   if (!IsAllocationInlineable(constructor, original_constructor)) {
     142             :     return NoChange();
     143             :   }
     144             : 
     145             :   SlackTrackingPrediction slack_tracking_prediction =
     146             :       dependencies()->DependOnInitialMapInstanceSizePrediction(
     147        3460 :           original_constructor);
     148        3460 :   MapRef initial_map = original_constructor.initial_map();
     149             : 
     150             :   // Emit code to allocate the JSObject instance for the
     151             :   // {original_constructor}.
     152             :   AllocationBuilder a(jsgraph(), effect, control);
     153        3460 :   a.Allocate(slack_tracking_prediction.instance_size());
     154        3460 :   a.Store(AccessBuilder::ForMap(), initial_map);
     155             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
     156        3460 :           jsgraph()->EmptyFixedArrayConstant());
     157             :   a.Store(AccessBuilder::ForJSObjectElements(),
     158        3460 :           jsgraph()->EmptyFixedArrayConstant());
     159       10531 :   for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
     160             :        ++i) {
     161             :     a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
     162        7071 :             jsgraph()->UndefinedConstant());
     163             :   }
     164             : 
     165             :   RelaxControls(node);
     166        3460 :   a.FinishAndChange(node);
     167             :   return Changed(node);
     168             : }
     169             : 
     170       78744 : Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) {
     171             :   DCHECK_EQ(IrOpcode::kJSCreateArguments, node->opcode());
     172       19294 :   CreateArgumentsType type = CreateArgumentsTypeOf(node->op());
     173       38588 :   Node* const frame_state = NodeProperties::GetFrameStateInput(node);
     174       19294 :   Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
     175       19294 :   Node* const control = graph()->start();
     176       19294 :   FrameStateInfo state_info = FrameStateInfoOf(frame_state->op());
     177             :   SharedFunctionInfoRef shared(broker(),
     178             :                                state_info.shared_info().ToHandleChecked());
     179             : 
     180             :   // Use the ArgumentsAccessStub for materializing both mapped and unmapped
     181             :   // arguments object, but only for non-inlined (i.e. outermost) frames.
     182       19294 :   if (outer_state->opcode() != IrOpcode::kFrameState) {
     183       17710 :     switch (type) {
     184             :       case CreateArgumentsType::kMappedArguments: {
     185             :         // TODO(mstarzinger): Duplicate parameters are not handled yet.
     186       11041 :         if (shared.has_duplicate_parameters()) return NoChange();
     187       11033 :         Node* const callee = NodeProperties::GetValueInput(node, 0);
     188       11033 :         Node* const context = NodeProperties::GetContextInput(node);
     189       11033 :         Node* effect = NodeProperties::GetEffectInput(node);
     190             :         Node* const arguments_frame =
     191       11033 :             graph()->NewNode(simplified()->ArgumentsFrame());
     192             :         Node* const arguments_length = graph()->NewNode(
     193             :             simplified()->ArgumentsLength(
     194             :                 shared.internal_formal_parameter_count(), false),
     195       22066 :             arguments_frame);
     196             :         // Allocate the elements backing store.
     197       11033 :         bool has_aliased_arguments = false;
     198             :         Node* const elements = effect = AllocateAliasedArguments(
     199             :             effect, control, context, arguments_frame, arguments_length, shared,
     200       11033 :             &has_aliased_arguments);
     201             :         // Load the arguments object map.
     202             :         Node* const arguments_map = jsgraph()->Constant(
     203             :             has_aliased_arguments
     204       15889 :                 ? native_context().fast_aliased_arguments_map()
     205       41704 :                 : native_context().sloppy_arguments_map());
     206             :         // Actually allocate and initialize the arguments object.
     207             :         AllocationBuilder a(jsgraph(), effect, control);
     208       11033 :         Node* properties = jsgraph()->EmptyFixedArrayConstant();
     209             :         STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kTaggedSize);
     210       11033 :         a.Allocate(JSSloppyArgumentsObject::kSize);
     211       11033 :         a.Store(AccessBuilder::ForMap(), arguments_map);
     212       11033 :         a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     213       11033 :         a.Store(AccessBuilder::ForJSObjectElements(), elements);
     214       11033 :         a.Store(AccessBuilder::ForArgumentsLength(), arguments_length);
     215       11033 :         a.Store(AccessBuilder::ForArgumentsCallee(), callee);
     216             :         RelaxControls(node);
     217       11033 :         a.FinishAndChange(node);
     218             :         return Changed(node);
     219             :       }
     220             :       case CreateArgumentsType::kUnmappedArguments: {
     221        5752 :         Node* effect = NodeProperties::GetEffectInput(node);
     222             :         Node* const arguments_frame =
     223        5752 :             graph()->NewNode(simplified()->ArgumentsFrame());
     224             :         Node* const arguments_length = graph()->NewNode(
     225             :             simplified()->ArgumentsLength(
     226             :                 shared.internal_formal_parameter_count(), false),
     227       11504 :             arguments_frame);
     228             :         // Allocate the elements backing store.
     229             :         Node* const elements = effect =
     230             :             graph()->NewNode(simplified()->NewArgumentsElements(0),
     231        5752 :                              arguments_frame, arguments_length, effect);
     232             :         // Load the arguments object map.
     233             :         Node* const arguments_map =
     234       11504 :             jsgraph()->Constant(native_context().strict_arguments_map());
     235             :         // Actually allocate and initialize the arguments object.
     236             :         AllocationBuilder a(jsgraph(), effect, control);
     237        5752 :         Node* properties = jsgraph()->EmptyFixedArrayConstant();
     238             :         STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kTaggedSize);
     239        5752 :         a.Allocate(JSStrictArgumentsObject::kSize);
     240        5752 :         a.Store(AccessBuilder::ForMap(), arguments_map);
     241        5752 :         a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     242        5752 :         a.Store(AccessBuilder::ForJSObjectElements(), elements);
     243        5752 :         a.Store(AccessBuilder::ForArgumentsLength(), arguments_length);
     244             :         RelaxControls(node);
     245        5752 :         a.FinishAndChange(node);
     246             :         return Changed(node);
     247             :       }
     248             :       case CreateArgumentsType::kRestParameter: {
     249         917 :         Node* effect = NodeProperties::GetEffectInput(node);
     250             :         Node* const arguments_frame =
     251         917 :             graph()->NewNode(simplified()->ArgumentsFrame());
     252             :         Node* const rest_length = graph()->NewNode(
     253             :             simplified()->ArgumentsLength(
     254             :                 shared.internal_formal_parameter_count(), true),
     255        1834 :             arguments_frame);
     256             :         // Allocate the elements backing store. Since NewArgumentsElements
     257             :         // copies from the end of the arguments adapter frame, this is a suffix
     258             :         // of the actual arguments.
     259             :         Node* const elements = effect =
     260             :             graph()->NewNode(simplified()->NewArgumentsElements(0),
     261         917 :                              arguments_frame, rest_length, effect);
     262             :         // Load the JSArray object map.
     263             :         Node* const jsarray_map = jsgraph()->Constant(
     264        1834 :             native_context().js_array_packed_elements_map());
     265             :         // Actually allocate and initialize the jsarray.
     266             :         AllocationBuilder a(jsgraph(), effect, control);
     267         917 :         Node* properties = jsgraph()->EmptyFixedArrayConstant();
     268             :         STATIC_ASSERT(JSArray::kSize == 4 * kTaggedSize);
     269         917 :         a.Allocate(JSArray::kSize);
     270         917 :         a.Store(AccessBuilder::ForMap(), jsarray_map);
     271         917 :         a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     272         917 :         a.Store(AccessBuilder::ForJSObjectElements(), elements);
     273         917 :         a.Store(AccessBuilder::ForJSArrayLength(PACKED_ELEMENTS), rest_length);
     274             :         RelaxControls(node);
     275         917 :         a.FinishAndChange(node);
     276             :         return Changed(node);
     277             :       }
     278             :     }
     279           0 :     UNREACHABLE();
     280        1584 :   } else if (outer_state->opcode() == IrOpcode::kFrameState) {
     281             :     // Use inline allocation for all mapped arguments objects within inlined
     282             :     // (i.e. non-outermost) frames, independent of the object size.
     283        1584 :     if (type == CreateArgumentsType::kMappedArguments) {
     284         638 :       Node* const callee = NodeProperties::GetValueInput(node, 0);
     285         638 :       Node* const context = NodeProperties::GetContextInput(node);
     286         638 :       Node* effect = NodeProperties::GetEffectInput(node);
     287             :       // TODO(mstarzinger): Duplicate parameters are not handled yet.
     288         638 :       if (shared.has_duplicate_parameters()) return NoChange();
     289             :       // Choose the correct frame state and frame state info depending on
     290             :       // whether there conceptually is an arguments adaptor frame in the call
     291             :       // chain.
     292        1276 :       Node* const args_state = GetArgumentsFrameState(frame_state);
     293        1276 :       if (args_state->InputAt(kFrameStateParametersInput)->opcode() ==
     294             :           IrOpcode::kDeadValue) {
     295             :         // This protects against an incompletely propagated DeadValue node.
     296             :         // If the FrameState has a DeadValue input, then this node will be
     297             :         // pruned anyway.
     298             :         return NoChange();
     299             :       }
     300         638 :       FrameStateInfo args_state_info = FrameStateInfoOf(args_state->op());
     301             :       // Prepare element backing store to be used by arguments object.
     302         638 :       bool has_aliased_arguments = false;
     303         638 :       Node* const elements = AllocateAliasedArguments(
     304         638 :           effect, control, args_state, context, shared, &has_aliased_arguments);
     305        1276 :       effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
     306             :       // Load the arguments object map.
     307             :       Node* const arguments_map = jsgraph()->Constant(
     308        1338 :           has_aliased_arguments ? native_context().fast_aliased_arguments_map()
     309        2202 :                                 : native_context().sloppy_arguments_map());
     310             :       // Actually allocate and initialize the arguments object.
     311             :       AllocationBuilder a(jsgraph(), effect, control);
     312         638 :       Node* properties = jsgraph()->EmptyFixedArrayConstant();
     313         638 :       int length = args_state_info.parameter_count() - 1;  // Minus receiver.
     314             :       STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kTaggedSize);
     315         638 :       a.Allocate(JSSloppyArgumentsObject::kSize);
     316         638 :       a.Store(AccessBuilder::ForMap(), arguments_map);
     317         638 :       a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     318         638 :       a.Store(AccessBuilder::ForJSObjectElements(), elements);
     319        1276 :       a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length));
     320         638 :       a.Store(AccessBuilder::ForArgumentsCallee(), callee);
     321             :       RelaxControls(node);
     322         638 :       a.FinishAndChange(node);
     323             :       return Changed(node);
     324         946 :     } else if (type == CreateArgumentsType::kUnmappedArguments) {
     325             :       // Use inline allocation for all unmapped arguments objects within inlined
     326             :       // (i.e. non-outermost) frames, independent of the object size.
     327         420 :       Node* effect = NodeProperties::GetEffectInput(node);
     328             :       // Choose the correct frame state and frame state info depending on
     329             :       // whether there conceptually is an arguments adaptor frame in the call
     330             :       // chain.
     331         840 :       Node* const args_state = GetArgumentsFrameState(frame_state);
     332         840 :       if (args_state->InputAt(kFrameStateParametersInput)->opcode() ==
     333             :           IrOpcode::kDeadValue) {
     334             :         // This protects against an incompletely propagated DeadValue node.
     335             :         // If the FrameState has a DeadValue input, then this node will be
     336             :         // pruned anyway.
     337             :         return NoChange();
     338             :       }
     339         420 :       FrameStateInfo args_state_info = FrameStateInfoOf(args_state->op());
     340             :       // Prepare element backing store to be used by arguments object.
     341         420 :       Node* const elements = AllocateArguments(effect, control, args_state);
     342         840 :       effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
     343             :       // Load the arguments object map.
     344             :       Node* const arguments_map =
     345         840 :           jsgraph()->Constant(native_context().strict_arguments_map());
     346             :       // Actually allocate and initialize the arguments object.
     347             :       AllocationBuilder a(jsgraph(), effect, control);
     348         420 :       Node* properties = jsgraph()->EmptyFixedArrayConstant();
     349         420 :       int length = args_state_info.parameter_count() - 1;  // Minus receiver.
     350             :       STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kTaggedSize);
     351         420 :       a.Allocate(JSStrictArgumentsObject::kSize);
     352         420 :       a.Store(AccessBuilder::ForMap(), arguments_map);
     353         420 :       a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     354         420 :       a.Store(AccessBuilder::ForJSObjectElements(), elements);
     355         840 :       a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length));
     356             :       RelaxControls(node);
     357         420 :       a.FinishAndChange(node);
     358             :       return Changed(node);
     359         526 :     } else if (type == CreateArgumentsType::kRestParameter) {
     360         526 :       int start_index = shared.internal_formal_parameter_count();
     361             :       // Use inline allocation for all unmapped arguments objects within inlined
     362             :       // (i.e. non-outermost) frames, independent of the object size.
     363         526 :       Node* effect = NodeProperties::GetEffectInput(node);
     364             :       // Choose the correct frame state and frame state info depending on
     365             :       // whether there conceptually is an arguments adaptor frame in the call
     366             :       // chain.
     367        1052 :       Node* const args_state = GetArgumentsFrameState(frame_state);
     368        1052 :       if (args_state->InputAt(kFrameStateParametersInput)->opcode() ==
     369             :           IrOpcode::kDeadValue) {
     370             :         // This protects against an incompletely propagated DeadValue node.
     371             :         // If the FrameState has a DeadValue input, then this node will be
     372             :         // pruned anyway.
     373             :         return NoChange();
     374             :       }
     375         526 :       FrameStateInfo args_state_info = FrameStateInfoOf(args_state->op());
     376             :       // Prepare element backing store to be used by the rest array.
     377         526 :       Node* const elements =
     378         526 :           AllocateRestArguments(effect, control, args_state, start_index);
     379        1052 :       effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
     380             :       // Load the JSArray object map.
     381             :       Node* const jsarray_map =
     382        1052 :           jsgraph()->Constant(native_context().js_array_packed_elements_map());
     383             :       // Actually allocate and initialize the jsarray.
     384             :       AllocationBuilder a(jsgraph(), effect, control);
     385         526 :       Node* properties = jsgraph()->EmptyFixedArrayConstant();
     386             : 
     387             :       // -1 to minus receiver
     388         526 :       int argument_count = args_state_info.parameter_count() - 1;
     389        1052 :       int length = std::max(0, argument_count - start_index);
     390             :       STATIC_ASSERT(JSArray::kSize == 4 * kTaggedSize);
     391         526 :       a.Allocate(JSArray::kSize);
     392         526 :       a.Store(AccessBuilder::ForMap(), jsarray_map);
     393         526 :       a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     394         526 :       a.Store(AccessBuilder::ForJSObjectElements(), elements);
     395             :       a.Store(AccessBuilder::ForJSArrayLength(PACKED_ELEMENTS),
     396        1052 :               jsgraph()->Constant(length));
     397             :       RelaxControls(node);
     398         526 :       a.FinishAndChange(node);
     399             :       return Changed(node);
     400             :     }
     401             :   }
     402             : 
     403             :   return NoChange();
     404             : }
     405             : 
     406        7854 : Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
     407             :   DCHECK_EQ(IrOpcode::kJSCreateGeneratorObject, node->opcode());
     408        1270 :   Node* const closure = NodeProperties::GetValueInput(node, 0);
     409        1270 :   Node* const receiver = NodeProperties::GetValueInput(node, 1);
     410        1270 :   Node* const context = NodeProperties::GetContextInput(node);
     411        1270 :   Type const closure_type = NodeProperties::GetType(closure);
     412        1270 :   Node* effect = NodeProperties::GetEffectInput(node);
     413        1270 :   Node* const control = NodeProperties::GetControlInput(node);
     414        1270 :   if (closure_type.IsHeapConstant()) {
     415             :     DCHECK(closure_type.AsHeapConstant()->Ref().IsJSFunction());
     416             :     JSFunctionRef js_function =
     417        1236 :         closure_type.AsHeapConstant()->Ref().AsJSFunction();
     418        1236 :     if (!js_function.has_initial_map()) return NoChange();
     419             : 
     420             :     SlackTrackingPrediction slack_tracking_prediction =
     421         490 :         dependencies()->DependOnInitialMapInstanceSizePrediction(js_function);
     422             : 
     423         490 :     MapRef initial_map = js_function.initial_map();
     424             :     DCHECK(initial_map.instance_type() == JS_GENERATOR_OBJECT_TYPE ||
     425             :            initial_map.instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE);
     426             : 
     427             :     // Allocate a register file.
     428         490 :     SharedFunctionInfoRef shared = js_function.shared();
     429             :     DCHECK(shared.HasBytecodeArray());
     430         490 :     int parameter_count_no_receiver = shared.internal_formal_parameter_count();
     431             :     int size = parameter_count_no_receiver +
     432         490 :                shared.GetBytecodeArray().register_count();
     433             :     AllocationBuilder ab(jsgraph(), effect, control);
     434         490 :     ab.AllocateArray(size, factory()->fixed_array_map());
     435        3609 :     for (int i = 0; i < size; ++i) {
     436        3119 :       ab.Store(AccessBuilder::ForFixedArraySlot(i),
     437        6238 :                jsgraph()->UndefinedConstant());
     438             :     }
     439         490 :     Node* parameters_and_registers = effect = ab.Finish();
     440             : 
     441             :     // Emit code to allocate the JS[Async]GeneratorObject instance.
     442             :     AllocationBuilder a(jsgraph(), effect, control);
     443         490 :     a.Allocate(slack_tracking_prediction.instance_size());
     444         490 :     Node* empty_fixed_array = jsgraph()->EmptyFixedArrayConstant();
     445         490 :     Node* undefined = jsgraph()->UndefinedConstant();
     446         490 :     a.Store(AccessBuilder::ForMap(), initial_map);
     447         490 :     a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), empty_fixed_array);
     448         490 :     a.Store(AccessBuilder::ForJSObjectElements(), empty_fixed_array);
     449         490 :     a.Store(AccessBuilder::ForJSGeneratorObjectContext(), context);
     450         490 :     a.Store(AccessBuilder::ForJSGeneratorObjectFunction(), closure);
     451         490 :     a.Store(AccessBuilder::ForJSGeneratorObjectReceiver(), receiver);
     452         490 :     a.Store(AccessBuilder::ForJSGeneratorObjectInputOrDebugPos(), undefined);
     453             :     a.Store(AccessBuilder::ForJSGeneratorObjectResumeMode(),
     454         490 :             jsgraph()->Constant(JSGeneratorObject::kNext));
     455             :     a.Store(AccessBuilder::ForJSGeneratorObjectContinuation(),
     456         490 :             jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting));
     457             :     a.Store(AccessBuilder::ForJSGeneratorObjectParametersAndRegisters(),
     458         490 :             parameters_and_registers);
     459             : 
     460         490 :     if (initial_map.instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE) {
     461          35 :       a.Store(AccessBuilder::ForJSAsyncGeneratorObjectQueue(), undefined);
     462             :       a.Store(AccessBuilder::ForJSAsyncGeneratorObjectIsAwaiting(),
     463          35 :               jsgraph()->ZeroConstant());
     464             :     }
     465             : 
     466             :     // Handle in-object properties, too.
     467          14 :     for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
     468             :          ++i) {
     469             :       a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
     470          14 :               undefined);
     471             :     }
     472         490 :     a.FinishAndChange(node);
     473             :     return Changed(node);
     474             :   }
     475             :   return NoChange();
     476             : }
     477             : 
     478             : // Constructs an array with a variable {length} when no upper bound
     479             : // is known for the capacity.
     480         515 : Reduction JSCreateLowering::ReduceNewArray(
     481             :     Node* node, Node* length, MapRef initial_map, ElementsKind elements_kind,
     482             :     PretenureFlag pretenure,
     483        2575 :     const SlackTrackingPrediction& slack_tracking_prediction) {
     484             :   DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
     485         515 :   Node* effect = NodeProperties::GetEffectInput(node);
     486         515 :   Node* control = NodeProperties::GetControlInput(node);
     487             : 
     488             :   // Constructing an Array via new Array(N) where N is an unsigned
     489             :   // integer, always creates a holey backing store.
     490         515 :   ASSIGN_RETURN_NO_CHANGE_IF_DATA_MISSING(
     491             :       initial_map,
     492             :       initial_map.AsElementsKind(GetHoleyElementsKind(elements_kind)));
     493             : 
     494             :   // Check that the {limit} is an unsigned integer in the valid range.
     495             :   // This has to be kept in sync with src/runtime/runtime-array.cc,
     496             :   // where this limit is protected.
     497             :   length = effect = graph()->NewNode(
     498             :       simplified()->CheckBounds(VectorSlotPair()), length,
     499             :       jsgraph()->Constant(JSArray::kInitialMaxFastElementArray), effect,
     500        1545 :       control);
     501             : 
     502             :   // Construct elements and properties for the resulting JSArray.
     503             :   Node* elements = effect =
     504         515 :       graph()->NewNode(IsDoubleElementsKind(initial_map.elements_kind())
     505             :                            ? simplified()->NewDoubleElements(pretenure)
     506             :                            : simplified()->NewSmiOrObjectElements(pretenure),
     507        1030 :                        length, effect, control);
     508         515 :   Node* properties = jsgraph()->EmptyFixedArrayConstant();
     509             : 
     510             :   // Perform the allocation of the actual JSArray object.
     511             :   AllocationBuilder a(jsgraph(), effect, control);
     512         515 :   a.Allocate(slack_tracking_prediction.instance_size(), pretenure);
     513         515 :   a.Store(AccessBuilder::ForMap(), initial_map);
     514         515 :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     515         515 :   a.Store(AccessBuilder::ForJSObjectElements(), elements);
     516         515 :   a.Store(AccessBuilder::ForJSArrayLength(initial_map.elements_kind()), length);
     517        1030 :   for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
     518             :        ++i) {
     519             :     a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
     520           0 :             jsgraph()->UndefinedConstant());
     521             :   }
     522             :   RelaxControls(node);
     523         515 :   a.FinishAndChange(node);
     524             :   return Changed(node);
     525             : }
     526             : 
     527             : // Constructs an array with a variable {length} when an actual
     528             : // upper bound is known for the {capacity}.
     529        1684 : Reduction JSCreateLowering::ReduceNewArray(
     530             :     Node* node, Node* length, int capacity, MapRef initial_map,
     531             :     ElementsKind elements_kind, PretenureFlag pretenure,
     532        7841 :     const SlackTrackingPrediction& slack_tracking_prediction) {
     533             :   DCHECK(node->opcode() == IrOpcode::kJSCreateArray ||
     534             :          node->opcode() == IrOpcode::kJSCreateEmptyLiteralArray);
     535        1684 :   Node* effect = NodeProperties::GetEffectInput(node);
     536        1684 :   Node* control = NodeProperties::GetControlInput(node);
     537             : 
     538             :   // Determine the appropriate elements kind.
     539        1684 :   if (NodeProperties::GetType(length).Max() > 0.0) {
     540             :     elements_kind = GetHoleyElementsKind(elements_kind);
     541             :   }
     542        1684 :   ASSIGN_RETURN_NO_CHANGE_IF_DATA_MISSING(
     543             :       initial_map, initial_map.AsElementsKind(elements_kind));
     544             :   DCHECK(IsFastElementsKind(elements_kind));
     545             : 
     546             :   // Setup elements and properties.
     547             :   Node* elements;
     548        1684 :   if (capacity == 0) {
     549        1063 :     elements = jsgraph()->EmptyFixedArrayConstant();
     550             :   } else {
     551             :     elements = effect =
     552         621 :         AllocateElements(effect, control, elements_kind, capacity, pretenure);
     553             :   }
     554        1684 :   Node* properties = jsgraph()->EmptyFixedArrayConstant();
     555             : 
     556             :   // Perform the allocation of the actual JSArray object.
     557             :   AllocationBuilder a(jsgraph(), effect, control);
     558        1684 :   a.Allocate(slack_tracking_prediction.instance_size(), pretenure);
     559        1684 :   a.Store(AccessBuilder::ForMap(), initial_map);
     560        1684 :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     561        1684 :   a.Store(AccessBuilder::ForJSObjectElements(), elements);
     562        1684 :   a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
     563        3410 :   for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
     564             :        ++i) {
     565             :     a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
     566          21 :             jsgraph()->UndefinedConstant());
     567             :   }
     568             :   RelaxControls(node);
     569        1684 :   a.FinishAndChange(node);
     570             :   return Changed(node);
     571             : }
     572             : 
     573         196 : Reduction JSCreateLowering::ReduceNewArray(
     574         196 :     Node* node, std::vector<Node*> values, MapRef initial_map,
     575             :     ElementsKind elements_kind, PretenureFlag pretenure,
     576        1064 :     const SlackTrackingPrediction& slack_tracking_prediction) {
     577             :   DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
     578         196 :   Node* effect = NodeProperties::GetEffectInput(node);
     579         196 :   Node* control = NodeProperties::GetControlInput(node);
     580             : 
     581             :   // Determine the appropriate elements kind.
     582             :   DCHECK(IsFastElementsKind(elements_kind));
     583         196 :   ASSIGN_RETURN_NO_CHANGE_IF_DATA_MISSING(
     584             :       initial_map, initial_map.AsElementsKind(elements_kind));
     585             : 
     586             :   // Check {values} based on the {elements_kind}. These checks are guarded
     587             :   // by the {elements_kind} feedback on the {site}, so it's safe to just
     588             :   // deoptimize in this case.
     589         196 :   if (IsSmiElementsKind(elements_kind)) {
     590         240 :     for (auto& value : values) {
     591         320 :       if (!NodeProperties::GetType(value).Is(Type::SignedSmall())) {
     592             :         value = effect = graph()->NewNode(
     593          75 :             simplified()->CheckSmi(VectorSlotPair()), value, effect, control);
     594             :       }
     595             :     }
     596         156 :   } else if (IsDoubleElementsKind(elements_kind)) {
     597         100 :     for (auto& value : values) {
     598         116 :       if (!NodeProperties::GetType(value).Is(Type::Number())) {
     599             :         value = effect =
     600             :             graph()->NewNode(simplified()->CheckNumber(VectorSlotPair()), value,
     601           0 :                              effect, control);
     602             :       }
     603             :       // Make sure we do not store signaling NaNs into double arrays.
     604         174 :       value = graph()->NewNode(simplified()->NumberSilenceNaN(), value);
     605             :     }
     606             :   }
     607             : 
     608             :   // Setup elements, properties and length.
     609             :   Node* elements = effect =
     610         196 :       AllocateElements(effect, control, elements_kind, values, pretenure);
     611         196 :   Node* properties = jsgraph()->EmptyFixedArrayConstant();
     612         392 :   Node* length = jsgraph()->Constant(static_cast<int>(values.size()));
     613             : 
     614             :   // Perform the allocation of the actual JSArray object.
     615             :   AllocationBuilder a(jsgraph(), effect, control);
     616         196 :   a.Allocate(slack_tracking_prediction.instance_size(), pretenure);
     617         196 :   a.Store(AccessBuilder::ForMap(), initial_map);
     618         196 :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     619         196 :   a.Store(AccessBuilder::ForJSObjectElements(), elements);
     620         196 :   a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
     621         476 :   for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
     622             :        ++i) {
     623             :     a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
     624          42 :             jsgraph()->UndefinedConstant());
     625             :   }
     626             :   RelaxControls(node);
     627         196 :   a.FinishAndChange(node);
     628             :   return Changed(node);
     629             : }
     630             : 
     631        6973 : Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) {
     632             :   DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
     633        1567 :   CreateArrayParameters const& p = CreateArrayParametersOf(node->op());
     634        1454 :   int const arity = static_cast<int>(p.arity());
     635        1454 :   base::Optional<AllocationSiteRef> site_ref;
     636             :   {
     637             :     Handle<AllocationSite> site;
     638        1454 :     if (p.site().ToHandle(&site)) {
     639         553 :       site_ref = AllocationSiteRef(broker(), site);
     640             :     }
     641             :   }
     642             :   PretenureFlag pretenure = NOT_TENURED;
     643        1454 :   JSFunctionRef constructor = native_context().array_function();
     644        1454 :   Node* target = NodeProperties::GetValueInput(node, 0);
     645        1454 :   Node* new_target = NodeProperties::GetValueInput(node, 1);
     646             :   Type new_target_type = (target == new_target)
     647             :                              ? Type::HeapConstant(constructor, zone())
     648        2544 :                              : NodeProperties::GetType(new_target);
     649             : 
     650             :   // Extract original constructor function.
     651        2908 :   if (new_target_type.IsHeapConstant() &&
     652        1454 :       new_target_type.AsHeapConstant()->Ref().IsJSFunction()) {
     653             :     JSFunctionRef original_constructor =
     654        1454 :         new_target_type.AsHeapConstant()->Ref().AsJSFunction();
     655             :     DCHECK(constructor.map().is_constructor());
     656             :     DCHECK(original_constructor.map().is_constructor());
     657             : 
     658             :     // Check if we can inline the allocation.
     659        1454 :     if (IsAllocationInlineable(constructor, original_constructor)) {
     660             :       SlackTrackingPrediction slack_tracking_prediction =
     661             :           dependencies()->DependOnInitialMapInstanceSizePrediction(
     662        1454 :               original_constructor);
     663        1454 :       MapRef initial_map = original_constructor.initial_map();
     664             : 
     665             :       // Tells whether we are protected by either the {site} or a
     666             :       // protector cell to do certain speculative optimizations.
     667             :       bool can_inline_call = false;
     668             : 
     669             :       // Check if we have a feedback {site} on the {node}.
     670        1454 :       ElementsKind elements_kind = initial_map.elements_kind();
     671        1454 :       if (site_ref) {
     672         553 :         elements_kind = site_ref->GetElementsKind();
     673         553 :         can_inline_call = site_ref->CanInlineCall();
     674         553 :         pretenure = dependencies()->DependOnPretenureMode(*site_ref);
     675         553 :         dependencies()->DependOnElementsKind(*site_ref);
     676             :       } else {
     677             :         CellRef array_constructor_protector(
     678             :             broker(), factory()->array_constructor_protector());
     679        1802 :         can_inline_call = array_constructor_protector.value().AsSmi() ==
     680         901 :                           Isolate::kProtectorValid;
     681             :       }
     682             : 
     683        1454 :       if (arity == 0) {
     684         415 :         Node* length = jsgraph()->ZeroConstant();
     685             :         int capacity = JSArray::kPreallocatedArrayElements;
     686             :         return ReduceNewArray(node, length, capacity, initial_map,
     687             :                               elements_kind, pretenure,
     688        1756 :                               slack_tracking_prediction);
     689        1039 :       } else if (arity == 1) {
     690         926 :         Node* length = NodeProperties::GetValueInput(node, 2);
     691         926 :         Type length_type = NodeProperties::GetType(length);
     692         926 :         if (!length_type.Maybe(Type::Number())) {
     693             :           // Handle the single argument case, where we know that the value
     694             :           // cannot be a valid Array length.
     695             :           elements_kind = GetMoreGeneralElementsKind(
     696             :               elements_kind, IsHoleyElementsKind(elements_kind)
     697             :                                  ? HOLEY_ELEMENTS
     698          91 :                                  : PACKED_ELEMENTS);
     699             :           return ReduceNewArray(node, std::vector<Node*>{length}, initial_map,
     700             :                                 elements_kind, pretenure,
     701         273 :                                 slack_tracking_prediction);
     702             :         }
     703        2266 :         if (length_type.Is(Type::SignedSmall()) && length_type.Min() >= 0 &&
     704        1756 :             length_type.Max() <= kElementLoopUnrollLimit &&
     705         215 :             length_type.Min() == length_type.Max()) {
     706         207 :           int capacity = static_cast<int>(length_type.Max());
     707             :           return ReduceNewArray(node, length, capacity, initial_map,
     708             :                                 elements_kind, pretenure,
     709         207 :                                 slack_tracking_prediction);
     710             :         }
     711         628 :         if (length_type.Maybe(Type::UnsignedSmall()) && can_inline_call) {
     712             :           return ReduceNewArray(node, length, initial_map, elements_kind,
     713         515 :                                 pretenure, slack_tracking_prediction);
     714             :         }
     715         113 :       } else if (arity <= JSArray::kInitialMaxFastElementArray) {
     716             :         // Gather the values to store into the newly created array.
     717             :         bool values_all_smis = true, values_all_numbers = true,
     718             :              values_any_nonnumber = false;
     719             :         std::vector<Node*> values;
     720         113 :         values.reserve(p.arity());
     721         596 :         for (int i = 0; i < arity; ++i) {
     722         483 :           Node* value = NodeProperties::GetValueInput(node, 2 + i);
     723         483 :           Type value_type = NodeProperties::GetType(value);
     724         483 :           if (!value_type.Is(Type::SignedSmall())) {
     725             :             values_all_smis = false;
     726             :           }
     727         483 :           if (!value_type.Is(Type::Number())) {
     728             :             values_all_numbers = false;
     729             :           }
     730         483 :           if (!value_type.Maybe(Type::Number())) {
     731             :             values_any_nonnumber = true;
     732             :           }
     733         483 :           values.push_back(value);
     734             :         }
     735             : 
     736             :         // Try to figure out the ideal elements kind statically.
     737         113 :         if (values_all_smis) {
     738             :           // Smis can be stored with any elements kind.
     739          79 :         } else if (values_all_numbers) {
     740             :           elements_kind = GetMoreGeneralElementsKind(
     741             :               elements_kind, IsHoleyElementsKind(elements_kind)
     742             :                                  ? HOLEY_DOUBLE_ELEMENTS
     743          19 :                                  : PACKED_DOUBLE_ELEMENTS);
     744          60 :         } else if (values_any_nonnumber) {
     745             :           elements_kind = GetMoreGeneralElementsKind(
     746             :               elements_kind, IsHoleyElementsKind(elements_kind)
     747             :                                  ? HOLEY_ELEMENTS
     748          39 :                                  : PACKED_ELEMENTS);
     749          21 :         } else if (!can_inline_call) {
     750             :           // We have some crazy combination of types for the {values} where
     751             :           // there's no clear decision on the elements kind statically. And
     752             :           // we don't have a protection against deoptimization loops for the
     753             :           // checks that are introduced in the call to ReduceNewArray, so
     754             :           // we cannot inline this invocation of the Array constructor here.
     755             :           return NoChange();
     756             :         }
     757             :         return ReduceNewArray(node, values, initial_map, elements_kind,
     758         210 :                               pretenure, slack_tracking_prediction);
     759             :       }
     760             :     }
     761             :   }
     762             :   return NoChange();
     763             : }
     764             : 
     765        7971 : Reduction JSCreateLowering::ReduceJSCreateArrayIterator(Node* node) {
     766             :   DCHECK_EQ(IrOpcode::kJSCreateArrayIterator, node->opcode());
     767             :   CreateArrayIteratorParameters const& p =
     768        1328 :       CreateArrayIteratorParametersOf(node->op());
     769        1328 :   Node* iterated_object = NodeProperties::GetValueInput(node, 0);
     770        1328 :   Node* effect = NodeProperties::GetEffectInput(node);
     771        1328 :   Node* control = NodeProperties::GetControlInput(node);
     772             : 
     773             :   // Create the JSArrayIterator result.
     774             :   AllocationBuilder a(jsgraph(), effect, control);
     775        1328 :   a.Allocate(JSArrayIterator::kSize, NOT_TENURED, Type::OtherObject());
     776             :   a.Store(AccessBuilder::ForMap(),
     777        1328 :           native_context().initial_array_iterator_map());
     778             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
     779        1329 :           jsgraph()->EmptyFixedArrayConstant());
     780             :   a.Store(AccessBuilder::ForJSObjectElements(),
     781        1328 :           jsgraph()->EmptyFixedArrayConstant());
     782        1329 :   a.Store(AccessBuilder::ForJSArrayIteratorIteratedObject(), iterated_object);
     783             :   a.Store(AccessBuilder::ForJSArrayIteratorNextIndex(),
     784        1329 :           jsgraph()->ZeroConstant());
     785             :   a.Store(AccessBuilder::ForJSArrayIteratorKind(),
     786        2658 :           jsgraph()->Constant(static_cast<int>(p.kind())));
     787             :   RelaxControls(node);
     788        1329 :   a.FinishAndChange(node);
     789        1329 :   return Changed(node);
     790             : }
     791             : 
     792       18673 : Reduction JSCreateLowering::ReduceJSCreateAsyncFunctionObject(Node* node) {
     793             :   DCHECK_EQ(IrOpcode::kJSCreateAsyncFunctionObject, node->opcode());
     794        1082 :   int const register_count = RegisterCountOf(node->op());
     795        1082 :   Node* closure = NodeProperties::GetValueInput(node, 0);
     796        1082 :   Node* receiver = NodeProperties::GetValueInput(node, 1);
     797        1082 :   Node* promise = NodeProperties::GetValueInput(node, 2);
     798        1082 :   Node* context = NodeProperties::GetContextInput(node);
     799        1082 :   Node* effect = NodeProperties::GetEffectInput(node);
     800        1082 :   Node* control = NodeProperties::GetControlInput(node);
     801             : 
     802             :   // Create the register file.
     803             :   AllocationBuilder ab(jsgraph(), effect, control);
     804        1082 :   ab.AllocateArray(register_count, factory()->fixed_array_map());
     805       12181 :   for (int i = 0; i < register_count; ++i) {
     806       11099 :     ab.Store(AccessBuilder::ForFixedArraySlot(i),
     807       22198 :              jsgraph()->UndefinedConstant());
     808             :   }
     809        1082 :   Node* parameters_and_registers = effect = ab.Finish();
     810             : 
     811             :   // Create the JSAsyncFunctionObject result.
     812             :   AllocationBuilder a(jsgraph(), effect, control);
     813        1082 :   a.Allocate(JSAsyncFunctionObject::kSize);
     814        1082 :   Node* empty_fixed_array = jsgraph()->EmptyFixedArrayConstant();
     815             :   a.Store(AccessBuilder::ForMap(),
     816        1082 :           native_context().async_function_object_map());
     817        1082 :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), empty_fixed_array);
     818        1082 :   a.Store(AccessBuilder::ForJSObjectElements(), empty_fixed_array);
     819        1082 :   a.Store(AccessBuilder::ForJSGeneratorObjectContext(), context);
     820        1082 :   a.Store(AccessBuilder::ForJSGeneratorObjectFunction(), closure);
     821        1082 :   a.Store(AccessBuilder::ForJSGeneratorObjectReceiver(), receiver);
     822             :   a.Store(AccessBuilder::ForJSGeneratorObjectInputOrDebugPos(),
     823        1082 :           jsgraph()->UndefinedConstant());
     824             :   a.Store(AccessBuilder::ForJSGeneratorObjectResumeMode(),
     825        1082 :           jsgraph()->Constant(JSGeneratorObject::kNext));
     826             :   a.Store(AccessBuilder::ForJSGeneratorObjectContinuation(),
     827        1082 :           jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting));
     828             :   a.Store(AccessBuilder::ForJSGeneratorObjectParametersAndRegisters(),
     829        1082 :           parameters_and_registers);
     830        1082 :   a.Store(AccessBuilder::ForJSAsyncFunctionObjectPromise(), promise);
     831        1082 :   a.FinishAndChange(node);
     832        1082 :   return Changed(node);
     833             : }
     834             : 
     835             : namespace {
     836             : 
     837         164 : MapRef MapForCollectionIterationKind(const NativeContextRef& native_context,
     838             :                                      CollectionKind collection_kind,
     839             :                                      IterationKind iteration_kind) {
     840         164 :   switch (collection_kind) {
     841             :     case CollectionKind::kSet:
     842          92 :       switch (iteration_kind) {
     843             :         case IterationKind::kKeys:
     844           0 :           UNREACHABLE();
     845             :         case IterationKind::kValues:
     846          78 :           return native_context.set_value_iterator_map();
     847             :         case IterationKind::kEntries:
     848          14 :           return native_context.set_key_value_iterator_map();
     849             :       }
     850             :       break;
     851             :     case CollectionKind::kMap:
     852          72 :       switch (iteration_kind) {
     853             :         case IterationKind::kKeys:
     854          15 :           return native_context.map_key_iterator_map();
     855             :         case IterationKind::kValues:
     856          35 :           return native_context.map_value_iterator_map();
     857             :         case IterationKind::kEntries:
     858          22 :           return native_context.map_key_value_iterator_map();
     859             :       }
     860             :       break;
     861             :   }
     862           0 :   UNREACHABLE();
     863             : }
     864             : 
     865             : }  // namespace
     866             : 
     867         820 : Reduction JSCreateLowering::ReduceJSCreateCollectionIterator(Node* node) {
     868             :   DCHECK_EQ(IrOpcode::kJSCreateCollectionIterator, node->opcode());
     869         164 :   CreateCollectionIteratorParameters const& p =
     870         164 :       CreateCollectionIteratorParametersOf(node->op());
     871         164 :   Node* iterated_object = NodeProperties::GetValueInput(node, 0);
     872         164 :   Node* effect = NodeProperties::GetEffectInput(node);
     873         164 :   Node* control = NodeProperties::GetControlInput(node);
     874             : 
     875             :   // Load the OrderedHashTable from the {receiver}.
     876             :   Node* table = effect = graph()->NewNode(
     877             :       simplified()->LoadField(AccessBuilder::ForJSCollectionTable()),
     878         492 :       iterated_object, effect, control);
     879             : 
     880             :   // Create the JSArrayIterator result.
     881             :   AllocationBuilder a(jsgraph(), effect, control);
     882         164 :   a.Allocate(JSCollectionIterator::kSize, NOT_TENURED, Type::OtherObject());
     883             :   a.Store(AccessBuilder::ForMap(),
     884             :           MapForCollectionIterationKind(native_context(), p.collection_kind(),
     885         164 :                                         p.iteration_kind()));
     886             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
     887         164 :           jsgraph()->EmptyFixedArrayConstant());
     888             :   a.Store(AccessBuilder::ForJSObjectElements(),
     889         164 :           jsgraph()->EmptyFixedArrayConstant());
     890         164 :   a.Store(AccessBuilder::ForJSCollectionIteratorTable(), table);
     891             :   a.Store(AccessBuilder::ForJSCollectionIteratorIndex(),
     892         164 :           jsgraph()->ZeroConstant());
     893             :   RelaxControls(node);
     894         164 :   a.FinishAndChange(node);
     895         164 :   return Changed(node);
     896             : }
     897             : 
     898         695 : Reduction JSCreateLowering::ReduceJSCreateBoundFunction(Node* node) {
     899             :   DCHECK_EQ(IrOpcode::kJSCreateBoundFunction, node->opcode());
     900         105 :   CreateBoundFunctionParameters const& p =
     901         105 :       CreateBoundFunctionParametersOf(node->op());
     902         105 :   int const arity = static_cast<int>(p.arity());
     903             :   MapRef const map(broker(), p.map());
     904         105 :   Node* bound_target_function = NodeProperties::GetValueInput(node, 0);
     905         105 :   Node* bound_this = NodeProperties::GetValueInput(node, 1);
     906         105 :   Node* effect = NodeProperties::GetEffectInput(node);
     907         105 :   Node* control = NodeProperties::GetControlInput(node);
     908             : 
     909             :   // Create the [[BoundArguments]] for the result.
     910         105 :   Node* bound_arguments = jsgraph()->EmptyFixedArrayConstant();
     911         105 :   if (arity > 0) {
     912             :     AllocationBuilder a(jsgraph(), effect, control);
     913          65 :     a.AllocateArray(arity, factory()->fixed_array_map());
     914         152 :     for (int i = 0; i < arity; ++i) {
     915          87 :       a.Store(AccessBuilder::ForFixedArraySlot(i),
     916         174 :               NodeProperties::GetValueInput(node, 2 + i));
     917             :     }
     918          65 :     bound_arguments = effect = a.Finish();
     919             :   }
     920             : 
     921             :   // Create the JSBoundFunction result.
     922             :   AllocationBuilder a(jsgraph(), effect, control);
     923         105 :   a.Allocate(JSBoundFunction::kSize, NOT_TENURED, Type::BoundFunction());
     924         105 :   a.Store(AccessBuilder::ForMap(), map);
     925             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
     926         105 :           jsgraph()->EmptyFixedArrayConstant());
     927             :   a.Store(AccessBuilder::ForJSObjectElements(),
     928         105 :           jsgraph()->EmptyFixedArrayConstant());
     929             :   a.Store(AccessBuilder::ForJSBoundFunctionBoundTargetFunction(),
     930         105 :           bound_target_function);
     931         105 :   a.Store(AccessBuilder::ForJSBoundFunctionBoundThis(), bound_this);
     932         105 :   a.Store(AccessBuilder::ForJSBoundFunctionBoundArguments(), bound_arguments);
     933             :   RelaxControls(node);
     934         105 :   a.FinishAndChange(node);
     935         105 :   return Changed(node);
     936             : }
     937             : 
     938     2204109 : Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
     939             :   DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode());
     940      420922 :   CreateClosureParameters const& p = CreateClosureParametersOf(node->op());
     941             :   SharedFunctionInfoRef shared(broker(), p.shared_info());
     942             :   HeapObjectRef feedback_cell(broker(), p.feedback_cell());
     943             :   HeapObjectRef code(broker(), p.code());
     944      420933 :   Node* effect = NodeProperties::GetEffectInput(node);
     945      420934 :   Node* control = NodeProperties::GetControlInput(node);
     946      420934 :   Node* context = NodeProperties::GetContextInput(node);
     947             : 
     948             :   // Use inline allocation of closures only for instantiation sites that have
     949             :   // seen more than one instantiation, this simplifies the generated code and
     950             :   // also serves as a heuristic of which allocation sites benefit from it.
     951      420932 :   if (!feedback_cell.map().equals(
     952      420933 :           MapRef(broker(), factory()->many_closures_cell_map()))) {
     953             :     return NoChange();
     954             :   }
     955             : 
     956             :   MapRef function_map =
     957       64670 :       native_context().GetFunctionMapFromIndex(shared.function_map_index());
     958             :   DCHECK(!function_map.IsInobjectSlackTrackingInProgress());
     959             :   DCHECK(!function_map.is_dictionary_map());
     960             : 
     961             :   // TODO(turbofan): We should use the pretenure flag from {p} here,
     962             :   // but currently the heuristic in the parser works against us, as
     963             :   // it marks closures like
     964             :   //
     965             :   //   args[l] = function(...) { ... }
     966             :   //
     967             :   // for old-space allocation, which doesn't always make sense. For
     968             :   // example in case of the bluebird-parallel benchmark, where this
     969             :   // is a core part of the *promisify* logic (see crbug.com/810132).
     970             :   PretenureFlag pretenure = NOT_TENURED;
     971             : 
     972             :   // Emit code to allocate the JSFunction instance.
     973             :   STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kTaggedSize);
     974             :   AllocationBuilder a(jsgraph(), effect, control);
     975       32335 :   a.Allocate(function_map.instance_size(), pretenure, Type::Function());
     976       32335 :   a.Store(AccessBuilder::ForMap(), function_map);
     977             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
     978       32335 :           jsgraph()->EmptyFixedArrayConstant());
     979             :   a.Store(AccessBuilder::ForJSObjectElements(),
     980       32335 :           jsgraph()->EmptyFixedArrayConstant());
     981       32335 :   a.Store(AccessBuilder::ForJSFunctionSharedFunctionInfo(), shared);
     982       32335 :   a.Store(AccessBuilder::ForJSFunctionContext(), context);
     983       32335 :   a.Store(AccessBuilder::ForJSFunctionFeedbackCell(), feedback_cell);
     984       32335 :   a.Store(AccessBuilder::ForJSFunctionCode(), code);
     985             :   STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kTaggedSize);
     986       32335 :   if (function_map.has_prototype_slot()) {
     987             :     a.Store(AccessBuilder::ForJSFunctionPrototypeOrInitialMap(),
     988        2412 :             jsgraph()->TheHoleConstant());
     989             :     STATIC_ASSERT(JSFunction::kSizeWithPrototype == 8 * kTaggedSize);
     990             :   }
     991          39 :   for (int i = 0; i < function_map.GetInObjectProperties(); i++) {
     992             :     a.Store(AccessBuilder::ForJSObjectInObjectProperty(function_map, i),
     993          39 :             jsgraph()->UndefinedConstant());
     994             :   }
     995             :   RelaxControls(node);
     996       32335 :   a.FinishAndChange(node);
     997             :   return Changed(node);
     998             : }
     999             : 
    1000       12700 : Reduction JSCreateLowering::ReduceJSCreateIterResultObject(Node* node) {
    1001             :   DCHECK_EQ(IrOpcode::kJSCreateIterResultObject, node->opcode());
    1002        3175 :   Node* value = NodeProperties::GetValueInput(node, 0);
    1003        3175 :   Node* done = NodeProperties::GetValueInput(node, 1);
    1004        3175 :   Node* effect = NodeProperties::GetEffectInput(node);
    1005             : 
    1006             :   Node* iterator_result_map =
    1007        6350 :       jsgraph()->Constant(native_context().iterator_result_map());
    1008             : 
    1009             :   // Emit code to allocate the JSIteratorResult instance.
    1010        3175 :   AllocationBuilder a(jsgraph(), effect, graph()->start());
    1011        3175 :   a.Allocate(JSIteratorResult::kSize);
    1012        3175 :   a.Store(AccessBuilder::ForMap(), iterator_result_map);
    1013             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
    1014        3175 :           jsgraph()->EmptyFixedArrayConstant());
    1015             :   a.Store(AccessBuilder::ForJSObjectElements(),
    1016        3175 :           jsgraph()->EmptyFixedArrayConstant());
    1017        3175 :   a.Store(AccessBuilder::ForJSIteratorResultValue(), value);
    1018        3175 :   a.Store(AccessBuilder::ForJSIteratorResultDone(), done);
    1019             :   STATIC_ASSERT(JSIteratorResult::kSize == 5 * kTaggedSize);
    1020        3175 :   a.FinishAndChange(node);
    1021        3175 :   return Changed(node);
    1022             : }
    1023             : 
    1024         335 : Reduction JSCreateLowering::ReduceJSCreateStringIterator(Node* node) {
    1025             :   DCHECK_EQ(IrOpcode::kJSCreateStringIterator, node->opcode());
    1026          67 :   Node* string = NodeProperties::GetValueInput(node, 0);
    1027          67 :   Node* effect = NodeProperties::GetEffectInput(node);
    1028             : 
    1029             :   Node* map =
    1030         134 :       jsgraph()->Constant(native_context().initial_string_iterator_map());
    1031             :   // Allocate new iterator and attach the iterator to this string.
    1032          67 :   AllocationBuilder a(jsgraph(), effect, graph()->start());
    1033          67 :   a.Allocate(JSStringIterator::kSize, NOT_TENURED, Type::OtherObject());
    1034          67 :   a.Store(AccessBuilder::ForMap(), map);
    1035             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
    1036          67 :           jsgraph()->EmptyFixedArrayConstant());
    1037             :   a.Store(AccessBuilder::ForJSObjectElements(),
    1038          67 :           jsgraph()->EmptyFixedArrayConstant());
    1039          67 :   a.Store(AccessBuilder::ForJSStringIteratorString(), string);
    1040          67 :   a.Store(AccessBuilder::ForJSStringIteratorIndex(), jsgraph()->SmiConstant(0));
    1041             :   STATIC_ASSERT(JSIteratorResult::kSize == 5 * kTaggedSize);
    1042          67 :   a.FinishAndChange(node);
    1043          67 :   return Changed(node);
    1044             : }
    1045             : 
    1046         546 : Reduction JSCreateLowering::ReduceJSCreateKeyValueArray(Node* node) {
    1047             :   DCHECK_EQ(IrOpcode::kJSCreateKeyValueArray, node->opcode());
    1048          91 :   Node* key = NodeProperties::GetValueInput(node, 0);
    1049          91 :   Node* value = NodeProperties::GetValueInput(node, 1);
    1050          91 :   Node* effect = NodeProperties::GetEffectInput(node);
    1051             : 
    1052             :   Node* array_map =
    1053         182 :       jsgraph()->Constant(native_context().js_array_packed_elements_map());
    1054          91 :   Node* properties = jsgraph()->EmptyFixedArrayConstant();
    1055          91 :   Node* length = jsgraph()->Constant(2);
    1056             : 
    1057          91 :   AllocationBuilder aa(jsgraph(), effect, graph()->start());
    1058          91 :   aa.AllocateArray(2, factory()->fixed_array_map());
    1059             :   aa.Store(AccessBuilder::ForFixedArrayElement(PACKED_ELEMENTS),
    1060          91 :            jsgraph()->ZeroConstant(), key);
    1061             :   aa.Store(AccessBuilder::ForFixedArrayElement(PACKED_ELEMENTS),
    1062          91 :            jsgraph()->OneConstant(), value);
    1063          91 :   Node* elements = aa.Finish();
    1064             : 
    1065          91 :   AllocationBuilder a(jsgraph(), elements, graph()->start());
    1066          91 :   a.Allocate(JSArray::kSize);
    1067          91 :   a.Store(AccessBuilder::ForMap(), array_map);
    1068          91 :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
    1069          91 :   a.Store(AccessBuilder::ForJSObjectElements(), elements);
    1070          91 :   a.Store(AccessBuilder::ForJSArrayLength(PACKED_ELEMENTS), length);
    1071             :   STATIC_ASSERT(JSArray::kSize == 4 * kTaggedSize);
    1072          91 :   a.FinishAndChange(node);
    1073          91 :   return Changed(node);
    1074             : }
    1075             : 
    1076        7015 : Reduction JSCreateLowering::ReduceJSCreatePromise(Node* node) {
    1077             :   DCHECK_EQ(IrOpcode::kJSCreatePromise, node->opcode());
    1078        1403 :   Node* effect = NodeProperties::GetEffectInput(node);
    1079             : 
    1080        1403 :   MapRef promise_map = native_context().promise_function().initial_map();
    1081             : 
    1082        1403 :   AllocationBuilder a(jsgraph(), effect, graph()->start());
    1083        1403 :   a.Allocate(promise_map.instance_size());
    1084        1403 :   a.Store(AccessBuilder::ForMap(), promise_map);
    1085             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
    1086        1403 :           jsgraph()->EmptyFixedArrayConstant());
    1087             :   a.Store(AccessBuilder::ForJSObjectElements(),
    1088        1403 :           jsgraph()->EmptyFixedArrayConstant());
    1089             :   a.Store(AccessBuilder::ForJSObjectOffset(JSPromise::kReactionsOrResultOffset),
    1090        1403 :           jsgraph()->ZeroConstant());
    1091             :   STATIC_ASSERT(v8::Promise::kPending == 0);
    1092             :   a.Store(AccessBuilder::ForJSObjectOffset(JSPromise::kFlagsOffset),
    1093        1403 :           jsgraph()->ZeroConstant());
    1094             :   STATIC_ASSERT(JSPromise::kSize == 5 * kTaggedSize);
    1095             :   for (int offset = JSPromise::kSize;
    1096             :        offset < JSPromise::kSizeWithEmbedderFields; offset += kTaggedSize) {
    1097             :     a.Store(AccessBuilder::ForJSObjectOffset(offset),
    1098             :             jsgraph()->ZeroConstant());
    1099             :   }
    1100        1403 :   a.FinishAndChange(node);
    1101        1403 :   return Changed(node);
    1102             : }
    1103             : 
    1104       58215 : Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
    1105             :   DCHECK(node->opcode() == IrOpcode::kJSCreateLiteralArray ||
    1106             :          node->opcode() == IrOpcode::kJSCreateLiteralObject);
    1107       23137 :   CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
    1108       23137 :   Node* effect = NodeProperties::GetEffectInput(node);
    1109       23138 :   Node* control = NodeProperties::GetControlInput(node);
    1110             : 
    1111             :   FeedbackVectorRef feedback_vector(broker(), p.feedback().vector());
    1112       23138 :   ObjectRef feedback = feedback_vector.get(p.feedback().slot());
    1113       23138 :   if (feedback.IsAllocationSite()) {
    1114        6190 :     AllocationSiteRef site = feedback.AsAllocationSite();
    1115        6190 :     if (site.IsFastLiteral()) {
    1116             :       PretenureFlag pretenure = NOT_TENURED;
    1117        5970 :       if (FLAG_allocation_site_pretenuring) {
    1118        5970 :         pretenure = dependencies()->DependOnPretenureMode(site);
    1119             :       }
    1120        5970 :       dependencies()->DependOnElementsKinds(site);
    1121        5970 :       JSObjectRef boilerplate = site.boilerplate().value();
    1122             :       Node* value = effect =
    1123        5970 :           AllocateFastLiteral(effect, control, boilerplate, pretenure);
    1124        5970 :       ReplaceWithValue(node, value, effect, control);
    1125             :       return Replace(value);
    1126             :     }
    1127             :   }
    1128             :   return NoChange();
    1129             : }
    1130             : 
    1131       45816 : Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) {
    1132             :   DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralArray, node->opcode());
    1133       21315 :   FeedbackParameter const& p = FeedbackParameterOf(node->op());
    1134             :   FeedbackVectorRef fv(broker(), p.feedback().vector());
    1135       21315 :   ObjectRef feedback = fv.get(p.feedback().slot());
    1136       21315 :   if (feedback.IsAllocationSite()) {
    1137        1062 :     AllocationSiteRef site = feedback.AsAllocationSite();
    1138             :     DCHECK(!site.PointsToLiteral());
    1139             :     MapRef initial_map =
    1140        2124 :         native_context().GetInitialJSArrayMap(site.GetElementsKind());
    1141        1062 :     PretenureFlag const pretenure = dependencies()->DependOnPretenureMode(site);
    1142        1062 :     dependencies()->DependOnElementsKind(site);
    1143        1062 :     Node* length = jsgraph()->ZeroConstant();
    1144             :     DCHECK(!initial_map.IsInobjectSlackTrackingInProgress());
    1145             :     SlackTrackingPrediction slack_tracking_prediction(
    1146        1062 :         initial_map, initial_map.instance_size());
    1147             :     return ReduceNewArray(node, length, 0, initial_map,
    1148        1062 :                           initial_map.elements_kind(), pretenure,
    1149        1062 :                           slack_tracking_prediction);
    1150             :   }
    1151             :   return NoChange();
    1152             : }
    1153             : 
    1154       53937 : Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralObject(Node* node) {
    1155             :   DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralObject, node->opcode());
    1156        5993 :   Node* effect = NodeProperties::GetEffectInput(node);
    1157        5993 :   Node* control = NodeProperties::GetControlInput(node);
    1158             : 
    1159             :   // Retrieve the initial map for the object.
    1160        5993 :   MapRef map = native_context().object_function().initial_map();
    1161             :   DCHECK(!map.is_dictionary_map());
    1162             :   DCHECK(!map.IsInobjectSlackTrackingInProgress());
    1163        5993 :   Node* js_object_map = jsgraph()->Constant(map);
    1164             : 
    1165             :   // Setup elements and properties.
    1166        5993 :   Node* elements = jsgraph()->EmptyFixedArrayConstant();
    1167        5993 :   Node* properties = jsgraph()->EmptyFixedArrayConstant();
    1168             : 
    1169             :   // Perform the allocation of the actual JSArray object.
    1170             :   AllocationBuilder a(jsgraph(), effect, control);
    1171        5993 :   a.Allocate(map.instance_size());
    1172        5993 :   a.Store(AccessBuilder::ForMap(), js_object_map);
    1173        5993 :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
    1174        5993 :   a.Store(AccessBuilder::ForJSObjectElements(), elements);
    1175       29965 :   for (int i = 0; i < map.GetInObjectProperties(); i++) {
    1176             :     a.Store(AccessBuilder::ForJSObjectInObjectProperty(map, i),
    1177       23972 :             jsgraph()->UndefinedConstant());
    1178             :   }
    1179             : 
    1180             :   RelaxControls(node);
    1181        5993 :   a.FinishAndChange(node);
    1182        5993 :   return Changed(node);
    1183             : }
    1184             : 
    1185       12928 : Reduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) {
    1186             :   DCHECK_EQ(IrOpcode::kJSCreateLiteralRegExp, node->opcode());
    1187        6464 :   CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
    1188        6464 :   Node* effect = NodeProperties::GetEffectInput(node);
    1189        6464 :   Node* control = NodeProperties::GetControlInput(node);
    1190             : 
    1191             :   FeedbackVectorRef feedback_vector(broker(), p.feedback().vector());
    1192        6464 :   ObjectRef feedback = feedback_vector.get(p.feedback().slot());
    1193        6464 :   if (feedback.IsJSRegExp()) {
    1194         602 :     JSRegExpRef boilerplate = feedback.AsJSRegExp();
    1195         602 :     Node* value = effect = AllocateLiteralRegExp(effect, control, boilerplate);
    1196         602 :     ReplaceWithValue(node, value, effect, control);
    1197             :     return Replace(value);
    1198             :   }
    1199             :   return NoChange();
    1200             : }
    1201             : 
    1202      196056 : Reduction JSCreateLowering::ReduceJSCreateFunctionContext(Node* node) {
    1203             :   DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode());
    1204       29355 :   const CreateFunctionContextParameters& parameters =
    1205       29355 :       CreateFunctionContextParametersOf(node->op());
    1206             :   ScopeInfoRef scope_info(broker(), parameters.scope_info());
    1207             :   int slot_count = parameters.slot_count();
    1208             :   ScopeType scope_type = parameters.scope_type();
    1209             : 
    1210             :   // Use inline allocation for function contexts up to a size limit.
    1211       29355 :   if (slot_count < kFunctionContextAllocationLimit) {
    1212             :     // JSCreateFunctionContext[slot_count < limit]](fun)
    1213       24721 :     Node* effect = NodeProperties::GetEffectInput(node);
    1214       24721 :     Node* control = NodeProperties::GetControlInput(node);
    1215       24721 :     Node* context = NodeProperties::GetContextInput(node);
    1216       24721 :     Node* extension = jsgraph()->TheHoleConstant();
    1217             :     AllocationBuilder a(jsgraph(), effect, control);
    1218             :     STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);  // Ensure fully covered.
    1219       24721 :     int context_length = slot_count + Context::MIN_CONTEXT_SLOTS;
    1220             :     Handle<Map> map;
    1221       24721 :     switch (scope_type) {
    1222             :       case EVAL_SCOPE:
    1223        5623 :         map = factory()->eval_context_map();
    1224        5623 :         break;
    1225             :       case FUNCTION_SCOPE:
    1226       19098 :         map = factory()->function_context_map();
    1227       19098 :         break;
    1228             :       default:
    1229           0 :         UNREACHABLE();
    1230             :     }
    1231       24721 :     a.AllocateContext(context_length, map);
    1232             :     a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX),
    1233       24721 :             scope_info);
    1234       24721 :     a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
    1235       24721 :     a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
    1236             :     a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
    1237       49442 :             jsgraph()->Constant(native_context()));
    1238       87904 :     for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) {
    1239       63183 :       a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant());
    1240             :     }
    1241             :     RelaxControls(node);
    1242       24721 :     a.FinishAndChange(node);
    1243             :     return Changed(node);
    1244             :   }
    1245             : 
    1246             :   return NoChange();
    1247             : }
    1248             : 
    1249        1968 : Reduction JSCreateLowering::ReduceJSCreateWithContext(Node* node) {
    1250             :   DCHECK_EQ(IrOpcode::kJSCreateWithContext, node->opcode());
    1251         492 :   ScopeInfoRef scope_info(broker(), ScopeInfoOf(node->op()));
    1252         492 :   Node* extension = NodeProperties::GetValueInput(node, 0);
    1253         492 :   Node* effect = NodeProperties::GetEffectInput(node);
    1254         492 :   Node* control = NodeProperties::GetControlInput(node);
    1255         492 :   Node* context = NodeProperties::GetContextInput(node);
    1256             : 
    1257             :   AllocationBuilder a(jsgraph(), effect, control);
    1258             :   STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);  // Ensure fully covered.
    1259         492 :   a.AllocateContext(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map());
    1260         492 :   a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX), scope_info);
    1261         492 :   a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
    1262         492 :   a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
    1263             :   a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
    1264         984 :           jsgraph()->Constant(native_context()));
    1265             :   RelaxControls(node);
    1266         492 :   a.FinishAndChange(node);
    1267         492 :   return Changed(node);
    1268             : }
    1269             : 
    1270       70595 : Reduction JSCreateLowering::ReduceJSCreateCatchContext(Node* node) {
    1271             :   DCHECK_EQ(IrOpcode::kJSCreateCatchContext, node->opcode());
    1272       14119 :   ScopeInfoRef scope_info(broker(), ScopeInfoOf(node->op()));
    1273       14119 :   Node* exception = NodeProperties::GetValueInput(node, 0);
    1274       14119 :   Node* effect = NodeProperties::GetEffectInput(node);
    1275       14119 :   Node* control = NodeProperties::GetControlInput(node);
    1276       14119 :   Node* context = NodeProperties::GetContextInput(node);
    1277       14119 :   Node* extension = jsgraph()->TheHoleConstant();
    1278             : 
    1279             :   AllocationBuilder a(jsgraph(), effect, control);
    1280             :   STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);  // Ensure fully covered.
    1281             :   a.AllocateContext(Context::MIN_CONTEXT_SLOTS + 1,
    1282       14119 :                     factory()->catch_context_map());
    1283       14119 :   a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX), scope_info);
    1284       14119 :   a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
    1285       14119 :   a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
    1286             :   a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
    1287       28238 :           jsgraph()->Constant(native_context()));
    1288             :   a.Store(AccessBuilder::ForContextSlot(Context::THROWN_OBJECT_INDEX),
    1289       14119 :           exception);
    1290             :   RelaxControls(node);
    1291       14119 :   a.FinishAndChange(node);
    1292       14119 :   return Changed(node);
    1293             : }
    1294             : 
    1295       51767 : Reduction JSCreateLowering::ReduceJSCreateBlockContext(Node* node) {
    1296             :   DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode());
    1297        8845 :   ScopeInfoRef scope_info(broker(), ScopeInfoOf(node->op()));
    1298        8845 :   int const context_length = scope_info.ContextLength();
    1299             : 
    1300             :   // Use inline allocation for block contexts up to a size limit.
    1301        8845 :   if (context_length < kBlockContextAllocationLimit) {
    1302             :     // JSCreateBlockContext[scope[length < limit]](fun)
    1303        8845 :     Node* effect = NodeProperties::GetEffectInput(node);
    1304        8845 :     Node* control = NodeProperties::GetControlInput(node);
    1305        8845 :     Node* context = NodeProperties::GetContextInput(node);
    1306        8845 :     Node* extension = jsgraph()->TheHoleConstant();
    1307             : 
    1308             :     AllocationBuilder a(jsgraph(), effect, control);
    1309             :     STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);  // Ensure fully covered.
    1310        8845 :     a.AllocateContext(context_length, factory()->block_context_map());
    1311             :     a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX),
    1312        8845 :             scope_info);
    1313        8845 :     a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
    1314        8845 :     a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
    1315             :     a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
    1316       17690 :             jsgraph()->Constant(native_context()));
    1317       16387 :     for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) {
    1318        7542 :       a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant());
    1319             :     }
    1320             :     RelaxControls(node);
    1321        8845 :     a.FinishAndChange(node);
    1322             :     return Changed(node);
    1323             :   }
    1324             : 
    1325             :   return NoChange();
    1326             : }
    1327             : 
    1328             : namespace {
    1329          37 : base::Optional<MapRef> GetObjectCreateMap(JSHeapBroker* broker,
    1330             :                                           HeapObjectRef prototype) {
    1331             :   MapRef standard_map =
    1332          37 :       broker->native_context().object_function().initial_map();
    1333          37 :   if (prototype.equals(standard_map.prototype())) {
    1334             :     return standard_map;
    1335             :   }
    1336          30 :   if (prototype.map().oddball_type() == OddballType::kNull) {
    1337          30 :     return broker->native_context().slow_object_with_null_prototype_map();
    1338             :   }
    1339          15 :   if (prototype.IsJSObject()) {
    1340          15 :     return prototype.AsJSObject().GetObjectCreateMap();
    1341             :   }
    1342           0 :   return base::Optional<MapRef>();
    1343             : }
    1344             : }  // namespace
    1345             : 
    1346         363 : Reduction JSCreateLowering::ReduceJSCreateObject(Node* node) {
    1347             :   DCHECK_EQ(IrOpcode::kJSCreateObject, node->opcode());
    1348          75 :   Node* effect = NodeProperties::GetEffectInput(node);
    1349          75 :   Node* control = NodeProperties::GetControlInput(node);
    1350          75 :   Node* prototype = NodeProperties::GetValueInput(node, 0);
    1351          75 :   Type prototype_type = NodeProperties::GetType(prototype);
    1352          75 :   if (!prototype_type.IsHeapConstant()) return NoChange();
    1353             : 
    1354          37 :   HeapObjectRef prototype_const = prototype_type.AsHeapConstant()->Ref();
    1355          37 :   auto maybe_instance_map = GetObjectCreateMap(broker(), prototype_const);
    1356          37 :   if (!maybe_instance_map) return NoChange();
    1357          29 :   MapRef instance_map = maybe_instance_map.value();
    1358             : 
    1359          29 :   Node* properties = jsgraph()->EmptyFixedArrayConstant();
    1360          29 :   if (instance_map.is_dictionary_map()) {
    1361             :     DCHECK_EQ(prototype_const.map().oddball_type(), OddballType::kNull);
    1362             :     // Allocate an empty NameDictionary as backing store for the properties.
    1363             :     MapRef map(broker(), factory()->name_dictionary_map());
    1364             :     int capacity =
    1365             :         NameDictionary::ComputeCapacity(NameDictionary::kInitialCapacity);
    1366             :     DCHECK(base::bits::IsPowerOfTwo(capacity));
    1367             :     int length = NameDictionary::EntryToIndex(capacity);
    1368             :     int size = NameDictionary::SizeFor(length);
    1369             : 
    1370             :     AllocationBuilder a(jsgraph(), effect, control);
    1371          15 :     a.Allocate(size, NOT_TENURED, Type::Any());
    1372          15 :     a.Store(AccessBuilder::ForMap(), map);
    1373             :     // Initialize FixedArray fields.
    1374             :     a.Store(AccessBuilder::ForFixedArrayLength(),
    1375          15 :             jsgraph()->SmiConstant(length));
    1376             :     // Initialize HashTable fields.
    1377             :     a.Store(AccessBuilder::ForHashTableBaseNumberOfElements(),
    1378          15 :             jsgraph()->SmiConstant(0));
    1379             :     a.Store(AccessBuilder::ForHashTableBaseNumberOfDeletedElement(),
    1380          15 :             jsgraph()->SmiConstant(0));
    1381             :     a.Store(AccessBuilder::ForHashTableBaseCapacity(),
    1382          15 :             jsgraph()->SmiConstant(capacity));
    1383             :     // Initialize Dictionary fields.
    1384             :     a.Store(AccessBuilder::ForDictionaryNextEnumerationIndex(),
    1385          15 :             jsgraph()->SmiConstant(PropertyDetails::kInitialIndex));
    1386             :     a.Store(AccessBuilder::ForDictionaryObjectHashIndex(),
    1387          15 :             jsgraph()->SmiConstant(PropertyArray::kNoHashSentinel));
    1388             :     // Initialize the Properties fields.
    1389          15 :     Node* undefined = jsgraph()->UndefinedConstant();
    1390             :     STATIC_ASSERT(NameDictionary::kElementsStartIndex ==
    1391             :                   NameDictionary::kObjectHashIndex + 1);
    1392         195 :     for (int index = NameDictionary::kElementsStartIndex; index < length;
    1393             :          index++) {
    1394         180 :       a.Store(AccessBuilder::ForFixedArraySlot(index, kNoWriteBarrier),
    1395         180 :               undefined);
    1396             :     }
    1397          15 :     properties = effect = a.Finish();
    1398             :   }
    1399             : 
    1400          29 :   int const instance_size = instance_map.instance_size();
    1401          29 :   if (instance_size > kMaxRegularHeapObjectSize) return NoChange();
    1402          29 :   CHECK(!instance_map.IsInobjectSlackTrackingInProgress());
    1403             : 
    1404             :   // Emit code to allocate the JSObject instance for the given
    1405             :   // {instance_map}.
    1406             :   AllocationBuilder a(jsgraph(), effect, control);
    1407          29 :   a.Allocate(instance_size, NOT_TENURED, Type::Any());
    1408          29 :   a.Store(AccessBuilder::ForMap(), instance_map);
    1409          29 :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
    1410             :   a.Store(AccessBuilder::ForJSObjectElements(),
    1411          29 :           jsgraph()->EmptyFixedArrayConstant());
    1412             :   // Initialize Object fields.
    1413          29 :   Node* undefined = jsgraph()->UndefinedConstant();
    1414          85 :   for (int offset = JSObject::kHeaderSize; offset < instance_size;
    1415             :        offset += kTaggedSize) {
    1416             :     a.Store(AccessBuilder::ForJSObjectOffset(offset, kNoWriteBarrier),
    1417          56 :             undefined);
    1418             :   }
    1419          29 :   Node* value = effect = a.Finish();
    1420             : 
    1421          29 :   ReplaceWithValue(node, value, effect, control);
    1422             :   return Replace(value);
    1423             : }
    1424             : 
    1425             : // Helper that allocates a FixedArray holding argument values recorded in the
    1426             : // given {frame_state}. Serves as backing store for JSCreateArguments nodes.
    1427         597 : Node* JSCreateLowering::AllocateArguments(Node* effect, Node* control,
    1428        2514 :                                           Node* frame_state) {
    1429         597 :   FrameStateInfo state_info = FrameStateInfoOf(frame_state->op());
    1430         597 :   int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
    1431         636 :   if (argument_count == 0) return jsgraph()->EmptyFixedArrayConstant();
    1432             : 
    1433             :   // Prepare an iterator over argument values recorded in the frame state.
    1434             :   Node* const parameters = frame_state->InputAt(kFrameStateParametersInput);
    1435             :   StateValuesAccess parameters_access(parameters);
    1436         558 :   auto parameters_it = ++parameters_access.begin();
    1437             : 
    1438             :   // Actually allocate the backing store.
    1439             :   AllocationBuilder a(jsgraph(), effect, control);
    1440         558 :   a.AllocateArray(argument_count, factory()->fixed_array_map());
    1441        1878 :   for (int i = 0; i < argument_count; ++i, ++parameters_it) {
    1442             :     DCHECK_NOT_NULL((*parameters_it).node);
    1443             :     a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
    1444        2640 :             (*parameters_it).node);
    1445             :   }
    1446         558 :   return a.Finish();
    1447             : }
    1448             : 
    1449             : // Helper that allocates a FixedArray holding argument values recorded in the
    1450             : // given {frame_state}. Serves as backing store for JSCreateArguments nodes.
    1451         526 : Node* JSCreateLowering::AllocateRestArguments(Node* effect, Node* control,
    1452         526 :                                               Node* frame_state,
    1453        1033 :                                               int start_index) {
    1454         526 :   FrameStateInfo state_info = FrameStateInfoOf(frame_state->op());
    1455         526 :   int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
    1456        1052 :   int num_elements = std::max(0, argument_count - start_index);
    1457         795 :   if (num_elements == 0) return jsgraph()->EmptyFixedArrayConstant();
    1458             : 
    1459             :   // Prepare an iterator over argument values recorded in the frame state.
    1460             :   Node* const parameters = frame_state->InputAt(kFrameStateParametersInput);
    1461             :   StateValuesAccess parameters_access(parameters);
    1462         257 :   auto parameters_it = ++parameters_access.begin();
    1463             : 
    1464             :   // Skip unused arguments.
    1465         395 :   for (int i = 0; i < start_index; i++) {
    1466         138 :     ++parameters_it;
    1467             :   }
    1468             : 
    1469             :   // Actually allocate the backing store.
    1470             :   AllocationBuilder a(jsgraph(), effect, control);
    1471         257 :   a.AllocateArray(num_elements, factory()->fixed_array_map());
    1472         764 :   for (int i = 0; i < num_elements; ++i, ++parameters_it) {
    1473             :     DCHECK_NOT_NULL((*parameters_it).node);
    1474             :     a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
    1475        1014 :             (*parameters_it).node);
    1476             :   }
    1477         257 :   return a.Finish();
    1478             : }
    1479             : 
    1480             : // Helper that allocates a FixedArray serving as a parameter map for values
    1481             : // recorded in the given {frame_state}. Some elements map to slots within the
    1482             : // given {context}. Serves as backing store for JSCreateArguments nodes.
    1483         638 : Node* JSCreateLowering::AllocateAliasedArguments(
    1484         638 :     Node* effect, Node* control, Node* frame_state, Node* context,
    1485        4050 :     const SharedFunctionInfoRef& shared, bool* has_aliased_arguments) {
    1486         638 :   FrameStateInfo state_info = FrameStateInfoOf(frame_state->op());
    1487         638 :   int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
    1488         749 :   if (argument_count == 0) return jsgraph()->EmptyFixedArrayConstant();
    1489             : 
    1490             :   // If there is no aliasing, the arguments object elements are not special in
    1491             :   // any way, we can just return an unmapped backing store instead.
    1492         527 :   int parameter_count = shared.internal_formal_parameter_count();
    1493         527 :   if (parameter_count == 0) {
    1494         177 :     return AllocateArguments(effect, control, frame_state);
    1495             :   }
    1496             : 
    1497             :   // Calculate number of argument values being aliased/mapped.
    1498             :   int mapped_count = Min(argument_count, parameter_count);
    1499         350 :   *has_aliased_arguments = true;
    1500             : 
    1501             :   // Prepare an iterator over argument values recorded in the frame state.
    1502             :   Node* const parameters = frame_state->InputAt(kFrameStateParametersInput);
    1503             :   StateValuesAccess parameters_access(parameters);
    1504         350 :   auto parameters_it = ++parameters_access.begin();
    1505             : 
    1506             :   // The unmapped argument values recorded in the frame state are stored yet
    1507             :   // another indirection away and then linked into the parameter map below,
    1508             :   // whereas mapped argument values are replaced with a hole instead.
    1509             :   AllocationBuilder aa(jsgraph(), effect, control);
    1510         350 :   aa.AllocateArray(argument_count, factory()->fixed_array_map());
    1511         983 :   for (int i = 0; i < mapped_count; ++i, ++parameters_it) {
    1512             :     aa.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
    1513        1266 :              jsgraph()->TheHoleConstant());
    1514             :   }
    1515           7 :   for (int i = mapped_count; i < argument_count; ++i, ++parameters_it) {
    1516             :     DCHECK_NOT_NULL((*parameters_it).node);
    1517             :     aa.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
    1518          14 :              (*parameters_it).node);
    1519             :   }
    1520         350 :   Node* arguments = aa.Finish();
    1521             : 
    1522             :   // Actually allocate the backing store.
    1523             :   AllocationBuilder a(jsgraph(), arguments, control);
    1524         350 :   a.AllocateArray(mapped_count + 2, factory()->sloppy_arguments_elements_map());
    1525             :   a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(0),
    1526         350 :           context);
    1527             :   a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(1),
    1528         350 :           arguments);
    1529         983 :   for (int i = 0; i < mapped_count; ++i) {
    1530         633 :     int idx = Context::MIN_CONTEXT_SLOTS + parameter_count - 1 - i;
    1531         633 :     a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i + 2),
    1532        2532 :             jsgraph()->Constant(idx));
    1533             :   }
    1534         350 :   return a.Finish();
    1535             : }
    1536             : 
    1537             : // Helper that allocates a FixedArray serving as a parameter map for values
    1538             : // unknown at compile-time, the true {arguments_length} and {arguments_frame}
    1539             : // values can only be determined dynamically at run-time and are provided.
    1540             : // Serves as backing store for JSCreateArguments nodes.
    1541       11033 : Node* JSCreateLowering::AllocateAliasedArguments(
    1542             :     Node* effect, Node* control, Node* context, Node* arguments_frame,
    1543             :     Node* arguments_length, const SharedFunctionInfoRef& shared,
    1544       29332 :     bool* has_aliased_arguments) {
    1545             :   // If there is no aliasing, the arguments object elements are not
    1546             :   // special in any way, we can just return an unmapped backing store.
    1547       11033 :   int parameter_count = shared.internal_formal_parameter_count();
    1548       11033 :   if (parameter_count == 0) {
    1549             :     return graph()->NewNode(simplified()->NewArgumentsElements(0),
    1550       17210 :                             arguments_frame, arguments_length, effect);
    1551             :   }
    1552             : 
    1553             :   // From here on we are going to allocate a mapped (aka. aliased) elements
    1554             :   // backing store. We do not statically know how many arguments exist, but
    1555             :   // dynamically selecting the hole for some of the "mapped" elements allows
    1556             :   // using a static shape for the parameter map.
    1557             :   int mapped_count = parameter_count;
    1558        2428 :   *has_aliased_arguments = true;
    1559             : 
    1560             :   // The unmapped argument values are stored yet another indirection away and
    1561             :   // then linked into the parameter map below, whereas mapped argument values
    1562             :   // (i.e. the first {mapped_count} elements) are replaced with a hole instead.
    1563             :   Node* arguments =
    1564             :       graph()->NewNode(simplified()->NewArgumentsElements(mapped_count),
    1565        2428 :                        arguments_frame, arguments_length, effect);
    1566             : 
    1567             :   // Actually allocate the backing store.
    1568             :   AllocationBuilder a(jsgraph(), arguments, control);
    1569        2428 :   a.AllocateArray(mapped_count + 2, factory()->sloppy_arguments_elements_map());
    1570             :   a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(0),
    1571        2428 :           context);
    1572             :   a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(1),
    1573        2428 :           arguments);
    1574        7940 :   for (int i = 0; i < mapped_count; ++i) {
    1575        5512 :     int idx = Context::MIN_CONTEXT_SLOTS + parameter_count - 1 - i;
    1576             :     Node* value = graph()->NewNode(
    1577             :         common()->Select(MachineRepresentation::kTagged),
    1578             :         graph()->NewNode(simplified()->NumberLessThan(), jsgraph()->Constant(i),
    1579             :                          arguments_length),
    1580       27560 :         jsgraph()->Constant(idx), jsgraph()->TheHoleConstant());
    1581        5512 :     a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i + 2),
    1582       11024 :             value);
    1583             :   }
    1584        2428 :   return a.Finish();
    1585             : }
    1586             : 
    1587         621 : Node* JSCreateLowering::AllocateElements(Node* effect, Node* control,
    1588             :                                          ElementsKind elements_kind,
    1589             :                                          int capacity,
    1590        4066 :                                          PretenureFlag pretenure) {
    1591             :   DCHECK_LE(1, capacity);
    1592             :   DCHECK_LE(capacity, JSArray::kInitialMaxFastElementArray);
    1593             : 
    1594             :   Handle<Map> elements_map = IsDoubleElementsKind(elements_kind)
    1595             :                                  ? factory()->fixed_double_array_map()
    1596        1242 :                                  : factory()->fixed_array_map();
    1597             :   ElementAccess access = IsDoubleElementsKind(elements_kind)
    1598             :                              ? AccessBuilder::ForFixedDoubleArrayElement()
    1599         621 :                              : AccessBuilder::ForFixedArrayElement();
    1600         621 :   Node* value = jsgraph()->TheHoleConstant();
    1601             : 
    1602             :   // Actually allocate the backing store.
    1603             :   AllocationBuilder a(jsgraph(), effect, control);
    1604         621 :   a.AllocateArray(capacity, elements_map, pretenure);
    1605        3445 :   for (int i = 0; i < capacity; ++i) {
    1606        5648 :     Node* index = jsgraph()->Constant(i);
    1607        2824 :     a.Store(access, index, value);
    1608             :   }
    1609         621 :   return a.Finish();
    1610             : }
    1611             : 
    1612         196 : Node* JSCreateLowering::AllocateElements(Node* effect, Node* control,
    1613             :                                          ElementsKind elements_kind,
    1614         746 :                                          std::vector<Node*> const& values,
    1615         746 :                                          PretenureFlag pretenure) {
    1616         196 :   int const capacity = static_cast<int>(values.size());
    1617             :   DCHECK_LE(1, capacity);
    1618             :   DCHECK_LE(capacity, JSArray::kInitialMaxFastElementArray);
    1619             : 
    1620             :   Handle<Map> elements_map = IsDoubleElementsKind(elements_kind)
    1621             :                                  ? factory()->fixed_double_array_map()
    1622         392 :                                  : factory()->fixed_array_map();
    1623             :   ElementAccess access = IsDoubleElementsKind(elements_kind)
    1624             :                              ? AccessBuilder::ForFixedDoubleArrayElement()
    1625         196 :                              : AccessBuilder::ForFixedArrayElement();
    1626             : 
    1627             :   // Actually allocate the backing store.
    1628             :   AllocationBuilder a(jsgraph(), effect, control);
    1629         196 :   a.AllocateArray(capacity, elements_map, pretenure);
    1630         746 :   for (int i = 0; i < capacity; ++i) {
    1631        1100 :     Node* index = jsgraph()->Constant(i);
    1632        1100 :     a.Store(access, index, values[i]);
    1633             :   }
    1634         196 :   return a.Finish();
    1635             : }
    1636             : 
    1637        6663 : Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control,
    1638             :                                             JSObjectRef boilerplate,
    1639       23037 :                                             PretenureFlag pretenure) {
    1640             :   // Setup the properties backing store.
    1641        6663 :   Node* properties = jsgraph()->EmptyFixedArrayConstant();
    1642             : 
    1643             :   // Compute the in-object properties to store first (might have effects).
    1644        6663 :   MapRef boilerplate_map = boilerplate.map();
    1645             :   ZoneVector<std::pair<FieldAccess, Node*>> inobject_fields(zone());
    1646        6663 :   inobject_fields.reserve(boilerplate_map.GetInObjectProperties());
    1647        6663 :   int const boilerplate_nof = boilerplate_map.NumberOfOwnDescriptors();
    1648       14171 :   for (int i = 0; i < boilerplate_nof; ++i) {
    1649             :     PropertyDetails const property_details =
    1650        7508 :         boilerplate_map.GetPropertyDetails(i);
    1651       11664 :     if (property_details.location() != kField) continue;
    1652             :     DCHECK_EQ(kData, property_details.kind());
    1653        3352 :     NameRef property_name = boilerplate_map.GetPropertyKey(i);
    1654        3352 :     FieldIndex index = boilerplate_map.GetFieldIndexFor(i);
    1655             :     FieldAccess access = {
    1656             :         kTaggedBase,        index.offset(), property_name.object(),
    1657             :         MaybeHandle<Map>(), Type::Any(),    MachineType::AnyTagged(),
    1658        3352 :         kFullWriteBarrier};
    1659             :     Node* value;
    1660        3352 :     if (boilerplate_map.IsUnboxedDoubleField(i)) {
    1661             :       access.machine_type = MachineType::Float64();
    1662             :       access.type = Type::Number();
    1663         254 :       value = jsgraph()->Constant(boilerplate.RawFastDoublePropertyAt(index));
    1664             :     } else {
    1665        3225 :       ObjectRef boilerplate_value = boilerplate.RawFastPropertyAt(index);
    1666        3225 :       if (boilerplate_value.IsJSObject()) {
    1667         304 :         JSObjectRef boilerplate_object = boilerplate_value.AsJSObject();
    1668             :         value = effect =
    1669         304 :             AllocateFastLiteral(effect, control, boilerplate_object, pretenure);
    1670        2921 :       } else if (property_details.representation().IsDouble()) {
    1671           0 :         double number = boilerplate_value.AsMutableHeapNumber().value();
    1672             :         // Allocate a mutable HeapNumber box and store the value into it.
    1673             :         AllocationBuilder builder(jsgraph(), effect, control);
    1674           0 :         builder.Allocate(HeapNumber::kSize, pretenure);
    1675             :         builder.Store(AccessBuilder::ForMap(),
    1676           0 :                       factory()->mutable_heap_number_map());
    1677             :         builder.Store(AccessBuilder::ForHeapNumberValue(),
    1678           0 :                       jsgraph()->Constant(number));
    1679           0 :         value = effect = builder.Finish();
    1680        2921 :       } else if (property_details.representation().IsSmi()) {
    1681             :         // Ensure that value is stored as smi.
    1682             :         bool is_uninitialized =
    1683        1698 :             boilerplate_value.IsHeapObject() &&
    1684        2056 :             boilerplate_value.AsHeapObject().map().oddball_type() ==
    1685         982 :                 OddballType::kUninitialized;
    1686             :         value = is_uninitialized
    1687             :                     ? jsgraph()->ZeroConstant()
    1688        2680 :                     : jsgraph()->Constant(boilerplate_value.AsSmi());
    1689             :       } else {
    1690        1581 :         value = jsgraph()->Constant(boilerplate_value);
    1691             :       }
    1692             :     }
    1693        3352 :     inobject_fields.push_back(std::make_pair(access, value));
    1694             :   }
    1695             : 
    1696             :   // Fill slack at the end of the boilerplate object with filler maps.
    1697        6663 :   int const boilerplate_length = boilerplate_map.GetInObjectProperties();
    1698       15164 :   for (int index = static_cast<int>(inobject_fields.size());
    1699             :        index < boilerplate_length; ++index) {
    1700             :     FieldAccess access =
    1701        1838 :         AccessBuilder::ForJSObjectInObjectProperty(boilerplate_map, index);
    1702        1838 :     Node* value = jsgraph()->HeapConstant(factory()->one_pointer_filler_map());
    1703        1838 :     inobject_fields.push_back(std::make_pair(access, value));
    1704             :   }
    1705             : 
    1706             :   // Setup the elements backing store.
    1707        6663 :   Node* elements =
    1708        6663 :       AllocateFastLiteralElements(effect, control, boilerplate, pretenure);
    1709       13326 :   if (elements->op()->EffectOutputCount() > 0) effect = elements;
    1710             : 
    1711             :   // Actually allocate and initialize the object.
    1712             :   AllocationBuilder builder(jsgraph(), effect, control);
    1713             :   builder.Allocate(boilerplate_map.instance_size(), pretenure,
    1714        6663 :                    Type::For(boilerplate_map));
    1715        6663 :   builder.Store(AccessBuilder::ForMap(), boilerplate_map);
    1716        6663 :   builder.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
    1717        6663 :   builder.Store(AccessBuilder::ForJSObjectElements(), elements);
    1718        6663 :   if (boilerplate.IsJSArray()) {
    1719        4156 :     JSArrayRef boilerplate_array = boilerplate.AsJSArray();
    1720             :     builder.Store(
    1721        4156 :         AccessBuilder::ForJSArrayLength(boilerplate_array.GetElementsKind()),
    1722        8312 :         boilerplate_array.length());
    1723             :   }
    1724       18516 :   for (auto const& inobject_field : inobject_fields) {
    1725        5190 :     builder.Store(inobject_field.first, inobject_field.second);
    1726             :   }
    1727        6663 :   return builder.Finish();
    1728             : }
    1729             : 
    1730        6663 : Node* JSCreateLowering::AllocateFastLiteralElements(Node* effect, Node* control,
    1731             :                                                     JSObjectRef boilerplate,
    1732       34824 :                                                     PretenureFlag pretenure) {
    1733        6663 :   FixedArrayBaseRef boilerplate_elements = boilerplate.elements();
    1734             : 
    1735             :   // Empty or copy-on-write elements just store a constant.
    1736        6663 :   int const elements_length = boilerplate_elements.length();
    1737        6663 :   MapRef elements_map = boilerplate_elements.map();
    1738        6663 :   if (boilerplate_elements.length() == 0 || elements_map.IsFixedCowArrayMap()) {
    1739        4493 :     if (pretenure == TENURED) {
    1740          40 :       boilerplate.EnsureElementsTenured();
    1741          40 :       boilerplate_elements = boilerplate.elements();
    1742             :     }
    1743        8986 :     return jsgraph()->HeapConstant(boilerplate_elements.object());
    1744             :   }
    1745             : 
    1746             :   // Compute the elements to store first (might have effects).
    1747        2170 :   ZoneVector<Node*> elements_values(elements_length, zone());
    1748        2170 :   if (elements_map.instance_type() == FIXED_DOUBLE_ARRAY_TYPE) {
    1749         511 :     FixedDoubleArrayRef elements = boilerplate_elements.AsFixedDoubleArray();
    1750        7005 :     for (int i = 0; i < elements_length; ++i) {
    1751        6494 :       if (elements.is_the_hole(i)) {
    1752         198 :         elements_values[i] = jsgraph()->TheHoleConstant();
    1753             :       } else {
    1754       19185 :         elements_values[i] = jsgraph()->Constant(elements.get_scalar(i));
    1755             :       }
    1756             :     }
    1757             :   } else {
    1758        1659 :     FixedArrayRef elements = boilerplate_elements.AsFixedArray();
    1759        8355 :     for (int i = 0; i < elements_length; ++i) {
    1760        6696 :       ObjectRef element_value = elements.get(i);
    1761        6696 :       if (element_value.IsJSObject()) {
    1762         389 :         elements_values[i] = effect = AllocateFastLiteral(
    1763         389 :             effect, control, element_value.AsJSObject(), pretenure);
    1764             :       } else {
    1765       12614 :         elements_values[i] = jsgraph()->Constant(element_value);
    1766             :       }
    1767             :     }
    1768             :   }
    1769             : 
    1770             :   // Allocate the backing store array and store the elements.
    1771             :   AllocationBuilder builder(jsgraph(), effect, control);
    1772        2170 :   builder.AllocateArray(elements_length, elements_map.object(), pretenure);
    1773             :   ElementAccess const access =
    1774        2170 :       (elements_map.instance_type() == FIXED_DOUBLE_ARRAY_TYPE)
    1775             :           ? AccessBuilder::ForFixedDoubleArrayElement()
    1776        2170 :           : AccessBuilder::ForFixedArrayElement();
    1777       13190 :   for (int i = 0; i < elements_length; ++i) {
    1778       39570 :     builder.Store(access, jsgraph()->Constant(i), elements_values[i]);
    1779             :   }
    1780        2170 :   return builder.Finish();
    1781             : }
    1782             : 
    1783         602 : Node* JSCreateLowering::AllocateLiteralRegExp(Node* effect, Node* control,
    1784         602 :                                               JSRegExpRef boilerplate) {
    1785         602 :   MapRef boilerplate_map = boilerplate.map();
    1786             : 
    1787             :   // Sanity check that JSRegExp object layout hasn't changed.
    1788             :   STATIC_ASSERT(static_cast<int>(JSRegExp::kDataOffset) ==
    1789             :                 static_cast<int>(JSObject::kHeaderSize));
    1790             :   STATIC_ASSERT(JSRegExp::kSourceOffset == JSRegExp::kDataOffset + kTaggedSize);
    1791             :   STATIC_ASSERT(JSRegExp::kFlagsOffset ==
    1792             :                 JSRegExp::kSourceOffset + kTaggedSize);
    1793             :   STATIC_ASSERT(JSRegExp::kSize == JSRegExp::kFlagsOffset + kTaggedSize);
    1794             :   STATIC_ASSERT(JSRegExp::kLastIndexOffset == JSRegExp::kSize);
    1795             :   STATIC_ASSERT(JSRegExp::kInObjectFieldCount == 1);  // LastIndex.
    1796             : 
    1797             :   const PretenureFlag pretenure = NOT_TENURED;
    1798             :   const int size =
    1799             :       JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kTaggedSize;
    1800             : 
    1801             :   AllocationBuilder builder(jsgraph(), effect, control);
    1802         602 :   builder.Allocate(size, pretenure, Type::For(boilerplate_map));
    1803         602 :   builder.Store(AccessBuilder::ForMap(), boilerplate_map);
    1804             :   builder.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
    1805         602 :                 boilerplate.raw_properties_or_hash());
    1806         602 :   builder.Store(AccessBuilder::ForJSObjectElements(), boilerplate.elements());
    1807             : 
    1808         602 :   builder.Store(AccessBuilder::ForJSRegExpData(), boilerplate.data());
    1809         602 :   builder.Store(AccessBuilder::ForJSRegExpSource(), boilerplate.source());
    1810         602 :   builder.Store(AccessBuilder::ForJSRegExpFlags(), boilerplate.flags());
    1811             :   builder.Store(AccessBuilder::ForJSRegExpLastIndex(),
    1812         602 :                 boilerplate.last_index());
    1813             : 
    1814         602 :   return builder.Finish();
    1815             : }
    1816             : 
    1817      424504 : Factory* JSCreateLowering::factory() const {
    1818      478352 :   return jsgraph()->isolate()->factory();
    1819             : }
    1820             : 
    1821       89528 : Graph* JSCreateLowering::graph() const { return jsgraph()->graph(); }
    1822             : 
    1823        5512 : CommonOperatorBuilder* JSCreateLowering::common() const {
    1824        5512 :   return jsgraph()->common();
    1825             : }
    1826             : 
    1827       59895 : SimplifiedOperatorBuilder* JSCreateLowering::simplified() const {
    1828       59895 :   return jsgraph()->simplified();
    1829             : }
    1830             : 
    1831      115617 : NativeContextRef JSCreateLowering::native_context() const {
    1832           0 :   return broker()->native_context();
    1833             : }
    1834             : 
    1835             : }  // namespace compiler
    1836             : }  // namespace internal
    1837      183867 : }  // namespace v8

Generated by: LCOV version 1.10