11cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/compiler/js-create-lowering.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/codegen/code-factory.h"
81cb0ef41Sopenharmony_ci#include "src/compiler/access-builder.h"
91cb0ef41Sopenharmony_ci#include "src/compiler/allocation-builder-inl.h"
101cb0ef41Sopenharmony_ci#include "src/compiler/common-operator.h"
111cb0ef41Sopenharmony_ci#include "src/compiler/compilation-dependencies.h"
121cb0ef41Sopenharmony_ci#include "src/compiler/js-graph.h"
131cb0ef41Sopenharmony_ci#include "src/compiler/js-operator.h"
141cb0ef41Sopenharmony_ci#include "src/compiler/linkage.h"
151cb0ef41Sopenharmony_ci#include "src/compiler/node-matchers.h"
161cb0ef41Sopenharmony_ci#include "src/compiler/node-properties.h"
171cb0ef41Sopenharmony_ci#include "src/compiler/node.h"
181cb0ef41Sopenharmony_ci#include "src/compiler/operator-properties.h"
191cb0ef41Sopenharmony_ci#include "src/compiler/simplified-operator.h"
201cb0ef41Sopenharmony_ci#include "src/compiler/state-values-utils.h"
211cb0ef41Sopenharmony_ci#include "src/execution/protectors.h"
221cb0ef41Sopenharmony_ci#include "src/objects/arguments.h"
231cb0ef41Sopenharmony_ci#include "src/objects/hash-table-inl.h"
241cb0ef41Sopenharmony_ci#include "src/objects/heap-number.h"
251cb0ef41Sopenharmony_ci#include "src/objects/js-collection-iterator.h"
261cb0ef41Sopenharmony_ci#include "src/objects/js-generator.h"
271cb0ef41Sopenharmony_ci#include "src/objects/js-promise.h"
281cb0ef41Sopenharmony_ci#include "src/objects/js-regexp-inl.h"
291cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
301cb0ef41Sopenharmony_ci#include "src/objects/template-objects.h"
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_cinamespace v8 {
331cb0ef41Sopenharmony_cinamespace internal {
341cb0ef41Sopenharmony_cinamespace compiler {
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_cinamespace {
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci// Retrieves the frame state holding actual argument values.
391cb0ef41Sopenharmony_ciFrameState GetArgumentsFrameState(FrameState frame_state) {
401cb0ef41Sopenharmony_ci  FrameState outer_state{NodeProperties::GetFrameStateInput(frame_state)};
411cb0ef41Sopenharmony_ci  return outer_state.frame_state_info().type() ==
421cb0ef41Sopenharmony_ci                 FrameStateType::kArgumentsAdaptor
431cb0ef41Sopenharmony_ci             ? outer_state
441cb0ef41Sopenharmony_ci             : frame_state;
451cb0ef41Sopenharmony_ci}
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci// When initializing arrays, we'll unfold the loop if the number of
481cb0ef41Sopenharmony_ci// elements is known to be of this type.
491cb0ef41Sopenharmony_ciconst int kElementLoopUnrollLimit = 16;
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci// Limits up to which context allocations are inlined.
521cb0ef41Sopenharmony_ciconst int kFunctionContextAllocationLimit = 16;
531cb0ef41Sopenharmony_ciconst int kBlockContextAllocationLimit = 16;
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci}  // namespace
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ciReduction JSCreateLowering::Reduce(Node* node) {
581cb0ef41Sopenharmony_ci  switch (node->opcode()) {
591cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreate:
601cb0ef41Sopenharmony_ci      return ReduceJSCreate(node);
611cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateArguments:
621cb0ef41Sopenharmony_ci      return ReduceJSCreateArguments(node);
631cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateArray:
641cb0ef41Sopenharmony_ci      return ReduceJSCreateArray(node);
651cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateArrayIterator:
661cb0ef41Sopenharmony_ci      return ReduceJSCreateArrayIterator(node);
671cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateAsyncFunctionObject:
681cb0ef41Sopenharmony_ci      return ReduceJSCreateAsyncFunctionObject(node);
691cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateBoundFunction:
701cb0ef41Sopenharmony_ci      return ReduceJSCreateBoundFunction(node);
711cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateClosure:
721cb0ef41Sopenharmony_ci      return ReduceJSCreateClosure(node);
731cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateCollectionIterator:
741cb0ef41Sopenharmony_ci      return ReduceJSCreateCollectionIterator(node);
751cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateIterResultObject:
761cb0ef41Sopenharmony_ci      return ReduceJSCreateIterResultObject(node);
771cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateStringIterator:
781cb0ef41Sopenharmony_ci      return ReduceJSCreateStringIterator(node);
791cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateKeyValueArray:
801cb0ef41Sopenharmony_ci      return ReduceJSCreateKeyValueArray(node);
811cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreatePromise:
821cb0ef41Sopenharmony_ci      return ReduceJSCreatePromise(node);
831cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateLiteralArray:
841cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateLiteralObject:
851cb0ef41Sopenharmony_ci      return ReduceJSCreateLiteralArrayOrObject(node);
861cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateLiteralRegExp:
871cb0ef41Sopenharmony_ci      return ReduceJSCreateLiteralRegExp(node);
881cb0ef41Sopenharmony_ci    case IrOpcode::kJSGetTemplateObject:
891cb0ef41Sopenharmony_ci      return ReduceJSGetTemplateObject(node);
901cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateEmptyLiteralArray:
911cb0ef41Sopenharmony_ci      return ReduceJSCreateEmptyLiteralArray(node);
921cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateEmptyLiteralObject:
931cb0ef41Sopenharmony_ci      return ReduceJSCreateEmptyLiteralObject(node);
941cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateFunctionContext:
951cb0ef41Sopenharmony_ci      return ReduceJSCreateFunctionContext(node);
961cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateWithContext:
971cb0ef41Sopenharmony_ci      return ReduceJSCreateWithContext(node);
981cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateCatchContext:
991cb0ef41Sopenharmony_ci      return ReduceJSCreateCatchContext(node);
1001cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateBlockContext:
1011cb0ef41Sopenharmony_ci      return ReduceJSCreateBlockContext(node);
1021cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateGeneratorObject:
1031cb0ef41Sopenharmony_ci      return ReduceJSCreateGeneratorObject(node);
1041cb0ef41Sopenharmony_ci    case IrOpcode::kJSCreateObject:
1051cb0ef41Sopenharmony_ci      return ReduceJSCreateObject(node);
1061cb0ef41Sopenharmony_ci    default:
1071cb0ef41Sopenharmony_ci      break;
1081cb0ef41Sopenharmony_ci  }
1091cb0ef41Sopenharmony_ci  return NoChange();
1101cb0ef41Sopenharmony_ci}
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreate(Node* node) {
1131cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreate, node->opcode());
1141cb0ef41Sopenharmony_ci  Node* const new_target = NodeProperties::GetValueInput(node, 1);
1151cb0ef41Sopenharmony_ci  Node* const effect = NodeProperties::GetEffectInput(node);
1161cb0ef41Sopenharmony_ci  Node* const control = NodeProperties::GetControlInput(node);
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_ci  base::Optional<MapRef> initial_map =
1191cb0ef41Sopenharmony_ci      NodeProperties::GetJSCreateMap(broker(), node);
1201cb0ef41Sopenharmony_ci  if (!initial_map.has_value()) return NoChange();
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  JSFunctionRef original_constructor =
1231cb0ef41Sopenharmony_ci      HeapObjectMatcher(new_target).Ref(broker()).AsJSFunction();
1241cb0ef41Sopenharmony_ci  SlackTrackingPrediction slack_tracking_prediction =
1251cb0ef41Sopenharmony_ci      dependencies()->DependOnInitialMapInstanceSizePrediction(
1261cb0ef41Sopenharmony_ci          original_constructor);
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci  // Emit code to allocate the JSObject instance for the
1291cb0ef41Sopenharmony_ci  // {original_constructor}.
1301cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
1311cb0ef41Sopenharmony_ci  a.Allocate(slack_tracking_prediction.instance_size());
1321cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(), *initial_map);
1331cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
1341cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
1351cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(),
1361cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
1371cb0ef41Sopenharmony_ci  for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
1381cb0ef41Sopenharmony_ci       ++i) {
1391cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSObjectInObjectProperty(*initial_map, i),
1401cb0ef41Sopenharmony_ci            jsgraph()->UndefinedConstant());
1411cb0ef41Sopenharmony_ci  }
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  RelaxControls(node);
1441cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
1451cb0ef41Sopenharmony_ci  return Changed(node);
1461cb0ef41Sopenharmony_ci}
1471cb0ef41Sopenharmony_ci
1481cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateArguments(Node* node) {
1491cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateArguments, node->opcode());
1501cb0ef41Sopenharmony_ci  CreateArgumentsType type = CreateArgumentsTypeOf(node->op());
1511cb0ef41Sopenharmony_ci  FrameState frame_state{NodeProperties::GetFrameStateInput(node)};
1521cb0ef41Sopenharmony_ci  Node* const control = graph()->start();
1531cb0ef41Sopenharmony_ci  FrameStateInfo state_info = frame_state.frame_state_info();
1541cb0ef41Sopenharmony_ci  SharedFunctionInfoRef shared =
1551cb0ef41Sopenharmony_ci      MakeRef(broker(), state_info.shared_info().ToHandleChecked());
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ci  // Use the ArgumentsAccessStub for materializing both mapped and unmapped
1581cb0ef41Sopenharmony_ci  // arguments object, but only for non-inlined (i.e. outermost) frames.
1591cb0ef41Sopenharmony_ci  if (frame_state.outer_frame_state()->opcode() != IrOpcode::kFrameState) {
1601cb0ef41Sopenharmony_ci    switch (type) {
1611cb0ef41Sopenharmony_ci      case CreateArgumentsType::kMappedArguments: {
1621cb0ef41Sopenharmony_ci        // TODO(turbofan): Duplicate parameters are not handled yet.
1631cb0ef41Sopenharmony_ci        if (shared.has_duplicate_parameters()) return NoChange();
1641cb0ef41Sopenharmony_ci        Node* const callee = NodeProperties::GetValueInput(node, 0);
1651cb0ef41Sopenharmony_ci        Node* const context = NodeProperties::GetContextInput(node);
1661cb0ef41Sopenharmony_ci        Node* effect = NodeProperties::GetEffectInput(node);
1671cb0ef41Sopenharmony_ci        Node* const arguments_length =
1681cb0ef41Sopenharmony_ci            graph()->NewNode(simplified()->ArgumentsLength());
1691cb0ef41Sopenharmony_ci        // Allocate the elements backing store.
1701cb0ef41Sopenharmony_ci        bool has_aliased_arguments = false;
1711cb0ef41Sopenharmony_ci        Node* const elements = effect = TryAllocateAliasedArguments(
1721cb0ef41Sopenharmony_ci            effect, control, context, arguments_length, shared,
1731cb0ef41Sopenharmony_ci            &has_aliased_arguments);
1741cb0ef41Sopenharmony_ci        if (elements == nullptr) return NoChange();
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ci        // Load the arguments object map.
1771cb0ef41Sopenharmony_ci        Node* const arguments_map = jsgraph()->Constant(
1781cb0ef41Sopenharmony_ci            has_aliased_arguments
1791cb0ef41Sopenharmony_ci                ? native_context().fast_aliased_arguments_map()
1801cb0ef41Sopenharmony_ci                : native_context().sloppy_arguments_map());
1811cb0ef41Sopenharmony_ci        // Actually allocate and initialize the arguments object.
1821cb0ef41Sopenharmony_ci        AllocationBuilder a(jsgraph(), effect, control);
1831cb0ef41Sopenharmony_ci        STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kTaggedSize);
1841cb0ef41Sopenharmony_ci        a.Allocate(JSSloppyArgumentsObject::kSize);
1851cb0ef41Sopenharmony_ci        a.Store(AccessBuilder::ForMap(), arguments_map);
1861cb0ef41Sopenharmony_ci        a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
1871cb0ef41Sopenharmony_ci                jsgraph()->EmptyFixedArrayConstant());
1881cb0ef41Sopenharmony_ci        a.Store(AccessBuilder::ForJSObjectElements(), elements);
1891cb0ef41Sopenharmony_ci        a.Store(AccessBuilder::ForArgumentsLength(), arguments_length);
1901cb0ef41Sopenharmony_ci        a.Store(AccessBuilder::ForArgumentsCallee(), callee);
1911cb0ef41Sopenharmony_ci        RelaxControls(node);
1921cb0ef41Sopenharmony_ci        a.FinishAndChange(node);
1931cb0ef41Sopenharmony_ci        return Changed(node);
1941cb0ef41Sopenharmony_ci      }
1951cb0ef41Sopenharmony_ci      case CreateArgumentsType::kUnmappedArguments: {
1961cb0ef41Sopenharmony_ci        Node* effect = NodeProperties::GetEffectInput(node);
1971cb0ef41Sopenharmony_ci        Node* const arguments_length =
1981cb0ef41Sopenharmony_ci            graph()->NewNode(simplified()->ArgumentsLength());
1991cb0ef41Sopenharmony_ci        // Allocate the elements backing store.
2001cb0ef41Sopenharmony_ci        Node* const elements = effect = graph()->NewNode(
2011cb0ef41Sopenharmony_ci            simplified()->NewArgumentsElements(
2021cb0ef41Sopenharmony_ci                CreateArgumentsType::kUnmappedArguments,
2031cb0ef41Sopenharmony_ci                shared.internal_formal_parameter_count_without_receiver()),
2041cb0ef41Sopenharmony_ci            arguments_length, effect);
2051cb0ef41Sopenharmony_ci        // Load the arguments object map.
2061cb0ef41Sopenharmony_ci        Node* const arguments_map =
2071cb0ef41Sopenharmony_ci            jsgraph()->Constant(native_context().strict_arguments_map());
2081cb0ef41Sopenharmony_ci        // Actually allocate and initialize the arguments object.
2091cb0ef41Sopenharmony_ci        AllocationBuilder a(jsgraph(), effect, control);
2101cb0ef41Sopenharmony_ci        STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kTaggedSize);
2111cb0ef41Sopenharmony_ci        a.Allocate(JSStrictArgumentsObject::kSize);
2121cb0ef41Sopenharmony_ci        a.Store(AccessBuilder::ForMap(), arguments_map);
2131cb0ef41Sopenharmony_ci        a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
2141cb0ef41Sopenharmony_ci                jsgraph()->EmptyFixedArrayConstant());
2151cb0ef41Sopenharmony_ci        a.Store(AccessBuilder::ForJSObjectElements(), elements);
2161cb0ef41Sopenharmony_ci        a.Store(AccessBuilder::ForArgumentsLength(), arguments_length);
2171cb0ef41Sopenharmony_ci        RelaxControls(node);
2181cb0ef41Sopenharmony_ci        a.FinishAndChange(node);
2191cb0ef41Sopenharmony_ci        return Changed(node);
2201cb0ef41Sopenharmony_ci      }
2211cb0ef41Sopenharmony_ci      case CreateArgumentsType::kRestParameter: {
2221cb0ef41Sopenharmony_ci        Node* effect = NodeProperties::GetEffectInput(node);
2231cb0ef41Sopenharmony_ci        Node* const arguments_length =
2241cb0ef41Sopenharmony_ci            graph()->NewNode(simplified()->ArgumentsLength());
2251cb0ef41Sopenharmony_ci        Node* const rest_length = graph()->NewNode(simplified()->RestLength(
2261cb0ef41Sopenharmony_ci            shared.internal_formal_parameter_count_without_receiver()));
2271cb0ef41Sopenharmony_ci        // Allocate the elements backing store.
2281cb0ef41Sopenharmony_ci        Node* const elements = effect = graph()->NewNode(
2291cb0ef41Sopenharmony_ci            simplified()->NewArgumentsElements(
2301cb0ef41Sopenharmony_ci                CreateArgumentsType::kRestParameter,
2311cb0ef41Sopenharmony_ci                shared.internal_formal_parameter_count_without_receiver()),
2321cb0ef41Sopenharmony_ci            arguments_length, effect);
2331cb0ef41Sopenharmony_ci        // Load the JSArray object map.
2341cb0ef41Sopenharmony_ci        Node* const jsarray_map = jsgraph()->Constant(
2351cb0ef41Sopenharmony_ci            native_context().js_array_packed_elements_map());
2361cb0ef41Sopenharmony_ci        // Actually allocate and initialize the jsarray.
2371cb0ef41Sopenharmony_ci        AllocationBuilder a(jsgraph(), effect, control);
2381cb0ef41Sopenharmony_ci        STATIC_ASSERT(JSArray::kHeaderSize == 4 * kTaggedSize);
2391cb0ef41Sopenharmony_ci        a.Allocate(JSArray::kHeaderSize);
2401cb0ef41Sopenharmony_ci        a.Store(AccessBuilder::ForMap(), jsarray_map);
2411cb0ef41Sopenharmony_ci        a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
2421cb0ef41Sopenharmony_ci                jsgraph()->EmptyFixedArrayConstant());
2431cb0ef41Sopenharmony_ci        a.Store(AccessBuilder::ForJSObjectElements(), elements);
2441cb0ef41Sopenharmony_ci        a.Store(AccessBuilder::ForJSArrayLength(PACKED_ELEMENTS), rest_length);
2451cb0ef41Sopenharmony_ci        RelaxControls(node);
2461cb0ef41Sopenharmony_ci        a.FinishAndChange(node);
2471cb0ef41Sopenharmony_ci        return Changed(node);
2481cb0ef41Sopenharmony_ci      }
2491cb0ef41Sopenharmony_ci    }
2501cb0ef41Sopenharmony_ci    UNREACHABLE();
2511cb0ef41Sopenharmony_ci  }
2521cb0ef41Sopenharmony_ci  // Use inline allocation for all mapped arguments objects within inlined
2531cb0ef41Sopenharmony_ci  // (i.e. non-outermost) frames, independent of the object size.
2541cb0ef41Sopenharmony_ci  DCHECK_EQ(frame_state.outer_frame_state()->opcode(), IrOpcode::kFrameState);
2551cb0ef41Sopenharmony_ci  switch (type) {
2561cb0ef41Sopenharmony_ci    case CreateArgumentsType::kMappedArguments: {
2571cb0ef41Sopenharmony_ci      Node* const callee = NodeProperties::GetValueInput(node, 0);
2581cb0ef41Sopenharmony_ci      Node* const context = NodeProperties::GetContextInput(node);
2591cb0ef41Sopenharmony_ci      Node* effect = NodeProperties::GetEffectInput(node);
2601cb0ef41Sopenharmony_ci      // TODO(turbofan): Duplicate parameters are not handled yet.
2611cb0ef41Sopenharmony_ci      if (shared.has_duplicate_parameters()) return NoChange();
2621cb0ef41Sopenharmony_ci      // Choose the correct frame state and frame state info depending on
2631cb0ef41Sopenharmony_ci      // whether there conceptually is an arguments adaptor frame in the call
2641cb0ef41Sopenharmony_ci      // chain.
2651cb0ef41Sopenharmony_ci      FrameState args_state = GetArgumentsFrameState(frame_state);
2661cb0ef41Sopenharmony_ci      if (args_state.parameters()->opcode() == IrOpcode::kDeadValue) {
2671cb0ef41Sopenharmony_ci        // This protects against an incompletely propagated DeadValue node.
2681cb0ef41Sopenharmony_ci        // If the FrameState has a DeadValue input, then this node will be
2691cb0ef41Sopenharmony_ci        // pruned anyway.
2701cb0ef41Sopenharmony_ci        return NoChange();
2711cb0ef41Sopenharmony_ci      }
2721cb0ef41Sopenharmony_ci      FrameStateInfo args_state_info = args_state.frame_state_info();
2731cb0ef41Sopenharmony_ci      int length = args_state_info.parameter_count() - 1;  // Minus receiver.
2741cb0ef41Sopenharmony_ci      // Prepare element backing store to be used by arguments object.
2751cb0ef41Sopenharmony_ci      bool has_aliased_arguments = false;
2761cb0ef41Sopenharmony_ci      Node* const elements = TryAllocateAliasedArguments(
2771cb0ef41Sopenharmony_ci          effect, control, args_state, context, shared, &has_aliased_arguments);
2781cb0ef41Sopenharmony_ci      if (elements == nullptr) return NoChange();
2791cb0ef41Sopenharmony_ci      effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
2801cb0ef41Sopenharmony_ci      // Load the arguments object map.
2811cb0ef41Sopenharmony_ci      Node* const arguments_map = jsgraph()->Constant(
2821cb0ef41Sopenharmony_ci          has_aliased_arguments ? native_context().fast_aliased_arguments_map()
2831cb0ef41Sopenharmony_ci                                : native_context().sloppy_arguments_map());
2841cb0ef41Sopenharmony_ci      // Actually allocate and initialize the arguments object.
2851cb0ef41Sopenharmony_ci      AllocationBuilder a(jsgraph(), effect, control);
2861cb0ef41Sopenharmony_ci      STATIC_ASSERT(JSSloppyArgumentsObject::kSize == 5 * kTaggedSize);
2871cb0ef41Sopenharmony_ci      a.Allocate(JSSloppyArgumentsObject::kSize);
2881cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForMap(), arguments_map);
2891cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
2901cb0ef41Sopenharmony_ci              jsgraph()->EmptyFixedArrayConstant());
2911cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForJSObjectElements(), elements);
2921cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length));
2931cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForArgumentsCallee(), callee);
2941cb0ef41Sopenharmony_ci      RelaxControls(node);
2951cb0ef41Sopenharmony_ci      a.FinishAndChange(node);
2961cb0ef41Sopenharmony_ci      return Changed(node);
2971cb0ef41Sopenharmony_ci    }
2981cb0ef41Sopenharmony_ci    case CreateArgumentsType::kUnmappedArguments: {
2991cb0ef41Sopenharmony_ci      // Use inline allocation for all unmapped arguments objects within inlined
3001cb0ef41Sopenharmony_ci      // (i.e. non-outermost) frames, independent of the object size.
3011cb0ef41Sopenharmony_ci      Node* effect = NodeProperties::GetEffectInput(node);
3021cb0ef41Sopenharmony_ci      // Choose the correct frame state and frame state info depending on
3031cb0ef41Sopenharmony_ci      // whether there conceptually is an arguments adaptor frame in the call
3041cb0ef41Sopenharmony_ci      // chain.
3051cb0ef41Sopenharmony_ci      FrameState args_state = GetArgumentsFrameState(frame_state);
3061cb0ef41Sopenharmony_ci      if (args_state.parameters()->opcode() == IrOpcode::kDeadValue) {
3071cb0ef41Sopenharmony_ci        // This protects against an incompletely propagated DeadValue node.
3081cb0ef41Sopenharmony_ci        // If the FrameState has a DeadValue input, then this node will be
3091cb0ef41Sopenharmony_ci        // pruned anyway.
3101cb0ef41Sopenharmony_ci        return NoChange();
3111cb0ef41Sopenharmony_ci      }
3121cb0ef41Sopenharmony_ci      FrameStateInfo args_state_info = args_state.frame_state_info();
3131cb0ef41Sopenharmony_ci      int length = args_state_info.parameter_count() - 1;  // Minus receiver.
3141cb0ef41Sopenharmony_ci      // Prepare element backing store to be used by arguments object.
3151cb0ef41Sopenharmony_ci      Node* const elements = TryAllocateArguments(effect, control, args_state);
3161cb0ef41Sopenharmony_ci      if (elements == nullptr) return NoChange();
3171cb0ef41Sopenharmony_ci      effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
3181cb0ef41Sopenharmony_ci      // Load the arguments object map.
3191cb0ef41Sopenharmony_ci      Node* const arguments_map =
3201cb0ef41Sopenharmony_ci          jsgraph()->Constant(native_context().strict_arguments_map());
3211cb0ef41Sopenharmony_ci      // Actually allocate and initialize the arguments object.
3221cb0ef41Sopenharmony_ci      AllocationBuilder a(jsgraph(), effect, control);
3231cb0ef41Sopenharmony_ci      STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kTaggedSize);
3241cb0ef41Sopenharmony_ci      a.Allocate(JSStrictArgumentsObject::kSize);
3251cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForMap(), arguments_map);
3261cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
3271cb0ef41Sopenharmony_ci              jsgraph()->EmptyFixedArrayConstant());
3281cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForJSObjectElements(), elements);
3291cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length));
3301cb0ef41Sopenharmony_ci      RelaxControls(node);
3311cb0ef41Sopenharmony_ci      a.FinishAndChange(node);
3321cb0ef41Sopenharmony_ci      return Changed(node);
3331cb0ef41Sopenharmony_ci    }
3341cb0ef41Sopenharmony_ci    case CreateArgumentsType::kRestParameter: {
3351cb0ef41Sopenharmony_ci      int start_index =
3361cb0ef41Sopenharmony_ci          shared.internal_formal_parameter_count_without_receiver();
3371cb0ef41Sopenharmony_ci      // Use inline allocation for all unmapped arguments objects within inlined
3381cb0ef41Sopenharmony_ci      // (i.e. non-outermost) frames, independent of the object size.
3391cb0ef41Sopenharmony_ci      Node* effect = NodeProperties::GetEffectInput(node);
3401cb0ef41Sopenharmony_ci      // Choose the correct frame state and frame state info depending on
3411cb0ef41Sopenharmony_ci      // whether there conceptually is an arguments adaptor frame in the call
3421cb0ef41Sopenharmony_ci      // chain.
3431cb0ef41Sopenharmony_ci      FrameState args_state = GetArgumentsFrameState(frame_state);
3441cb0ef41Sopenharmony_ci      if (args_state.parameters()->opcode() == IrOpcode::kDeadValue) {
3451cb0ef41Sopenharmony_ci        // This protects against an incompletely propagated DeadValue node.
3461cb0ef41Sopenharmony_ci        // If the FrameState has a DeadValue input, then this node will be
3471cb0ef41Sopenharmony_ci        // pruned anyway.
3481cb0ef41Sopenharmony_ci        return NoChange();
3491cb0ef41Sopenharmony_ci      }
3501cb0ef41Sopenharmony_ci      FrameStateInfo args_state_info = args_state.frame_state_info();
3511cb0ef41Sopenharmony_ci      // Prepare element backing store to be used by the rest array.
3521cb0ef41Sopenharmony_ci      Node* const elements =
3531cb0ef41Sopenharmony_ci          TryAllocateRestArguments(effect, control, args_state, start_index);
3541cb0ef41Sopenharmony_ci      if (elements == nullptr) return NoChange();
3551cb0ef41Sopenharmony_ci      effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
3561cb0ef41Sopenharmony_ci      // Load the JSArray object map.
3571cb0ef41Sopenharmony_ci      Node* const jsarray_map =
3581cb0ef41Sopenharmony_ci          jsgraph()->Constant(native_context().js_array_packed_elements_map());
3591cb0ef41Sopenharmony_ci      // Actually allocate and initialize the jsarray.
3601cb0ef41Sopenharmony_ci      AllocationBuilder a(jsgraph(), effect, control);
3611cb0ef41Sopenharmony_ci
3621cb0ef41Sopenharmony_ci      // -1 to minus receiver
3631cb0ef41Sopenharmony_ci      int argument_count = args_state_info.parameter_count() - 1;
3641cb0ef41Sopenharmony_ci      int length = std::max(0, argument_count - start_index);
3651cb0ef41Sopenharmony_ci      STATIC_ASSERT(JSArray::kHeaderSize == 4 * kTaggedSize);
3661cb0ef41Sopenharmony_ci      a.Allocate(JSArray::kHeaderSize);
3671cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForMap(), jsarray_map);
3681cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
3691cb0ef41Sopenharmony_ci              jsgraph()->EmptyFixedArrayConstant());
3701cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForJSObjectElements(), elements);
3711cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForJSArrayLength(PACKED_ELEMENTS),
3721cb0ef41Sopenharmony_ci              jsgraph()->Constant(length));
3731cb0ef41Sopenharmony_ci      RelaxControls(node);
3741cb0ef41Sopenharmony_ci      a.FinishAndChange(node);
3751cb0ef41Sopenharmony_ci      return Changed(node);
3761cb0ef41Sopenharmony_ci    }
3771cb0ef41Sopenharmony_ci  }
3781cb0ef41Sopenharmony_ci  UNREACHABLE();
3791cb0ef41Sopenharmony_ci}
3801cb0ef41Sopenharmony_ci
3811cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
3821cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateGeneratorObject, node->opcode());
3831cb0ef41Sopenharmony_ci  Node* const closure = NodeProperties::GetValueInput(node, 0);
3841cb0ef41Sopenharmony_ci  Node* const receiver = NodeProperties::GetValueInput(node, 1);
3851cb0ef41Sopenharmony_ci  Node* const context = NodeProperties::GetContextInput(node);
3861cb0ef41Sopenharmony_ci  Type const closure_type = NodeProperties::GetType(closure);
3871cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
3881cb0ef41Sopenharmony_ci  Node* const control = NodeProperties::GetControlInput(node);
3891cb0ef41Sopenharmony_ci  if (closure_type.IsHeapConstant()) {
3901cb0ef41Sopenharmony_ci    DCHECK(closure_type.AsHeapConstant()->Ref().IsJSFunction());
3911cb0ef41Sopenharmony_ci    JSFunctionRef js_function =
3921cb0ef41Sopenharmony_ci        closure_type.AsHeapConstant()->Ref().AsJSFunction();
3931cb0ef41Sopenharmony_ci    if (!js_function.has_initial_map(dependencies())) return NoChange();
3941cb0ef41Sopenharmony_ci
3951cb0ef41Sopenharmony_ci    SlackTrackingPrediction slack_tracking_prediction =
3961cb0ef41Sopenharmony_ci        dependencies()->DependOnInitialMapInstanceSizePrediction(js_function);
3971cb0ef41Sopenharmony_ci
3981cb0ef41Sopenharmony_ci    MapRef initial_map = js_function.initial_map(dependencies());
3991cb0ef41Sopenharmony_ci    DCHECK(initial_map.instance_type() == JS_GENERATOR_OBJECT_TYPE ||
4001cb0ef41Sopenharmony_ci           initial_map.instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE);
4011cb0ef41Sopenharmony_ci
4021cb0ef41Sopenharmony_ci    // Allocate a register file.
4031cb0ef41Sopenharmony_ci    SharedFunctionInfoRef shared = js_function.shared();
4041cb0ef41Sopenharmony_ci    DCHECK(shared.HasBytecodeArray());
4051cb0ef41Sopenharmony_ci    int parameter_count_no_receiver =
4061cb0ef41Sopenharmony_ci        shared.internal_formal_parameter_count_without_receiver();
4071cb0ef41Sopenharmony_ci    int length = parameter_count_no_receiver +
4081cb0ef41Sopenharmony_ci                 shared.GetBytecodeArray().register_count();
4091cb0ef41Sopenharmony_ci    MapRef fixed_array_map = MakeRef(broker(), factory()->fixed_array_map());
4101cb0ef41Sopenharmony_ci    AllocationBuilder ab(jsgraph(), effect, control);
4111cb0ef41Sopenharmony_ci    if (!ab.CanAllocateArray(length, fixed_array_map)) {
4121cb0ef41Sopenharmony_ci      return NoChange();
4131cb0ef41Sopenharmony_ci    }
4141cb0ef41Sopenharmony_ci    ab.AllocateArray(length, fixed_array_map);
4151cb0ef41Sopenharmony_ci    for (int i = 0; i < length; ++i) {
4161cb0ef41Sopenharmony_ci      ab.Store(AccessBuilder::ForFixedArraySlot(i),
4171cb0ef41Sopenharmony_ci               jsgraph()->UndefinedConstant());
4181cb0ef41Sopenharmony_ci    }
4191cb0ef41Sopenharmony_ci    Node* parameters_and_registers = effect = ab.Finish();
4201cb0ef41Sopenharmony_ci
4211cb0ef41Sopenharmony_ci    // Emit code to allocate the JS[Async]GeneratorObject instance.
4221cb0ef41Sopenharmony_ci    AllocationBuilder a(jsgraph(), effect, control);
4231cb0ef41Sopenharmony_ci    a.Allocate(slack_tracking_prediction.instance_size());
4241cb0ef41Sopenharmony_ci    Node* undefined = jsgraph()->UndefinedConstant();
4251cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForMap(), initial_map);
4261cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
4271cb0ef41Sopenharmony_ci            jsgraph()->EmptyFixedArrayConstant());
4281cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSObjectElements(),
4291cb0ef41Sopenharmony_ci            jsgraph()->EmptyFixedArrayConstant());
4301cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSGeneratorObjectContext(), context);
4311cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSGeneratorObjectFunction(), closure);
4321cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSGeneratorObjectReceiver(), receiver);
4331cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSGeneratorObjectInputOrDebugPos(), undefined);
4341cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSGeneratorObjectResumeMode(),
4351cb0ef41Sopenharmony_ci            jsgraph()->Constant(JSGeneratorObject::kNext));
4361cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSGeneratorObjectContinuation(),
4371cb0ef41Sopenharmony_ci            jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting));
4381cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSGeneratorObjectParametersAndRegisters(),
4391cb0ef41Sopenharmony_ci            parameters_and_registers);
4401cb0ef41Sopenharmony_ci
4411cb0ef41Sopenharmony_ci    if (initial_map.instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE) {
4421cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForJSAsyncGeneratorObjectQueue(), undefined);
4431cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForJSAsyncGeneratorObjectIsAwaiting(),
4441cb0ef41Sopenharmony_ci              jsgraph()->ZeroConstant());
4451cb0ef41Sopenharmony_ci    }
4461cb0ef41Sopenharmony_ci
4471cb0ef41Sopenharmony_ci    // Handle in-object properties, too.
4481cb0ef41Sopenharmony_ci    for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
4491cb0ef41Sopenharmony_ci         ++i) {
4501cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
4511cb0ef41Sopenharmony_ci              undefined);
4521cb0ef41Sopenharmony_ci    }
4531cb0ef41Sopenharmony_ci    a.FinishAndChange(node);
4541cb0ef41Sopenharmony_ci    return Changed(node);
4551cb0ef41Sopenharmony_ci  }
4561cb0ef41Sopenharmony_ci  return NoChange();
4571cb0ef41Sopenharmony_ci}
4581cb0ef41Sopenharmony_ci
4591cb0ef41Sopenharmony_ci// Constructs an array with a variable {length} when no upper bound
4601cb0ef41Sopenharmony_ci// is known for the capacity.
4611cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceNewArray(
4621cb0ef41Sopenharmony_ci    Node* node, Node* length, MapRef initial_map, ElementsKind elements_kind,
4631cb0ef41Sopenharmony_ci    AllocationType allocation,
4641cb0ef41Sopenharmony_ci    const SlackTrackingPrediction& slack_tracking_prediction) {
4651cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
4661cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
4671cb0ef41Sopenharmony_ci  Node* control = NodeProperties::GetControlInput(node);
4681cb0ef41Sopenharmony_ci
4691cb0ef41Sopenharmony_ci  // Constructing an Array via new Array(N) where N is an unsigned
4701cb0ef41Sopenharmony_ci  // integer, always creates a holey backing store.
4711cb0ef41Sopenharmony_ci  base::Optional<MapRef> maybe_initial_map =
4721cb0ef41Sopenharmony_ci      initial_map.AsElementsKind(GetHoleyElementsKind(elements_kind));
4731cb0ef41Sopenharmony_ci  if (!maybe_initial_map.has_value()) return NoChange();
4741cb0ef41Sopenharmony_ci  initial_map = maybe_initial_map.value();
4751cb0ef41Sopenharmony_ci
4761cb0ef41Sopenharmony_ci  // Because CheckBounds performs implicit conversion from string to number, an
4771cb0ef41Sopenharmony_ci  // additional CheckNumber is required to behave correctly for calls with a
4781cb0ef41Sopenharmony_ci  // single string argument.
4791cb0ef41Sopenharmony_ci  length = effect = graph()->NewNode(
4801cb0ef41Sopenharmony_ci      simplified()->CheckNumber(FeedbackSource{}), length, effect, control);
4811cb0ef41Sopenharmony_ci
4821cb0ef41Sopenharmony_ci  // Check that the {limit} is an unsigned integer in the valid range.
4831cb0ef41Sopenharmony_ci  // This has to be kept in sync with src/runtime/runtime-array.cc,
4841cb0ef41Sopenharmony_ci  // where this limit is protected.
4851cb0ef41Sopenharmony_ci  length = effect = graph()->NewNode(
4861cb0ef41Sopenharmony_ci      simplified()->CheckBounds(FeedbackSource()), length,
4871cb0ef41Sopenharmony_ci      jsgraph()->Constant(JSArray::kInitialMaxFastElementArray), effect,
4881cb0ef41Sopenharmony_ci      control);
4891cb0ef41Sopenharmony_ci
4901cb0ef41Sopenharmony_ci  // Construct elements and properties for the resulting JSArray.
4911cb0ef41Sopenharmony_ci  Node* elements = effect =
4921cb0ef41Sopenharmony_ci      graph()->NewNode(IsDoubleElementsKind(initial_map.elements_kind())
4931cb0ef41Sopenharmony_ci                           ? simplified()->NewDoubleElements(allocation)
4941cb0ef41Sopenharmony_ci                           : simplified()->NewSmiOrObjectElements(allocation),
4951cb0ef41Sopenharmony_ci                       length, effect, control);
4961cb0ef41Sopenharmony_ci
4971cb0ef41Sopenharmony_ci  // Perform the allocation of the actual JSArray object.
4981cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
4991cb0ef41Sopenharmony_ci  a.Allocate(slack_tracking_prediction.instance_size(), allocation);
5001cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(), initial_map);
5011cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
5021cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
5031cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(), elements);
5041cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSArrayLength(initial_map.elements_kind()), length);
5051cb0ef41Sopenharmony_ci  for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
5061cb0ef41Sopenharmony_ci       ++i) {
5071cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
5081cb0ef41Sopenharmony_ci            jsgraph()->UndefinedConstant());
5091cb0ef41Sopenharmony_ci  }
5101cb0ef41Sopenharmony_ci  RelaxControls(node);
5111cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
5121cb0ef41Sopenharmony_ci  return Changed(node);
5131cb0ef41Sopenharmony_ci}
5141cb0ef41Sopenharmony_ci
5151cb0ef41Sopenharmony_ci// Constructs an array with a variable {length} when an actual
5161cb0ef41Sopenharmony_ci// upper bound is known for the {capacity}.
5171cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceNewArray(
5181cb0ef41Sopenharmony_ci    Node* node, Node* length, int capacity, MapRef initial_map,
5191cb0ef41Sopenharmony_ci    ElementsKind elements_kind, AllocationType allocation,
5201cb0ef41Sopenharmony_ci    const SlackTrackingPrediction& slack_tracking_prediction) {
5211cb0ef41Sopenharmony_ci  DCHECK(node->opcode() == IrOpcode::kJSCreateArray ||
5221cb0ef41Sopenharmony_ci         node->opcode() == IrOpcode::kJSCreateEmptyLiteralArray);
5231cb0ef41Sopenharmony_ci  DCHECK(NodeProperties::GetType(length).Is(Type::Number()));
5241cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
5251cb0ef41Sopenharmony_ci  Node* control = NodeProperties::GetControlInput(node);
5261cb0ef41Sopenharmony_ci
5271cb0ef41Sopenharmony_ci  // Determine the appropriate elements kind.
5281cb0ef41Sopenharmony_ci  if (NodeProperties::GetType(length).Max() > 0.0) {
5291cb0ef41Sopenharmony_ci    elements_kind = GetHoleyElementsKind(elements_kind);
5301cb0ef41Sopenharmony_ci  }
5311cb0ef41Sopenharmony_ci
5321cb0ef41Sopenharmony_ci  base::Optional<MapRef> maybe_initial_map =
5331cb0ef41Sopenharmony_ci      initial_map.AsElementsKind(elements_kind);
5341cb0ef41Sopenharmony_ci  if (!maybe_initial_map.has_value()) return NoChange();
5351cb0ef41Sopenharmony_ci  initial_map = maybe_initial_map.value();
5361cb0ef41Sopenharmony_ci
5371cb0ef41Sopenharmony_ci  DCHECK(IsFastElementsKind(elements_kind));
5381cb0ef41Sopenharmony_ci
5391cb0ef41Sopenharmony_ci  // Setup elements and properties.
5401cb0ef41Sopenharmony_ci  Node* elements;
5411cb0ef41Sopenharmony_ci  if (capacity == 0) {
5421cb0ef41Sopenharmony_ci    elements = jsgraph()->EmptyFixedArrayConstant();
5431cb0ef41Sopenharmony_ci  } else {
5441cb0ef41Sopenharmony_ci    elements = effect =
5451cb0ef41Sopenharmony_ci        AllocateElements(effect, control, elements_kind, capacity, allocation);
5461cb0ef41Sopenharmony_ci  }
5471cb0ef41Sopenharmony_ci
5481cb0ef41Sopenharmony_ci  // Perform the allocation of the actual JSArray object.
5491cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
5501cb0ef41Sopenharmony_ci  a.Allocate(slack_tracking_prediction.instance_size(), allocation);
5511cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(), initial_map);
5521cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
5531cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
5541cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(), elements);
5551cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
5561cb0ef41Sopenharmony_ci  for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
5571cb0ef41Sopenharmony_ci       ++i) {
5581cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
5591cb0ef41Sopenharmony_ci            jsgraph()->UndefinedConstant());
5601cb0ef41Sopenharmony_ci  }
5611cb0ef41Sopenharmony_ci  RelaxControls(node);
5621cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
5631cb0ef41Sopenharmony_ci  return Changed(node);
5641cb0ef41Sopenharmony_ci}
5651cb0ef41Sopenharmony_ci
5661cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceNewArray(
5671cb0ef41Sopenharmony_ci    Node* node, std::vector<Node*> values, MapRef initial_map,
5681cb0ef41Sopenharmony_ci    ElementsKind elements_kind, AllocationType allocation,
5691cb0ef41Sopenharmony_ci    const SlackTrackingPrediction& slack_tracking_prediction) {
5701cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
5711cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
5721cb0ef41Sopenharmony_ci  Node* control = NodeProperties::GetControlInput(node);
5731cb0ef41Sopenharmony_ci
5741cb0ef41Sopenharmony_ci  // Determine the appropriate elements kind.
5751cb0ef41Sopenharmony_ci  DCHECK(IsFastElementsKind(elements_kind));
5761cb0ef41Sopenharmony_ci
5771cb0ef41Sopenharmony_ci  base::Optional<MapRef> maybe_initial_map =
5781cb0ef41Sopenharmony_ci      initial_map.AsElementsKind(elements_kind);
5791cb0ef41Sopenharmony_ci  if (!maybe_initial_map.has_value()) return NoChange();
5801cb0ef41Sopenharmony_ci  initial_map = maybe_initial_map.value();
5811cb0ef41Sopenharmony_ci
5821cb0ef41Sopenharmony_ci  // Check {values} based on the {elements_kind}. These checks are guarded
5831cb0ef41Sopenharmony_ci  // by the {elements_kind} feedback on the {site}, so it's safe to just
5841cb0ef41Sopenharmony_ci  // deoptimize in this case.
5851cb0ef41Sopenharmony_ci  if (IsSmiElementsKind(elements_kind)) {
5861cb0ef41Sopenharmony_ci    for (auto& value : values) {
5871cb0ef41Sopenharmony_ci      if (!NodeProperties::GetType(value).Is(Type::SignedSmall())) {
5881cb0ef41Sopenharmony_ci        value = effect = graph()->NewNode(
5891cb0ef41Sopenharmony_ci            simplified()->CheckSmi(FeedbackSource()), value, effect, control);
5901cb0ef41Sopenharmony_ci      }
5911cb0ef41Sopenharmony_ci    }
5921cb0ef41Sopenharmony_ci  } else if (IsDoubleElementsKind(elements_kind)) {
5931cb0ef41Sopenharmony_ci    for (auto& value : values) {
5941cb0ef41Sopenharmony_ci      if (!NodeProperties::GetType(value).Is(Type::Number())) {
5951cb0ef41Sopenharmony_ci        value = effect =
5961cb0ef41Sopenharmony_ci            graph()->NewNode(simplified()->CheckNumber(FeedbackSource()), value,
5971cb0ef41Sopenharmony_ci                             effect, control);
5981cb0ef41Sopenharmony_ci      }
5991cb0ef41Sopenharmony_ci      // Make sure we do not store signaling NaNs into double arrays.
6001cb0ef41Sopenharmony_ci      value = graph()->NewNode(simplified()->NumberSilenceNaN(), value);
6011cb0ef41Sopenharmony_ci    }
6021cb0ef41Sopenharmony_ci  }
6031cb0ef41Sopenharmony_ci
6041cb0ef41Sopenharmony_ci  // Setup elements, properties and length.
6051cb0ef41Sopenharmony_ci  Node* elements = effect =
6061cb0ef41Sopenharmony_ci      AllocateElements(effect, control, elements_kind, values, allocation);
6071cb0ef41Sopenharmony_ci  Node* length = jsgraph()->Constant(static_cast<int>(values.size()));
6081cb0ef41Sopenharmony_ci
6091cb0ef41Sopenharmony_ci  // Perform the allocation of the actual JSArray object.
6101cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
6111cb0ef41Sopenharmony_ci  a.Allocate(slack_tracking_prediction.instance_size(), allocation);
6121cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(), initial_map);
6131cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
6141cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
6151cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(), elements);
6161cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
6171cb0ef41Sopenharmony_ci  for (int i = 0; i < slack_tracking_prediction.inobject_property_count();
6181cb0ef41Sopenharmony_ci       ++i) {
6191cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
6201cb0ef41Sopenharmony_ci            jsgraph()->UndefinedConstant());
6211cb0ef41Sopenharmony_ci  }
6221cb0ef41Sopenharmony_ci  RelaxControls(node);
6231cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
6241cb0ef41Sopenharmony_ci  return Changed(node);
6251cb0ef41Sopenharmony_ci}
6261cb0ef41Sopenharmony_ci
6271cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateArray(Node* node) {
6281cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
6291cb0ef41Sopenharmony_ci  CreateArrayParameters const& p = CreateArrayParametersOf(node->op());
6301cb0ef41Sopenharmony_ci  int const arity = static_cast<int>(p.arity());
6311cb0ef41Sopenharmony_ci  base::Optional<AllocationSiteRef> site_ref = p.site(broker());
6321cb0ef41Sopenharmony_ci  AllocationType allocation = AllocationType::kYoung;
6331cb0ef41Sopenharmony_ci
6341cb0ef41Sopenharmony_ci  base::Optional<MapRef> initial_map =
6351cb0ef41Sopenharmony_ci      NodeProperties::GetJSCreateMap(broker(), node);
6361cb0ef41Sopenharmony_ci  if (!initial_map.has_value()) return NoChange();
6371cb0ef41Sopenharmony_ci
6381cb0ef41Sopenharmony_ci  Node* new_target = NodeProperties::GetValueInput(node, 1);
6391cb0ef41Sopenharmony_ci  JSFunctionRef original_constructor =
6401cb0ef41Sopenharmony_ci      HeapObjectMatcher(new_target).Ref(broker()).AsJSFunction();
6411cb0ef41Sopenharmony_ci  SlackTrackingPrediction slack_tracking_prediction =
6421cb0ef41Sopenharmony_ci      dependencies()->DependOnInitialMapInstanceSizePrediction(
6431cb0ef41Sopenharmony_ci          original_constructor);
6441cb0ef41Sopenharmony_ci
6451cb0ef41Sopenharmony_ci  // Tells whether we are protected by either the {site} or a
6461cb0ef41Sopenharmony_ci  // protector cell to do certain speculative optimizations.
6471cb0ef41Sopenharmony_ci  bool can_inline_call = false;
6481cb0ef41Sopenharmony_ci
6491cb0ef41Sopenharmony_ci  // Check if we have a feedback {site} on the {node}.
6501cb0ef41Sopenharmony_ci  ElementsKind elements_kind = initial_map->elements_kind();
6511cb0ef41Sopenharmony_ci  if (site_ref) {
6521cb0ef41Sopenharmony_ci    elements_kind = site_ref->GetElementsKind();
6531cb0ef41Sopenharmony_ci    can_inline_call = site_ref->CanInlineCall();
6541cb0ef41Sopenharmony_ci    allocation = dependencies()->DependOnPretenureMode(*site_ref);
6551cb0ef41Sopenharmony_ci    dependencies()->DependOnElementsKind(*site_ref);
6561cb0ef41Sopenharmony_ci  } else {
6571cb0ef41Sopenharmony_ci    PropertyCellRef array_constructor_protector =
6581cb0ef41Sopenharmony_ci        MakeRef(broker(), factory()->array_constructor_protector());
6591cb0ef41Sopenharmony_ci    array_constructor_protector.CacheAsProtector();
6601cb0ef41Sopenharmony_ci    can_inline_call = array_constructor_protector.value().AsSmi() ==
6611cb0ef41Sopenharmony_ci                      Protectors::kProtectorValid;
6621cb0ef41Sopenharmony_ci  }
6631cb0ef41Sopenharmony_ci
6641cb0ef41Sopenharmony_ci  if (arity == 0) {
6651cb0ef41Sopenharmony_ci    Node* length = jsgraph()->ZeroConstant();
6661cb0ef41Sopenharmony_ci    int capacity = JSArray::kPreallocatedArrayElements;
6671cb0ef41Sopenharmony_ci    return ReduceNewArray(node, length, capacity, *initial_map, elements_kind,
6681cb0ef41Sopenharmony_ci                          allocation, slack_tracking_prediction);
6691cb0ef41Sopenharmony_ci  } else if (arity == 1) {
6701cb0ef41Sopenharmony_ci    Node* length = NodeProperties::GetValueInput(node, 2);
6711cb0ef41Sopenharmony_ci    Type length_type = NodeProperties::GetType(length);
6721cb0ef41Sopenharmony_ci    if (!length_type.Maybe(Type::Number())) {
6731cb0ef41Sopenharmony_ci      // Handle the single argument case, where we know that the value
6741cb0ef41Sopenharmony_ci      // cannot be a valid Array length.
6751cb0ef41Sopenharmony_ci      elements_kind = GetMoreGeneralElementsKind(
6761cb0ef41Sopenharmony_ci          elements_kind, IsHoleyElementsKind(elements_kind) ? HOLEY_ELEMENTS
6771cb0ef41Sopenharmony_ci                                                            : PACKED_ELEMENTS);
6781cb0ef41Sopenharmony_ci      return ReduceNewArray(node, std::vector<Node*>{length}, *initial_map,
6791cb0ef41Sopenharmony_ci                            elements_kind, allocation,
6801cb0ef41Sopenharmony_ci                            slack_tracking_prediction);
6811cb0ef41Sopenharmony_ci    }
6821cb0ef41Sopenharmony_ci    if (length_type.Is(Type::SignedSmall()) && length_type.Min() >= 0 &&
6831cb0ef41Sopenharmony_ci        length_type.Max() <= kElementLoopUnrollLimit &&
6841cb0ef41Sopenharmony_ci        length_type.Min() == length_type.Max()) {
6851cb0ef41Sopenharmony_ci      int capacity = static_cast<int>(length_type.Max());
6861cb0ef41Sopenharmony_ci      // Replace length with a constant in order to protect against a potential
6871cb0ef41Sopenharmony_ci      // typer bug leading to length > capacity.
6881cb0ef41Sopenharmony_ci      length = jsgraph()->Constant(capacity);
6891cb0ef41Sopenharmony_ci      return ReduceNewArray(node, length, capacity, *initial_map, elements_kind,
6901cb0ef41Sopenharmony_ci                            allocation, slack_tracking_prediction);
6911cb0ef41Sopenharmony_ci    }
6921cb0ef41Sopenharmony_ci    if (length_type.Maybe(Type::UnsignedSmall()) && can_inline_call) {
6931cb0ef41Sopenharmony_ci      return ReduceNewArray(node, length, *initial_map, elements_kind,
6941cb0ef41Sopenharmony_ci                            allocation, slack_tracking_prediction);
6951cb0ef41Sopenharmony_ci    }
6961cb0ef41Sopenharmony_ci  } else if (arity <= JSArray::kInitialMaxFastElementArray) {
6971cb0ef41Sopenharmony_ci    // Gather the values to store into the newly created array.
6981cb0ef41Sopenharmony_ci    bool values_all_smis = true, values_all_numbers = true,
6991cb0ef41Sopenharmony_ci         values_any_nonnumber = false;
7001cb0ef41Sopenharmony_ci    std::vector<Node*> values;
7011cb0ef41Sopenharmony_ci    values.reserve(p.arity());
7021cb0ef41Sopenharmony_ci    for (int i = 0; i < arity; ++i) {
7031cb0ef41Sopenharmony_ci      Node* value = NodeProperties::GetValueInput(node, 2 + i);
7041cb0ef41Sopenharmony_ci      Type value_type = NodeProperties::GetType(value);
7051cb0ef41Sopenharmony_ci      if (!value_type.Is(Type::SignedSmall())) {
7061cb0ef41Sopenharmony_ci        values_all_smis = false;
7071cb0ef41Sopenharmony_ci      }
7081cb0ef41Sopenharmony_ci      if (!value_type.Is(Type::Number())) {
7091cb0ef41Sopenharmony_ci        values_all_numbers = false;
7101cb0ef41Sopenharmony_ci      }
7111cb0ef41Sopenharmony_ci      if (!value_type.Maybe(Type::Number())) {
7121cb0ef41Sopenharmony_ci        values_any_nonnumber = true;
7131cb0ef41Sopenharmony_ci      }
7141cb0ef41Sopenharmony_ci      values.push_back(value);
7151cb0ef41Sopenharmony_ci    }
7161cb0ef41Sopenharmony_ci
7171cb0ef41Sopenharmony_ci    // Try to figure out the ideal elements kind statically.
7181cb0ef41Sopenharmony_ci    if (values_all_smis) {
7191cb0ef41Sopenharmony_ci      // Smis can be stored with any elements kind.
7201cb0ef41Sopenharmony_ci    } else if (values_all_numbers) {
7211cb0ef41Sopenharmony_ci      elements_kind = GetMoreGeneralElementsKind(
7221cb0ef41Sopenharmony_ci          elements_kind, IsHoleyElementsKind(elements_kind)
7231cb0ef41Sopenharmony_ci                             ? HOLEY_DOUBLE_ELEMENTS
7241cb0ef41Sopenharmony_ci                             : PACKED_DOUBLE_ELEMENTS);
7251cb0ef41Sopenharmony_ci    } else if (values_any_nonnumber) {
7261cb0ef41Sopenharmony_ci      elements_kind = GetMoreGeneralElementsKind(
7271cb0ef41Sopenharmony_ci          elements_kind, IsHoleyElementsKind(elements_kind) ? HOLEY_ELEMENTS
7281cb0ef41Sopenharmony_ci                                                            : PACKED_ELEMENTS);
7291cb0ef41Sopenharmony_ci    } else if (!can_inline_call) {
7301cb0ef41Sopenharmony_ci      // We have some crazy combination of types for the {values} where
7311cb0ef41Sopenharmony_ci      // there's no clear decision on the elements kind statically. And
7321cb0ef41Sopenharmony_ci      // we don't have a protection against deoptimization loops for the
7331cb0ef41Sopenharmony_ci      // checks that are introduced in the call to ReduceNewArray, so
7341cb0ef41Sopenharmony_ci      // we cannot inline this invocation of the Array constructor here.
7351cb0ef41Sopenharmony_ci      return NoChange();
7361cb0ef41Sopenharmony_ci    }
7371cb0ef41Sopenharmony_ci    return ReduceNewArray(node, values, *initial_map, elements_kind, allocation,
7381cb0ef41Sopenharmony_ci                          slack_tracking_prediction);
7391cb0ef41Sopenharmony_ci  }
7401cb0ef41Sopenharmony_ci  return NoChange();
7411cb0ef41Sopenharmony_ci}
7421cb0ef41Sopenharmony_ci
7431cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateArrayIterator(Node* node) {
7441cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateArrayIterator, node->opcode());
7451cb0ef41Sopenharmony_ci  CreateArrayIteratorParameters const& p =
7461cb0ef41Sopenharmony_ci      CreateArrayIteratorParametersOf(node->op());
7471cb0ef41Sopenharmony_ci  Node* iterated_object = NodeProperties::GetValueInput(node, 0);
7481cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
7491cb0ef41Sopenharmony_ci  Node* control = NodeProperties::GetControlInput(node);
7501cb0ef41Sopenharmony_ci
7511cb0ef41Sopenharmony_ci  // Create the JSArrayIterator result.
7521cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
7531cb0ef41Sopenharmony_ci  a.Allocate(JSArrayIterator::kHeaderSize, AllocationType::kYoung,
7541cb0ef41Sopenharmony_ci             Type::OtherObject());
7551cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(),
7561cb0ef41Sopenharmony_ci          native_context().initial_array_iterator_map());
7571cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
7581cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
7591cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(),
7601cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
7611cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSArrayIteratorIteratedObject(), iterated_object);
7621cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSArrayIteratorNextIndex(),
7631cb0ef41Sopenharmony_ci          jsgraph()->ZeroConstant());
7641cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSArrayIteratorKind(),
7651cb0ef41Sopenharmony_ci          jsgraph()->Constant(static_cast<int>(p.kind())));
7661cb0ef41Sopenharmony_ci  RelaxControls(node);
7671cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
7681cb0ef41Sopenharmony_ci  return Changed(node);
7691cb0ef41Sopenharmony_ci}
7701cb0ef41Sopenharmony_ci
7711cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateAsyncFunctionObject(Node* node) {
7721cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateAsyncFunctionObject, node->opcode());
7731cb0ef41Sopenharmony_ci  int const register_count = RegisterCountOf(node->op());
7741cb0ef41Sopenharmony_ci  Node* closure = NodeProperties::GetValueInput(node, 0);
7751cb0ef41Sopenharmony_ci  Node* receiver = NodeProperties::GetValueInput(node, 1);
7761cb0ef41Sopenharmony_ci  Node* promise = NodeProperties::GetValueInput(node, 2);
7771cb0ef41Sopenharmony_ci  Node* context = NodeProperties::GetContextInput(node);
7781cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
7791cb0ef41Sopenharmony_ci  Node* control = NodeProperties::GetControlInput(node);
7801cb0ef41Sopenharmony_ci
7811cb0ef41Sopenharmony_ci  // Create the register file.
7821cb0ef41Sopenharmony_ci  MapRef fixed_array_map = MakeRef(broker(), factory()->fixed_array_map());
7831cb0ef41Sopenharmony_ci  AllocationBuilder ab(jsgraph(), effect, control);
7841cb0ef41Sopenharmony_ci  CHECK(ab.CanAllocateArray(register_count, fixed_array_map));
7851cb0ef41Sopenharmony_ci  ab.AllocateArray(register_count, fixed_array_map);
7861cb0ef41Sopenharmony_ci  for (int i = 0; i < register_count; ++i) {
7871cb0ef41Sopenharmony_ci    ab.Store(AccessBuilder::ForFixedArraySlot(i),
7881cb0ef41Sopenharmony_ci             jsgraph()->UndefinedConstant());
7891cb0ef41Sopenharmony_ci  }
7901cb0ef41Sopenharmony_ci  Node* parameters_and_registers = effect = ab.Finish();
7911cb0ef41Sopenharmony_ci
7921cb0ef41Sopenharmony_ci  // Create the JSAsyncFunctionObject result.
7931cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
7941cb0ef41Sopenharmony_ci  a.Allocate(JSAsyncFunctionObject::kHeaderSize);
7951cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(),
7961cb0ef41Sopenharmony_ci          native_context().async_function_object_map());
7971cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
7981cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
7991cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(),
8001cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
8011cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSGeneratorObjectContext(), context);
8021cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSGeneratorObjectFunction(), closure);
8031cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSGeneratorObjectReceiver(), receiver);
8041cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSGeneratorObjectInputOrDebugPos(),
8051cb0ef41Sopenharmony_ci          jsgraph()->UndefinedConstant());
8061cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSGeneratorObjectResumeMode(),
8071cb0ef41Sopenharmony_ci          jsgraph()->Constant(JSGeneratorObject::kNext));
8081cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSGeneratorObjectContinuation(),
8091cb0ef41Sopenharmony_ci          jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting));
8101cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSGeneratorObjectParametersAndRegisters(),
8111cb0ef41Sopenharmony_ci          parameters_and_registers);
8121cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSAsyncFunctionObjectPromise(), promise);
8131cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
8141cb0ef41Sopenharmony_ci  return Changed(node);
8151cb0ef41Sopenharmony_ci}
8161cb0ef41Sopenharmony_ci
8171cb0ef41Sopenharmony_cinamespace {
8181cb0ef41Sopenharmony_ci
8191cb0ef41Sopenharmony_ciMapRef MapForCollectionIterationKind(const NativeContextRef& native_context,
8201cb0ef41Sopenharmony_ci                                     CollectionKind collection_kind,
8211cb0ef41Sopenharmony_ci                                     IterationKind iteration_kind) {
8221cb0ef41Sopenharmony_ci  switch (collection_kind) {
8231cb0ef41Sopenharmony_ci    case CollectionKind::kSet:
8241cb0ef41Sopenharmony_ci      switch (iteration_kind) {
8251cb0ef41Sopenharmony_ci        case IterationKind::kKeys:
8261cb0ef41Sopenharmony_ci          UNREACHABLE();
8271cb0ef41Sopenharmony_ci        case IterationKind::kValues:
8281cb0ef41Sopenharmony_ci          return native_context.set_value_iterator_map();
8291cb0ef41Sopenharmony_ci        case IterationKind::kEntries:
8301cb0ef41Sopenharmony_ci          return native_context.set_key_value_iterator_map();
8311cb0ef41Sopenharmony_ci      }
8321cb0ef41Sopenharmony_ci      break;
8331cb0ef41Sopenharmony_ci    case CollectionKind::kMap:
8341cb0ef41Sopenharmony_ci      switch (iteration_kind) {
8351cb0ef41Sopenharmony_ci        case IterationKind::kKeys:
8361cb0ef41Sopenharmony_ci          return native_context.map_key_iterator_map();
8371cb0ef41Sopenharmony_ci        case IterationKind::kValues:
8381cb0ef41Sopenharmony_ci          return native_context.map_value_iterator_map();
8391cb0ef41Sopenharmony_ci        case IterationKind::kEntries:
8401cb0ef41Sopenharmony_ci          return native_context.map_key_value_iterator_map();
8411cb0ef41Sopenharmony_ci      }
8421cb0ef41Sopenharmony_ci      break;
8431cb0ef41Sopenharmony_ci  }
8441cb0ef41Sopenharmony_ci  UNREACHABLE();
8451cb0ef41Sopenharmony_ci}
8461cb0ef41Sopenharmony_ci
8471cb0ef41Sopenharmony_ci}  // namespace
8481cb0ef41Sopenharmony_ci
8491cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateCollectionIterator(Node* node) {
8501cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateCollectionIterator, node->opcode());
8511cb0ef41Sopenharmony_ci  CreateCollectionIteratorParameters const& p =
8521cb0ef41Sopenharmony_ci      CreateCollectionIteratorParametersOf(node->op());
8531cb0ef41Sopenharmony_ci  Node* iterated_object = NodeProperties::GetValueInput(node, 0);
8541cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
8551cb0ef41Sopenharmony_ci  Node* control = NodeProperties::GetControlInput(node);
8561cb0ef41Sopenharmony_ci
8571cb0ef41Sopenharmony_ci  // Load the OrderedHashTable from the {receiver}.
8581cb0ef41Sopenharmony_ci  Node* table = effect = graph()->NewNode(
8591cb0ef41Sopenharmony_ci      simplified()->LoadField(AccessBuilder::ForJSCollectionTable()),
8601cb0ef41Sopenharmony_ci      iterated_object, effect, control);
8611cb0ef41Sopenharmony_ci
8621cb0ef41Sopenharmony_ci  // Create the JSCollectionIterator result.
8631cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
8641cb0ef41Sopenharmony_ci  a.Allocate(JSCollectionIterator::kHeaderSize, AllocationType::kYoung,
8651cb0ef41Sopenharmony_ci             Type::OtherObject());
8661cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(),
8671cb0ef41Sopenharmony_ci          MapForCollectionIterationKind(native_context(), p.collection_kind(),
8681cb0ef41Sopenharmony_ci                                        p.iteration_kind()));
8691cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
8701cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
8711cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(),
8721cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
8731cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSCollectionIteratorTable(), table);
8741cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSCollectionIteratorIndex(),
8751cb0ef41Sopenharmony_ci          jsgraph()->ZeroConstant());
8761cb0ef41Sopenharmony_ci  RelaxControls(node);
8771cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
8781cb0ef41Sopenharmony_ci  return Changed(node);
8791cb0ef41Sopenharmony_ci}
8801cb0ef41Sopenharmony_ci
8811cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateBoundFunction(Node* node) {
8821cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateBoundFunction, node->opcode());
8831cb0ef41Sopenharmony_ci  CreateBoundFunctionParameters const& p =
8841cb0ef41Sopenharmony_ci      CreateBoundFunctionParametersOf(node->op());
8851cb0ef41Sopenharmony_ci  int const arity = static_cast<int>(p.arity());
8861cb0ef41Sopenharmony_ci  MapRef const map = p.map(broker());
8871cb0ef41Sopenharmony_ci  Node* bound_target_function = NodeProperties::GetValueInput(node, 0);
8881cb0ef41Sopenharmony_ci  Node* bound_this = NodeProperties::GetValueInput(node, 1);
8891cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
8901cb0ef41Sopenharmony_ci  Node* control = NodeProperties::GetControlInput(node);
8911cb0ef41Sopenharmony_ci
8921cb0ef41Sopenharmony_ci  // Create the [[BoundArguments]] for the result.
8931cb0ef41Sopenharmony_ci  Node* bound_arguments = jsgraph()->EmptyFixedArrayConstant();
8941cb0ef41Sopenharmony_ci  if (arity > 0) {
8951cb0ef41Sopenharmony_ci    MapRef fixed_array_map = MakeRef(broker(), factory()->fixed_array_map());
8961cb0ef41Sopenharmony_ci    AllocationBuilder ab(jsgraph(), effect, control);
8971cb0ef41Sopenharmony_ci    CHECK(ab.CanAllocateArray(arity, fixed_array_map));
8981cb0ef41Sopenharmony_ci    ab.AllocateArray(arity, fixed_array_map);
8991cb0ef41Sopenharmony_ci    for (int i = 0; i < arity; ++i) {
9001cb0ef41Sopenharmony_ci      ab.Store(AccessBuilder::ForFixedArraySlot(i),
9011cb0ef41Sopenharmony_ci               NodeProperties::GetValueInput(node, 2 + i));
9021cb0ef41Sopenharmony_ci    }
9031cb0ef41Sopenharmony_ci    bound_arguments = effect = ab.Finish();
9041cb0ef41Sopenharmony_ci  }
9051cb0ef41Sopenharmony_ci
9061cb0ef41Sopenharmony_ci  // Create the JSBoundFunction result.
9071cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
9081cb0ef41Sopenharmony_ci  a.Allocate(JSBoundFunction::kHeaderSize, AllocationType::kYoung,
9091cb0ef41Sopenharmony_ci             Type::BoundFunction());
9101cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(), map);
9111cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
9121cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
9131cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(),
9141cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
9151cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSBoundFunctionBoundTargetFunction(),
9161cb0ef41Sopenharmony_ci          bound_target_function);
9171cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSBoundFunctionBoundThis(), bound_this);
9181cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSBoundFunctionBoundArguments(), bound_arguments);
9191cb0ef41Sopenharmony_ci  RelaxControls(node);
9201cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
9211cb0ef41Sopenharmony_ci  return Changed(node);
9221cb0ef41Sopenharmony_ci}
9231cb0ef41Sopenharmony_ci
9241cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
9251cb0ef41Sopenharmony_ci  JSCreateClosureNode n(node);
9261cb0ef41Sopenharmony_ci  CreateClosureParameters const& p = n.Parameters();
9271cb0ef41Sopenharmony_ci  SharedFunctionInfoRef shared = p.shared_info(broker());
9281cb0ef41Sopenharmony_ci  FeedbackCellRef feedback_cell = n.GetFeedbackCellRefChecked(broker());
9291cb0ef41Sopenharmony_ci  HeapObjectRef code = p.code(broker());
9301cb0ef41Sopenharmony_ci  Effect effect = n.effect();
9311cb0ef41Sopenharmony_ci  Control control = n.control();
9321cb0ef41Sopenharmony_ci  Node* context = n.context();
9331cb0ef41Sopenharmony_ci
9341cb0ef41Sopenharmony_ci  // Use inline allocation of closures only for instantiation sites that have
9351cb0ef41Sopenharmony_ci  // seen more than one instantiation, this simplifies the generated code and
9361cb0ef41Sopenharmony_ci  // also serves as a heuristic of which allocation sites benefit from it.
9371cb0ef41Sopenharmony_ci  if (!feedback_cell.map().equals(
9381cb0ef41Sopenharmony_ci          MakeRef(broker(), factory()->many_closures_cell_map()))) {
9391cb0ef41Sopenharmony_ci    return NoChange();
9401cb0ef41Sopenharmony_ci  }
9411cb0ef41Sopenharmony_ci
9421cb0ef41Sopenharmony_ci  // Don't inline anything for class constructors.
9431cb0ef41Sopenharmony_ci  if (IsClassConstructor(shared.kind())) return NoChange();
9441cb0ef41Sopenharmony_ci
9451cb0ef41Sopenharmony_ci  MapRef function_map =
9461cb0ef41Sopenharmony_ci      native_context().GetFunctionMapFromIndex(shared.function_map_index());
9471cb0ef41Sopenharmony_ci  DCHECK(!function_map.IsInobjectSlackTrackingInProgress());
9481cb0ef41Sopenharmony_ci  DCHECK(!function_map.is_dictionary_map());
9491cb0ef41Sopenharmony_ci
9501cb0ef41Sopenharmony_ci  // TODO(turbofan): We should use the pretenure flag from {p} here,
9511cb0ef41Sopenharmony_ci  // but currently the heuristic in the parser works against us, as
9521cb0ef41Sopenharmony_ci  // it marks closures like
9531cb0ef41Sopenharmony_ci  //
9541cb0ef41Sopenharmony_ci  //   args[l] = function(...) { ... }
9551cb0ef41Sopenharmony_ci  //
9561cb0ef41Sopenharmony_ci  // for old-space allocation, which doesn't always make sense. For
9571cb0ef41Sopenharmony_ci  // example in case of the bluebird-parallel benchmark, where this
9581cb0ef41Sopenharmony_ci  // is a core part of the *promisify* logic (see crbug.com/810132).
9591cb0ef41Sopenharmony_ci  AllocationType allocation = AllocationType::kYoung;
9601cb0ef41Sopenharmony_ci
9611cb0ef41Sopenharmony_ci  // Emit code to allocate the JSFunction instance.
9621cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kTaggedSize);
9631cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
9641cb0ef41Sopenharmony_ci  a.Allocate(function_map.instance_size(), allocation,
9651cb0ef41Sopenharmony_ci             Type::CallableFunction());
9661cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(), function_map);
9671cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
9681cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
9691cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(),
9701cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
9711cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSFunctionSharedFunctionInfo(), shared);
9721cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSFunctionContext(), context);
9731cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSFunctionFeedbackCell(), feedback_cell);
9741cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSFunctionCode(), code);
9751cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kTaggedSize);
9761cb0ef41Sopenharmony_ci  if (function_map.has_prototype_slot()) {
9771cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSFunctionPrototypeOrInitialMap(),
9781cb0ef41Sopenharmony_ci            jsgraph()->TheHoleConstant());
9791cb0ef41Sopenharmony_ci    STATIC_ASSERT(JSFunction::kSizeWithPrototype == 8 * kTaggedSize);
9801cb0ef41Sopenharmony_ci  }
9811cb0ef41Sopenharmony_ci  for (int i = 0; i < function_map.GetInObjectProperties(); i++) {
9821cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSObjectInObjectProperty(function_map, i),
9831cb0ef41Sopenharmony_ci            jsgraph()->UndefinedConstant());
9841cb0ef41Sopenharmony_ci  }
9851cb0ef41Sopenharmony_ci  RelaxControls(node);
9861cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
9871cb0ef41Sopenharmony_ci  return Changed(node);
9881cb0ef41Sopenharmony_ci}
9891cb0ef41Sopenharmony_ci
9901cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateIterResultObject(Node* node) {
9911cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateIterResultObject, node->opcode());
9921cb0ef41Sopenharmony_ci  Node* value = NodeProperties::GetValueInput(node, 0);
9931cb0ef41Sopenharmony_ci  Node* done = NodeProperties::GetValueInput(node, 1);
9941cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
9951cb0ef41Sopenharmony_ci
9961cb0ef41Sopenharmony_ci  Node* iterator_result_map =
9971cb0ef41Sopenharmony_ci      jsgraph()->Constant(native_context().iterator_result_map());
9981cb0ef41Sopenharmony_ci
9991cb0ef41Sopenharmony_ci  // Emit code to allocate the JSIteratorResult instance.
10001cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, graph()->start());
10011cb0ef41Sopenharmony_ci  a.Allocate(JSIteratorResult::kSize);
10021cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(), iterator_result_map);
10031cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
10041cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
10051cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(),
10061cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
10071cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSIteratorResultValue(), value);
10081cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSIteratorResultDone(), done);
10091cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSIteratorResult::kSize == 5 * kTaggedSize);
10101cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
10111cb0ef41Sopenharmony_ci  return Changed(node);
10121cb0ef41Sopenharmony_ci}
10131cb0ef41Sopenharmony_ci
10141cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateStringIterator(Node* node) {
10151cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateStringIterator, node->opcode());
10161cb0ef41Sopenharmony_ci  Node* string = NodeProperties::GetValueInput(node, 0);
10171cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
10181cb0ef41Sopenharmony_ci
10191cb0ef41Sopenharmony_ci  Node* map =
10201cb0ef41Sopenharmony_ci      jsgraph()->Constant(native_context().initial_string_iterator_map());
10211cb0ef41Sopenharmony_ci  // Allocate new iterator and attach the iterator to this string.
10221cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, graph()->start());
10231cb0ef41Sopenharmony_ci  a.Allocate(JSStringIterator::kHeaderSize, AllocationType::kYoung,
10241cb0ef41Sopenharmony_ci             Type::OtherObject());
10251cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(), map);
10261cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
10271cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
10281cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(),
10291cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
10301cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSStringIteratorString(), string);
10311cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSStringIteratorIndex(), jsgraph()->SmiConstant(0));
10321cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSIteratorResult::kSize == 5 * kTaggedSize);
10331cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
10341cb0ef41Sopenharmony_ci  return Changed(node);
10351cb0ef41Sopenharmony_ci}
10361cb0ef41Sopenharmony_ci
10371cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateKeyValueArray(Node* node) {
10381cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateKeyValueArray, node->opcode());
10391cb0ef41Sopenharmony_ci  Node* key = NodeProperties::GetValueInput(node, 0);
10401cb0ef41Sopenharmony_ci  Node* value = NodeProperties::GetValueInput(node, 1);
10411cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
10421cb0ef41Sopenharmony_ci
10431cb0ef41Sopenharmony_ci  Node* array_map =
10441cb0ef41Sopenharmony_ci      jsgraph()->Constant(native_context().js_array_packed_elements_map());
10451cb0ef41Sopenharmony_ci  Node* length = jsgraph()->Constant(2);
10461cb0ef41Sopenharmony_ci
10471cb0ef41Sopenharmony_ci  AllocationBuilder aa(jsgraph(), effect, graph()->start());
10481cb0ef41Sopenharmony_ci  aa.AllocateArray(2, MakeRef(broker(), factory()->fixed_array_map()));
10491cb0ef41Sopenharmony_ci  aa.Store(AccessBuilder::ForFixedArrayElement(PACKED_ELEMENTS),
10501cb0ef41Sopenharmony_ci           jsgraph()->ZeroConstant(), key);
10511cb0ef41Sopenharmony_ci  aa.Store(AccessBuilder::ForFixedArrayElement(PACKED_ELEMENTS),
10521cb0ef41Sopenharmony_ci           jsgraph()->OneConstant(), value);
10531cb0ef41Sopenharmony_ci  Node* elements = aa.Finish();
10541cb0ef41Sopenharmony_ci
10551cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), elements, graph()->start());
10561cb0ef41Sopenharmony_ci  a.Allocate(JSArray::kHeaderSize);
10571cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(), array_map);
10581cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
10591cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
10601cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(), elements);
10611cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSArrayLength(PACKED_ELEMENTS), length);
10621cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSArray::kHeaderSize == 4 * kTaggedSize);
10631cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
10641cb0ef41Sopenharmony_ci  return Changed(node);
10651cb0ef41Sopenharmony_ci}
10661cb0ef41Sopenharmony_ci
10671cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreatePromise(Node* node) {
10681cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreatePromise, node->opcode());
10691cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
10701cb0ef41Sopenharmony_ci
10711cb0ef41Sopenharmony_ci  MapRef promise_map =
10721cb0ef41Sopenharmony_ci      native_context().promise_function().initial_map(dependencies());
10731cb0ef41Sopenharmony_ci
10741cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, graph()->start());
10751cb0ef41Sopenharmony_ci  a.Allocate(promise_map.instance_size());
10761cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(), promise_map);
10771cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
10781cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
10791cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(),
10801cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
10811cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectOffset(JSPromise::kReactionsOrResultOffset),
10821cb0ef41Sopenharmony_ci          jsgraph()->ZeroConstant());
10831cb0ef41Sopenharmony_ci  STATIC_ASSERT(v8::Promise::kPending == 0);
10841cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectOffset(JSPromise::kFlagsOffset),
10851cb0ef41Sopenharmony_ci          jsgraph()->ZeroConstant());
10861cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSPromise::kHeaderSize == 5 * kTaggedSize);
10871cb0ef41Sopenharmony_ci  for (int offset = JSPromise::kHeaderSize;
10881cb0ef41Sopenharmony_ci       offset < JSPromise::kSizeWithEmbedderFields; offset += kTaggedSize) {
10891cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSObjectOffset(offset),
10901cb0ef41Sopenharmony_ci            jsgraph()->ZeroConstant());
10911cb0ef41Sopenharmony_ci  }
10921cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
10931cb0ef41Sopenharmony_ci  return Changed(node);
10941cb0ef41Sopenharmony_ci}
10951cb0ef41Sopenharmony_ci
10961cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateLiteralArrayOrObject(Node* node) {
10971cb0ef41Sopenharmony_ci  DCHECK(node->opcode() == IrOpcode::kJSCreateLiteralArray ||
10981cb0ef41Sopenharmony_ci         node->opcode() == IrOpcode::kJSCreateLiteralObject);
10991cb0ef41Sopenharmony_ci  JSCreateLiteralOpNode n(node);
11001cb0ef41Sopenharmony_ci  CreateLiteralParameters const& p = n.Parameters();
11011cb0ef41Sopenharmony_ci  Effect effect = n.effect();
11021cb0ef41Sopenharmony_ci  Control control = n.control();
11031cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback =
11041cb0ef41Sopenharmony_ci      broker()->GetFeedbackForArrayOrObjectLiteral(p.feedback());
11051cb0ef41Sopenharmony_ci  if (!feedback.IsInsufficient()) {
11061cb0ef41Sopenharmony_ci    AllocationSiteRef site = feedback.AsLiteral().value();
11071cb0ef41Sopenharmony_ci    if (!site.boilerplate().has_value()) return NoChange();
11081cb0ef41Sopenharmony_ci    AllocationType allocation = dependencies()->DependOnPretenureMode(site);
11091cb0ef41Sopenharmony_ci    int max_properties = kMaxFastLiteralProperties;
11101cb0ef41Sopenharmony_ci    base::Optional<Node*> maybe_value =
11111cb0ef41Sopenharmony_ci        TryAllocateFastLiteral(effect, control, *site.boilerplate(), allocation,
11121cb0ef41Sopenharmony_ci                               kMaxFastLiteralDepth, &max_properties);
11131cb0ef41Sopenharmony_ci    if (!maybe_value.has_value()) return NoChange();
11141cb0ef41Sopenharmony_ci    dependencies()->DependOnElementsKinds(site);
11151cb0ef41Sopenharmony_ci    Node* value = effect = maybe_value.value();
11161cb0ef41Sopenharmony_ci    ReplaceWithValue(node, value, effect, control);
11171cb0ef41Sopenharmony_ci    return Replace(value);
11181cb0ef41Sopenharmony_ci  }
11191cb0ef41Sopenharmony_ci  return NoChange();
11201cb0ef41Sopenharmony_ci}
11211cb0ef41Sopenharmony_ci
11221cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateEmptyLiteralArray(Node* node) {
11231cb0ef41Sopenharmony_ci  JSCreateEmptyLiteralArrayNode n(node);
11241cb0ef41Sopenharmony_ci  FeedbackParameter const& p = n.Parameters();
11251cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback =
11261cb0ef41Sopenharmony_ci      broker()->GetFeedbackForArrayOrObjectLiteral(p.feedback());
11271cb0ef41Sopenharmony_ci  if (!feedback.IsInsufficient()) {
11281cb0ef41Sopenharmony_ci    AllocationSiteRef site = feedback.AsLiteral().value();
11291cb0ef41Sopenharmony_ci    DCHECK(!site.PointsToLiteral());
11301cb0ef41Sopenharmony_ci    MapRef initial_map =
11311cb0ef41Sopenharmony_ci        native_context().GetInitialJSArrayMap(site.GetElementsKind());
11321cb0ef41Sopenharmony_ci    AllocationType const allocation =
11331cb0ef41Sopenharmony_ci        dependencies()->DependOnPretenureMode(site);
11341cb0ef41Sopenharmony_ci    dependencies()->DependOnElementsKind(site);
11351cb0ef41Sopenharmony_ci    Node* length = jsgraph()->ZeroConstant();
11361cb0ef41Sopenharmony_ci    DCHECK(!initial_map.IsInobjectSlackTrackingInProgress());
11371cb0ef41Sopenharmony_ci    SlackTrackingPrediction slack_tracking_prediction(
11381cb0ef41Sopenharmony_ci        initial_map, initial_map.instance_size());
11391cb0ef41Sopenharmony_ci    return ReduceNewArray(node, length, 0, initial_map,
11401cb0ef41Sopenharmony_ci                          initial_map.elements_kind(), allocation,
11411cb0ef41Sopenharmony_ci                          slack_tracking_prediction);
11421cb0ef41Sopenharmony_ci  }
11431cb0ef41Sopenharmony_ci  return NoChange();
11441cb0ef41Sopenharmony_ci}
11451cb0ef41Sopenharmony_ci
11461cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateEmptyLiteralObject(Node* node) {
11471cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateEmptyLiteralObject, node->opcode());
11481cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
11491cb0ef41Sopenharmony_ci  Node* control = NodeProperties::GetControlInput(node);
11501cb0ef41Sopenharmony_ci
11511cb0ef41Sopenharmony_ci  // Retrieve the initial map for the object.
11521cb0ef41Sopenharmony_ci  MapRef map = native_context().object_function().initial_map(dependencies());
11531cb0ef41Sopenharmony_ci  DCHECK(!map.is_dictionary_map());
11541cb0ef41Sopenharmony_ci  DCHECK(!map.IsInobjectSlackTrackingInProgress());
11551cb0ef41Sopenharmony_ci  Node* js_object_map = jsgraph()->Constant(map);
11561cb0ef41Sopenharmony_ci
11571cb0ef41Sopenharmony_ci  // Setup elements and properties.
11581cb0ef41Sopenharmony_ci  Node* elements = jsgraph()->EmptyFixedArrayConstant();
11591cb0ef41Sopenharmony_ci
11601cb0ef41Sopenharmony_ci  // Perform the allocation of the actual JSArray object.
11611cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
11621cb0ef41Sopenharmony_ci  a.Allocate(map.instance_size());
11631cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(), js_object_map);
11641cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
11651cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
11661cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(), elements);
11671cb0ef41Sopenharmony_ci  for (int i = 0; i < map.GetInObjectProperties(); i++) {
11681cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSObjectInObjectProperty(map, i),
11691cb0ef41Sopenharmony_ci            jsgraph()->UndefinedConstant());
11701cb0ef41Sopenharmony_ci  }
11711cb0ef41Sopenharmony_ci
11721cb0ef41Sopenharmony_ci  RelaxControls(node);
11731cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
11741cb0ef41Sopenharmony_ci  return Changed(node);
11751cb0ef41Sopenharmony_ci}
11761cb0ef41Sopenharmony_ci
11771cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateLiteralRegExp(Node* node) {
11781cb0ef41Sopenharmony_ci  JSCreateLiteralRegExpNode n(node);
11791cb0ef41Sopenharmony_ci  CreateLiteralParameters const& p = n.Parameters();
11801cb0ef41Sopenharmony_ci  Effect effect = n.effect();
11811cb0ef41Sopenharmony_ci  Control control = n.control();
11821cb0ef41Sopenharmony_ci  ProcessedFeedback const& feedback =
11831cb0ef41Sopenharmony_ci      broker()->GetFeedbackForRegExpLiteral(p.feedback());
11841cb0ef41Sopenharmony_ci  if (!feedback.IsInsufficient()) {
11851cb0ef41Sopenharmony_ci    RegExpBoilerplateDescriptionRef literal =
11861cb0ef41Sopenharmony_ci        feedback.AsRegExpLiteral().value();
11871cb0ef41Sopenharmony_ci    Node* value = effect = AllocateLiteralRegExp(effect, control, literal);
11881cb0ef41Sopenharmony_ci    ReplaceWithValue(node, value, effect, control);
11891cb0ef41Sopenharmony_ci    return Replace(value);
11901cb0ef41Sopenharmony_ci  }
11911cb0ef41Sopenharmony_ci  return NoChange();
11921cb0ef41Sopenharmony_ci}
11931cb0ef41Sopenharmony_ci
11941cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSGetTemplateObject(Node* node) {
11951cb0ef41Sopenharmony_ci  JSGetTemplateObjectNode n(node);
11961cb0ef41Sopenharmony_ci  GetTemplateObjectParameters const& parameters = n.Parameters();
11971cb0ef41Sopenharmony_ci
11981cb0ef41Sopenharmony_ci  const ProcessedFeedback& feedback =
11991cb0ef41Sopenharmony_ci      broker()->GetFeedbackForTemplateObject(parameters.feedback());
12001cb0ef41Sopenharmony_ci  // TODO(v8:7790): Consider not generating JSGetTemplateObject operator
12011cb0ef41Sopenharmony_ci  // in the BytecodeGraphBuilder in the first place, if template_object is not
12021cb0ef41Sopenharmony_ci  // available.
12031cb0ef41Sopenharmony_ci  if (feedback.IsInsufficient()) return NoChange();
12041cb0ef41Sopenharmony_ci
12051cb0ef41Sopenharmony_ci  JSArrayRef template_object = feedback.AsTemplateObject().value();
12061cb0ef41Sopenharmony_ci  Node* value = jsgraph()->Constant(template_object);
12071cb0ef41Sopenharmony_ci  ReplaceWithValue(node, value);
12081cb0ef41Sopenharmony_ci  return Replace(value);
12091cb0ef41Sopenharmony_ci}
12101cb0ef41Sopenharmony_ci
12111cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateFunctionContext(Node* node) {
12121cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode());
12131cb0ef41Sopenharmony_ci  const CreateFunctionContextParameters& parameters =
12141cb0ef41Sopenharmony_ci      CreateFunctionContextParametersOf(node->op());
12151cb0ef41Sopenharmony_ci  ScopeInfoRef scope_info = parameters.scope_info(broker());
12161cb0ef41Sopenharmony_ci  int slot_count = parameters.slot_count();
12171cb0ef41Sopenharmony_ci  ScopeType scope_type = parameters.scope_type();
12181cb0ef41Sopenharmony_ci
12191cb0ef41Sopenharmony_ci  // Use inline allocation for function contexts up to a size limit.
12201cb0ef41Sopenharmony_ci  if (slot_count < kFunctionContextAllocationLimit) {
12211cb0ef41Sopenharmony_ci    // JSCreateFunctionContext[slot_count < limit]](fun)
12221cb0ef41Sopenharmony_ci    Node* effect = NodeProperties::GetEffectInput(node);
12231cb0ef41Sopenharmony_ci    Node* control = NodeProperties::GetControlInput(node);
12241cb0ef41Sopenharmony_ci    Node* context = NodeProperties::GetContextInput(node);
12251cb0ef41Sopenharmony_ci    AllocationBuilder a(jsgraph(), effect, control);
12261cb0ef41Sopenharmony_ci    STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 2);  // Ensure fully covered.
12271cb0ef41Sopenharmony_ci    int context_length = slot_count + Context::MIN_CONTEXT_SLOTS;
12281cb0ef41Sopenharmony_ci    switch (scope_type) {
12291cb0ef41Sopenharmony_ci      case EVAL_SCOPE:
12301cb0ef41Sopenharmony_ci        a.AllocateContext(context_length, native_context().eval_context_map());
12311cb0ef41Sopenharmony_ci        break;
12321cb0ef41Sopenharmony_ci      case FUNCTION_SCOPE:
12331cb0ef41Sopenharmony_ci        a.AllocateContext(context_length,
12341cb0ef41Sopenharmony_ci                          native_context().function_context_map());
12351cb0ef41Sopenharmony_ci        break;
12361cb0ef41Sopenharmony_ci      default:
12371cb0ef41Sopenharmony_ci        UNREACHABLE();
12381cb0ef41Sopenharmony_ci    }
12391cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX),
12401cb0ef41Sopenharmony_ci            scope_info);
12411cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
12421cb0ef41Sopenharmony_ci    for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) {
12431cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant());
12441cb0ef41Sopenharmony_ci    }
12451cb0ef41Sopenharmony_ci    RelaxControls(node);
12461cb0ef41Sopenharmony_ci    a.FinishAndChange(node);
12471cb0ef41Sopenharmony_ci    return Changed(node);
12481cb0ef41Sopenharmony_ci  }
12491cb0ef41Sopenharmony_ci
12501cb0ef41Sopenharmony_ci  return NoChange();
12511cb0ef41Sopenharmony_ci}
12521cb0ef41Sopenharmony_ci
12531cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateWithContext(Node* node) {
12541cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateWithContext, node->opcode());
12551cb0ef41Sopenharmony_ci  ScopeInfoRef scope_info = ScopeInfoOf(broker(), node->op());
12561cb0ef41Sopenharmony_ci  Node* extension = NodeProperties::GetValueInput(node, 0);
12571cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
12581cb0ef41Sopenharmony_ci  Node* control = NodeProperties::GetControlInput(node);
12591cb0ef41Sopenharmony_ci  Node* context = NodeProperties::GetContextInput(node);
12601cb0ef41Sopenharmony_ci
12611cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
12621cb0ef41Sopenharmony_ci  STATIC_ASSERT(Context::MIN_CONTEXT_EXTENDED_SLOTS ==
12631cb0ef41Sopenharmony_ci                3);  // Ensure fully covered.
12641cb0ef41Sopenharmony_ci  a.AllocateContext(Context::MIN_CONTEXT_EXTENDED_SLOTS,
12651cb0ef41Sopenharmony_ci                    native_context().with_context_map());
12661cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX), scope_info);
12671cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
12681cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForContextSlot(Context::EXTENSION_INDEX), extension);
12691cb0ef41Sopenharmony_ci  RelaxControls(node);
12701cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
12711cb0ef41Sopenharmony_ci  return Changed(node);
12721cb0ef41Sopenharmony_ci}
12731cb0ef41Sopenharmony_ci
12741cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateCatchContext(Node* node) {
12751cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateCatchContext, node->opcode());
12761cb0ef41Sopenharmony_ci  ScopeInfoRef scope_info = ScopeInfoOf(broker(), node->op());
12771cb0ef41Sopenharmony_ci  Node* exception = NodeProperties::GetValueInput(node, 0);
12781cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
12791cb0ef41Sopenharmony_ci  Node* control = NodeProperties::GetControlInput(node);
12801cb0ef41Sopenharmony_ci  Node* context = NodeProperties::GetContextInput(node);
12811cb0ef41Sopenharmony_ci
12821cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
12831cb0ef41Sopenharmony_ci  STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 2);  // Ensure fully covered.
12841cb0ef41Sopenharmony_ci  a.AllocateContext(Context::MIN_CONTEXT_SLOTS + 1,
12851cb0ef41Sopenharmony_ci                    native_context().catch_context_map());
12861cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX), scope_info);
12871cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
12881cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForContextSlot(Context::THROWN_OBJECT_INDEX),
12891cb0ef41Sopenharmony_ci          exception);
12901cb0ef41Sopenharmony_ci  RelaxControls(node);
12911cb0ef41Sopenharmony_ci  a.FinishAndChange(node);
12921cb0ef41Sopenharmony_ci  return Changed(node);
12931cb0ef41Sopenharmony_ci}
12941cb0ef41Sopenharmony_ci
12951cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateBlockContext(Node* node) {
12961cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateBlockContext, node->opcode());
12971cb0ef41Sopenharmony_ci  ScopeInfoRef scope_info = ScopeInfoOf(broker(), node->op());
12981cb0ef41Sopenharmony_ci  int const context_length = scope_info.ContextLength();
12991cb0ef41Sopenharmony_ci
13001cb0ef41Sopenharmony_ci  // Use inline allocation for block contexts up to a size limit.
13011cb0ef41Sopenharmony_ci  if (context_length < kBlockContextAllocationLimit) {
13021cb0ef41Sopenharmony_ci    // JSCreateBlockContext[scope[length < limit]](fun)
13031cb0ef41Sopenharmony_ci    Node* effect = NodeProperties::GetEffectInput(node);
13041cb0ef41Sopenharmony_ci    Node* control = NodeProperties::GetControlInput(node);
13051cb0ef41Sopenharmony_ci    Node* context = NodeProperties::GetContextInput(node);
13061cb0ef41Sopenharmony_ci
13071cb0ef41Sopenharmony_ci    AllocationBuilder a(jsgraph(), effect, control);
13081cb0ef41Sopenharmony_ci    STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == 2);  // Ensure fully covered.
13091cb0ef41Sopenharmony_ci    a.AllocateContext(context_length, native_context().block_context_map());
13101cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForContextSlot(Context::SCOPE_INFO_INDEX),
13111cb0ef41Sopenharmony_ci            scope_info);
13121cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX), context);
13131cb0ef41Sopenharmony_ci    for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) {
13141cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant());
13151cb0ef41Sopenharmony_ci    }
13161cb0ef41Sopenharmony_ci    RelaxControls(node);
13171cb0ef41Sopenharmony_ci    a.FinishAndChange(node);
13181cb0ef41Sopenharmony_ci    return Changed(node);
13191cb0ef41Sopenharmony_ci  }
13201cb0ef41Sopenharmony_ci
13211cb0ef41Sopenharmony_ci  return NoChange();
13221cb0ef41Sopenharmony_ci}
13231cb0ef41Sopenharmony_ci
13241cb0ef41Sopenharmony_cinamespace {
13251cb0ef41Sopenharmony_ci
13261cb0ef41Sopenharmony_cibase::Optional<MapRef> GetObjectCreateMap(JSHeapBroker* broker,
13271cb0ef41Sopenharmony_ci                                          HeapObjectRef prototype) {
13281cb0ef41Sopenharmony_ci  MapRef standard_map =
13291cb0ef41Sopenharmony_ci      broker->target_native_context().object_function().initial_map(
13301cb0ef41Sopenharmony_ci          broker->dependencies());
13311cb0ef41Sopenharmony_ci  if (prototype.equals(standard_map.prototype())) {
13321cb0ef41Sopenharmony_ci    return standard_map;
13331cb0ef41Sopenharmony_ci  }
13341cb0ef41Sopenharmony_ci  if (prototype.map().oddball_type() == OddballType::kNull) {
13351cb0ef41Sopenharmony_ci    return broker->target_native_context()
13361cb0ef41Sopenharmony_ci        .slow_object_with_null_prototype_map();
13371cb0ef41Sopenharmony_ci  }
13381cb0ef41Sopenharmony_ci  if (prototype.IsJSObject()) {
13391cb0ef41Sopenharmony_ci    return prototype.AsJSObject().GetObjectCreateMap();
13401cb0ef41Sopenharmony_ci  }
13411cb0ef41Sopenharmony_ci  return base::Optional<MapRef>();
13421cb0ef41Sopenharmony_ci}
13431cb0ef41Sopenharmony_ci
13441cb0ef41Sopenharmony_ci}  // namespace
13451cb0ef41Sopenharmony_ci
13461cb0ef41Sopenharmony_ciReduction JSCreateLowering::ReduceJSCreateObject(Node* node) {
13471cb0ef41Sopenharmony_ci  DCHECK_EQ(IrOpcode::kJSCreateObject, node->opcode());
13481cb0ef41Sopenharmony_ci  Node* effect = NodeProperties::GetEffectInput(node);
13491cb0ef41Sopenharmony_ci  Node* control = NodeProperties::GetControlInput(node);
13501cb0ef41Sopenharmony_ci  Node* prototype = NodeProperties::GetValueInput(node, 0);
13511cb0ef41Sopenharmony_ci  Type prototype_type = NodeProperties::GetType(prototype);
13521cb0ef41Sopenharmony_ci  if (!prototype_type.IsHeapConstant()) return NoChange();
13531cb0ef41Sopenharmony_ci
13541cb0ef41Sopenharmony_ci  HeapObjectRef prototype_const = prototype_type.AsHeapConstant()->Ref();
13551cb0ef41Sopenharmony_ci  auto maybe_instance_map = GetObjectCreateMap(broker(), prototype_const);
13561cb0ef41Sopenharmony_ci  if (!maybe_instance_map) return NoChange();
13571cb0ef41Sopenharmony_ci  MapRef instance_map = maybe_instance_map.value();
13581cb0ef41Sopenharmony_ci
13591cb0ef41Sopenharmony_ci  Node* properties = jsgraph()->EmptyFixedArrayConstant();
13601cb0ef41Sopenharmony_ci  if (instance_map.is_dictionary_map()) {
13611cb0ef41Sopenharmony_ci    DCHECK_EQ(prototype_const.map().oddball_type(), OddballType::kNull);
13621cb0ef41Sopenharmony_ci    // Allocate an empty NameDictionary as backing store for the properties.
13631cb0ef41Sopenharmony_ci    MapRef map = MakeRef(broker(), factory()->name_dictionary_map());
13641cb0ef41Sopenharmony_ci    int capacity =
13651cb0ef41Sopenharmony_ci        NameDictionary::ComputeCapacity(NameDictionary::kInitialCapacity);
13661cb0ef41Sopenharmony_ci    DCHECK(base::bits::IsPowerOfTwo(capacity));
13671cb0ef41Sopenharmony_ci    int length = NameDictionary::EntryToIndex(InternalIndex(capacity));
13681cb0ef41Sopenharmony_ci    int size = NameDictionary::SizeFor(length);
13691cb0ef41Sopenharmony_ci
13701cb0ef41Sopenharmony_ci    AllocationBuilder a(jsgraph(), effect, control);
13711cb0ef41Sopenharmony_ci    a.Allocate(size, AllocationType::kYoung, Type::Any());
13721cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForMap(), map);
13731cb0ef41Sopenharmony_ci    // Initialize FixedArray fields.
13741cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForFixedArrayLength(),
13751cb0ef41Sopenharmony_ci            jsgraph()->SmiConstant(length));
13761cb0ef41Sopenharmony_ci    // Initialize HashTable fields.
13771cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForHashTableBaseNumberOfElements(),
13781cb0ef41Sopenharmony_ci            jsgraph()->SmiConstant(0));
13791cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForHashTableBaseNumberOfDeletedElement(),
13801cb0ef41Sopenharmony_ci            jsgraph()->SmiConstant(0));
13811cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForHashTableBaseCapacity(),
13821cb0ef41Sopenharmony_ci            jsgraph()->SmiConstant(capacity));
13831cb0ef41Sopenharmony_ci    // Initialize Dictionary fields.
13841cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForDictionaryNextEnumerationIndex(),
13851cb0ef41Sopenharmony_ci            jsgraph()->SmiConstant(PropertyDetails::kInitialIndex));
13861cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForDictionaryObjectHashIndex(),
13871cb0ef41Sopenharmony_ci            jsgraph()->SmiConstant(PropertyArray::kNoHashSentinel));
13881cb0ef41Sopenharmony_ci    // Initialize the Properties fields.
13891cb0ef41Sopenharmony_ci    Node* undefined = jsgraph()->UndefinedConstant();
13901cb0ef41Sopenharmony_ci    STATIC_ASSERT(NameDictionary::kElementsStartIndex ==
13911cb0ef41Sopenharmony_ci                  NameDictionary::kObjectHashIndex + 1);
13921cb0ef41Sopenharmony_ci    for (int index = NameDictionary::kElementsStartIndex; index < length;
13931cb0ef41Sopenharmony_ci         index++) {
13941cb0ef41Sopenharmony_ci      a.Store(AccessBuilder::ForFixedArraySlot(index, kNoWriteBarrier),
13951cb0ef41Sopenharmony_ci              undefined);
13961cb0ef41Sopenharmony_ci    }
13971cb0ef41Sopenharmony_ci    properties = effect = a.Finish();
13981cb0ef41Sopenharmony_ci  }
13991cb0ef41Sopenharmony_ci
14001cb0ef41Sopenharmony_ci  int const instance_size = instance_map.instance_size();
14011cb0ef41Sopenharmony_ci  if (instance_size > kMaxRegularHeapObjectSize) return NoChange();
14021cb0ef41Sopenharmony_ci  CHECK(!instance_map.IsInobjectSlackTrackingInProgress());
14031cb0ef41Sopenharmony_ci
14041cb0ef41Sopenharmony_ci  // Emit code to allocate the JSObject instance for the given
14051cb0ef41Sopenharmony_ci  // {instance_map}.
14061cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
14071cb0ef41Sopenharmony_ci  a.Allocate(instance_size, AllocationType::kYoung, Type::Any());
14081cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForMap(), instance_map);
14091cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
14101cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForJSObjectElements(),
14111cb0ef41Sopenharmony_ci          jsgraph()->EmptyFixedArrayConstant());
14121cb0ef41Sopenharmony_ci  // Initialize Object fields.
14131cb0ef41Sopenharmony_ci  Node* undefined = jsgraph()->UndefinedConstant();
14141cb0ef41Sopenharmony_ci  for (int offset = JSObject::kHeaderSize; offset < instance_size;
14151cb0ef41Sopenharmony_ci       offset += kTaggedSize) {
14161cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForJSObjectOffset(offset, kNoWriteBarrier),
14171cb0ef41Sopenharmony_ci            undefined);
14181cb0ef41Sopenharmony_ci  }
14191cb0ef41Sopenharmony_ci  Node* value = effect = a.Finish();
14201cb0ef41Sopenharmony_ci
14211cb0ef41Sopenharmony_ci  ReplaceWithValue(node, value, effect, control);
14221cb0ef41Sopenharmony_ci  return Replace(value);
14231cb0ef41Sopenharmony_ci}
14241cb0ef41Sopenharmony_ci
14251cb0ef41Sopenharmony_ci// Helper that allocates a FixedArray holding argument values recorded in the
14261cb0ef41Sopenharmony_ci// given {frame_state}. Serves as backing store for JSCreateArguments nodes.
14271cb0ef41Sopenharmony_ciNode* JSCreateLowering::TryAllocateArguments(Node* effect, Node* control,
14281cb0ef41Sopenharmony_ci                                             FrameState frame_state) {
14291cb0ef41Sopenharmony_ci  FrameStateInfo state_info = frame_state.frame_state_info();
14301cb0ef41Sopenharmony_ci  int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
14311cb0ef41Sopenharmony_ci  if (argument_count == 0) return jsgraph()->EmptyFixedArrayConstant();
14321cb0ef41Sopenharmony_ci
14331cb0ef41Sopenharmony_ci  // Prepare an iterator over argument values recorded in the frame state.
14341cb0ef41Sopenharmony_ci  Node* const parameters = frame_state.parameters();
14351cb0ef41Sopenharmony_ci  StateValuesAccess parameters_access(parameters);
14361cb0ef41Sopenharmony_ci  auto parameters_it = parameters_access.begin_without_receiver();
14371cb0ef41Sopenharmony_ci
14381cb0ef41Sopenharmony_ci  // Actually allocate the backing store.
14391cb0ef41Sopenharmony_ci  MapRef fixed_array_map = MakeRef(broker(), factory()->fixed_array_map());
14401cb0ef41Sopenharmony_ci  AllocationBuilder ab(jsgraph(), effect, control);
14411cb0ef41Sopenharmony_ci  if (!ab.CanAllocateArray(argument_count, fixed_array_map)) {
14421cb0ef41Sopenharmony_ci    return nullptr;
14431cb0ef41Sopenharmony_ci  }
14441cb0ef41Sopenharmony_ci  ab.AllocateArray(argument_count, fixed_array_map);
14451cb0ef41Sopenharmony_ci  for (int i = 0; i < argument_count; ++i, ++parameters_it) {
14461cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(parameters_it.node());
14471cb0ef41Sopenharmony_ci    ab.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
14481cb0ef41Sopenharmony_ci             parameters_it.node());
14491cb0ef41Sopenharmony_ci  }
14501cb0ef41Sopenharmony_ci  return ab.Finish();
14511cb0ef41Sopenharmony_ci}
14521cb0ef41Sopenharmony_ci
14531cb0ef41Sopenharmony_ci// Helper that allocates a FixedArray holding argument values recorded in the
14541cb0ef41Sopenharmony_ci// given {frame_state}. Serves as backing store for JSCreateArguments nodes.
14551cb0ef41Sopenharmony_ciNode* JSCreateLowering::TryAllocateRestArguments(Node* effect, Node* control,
14561cb0ef41Sopenharmony_ci                                                 FrameState frame_state,
14571cb0ef41Sopenharmony_ci                                                 int start_index) {
14581cb0ef41Sopenharmony_ci  FrameStateInfo state_info = frame_state.frame_state_info();
14591cb0ef41Sopenharmony_ci  int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
14601cb0ef41Sopenharmony_ci  int num_elements = std::max(0, argument_count - start_index);
14611cb0ef41Sopenharmony_ci  if (num_elements == 0) return jsgraph()->EmptyFixedArrayConstant();
14621cb0ef41Sopenharmony_ci
14631cb0ef41Sopenharmony_ci  // Prepare an iterator over argument values recorded in the frame state.
14641cb0ef41Sopenharmony_ci  Node* const parameters = frame_state.parameters();
14651cb0ef41Sopenharmony_ci  StateValuesAccess parameters_access(parameters);
14661cb0ef41Sopenharmony_ci  auto parameters_it =
14671cb0ef41Sopenharmony_ci      parameters_access.begin_without_receiver_and_skip(start_index);
14681cb0ef41Sopenharmony_ci
14691cb0ef41Sopenharmony_ci  // Actually allocate the backing store.
14701cb0ef41Sopenharmony_ci  MapRef fixed_array_map = MakeRef(broker(), factory()->fixed_array_map());
14711cb0ef41Sopenharmony_ci  AllocationBuilder ab(jsgraph(), effect, control);
14721cb0ef41Sopenharmony_ci  if (!ab.CanAllocateArray(num_elements, fixed_array_map)) {
14731cb0ef41Sopenharmony_ci    return nullptr;
14741cb0ef41Sopenharmony_ci  }
14751cb0ef41Sopenharmony_ci  ab.AllocateArray(num_elements, fixed_array_map);
14761cb0ef41Sopenharmony_ci  for (int i = 0; i < num_elements; ++i, ++parameters_it) {
14771cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(parameters_it.node());
14781cb0ef41Sopenharmony_ci    ab.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
14791cb0ef41Sopenharmony_ci             parameters_it.node());
14801cb0ef41Sopenharmony_ci  }
14811cb0ef41Sopenharmony_ci  return ab.Finish();
14821cb0ef41Sopenharmony_ci}
14831cb0ef41Sopenharmony_ci
14841cb0ef41Sopenharmony_ci// Helper that allocates a FixedArray serving as a parameter map for values
14851cb0ef41Sopenharmony_ci// recorded in the given {frame_state}. Some elements map to slots within the
14861cb0ef41Sopenharmony_ci// given {context}. Serves as backing store for JSCreateArguments nodes.
14871cb0ef41Sopenharmony_ciNode* JSCreateLowering::TryAllocateAliasedArguments(
14881cb0ef41Sopenharmony_ci    Node* effect, Node* control, FrameState frame_state, Node* context,
14891cb0ef41Sopenharmony_ci    const SharedFunctionInfoRef& shared, bool* has_aliased_arguments) {
14901cb0ef41Sopenharmony_ci  FrameStateInfo state_info = frame_state.frame_state_info();
14911cb0ef41Sopenharmony_ci  int argument_count = state_info.parameter_count() - 1;  // Minus receiver.
14921cb0ef41Sopenharmony_ci  if (argument_count == 0) return jsgraph()->EmptyFixedArrayConstant();
14931cb0ef41Sopenharmony_ci
14941cb0ef41Sopenharmony_ci  // If there is no aliasing, the arguments object elements are not special in
14951cb0ef41Sopenharmony_ci  // any way, we can just return an unmapped backing store instead.
14961cb0ef41Sopenharmony_ci  int parameter_count =
14971cb0ef41Sopenharmony_ci      shared.internal_formal_parameter_count_without_receiver();
14981cb0ef41Sopenharmony_ci  if (parameter_count == 0) {
14991cb0ef41Sopenharmony_ci    return TryAllocateArguments(effect, control, frame_state);
15001cb0ef41Sopenharmony_ci  }
15011cb0ef41Sopenharmony_ci
15021cb0ef41Sopenharmony_ci  // Calculate number of argument values being aliased/mapped.
15031cb0ef41Sopenharmony_ci  int mapped_count = std::min(argument_count, parameter_count);
15041cb0ef41Sopenharmony_ci  *has_aliased_arguments = true;
15051cb0ef41Sopenharmony_ci
15061cb0ef41Sopenharmony_ci  MapRef sloppy_arguments_elements_map =
15071cb0ef41Sopenharmony_ci      MakeRef(broker(), factory()->sloppy_arguments_elements_map());
15081cb0ef41Sopenharmony_ci  AllocationBuilder ab(jsgraph(), effect, control);
15091cb0ef41Sopenharmony_ci
15101cb0ef41Sopenharmony_ci  if (!ab.CanAllocateSloppyArgumentElements(mapped_count,
15111cb0ef41Sopenharmony_ci                                            sloppy_arguments_elements_map)) {
15121cb0ef41Sopenharmony_ci    return nullptr;
15131cb0ef41Sopenharmony_ci  }
15141cb0ef41Sopenharmony_ci
15151cb0ef41Sopenharmony_ci  MapRef fixed_array_map = MakeRef(broker(), factory()->fixed_array_map());
15161cb0ef41Sopenharmony_ci  if (!ab.CanAllocateArray(argument_count, fixed_array_map)) {
15171cb0ef41Sopenharmony_ci    return nullptr;
15181cb0ef41Sopenharmony_ci  }
15191cb0ef41Sopenharmony_ci
15201cb0ef41Sopenharmony_ci  // Prepare an iterator over argument values recorded in the frame state.
15211cb0ef41Sopenharmony_ci  Node* const parameters = frame_state.parameters();
15221cb0ef41Sopenharmony_ci  StateValuesAccess parameters_access(parameters);
15231cb0ef41Sopenharmony_ci  auto parameters_it =
15241cb0ef41Sopenharmony_ci      parameters_access.begin_without_receiver_and_skip(mapped_count);
15251cb0ef41Sopenharmony_ci
15261cb0ef41Sopenharmony_ci  // The unmapped argument values recorded in the frame state are stored yet
15271cb0ef41Sopenharmony_ci  // another indirection away and then linked into the parameter map below,
15281cb0ef41Sopenharmony_ci  // whereas mapped argument values are replaced with a hole instead.
15291cb0ef41Sopenharmony_ci  ab.AllocateArray(argument_count, fixed_array_map);
15301cb0ef41Sopenharmony_ci  for (int i = 0; i < mapped_count; ++i) {
15311cb0ef41Sopenharmony_ci    ab.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
15321cb0ef41Sopenharmony_ci             jsgraph()->TheHoleConstant());
15331cb0ef41Sopenharmony_ci  }
15341cb0ef41Sopenharmony_ci  for (int i = mapped_count; i < argument_count; ++i, ++parameters_it) {
15351cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(parameters_it.node());
15361cb0ef41Sopenharmony_ci    ab.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
15371cb0ef41Sopenharmony_ci             parameters_it.node());
15381cb0ef41Sopenharmony_ci  }
15391cb0ef41Sopenharmony_ci  Node* arguments = ab.Finish();
15401cb0ef41Sopenharmony_ci
15411cb0ef41Sopenharmony_ci  // Actually allocate the backing store.
15421cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), arguments, control);
15431cb0ef41Sopenharmony_ci  a.AllocateSloppyArgumentElements(mapped_count, sloppy_arguments_elements_map);
15441cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForSloppyArgumentsElementsContext(), context);
15451cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForSloppyArgumentsElementsArguments(), arguments);
15461cb0ef41Sopenharmony_ci  for (int i = 0; i < mapped_count; ++i) {
15471cb0ef41Sopenharmony_ci    int idx = shared.context_parameters_start() + parameter_count - 1 - i;
15481cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForSloppyArgumentsElementsMappedEntry(),
15491cb0ef41Sopenharmony_ci            jsgraph()->Constant(i), jsgraph()->Constant(idx));
15501cb0ef41Sopenharmony_ci  }
15511cb0ef41Sopenharmony_ci  return a.Finish();
15521cb0ef41Sopenharmony_ci}
15531cb0ef41Sopenharmony_ci
15541cb0ef41Sopenharmony_ci// Helper that allocates a FixedArray serving as a parameter map for values
15551cb0ef41Sopenharmony_ci// unknown at compile-time, the true {arguments_length} and {arguments_frame}
15561cb0ef41Sopenharmony_ci// values can only be determined dynamically at run-time and are provided.
15571cb0ef41Sopenharmony_ci// Serves as backing store for JSCreateArguments nodes.
15581cb0ef41Sopenharmony_ciNode* JSCreateLowering::TryAllocateAliasedArguments(
15591cb0ef41Sopenharmony_ci    Node* effect, Node* control, Node* context, Node* arguments_length,
15601cb0ef41Sopenharmony_ci    const SharedFunctionInfoRef& shared, bool* has_aliased_arguments) {
15611cb0ef41Sopenharmony_ci  // If there is no aliasing, the arguments object elements are not
15621cb0ef41Sopenharmony_ci  // special in any way, we can just return an unmapped backing store.
15631cb0ef41Sopenharmony_ci  int parameter_count =
15641cb0ef41Sopenharmony_ci      shared.internal_formal_parameter_count_without_receiver();
15651cb0ef41Sopenharmony_ci  if (parameter_count == 0) {
15661cb0ef41Sopenharmony_ci    return graph()->NewNode(
15671cb0ef41Sopenharmony_ci        simplified()->NewArgumentsElements(
15681cb0ef41Sopenharmony_ci            CreateArgumentsType::kUnmappedArguments, parameter_count),
15691cb0ef41Sopenharmony_ci        arguments_length, effect);
15701cb0ef41Sopenharmony_ci  }
15711cb0ef41Sopenharmony_ci
15721cb0ef41Sopenharmony_ci  int mapped_count = parameter_count;
15731cb0ef41Sopenharmony_ci  MapRef sloppy_arguments_elements_map =
15741cb0ef41Sopenharmony_ci      MakeRef(broker(), factory()->sloppy_arguments_elements_map());
15751cb0ef41Sopenharmony_ci
15761cb0ef41Sopenharmony_ci  {
15771cb0ef41Sopenharmony_ci    AllocationBuilder ab(jsgraph(), effect, control);
15781cb0ef41Sopenharmony_ci    if (!ab.CanAllocateSloppyArgumentElements(mapped_count,
15791cb0ef41Sopenharmony_ci                                              sloppy_arguments_elements_map)) {
15801cb0ef41Sopenharmony_ci      return nullptr;
15811cb0ef41Sopenharmony_ci    }
15821cb0ef41Sopenharmony_ci  }
15831cb0ef41Sopenharmony_ci
15841cb0ef41Sopenharmony_ci  // From here on we are going to allocate a mapped (aka. aliased) elements
15851cb0ef41Sopenharmony_ci  // backing store. We do not statically know how many arguments exist, but
15861cb0ef41Sopenharmony_ci  // dynamically selecting the hole for some of the "mapped" elements allows
15871cb0ef41Sopenharmony_ci  // using a static shape for the parameter map.
15881cb0ef41Sopenharmony_ci  *has_aliased_arguments = true;
15891cb0ef41Sopenharmony_ci
15901cb0ef41Sopenharmony_ci  // The unmapped argument values are stored yet another indirection away and
15911cb0ef41Sopenharmony_ci  // then linked into the parameter map below, whereas mapped argument values
15921cb0ef41Sopenharmony_ci  // (i.e. the first {mapped_count} elements) are replaced with a hole instead.
15931cb0ef41Sopenharmony_ci  Node* arguments = effect =
15941cb0ef41Sopenharmony_ci      graph()->NewNode(simplified()->NewArgumentsElements(
15951cb0ef41Sopenharmony_ci                           CreateArgumentsType::kMappedArguments, mapped_count),
15961cb0ef41Sopenharmony_ci                       arguments_length, effect);
15971cb0ef41Sopenharmony_ci
15981cb0ef41Sopenharmony_ci  // Actually allocate the backing store.
15991cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
16001cb0ef41Sopenharmony_ci  a.AllocateSloppyArgumentElements(mapped_count, sloppy_arguments_elements_map);
16011cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForSloppyArgumentsElementsContext(), context);
16021cb0ef41Sopenharmony_ci  a.Store(AccessBuilder::ForSloppyArgumentsElementsArguments(), arguments);
16031cb0ef41Sopenharmony_ci  for (int i = 0; i < mapped_count; ++i) {
16041cb0ef41Sopenharmony_ci    int idx = shared.context_parameters_start() + parameter_count - 1 - i;
16051cb0ef41Sopenharmony_ci    Node* value = graph()->NewNode(
16061cb0ef41Sopenharmony_ci        common()->Select(MachineRepresentation::kTagged),
16071cb0ef41Sopenharmony_ci        graph()->NewNode(simplified()->NumberLessThan(), jsgraph()->Constant(i),
16081cb0ef41Sopenharmony_ci                         arguments_length),
16091cb0ef41Sopenharmony_ci        jsgraph()->Constant(idx), jsgraph()->TheHoleConstant());
16101cb0ef41Sopenharmony_ci    a.Store(AccessBuilder::ForSloppyArgumentsElementsMappedEntry(),
16111cb0ef41Sopenharmony_ci            jsgraph()->Constant(i), value);
16121cb0ef41Sopenharmony_ci  }
16131cb0ef41Sopenharmony_ci  return a.Finish();
16141cb0ef41Sopenharmony_ci}
16151cb0ef41Sopenharmony_ci
16161cb0ef41Sopenharmony_ciNode* JSCreateLowering::AllocateElements(Node* effect, Node* control,
16171cb0ef41Sopenharmony_ci                                         ElementsKind elements_kind,
16181cb0ef41Sopenharmony_ci                                         int capacity,
16191cb0ef41Sopenharmony_ci                                         AllocationType allocation) {
16201cb0ef41Sopenharmony_ci  DCHECK_LE(1, capacity);
16211cb0ef41Sopenharmony_ci  DCHECK_LE(capacity, JSArray::kInitialMaxFastElementArray);
16221cb0ef41Sopenharmony_ci
16231cb0ef41Sopenharmony_ci  Handle<Map> elements_map = IsDoubleElementsKind(elements_kind)
16241cb0ef41Sopenharmony_ci                                 ? factory()->fixed_double_array_map()
16251cb0ef41Sopenharmony_ci                                 : factory()->fixed_array_map();
16261cb0ef41Sopenharmony_ci  ElementAccess access = IsDoubleElementsKind(elements_kind)
16271cb0ef41Sopenharmony_ci                             ? AccessBuilder::ForFixedDoubleArrayElement()
16281cb0ef41Sopenharmony_ci                             : AccessBuilder::ForFixedArrayElement();
16291cb0ef41Sopenharmony_ci  Node* value = jsgraph()->TheHoleConstant();
16301cb0ef41Sopenharmony_ci
16311cb0ef41Sopenharmony_ci  // Actually allocate the backing store.
16321cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
16331cb0ef41Sopenharmony_ci  a.AllocateArray(capacity, MakeRef(broker(), elements_map), allocation);
16341cb0ef41Sopenharmony_ci  for (int i = 0; i < capacity; ++i) {
16351cb0ef41Sopenharmony_ci    Node* index = jsgraph()->Constant(i);
16361cb0ef41Sopenharmony_ci    a.Store(access, index, value);
16371cb0ef41Sopenharmony_ci  }
16381cb0ef41Sopenharmony_ci  return a.Finish();
16391cb0ef41Sopenharmony_ci}
16401cb0ef41Sopenharmony_ci
16411cb0ef41Sopenharmony_ciNode* JSCreateLowering::AllocateElements(Node* effect, Node* control,
16421cb0ef41Sopenharmony_ci                                         ElementsKind elements_kind,
16431cb0ef41Sopenharmony_ci                                         std::vector<Node*> const& values,
16441cb0ef41Sopenharmony_ci                                         AllocationType allocation) {
16451cb0ef41Sopenharmony_ci  int const capacity = static_cast<int>(values.size());
16461cb0ef41Sopenharmony_ci  DCHECK_LE(1, capacity);
16471cb0ef41Sopenharmony_ci  DCHECK_LE(capacity, JSArray::kInitialMaxFastElementArray);
16481cb0ef41Sopenharmony_ci
16491cb0ef41Sopenharmony_ci  Handle<Map> elements_map = IsDoubleElementsKind(elements_kind)
16501cb0ef41Sopenharmony_ci                                 ? factory()->fixed_double_array_map()
16511cb0ef41Sopenharmony_ci                                 : factory()->fixed_array_map();
16521cb0ef41Sopenharmony_ci  ElementAccess access = IsDoubleElementsKind(elements_kind)
16531cb0ef41Sopenharmony_ci                             ? AccessBuilder::ForFixedDoubleArrayElement()
16541cb0ef41Sopenharmony_ci                             : AccessBuilder::ForFixedArrayElement();
16551cb0ef41Sopenharmony_ci
16561cb0ef41Sopenharmony_ci  // Actually allocate the backing store.
16571cb0ef41Sopenharmony_ci  AllocationBuilder a(jsgraph(), effect, control);
16581cb0ef41Sopenharmony_ci  a.AllocateArray(capacity, MakeRef(broker(), elements_map), allocation);
16591cb0ef41Sopenharmony_ci  for (int i = 0; i < capacity; ++i) {
16601cb0ef41Sopenharmony_ci    Node* index = jsgraph()->Constant(i);
16611cb0ef41Sopenharmony_ci    a.Store(access, index, values[i]);
16621cb0ef41Sopenharmony_ci  }
16631cb0ef41Sopenharmony_ci  return a.Finish();
16641cb0ef41Sopenharmony_ci}
16651cb0ef41Sopenharmony_ci
16661cb0ef41Sopenharmony_cibase::Optional<Node*> JSCreateLowering::TryAllocateFastLiteral(
16671cb0ef41Sopenharmony_ci    Node* effect, Node* control, JSObjectRef boilerplate,
16681cb0ef41Sopenharmony_ci    AllocationType allocation, int max_depth, int* max_properties) {
16691cb0ef41Sopenharmony_ci  DCHECK_GE(max_depth, 0);
16701cb0ef41Sopenharmony_ci  DCHECK_GE(*max_properties, 0);
16711cb0ef41Sopenharmony_ci
16721cb0ef41Sopenharmony_ci  if (max_depth == 0) return {};
16731cb0ef41Sopenharmony_ci
16741cb0ef41Sopenharmony_ci  // Prevent concurrent migrations of boilerplate objects.
16751cb0ef41Sopenharmony_ci  JSHeapBroker::BoilerplateMigrationGuardIfNeeded boilerplate_access_guard(
16761cb0ef41Sopenharmony_ci      broker());
16771cb0ef41Sopenharmony_ci
16781cb0ef41Sopenharmony_ci  // Now that we hold the migration lock, get the current map.
16791cb0ef41Sopenharmony_ci  MapRef boilerplate_map = boilerplate.map();
16801cb0ef41Sopenharmony_ci  // Protect against concurrent changes to the boilerplate object by checking
16811cb0ef41Sopenharmony_ci  // for an identical value at the end of the compilation.
16821cb0ef41Sopenharmony_ci  dependencies()->DependOnObjectSlotValue(boilerplate, HeapObject::kMapOffset,
16831cb0ef41Sopenharmony_ci                                          boilerplate_map);
16841cb0ef41Sopenharmony_ci  {
16851cb0ef41Sopenharmony_ci    base::Optional<MapRef> current_boilerplate_map =
16861cb0ef41Sopenharmony_ci        boilerplate.map_direct_read();
16871cb0ef41Sopenharmony_ci    if (!current_boilerplate_map.has_value() ||
16881cb0ef41Sopenharmony_ci        !current_boilerplate_map->equals(boilerplate_map)) {
16891cb0ef41Sopenharmony_ci      return {};
16901cb0ef41Sopenharmony_ci    }
16911cb0ef41Sopenharmony_ci  }
16921cb0ef41Sopenharmony_ci
16931cb0ef41Sopenharmony_ci  // Bail out if the boilerplate map has been deprecated.  The map could of
16941cb0ef41Sopenharmony_ci  // course be deprecated at some point after the line below, but it's not a
16951cb0ef41Sopenharmony_ci  // correctness issue -- it only means the literal won't be created with the
16961cb0ef41Sopenharmony_ci  // most up to date map(s).
16971cb0ef41Sopenharmony_ci  if (boilerplate_map.is_deprecated()) return {};
16981cb0ef41Sopenharmony_ci
16991cb0ef41Sopenharmony_ci  // We currently only support in-object properties.
17001cb0ef41Sopenharmony_ci  if (boilerplate.map().elements_kind() == DICTIONARY_ELEMENTS ||
17011cb0ef41Sopenharmony_ci      boilerplate.map().is_dictionary_map() ||
17021cb0ef41Sopenharmony_ci      !boilerplate.raw_properties_or_hash().has_value()) {
17031cb0ef41Sopenharmony_ci    return {};
17041cb0ef41Sopenharmony_ci  }
17051cb0ef41Sopenharmony_ci  {
17061cb0ef41Sopenharmony_ci    ObjectRef properties = *boilerplate.raw_properties_or_hash();
17071cb0ef41Sopenharmony_ci    bool const empty = properties.IsSmi() ||
17081cb0ef41Sopenharmony_ci                       properties.equals(MakeRef<Object>(
17091cb0ef41Sopenharmony_ci                           broker(), factory()->empty_fixed_array())) ||
17101cb0ef41Sopenharmony_ci                       properties.equals(MakeRef<Object>(
17111cb0ef41Sopenharmony_ci                           broker(), factory()->empty_property_array()));
17121cb0ef41Sopenharmony_ci    if (!empty) return {};
17131cb0ef41Sopenharmony_ci  }
17141cb0ef41Sopenharmony_ci
17151cb0ef41Sopenharmony_ci  // Compute the in-object properties to store first (might have effects).
17161cb0ef41Sopenharmony_ci  ZoneVector<std::pair<FieldAccess, Node*>> inobject_fields(zone());
17171cb0ef41Sopenharmony_ci  inobject_fields.reserve(boilerplate_map.GetInObjectProperties());
17181cb0ef41Sopenharmony_ci  int const boilerplate_nof = boilerplate_map.NumberOfOwnDescriptors();
17191cb0ef41Sopenharmony_ci  for (InternalIndex i : InternalIndex::Range(boilerplate_nof)) {
17201cb0ef41Sopenharmony_ci    PropertyDetails const property_details =
17211cb0ef41Sopenharmony_ci        boilerplate_map.GetPropertyDetails(i);
17221cb0ef41Sopenharmony_ci    if (property_details.location() != PropertyLocation::kField) continue;
17231cb0ef41Sopenharmony_ci    DCHECK_EQ(PropertyKind::kData, property_details.kind());
17241cb0ef41Sopenharmony_ci    if ((*max_properties)-- == 0) return {};
17251cb0ef41Sopenharmony_ci
17261cb0ef41Sopenharmony_ci    NameRef property_name = boilerplate_map.GetPropertyKey(i);
17271cb0ef41Sopenharmony_ci    FieldIndex index = boilerplate_map.GetFieldIndexFor(i);
17281cb0ef41Sopenharmony_ci    ConstFieldInfo const_field_info(boilerplate_map.object());
17291cb0ef41Sopenharmony_ci    FieldAccess access = {kTaggedBase,
17301cb0ef41Sopenharmony_ci                          index.offset(),
17311cb0ef41Sopenharmony_ci                          property_name.object(),
17321cb0ef41Sopenharmony_ci                          MaybeHandle<Map>(),
17331cb0ef41Sopenharmony_ci                          Type::Any(),
17341cb0ef41Sopenharmony_ci                          MachineType::AnyTagged(),
17351cb0ef41Sopenharmony_ci                          kFullWriteBarrier,
17361cb0ef41Sopenharmony_ci                          const_field_info};
17371cb0ef41Sopenharmony_ci
17381cb0ef41Sopenharmony_ci    // Note: the use of RawInobjectPropertyAt (vs. the higher-level
17391cb0ef41Sopenharmony_ci    // GetOwnFastDataProperty) here is necessary, since the underlying value
17401cb0ef41Sopenharmony_ci    // may be `uninitialized`, which the latter explicitly does not support.
17411cb0ef41Sopenharmony_ci    base::Optional<ObjectRef> maybe_boilerplate_value =
17421cb0ef41Sopenharmony_ci        boilerplate.RawInobjectPropertyAt(index);
17431cb0ef41Sopenharmony_ci    if (!maybe_boilerplate_value.has_value()) return {};
17441cb0ef41Sopenharmony_ci
17451cb0ef41Sopenharmony_ci    // Note: We don't need to take a compilation dependency verifying the value
17461cb0ef41Sopenharmony_ci    // of `boilerplate_value`, since boilerplate properties are constant after
17471cb0ef41Sopenharmony_ci    // initialization modulo map migration. We protect against concurrent map
17481cb0ef41Sopenharmony_ci    // migrations (other than elements kind transition, which don't affect us)
17491cb0ef41Sopenharmony_ci    // via the boilerplate_migration_access lock.
17501cb0ef41Sopenharmony_ci    ObjectRef boilerplate_value = maybe_boilerplate_value.value();
17511cb0ef41Sopenharmony_ci
17521cb0ef41Sopenharmony_ci    // Uninitialized fields are marked through the `uninitialized_value` Oddball
17531cb0ef41Sopenharmony_ci    // (even for Smi representation!), or in the case of Double representation
17541cb0ef41Sopenharmony_ci    // through a HeapNumber containing the hole-NaN. Since Double-to-Tagged
17551cb0ef41Sopenharmony_ci    // representation changes are done in-place, we may even encounter these
17561cb0ef41Sopenharmony_ci    // HeapNumbers in Tagged representation.
17571cb0ef41Sopenharmony_ci    // Note that although we create nodes to write `uninitialized_value` into
17581cb0ef41Sopenharmony_ci    // the object, the field should be overwritten immediately with a real
17591cb0ef41Sopenharmony_ci    // value, and `uninitialized_value` should never be exposed to JS.
17601cb0ef41Sopenharmony_ci    ObjectRef uninitialized_oddball =
17611cb0ef41Sopenharmony_ci        MakeRef<HeapObject>(broker(), factory()->uninitialized_value());
17621cb0ef41Sopenharmony_ci    if (boilerplate_value.equals(uninitialized_oddball) ||
17631cb0ef41Sopenharmony_ci        (boilerplate_value.IsHeapNumber() &&
17641cb0ef41Sopenharmony_ci         boilerplate_value.AsHeapNumber().value_as_bits() == kHoleNanInt64)) {
17651cb0ef41Sopenharmony_ci      access.const_field_info = ConstFieldInfo::None();
17661cb0ef41Sopenharmony_ci    }
17671cb0ef41Sopenharmony_ci
17681cb0ef41Sopenharmony_ci    Node* value;
17691cb0ef41Sopenharmony_ci    if (boilerplate_value.IsJSObject()) {
17701cb0ef41Sopenharmony_ci      JSObjectRef boilerplate_object = boilerplate_value.AsJSObject();
17711cb0ef41Sopenharmony_ci      base::Optional<Node*> maybe_value =
17721cb0ef41Sopenharmony_ci          TryAllocateFastLiteral(effect, control, boilerplate_object,
17731cb0ef41Sopenharmony_ci                                 allocation, max_depth - 1, max_properties);
17741cb0ef41Sopenharmony_ci      if (!maybe_value.has_value()) return {};
17751cb0ef41Sopenharmony_ci      value = effect = maybe_value.value();
17761cb0ef41Sopenharmony_ci    } else if (property_details.representation().IsDouble()) {
17771cb0ef41Sopenharmony_ci      double number = boilerplate_value.AsHeapNumber().value();
17781cb0ef41Sopenharmony_ci      // Allocate a mutable HeapNumber box and store the value into it.
17791cb0ef41Sopenharmony_ci      AllocationBuilder builder(jsgraph(), effect, control);
17801cb0ef41Sopenharmony_ci      builder.Allocate(HeapNumber::kSize, allocation);
17811cb0ef41Sopenharmony_ci      builder.Store(AccessBuilder::ForMap(),
17821cb0ef41Sopenharmony_ci                    MakeRef(broker(), factory()->heap_number_map()));
17831cb0ef41Sopenharmony_ci      builder.Store(AccessBuilder::ForHeapNumberValue(),
17841cb0ef41Sopenharmony_ci                    jsgraph()->Constant(number));
17851cb0ef41Sopenharmony_ci      value = effect = builder.Finish();
17861cb0ef41Sopenharmony_ci    } else {
17871cb0ef41Sopenharmony_ci      // It's fine to store the 'uninitialized' Oddball into a Smi field since
17881cb0ef41Sopenharmony_ci      // it will get overwritten anyways and the store's MachineType (AnyTagged)
17891cb0ef41Sopenharmony_ci      // is compatible with it.
17901cb0ef41Sopenharmony_ci      DCHECK_IMPLIES(property_details.representation().IsSmi() &&
17911cb0ef41Sopenharmony_ci                         !boilerplate_value.IsSmi(),
17921cb0ef41Sopenharmony_ci                     boilerplate_value.equals(uninitialized_oddball));
17931cb0ef41Sopenharmony_ci      value = jsgraph()->Constant(boilerplate_value);
17941cb0ef41Sopenharmony_ci    }
17951cb0ef41Sopenharmony_ci    inobject_fields.push_back(std::make_pair(access, value));
17961cb0ef41Sopenharmony_ci  }
17971cb0ef41Sopenharmony_ci
17981cb0ef41Sopenharmony_ci  // Fill slack at the end of the boilerplate object with filler maps.
17991cb0ef41Sopenharmony_ci  int const boilerplate_length = boilerplate_map.GetInObjectProperties();
18001cb0ef41Sopenharmony_ci  for (int index = static_cast<int>(inobject_fields.size());
18011cb0ef41Sopenharmony_ci       index < boilerplate_length; ++index) {
18021cb0ef41Sopenharmony_ci    DCHECK(!V8_MAP_PACKING_BOOL);
18031cb0ef41Sopenharmony_ci    // TODO(wenyuzhao): Fix incorrect MachineType when V8_MAP_PACKING is
18041cb0ef41Sopenharmony_ci    // enabled.
18051cb0ef41Sopenharmony_ci    FieldAccess access =
18061cb0ef41Sopenharmony_ci        AccessBuilder::ForJSObjectInObjectProperty(boilerplate_map, index);
18071cb0ef41Sopenharmony_ci    Node* value = jsgraph()->HeapConstant(factory()->one_pointer_filler_map());
18081cb0ef41Sopenharmony_ci    inobject_fields.push_back(std::make_pair(access, value));
18091cb0ef41Sopenharmony_ci  }
18101cb0ef41Sopenharmony_ci
18111cb0ef41Sopenharmony_ci  // Setup the elements backing store.
18121cb0ef41Sopenharmony_ci  base::Optional<Node*> maybe_elements = TryAllocateFastLiteralElements(
18131cb0ef41Sopenharmony_ci      effect, control, boilerplate, allocation, max_depth, max_properties);
18141cb0ef41Sopenharmony_ci  if (!maybe_elements.has_value()) return {};
18151cb0ef41Sopenharmony_ci  Node* elements = maybe_elements.value();
18161cb0ef41Sopenharmony_ci  if (elements->op()->EffectOutputCount() > 0) effect = elements;
18171cb0ef41Sopenharmony_ci
18181cb0ef41Sopenharmony_ci  // Actually allocate and initialize the object.
18191cb0ef41Sopenharmony_ci  AllocationBuilder builder(jsgraph(), effect, control);
18201cb0ef41Sopenharmony_ci  builder.Allocate(boilerplate_map.instance_size(), allocation,
18211cb0ef41Sopenharmony_ci                   Type::For(boilerplate_map));
18221cb0ef41Sopenharmony_ci  builder.Store(AccessBuilder::ForMap(), boilerplate_map);
18231cb0ef41Sopenharmony_ci  builder.Store(AccessBuilder::ForJSObjectPropertiesOrHashKnownPointer(),
18241cb0ef41Sopenharmony_ci                jsgraph()->EmptyFixedArrayConstant());
18251cb0ef41Sopenharmony_ci  builder.Store(AccessBuilder::ForJSObjectElements(), elements);
18261cb0ef41Sopenharmony_ci  if (boilerplate.IsJSArray()) {
18271cb0ef41Sopenharmony_ci    JSArrayRef boilerplate_array = boilerplate.AsJSArray();
18281cb0ef41Sopenharmony_ci    builder.Store(AccessBuilder::ForJSArrayLength(
18291cb0ef41Sopenharmony_ci                      boilerplate_array.map().elements_kind()),
18301cb0ef41Sopenharmony_ci                  boilerplate_array.GetBoilerplateLength());
18311cb0ef41Sopenharmony_ci  }
18321cb0ef41Sopenharmony_ci  for (auto const& inobject_field : inobject_fields) {
18331cb0ef41Sopenharmony_ci    builder.Store(inobject_field.first, inobject_field.second);
18341cb0ef41Sopenharmony_ci  }
18351cb0ef41Sopenharmony_ci  return builder.Finish();
18361cb0ef41Sopenharmony_ci}
18371cb0ef41Sopenharmony_ci
18381cb0ef41Sopenharmony_cibase::Optional<Node*> JSCreateLowering::TryAllocateFastLiteralElements(
18391cb0ef41Sopenharmony_ci    Node* effect, Node* control, JSObjectRef boilerplate,
18401cb0ef41Sopenharmony_ci    AllocationType allocation, int max_depth, int* max_properties) {
18411cb0ef41Sopenharmony_ci  DCHECK_GT(max_depth, 0);
18421cb0ef41Sopenharmony_ci  DCHECK_GE(*max_properties, 0);
18431cb0ef41Sopenharmony_ci
18441cb0ef41Sopenharmony_ci  base::Optional<FixedArrayBaseRef> maybe_boilerplate_elements =
18451cb0ef41Sopenharmony_ci      boilerplate.elements(kRelaxedLoad);
18461cb0ef41Sopenharmony_ci  if (!maybe_boilerplate_elements.has_value()) return {};
18471cb0ef41Sopenharmony_ci  FixedArrayBaseRef boilerplate_elements = maybe_boilerplate_elements.value();
18481cb0ef41Sopenharmony_ci  // Protect against concurrent changes to the boilerplate object by checking
18491cb0ef41Sopenharmony_ci  // for an identical value at the end of the compilation.
18501cb0ef41Sopenharmony_ci  dependencies()->DependOnObjectSlotValue(
18511cb0ef41Sopenharmony_ci      boilerplate, JSObject::kElementsOffset, boilerplate_elements);
18521cb0ef41Sopenharmony_ci
18531cb0ef41Sopenharmony_ci  // Empty or copy-on-write elements just store a constant.
18541cb0ef41Sopenharmony_ci  int const elements_length = boilerplate_elements.length();
18551cb0ef41Sopenharmony_ci  MapRef elements_map = boilerplate_elements.map();
18561cb0ef41Sopenharmony_ci  // Protect against concurrent changes to the boilerplate object by checking
18571cb0ef41Sopenharmony_ci  // for an identical value at the end of the compilation.
18581cb0ef41Sopenharmony_ci  dependencies()->DependOnObjectSlotValue(boilerplate_elements,
18591cb0ef41Sopenharmony_ci                                          HeapObject::kMapOffset, elements_map);
18601cb0ef41Sopenharmony_ci  if (boilerplate_elements.length() == 0 || elements_map.IsFixedCowArrayMap()) {
18611cb0ef41Sopenharmony_ci    if (allocation == AllocationType::kOld &&
18621cb0ef41Sopenharmony_ci        !boilerplate.IsElementsTenured(boilerplate_elements)) {
18631cb0ef41Sopenharmony_ci      return {};
18641cb0ef41Sopenharmony_ci    }
18651cb0ef41Sopenharmony_ci    return jsgraph()->Constant(boilerplate_elements);
18661cb0ef41Sopenharmony_ci  }
18671cb0ef41Sopenharmony_ci
18681cb0ef41Sopenharmony_ci  // Compute the elements to store first (might have effects).
18691cb0ef41Sopenharmony_ci  ZoneVector<Node*> elements_values(elements_length, zone());
18701cb0ef41Sopenharmony_ci  if (boilerplate_elements.IsFixedDoubleArray()) {
18711cb0ef41Sopenharmony_ci    int const size = FixedDoubleArray::SizeFor(boilerplate_elements.length());
18721cb0ef41Sopenharmony_ci    if (size > kMaxRegularHeapObjectSize) return {};
18731cb0ef41Sopenharmony_ci
18741cb0ef41Sopenharmony_ci    FixedDoubleArrayRef elements = boilerplate_elements.AsFixedDoubleArray();
18751cb0ef41Sopenharmony_ci    for (int i = 0; i < elements_length; ++i) {
18761cb0ef41Sopenharmony_ci      Float64 value = elements.GetFromImmutableFixedDoubleArray(i);
18771cb0ef41Sopenharmony_ci      elements_values[i] = value.is_hole_nan()
18781cb0ef41Sopenharmony_ci                               ? jsgraph()->TheHoleConstant()
18791cb0ef41Sopenharmony_ci                               : jsgraph()->Constant(value.get_scalar());
18801cb0ef41Sopenharmony_ci    }
18811cb0ef41Sopenharmony_ci  } else {
18821cb0ef41Sopenharmony_ci    FixedArrayRef elements = boilerplate_elements.AsFixedArray();
18831cb0ef41Sopenharmony_ci    for (int i = 0; i < elements_length; ++i) {
18841cb0ef41Sopenharmony_ci      if ((*max_properties)-- == 0) return {};
18851cb0ef41Sopenharmony_ci      base::Optional<ObjectRef> element_value = elements.TryGet(i);
18861cb0ef41Sopenharmony_ci      if (!element_value.has_value()) return {};
18871cb0ef41Sopenharmony_ci      if (element_value->IsJSObject()) {
18881cb0ef41Sopenharmony_ci        base::Optional<Node*> object =
18891cb0ef41Sopenharmony_ci            TryAllocateFastLiteral(effect, control, element_value->AsJSObject(),
18901cb0ef41Sopenharmony_ci                                   allocation, max_depth - 1, max_properties);
18911cb0ef41Sopenharmony_ci        if (!object.has_value()) return {};
18921cb0ef41Sopenharmony_ci        elements_values[i] = effect = *object;
18931cb0ef41Sopenharmony_ci      } else {
18941cb0ef41Sopenharmony_ci        elements_values[i] = jsgraph()->Constant(*element_value);
18951cb0ef41Sopenharmony_ci      }
18961cb0ef41Sopenharmony_ci    }
18971cb0ef41Sopenharmony_ci  }
18981cb0ef41Sopenharmony_ci
18991cb0ef41Sopenharmony_ci  // Allocate the backing store array and store the elements.
19001cb0ef41Sopenharmony_ci  AllocationBuilder ab(jsgraph(), effect, control);
19011cb0ef41Sopenharmony_ci  CHECK(ab.CanAllocateArray(elements_length, elements_map, allocation));
19021cb0ef41Sopenharmony_ci  ab.AllocateArray(elements_length, elements_map, allocation);
19031cb0ef41Sopenharmony_ci  ElementAccess const access = boilerplate_elements.IsFixedDoubleArray()
19041cb0ef41Sopenharmony_ci                                   ? AccessBuilder::ForFixedDoubleArrayElement()
19051cb0ef41Sopenharmony_ci                                   : AccessBuilder::ForFixedArrayElement();
19061cb0ef41Sopenharmony_ci  for (int i = 0; i < elements_length; ++i) {
19071cb0ef41Sopenharmony_ci    ab.Store(access, jsgraph()->Constant(i), elements_values[i]);
19081cb0ef41Sopenharmony_ci  }
19091cb0ef41Sopenharmony_ci  return ab.Finish();
19101cb0ef41Sopenharmony_ci}
19111cb0ef41Sopenharmony_ci
19121cb0ef41Sopenharmony_ciNode* JSCreateLowering::AllocateLiteralRegExp(
19131cb0ef41Sopenharmony_ci    Node* effect, Node* control, RegExpBoilerplateDescriptionRef boilerplate) {
19141cb0ef41Sopenharmony_ci  MapRef initial_map =
19151cb0ef41Sopenharmony_ci      native_context().regexp_function().initial_map(dependencies());
19161cb0ef41Sopenharmony_ci
19171cb0ef41Sopenharmony_ci  // Sanity check that JSRegExp object layout hasn't changed.
19181cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSRegExp::kDataOffset == JSObject::kHeaderSize);
19191cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSRegExp::kSourceOffset == JSRegExp::kDataOffset + kTaggedSize);
19201cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSRegExp::kFlagsOffset ==
19211cb0ef41Sopenharmony_ci                JSRegExp::kSourceOffset + kTaggedSize);
19221cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSRegExp::kHeaderSize == JSRegExp::kFlagsOffset + kTaggedSize);
19231cb0ef41Sopenharmony_ci  STATIC_ASSERT(JSRegExp::kLastIndexOffset == JSRegExp::kHeaderSize);
19241cb0ef41Sopenharmony_ci  DCHECK_EQ(JSRegExp::Size(), JSRegExp::kLastIndexOffset + kTaggedSize);
19251cb0ef41Sopenharmony_ci
19261cb0ef41Sopenharmony_ci  AllocationBuilder builder(jsgraph(), effect, control);
19271cb0ef41Sopenharmony_ci  builder.Allocate(JSRegExp::Size(), AllocationType::kYoung,
19281cb0ef41Sopenharmony_ci                   Type::For(initial_map));
19291cb0ef41Sopenharmony_ci  builder.Store(AccessBuilder::ForMap(), initial_map);
19301cb0ef41Sopenharmony_ci  builder.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
19311cb0ef41Sopenharmony_ci                jsgraph()->EmptyFixedArrayConstant());
19321cb0ef41Sopenharmony_ci  builder.Store(AccessBuilder::ForJSObjectElements(),
19331cb0ef41Sopenharmony_ci                jsgraph()->EmptyFixedArrayConstant());
19341cb0ef41Sopenharmony_ci
19351cb0ef41Sopenharmony_ci  builder.Store(AccessBuilder::ForJSRegExpData(), boilerplate.data());
19361cb0ef41Sopenharmony_ci  builder.Store(AccessBuilder::ForJSRegExpSource(), boilerplate.source());
19371cb0ef41Sopenharmony_ci  builder.Store(AccessBuilder::ForJSRegExpFlags(),
19381cb0ef41Sopenharmony_ci                jsgraph()->SmiConstant(boilerplate.flags()));
19391cb0ef41Sopenharmony_ci  builder.Store(AccessBuilder::ForJSRegExpLastIndex(),
19401cb0ef41Sopenharmony_ci                jsgraph()->SmiConstant(JSRegExp::kInitialLastIndexValue));
19411cb0ef41Sopenharmony_ci
19421cb0ef41Sopenharmony_ci  return builder.Finish();
19431cb0ef41Sopenharmony_ci}
19441cb0ef41Sopenharmony_ci
19451cb0ef41Sopenharmony_ciFactory* JSCreateLowering::factory() const {
19461cb0ef41Sopenharmony_ci  return jsgraph()->isolate()->factory();
19471cb0ef41Sopenharmony_ci}
19481cb0ef41Sopenharmony_ci
19491cb0ef41Sopenharmony_ciGraph* JSCreateLowering::graph() const { return jsgraph()->graph(); }
19501cb0ef41Sopenharmony_ci
19511cb0ef41Sopenharmony_ciCommonOperatorBuilder* JSCreateLowering::common() const {
19521cb0ef41Sopenharmony_ci  return jsgraph()->common();
19531cb0ef41Sopenharmony_ci}
19541cb0ef41Sopenharmony_ci
19551cb0ef41Sopenharmony_ciSimplifiedOperatorBuilder* JSCreateLowering::simplified() const {
19561cb0ef41Sopenharmony_ci  return jsgraph()->simplified();
19571cb0ef41Sopenharmony_ci}
19581cb0ef41Sopenharmony_ci
19591cb0ef41Sopenharmony_ciNativeContextRef JSCreateLowering::native_context() const {
19601cb0ef41Sopenharmony_ci  return broker()->target_native_context();
19611cb0ef41Sopenharmony_ci}
19621cb0ef41Sopenharmony_ci
19631cb0ef41Sopenharmony_ci}  // namespace compiler
19641cb0ef41Sopenharmony_ci}  // namespace internal
19651cb0ef41Sopenharmony_ci}  // namespace v8
1966