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