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