11cb0ef41Sopenharmony_ci// Copyright 2014 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-generic-lowering.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include "src/ast/ast.h" 81cb0ef41Sopenharmony_ci#include "src/builtins/builtins-constructor.h" 91cb0ef41Sopenharmony_ci#include "src/codegen/code-factory.h" 101cb0ef41Sopenharmony_ci#include "src/codegen/interface-descriptors-inl.h" 111cb0ef41Sopenharmony_ci#include "src/compiler/access-builder.h" 121cb0ef41Sopenharmony_ci#include "src/compiler/common-operator.h" 131cb0ef41Sopenharmony_ci#include "src/compiler/js-graph.h" 141cb0ef41Sopenharmony_ci#include "src/compiler/js-heap-broker.h" 151cb0ef41Sopenharmony_ci#include "src/compiler/machine-operator.h" 161cb0ef41Sopenharmony_ci#include "src/compiler/node-matchers.h" 171cb0ef41Sopenharmony_ci#include "src/compiler/node-properties.h" 181cb0ef41Sopenharmony_ci#include "src/compiler/operator-properties.h" 191cb0ef41Sopenharmony_ci#include "src/compiler/processed-feedback.h" 201cb0ef41Sopenharmony_ci#include "src/compiler/simplified-operator.h" 211cb0ef41Sopenharmony_ci#include "src/objects/feedback-cell.h" 221cb0ef41Sopenharmony_ci#include "src/objects/feedback-vector.h" 231cb0ef41Sopenharmony_ci#include "src/objects/scope-info.h" 241cb0ef41Sopenharmony_ci#include "src/objects/template-objects-inl.h" 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_cinamespace v8 { 271cb0ef41Sopenharmony_cinamespace internal { 281cb0ef41Sopenharmony_cinamespace compiler { 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_cinamespace { 311cb0ef41Sopenharmony_ci 321cb0ef41Sopenharmony_ciCallDescriptor::Flags FrameStateFlagForCall(Node* node) { 331cb0ef41Sopenharmony_ci return OperatorProperties::HasFrameStateInput(node->op()) 341cb0ef41Sopenharmony_ci ? CallDescriptor::kNeedsFrameState 351cb0ef41Sopenharmony_ci : CallDescriptor::kNoFlags; 361cb0ef41Sopenharmony_ci} 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci} // namespace 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ciJSGenericLowering::JSGenericLowering(JSGraph* jsgraph, Editor* editor, 411cb0ef41Sopenharmony_ci JSHeapBroker* broker) 421cb0ef41Sopenharmony_ci : AdvancedReducer(editor), jsgraph_(jsgraph), broker_(broker) {} 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ciJSGenericLowering::~JSGenericLowering() = default; 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ciReduction JSGenericLowering::Reduce(Node* node) { 481cb0ef41Sopenharmony_ci switch (node->opcode()) { 491cb0ef41Sopenharmony_ci#define DECLARE_CASE(x, ...) \ 501cb0ef41Sopenharmony_ci case IrOpcode::k##x: \ 511cb0ef41Sopenharmony_ci Lower##x(node); \ 521cb0ef41Sopenharmony_ci break; 531cb0ef41Sopenharmony_ci JS_OP_LIST(DECLARE_CASE) 541cb0ef41Sopenharmony_ci#undef DECLARE_CASE 551cb0ef41Sopenharmony_ci default: 561cb0ef41Sopenharmony_ci // Nothing to see. 571cb0ef41Sopenharmony_ci return NoChange(); 581cb0ef41Sopenharmony_ci } 591cb0ef41Sopenharmony_ci return Changed(node); 601cb0ef41Sopenharmony_ci} 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci#define REPLACE_STUB_CALL(Name) \ 631cb0ef41Sopenharmony_ci void JSGenericLowering::LowerJS##Name(Node* node) { \ 641cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::k##Name); \ 651cb0ef41Sopenharmony_ci } 661cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ToLength) 671cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ToNumber) 681cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ToNumberConvertBigInt) 691cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ToNumeric) 701cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ToName) 711cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ToObject) 721cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ToString) 731cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ForInEnumerate) 741cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(AsyncFunctionEnter) 751cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(AsyncFunctionReject) 761cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(AsyncFunctionResolve) 771cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(FulfillPromise) 781cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(PerformPromiseThen) 791cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(PromiseResolve) 801cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(RejectPromise) 811cb0ef41Sopenharmony_ciREPLACE_STUB_CALL(ResolvePromise) 821cb0ef41Sopenharmony_ci#undef REPLACE_STUB_CALL 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_civoid JSGenericLowering::ReplaceWithBuiltinCall(Node* node, Builtin builtin) { 851cb0ef41Sopenharmony_ci CallDescriptor::Flags flags = FrameStateFlagForCall(node); 861cb0ef41Sopenharmony_ci Callable callable = Builtins::CallableFor(isolate(), builtin); 871cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, callable, flags); 881cb0ef41Sopenharmony_ci} 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_civoid JSGenericLowering::ReplaceWithBuiltinCall(Node* node, Callable callable, 911cb0ef41Sopenharmony_ci CallDescriptor::Flags flags) { 921cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, callable, flags, node->op()->properties()); 931cb0ef41Sopenharmony_ci} 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_civoid JSGenericLowering::ReplaceWithBuiltinCall( 961cb0ef41Sopenharmony_ci Node* node, Callable callable, CallDescriptor::Flags flags, 971cb0ef41Sopenharmony_ci Operator::Properties properties) { 981cb0ef41Sopenharmony_ci const CallInterfaceDescriptor& descriptor = callable.descriptor(); 991cb0ef41Sopenharmony_ci auto call_descriptor = Linkage::GetStubCallDescriptor( 1001cb0ef41Sopenharmony_ci zone(), descriptor, descriptor.GetStackParameterCount(), flags, 1011cb0ef41Sopenharmony_ci properties); 1021cb0ef41Sopenharmony_ci Node* stub_code = jsgraph()->HeapConstant(callable.code()); 1031cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, stub_code); 1041cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); 1051cb0ef41Sopenharmony_ci} 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_civoid JSGenericLowering::ReplaceWithRuntimeCall(Node* node, 1081cb0ef41Sopenharmony_ci Runtime::FunctionId f, 1091cb0ef41Sopenharmony_ci int nargs_override) { 1101cb0ef41Sopenharmony_ci CallDescriptor::Flags flags = FrameStateFlagForCall(node); 1111cb0ef41Sopenharmony_ci Operator::Properties properties = node->op()->properties(); 1121cb0ef41Sopenharmony_ci const Runtime::Function* fun = Runtime::FunctionForId(f); 1131cb0ef41Sopenharmony_ci int nargs = (nargs_override < 0) ? fun->nargs : nargs_override; 1141cb0ef41Sopenharmony_ci auto call_descriptor = 1151cb0ef41Sopenharmony_ci Linkage::GetRuntimeCallDescriptor(zone(), f, nargs, properties, flags); 1161cb0ef41Sopenharmony_ci Node* ref = jsgraph()->ExternalConstant(ExternalReference::Create(f)); 1171cb0ef41Sopenharmony_ci Node* arity = jsgraph()->Int32Constant(nargs); 1181cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, jsgraph()->CEntryStubConstant(fun->result_size)); 1191cb0ef41Sopenharmony_ci node->InsertInput(zone(), nargs + 1, ref); 1201cb0ef41Sopenharmony_ci node->InsertInput(zone(), nargs + 2, arity); 1211cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); 1221cb0ef41Sopenharmony_ci} 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_civoid JSGenericLowering::ReplaceUnaryOpWithBuiltinCall( 1251cb0ef41Sopenharmony_ci Node* node, Builtin builtin_without_feedback, 1261cb0ef41Sopenharmony_ci Builtin builtin_with_feedback) { 1271cb0ef41Sopenharmony_ci DCHECK(JSOperator::IsUnaryWithFeedback(node->opcode())); 1281cb0ef41Sopenharmony_ci const FeedbackParameter& p = FeedbackParameterOf(node->op()); 1291cb0ef41Sopenharmony_ci if (CollectFeedbackInGenericLowering() && p.feedback().IsValid()) { 1301cb0ef41Sopenharmony_ci Callable callable = Builtins::CallableFor(isolate(), builtin_with_feedback); 1311cb0ef41Sopenharmony_ci Node* slot = jsgraph()->UintPtrConstant(p.feedback().slot.ToInt()); 1321cb0ef41Sopenharmony_ci const CallInterfaceDescriptor& descriptor = callable.descriptor(); 1331cb0ef41Sopenharmony_ci CallDescriptor::Flags flags = FrameStateFlagForCall(node); 1341cb0ef41Sopenharmony_ci auto call_descriptor = Linkage::GetStubCallDescriptor( 1351cb0ef41Sopenharmony_ci zone(), descriptor, descriptor.GetStackParameterCount(), flags, 1361cb0ef41Sopenharmony_ci node->op()->properties()); 1371cb0ef41Sopenharmony_ci Node* stub_code = jsgraph()->HeapConstant(callable.code()); 1381cb0ef41Sopenharmony_ci STATIC_ASSERT(JSUnaryOpNode::ValueIndex() == 0); 1391cb0ef41Sopenharmony_ci STATIC_ASSERT(JSUnaryOpNode::FeedbackVectorIndex() == 1); 1401cb0ef41Sopenharmony_ci DCHECK_EQ(node->op()->ValueInputCount(), 2); 1411cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, stub_code); 1421cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, slot); 1431cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); 1441cb0ef41Sopenharmony_ci } else { 1451cb0ef41Sopenharmony_ci node->RemoveInput(JSUnaryOpNode::FeedbackVectorIndex()); 1461cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, builtin_without_feedback); 1471cb0ef41Sopenharmony_ci } 1481cb0ef41Sopenharmony_ci} 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci#define DEF_UNARY_LOWERING(Name) \ 1511cb0ef41Sopenharmony_ci void JSGenericLowering::LowerJS##Name(Node* node) { \ 1521cb0ef41Sopenharmony_ci ReplaceUnaryOpWithBuiltinCall(node, Builtin::k##Name, \ 1531cb0ef41Sopenharmony_ci Builtin::k##Name##_WithFeedback); \ 1541cb0ef41Sopenharmony_ci } 1551cb0ef41Sopenharmony_ciDEF_UNARY_LOWERING(BitwiseNot) 1561cb0ef41Sopenharmony_ciDEF_UNARY_LOWERING(Decrement) 1571cb0ef41Sopenharmony_ciDEF_UNARY_LOWERING(Increment) 1581cb0ef41Sopenharmony_ciDEF_UNARY_LOWERING(Negate) 1591cb0ef41Sopenharmony_ci#undef DEF_UNARY_LOWERING 1601cb0ef41Sopenharmony_ci 1611cb0ef41Sopenharmony_civoid JSGenericLowering::ReplaceBinaryOpWithBuiltinCall( 1621cb0ef41Sopenharmony_ci Node* node, Builtin builtin_without_feedback, 1631cb0ef41Sopenharmony_ci Builtin builtin_with_feedback) { 1641cb0ef41Sopenharmony_ci DCHECK(JSOperator::IsBinaryWithFeedback(node->opcode())); 1651cb0ef41Sopenharmony_ci Builtin builtin; 1661cb0ef41Sopenharmony_ci const FeedbackParameter& p = FeedbackParameterOf(node->op()); 1671cb0ef41Sopenharmony_ci if (CollectFeedbackInGenericLowering() && p.feedback().IsValid()) { 1681cb0ef41Sopenharmony_ci Node* slot = jsgraph()->UintPtrConstant(p.feedback().slot.ToInt()); 1691cb0ef41Sopenharmony_ci STATIC_ASSERT(JSBinaryOpNode::LeftIndex() == 0); 1701cb0ef41Sopenharmony_ci STATIC_ASSERT(JSBinaryOpNode::RightIndex() == 1); 1711cb0ef41Sopenharmony_ci STATIC_ASSERT(JSBinaryOpNode::FeedbackVectorIndex() == 2); 1721cb0ef41Sopenharmony_ci DCHECK_EQ(node->op()->ValueInputCount(), 3); 1731cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, slot); 1741cb0ef41Sopenharmony_ci builtin = builtin_with_feedback; 1751cb0ef41Sopenharmony_ci } else { 1761cb0ef41Sopenharmony_ci node->RemoveInput(JSBinaryOpNode::FeedbackVectorIndex()); 1771cb0ef41Sopenharmony_ci builtin = builtin_without_feedback; 1781cb0ef41Sopenharmony_ci } 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, builtin); 1811cb0ef41Sopenharmony_ci} 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci#define DEF_BINARY_LOWERING(Name) \ 1841cb0ef41Sopenharmony_ci void JSGenericLowering::LowerJS##Name(Node* node) { \ 1851cb0ef41Sopenharmony_ci ReplaceBinaryOpWithBuiltinCall(node, Builtin::k##Name, \ 1861cb0ef41Sopenharmony_ci Builtin::k##Name##_WithFeedback); \ 1871cb0ef41Sopenharmony_ci } 1881cb0ef41Sopenharmony_ci// Binary ops. 1891cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(Add) 1901cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(BitwiseAnd) 1911cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(BitwiseOr) 1921cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(BitwiseXor) 1931cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(Divide) 1941cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(Exponentiate) 1951cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(Modulus) 1961cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(Multiply) 1971cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(ShiftLeft) 1981cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(ShiftRight) 1991cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(ShiftRightLogical) 2001cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(Subtract) 2011cb0ef41Sopenharmony_ci// Compare ops. 2021cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(Equal) 2031cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(GreaterThan) 2041cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(GreaterThanOrEqual) 2051cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(InstanceOf) 2061cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(LessThan) 2071cb0ef41Sopenharmony_ciDEF_BINARY_LOWERING(LessThanOrEqual) 2081cb0ef41Sopenharmony_ci#undef DEF_BINARY_LOWERING 2091cb0ef41Sopenharmony_ci 2101cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSStrictEqual(Node* node) { 2111cb0ef41Sopenharmony_ci // The === operator doesn't need the current context. 2121cb0ef41Sopenharmony_ci NodeProperties::ReplaceContextInput(node, jsgraph()->NoContextConstant()); 2131cb0ef41Sopenharmony_ci DCHECK_EQ(node->op()->ControlInputCount(), 1); 2141cb0ef41Sopenharmony_ci node->RemoveInput(NodeProperties::FirstControlIndex(node)); 2151cb0ef41Sopenharmony_ci 2161cb0ef41Sopenharmony_ci Builtin builtin; 2171cb0ef41Sopenharmony_ci const FeedbackParameter& p = FeedbackParameterOf(node->op()); 2181cb0ef41Sopenharmony_ci if (CollectFeedbackInGenericLowering() && p.feedback().IsValid()) { 2191cb0ef41Sopenharmony_ci Node* slot = jsgraph()->UintPtrConstant(p.feedback().slot.ToInt()); 2201cb0ef41Sopenharmony_ci STATIC_ASSERT(JSStrictEqualNode::LeftIndex() == 0); 2211cb0ef41Sopenharmony_ci STATIC_ASSERT(JSStrictEqualNode::RightIndex() == 1); 2221cb0ef41Sopenharmony_ci STATIC_ASSERT(JSStrictEqualNode::FeedbackVectorIndex() == 2); 2231cb0ef41Sopenharmony_ci DCHECK_EQ(node->op()->ValueInputCount(), 3); 2241cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, slot); 2251cb0ef41Sopenharmony_ci builtin = Builtin::kStrictEqual_WithFeedback; 2261cb0ef41Sopenharmony_ci } else { 2271cb0ef41Sopenharmony_ci node->RemoveInput(JSStrictEqualNode::FeedbackVectorIndex()); 2281cb0ef41Sopenharmony_ci builtin = Builtin::kStrictEqual; 2291cb0ef41Sopenharmony_ci } 2301cb0ef41Sopenharmony_ci 2311cb0ef41Sopenharmony_ci Callable callable = Builtins::CallableFor(isolate(), builtin); 2321cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, callable, CallDescriptor::kNoFlags, 2331cb0ef41Sopenharmony_ci Operator::kEliminatable); 2341cb0ef41Sopenharmony_ci} 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_cinamespace { 2371cb0ef41Sopenharmony_ci 2381cb0ef41Sopenharmony_ci// The megamorphic load builtin can be used as a performance optimization in 2391cb0ef41Sopenharmony_ci// some cases - unlike the full builtin, the megamorphic builtin does fewer 2401cb0ef41Sopenharmony_ci// checks and does not collect feedback. 2411cb0ef41Sopenharmony_cibool ShouldUseMegamorphicLoadBuiltin(FeedbackSource const& source, 2421cb0ef41Sopenharmony_ci base::Optional<NameRef> name, 2431cb0ef41Sopenharmony_ci JSHeapBroker* broker) { 2441cb0ef41Sopenharmony_ci ProcessedFeedback const& feedback = 2451cb0ef41Sopenharmony_ci broker->GetFeedbackForPropertyAccess(source, AccessMode::kLoad, name); 2461cb0ef41Sopenharmony_ci 2471cb0ef41Sopenharmony_ci if (feedback.kind() == ProcessedFeedback::kElementAccess) { 2481cb0ef41Sopenharmony_ci return feedback.AsElementAccess().transition_groups().empty(); 2491cb0ef41Sopenharmony_ci } else if (feedback.kind() == ProcessedFeedback::kNamedAccess) { 2501cb0ef41Sopenharmony_ci return feedback.AsNamedAccess().maps().empty(); 2511cb0ef41Sopenharmony_ci } else if (feedback.kind() == ProcessedFeedback::kInsufficient) { 2521cb0ef41Sopenharmony_ci return false; 2531cb0ef41Sopenharmony_ci } 2541cb0ef41Sopenharmony_ci UNREACHABLE(); 2551cb0ef41Sopenharmony_ci} 2561cb0ef41Sopenharmony_ci 2571cb0ef41Sopenharmony_ci} // namespace 2581cb0ef41Sopenharmony_ci 2591cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSHasProperty(Node* node) { 2601cb0ef41Sopenharmony_ci JSHasPropertyNode n(node); 2611cb0ef41Sopenharmony_ci const PropertyAccess& p = n.Parameters(); 2621cb0ef41Sopenharmony_ci if (!p.feedback().IsValid()) { 2631cb0ef41Sopenharmony_ci node->RemoveInput(JSHasPropertyNode::FeedbackVectorIndex()); 2641cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kHasProperty); 2651cb0ef41Sopenharmony_ci } else { 2661cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 2); 2671cb0ef41Sopenharmony_ci n->InsertInput(zone(), 2, 2681cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 2691cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kKeyedHasIC); 2701cb0ef41Sopenharmony_ci } 2711cb0ef41Sopenharmony_ci} 2721cb0ef41Sopenharmony_ci 2731cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSLoadProperty(Node* node) { 2741cb0ef41Sopenharmony_ci JSLoadPropertyNode n(node); 2751cb0ef41Sopenharmony_ci const PropertyAccess& p = n.Parameters(); 2761cb0ef41Sopenharmony_ci FrameState frame_state = n.frame_state(); 2771cb0ef41Sopenharmony_ci Node* outer_state = frame_state.outer_frame_state(); 2781cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 2); 2791cb0ef41Sopenharmony_ci if (outer_state->opcode() != IrOpcode::kFrameState) { 2801cb0ef41Sopenharmony_ci n->RemoveInput(n.FeedbackVectorIndex()); 2811cb0ef41Sopenharmony_ci n->InsertInput(zone(), 2, 2821cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 2831cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall( 2841cb0ef41Sopenharmony_ci node, ShouldUseMegamorphicLoadBuiltin(p.feedback(), {}, broker()) 2851cb0ef41Sopenharmony_ci ? Builtin::kKeyedLoadICTrampoline_Megamorphic 2861cb0ef41Sopenharmony_ci : Builtin::kKeyedLoadICTrampoline); 2871cb0ef41Sopenharmony_ci } else { 2881cb0ef41Sopenharmony_ci n->InsertInput(zone(), 2, 2891cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 2901cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall( 2911cb0ef41Sopenharmony_ci node, ShouldUseMegamorphicLoadBuiltin(p.feedback(), {}, broker()) 2921cb0ef41Sopenharmony_ci ? Builtin::kKeyedLoadIC_Megamorphic 2931cb0ef41Sopenharmony_ci : Builtin::kKeyedLoadIC); 2941cb0ef41Sopenharmony_ci } 2951cb0ef41Sopenharmony_ci} 2961cb0ef41Sopenharmony_ci 2971cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSLoadNamed(Node* node) { 2981cb0ef41Sopenharmony_ci JSLoadNamedNode n(node); 2991cb0ef41Sopenharmony_ci NamedAccess const& p = n.Parameters(); 3001cb0ef41Sopenharmony_ci FrameState frame_state = n.frame_state(); 3011cb0ef41Sopenharmony_ci Node* outer_state = frame_state.outer_frame_state(); 3021cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 1); 3031cb0ef41Sopenharmony_ci if (!p.feedback().IsValid()) { 3041cb0ef41Sopenharmony_ci n->RemoveInput(n.FeedbackVectorIndex()); 3051cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker()))); 3061cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kGetProperty); 3071cb0ef41Sopenharmony_ci } else if (outer_state->opcode() != IrOpcode::kFrameState) { 3081cb0ef41Sopenharmony_ci n->RemoveInput(n.FeedbackVectorIndex()); 3091cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker()))); 3101cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, 3111cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 3121cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, ShouldUseMegamorphicLoadBuiltin( 3131cb0ef41Sopenharmony_ci p.feedback(), p.name(broker()), broker()) 3141cb0ef41Sopenharmony_ci ? Builtin::kLoadICTrampoline_Megamorphic 3151cb0ef41Sopenharmony_ci : Builtin::kLoadICTrampoline); 3161cb0ef41Sopenharmony_ci } else { 3171cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker()))); 3181cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, 3191cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 3201cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, ShouldUseMegamorphicLoadBuiltin( 3211cb0ef41Sopenharmony_ci p.feedback(), p.name(broker()), broker()) 3221cb0ef41Sopenharmony_ci ? Builtin::kLoadIC_Megamorphic 3231cb0ef41Sopenharmony_ci : Builtin::kLoadIC); 3241cb0ef41Sopenharmony_ci } 3251cb0ef41Sopenharmony_ci} 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSLoadNamedFromSuper(Node* node) { 3281cb0ef41Sopenharmony_ci JSLoadNamedFromSuperNode n(node); 3291cb0ef41Sopenharmony_ci NamedAccess const& p = n.Parameters(); 3301cb0ef41Sopenharmony_ci Node* effect = NodeProperties::GetEffectInput(node); 3311cb0ef41Sopenharmony_ci Node* control = NodeProperties::GetControlInput(node); 3321cb0ef41Sopenharmony_ci // Node inputs: receiver, home object, FeedbackVector. 3331cb0ef41Sopenharmony_ci // LoadSuperIC expects: receiver, lookup start object, name, slot, 3341cb0ef41Sopenharmony_ci // FeedbackVector. 3351cb0ef41Sopenharmony_ci Node* home_object_map = effect = graph()->NewNode( 3361cb0ef41Sopenharmony_ci jsgraph()->simplified()->LoadField(AccessBuilder::ForMap()), 3371cb0ef41Sopenharmony_ci n.home_object(), effect, control); 3381cb0ef41Sopenharmony_ci Node* home_object_proto = effect = graph()->NewNode( 3391cb0ef41Sopenharmony_ci jsgraph()->simplified()->LoadField(AccessBuilder::ForMapPrototype()), 3401cb0ef41Sopenharmony_ci home_object_map, effect, control); 3411cb0ef41Sopenharmony_ci n->ReplaceInput(n.HomeObjectIndex(), home_object_proto); 3421cb0ef41Sopenharmony_ci NodeProperties::ReplaceEffectInput(node, effect); 3431cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 2); 3441cb0ef41Sopenharmony_ci // If the code below will be used for the invalid feedback case, it needs to 3451cb0ef41Sopenharmony_ci // be double-checked that the FeedbackVector parameter will be the 3461cb0ef41Sopenharmony_ci // UndefinedConstant. 3471cb0ef41Sopenharmony_ci DCHECK(p.feedback().IsValid()); 3481cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, jsgraph()->Constant(p.name(broker()))); 3491cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, 3501cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 3511cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kLoadSuperIC); 3521cb0ef41Sopenharmony_ci} 3531cb0ef41Sopenharmony_ci 3541cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSLoadGlobal(Node* node) { 3551cb0ef41Sopenharmony_ci JSLoadGlobalNode n(node); 3561cb0ef41Sopenharmony_ci const LoadGlobalParameters& p = n.Parameters(); 3571cb0ef41Sopenharmony_ci CallDescriptor::Flags flags = FrameStateFlagForCall(node); 3581cb0ef41Sopenharmony_ci FrameState frame_state = n.frame_state(); 3591cb0ef41Sopenharmony_ci Node* outer_state = frame_state.outer_frame_state(); 3601cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 0); 3611cb0ef41Sopenharmony_ci if (outer_state->opcode() != IrOpcode::kFrameState) { 3621cb0ef41Sopenharmony_ci n->RemoveInput(n.FeedbackVectorIndex()); 3631cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, jsgraph()->Constant(p.name(broker()))); 3641cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, 3651cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 3661cb0ef41Sopenharmony_ci Callable callable = CodeFactory::LoadGlobalIC(isolate(), p.typeof_mode()); 3671cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, callable, flags); 3681cb0ef41Sopenharmony_ci } else { 3691cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, jsgraph()->Constant(p.name(broker()))); 3701cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, 3711cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 3721cb0ef41Sopenharmony_ci Callable callable = 3731cb0ef41Sopenharmony_ci CodeFactory::LoadGlobalICInOptimizedCode(isolate(), p.typeof_mode()); 3741cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, callable, flags); 3751cb0ef41Sopenharmony_ci } 3761cb0ef41Sopenharmony_ci} 3771cb0ef41Sopenharmony_ci 3781cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGetIterator(Node* node) { 3791cb0ef41Sopenharmony_ci // TODO(v8:9625): Currently, the GetIterator operator is desugared in the 3801cb0ef41Sopenharmony_ci // native context specialization phase. Thus, the following generic lowering 3811cb0ef41Sopenharmony_ci // is not reachable unless that phase is disabled (e.g. for 3821cb0ef41Sopenharmony_ci // native-context-independent code). 3831cb0ef41Sopenharmony_ci // We can add a check in native context specialization to avoid desugaring 3841cb0ef41Sopenharmony_ci // the GetIterator operator when feedback is megamorphic. This would reduce 3851cb0ef41Sopenharmony_ci // the size of the compiled code as it would insert 1 call to the builtin 3861cb0ef41Sopenharmony_ci // instead of 2 calls resulting from the generic lowering of the LoadNamed 3871cb0ef41Sopenharmony_ci // and Call operators. 3881cb0ef41Sopenharmony_ci 3891cb0ef41Sopenharmony_ci JSGetIteratorNode n(node); 3901cb0ef41Sopenharmony_ci GetIteratorParameters const& p = n.Parameters(); 3911cb0ef41Sopenharmony_ci Node* load_slot = 3921cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.loadFeedback().slot.ToInt()); 3931cb0ef41Sopenharmony_ci Node* call_slot = 3941cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.callFeedback().slot.ToInt()); 3951cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 1); 3961cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, load_slot); 3971cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, call_slot); 3981cb0ef41Sopenharmony_ci 3991cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kGetIteratorWithFeedback); 4001cb0ef41Sopenharmony_ci} 4011cb0ef41Sopenharmony_ci 4021cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSSetKeyedProperty(Node* node) { 4031cb0ef41Sopenharmony_ci JSSetKeyedPropertyNode n(node); 4041cb0ef41Sopenharmony_ci const PropertyAccess& p = n.Parameters(); 4051cb0ef41Sopenharmony_ci FrameState frame_state = n.frame_state(); 4061cb0ef41Sopenharmony_ci Node* outer_state = frame_state.outer_frame_state(); 4071cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 3); 4081cb0ef41Sopenharmony_ci if (outer_state->opcode() != IrOpcode::kFrameState) { 4091cb0ef41Sopenharmony_ci n->RemoveInput(n.FeedbackVectorIndex()); 4101cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, 4111cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 4121cb0ef41Sopenharmony_ci 4131cb0ef41Sopenharmony_ci // KeyedStoreIC is currently a base class for multiple keyed property store 4141cb0ef41Sopenharmony_ci // operations and contains mixed logic for set and define operations, 4151cb0ef41Sopenharmony_ci // the paths are controlled by feedback. 4161cb0ef41Sopenharmony_ci // TODO(v8:12548): refactor SetKeyedIC as a subclass of KeyedStoreIC, which 4171cb0ef41Sopenharmony_ci // can be called here. 4181cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kKeyedStoreICTrampoline); 4191cb0ef41Sopenharmony_ci } else { 4201cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, 4211cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 4221cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kKeyedStoreIC); 4231cb0ef41Sopenharmony_ci } 4241cb0ef41Sopenharmony_ci} 4251cb0ef41Sopenharmony_ci 4261cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSDefineKeyedOwnProperty(Node* node) { 4271cb0ef41Sopenharmony_ci JSDefineKeyedOwnPropertyNode n(node); 4281cb0ef41Sopenharmony_ci const PropertyAccess& p = n.Parameters(); 4291cb0ef41Sopenharmony_ci FrameState frame_state = n.frame_state(); 4301cb0ef41Sopenharmony_ci Node* outer_state = frame_state.outer_frame_state(); 4311cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 3); 4321cb0ef41Sopenharmony_ci if (outer_state->opcode() != IrOpcode::kFrameState) { 4331cb0ef41Sopenharmony_ci n->RemoveInput(n.FeedbackVectorIndex()); 4341cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, 4351cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 4361cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kDefineKeyedOwnICTrampoline); 4371cb0ef41Sopenharmony_ci } else { 4381cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, 4391cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 4401cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kDefineKeyedOwnIC); 4411cb0ef41Sopenharmony_ci } 4421cb0ef41Sopenharmony_ci} 4431cb0ef41Sopenharmony_ci 4441cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSSetNamedProperty(Node* node) { 4451cb0ef41Sopenharmony_ci JSSetNamedPropertyNode n(node); 4461cb0ef41Sopenharmony_ci NamedAccess const& p = n.Parameters(); 4471cb0ef41Sopenharmony_ci FrameState frame_state = n.frame_state(); 4481cb0ef41Sopenharmony_ci Node* outer_state = frame_state.outer_frame_state(); 4491cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 2); 4501cb0ef41Sopenharmony_ci if (!p.feedback().IsValid()) { 4511cb0ef41Sopenharmony_ci n->RemoveInput(n.FeedbackVectorIndex()); 4521cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker()))); 4531cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kSetNamedProperty); 4541cb0ef41Sopenharmony_ci } else if (outer_state->opcode() != IrOpcode::kFrameState) { 4551cb0ef41Sopenharmony_ci n->RemoveInput(n.FeedbackVectorIndex()); 4561cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker()))); 4571cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, 4581cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 4591cb0ef41Sopenharmony_ci // StoreIC is currently a base class for multiple property store operations 4601cb0ef41Sopenharmony_ci // and contains mixed logic for named and keyed, set and define operations, 4611cb0ef41Sopenharmony_ci // the paths are controlled by feedback. 4621cb0ef41Sopenharmony_ci // TODO(v8:12548): refactor SetNamedIC as a subclass of StoreIC, which can 4631cb0ef41Sopenharmony_ci // be called here. 4641cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kStoreICTrampoline); 4651cb0ef41Sopenharmony_ci } else { 4661cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker()))); 4671cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, 4681cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 4691cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kStoreIC); 4701cb0ef41Sopenharmony_ci } 4711cb0ef41Sopenharmony_ci} 4721cb0ef41Sopenharmony_ci 4731cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSDefineNamedOwnProperty(Node* node) { 4741cb0ef41Sopenharmony_ci CallDescriptor::Flags flags = FrameStateFlagForCall(node); 4751cb0ef41Sopenharmony_ci JSDefineNamedOwnPropertyNode n(node); 4761cb0ef41Sopenharmony_ci DefineNamedOwnPropertyParameters const& p = n.Parameters(); 4771cb0ef41Sopenharmony_ci FrameState frame_state = n.frame_state(); 4781cb0ef41Sopenharmony_ci Node* outer_state = frame_state.outer_frame_state(); 4791cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 2); 4801cb0ef41Sopenharmony_ci if (outer_state->opcode() != IrOpcode::kFrameState) { 4811cb0ef41Sopenharmony_ci n->RemoveInput(n.FeedbackVectorIndex()); 4821cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker()))); 4831cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, 4841cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 4851cb0ef41Sopenharmony_ci Callable callable = CodeFactory::DefineNamedOwnIC(isolate()); 4861cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, callable, flags); 4871cb0ef41Sopenharmony_ci } else { 4881cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, jsgraph()->Constant(p.name(broker()))); 4891cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, 4901cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 4911cb0ef41Sopenharmony_ci Callable callable = CodeFactory::DefineNamedOwnICInOptimizedCode(isolate()); 4921cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, callable, flags); 4931cb0ef41Sopenharmony_ci } 4941cb0ef41Sopenharmony_ci} 4951cb0ef41Sopenharmony_ci 4961cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSStoreGlobal(Node* node) { 4971cb0ef41Sopenharmony_ci JSStoreGlobalNode n(node); 4981cb0ef41Sopenharmony_ci const StoreGlobalParameters& p = n.Parameters(); 4991cb0ef41Sopenharmony_ci FrameState frame_state = n.frame_state(); 5001cb0ef41Sopenharmony_ci Node* outer_state = frame_state.outer_frame_state(); 5011cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 1); 5021cb0ef41Sopenharmony_ci if (outer_state->opcode() != IrOpcode::kFrameState) { 5031cb0ef41Sopenharmony_ci n->RemoveInput(n.FeedbackVectorIndex()); 5041cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, jsgraph()->Constant(p.name(broker()))); 5051cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, 5061cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 5071cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kStoreGlobalICTrampoline); 5081cb0ef41Sopenharmony_ci } else { 5091cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, jsgraph()->Constant(p.name(broker()))); 5101cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, 5111cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 5121cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kStoreGlobalIC); 5131cb0ef41Sopenharmony_ci } 5141cb0ef41Sopenharmony_ci} 5151cb0ef41Sopenharmony_ci 5161cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSDefineKeyedOwnPropertyInLiteral(Node* node) { 5171cb0ef41Sopenharmony_ci JSDefineKeyedOwnPropertyInLiteralNode n(node); 5181cb0ef41Sopenharmony_ci FeedbackParameter const& p = n.Parameters(); 5191cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 4); 5201cb0ef41Sopenharmony_ci RelaxControls(node); 5211cb0ef41Sopenharmony_ci node->InsertInput(zone(), 5, 5221cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 5231cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kDefineKeyedOwnPropertyInLiteral); 5241cb0ef41Sopenharmony_ci} 5251cb0ef41Sopenharmony_ci 5261cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSStoreInArrayLiteral(Node* node) { 5271cb0ef41Sopenharmony_ci JSStoreInArrayLiteralNode n(node); 5281cb0ef41Sopenharmony_ci FeedbackParameter const& p = n.Parameters(); 5291cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 3); 5301cb0ef41Sopenharmony_ci RelaxControls(node); 5311cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, 5321cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 5331cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kStoreInArrayLiteralIC); 5341cb0ef41Sopenharmony_ci} 5351cb0ef41Sopenharmony_ci 5361cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSDeleteProperty(Node* node) { 5371cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kDeleteProperty); 5381cb0ef41Sopenharmony_ci} 5391cb0ef41Sopenharmony_ci 5401cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGetSuperConstructor(Node* node) { 5411cb0ef41Sopenharmony_ci Node* active_function = NodeProperties::GetValueInput(node, 0); 5421cb0ef41Sopenharmony_ci Node* effect = NodeProperties::GetEffectInput(node); 5431cb0ef41Sopenharmony_ci Node* control = NodeProperties::GetControlInput(node); 5441cb0ef41Sopenharmony_ci 5451cb0ef41Sopenharmony_ci Node* function_map = effect = graph()->NewNode( 5461cb0ef41Sopenharmony_ci jsgraph()->simplified()->LoadField(AccessBuilder::ForMap()), 5471cb0ef41Sopenharmony_ci active_function, effect, control); 5481cb0ef41Sopenharmony_ci 5491cb0ef41Sopenharmony_ci RelaxControls(node); 5501cb0ef41Sopenharmony_ci node->ReplaceInput(0, function_map); 5511cb0ef41Sopenharmony_ci node->ReplaceInput(1, effect); 5521cb0ef41Sopenharmony_ci node->ReplaceInput(2, control); 5531cb0ef41Sopenharmony_ci node->TrimInputCount(3); 5541cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, jsgraph()->simplified()->LoadField( 5551cb0ef41Sopenharmony_ci AccessBuilder::ForMapPrototype())); 5561cb0ef41Sopenharmony_ci} 5571cb0ef41Sopenharmony_ci 5581cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSHasInPrototypeChain(Node* node) { 5591cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kHasInPrototypeChain); 5601cb0ef41Sopenharmony_ci} 5611cb0ef41Sopenharmony_ci 5621cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSOrdinaryHasInstance(Node* node) { 5631cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kOrdinaryHasInstance); 5641cb0ef41Sopenharmony_ci} 5651cb0ef41Sopenharmony_ci 5661cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSHasContextExtension(Node* node) { 5671cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 5681cb0ef41Sopenharmony_ci} 5691cb0ef41Sopenharmony_ci 5701cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSLoadContext(Node* node) { 5711cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 5721cb0ef41Sopenharmony_ci} 5731cb0ef41Sopenharmony_ci 5741cb0ef41Sopenharmony_ci 5751cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSStoreContext(Node* node) { 5761cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 5771cb0ef41Sopenharmony_ci} 5781cb0ef41Sopenharmony_ci 5791cb0ef41Sopenharmony_ci 5801cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreate(Node* node) { 5811cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kFastNewObject); 5821cb0ef41Sopenharmony_ci} 5831cb0ef41Sopenharmony_ci 5841cb0ef41Sopenharmony_ci 5851cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateArguments(Node* node) { 5861cb0ef41Sopenharmony_ci CreateArgumentsType const type = CreateArgumentsTypeOf(node->op()); 5871cb0ef41Sopenharmony_ci switch (type) { 5881cb0ef41Sopenharmony_ci case CreateArgumentsType::kMappedArguments: 5891cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kNewSloppyArguments); 5901cb0ef41Sopenharmony_ci break; 5911cb0ef41Sopenharmony_ci case CreateArgumentsType::kUnmappedArguments: 5921cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kNewStrictArguments); 5931cb0ef41Sopenharmony_ci break; 5941cb0ef41Sopenharmony_ci case CreateArgumentsType::kRestParameter: 5951cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kNewRestParameter); 5961cb0ef41Sopenharmony_ci break; 5971cb0ef41Sopenharmony_ci } 5981cb0ef41Sopenharmony_ci} 5991cb0ef41Sopenharmony_ci 6001cb0ef41Sopenharmony_ci 6011cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateArray(Node* node) { 6021cb0ef41Sopenharmony_ci CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); 6031cb0ef41Sopenharmony_ci int const arity = static_cast<int>(p.arity()); 6041cb0ef41Sopenharmony_ci auto interface_descriptor = ArrayConstructorDescriptor{}; 6051cb0ef41Sopenharmony_ci auto call_descriptor = Linkage::GetStubCallDescriptor( 6061cb0ef41Sopenharmony_ci zone(), interface_descriptor, arity + 1, CallDescriptor::kNeedsFrameState, 6071cb0ef41Sopenharmony_ci node->op()->properties()); 6081cb0ef41Sopenharmony_ci // If this fails, we might need to update the parameter reordering code 6091cb0ef41Sopenharmony_ci // to ensure that the additional arguments passed via stack are pushed 6101cb0ef41Sopenharmony_ci // between top of stack and JS arguments. 6111cb0ef41Sopenharmony_ci DCHECK_EQ(interface_descriptor.GetStackParameterCount(), 0); 6121cb0ef41Sopenharmony_ci Node* stub_code = jsgraph()->ArrayConstructorStubConstant(); 6131cb0ef41Sopenharmony_ci Node* stub_arity = jsgraph()->Int32Constant(JSParameterCount(arity)); 6141cb0ef41Sopenharmony_ci base::Optional<AllocationSiteRef> const site = p.site(broker()); 6151cb0ef41Sopenharmony_ci Node* type_info = site.has_value() ? jsgraph()->Constant(site.value()) 6161cb0ef41Sopenharmony_ci : jsgraph()->UndefinedConstant(); 6171cb0ef41Sopenharmony_ci Node* receiver = jsgraph()->UndefinedConstant(); 6181cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, stub_code); 6191cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, stub_arity); 6201cb0ef41Sopenharmony_ci node->InsertInput(zone(), 4, type_info); 6211cb0ef41Sopenharmony_ci node->InsertInput(zone(), 5, receiver); 6221cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); 6231cb0ef41Sopenharmony_ci} 6241cb0ef41Sopenharmony_ci 6251cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateArrayIterator(Node* node) { 6261cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 6271cb0ef41Sopenharmony_ci} 6281cb0ef41Sopenharmony_ci 6291cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateAsyncFunctionObject(Node* node) { 6301cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 6311cb0ef41Sopenharmony_ci} 6321cb0ef41Sopenharmony_ci 6331cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateCollectionIterator(Node* node) { 6341cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 6351cb0ef41Sopenharmony_ci} 6361cb0ef41Sopenharmony_ci 6371cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateBoundFunction(Node* node) { 6381cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 6391cb0ef41Sopenharmony_ci} 6401cb0ef41Sopenharmony_ci 6411cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSObjectIsArray(Node* node) { 6421cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 6431cb0ef41Sopenharmony_ci} 6441cb0ef41Sopenharmony_ci 6451cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateObject(Node* node) { 6461cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kCreateObjectWithoutProperties); 6471cb0ef41Sopenharmony_ci} 6481cb0ef41Sopenharmony_ci 6491cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSParseInt(Node* node) { 6501cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kParseInt); 6511cb0ef41Sopenharmony_ci} 6521cb0ef41Sopenharmony_ci 6531cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSRegExpTest(Node* node) { 6541cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kRegExpPrototypeTestFast); 6551cb0ef41Sopenharmony_ci} 6561cb0ef41Sopenharmony_ci 6571cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateClosure(Node* node) { 6581cb0ef41Sopenharmony_ci JSCreateClosureNode n(node); 6591cb0ef41Sopenharmony_ci CreateClosureParameters const& p = n.Parameters(); 6601cb0ef41Sopenharmony_ci SharedFunctionInfoRef shared_info = p.shared_info(broker()); 6611cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackCellIndex() == 0); 6621cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, jsgraph()->Constant(shared_info)); 6631cb0ef41Sopenharmony_ci node->RemoveInput(4); // control 6641cb0ef41Sopenharmony_ci 6651cb0ef41Sopenharmony_ci // Use the FastNewClosure builtin only for functions allocated in new space. 6661cb0ef41Sopenharmony_ci if (p.allocation() == AllocationType::kYoung) { 6671cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kFastNewClosure); 6681cb0ef41Sopenharmony_ci } else { 6691cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kNewClosure_Tenured); 6701cb0ef41Sopenharmony_ci } 6711cb0ef41Sopenharmony_ci} 6721cb0ef41Sopenharmony_ci 6731cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateFunctionContext(Node* node) { 6741cb0ef41Sopenharmony_ci const CreateFunctionContextParameters& parameters = 6751cb0ef41Sopenharmony_ci CreateFunctionContextParametersOf(node->op()); 6761cb0ef41Sopenharmony_ci ScopeInfoRef scope_info = parameters.scope_info(broker()); 6771cb0ef41Sopenharmony_ci int slot_count = parameters.slot_count(); 6781cb0ef41Sopenharmony_ci ScopeType scope_type = parameters.scope_type(); 6791cb0ef41Sopenharmony_ci CallDescriptor::Flags flags = FrameStateFlagForCall(node); 6801cb0ef41Sopenharmony_ci 6811cb0ef41Sopenharmony_ci if (slot_count <= ConstructorBuiltins::MaximumFunctionContextSlots()) { 6821cb0ef41Sopenharmony_ci Callable callable = 6831cb0ef41Sopenharmony_ci CodeFactory::FastNewFunctionContext(isolate(), scope_type); 6841cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, jsgraph()->Constant(scope_info)); 6851cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, jsgraph()->Int32Constant(slot_count)); 6861cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, callable, flags); 6871cb0ef41Sopenharmony_ci } else { 6881cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, jsgraph()->Constant(scope_info)); 6891cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kNewFunctionContext); 6901cb0ef41Sopenharmony_ci } 6911cb0ef41Sopenharmony_ci} 6921cb0ef41Sopenharmony_ci 6931cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateGeneratorObject(Node* node) { 6941cb0ef41Sopenharmony_ci node->RemoveInput(4); // control 6951cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kCreateGeneratorObject); 6961cb0ef41Sopenharmony_ci} 6971cb0ef41Sopenharmony_ci 6981cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateIterResultObject(Node* node) { 6991cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kCreateIterResultObject); 7001cb0ef41Sopenharmony_ci} 7011cb0ef41Sopenharmony_ci 7021cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateStringIterator(Node* node) { 7031cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 7041cb0ef41Sopenharmony_ci} 7051cb0ef41Sopenharmony_ci 7061cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateKeyValueArray(Node* node) { 7071cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 7081cb0ef41Sopenharmony_ci} 7091cb0ef41Sopenharmony_ci 7101cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreatePromise(Node* node) { 7111cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 7121cb0ef41Sopenharmony_ci} 7131cb0ef41Sopenharmony_ci 7141cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateTypedArray(Node* node) { 7151cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kCreateTypedArray); 7161cb0ef41Sopenharmony_ci} 7171cb0ef41Sopenharmony_ci 7181cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateLiteralArray(Node* node) { 7191cb0ef41Sopenharmony_ci JSCreateLiteralArrayNode n(node); 7201cb0ef41Sopenharmony_ci CreateLiteralParameters const& p = n.Parameters(); 7211cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 0); 7221cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, 7231cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 7241cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, jsgraph()->Constant(p.constant(broker()))); 7251cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags())); 7261cb0ef41Sopenharmony_ci 7271cb0ef41Sopenharmony_ci // Use the CreateShallowArrayLiteral builtin only for shallow boilerplates 7281cb0ef41Sopenharmony_ci // without properties up to the number of elements that the stubs can handle. 7291cb0ef41Sopenharmony_ci if ((p.flags() & AggregateLiteral::kIsShallow) != 0 && 7301cb0ef41Sopenharmony_ci p.length() < ConstructorBuiltins::kMaximumClonedShallowArrayElements) { 7311cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kCreateShallowArrayLiteral); 7321cb0ef41Sopenharmony_ci } else { 7331cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kCreateArrayLiteral); 7341cb0ef41Sopenharmony_ci } 7351cb0ef41Sopenharmony_ci} 7361cb0ef41Sopenharmony_ci 7371cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGetTemplateObject(Node* node) { 7381cb0ef41Sopenharmony_ci JSGetTemplateObjectNode n(node); 7391cb0ef41Sopenharmony_ci GetTemplateObjectParameters const& p = n.Parameters(); 7401cb0ef41Sopenharmony_ci SharedFunctionInfoRef shared = p.shared(broker()); 7411cb0ef41Sopenharmony_ci TemplateObjectDescriptionRef description = p.description(broker()); 7421cb0ef41Sopenharmony_ci 7431cb0ef41Sopenharmony_ci DCHECK_EQ(node->op()->ControlInputCount(), 1); 7441cb0ef41Sopenharmony_ci node->RemoveInput(NodeProperties::FirstControlIndex(node)); 7451cb0ef41Sopenharmony_ci 7461cb0ef41Sopenharmony_ci STATIC_ASSERT(JSGetTemplateObjectNode::FeedbackVectorIndex() == 0); 7471cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, jsgraph()->Constant(shared)); 7481cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, jsgraph()->Constant(description)); 7491cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, 7501cb0ef41Sopenharmony_ci jsgraph()->UintPtrConstant(p.feedback().index())); 7511cb0ef41Sopenharmony_ci 7521cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kGetTemplateObject); 7531cb0ef41Sopenharmony_ci} 7541cb0ef41Sopenharmony_ci 7551cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) { 7561cb0ef41Sopenharmony_ci JSCreateEmptyLiteralArrayNode n(node); 7571cb0ef41Sopenharmony_ci FeedbackParameter const& p = n.Parameters(); 7581cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 0); 7591cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, 7601cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 7611cb0ef41Sopenharmony_ci node->RemoveInput(4); // control 7621cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kCreateEmptyArrayLiteral); 7631cb0ef41Sopenharmony_ci} 7641cb0ef41Sopenharmony_ci 7651cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateArrayFromIterable(Node* node) { 7661cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kIterableToListWithSymbolLookup); 7671cb0ef41Sopenharmony_ci} 7681cb0ef41Sopenharmony_ci 7691cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateLiteralObject(Node* node) { 7701cb0ef41Sopenharmony_ci JSCreateLiteralObjectNode n(node); 7711cb0ef41Sopenharmony_ci CreateLiteralParameters const& p = n.Parameters(); 7721cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 0); 7731cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, 7741cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 7751cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, jsgraph()->Constant(p.constant(broker()))); 7761cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags())); 7771cb0ef41Sopenharmony_ci 7781cb0ef41Sopenharmony_ci // Use the CreateShallowObjectLiteratal builtin only for shallow boilerplates 7791cb0ef41Sopenharmony_ci // without elements up to the number of properties that the stubs can handle. 7801cb0ef41Sopenharmony_ci if ((p.flags() & AggregateLiteral::kIsShallow) != 0 && 7811cb0ef41Sopenharmony_ci p.length() <= 7821cb0ef41Sopenharmony_ci ConstructorBuiltins::kMaximumClonedShallowObjectProperties) { 7831cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kCreateShallowObjectLiteral); 7841cb0ef41Sopenharmony_ci } else { 7851cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kCreateObjectLiteral); 7861cb0ef41Sopenharmony_ci } 7871cb0ef41Sopenharmony_ci} 7881cb0ef41Sopenharmony_ci 7891cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCloneObject(Node* node) { 7901cb0ef41Sopenharmony_ci JSCloneObjectNode n(node); 7911cb0ef41Sopenharmony_ci CloneObjectParameters const& p = n.Parameters(); 7921cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 1); 7931cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.flags())); 7941cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, 7951cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 7961cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kCloneObjectIC); 7971cb0ef41Sopenharmony_ci} 7981cb0ef41Sopenharmony_ci 7991cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateEmptyLiteralObject(Node* node) { 8001cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kCreateEmptyLiteralObject); 8011cb0ef41Sopenharmony_ci} 8021cb0ef41Sopenharmony_ci 8031cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateLiteralRegExp(Node* node) { 8041cb0ef41Sopenharmony_ci JSCreateLiteralRegExpNode n(node); 8051cb0ef41Sopenharmony_ci CreateLiteralParameters const& p = n.Parameters(); 8061cb0ef41Sopenharmony_ci STATIC_ASSERT(n.FeedbackVectorIndex() == 0); 8071cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, 8081cb0ef41Sopenharmony_ci jsgraph()->TaggedIndexConstant(p.feedback().index())); 8091cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, jsgraph()->Constant(p.constant(broker()))); 8101cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags())); 8111cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kCreateRegExpLiteral); 8121cb0ef41Sopenharmony_ci} 8131cb0ef41Sopenharmony_ci 8141cb0ef41Sopenharmony_ci 8151cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateCatchContext(Node* node) { 8161cb0ef41Sopenharmony_ci ScopeInfoRef scope_info = ScopeInfoOf(broker(), node->op()); 8171cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, jsgraph()->Constant(scope_info)); 8181cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kPushCatchContext); 8191cb0ef41Sopenharmony_ci} 8201cb0ef41Sopenharmony_ci 8211cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateWithContext(Node* node) { 8221cb0ef41Sopenharmony_ci ScopeInfoRef scope_info = ScopeInfoOf(broker(), node->op()); 8231cb0ef41Sopenharmony_ci node->InsertInput(zone(), 1, jsgraph()->Constant(scope_info)); 8241cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kPushWithContext); 8251cb0ef41Sopenharmony_ci} 8261cb0ef41Sopenharmony_ci 8271cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCreateBlockContext(Node* node) { 8281cb0ef41Sopenharmony_ci ScopeInfoRef scope_info = ScopeInfoOf(broker(), node->op()); 8291cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, jsgraph()->Constant(scope_info)); 8301cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kPushBlockContext); 8311cb0ef41Sopenharmony_ci} 8321cb0ef41Sopenharmony_ci 8331cb0ef41Sopenharmony_ci// TODO(jgruber,v8:8888): Should this collect feedback? 8341cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSConstructForwardVarargs(Node* node) { 8351cb0ef41Sopenharmony_ci ConstructForwardVarargsParameters p = 8361cb0ef41Sopenharmony_ci ConstructForwardVarargsParametersOf(node->op()); 8371cb0ef41Sopenharmony_ci int const arg_count = static_cast<int>(p.arity() - 2); 8381cb0ef41Sopenharmony_ci CallDescriptor::Flags flags = FrameStateFlagForCall(node); 8391cb0ef41Sopenharmony_ci Callable callable = CodeFactory::ConstructForwardVarargs(isolate()); 8401cb0ef41Sopenharmony_ci // If this fails, we might need to update the parameter reordering code 8411cb0ef41Sopenharmony_ci // to ensure that the additional arguments passed via stack are pushed 8421cb0ef41Sopenharmony_ci // between top of stack and JS arguments. 8431cb0ef41Sopenharmony_ci DCHECK_EQ(callable.descriptor().GetStackParameterCount(), 0); 8441cb0ef41Sopenharmony_ci auto call_descriptor = Linkage::GetStubCallDescriptor( 8451cb0ef41Sopenharmony_ci zone(), callable.descriptor(), arg_count + 1, flags); 8461cb0ef41Sopenharmony_ci Node* stub_code = jsgraph()->HeapConstant(callable.code()); 8471cb0ef41Sopenharmony_ci Node* stub_arity = jsgraph()->Int32Constant(JSParameterCount(arg_count)); 8481cb0ef41Sopenharmony_ci Node* start_index = jsgraph()->Uint32Constant(p.start_index()); 8491cb0ef41Sopenharmony_ci Node* receiver = jsgraph()->UndefinedConstant(); 8501cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, stub_code); 8511cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, stub_arity); 8521cb0ef41Sopenharmony_ci node->InsertInput(zone(), 4, start_index); 8531cb0ef41Sopenharmony_ci node->InsertInput(zone(), 5, receiver); 8541cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); 8551cb0ef41Sopenharmony_ci} 8561cb0ef41Sopenharmony_ci 8571cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSConstruct(Node* node) { 8581cb0ef41Sopenharmony_ci JSConstructNode n(node); 8591cb0ef41Sopenharmony_ci ConstructParameters const& p = n.Parameters(); 8601cb0ef41Sopenharmony_ci int const arg_count = p.arity_without_implicit_args(); 8611cb0ef41Sopenharmony_ci CallDescriptor::Flags flags = FrameStateFlagForCall(node); 8621cb0ef41Sopenharmony_ci 8631cb0ef41Sopenharmony_ci static constexpr int kReceiver = 1; 8641cb0ef41Sopenharmony_ci 8651cb0ef41Sopenharmony_ci const int stack_argument_count = arg_count + kReceiver; 8661cb0ef41Sopenharmony_ci Callable callable = Builtins::CallableFor(isolate(), Builtin::kConstruct); 8671cb0ef41Sopenharmony_ci auto call_descriptor = Linkage::GetStubCallDescriptor( 8681cb0ef41Sopenharmony_ci zone(), callable.descriptor(), stack_argument_count, flags); 8691cb0ef41Sopenharmony_ci Node* stub_code = jsgraph()->HeapConstant(callable.code()); 8701cb0ef41Sopenharmony_ci Node* stub_arity = jsgraph()->Int32Constant(JSParameterCount(arg_count)); 8711cb0ef41Sopenharmony_ci Node* receiver = jsgraph()->UndefinedConstant(); 8721cb0ef41Sopenharmony_ci node->RemoveInput(n.FeedbackVectorIndex()); 8731cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, stub_code); 8741cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, stub_arity); 8751cb0ef41Sopenharmony_ci node->InsertInput(zone(), 4, receiver); 8761cb0ef41Sopenharmony_ci 8771cb0ef41Sopenharmony_ci // After: {code, target, new_target, arity, receiver, ...args}. 8781cb0ef41Sopenharmony_ci 8791cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); 8801cb0ef41Sopenharmony_ci} 8811cb0ef41Sopenharmony_ci 8821cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSConstructWithArrayLike(Node* node) { 8831cb0ef41Sopenharmony_ci JSConstructWithArrayLikeNode n(node); 8841cb0ef41Sopenharmony_ci ConstructParameters const& p = n.Parameters(); 8851cb0ef41Sopenharmony_ci CallDescriptor::Flags flags = FrameStateFlagForCall(node); 8861cb0ef41Sopenharmony_ci const int arg_count = p.arity_without_implicit_args(); 8871cb0ef41Sopenharmony_ci DCHECK_EQ(arg_count, 1); 8881cb0ef41Sopenharmony_ci 8891cb0ef41Sopenharmony_ci static constexpr int kReceiver = 1; 8901cb0ef41Sopenharmony_ci static constexpr int kArgumentList = 1; 8911cb0ef41Sopenharmony_ci 8921cb0ef41Sopenharmony_ci const int stack_argument_count = arg_count - kArgumentList + kReceiver; 8931cb0ef41Sopenharmony_ci Callable callable = 8941cb0ef41Sopenharmony_ci Builtins::CallableFor(isolate(), Builtin::kConstructWithArrayLike); 8951cb0ef41Sopenharmony_ci // If this fails, we might need to update the parameter reordering code 8961cb0ef41Sopenharmony_ci // to ensure that the additional arguments passed via stack are pushed 8971cb0ef41Sopenharmony_ci // between top of stack and JS arguments. 8981cb0ef41Sopenharmony_ci DCHECK_EQ(callable.descriptor().GetStackParameterCount(), 0); 8991cb0ef41Sopenharmony_ci auto call_descriptor = Linkage::GetStubCallDescriptor( 9001cb0ef41Sopenharmony_ci zone(), callable.descriptor(), stack_argument_count, flags); 9011cb0ef41Sopenharmony_ci Node* stub_code = jsgraph()->HeapConstant(callable.code()); 9021cb0ef41Sopenharmony_ci Node* receiver = jsgraph()->UndefinedConstant(); 9031cb0ef41Sopenharmony_ci node->RemoveInput(n.FeedbackVectorIndex()); 9041cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, stub_code); 9051cb0ef41Sopenharmony_ci node->InsertInput(zone(), 4, receiver); 9061cb0ef41Sopenharmony_ci 9071cb0ef41Sopenharmony_ci // After: {code, target, new_target, arguments_list, receiver}. 9081cb0ef41Sopenharmony_ci 9091cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); 9101cb0ef41Sopenharmony_ci} 9111cb0ef41Sopenharmony_ci 9121cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSConstructWithSpread(Node* node) { 9131cb0ef41Sopenharmony_ci JSConstructWithSpreadNode n(node); 9141cb0ef41Sopenharmony_ci ConstructParameters const& p = n.Parameters(); 9151cb0ef41Sopenharmony_ci int const arg_count = p.arity_without_implicit_args(); 9161cb0ef41Sopenharmony_ci DCHECK_GE(arg_count, 1); 9171cb0ef41Sopenharmony_ci CallDescriptor::Flags flags = FrameStateFlagForCall(node); 9181cb0ef41Sopenharmony_ci 9191cb0ef41Sopenharmony_ci static constexpr int kReceiver = 1; 9201cb0ef41Sopenharmony_ci static constexpr int kTheSpread = 1; // Included in `arg_count`. 9211cb0ef41Sopenharmony_ci 9221cb0ef41Sopenharmony_ci const int stack_argument_count = arg_count + kReceiver - kTheSpread; 9231cb0ef41Sopenharmony_ci Callable callable = CodeFactory::ConstructWithSpread(isolate()); 9241cb0ef41Sopenharmony_ci // If this fails, we might need to update the parameter reordering code 9251cb0ef41Sopenharmony_ci // to ensure that the additional arguments passed via stack are pushed 9261cb0ef41Sopenharmony_ci // between top of stack and JS arguments. 9271cb0ef41Sopenharmony_ci DCHECK_EQ(callable.descriptor().GetStackParameterCount(), 0); 9281cb0ef41Sopenharmony_ci auto call_descriptor = Linkage::GetStubCallDescriptor( 9291cb0ef41Sopenharmony_ci zone(), callable.descriptor(), stack_argument_count, flags); 9301cb0ef41Sopenharmony_ci Node* stub_code = jsgraph()->HeapConstant(callable.code()); 9311cb0ef41Sopenharmony_ci 9321cb0ef41Sopenharmony_ci // We pass the spread in a register, not on the stack. 9331cb0ef41Sopenharmony_ci Node* stub_arity = 9341cb0ef41Sopenharmony_ci jsgraph()->Int32Constant(JSParameterCount(arg_count - kTheSpread)); 9351cb0ef41Sopenharmony_ci Node* receiver = jsgraph()->UndefinedConstant(); 9361cb0ef41Sopenharmony_ci DCHECK(n.FeedbackVectorIndex() > n.LastArgumentIndex()); 9371cb0ef41Sopenharmony_ci node->RemoveInput(n.FeedbackVectorIndex()); 9381cb0ef41Sopenharmony_ci Node* spread = node->RemoveInput(n.LastArgumentIndex()); 9391cb0ef41Sopenharmony_ci 9401cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, stub_code); 9411cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, stub_arity); 9421cb0ef41Sopenharmony_ci node->InsertInput(zone(), 4, spread); 9431cb0ef41Sopenharmony_ci node->InsertInput(zone(), 5, receiver); 9441cb0ef41Sopenharmony_ci 9451cb0ef41Sopenharmony_ci // After: {code, target, new_target, arity, spread, receiver, ...args}. 9461cb0ef41Sopenharmony_ci 9471cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); 9481cb0ef41Sopenharmony_ci} 9491cb0ef41Sopenharmony_ci 9501cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCallForwardVarargs(Node* node) { 9511cb0ef41Sopenharmony_ci CallForwardVarargsParameters p = CallForwardVarargsParametersOf(node->op()); 9521cb0ef41Sopenharmony_ci int const arg_count = static_cast<int>(p.arity() - 2); 9531cb0ef41Sopenharmony_ci CallDescriptor::Flags flags = FrameStateFlagForCall(node); 9541cb0ef41Sopenharmony_ci Callable callable = CodeFactory::CallForwardVarargs(isolate()); 9551cb0ef41Sopenharmony_ci auto call_descriptor = Linkage::GetStubCallDescriptor( 9561cb0ef41Sopenharmony_ci zone(), callable.descriptor(), arg_count + 1, flags); 9571cb0ef41Sopenharmony_ci Node* stub_code = jsgraph()->HeapConstant(callable.code()); 9581cb0ef41Sopenharmony_ci Node* stub_arity = jsgraph()->Int32Constant(JSParameterCount(arg_count)); 9591cb0ef41Sopenharmony_ci Node* start_index = jsgraph()->Uint32Constant(p.start_index()); 9601cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, stub_code); 9611cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, stub_arity); 9621cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, start_index); 9631cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); 9641cb0ef41Sopenharmony_ci} 9651cb0ef41Sopenharmony_ci 9661cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCall(Node* node) { 9671cb0ef41Sopenharmony_ci JSCallNode n(node); 9681cb0ef41Sopenharmony_ci CallParameters const& p = n.Parameters(); 9691cb0ef41Sopenharmony_ci int const arg_count = p.arity_without_implicit_args(); 9701cb0ef41Sopenharmony_ci ConvertReceiverMode const mode = p.convert_mode(); 9711cb0ef41Sopenharmony_ci 9721cb0ef41Sopenharmony_ci node->RemoveInput(n.FeedbackVectorIndex()); 9731cb0ef41Sopenharmony_ci 9741cb0ef41Sopenharmony_ci Callable callable = CodeFactory::Call(isolate(), mode); 9751cb0ef41Sopenharmony_ci CallDescriptor::Flags flags = FrameStateFlagForCall(node); 9761cb0ef41Sopenharmony_ci auto call_descriptor = Linkage::GetStubCallDescriptor( 9771cb0ef41Sopenharmony_ci zone(), callable.descriptor(), arg_count + 1, flags); 9781cb0ef41Sopenharmony_ci Node* stub_code = jsgraph()->HeapConstant(callable.code()); 9791cb0ef41Sopenharmony_ci Node* stub_arity = jsgraph()->Int32Constant(JSParameterCount(arg_count)); 9801cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, stub_code); 9811cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, stub_arity); 9821cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); 9831cb0ef41Sopenharmony_ci} 9841cb0ef41Sopenharmony_ci 9851cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCallWithArrayLike(Node* node) { 9861cb0ef41Sopenharmony_ci JSCallWithArrayLikeNode n(node); 9871cb0ef41Sopenharmony_ci CallParameters const& p = n.Parameters(); 9881cb0ef41Sopenharmony_ci const int arg_count = p.arity_without_implicit_args(); 9891cb0ef41Sopenharmony_ci DCHECK_EQ(arg_count, 1); // The arraylike object. 9901cb0ef41Sopenharmony_ci CallDescriptor::Flags flags = FrameStateFlagForCall(node); 9911cb0ef41Sopenharmony_ci 9921cb0ef41Sopenharmony_ci static constexpr int kArgumentsList = 1; 9931cb0ef41Sopenharmony_ci static constexpr int kReceiver = 1; 9941cb0ef41Sopenharmony_ci 9951cb0ef41Sopenharmony_ci const int stack_argument_count = arg_count - kArgumentsList + kReceiver; 9961cb0ef41Sopenharmony_ci Callable callable = CodeFactory::CallWithArrayLike(isolate()); 9971cb0ef41Sopenharmony_ci auto call_descriptor = Linkage::GetStubCallDescriptor( 9981cb0ef41Sopenharmony_ci zone(), callable.descriptor(), stack_argument_count, flags); 9991cb0ef41Sopenharmony_ci Node* stub_code = jsgraph()->HeapConstant(callable.code()); 10001cb0ef41Sopenharmony_ci Node* receiver = n.receiver(); 10011cb0ef41Sopenharmony_ci Node* arguments_list = n.Argument(0); 10021cb0ef41Sopenharmony_ci 10031cb0ef41Sopenharmony_ci // Shuffling inputs. 10041cb0ef41Sopenharmony_ci // Before: {target, receiver, arguments_list, vector}. 10051cb0ef41Sopenharmony_ci 10061cb0ef41Sopenharmony_ci node->RemoveInput(n.FeedbackVectorIndex()); 10071cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, stub_code); 10081cb0ef41Sopenharmony_ci node->ReplaceInput(2, arguments_list); 10091cb0ef41Sopenharmony_ci node->ReplaceInput(3, receiver); 10101cb0ef41Sopenharmony_ci 10111cb0ef41Sopenharmony_ci // After: {code, target, arguments_list, receiver}. 10121cb0ef41Sopenharmony_ci 10131cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); 10141cb0ef41Sopenharmony_ci} 10151cb0ef41Sopenharmony_ci 10161cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCallWithSpread(Node* node) { 10171cb0ef41Sopenharmony_ci JSCallWithSpreadNode n(node); 10181cb0ef41Sopenharmony_ci CallParameters const& p = n.Parameters(); 10191cb0ef41Sopenharmony_ci int const arg_count = p.arity_without_implicit_args(); 10201cb0ef41Sopenharmony_ci DCHECK_GE(arg_count, 1); // At least the spread. 10211cb0ef41Sopenharmony_ci CallDescriptor::Flags flags = FrameStateFlagForCall(node); 10221cb0ef41Sopenharmony_ci 10231cb0ef41Sopenharmony_ci static constexpr int kReceiver = 1; 10241cb0ef41Sopenharmony_ci static constexpr int kTheSpread = 1; 10251cb0ef41Sopenharmony_ci 10261cb0ef41Sopenharmony_ci const int stack_argument_count = arg_count - kTheSpread + kReceiver; 10271cb0ef41Sopenharmony_ci Callable callable = CodeFactory::CallWithSpread(isolate()); 10281cb0ef41Sopenharmony_ci // If this fails, we might need to update the parameter reordering code 10291cb0ef41Sopenharmony_ci // to ensure that the additional arguments passed via stack are pushed 10301cb0ef41Sopenharmony_ci // between top of stack and JS arguments. 10311cb0ef41Sopenharmony_ci DCHECK_EQ(callable.descriptor().GetStackParameterCount(), 0); 10321cb0ef41Sopenharmony_ci auto call_descriptor = Linkage::GetStubCallDescriptor( 10331cb0ef41Sopenharmony_ci zone(), callable.descriptor(), stack_argument_count, flags); 10341cb0ef41Sopenharmony_ci Node* stub_code = jsgraph()->HeapConstant(callable.code()); 10351cb0ef41Sopenharmony_ci 10361cb0ef41Sopenharmony_ci // We pass the spread in a register, not on the stack. 10371cb0ef41Sopenharmony_ci Node* stub_arity = 10381cb0ef41Sopenharmony_ci jsgraph()->Int32Constant(JSParameterCount(arg_count - kTheSpread)); 10391cb0ef41Sopenharmony_ci 10401cb0ef41Sopenharmony_ci // Shuffling inputs. 10411cb0ef41Sopenharmony_ci // Before: {target, receiver, ...args, spread, vector}. 10421cb0ef41Sopenharmony_ci 10431cb0ef41Sopenharmony_ci node->RemoveInput(n.FeedbackVectorIndex()); 10441cb0ef41Sopenharmony_ci Node* spread = node->RemoveInput(n.LastArgumentIndex()); 10451cb0ef41Sopenharmony_ci 10461cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, stub_code); 10471cb0ef41Sopenharmony_ci node->InsertInput(zone(), 2, stub_arity); 10481cb0ef41Sopenharmony_ci node->InsertInput(zone(), 3, spread); 10491cb0ef41Sopenharmony_ci 10501cb0ef41Sopenharmony_ci // After: {code, target, arity, spread, receiver, ...args}. 10511cb0ef41Sopenharmony_ci 10521cb0ef41Sopenharmony_ci NodeProperties::ChangeOp(node, common()->Call(call_descriptor)); 10531cb0ef41Sopenharmony_ci} 10541cb0ef41Sopenharmony_ci 10551cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSCallRuntime(Node* node) { 10561cb0ef41Sopenharmony_ci const CallRuntimeParameters& p = CallRuntimeParametersOf(node->op()); 10571cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, p.id(), static_cast<int>(p.arity())); 10581cb0ef41Sopenharmony_ci} 10591cb0ef41Sopenharmony_ci 10601cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY 10611cb0ef41Sopenharmony_ci// Will be lowered in SimplifiedLowering. 10621cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSWasmCall(Node* node) {} 10631cb0ef41Sopenharmony_ci#endif // V8_ENABLE_WEBASSEMBLY 10641cb0ef41Sopenharmony_ci 10651cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSForInPrepare(Node* node) { 10661cb0ef41Sopenharmony_ci JSForInPrepareNode n(node); 10671cb0ef41Sopenharmony_ci Effect effect(node); // {node} is kept in the effect chain. 10681cb0ef41Sopenharmony_ci Control control = n.control(); // .. but not in the control chain. 10691cb0ef41Sopenharmony_ci Node* enumerator = n.enumerator(); 10701cb0ef41Sopenharmony_ci Node* slot = 10711cb0ef41Sopenharmony_ci jsgraph()->UintPtrConstant(n.Parameters().feedback().slot.ToInt()); 10721cb0ef41Sopenharmony_ci 10731cb0ef41Sopenharmony_ci std::vector<Edge> use_edges; 10741cb0ef41Sopenharmony_ci for (Edge edge : node->use_edges()) use_edges.push_back(edge); 10751cb0ef41Sopenharmony_ci 10761cb0ef41Sopenharmony_ci // {node} will be changed to a builtin call (see below). The returned value 10771cb0ef41Sopenharmony_ci // is a fixed array containing {cache_array} and {cache_length}. 10781cb0ef41Sopenharmony_ci // TODO(jgruber): This is awkward; what we really want is two return values, 10791cb0ef41Sopenharmony_ci // the {cache_array} and {cache_length}, or better yet three return values 10801cb0ef41Sopenharmony_ci // s.t. we can avoid the graph rewrites below. Builtin support for multiple 10811cb0ef41Sopenharmony_ci // return types is unclear though. 10821cb0ef41Sopenharmony_ci 10831cb0ef41Sopenharmony_ci Node* result_fixed_array = node; 10841cb0ef41Sopenharmony_ci Node* cache_type = enumerator; // Just to clarify the rename. 10851cb0ef41Sopenharmony_ci Node* cache_array; 10861cb0ef41Sopenharmony_ci Node* cache_length; 10871cb0ef41Sopenharmony_ci 10881cb0ef41Sopenharmony_ci cache_array = effect = graph()->NewNode( 10891cb0ef41Sopenharmony_ci machine()->Load(MachineType::AnyTagged()), result_fixed_array, 10901cb0ef41Sopenharmony_ci jsgraph()->IntPtrConstant(FixedArray::OffsetOfElementAt(0) - 10911cb0ef41Sopenharmony_ci kHeapObjectTag), 10921cb0ef41Sopenharmony_ci effect, control); 10931cb0ef41Sopenharmony_ci cache_length = effect = graph()->NewNode( 10941cb0ef41Sopenharmony_ci machine()->Load(MachineType::AnyTagged()), result_fixed_array, 10951cb0ef41Sopenharmony_ci jsgraph()->IntPtrConstant(FixedArray::OffsetOfElementAt(1) - 10961cb0ef41Sopenharmony_ci kHeapObjectTag), 10971cb0ef41Sopenharmony_ci effect, control); 10981cb0ef41Sopenharmony_ci 10991cb0ef41Sopenharmony_ci // Update the uses of {node}. 11001cb0ef41Sopenharmony_ci for (Edge edge : use_edges) { 11011cb0ef41Sopenharmony_ci Node* const user = edge.from(); 11021cb0ef41Sopenharmony_ci if (NodeProperties::IsEffectEdge(edge)) { 11031cb0ef41Sopenharmony_ci edge.UpdateTo(effect); 11041cb0ef41Sopenharmony_ci } else if (NodeProperties::IsControlEdge(edge)) { 11051cb0ef41Sopenharmony_ci edge.UpdateTo(control); 11061cb0ef41Sopenharmony_ci } else { 11071cb0ef41Sopenharmony_ci DCHECK(NodeProperties::IsValueEdge(edge)); 11081cb0ef41Sopenharmony_ci switch (ProjectionIndexOf(user->op())) { 11091cb0ef41Sopenharmony_ci case 0: 11101cb0ef41Sopenharmony_ci Replace(user, cache_type); 11111cb0ef41Sopenharmony_ci break; 11121cb0ef41Sopenharmony_ci case 1: 11131cb0ef41Sopenharmony_ci Replace(user, cache_array); 11141cb0ef41Sopenharmony_ci break; 11151cb0ef41Sopenharmony_ci case 2: 11161cb0ef41Sopenharmony_ci Replace(user, cache_length); 11171cb0ef41Sopenharmony_ci break; 11181cb0ef41Sopenharmony_ci default: 11191cb0ef41Sopenharmony_ci UNREACHABLE(); 11201cb0ef41Sopenharmony_ci } 11211cb0ef41Sopenharmony_ci } 11221cb0ef41Sopenharmony_ci } 11231cb0ef41Sopenharmony_ci 11241cb0ef41Sopenharmony_ci // Finally, change the original node into a builtin call. This happens here, 11251cb0ef41Sopenharmony_ci // after graph rewrites, since the Call does not have a control output and 11261cb0ef41Sopenharmony_ci // thus must not have any control uses. Any previously existing control 11271cb0ef41Sopenharmony_ci // outputs have been replaced by the graph rewrite above. 11281cb0ef41Sopenharmony_ci node->InsertInput(zone(), n.FeedbackVectorIndex(), slot); 11291cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kForInPrepare); 11301cb0ef41Sopenharmony_ci} 11311cb0ef41Sopenharmony_ci 11321cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSForInNext(Node* node) { 11331cb0ef41Sopenharmony_ci JSForInNextNode n(node); 11341cb0ef41Sopenharmony_ci node->InsertInput( 11351cb0ef41Sopenharmony_ci zone(), 0, 11361cb0ef41Sopenharmony_ci jsgraph()->UintPtrConstant(n.Parameters().feedback().slot.ToInt())); 11371cb0ef41Sopenharmony_ci ReplaceWithBuiltinCall(node, Builtin::kForInNext); 11381cb0ef41Sopenharmony_ci} 11391cb0ef41Sopenharmony_ci 11401cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSLoadMessage(Node* node) { 11411cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 11421cb0ef41Sopenharmony_ci} 11431cb0ef41Sopenharmony_ci 11441cb0ef41Sopenharmony_ci 11451cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSStoreMessage(Node* node) { 11461cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 11471cb0ef41Sopenharmony_ci} 11481cb0ef41Sopenharmony_ci 11491cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSLoadModule(Node* node) { 11501cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 11511cb0ef41Sopenharmony_ci} 11521cb0ef41Sopenharmony_ci 11531cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSStoreModule(Node* node) { 11541cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 11551cb0ef41Sopenharmony_ci} 11561cb0ef41Sopenharmony_ci 11571cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGetImportMeta(Node* node) { 11581cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kGetImportMetaObject); 11591cb0ef41Sopenharmony_ci} 11601cb0ef41Sopenharmony_ci 11611cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGeneratorStore(Node* node) { 11621cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 11631cb0ef41Sopenharmony_ci} 11641cb0ef41Sopenharmony_ci 11651cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGeneratorRestoreContinuation(Node* node) { 11661cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 11671cb0ef41Sopenharmony_ci} 11681cb0ef41Sopenharmony_ci 11691cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGeneratorRestoreContext(Node* node) { 11701cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 11711cb0ef41Sopenharmony_ci} 11721cb0ef41Sopenharmony_ci 11731cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGeneratorRestoreInputOrDebugPos(Node* node) { 11741cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 11751cb0ef41Sopenharmony_ci} 11761cb0ef41Sopenharmony_ci 11771cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSGeneratorRestoreRegister(Node* node) { 11781cb0ef41Sopenharmony_ci UNREACHABLE(); // Eliminated in typed lowering. 11791cb0ef41Sopenharmony_ci} 11801cb0ef41Sopenharmony_ci 11811cb0ef41Sopenharmony_cinamespace { 11821cb0ef41Sopenharmony_ci 11831cb0ef41Sopenharmony_ciStackCheckKind StackCheckKindOfJSStackCheck(const Operator* op) { 11841cb0ef41Sopenharmony_ci DCHECK(op->opcode() == IrOpcode::kJSStackCheck); 11851cb0ef41Sopenharmony_ci return OpParameter<StackCheckKind>(op); 11861cb0ef41Sopenharmony_ci} 11871cb0ef41Sopenharmony_ci 11881cb0ef41Sopenharmony_ci} // namespace 11891cb0ef41Sopenharmony_ci 11901cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSStackCheck(Node* node) { 11911cb0ef41Sopenharmony_ci Node* effect = NodeProperties::GetEffectInput(node); 11921cb0ef41Sopenharmony_ci Node* control = NodeProperties::GetControlInput(node); 11931cb0ef41Sopenharmony_ci 11941cb0ef41Sopenharmony_ci Node* limit = effect = 11951cb0ef41Sopenharmony_ci graph()->NewNode(machine()->Load(MachineType::Pointer()), 11961cb0ef41Sopenharmony_ci jsgraph()->ExternalConstant( 11971cb0ef41Sopenharmony_ci ExternalReference::address_of_jslimit(isolate())), 11981cb0ef41Sopenharmony_ci jsgraph()->IntPtrConstant(0), effect, control); 11991cb0ef41Sopenharmony_ci 12001cb0ef41Sopenharmony_ci StackCheckKind stack_check_kind = StackCheckKindOfJSStackCheck(node->op()); 12011cb0ef41Sopenharmony_ci Node* check = effect = graph()->NewNode( 12021cb0ef41Sopenharmony_ci machine()->StackPointerGreaterThan(stack_check_kind), limit, effect); 12031cb0ef41Sopenharmony_ci Node* branch = 12041cb0ef41Sopenharmony_ci graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); 12051cb0ef41Sopenharmony_ci 12061cb0ef41Sopenharmony_ci Node* if_true = graph()->NewNode(common()->IfTrue(), branch); 12071cb0ef41Sopenharmony_ci Node* etrue = effect; 12081cb0ef41Sopenharmony_ci 12091cb0ef41Sopenharmony_ci Node* if_false = graph()->NewNode(common()->IfFalse(), branch); 12101cb0ef41Sopenharmony_ci NodeProperties::ReplaceControlInput(node, if_false); 12111cb0ef41Sopenharmony_ci NodeProperties::ReplaceEffectInput(node, effect); 12121cb0ef41Sopenharmony_ci Node* efalse = if_false = node; 12131cb0ef41Sopenharmony_ci 12141cb0ef41Sopenharmony_ci Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); 12151cb0ef41Sopenharmony_ci Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge); 12161cb0ef41Sopenharmony_ci 12171cb0ef41Sopenharmony_ci // Wire the new diamond into the graph, {node} can still throw. 12181cb0ef41Sopenharmony_ci NodeProperties::ReplaceUses(node, node, ephi, merge, merge); 12191cb0ef41Sopenharmony_ci NodeProperties::ReplaceControlInput(merge, if_false, 1); 12201cb0ef41Sopenharmony_ci NodeProperties::ReplaceEffectInput(ephi, efalse, 1); 12211cb0ef41Sopenharmony_ci 12221cb0ef41Sopenharmony_ci // This iteration cuts out potential {IfSuccess} or {IfException} projection 12231cb0ef41Sopenharmony_ci // uses of the original node and places them inside the diamond, so that we 12241cb0ef41Sopenharmony_ci // can change the original {node} into the slow-path runtime call. 12251cb0ef41Sopenharmony_ci for (Edge edge : merge->use_edges()) { 12261cb0ef41Sopenharmony_ci if (!NodeProperties::IsControlEdge(edge)) continue; 12271cb0ef41Sopenharmony_ci if (edge.from()->opcode() == IrOpcode::kIfSuccess) { 12281cb0ef41Sopenharmony_ci NodeProperties::ReplaceUses(edge.from(), nullptr, nullptr, merge); 12291cb0ef41Sopenharmony_ci NodeProperties::ReplaceControlInput(merge, edge.from(), 1); 12301cb0ef41Sopenharmony_ci edge.UpdateTo(node); 12311cb0ef41Sopenharmony_ci } 12321cb0ef41Sopenharmony_ci if (edge.from()->opcode() == IrOpcode::kIfException) { 12331cb0ef41Sopenharmony_ci NodeProperties::ReplaceEffectInput(edge.from(), node); 12341cb0ef41Sopenharmony_ci edge.UpdateTo(node); 12351cb0ef41Sopenharmony_ci } 12361cb0ef41Sopenharmony_ci } 12371cb0ef41Sopenharmony_ci 12381cb0ef41Sopenharmony_ci // Turn the stack check into a runtime call. At function entry, the runtime 12391cb0ef41Sopenharmony_ci // function takes an offset argument which is subtracted from the stack 12401cb0ef41Sopenharmony_ci // pointer prior to the stack check (i.e. the check is `sp - offset >= 12411cb0ef41Sopenharmony_ci // limit`). 12421cb0ef41Sopenharmony_ci if (stack_check_kind == StackCheckKind::kJSFunctionEntry) { 12431cb0ef41Sopenharmony_ci node->InsertInput(zone(), 0, 12441cb0ef41Sopenharmony_ci graph()->NewNode(machine()->LoadStackCheckOffset())); 12451cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kStackGuardWithGap); 12461cb0ef41Sopenharmony_ci } else { 12471cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kStackGuard); 12481cb0ef41Sopenharmony_ci } 12491cb0ef41Sopenharmony_ci} 12501cb0ef41Sopenharmony_ci 12511cb0ef41Sopenharmony_civoid JSGenericLowering::LowerJSDebugger(Node* node) { 12521cb0ef41Sopenharmony_ci ReplaceWithRuntimeCall(node, Runtime::kHandleDebuggerStatement); 12531cb0ef41Sopenharmony_ci} 12541cb0ef41Sopenharmony_ci 12551cb0ef41Sopenharmony_ciZone* JSGenericLowering::zone() const { return graph()->zone(); } 12561cb0ef41Sopenharmony_ci 12571cb0ef41Sopenharmony_ci 12581cb0ef41Sopenharmony_ciIsolate* JSGenericLowering::isolate() const { return jsgraph()->isolate(); } 12591cb0ef41Sopenharmony_ci 12601cb0ef41Sopenharmony_ci 12611cb0ef41Sopenharmony_ciGraph* JSGenericLowering::graph() const { return jsgraph()->graph(); } 12621cb0ef41Sopenharmony_ci 12631cb0ef41Sopenharmony_ci 12641cb0ef41Sopenharmony_ciCommonOperatorBuilder* JSGenericLowering::common() const { 12651cb0ef41Sopenharmony_ci return jsgraph()->common(); 12661cb0ef41Sopenharmony_ci} 12671cb0ef41Sopenharmony_ci 12681cb0ef41Sopenharmony_ci 12691cb0ef41Sopenharmony_ciMachineOperatorBuilder* JSGenericLowering::machine() const { 12701cb0ef41Sopenharmony_ci return jsgraph()->machine(); 12711cb0ef41Sopenharmony_ci} 12721cb0ef41Sopenharmony_ci 12731cb0ef41Sopenharmony_ci} // namespace compiler 12741cb0ef41Sopenharmony_ci} // namespace internal 12751cb0ef41Sopenharmony_ci} // namespace v8 1276