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-02-19 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        1601 : Node* GetArgumentsFrameState(Node* frame_state) {
      37        1601 :   Node* const outer_state = NodeProperties::GetFrameStateInput(frame_state);
      38        1601 :   FrameStateInfo outer_state_info = FrameStateInfoOf(outer_state->op());
      39             :   return outer_state_info.type() == FrameStateType::kArgumentsAdaptor
      40             :              ? outer_state
      41        1601 :              : frame_state;
      42             : }
      43             : 
      44             : // Checks whether allocation using the given target and new.target can be
      45             : // inlined.
      46        4733 : bool IsAllocationInlineable(const JSFunctionRef& target,
      47             :                             const JSFunctionRef& new_target) {
      48        4733 :   CHECK_IMPLIES(new_target.has_initial_map(),
      49             :                 !new_target.initial_map().is_dictionary_map());
      50        9466 :   return new_target.has_initial_map() &&
      51        9466 :          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    34806186 : Reduction JSCreateLowering::Reduce(Node* node) {
      65             :   DisallowHeapAccess disallow_heap_access;
      66    34806186 :   switch (node->opcode()) {
      67             :     case IrOpcode::kJSCreate:
      68        3635 :       return ReduceJSCreate(node);
      69             :     case IrOpcode::kJSCreateArguments:
      70       19280 :       return ReduceJSCreateArguments(node);
      71             :     case IrOpcode::kJSCreateArray:
      72        1366 :       return ReduceJSCreateArray(node);
      73             :     case IrOpcode::kJSCreateArrayIterator:
      74        1396 :       return ReduceJSCreateArrayIterator(node);
      75             :     case IrOpcode::kJSCreateAsyncFunctionObject:
      76        1080 :       return ReduceJSCreateAsyncFunctionObject(node);
      77             :     case IrOpcode::kJSCreateBoundFunction:
      78         104 :       return ReduceJSCreateBoundFunction(node);
      79             :     case IrOpcode::kJSCreateClosure:
      80      437233 :       return ReduceJSCreateClosure(node);
      81             :     case IrOpcode::kJSCreateCollectionIterator:
      82         163 :       return ReduceJSCreateCollectionIterator(node);
      83             :     case IrOpcode::kJSCreateIterResultObject:
      84        3934 :       return ReduceJSCreateIterResultObject(node);
      85             :     case IrOpcode::kJSCreateStringIterator:
      86          62 :       return ReduceJSCreateStringIterator(node);
      87             :     case IrOpcode::kJSCreateKeyValueArray:
      88          91 :       return ReduceJSCreateKeyValueArray(node);
      89             :     case IrOpcode::kJSCreatePromise:
      90        1394 :       return ReduceJSCreatePromise(node);
      91             :     case IrOpcode::kJSCreateLiteralArray:
      92             :     case IrOpcode::kJSCreateLiteralObject:
      93       23187 :       return ReduceJSCreateLiteralArrayOrObject(node);
      94             :     case IrOpcode::kJSCreateLiteralRegExp:
      95        6421 :       return ReduceJSCreateLiteralRegExp(node);
      96             :     case IrOpcode::kJSCreateEmptyLiteralArray:
      97       21651 :       return ReduceJSCreateEmptyLiteralArray(node);
      98             :     case IrOpcode::kJSCreateEmptyLiteralObject:
      99        5909 :       return ReduceJSCreateEmptyLiteralObject(node);
     100             :     case IrOpcode::kJSCreateFunctionContext:
     101       29086 :       return ReduceJSCreateFunctionContext(node);
     102             :     case IrOpcode::kJSCreateWithContext:
     103         486 :       return ReduceJSCreateWithContext(node);
     104             :     case IrOpcode::kJSCreateCatchContext:
     105       14114 :       return ReduceJSCreateCatchContext(node);
     106             :     case IrOpcode::kJSCreateBlockContext:
     107        9134 :       return ReduceJSCreateBlockContext(node);
     108             :     case IrOpcode::kJSCreateGeneratorObject:
     109        1323 :       return ReduceJSCreateGeneratorObject(node);
     110             :     case IrOpcode::kJSCreateObject:
     111          75 :       return ReduceJSCreateObject(node);
     112             :     default:
     113             :       break;
     114             :   }
     115             :   return NoChange();
     116             : }
     117             : 
     118       24007 : Reduction JSCreateLowering::ReduceJSCreate(Node* node) {
     119             :   DCHECK_EQ(IrOpcode::kJSCreate, node->opcode());
     120        3635 :   Node* const target = NodeProperties::GetValueInput(node, 0);
     121        3635 :   Type const target_type = NodeProperties::GetType(target);
     122        3635 :   Node* const new_target = NodeProperties::GetValueInput(node, 1);
     123        3635 :   Type const new_target_type = NodeProperties::GetType(new_target);
     124        3635 :   Node* const effect = NodeProperties::GetEffectInput(node);
     125        3635 :   Node* const control = NodeProperties::GetControlInput(node);
     126             :   // Extract constructor and original constructor function.
     127       10618 :   if (!target_type.IsHeapConstant() || !new_target_type.IsHeapConstant() ||
     128       10397 :       !target_type.AsHeapConstant()->Ref().IsJSFunction() ||
     129        3381 :       !new_target_type.AsHeapConstant()->Ref().IsJSFunction()) {
     130             :     return NoChange();
     131             :   }
     132             : 
     133             :   JSFunctionRef constructor =
     134        3374 :       target_type.AsHeapConstant()->Ref().AsJSFunction();
     135        3374 :   if (!constructor.map().is_constructor()) return NoChange();
     136             :   JSFunctionRef original_constructor =
     137        3374 :       new_target_type.AsHeapConstant()->Ref().AsJSFunction();
     138        3374 :   if (!original_constructor.map().is_constructor()) return NoChange();
     139             : 
     140             :   // Check if we can inline the allocation.
     141        3367 :   if (!IsAllocationInlineable(constructor, original_constructor)) {
     142             :     return NoChange();
     143             :   }
     144             : 
     145             :   SlackTrackingPrediction slack_tracking_prediction =
     146             :       dependencies()->DependOnInitialMapInstanceSizePrediction(
     147        3367 :           original_constructor);
     148        3367 :   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        3367 :   a.Allocate(slack_tracking_prediction.instance_size());
     154        3367 :   a.Store(AccessBuilder::ForMap(), initial_map);
     155             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
     156        3367 :           jsgraph()->EmptyFixedArrayConstant());
     157             :   a.Store(AccessBuilder::ForJSObjectElements(),
     158        3367 :           jsgraph()->EmptyFixedArrayConstant());
     159       10271 :   for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
     160             :        ++i) {
     161             :     a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
     162        6904 :             jsgraph()->UndefinedConstant());
     163             :   }
     164             : 
     165             :   RelaxControls(node);
     166        3367 :   a.FinishAndChange(node);
     167             :   return Changed(node);
     168             : }
     169             : 
     170       78705 : Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) {
     171             :   DCHECK_EQ(IrOpcode::kJSCreateArguments, node->opcode());
     172       19280 :   CreateArgumentsType type = CreateArgumentsTypeOf(node->op());
     173       38560 :   Node* const frame_state = NodeProperties::GetFrameStateInput(node);
     174       19280 :   Node* const outer_state = frame_state->InputAt(kFrameStateOuterStateInput);
     175       19280 :   Node* const control = graph()->start();
     176       19280 :   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       19280 :   if (outer_state->opcode() != IrOpcode::kFrameState) {
     183       17679 :     switch (type) {
     184             :       case CreateArgumentsType::kMappedArguments: {
     185             :         // TODO(mstarzinger): Duplicate parameters are not handled yet.
     186       11001 :         if (shared.has_duplicate_parameters()) return NoChange();
     187       10993 :         Node* const callee = NodeProperties::GetValueInput(node, 0);
     188       10993 :         Node* const context = NodeProperties::GetContextInput(node);
     189       10993 :         Node* effect = NodeProperties::GetEffectInput(node);
     190             :         Node* const arguments_frame =
     191       10993 :             graph()->NewNode(simplified()->ArgumentsFrame());
     192             :         Node* const arguments_length = graph()->NewNode(
     193             :             simplified()->ArgumentsLength(
     194             :                 shared.internal_formal_parameter_count(), false),
     195       21986 :             arguments_frame);
     196             :         // Allocate the elements backing store.
     197       10993 :         bool has_aliased_arguments = false;
     198             :         Node* const elements = effect = AllocateAliasedArguments(
     199             :             effect, control, context, arguments_frame, arguments_length, shared,
     200       10993 :             &has_aliased_arguments);
     201             :         // Load the arguments object map.
     202             :         Node* const arguments_map = jsgraph()->Constant(
     203             :             has_aliased_arguments
     204       15701 :                 ? native_context().fast_aliased_arguments_map()
     205       41618 :                 : native_context().sloppy_arguments_map());
     206             :         // Actually allocate and initialize the arguments object.
     207             :         AllocationBuilder a(jsgraph(), effect, control);
     208       10993 :         Node* properties = jsgraph()->EmptyFixedArrayConstant();
     209             :         STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kTaggedSize);
     210       10993 :         a.Allocate(JSSloppyArgumentsObject::kSize);
     211       10993 :         a.Store(AccessBuilder::ForMap(), arguments_map);
     212       10993 :         a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     213       10993 :         a.Store(AccessBuilder::ForJSObjectElements(), elements);
     214       10993 :         a.Store(AccessBuilder::ForArgumentsLength(), arguments_length);
     215       10993 :         a.Store(AccessBuilder::ForArgumentsCallee(), callee);
     216             :         RelaxControls(node);
     217       10993 :         a.FinishAndChange(node);
     218             :         return Changed(node);
     219             :       }
     220             :       case CreateArgumentsType::kUnmappedArguments: {
     221        5736 :         Node* effect = NodeProperties::GetEffectInput(node);
     222             :         Node* const arguments_frame =
     223        5736 :             graph()->NewNode(simplified()->ArgumentsFrame());
     224             :         Node* const arguments_length = graph()->NewNode(
     225             :             simplified()->ArgumentsLength(
     226             :                 shared.internal_formal_parameter_count(), false),
     227       11472 :             arguments_frame);
     228             :         // Allocate the elements backing store.
     229             :         Node* const elements = effect =
     230             :             graph()->NewNode(simplified()->NewArgumentsElements(0),
     231        5736 :                              arguments_frame, arguments_length, effect);
     232             :         // Load the arguments object map.
     233             :         Node* const arguments_map =
     234       11472 :             jsgraph()->Constant(native_context().strict_arguments_map());
     235             :         // Actually allocate and initialize the arguments object.
     236             :         AllocationBuilder a(jsgraph(), effect, control);
     237        5736 :         Node* properties = jsgraph()->EmptyFixedArrayConstant();
     238             :         STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kTaggedSize);
     239        5736 :         a.Allocate(JSStrictArgumentsObject::kSize);
     240        5736 :         a.Store(AccessBuilder::ForMap(), arguments_map);
     241        5736 :         a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     242        5736 :         a.Store(AccessBuilder::ForJSObjectElements(), elements);
     243        5736 :         a.Store(AccessBuilder::ForArgumentsLength(), arguments_length);
     244             :         RelaxControls(node);
     245        5736 :         a.FinishAndChange(node);
     246             :         return Changed(node);
     247             :       }
     248             :       case CreateArgumentsType::kRestParameter: {
     249         942 :         Node* effect = NodeProperties::GetEffectInput(node);
     250             :         Node* const arguments_frame =
     251         942 :             graph()->NewNode(simplified()->ArgumentsFrame());
     252             :         Node* const rest_length = graph()->NewNode(
     253             :             simplified()->ArgumentsLength(
     254             :                 shared.internal_formal_parameter_count(), true),
     255        1884 :             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         942 :                              arguments_frame, rest_length, effect);
     262             :         // Load the JSArray object map.
     263             :         Node* const jsarray_map = jsgraph()->Constant(
     264        1884 :             native_context().js_array_packed_elements_map());
     265             :         // Actually allocate and initialize the jsarray.
     266             :         AllocationBuilder a(jsgraph(), effect, control);
     267         942 :         Node* properties = jsgraph()->EmptyFixedArrayConstant();
     268             :         STATIC_ASSERT(JSArray::kSize == 4 * kTaggedSize);
     269         942 :         a.Allocate(JSArray::kSize);
     270         942 :         a.Store(AccessBuilder::ForMap(), jsarray_map);
     271         942 :         a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     272         942 :         a.Store(AccessBuilder::ForJSObjectElements(), elements);
     273         942 :         a.Store(AccessBuilder::ForJSArrayLength(PACKED_ELEMENTS), rest_length);
     274             :         RelaxControls(node);
     275         942 :         a.FinishAndChange(node);
     276             :         return Changed(node);
     277             :       }
     278             :     }
     279           0 :     UNREACHABLE();
     280        1601 :   } 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        1601 :     if (type == CreateArgumentsType::kMappedArguments) {
     284         630 :       Node* const callee = NodeProperties::GetValueInput(node, 0);
     285         630 :       Node* const context = NodeProperties::GetContextInput(node);
     286         630 :       Node* effect = NodeProperties::GetEffectInput(node);
     287             :       // TODO(mstarzinger): Duplicate parameters are not handled yet.
     288         630 :       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        1260 :       Node* const args_state = GetArgumentsFrameState(frame_state);
     293        1260 :       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         630 :       FrameStateInfo args_state_info = FrameStateInfoOf(args_state->op());
     301             :       // Prepare element backing store to be used by arguments object.
     302         630 :       bool has_aliased_arguments = false;
     303         630 :       Node* const elements = AllocateAliasedArguments(
     304         630 :           effect, control, args_state, context, shared, &has_aliased_arguments);
     305        1260 :       effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
     306             :       // Load the arguments object map.
     307             :       Node* const arguments_map = jsgraph()->Constant(
     308        1318 :           has_aliased_arguments ? native_context().fast_aliased_arguments_map()
     309        2176 :                                 : native_context().sloppy_arguments_map());
     310             :       // Actually allocate and initialize the arguments object.
     311             :       AllocationBuilder a(jsgraph(), effect, control);
     312         630 :       Node* properties = jsgraph()->EmptyFixedArrayConstant();
     313         630 :       int length = args_state_info.parameter_count() - 1;  // Minus receiver.
     314             :       STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kTaggedSize);
     315         630 :       a.Allocate(JSSloppyArgumentsObject::kSize);
     316         630 :       a.Store(AccessBuilder::ForMap(), arguments_map);
     317         630 :       a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     318         630 :       a.Store(AccessBuilder::ForJSObjectElements(), elements);
     319        1260 :       a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length));
     320         630 :       a.Store(AccessBuilder::ForArgumentsCallee(), callee);
     321             :       RelaxControls(node);
     322         630 :       a.FinishAndChange(node);
     323             :       return Changed(node);
     324         971 :     } 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         417 :       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         834 :       Node* const args_state = GetArgumentsFrameState(frame_state);
     332         834 :       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         417 :       FrameStateInfo args_state_info = FrameStateInfoOf(args_state->op());
     340             :       // Prepare element backing store to be used by arguments object.
     341         417 :       Node* const elements = AllocateArguments(effect, control, args_state);
     342         834 :       effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
     343             :       // Load the arguments object map.
     344             :       Node* const arguments_map =
     345         834 :           jsgraph()->Constant(native_context().strict_arguments_map());
     346             :       // Actually allocate and initialize the arguments object.
     347             :       AllocationBuilder a(jsgraph(), effect, control);
     348         417 :       Node* properties = jsgraph()->EmptyFixedArrayConstant();
     349         417 :       int length = args_state_info.parameter_count() - 1;  // Minus receiver.
     350             :       STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kTaggedSize);
     351         417 :       a.Allocate(JSStrictArgumentsObject::kSize);
     352         417 :       a.Store(AccessBuilder::ForMap(), arguments_map);
     353         417 :       a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     354         417 :       a.Store(AccessBuilder::ForJSObjectElements(), elements);
     355         834 :       a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length));
     356             :       RelaxControls(node);
     357         417 :       a.FinishAndChange(node);
     358             :       return Changed(node);
     359         554 :     } else if (type == CreateArgumentsType::kRestParameter) {
     360         554 :       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         554 :       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        1108 :       Node* const args_state = GetArgumentsFrameState(frame_state);
     368        1108 :       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         554 :       FrameStateInfo args_state_info = FrameStateInfoOf(args_state->op());
     376             :       // Prepare element backing store to be used by the rest array.
     377         554 :       Node* const elements =
     378         554 :           AllocateRestArguments(effect, control, args_state, start_index);
     379        1108 :       effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
     380             :       // Load the JSArray object map.
     381             :       Node* const jsarray_map =
     382        1108 :           jsgraph()->Constant(native_context().js_array_packed_elements_map());
     383             :       // Actually allocate and initialize the jsarray.
     384             :       AllocationBuilder a(jsgraph(), effect, control);
     385         554 :       Node* properties = jsgraph()->EmptyFixedArrayConstant();
     386             : 
     387             :       // -1 to minus receiver
     388         554 :       int argument_count = args_state_info.parameter_count() - 1;
     389        1108 :       int length = std::max(0, argument_count - start_index);
     390             :       STATIC_ASSERT(JSArray::kSize == 4 * kTaggedSize);
     391         554 :       a.Allocate(JSArray::kSize);
     392         554 :       a.Store(AccessBuilder::ForMap(), jsarray_map);
     393         554 :       a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     394         554 :       a.Store(AccessBuilder::ForJSObjectElements(), elements);
     395             :       a.Store(AccessBuilder::ForJSArrayLength(PACKED_ELEMENTS),
     396        1108 :               jsgraph()->Constant(length));
     397             :       RelaxControls(node);
     398         554 :       a.FinishAndChange(node);
     399             :       return Changed(node);
     400             :     }
     401             :   }
     402             : 
     403             :   return NoChange();
     404             : }
     405             : 
     406        8631 : Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
     407             :   DCHECK_EQ(IrOpcode::kJSCreateGeneratorObject, node->opcode());
     408        1323 :   Node* const closure = NodeProperties::GetValueInput(node, 0);
     409        1323 :   Node* const receiver = NodeProperties::GetValueInput(node, 1);
     410        1323 :   Node* const context = NodeProperties::GetContextInput(node);
     411        1323 :   Type const closure_type = NodeProperties::GetType(closure);
     412        1323 :   Node* effect = NodeProperties::GetEffectInput(node);
     413        1323 :   Node* const control = NodeProperties::GetControlInput(node);
     414        1323 :   if (closure_type.IsHeapConstant()) {
     415             :     DCHECK(closure_type.AsHeapConstant()->Ref().IsJSFunction());
     416             :     JSFunctionRef js_function =
     417        1289 :         closure_type.AsHeapConstant()->Ref().AsJSFunction();
     418        1289 :     if (!js_function.has_initial_map()) return NoChange();
     419             : 
     420             :     SlackTrackingPrediction slack_tracking_prediction =
     421         543 :         dependencies()->DependOnInitialMapInstanceSizePrediction(js_function);
     422             : 
     423         543 :     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         543 :     SharedFunctionInfoRef shared = js_function.shared();
     429             :     DCHECK(shared.HasBytecodeArray());
     430         543 :     int parameter_count_no_receiver = shared.internal_formal_parameter_count();
     431             :     int size = parameter_count_no_receiver +
     432         543 :                shared.GetBytecodeArray().register_count();
     433             :     AllocationBuilder ab(jsgraph(), effect, control);
     434         543 :     ab.AllocateArray(size, factory()->fixed_array_map());
     435        4015 :     for (int i = 0; i < size; ++i) {
     436        3472 :       ab.Store(AccessBuilder::ForFixedArraySlot(i),
     437        6944 :                jsgraph()->UndefinedConstant());
     438             :     }
     439         543 :     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         543 :     a.Allocate(slack_tracking_prediction.instance_size());
     444         543 :     Node* empty_fixed_array = jsgraph()->EmptyFixedArrayConstant();
     445         543 :     Node* undefined = jsgraph()->UndefinedConstant();
     446         543 :     a.Store(AccessBuilder::ForMap(), initial_map);
     447         543 :     a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), empty_fixed_array);
     448         543 :     a.Store(AccessBuilder::ForJSObjectElements(), empty_fixed_array);
     449         543 :     a.Store(AccessBuilder::ForJSGeneratorObjectContext(), context);
     450         543 :     a.Store(AccessBuilder::ForJSGeneratorObjectFunction(), closure);
     451         543 :     a.Store(AccessBuilder::ForJSGeneratorObjectReceiver(), receiver);
     452         543 :     a.Store(AccessBuilder::ForJSGeneratorObjectInputOrDebugPos(), undefined);
     453             :     a.Store(AccessBuilder::ForJSGeneratorObjectResumeMode(),
     454         543 :             jsgraph()->Constant(JSGeneratorObject::kNext));
     455             :     a.Store(AccessBuilder::ForJSGeneratorObjectContinuation(),
     456         543 :             jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting));
     457             :     a.Store(AccessBuilder::ForJSGeneratorObjectParametersAndRegisters(),
     458         543 :             parameters_and_registers);
     459             : 
     460         543 :     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         543 :     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         492 : Reduction JSCreateLowering::ReduceNewArray(
     481             :     Node* node, Node* length, MapRef initial_map, ElementsKind elements_kind,
     482             :     PretenureFlag pretenure,
     483        2460 :     const SlackTrackingPrediction& slack_tracking_prediction) {
     484             :   DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
     485         492 :   Node* effect = NodeProperties::GetEffectInput(node);
     486         492 :   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         492 :   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        1476 :       control);
     501             : 
     502             :   // Construct elements and properties for the resulting JSArray.
     503             :   Node* elements = effect =
     504         492 :       graph()->NewNode(IsDoubleElementsKind(initial_map.elements_kind())
     505             :                            ? simplified()->NewDoubleElements(pretenure)
     506             :                            : simplified()->NewSmiOrObjectElements(pretenure),
     507         984 :                        length, effect, control);
     508         492 :   Node* properties = jsgraph()->EmptyFixedArrayConstant();
     509             : 
     510             :   // Perform the allocation of the actual JSArray object.
     511             :   AllocationBuilder a(jsgraph(), effect, control);
     512         492 :   a.Allocate(slack_tracking_prediction.instance_size(), pretenure);
     513         492 :   a.Store(AccessBuilder::ForMap(), initial_map);
     514         492 :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     515         492 :   a.Store(AccessBuilder::ForJSObjectElements(), elements);
     516         492 :   a.Store(AccessBuilder::ForJSArrayLength(initial_map.elements_kind()), length);
     517         984 :   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         492 :   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        1616 : Reduction JSCreateLowering::ReduceNewArray(
     530             :     Node* node, Node* length, int capacity, MapRef initial_map,
     531             :     ElementsKind elements_kind, PretenureFlag pretenure,
     532        7530 :     const SlackTrackingPrediction& slack_tracking_prediction) {
     533             :   DCHECK(node->opcode() == IrOpcode::kJSCreateArray ||
     534             :          node->opcode() == IrOpcode::kJSCreateEmptyLiteralArray);
     535        1616 :   Node* effect = NodeProperties::GetEffectInput(node);
     536        1616 :   Node* control = NodeProperties::GetControlInput(node);
     537             : 
     538             :   // Determine the appropriate elements kind.
     539        1616 :   if (NodeProperties::GetType(length).Max() > 0.0) {
     540             :     elements_kind = GetHoleyElementsKind(elements_kind);
     541             :   }
     542        1616 :   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        1616 :   if (capacity == 0) {
     549        1024 :     elements = jsgraph()->EmptyFixedArrayConstant();
     550             :   } else {
     551             :     elements = effect =
     552         592 :         AllocateElements(effect, control, elements_kind, capacity, pretenure);
     553             :   }
     554        1616 :   Node* properties = jsgraph()->EmptyFixedArrayConstant();
     555             : 
     556             :   // Perform the allocation of the actual JSArray object.
     557             :   AllocationBuilder a(jsgraph(), effect, control);
     558        1616 :   a.Allocate(slack_tracking_prediction.instance_size(), pretenure);
     559        1616 :   a.Store(AccessBuilder::ForMap(), initial_map);
     560        1616 :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     561        1616 :   a.Store(AccessBuilder::ForJSObjectElements(), elements);
     562        1616 :   a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
     563        3274 :   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        1616 :   a.FinishAndChange(node);
     570             :   return Changed(node);
     571             : }
     572             : 
     573         177 : Reduction JSCreateLowering::ReduceNewArray(
     574         177 :     Node* node, std::vector<Node*> values, MapRef initial_map,
     575             :     ElementsKind elements_kind, PretenureFlag pretenure,
     576         969 :     const SlackTrackingPrediction& slack_tracking_prediction) {
     577             :   DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
     578         177 :   Node* effect = NodeProperties::GetEffectInput(node);
     579         177 :   Node* control = NodeProperties::GetControlInput(node);
     580             : 
     581             :   // Determine the appropriate elements kind.
     582             :   DCHECK(IsFastElementsKind(elements_kind));
     583         177 :   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         177 :   if (IsSmiElementsKind(elements_kind)) {
     590         225 :     for (auto& value : values) {
     591         298 :       if (!NodeProperties::GetType(value).Is(Type::SignedSmall())) {
     592             :         value = effect = graph()->NewNode(
     593          63 :             simplified()->CheckSmi(VectorSlotPair()), value, effect, control);
     594             :       }
     595             :     }
     596         139 :   } else if (IsDoubleElementsKind(elements_kind)) {
     597          96 :     for (auto& value : values) {
     598         112 :       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         168 :       value = graph()->NewNode(simplified()->NumberSilenceNaN(), value);
     605             :     }
     606             :   }
     607             : 
     608             :   // Setup elements, properties and length.
     609             :   Node* elements = effect =
     610         177 :       AllocateElements(effect, control, elements_kind, values, pretenure);
     611         177 :   Node* properties = jsgraph()->EmptyFixedArrayConstant();
     612         354 :   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         177 :   a.Allocate(slack_tracking_prediction.instance_size(), pretenure);
     617         177 :   a.Store(AccessBuilder::ForMap(), initial_map);
     618         177 :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
     619         177 :   a.Store(AccessBuilder::ForJSObjectElements(), elements);
     620         177 :   a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
     621         438 :   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         177 :   a.FinishAndChange(node);
     628             :   return Changed(node);
     629             : }
     630             : 
     631        6577 : Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) {
     632             :   DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
     633        1466 :   CreateArrayParameters const& p = CreateArrayParametersOf(node->op());
     634        1366 :   int const arity = static_cast<int>(p.arity());
     635        1366 :   base::Optional<AllocationSiteRef> site_ref;
     636             :   {
     637             :     Handle<AllocationSite> site;
     638        1366 :     if (p.site().ToHandle(&site)) {
     639         537 :       site_ref = AllocationSiteRef(broker(), site);
     640             :     }
     641             :   }
     642             :   PretenureFlag pretenure = NOT_TENURED;
     643        1366 :   JSFunctionRef constructor = native_context().array_function();
     644        1366 :   Node* target = NodeProperties::GetValueInput(node, 0);
     645        1366 :   Node* new_target = NodeProperties::GetValueInput(node, 1);
     646             :   Type new_target_type = (target == new_target)
     647             :                              ? Type::HeapConstant(constructor, zone())
     648        2371 :                              : NodeProperties::GetType(new_target);
     649             : 
     650             :   // Extract original constructor function.
     651        2732 :   if (new_target_type.IsHeapConstant() &&
     652        1366 :       new_target_type.AsHeapConstant()->Ref().IsJSFunction()) {
     653             :     JSFunctionRef original_constructor =
     654        1366 :         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        1366 :     if (IsAllocationInlineable(constructor, original_constructor)) {
     660             :       SlackTrackingPrediction slack_tracking_prediction =
     661             :           dependencies()->DependOnInitialMapInstanceSizePrediction(
     662        1366 :               original_constructor);
     663        1366 :       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        1366 :       ElementsKind elements_kind = initial_map.elements_kind();
     671        1366 :       if (site_ref) {
     672         537 :         elements_kind = site_ref->GetElementsKind();
     673         537 :         can_inline_call = site_ref->CanInlineCall();
     674         537 :         pretenure = dependencies()->DependOnPretenureMode(*site_ref);
     675         537 :         dependencies()->DependOnElementsKind(*site_ref);
     676             :       } else {
     677             :         CellRef array_constructor_protector(
     678             :             broker(), factory()->array_constructor_protector());
     679        1658 :         can_inline_call = array_constructor_protector.value().AsSmi() ==
     680         829 :                           Isolate::kProtectorValid;
     681             :       }
     682             : 
     683        1366 :       if (arity == 0) {
     684         400 :         Node* length = jsgraph()->ZeroConstant();
     685             :         int capacity = JSArray::kPreallocatedArrayElements;
     686             :         return ReduceNewArray(node, length, capacity, initial_map,
     687             :                               elements_kind, pretenure,
     688        1668 :                               slack_tracking_prediction);
     689         966 :       } else if (arity == 1) {
     690         866 :         Node* length = NodeProperties::GetValueInput(node, 2);
     691         866 :         Type length_type = NodeProperties::GetType(length);
     692         866 :         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          84 :                                  : PACKED_ELEMENTS);
     699             :           return ReduceNewArray(node, std::vector<Node*>{length}, initial_map,
     700             :                                 elements_kind, pretenure,
     701         252 :                                 slack_tracking_prediction);
     702             :         }
     703        2134 :         if (length_type.Is(Type::SignedSmall()) && length_type.Min() >= 0 &&
     704        1650 :             length_type.Max() <= kElementLoopUnrollLimit &&
     705         200 :             length_type.Min() == length_type.Max()) {
     706         192 :           int capacity = static_cast<int>(length_type.Max());
     707             :           return ReduceNewArray(node, length, capacity, initial_map,
     708             :                                 elements_kind, pretenure,
     709         192 :                                 slack_tracking_prediction);
     710             :         }
     711         590 :         if (length_type.Maybe(Type::UnsignedSmall()) && can_inline_call) {
     712             :           return ReduceNewArray(node, length, initial_map, elements_kind,
     713         492 :                                 pretenure, slack_tracking_prediction);
     714             :         }
     715         100 :       } 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         100 :         values.reserve(p.arity());
     721         536 :         for (int i = 0; i < arity; ++i) {
     722         436 :           Node* value = NodeProperties::GetValueInput(node, 2 + i);
     723         436 :           Type value_type = NodeProperties::GetType(value);
     724         436 :           if (!value_type.Is(Type::SignedSmall())) {
     725             :             values_all_smis = false;
     726             :           }
     727         436 :           if (!value_type.Is(Type::Number())) {
     728             :             values_all_numbers = false;
     729             :           }
     730         436 :           if (!value_type.Maybe(Type::Number())) {
     731             :             values_any_nonnumber = true;
     732             :           }
     733         436 :           values.push_back(value);
     734             :         }
     735             : 
     736             :         // Try to figure out the ideal elements kind statically.
     737         100 :         if (values_all_smis) {
     738             :           // Smis can be stored with any elements kind.
     739          67 :         } else if (values_all_numbers) {
     740             :           elements_kind = GetMoreGeneralElementsKind(
     741             :               elements_kind, IsHoleyElementsKind(elements_kind)
     742             :                                  ? HOLEY_DOUBLE_ELEMENTS
     743          18 :                                  : PACKED_DOUBLE_ELEMENTS);
     744          49 :         } else if (values_any_nonnumber) {
     745             :           elements_kind = GetMoreGeneralElementsKind(
     746             :               elements_kind, IsHoleyElementsKind(elements_kind)
     747             :                                  ? HOLEY_ELEMENTS
     748          35 :                                  : PACKED_ELEMENTS);
     749          14 :         } 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         186 :                               pretenure, slack_tracking_prediction);
     759             :       }
     760             :     }
     761             :   }
     762             :   return NoChange();
     763             : }
     764             : 
     765        8376 : Reduction JSCreateLowering::ReduceJSCreateArrayIterator(Node* node) {
     766             :   DCHECK_EQ(IrOpcode::kJSCreateArrayIterator, node->opcode());
     767             :   CreateArrayIteratorParameters const& p =
     768        1396 :       CreateArrayIteratorParametersOf(node->op());
     769        1396 :   Node* iterated_object = NodeProperties::GetValueInput(node, 0);
     770        1396 :   Node* effect = NodeProperties::GetEffectInput(node);
     771        1396 :   Node* control = NodeProperties::GetControlInput(node);
     772             : 
     773             :   // Create the JSArrayIterator result.
     774             :   AllocationBuilder a(jsgraph(), effect, control);
     775        1396 :   a.Allocate(JSArrayIterator::kSize, NOT_TENURED, Type::OtherObject());
     776             :   a.Store(AccessBuilder::ForMap(),
     777        1396 :           native_context().initial_array_iterator_map());
     778             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
     779        1396 :           jsgraph()->EmptyFixedArrayConstant());
     780             :   a.Store(AccessBuilder::ForJSObjectElements(),
     781        1396 :           jsgraph()->EmptyFixedArrayConstant());
     782        1396 :   a.Store(AccessBuilder::ForJSArrayIteratorIteratedObject(), iterated_object);
     783             :   a.Store(AccessBuilder::ForJSArrayIteratorNextIndex(),
     784        1396 :           jsgraph()->ZeroConstant());
     785             :   a.Store(AccessBuilder::ForJSArrayIteratorKind(),
     786        2792 :           jsgraph()->Constant(static_cast<int>(p.kind())));
     787             :   RelaxControls(node);
     788        1396 :   a.FinishAndChange(node);
     789        1396 :   return Changed(node);
     790             : }
     791             : 
     792       18641 : Reduction JSCreateLowering::ReduceJSCreateAsyncFunctionObject(Node* node) {
     793             :   DCHECK_EQ(IrOpcode::kJSCreateAsyncFunctionObject, node->opcode());
     794        1080 :   int const register_count = RegisterCountOf(node->op());
     795        1080 :   Node* closure = NodeProperties::GetValueInput(node, 0);
     796        1080 :   Node* receiver = NodeProperties::GetValueInput(node, 1);
     797        1080 :   Node* promise = NodeProperties::GetValueInput(node, 2);
     798        1080 :   Node* context = NodeProperties::GetContextInput(node);
     799        1080 :   Node* effect = NodeProperties::GetEffectInput(node);
     800        1080 :   Node* control = NodeProperties::GetControlInput(node);
     801             : 
     802             :   // Create the register file.
     803             :   AllocationBuilder ab(jsgraph(), effect, control);
     804        1080 :   ab.AllocateArray(register_count, factory()->fixed_array_map());
     805       12161 :   for (int i = 0; i < register_count; ++i) {
     806       11081 :     ab.Store(AccessBuilder::ForFixedArraySlot(i),
     807       22162 :              jsgraph()->UndefinedConstant());
     808             :   }
     809        1080 :   Node* parameters_and_registers = effect = ab.Finish();
     810             : 
     811             :   // Create the JSAsyncFunctionObject result.
     812             :   AllocationBuilder a(jsgraph(), effect, control);
     813        1080 :   a.Allocate(JSAsyncFunctionObject::kSize);
     814        1080 :   Node* empty_fixed_array = jsgraph()->EmptyFixedArrayConstant();
     815             :   a.Store(AccessBuilder::ForMap(),
     816        1080 :           native_context().async_function_object_map());
     817        1080 :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), empty_fixed_array);
     818        1080 :   a.Store(AccessBuilder::ForJSObjectElements(), empty_fixed_array);
     819        1080 :   a.Store(AccessBuilder::ForJSGeneratorObjectContext(), context);
     820        1080 :   a.Store(AccessBuilder::ForJSGeneratorObjectFunction(), closure);
     821        1080 :   a.Store(AccessBuilder::ForJSGeneratorObjectReceiver(), receiver);
     822             :   a.Store(AccessBuilder::ForJSGeneratorObjectInputOrDebugPos(),
     823        1080 :           jsgraph()->UndefinedConstant());
     824             :   a.Store(AccessBuilder::ForJSGeneratorObjectResumeMode(),
     825        1080 :           jsgraph()->Constant(JSGeneratorObject::kNext));
     826             :   a.Store(AccessBuilder::ForJSGeneratorObjectContinuation(),
     827        1080 :           jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting));
     828             :   a.Store(AccessBuilder::ForJSGeneratorObjectParametersAndRegisters(),
     829        1080 :           parameters_and_registers);
     830        1080 :   a.Store(AccessBuilder::ForJSAsyncFunctionObjectPromise(), promise);
     831        1080 :   a.FinishAndChange(node);
     832        1080 :   return Changed(node);
     833             : }
     834             : 
     835             : namespace {
     836             : 
     837         163 : MapRef MapForCollectionIterationKind(const NativeContextRef& native_context,
     838             :                                      CollectionKind collection_kind,
     839             :                                      IterationKind iteration_kind) {
     840         163 :   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          71 :       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          21 :           return native_context.map_key_value_iterator_map();
     859             :       }
     860             :       break;
     861             :   }
     862           0 :   UNREACHABLE();
     863             : }
     864             : 
     865             : }  // namespace
     866             : 
     867         815 : Reduction JSCreateLowering::ReduceJSCreateCollectionIterator(Node* node) {
     868             :   DCHECK_EQ(IrOpcode::kJSCreateCollectionIterator, node->opcode());
     869         163 :   CreateCollectionIteratorParameters const& p =
     870         163 :       CreateCollectionIteratorParametersOf(node->op());
     871         163 :   Node* iterated_object = NodeProperties::GetValueInput(node, 0);
     872         163 :   Node* effect = NodeProperties::GetEffectInput(node);
     873         163 :   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         489 :       iterated_object, effect, control);
     879             : 
     880             :   // Create the JSArrayIterator result.
     881             :   AllocationBuilder a(jsgraph(), effect, control);
     882         163 :   a.Allocate(JSCollectionIterator::kSize, NOT_TENURED, Type::OtherObject());
     883             :   a.Store(AccessBuilder::ForMap(),
     884             :           MapForCollectionIterationKind(native_context(), p.collection_kind(),
     885         163 :                                         p.iteration_kind()));
     886             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
     887         163 :           jsgraph()->EmptyFixedArrayConstant());
     888             :   a.Store(AccessBuilder::ForJSObjectElements(),
     889         163 :           jsgraph()->EmptyFixedArrayConstant());
     890         163 :   a.Store(AccessBuilder::ForJSCollectionIteratorTable(), table);
     891             :   a.Store(AccessBuilder::ForJSCollectionIteratorIndex(),
     892         163 :           jsgraph()->ZeroConstant());
     893             :   RelaxControls(node);
     894         163 :   a.FinishAndChange(node);
     895         163 :   return Changed(node);
     896             : }
     897             : 
     898         689 : Reduction JSCreateLowering::ReduceJSCreateBoundFunction(Node* node) {
     899             :   DCHECK_EQ(IrOpcode::kJSCreateBoundFunction, node->opcode());
     900         104 :   CreateBoundFunctionParameters const& p =
     901         104 :       CreateBoundFunctionParametersOf(node->op());
     902         104 :   int const arity = static_cast<int>(p.arity());
     903             :   MapRef const map(broker(), p.map());
     904         104 :   Node* bound_target_function = NodeProperties::GetValueInput(node, 0);
     905         104 :   Node* bound_this = NodeProperties::GetValueInput(node, 1);
     906         104 :   Node* effect = NodeProperties::GetEffectInput(node);
     907         104 :   Node* control = NodeProperties::GetControlInput(node);
     908             : 
     909             :   // Create the [[BoundArguments]] for the result.
     910         104 :   Node* bound_arguments = jsgraph()->EmptyFixedArrayConstant();
     911         104 :   if (arity > 0) {
     912             :     AllocationBuilder a(jsgraph(), effect, control);
     913          65 :     a.AllocateArray(arity, factory()->fixed_array_map());
     914         157 :     for (int i = 0; i < arity; ++i) {
     915          92 :       a.Store(AccessBuilder::ForFixedArraySlot(i),
     916         184 :               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         104 :   a.Allocate(JSBoundFunction::kSize, NOT_TENURED, Type::BoundFunction());
     924         104 :   a.Store(AccessBuilder::ForMap(), map);
     925             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
     926         104 :           jsgraph()->EmptyFixedArrayConstant());
     927             :   a.Store(AccessBuilder::ForJSObjectElements(),
     928         104 :           jsgraph()->EmptyFixedArrayConstant());
     929             :   a.Store(AccessBuilder::ForJSBoundFunctionBoundTargetFunction(),
     930         104 :           bound_target_function);
     931         104 :   a.Store(AccessBuilder::ForJSBoundFunctionBoundThis(), bound_this);
     932         104 :   a.Store(AccessBuilder::ForJSBoundFunctionBoundArguments(), bound_arguments);
     933             :   RelaxControls(node);
     934         104 :   a.FinishAndChange(node);
     935         104 :   return Changed(node);
     936             : }
     937             : 
     938     2284489 : Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
     939             :   DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode());
     940      437233 :   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      437236 :   Node* effect = NodeProperties::GetEffectInput(node);
     945      437236 :   Node* control = NodeProperties::GetControlInput(node);
     946      437236 :   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      437235 :   if (!feedback_cell.map().equals(
     952      437236 :           MapRef(broker(), factory()->many_closures_cell_map()))) {
     953             :     return NoChange();
     954             :   }
     955             : 
     956             :   MapRef function_map =
     957       64036 :       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       32018 :   a.Allocate(function_map.instance_size(), pretenure, Type::Function());
     976       32018 :   a.Store(AccessBuilder::ForMap(), function_map);
     977             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
     978       32018 :           jsgraph()->EmptyFixedArrayConstant());
     979             :   a.Store(AccessBuilder::ForJSObjectElements(),
     980       32018 :           jsgraph()->EmptyFixedArrayConstant());
     981       32018 :   a.Store(AccessBuilder::ForJSFunctionSharedFunctionInfo(), shared);
     982       32018 :   a.Store(AccessBuilder::ForJSFunctionContext(), context);
     983       32018 :   a.Store(AccessBuilder::ForJSFunctionFeedbackCell(), feedback_cell);
     984       32018 :   a.Store(AccessBuilder::ForJSFunctionCode(), code);
     985             :   STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kTaggedSize);
     986       32018 :   if (function_map.has_prototype_slot()) {
     987             :     a.Store(AccessBuilder::ForJSFunctionPrototypeOrInitialMap(),
     988        2220 :             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       32018 :   a.FinishAndChange(node);
     997             :   return Changed(node);
     998             : }
     999             : 
    1000       15736 : Reduction JSCreateLowering::ReduceJSCreateIterResultObject(Node* node) {
    1001             :   DCHECK_EQ(IrOpcode::kJSCreateIterResultObject, node->opcode());
    1002        3934 :   Node* value = NodeProperties::GetValueInput(node, 0);
    1003        3934 :   Node* done = NodeProperties::GetValueInput(node, 1);
    1004        3934 :   Node* effect = NodeProperties::GetEffectInput(node);
    1005             : 
    1006             :   Node* iterator_result_map =
    1007        7868 :       jsgraph()->Constant(native_context().iterator_result_map());
    1008             : 
    1009             :   // Emit code to allocate the JSIteratorResult instance.
    1010        3934 :   AllocationBuilder a(jsgraph(), effect, graph()->start());
    1011        3934 :   a.Allocate(JSIteratorResult::kSize);
    1012        3934 :   a.Store(AccessBuilder::ForMap(), iterator_result_map);
    1013             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
    1014        3934 :           jsgraph()->EmptyFixedArrayConstant());
    1015             :   a.Store(AccessBuilder::ForJSObjectElements(),
    1016        3934 :           jsgraph()->EmptyFixedArrayConstant());
    1017        3934 :   a.Store(AccessBuilder::ForJSIteratorResultValue(), value);
    1018        3934 :   a.Store(AccessBuilder::ForJSIteratorResultDone(), done);
    1019             :   STATIC_ASSERT(JSIteratorResult::kSize == 5 * kTaggedSize);
    1020        3934 :   a.FinishAndChange(node);
    1021        3934 :   return Changed(node);
    1022             : }
    1023             : 
    1024         310 : Reduction JSCreateLowering::ReduceJSCreateStringIterator(Node* node) {
    1025             :   DCHECK_EQ(IrOpcode::kJSCreateStringIterator, node->opcode());
    1026          62 :   Node* string = NodeProperties::GetValueInput(node, 0);
    1027          62 :   Node* effect = NodeProperties::GetEffectInput(node);
    1028             : 
    1029             :   Node* map =
    1030         124 :       jsgraph()->Constant(native_context().initial_string_iterator_map());
    1031             :   // Allocate new iterator and attach the iterator to this string.
    1032          62 :   AllocationBuilder a(jsgraph(), effect, graph()->start());
    1033          62 :   a.Allocate(JSStringIterator::kSize, NOT_TENURED, Type::OtherObject());
    1034          62 :   a.Store(AccessBuilder::ForMap(), map);
    1035             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
    1036          62 :           jsgraph()->EmptyFixedArrayConstant());
    1037             :   a.Store(AccessBuilder::ForJSObjectElements(),
    1038          62 :           jsgraph()->EmptyFixedArrayConstant());
    1039          62 :   a.Store(AccessBuilder::ForJSStringIteratorString(), string);
    1040          62 :   a.Store(AccessBuilder::ForJSStringIteratorIndex(), jsgraph()->SmiConstant(0));
    1041             :   STATIC_ASSERT(JSIteratorResult::kSize == 5 * kTaggedSize);
    1042          62 :   a.FinishAndChange(node);
    1043          62 :   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        6970 : Reduction JSCreateLowering::ReduceJSCreatePromise(Node* node) {
    1077             :   DCHECK_EQ(IrOpcode::kJSCreatePromise, node->opcode());
    1078        1394 :   Node* effect = NodeProperties::GetEffectInput(node);
    1079             : 
    1080        1394 :   MapRef promise_map = native_context().promise_function().initial_map();
    1081             : 
    1082        1394 :   AllocationBuilder a(jsgraph(), effect, graph()->start());
    1083        1394 :   a.Allocate(promise_map.instance_size());
    1084        1394 :   a.Store(AccessBuilder::ForMap(), promise_map);
    1085             :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
    1086        1394 :           jsgraph()->EmptyFixedArrayConstant());
    1087             :   a.Store(AccessBuilder::ForJSObjectElements(),
    1088        1394 :           jsgraph()->EmptyFixedArrayConstant());
    1089             :   a.Store(AccessBuilder::ForJSObjectOffset(JSPromise::kReactionsOrResultOffset),
    1090        1394 :           jsgraph()->ZeroConstant());
    1091             :   STATIC_ASSERT(v8::Promise::kPending == 0);
    1092             :   a.Store(AccessBuilder::ForJSObjectOffset(JSPromise::kFlagsOffset),
    1093        1394 :           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        1394 :   a.FinishAndChange(node);
    1101        1394 :   return Changed(node);
    1102             : }
    1103             : 
    1104       57876 : Reduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
    1105             :   DCHECK(node->opcode() == IrOpcode::kJSCreateLiteralArray ||
    1106             :          node->opcode() == IrOpcode::kJSCreateLiteralObject);
    1107       23187 :   CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
    1108       23187 :   Node* effect = NodeProperties::GetEffectInput(node);
    1109       23187 :   Node* control = NodeProperties::GetControlInput(node);
    1110             : 
    1111             :   FeedbackVectorRef feedback_vector(broker(), p.feedback().vector());
    1112       23187 :   ObjectRef feedback = feedback_vector.get(p.feedback().slot());
    1113       23187 :   if (feedback.IsAllocationSite()) {
    1114        5970 :     AllocationSiteRef site = feedback.AsAllocationSite();
    1115        5970 :     if (site.IsFastLiteral()) {
    1116             :       PretenureFlag pretenure = NOT_TENURED;
    1117        5751 :       if (FLAG_allocation_site_pretenuring) {
    1118        5751 :         pretenure = dependencies()->DependOnPretenureMode(site);
    1119             :       }
    1120        5751 :       dependencies()->DependOnElementsKinds(site);
    1121        5751 :       JSObjectRef boilerplate = site.boilerplate().value();
    1122             :       Node* value = effect =
    1123        5751 :           AllocateFastLiteral(effect, control, boilerplate, pretenure);
    1124        5751 :       ReplaceWithValue(node, value, effect, control);
    1125             :       return Replace(value);
    1126             :     }
    1127             :   }
    1128             :   return NoChange();
    1129             : }
    1130             : 
    1131       46374 : Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) {
    1132             :   DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralArray, node->opcode());
    1133       21651 :   FeedbackParameter const& p = FeedbackParameterOf(node->op());
    1134             :   FeedbackVectorRef fv(broker(), p.feedback().vector());
    1135       21651 :   ObjectRef feedback = fv.get(p.feedback().slot());
    1136       21651 :   if (feedback.IsAllocationSite()) {
    1137        1024 :     AllocationSiteRef site = feedback.AsAllocationSite();
    1138             :     DCHECK(!site.PointsToLiteral());
    1139             :     MapRef initial_map =
    1140        2048 :         native_context().GetInitialJSArrayMap(site.GetElementsKind());
    1141        1024 :     PretenureFlag const pretenure = dependencies()->DependOnPretenureMode(site);
    1142        1024 :     dependencies()->DependOnElementsKind(site);
    1143        1024 :     Node* length = jsgraph()->ZeroConstant();
    1144             :     DCHECK(!initial_map.IsInobjectSlackTrackingInProgress());
    1145             :     SlackTrackingPrediction slack_tracking_prediction(
    1146        1024 :         initial_map, initial_map.instance_size());
    1147             :     return ReduceNewArray(node, length, 0, initial_map,
    1148        1024 :                           initial_map.elements_kind(), pretenure,
    1149        1024 :                           slack_tracking_prediction);
    1150             :   }
    1151             :   return NoChange();
    1152             : }
    1153             : 
    1154       53181 : Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralObject(Node* node) {
    1155             :   DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralObject, node->opcode());
    1156        5909 :   Node* effect = NodeProperties::GetEffectInput(node);
    1157        5909 :   Node* control = NodeProperties::GetControlInput(node);
    1158             : 
    1159             :   // Retrieve the initial map for the object.
    1160        5909 :   MapRef map = native_context().object_function().initial_map();
    1161             :   DCHECK(!map.is_dictionary_map());
    1162             :   DCHECK(!map.IsInobjectSlackTrackingInProgress());
    1163        5909 :   Node* js_object_map = jsgraph()->Constant(map);
    1164             : 
    1165             :   // Setup elements and properties.
    1166        5909 :   Node* elements = jsgraph()->EmptyFixedArrayConstant();
    1167        5909 :   Node* properties = jsgraph()->EmptyFixedArrayConstant();
    1168             : 
    1169             :   // Perform the allocation of the actual JSArray object.
    1170             :   AllocationBuilder a(jsgraph(), effect, control);
    1171        5909 :   a.Allocate(map.instance_size());
    1172        5909 :   a.Store(AccessBuilder::ForMap(), js_object_map);
    1173        5909 :   a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
    1174        5909 :   a.Store(AccessBuilder::ForJSObjectElements(), elements);
    1175       29545 :   for (int i = 0; i < map.GetInObjectProperties(); i++) {
    1176             :     a.Store(AccessBuilder::ForJSObjectInObjectProperty(map, i),
    1177       23636 :             jsgraph()->UndefinedConstant());
    1178             :   }
    1179             : 
    1180             :   RelaxControls(node);
    1181        5909 :   a.FinishAndChange(node);
    1182        5909 :   return Changed(node);
    1183             : }
    1184             : 
    1185       12842 : Reduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) {
    1186             :   DCHECK_EQ(IrOpcode::kJSCreateLiteralRegExp, node->opcode());
    1187        6421 :   CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
    1188        6421 :   Node* effect = NodeProperties::GetEffectInput(node);
    1189        6421 :   Node* control = NodeProperties::GetControlInput(node);
    1190             : 
    1191             :   FeedbackVectorRef feedback_vector(broker(), p.feedback().vector());
    1192        6421 :   ObjectRef feedback = feedback_vector.get(p.feedback().slot());
    1193        6421 :   if (feedback.IsJSRegExp()) {
    1194         583 :     JSRegExpRef boilerplate = feedback.AsJSRegExp();
    1195         583 :     Node* value = effect = AllocateLiteralRegExp(effect, control, boilerplate);
    1196         583 :     ReplaceWithValue(node, value, effect, control);
    1197             :     return Replace(value);
    1198             :   }
    1199             :   return NoChange();
    1200             : }
    1201             : 
    1202      190941 : Reduction JSCreateLowering::ReduceJSCreateFunctionContext(Node* node) {
    1203             :   DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode());
    1204       29086 :   const CreateFunctionContextParameters& parameters =
    1205       29086 :       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       29086 :   if (slot_count < kFunctionContextAllocationLimit) {
    1212             :     // JSCreateFunctionContext[slot_count < limit]](fun)
    1213       24417 :     Node* effect = NodeProperties::GetEffectInput(node);
    1214       24417 :     Node* control = NodeProperties::GetControlInput(node);
    1215       24417 :     Node* context = NodeProperties::GetContextInput(node);
    1216       24417 :     Node* extension = jsgraph()->TheHoleConstant();
    1217             :     AllocationBuilder a(jsgraph(), effect, control);
    1218             :     STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);  // Ensure fully covered.
    1219       24417 :     int context_length = slot_count + Context::MIN_CONTEXT_SLOTS;
    1220             :     Handle<Map> map;
    1221       24417 :     switch (scope_type) {
    1222             :       case EVAL_SCOPE:
    1223        5623 :         map = factory()->eval_context_map();
    1224        5623 :         break;
    1225             :       case FUNCTION_SCOPE:
    1226       18794 :         map = factory()->function_context_map();
    1227       18794 :         break;
    1228             :       default:
    1229           0 :         UNREACHABLE();
    1230             :     }
    1231       24417 :     a.AllocateContext(context_length, map);
    1232             :     a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX),
    1233       24417 :             scope_info);
    1234       24417 :     a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
    1235       24417 :     a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
    1236             :     a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
    1237       48834 :             jsgraph()->Constant(native_context()));
    1238       83935 :     for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) {
    1239       59518 :       a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant());
    1240             :     }
    1241             :     RelaxControls(node);
    1242       24417 :     a.FinishAndChange(node);
    1243             :     return Changed(node);
    1244             :   }
    1245             : 
    1246             :   return NoChange();
    1247             : }
    1248             : 
    1249        1944 : Reduction JSCreateLowering::ReduceJSCreateWithContext(Node* node) {
    1250             :   DCHECK_EQ(IrOpcode::kJSCreateWithContext, node->opcode());
    1251         486 :   ScopeInfoRef scope_info(broker(), ScopeInfoOf(node->op()));
    1252         486 :   Node* extension = NodeProperties::GetValueInput(node, 0);
    1253         486 :   Node* effect = NodeProperties::GetEffectInput(node);
    1254         486 :   Node* control = NodeProperties::GetControlInput(node);
    1255         486 :   Node* context = NodeProperties::GetContextInput(node);
    1256             : 
    1257             :   AllocationBuilder a(jsgraph(), effect, control);
    1258             :   STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);  // Ensure fully covered.
    1259         486 :   a.AllocateContext(Context::MIN_CONTEXT_SLOTS, factory()->with_context_map());
    1260         486 :   a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX), scope_info);
    1261         486 :   a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
    1262         486 :   a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
    1263             :   a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
    1264         972 :           jsgraph()->Constant(native_context()));
    1265             :   RelaxControls(node);
    1266         486 :   a.FinishAndChange(node);
    1267         486 :   return Changed(node);
    1268             : }
    1269             : 
    1270       70570 : Reduction JSCreateLowering::ReduceJSCreateCatchContext(Node* node) {
    1271             :   DCHECK_EQ(IrOpcode::kJSCreateCatchContext, node->opcode());
    1272       14114 :   ScopeInfoRef scope_info(broker(), ScopeInfoOf(node->op()));
    1273       14114 :   Node* exception = NodeProperties::GetValueInput(node, 0);
    1274       14114 :   Node* effect = NodeProperties::GetEffectInput(node);
    1275       14114 :   Node* control = NodeProperties::GetControlInput(node);
    1276       14114 :   Node* context = NodeProperties::GetContextInput(node);
    1277       14114 :   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       14114 :                     factory()->catch_context_map());
    1283       14114 :   a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX), scope_info);
    1284       14114 :   a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
    1285       14114 :   a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
    1286             :   a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
    1287       28228 :           jsgraph()->Constant(native_context()));
    1288             :   a.Store(AccessBuilder::ForContextSlot(Context::THROWN_OBJECT_INDEX),
    1289       14114 :           exception);
    1290             :   RelaxControls(node);
    1291       14114 :   a.FinishAndChange(node);
    1292       14114 :   return Changed(node);
    1293             : }
    1294             : 
    1295       53226 : Reduction JSCreateLowering::ReduceJSCreateBlockContext(Node* node) {
    1296             :   DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode());
    1297        9134 :   ScopeInfoRef scope_info(broker(), ScopeInfoOf(node->op()));
    1298        9134 :   int const context_length = scope_info.ContextLength();
    1299             : 
    1300             :   // Use inline allocation for block contexts up to a size limit.
    1301        9134 :   if (context_length < kBlockContextAllocationLimit) {
    1302             :     // JSCreateBlockContext[scope[length < limit]](fun)
    1303        9134 :     Node* effect = NodeProperties::GetEffectInput(node);
    1304        9134 :     Node* control = NodeProperties::GetControlInput(node);
    1305        9134 :     Node* context = NodeProperties::GetContextInput(node);
    1306        9134 :     Node* extension = jsgraph()->TheHoleConstant();
    1307             : 
    1308             :     AllocationBuilder a(jsgraph(), effect, control);
    1309             :     STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 4);  // Ensure fully covered.
    1310        9134 :     a.AllocateContext(context_length, factory()->block_context_map());
    1311             :     a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX),
    1312        9134 :             scope_info);
    1313        9134 :     a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
    1314        9134 :     a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
    1315             :     a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX),
    1316       18268 :             jsgraph()->Constant(native_context()));
    1317       16690 :     for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) {
    1318        7556 :       a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant());
    1319             :     }
    1320             :     RelaxControls(node);
    1321        9134 :     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         592 : Node* JSCreateLowering::AllocateArguments(Node* effect, Node* control,
    1428        2491 :                                           Node* frame_state) {
    1429         592 :   FrameStateInfo state_info = FrameStateInfoOf(frame_state->op());
    1430         592 :   int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
    1431         630 :   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         554 :   auto parameters_it = ++parameters_access.begin();
    1437             : 
    1438             :   // Actually allocate the backing store.
    1439             :   AllocationBuilder a(jsgraph(), effect, control);
    1440         554 :   a.AllocateArray(argument_count, factory()->fixed_array_map());
    1441        1861 :   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        2614 :             (*parameters_it).node);
    1445             :   }
    1446         554 :   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         554 : Node* JSCreateLowering::AllocateRestArguments(Node* effect, Node* control,
    1452         554 :                                               Node* frame_state,
    1453        1061 :                                               int start_index) {
    1454         554 :   FrameStateInfo state_info = FrameStateInfoOf(frame_state->op());
    1455         554 :   int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
    1456        1108 :   int num_elements = std::max(0, argument_count - start_index);
    1457         851 :   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         630 : Node* JSCreateLowering::AllocateAliasedArguments(
    1484         630 :     Node* effect, Node* control, Node* frame_state, Node* context,
    1485        3494 :     const SharedFunctionInfoRef& shared, bool* has_aliased_arguments) {
    1486         630 :   FrameStateInfo state_info = FrameStateInfoOf(frame_state->op());
    1487         630 :   int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
    1488         741 :   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         519 :   int parameter_count = shared.internal_formal_parameter_count();
    1493         519 :   if (parameter_count == 0) {
    1494         175 :     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         344 :   *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         344 :   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         344 :   aa.AllocateArray(argument_count, factory()->fixed_array_map());
    1511         844 :   for (int i = 0; i < mapped_count; ++i, ++parameters_it) {
    1512             :     aa.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
    1513        1000 :              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         344 :   Node* arguments = aa.Finish();
    1521             : 
    1522             :   // Actually allocate the backing store.
    1523             :   AllocationBuilder a(jsgraph(), arguments, control);
    1524         344 :   a.AllocateArray(mapped_count + 2, factory()->sloppy_arguments_elements_map());
    1525             :   a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(0),
    1526         344 :           context);
    1527             :   a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(1),
    1528         344 :           arguments);
    1529         844 :   for (int i = 0; i < mapped_count; ++i) {
    1530         500 :     int idx = Context::MIN_CONTEXT_SLOTS + parameter_count - 1 - i;
    1531         500 :     a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i + 2),
    1532        2000 :             jsgraph()->Constant(idx));
    1533             :   }
    1534         344 :   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       10993 : Node* JSCreateLowering::AllocateAliasedArguments(
    1542             :     Node* effect, Node* control, Node* context, Node* arguments_frame,
    1543             :     Node* arguments_length, const SharedFunctionInfoRef& shared,
    1544       22014 :     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       10993 :   int parameter_count = shared.internal_formal_parameter_count();
    1548       10993 :   if (parameter_count == 0) {
    1549             :     return graph()->NewNode(simplified()->NewArgumentsElements(0),
    1550       17278 :                             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        2354 :   *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        2354 :                        arguments_frame, arguments_length, effect);
    1566             : 
    1567             :   // Actually allocate the backing store.
    1568             :   AllocationBuilder a(jsgraph(), arguments, control);
    1569        2354 :   a.AllocateArray(mapped_count + 2, factory()->sloppy_arguments_elements_map());
    1570             :   a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(0),
    1571        2354 :           context);
    1572             :   a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(1),
    1573        2354 :           arguments);
    1574        6092 :   for (int i = 0; i < mapped_count; ++i) {
    1575        3738 :     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       18690 :         jsgraph()->Constant(idx), jsgraph()->TheHoleConstant());
    1581        3738 :     a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i + 2),
    1582        7476 :             value);
    1583             :   }
    1584        2354 :   return a.Finish();
    1585             : }
    1586             : 
    1587         592 : Node* JSCreateLowering::AllocateElements(Node* effect, Node* control,
    1588             :                                          ElementsKind elements_kind,
    1589             :                                          int capacity,
    1590        3855 :                                          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        1184 :                                  : factory()->fixed_array_map();
    1597             :   ElementAccess access = IsDoubleElementsKind(elements_kind)
    1598             :                              ? AccessBuilder::ForFixedDoubleArrayElement()
    1599         592 :                              : AccessBuilder::ForFixedArrayElement();
    1600         592 :   Node* value = jsgraph()->TheHoleConstant();
    1601             : 
    1602             :   // Actually allocate the backing store.
    1603             :   AllocationBuilder a(jsgraph(), effect, control);
    1604         592 :   a.AllocateArray(capacity, elements_map, pretenure);
    1605        3263 :   for (int i = 0; i < capacity; ++i) {
    1606        5342 :     Node* index = jsgraph()->Constant(i);
    1607        2671 :     a.Store(access, index, value);
    1608             :   }
    1609         592 :   return a.Finish();
    1610             : }
    1611             : 
    1612         177 : Node* JSCreateLowering::AllocateElements(Node* effect, Node* control,
    1613             :                                          ElementsKind elements_kind,
    1614         676 :                                          std::vector<Node*> const& values,
    1615         676 :                                          PretenureFlag pretenure) {
    1616         177 :   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         354 :                                  : factory()->fixed_array_map();
    1623             :   ElementAccess access = IsDoubleElementsKind(elements_kind)
    1624             :                              ? AccessBuilder::ForFixedDoubleArrayElement()
    1625         177 :                              : AccessBuilder::ForFixedArrayElement();
    1626             : 
    1627             :   // Actually allocate the backing store.
    1628             :   AllocationBuilder a(jsgraph(), effect, control);
    1629         177 :   a.AllocateArray(capacity, elements_map, pretenure);
    1630         676 :   for (int i = 0; i < capacity; ++i) {
    1631         998 :     Node* index = jsgraph()->Constant(i);
    1632         998 :     a.Store(access, index, values[i]);
    1633             :   }
    1634         177 :   return a.Finish();
    1635             : }
    1636             : 
    1637        6427 : Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control,
    1638             :                                             JSObjectRef boilerplate,
    1639       22268 :                                             PretenureFlag pretenure) {
    1640             :   // Setup the properties backing store.
    1641        6427 :   Node* properties = jsgraph()->EmptyFixedArrayConstant();
    1642             : 
    1643             :   // Compute the in-object properties to store first (might have effects).
    1644        6427 :   MapRef boilerplate_map = boilerplate.map();
    1645             :   ZoneVector<std::pair<FieldAccess, Node*>> inobject_fields(zone());
    1646        6427 :   inobject_fields.reserve(boilerplate_map.GetInObjectProperties());
    1647        6427 :   int const boilerplate_nof = boilerplate_map.NumberOfOwnDescriptors();
    1648       13680 :   for (int i = 0; i < boilerplate_nof; ++i) {
    1649             :     PropertyDetails const property_details =
    1650        7253 :         boilerplate_map.GetPropertyDetails(i);
    1651       11215 :     if (property_details.location() != kField) continue;
    1652             :     DCHECK_EQ(kData, property_details.kind());
    1653        3291 :     NameRef property_name = boilerplate_map.GetPropertyKey(i);
    1654        3291 :     FieldIndex index = boilerplate_map.GetFieldIndexFor(i);
    1655             :     FieldAccess access = {
    1656             :         kTaggedBase,        index.offset(), property_name.object(),
    1657             :         MaybeHandle<Map>(), Type::Any(),    MachineType::AnyTagged(),
    1658        3291 :         kFullWriteBarrier};
    1659             :     Node* value;
    1660        3291 :     if (boilerplate_map.IsUnboxedDoubleField(i)) {
    1661             :       access.machine_type = MachineType::Float64();
    1662             :       access.type = Type::Number();
    1663         256 :       value = jsgraph()->Constant(boilerplate.RawFastDoublePropertyAt(index));
    1664             :     } else {
    1665        3163 :       ObjectRef boilerplate_value = boilerplate.RawFastPropertyAt(index);
    1666        3163 :       if (boilerplate_value.IsJSObject()) {
    1667         304 :         JSObjectRef boilerplate_object = boilerplate_value.AsJSObject();
    1668             :         value = effect =
    1669         304 :             AllocateFastLiteral(effect, control, boilerplate_object, pretenure);
    1670        2859 :       } 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        2859 :       } else if (property_details.representation().IsSmi()) {
    1681             :         // Ensure that value is stored as smi.
    1682             :         bool is_uninitialized =
    1683        1668 :             boilerplate_value.IsHeapObject() &&
    1684        2036 :             boilerplate_value.AsHeapObject().map().oddball_type() ==
    1685         932 :                 OddballType::kUninitialized;
    1686             :         value = is_uninitialized
    1687             :                     ? jsgraph()->ZeroConstant()
    1688        2600 :                     : jsgraph()->Constant(boilerplate_value.AsSmi());
    1689             :       } else {
    1690        1559 :         value = jsgraph()->Constant(boilerplate_value);
    1691             :       }
    1692             :     }
    1693        3291 :     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        6427 :   int const boilerplate_length = boilerplate_map.GetInObjectProperties();
    1698       14684 :   for (int index = static_cast<int>(inobject_fields.size());
    1699             :        index < boilerplate_length; ++index) {
    1700             :     FieldAccess access =
    1701        1830 :         AccessBuilder::ForJSObjectInObjectProperty(boilerplate_map, index);
    1702        1830 :     Node* value = jsgraph()->HeapConstant(factory()->one_pointer_filler_map());
    1703        1830 :     inobject_fields.push_back(std::make_pair(access, value));
    1704             :   }
    1705             : 
    1706             :   // Setup the elements backing store.
    1707        6427 :   Node* elements =
    1708        6427 :       AllocateFastLiteralElements(effect, control, boilerplate, pretenure);
    1709       12854 :   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        6427 :                    Type::For(boilerplate_map));
    1715        6427 :   builder.Store(AccessBuilder::ForMap(), boilerplate_map);
    1716        6427 :   builder.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
    1717        6427 :   builder.Store(AccessBuilder::ForJSObjectElements(), elements);
    1718        6427 :   if (boilerplate.IsJSArray()) {
    1719        3962 :     JSArrayRef boilerplate_array = boilerplate.AsJSArray();
    1720             :     builder.Store(
    1721        3962 :         AccessBuilder::ForJSArrayLength(boilerplate_array.GetElementsKind()),
    1722        7924 :         boilerplate_array.length());
    1723             :   }
    1724       17975 :   for (auto const& inobject_field : inobject_fields) {
    1725        5121 :     builder.Store(inobject_field.first, inobject_field.second);
    1726             :   }
    1727        6427 :   return builder.Finish();
    1728             : }
    1729             : 
    1730        6427 : Node* JSCreateLowering::AllocateFastLiteralElements(Node* effect, Node* control,
    1731             :                                                     JSObjectRef boilerplate,
    1732       34211 :                                                     PretenureFlag pretenure) {
    1733        6427 :   FixedArrayBaseRef boilerplate_elements = boilerplate.elements();
    1734             : 
    1735             :   // Empty or copy-on-write elements just store a constant.
    1736        6427 :   int const elements_length = boilerplate_elements.length();
    1737        6427 :   MapRef elements_map = boilerplate_elements.map();
    1738        6427 :   if (boilerplate_elements.length() == 0 || elements_map.IsFixedCowArrayMap()) {
    1739        4341 :     if (pretenure == TENURED) {
    1740          40 :       boilerplate.EnsureElementsTenured();
    1741          40 :       boilerplate_elements = boilerplate.elements();
    1742             :     }
    1743        8682 :     return jsgraph()->HeapConstant(boilerplate_elements.object());
    1744             :   }
    1745             : 
    1746             :   // Compute the elements to store first (might have effects).
    1747        2086 :   ZoneVector<Node*> elements_values(elements_length, zone());
    1748        2086 :   if (elements_map.instance_type() == FIXED_DOUBLE_ARRAY_TYPE) {
    1749         508 :     FixedDoubleArrayRef elements = boilerplate_elements.AsFixedDoubleArray();
    1750        7028 :     for (int i = 0; i < elements_length; ++i) {
    1751        6520 :       if (elements.is_the_hole(i)) {
    1752         198 :         elements_values[i] = jsgraph()->TheHoleConstant();
    1753             :       } else {
    1754       19263 :         elements_values[i] = jsgraph()->Constant(elements.get_scalar(i));
    1755             :       }
    1756             :     }
    1757             :   } else {
    1758        1578 :     FixedArrayRef elements = boilerplate_elements.AsFixedArray();
    1759        8093 :     for (int i = 0; i < elements_length; ++i) {
    1760        6515 :       ObjectRef element_value = elements.get(i);
    1761        6515 :       if (element_value.IsJSObject()) {
    1762         372 :         elements_values[i] = effect = AllocateFastLiteral(
    1763         372 :             effect, control, element_value.AsJSObject(), pretenure);
    1764             :       } else {
    1765       12286 :         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        2086 :   builder.AllocateArray(elements_length, elements_map.object(), pretenure);
    1773             :   ElementAccess const access =
    1774        2086 :       (elements_map.instance_type() == FIXED_DOUBLE_ARRAY_TYPE)
    1775             :           ? AccessBuilder::ForFixedDoubleArrayElement()
    1776        2086 :           : AccessBuilder::ForFixedArrayElement();
    1777       13035 :   for (int i = 0; i < elements_length; ++i) {
    1778       39105 :     builder.Store(access, jsgraph()->Constant(i), elements_values[i]);
    1779             :   }
    1780        2086 :   return builder.Finish();
    1781             : }
    1782             : 
    1783         583 : Node* JSCreateLowering::AllocateLiteralRegExp(Node* effect, Node* control,
    1784         583 :                                               JSRegExpRef boilerplate) {
    1785         583 :   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         583 :   builder.Allocate(size, pretenure, Type::For(boilerplate_map));
    1803         583 :   builder.Store(AccessBuilder::ForMap(), boilerplate_map);
    1804             :   builder.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
    1805         583 :                 boilerplate.raw_properties_or_hash());
    1806         583 :   builder.Store(AccessBuilder::ForJSObjectElements(), boilerplate.elements());
    1807             : 
    1808         583 :   builder.Store(AccessBuilder::ForJSRegExpData(), boilerplate.data());
    1809         583 :   builder.Store(AccessBuilder::ForJSRegExpSource(), boilerplate.source());
    1810         583 :   builder.Store(AccessBuilder::ForJSRegExpFlags(), boilerplate.flags());
    1811             :   builder.Store(AccessBuilder::ForJSRegExpLastIndex(),
    1812         583 :                 boilerplate.last_index());
    1813             : 
    1814         583 :   return builder.Finish();
    1815             : }
    1816             : 
    1817      440679 : Factory* JSCreateLowering::factory() const {
    1818      494462 :   return jsgraph()->isolate()->factory();
    1819             : }
    1820             : 
    1821       86565 : Graph* JSCreateLowering::graph() const { return jsgraph()->graph(); }
    1822             : 
    1823        3738 : CommonOperatorBuilder* JSCreateLowering::common() const {
    1824        3738 :   return jsgraph()->common();
    1825             : }
    1826             : 
    1827       57975 : SimplifiedOperatorBuilder* JSCreateLowering::simplified() const {
    1828       57975 :   return jsgraph()->simplified();
    1829             : }
    1830             : 
    1831      115860 : NativeContextRef JSCreateLowering::native_context() const {
    1832           0 :   return broker()->native_context();
    1833             : }
    1834             : 
    1835             : }  // namespace compiler
    1836             : }  // namespace internal
    1837      178779 : }  // namespace v8

Generated by: LCOV version 1.10