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

Generated by: LCOV version 1.10