LCOV - code coverage report
Current view: top level - src/compiler - js-create-lowering.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 847 871 97.2 %
Date: 2019-04-17 Functions: 39 44 88.6 %

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

Generated by: LCOV version 1.10