Index: src/compiler/bytecode-graph-builder.cc |
diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc |
index e282095711cc1142f23c5517b2078179dabf4ad6..4a10958b160782127a8ceb730236f81e247bb785 100644 |
--- a/src/compiler/bytecode-graph-builder.cc |
+++ b/src/compiler/bytecode-graph-builder.cc |
@@ -1583,28 +1583,63 @@ void BytecodeGraphBuilder::VisitCallRuntimeForPair() { |
Environment::kAttachFrameState); |
} |
-Node* BytecodeGraphBuilder::ProcessConstructWithSpreadArguments( |
- const Operator* op, Node* callee, Node* new_target, |
- interpreter::Register receiver, size_t reg_count) { |
- int arg_count = static_cast<int>(reg_count); |
+Node* const* BytecodeGraphBuilder::GetConstructArgumentsFromRegister( |
+ Node* target, Node* new_target, interpreter::Register first_arg, |
+ int arg_count) { |
// arity is args + callee and new target. |
int arity = arg_count + 2; |
Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity)); |
- all[0] = callee; |
- int first_arg_index = receiver.index(); |
+ all[0] = target; |
+ int first_arg_index = first_arg.index(); |
for (int i = 0; i < arg_count; ++i) { |
all[1 + i] = environment()->LookupRegister( |
interpreter::Register(first_arg_index + i)); |
} |
all[arity - 1] = new_target; |
- Node* value = MakeNode(op, arity, all, false); |
- return value; |
+ return all; |
+} |
+ |
+Node* BytecodeGraphBuilder::ProcessConstructArguments(const Operator* op, |
+ Node* const* args, |
+ int arg_count) { |
+ return MakeNode(op, arg_count, args, false); |
+} |
+ |
+void BytecodeGraphBuilder::VisitConstruct() { |
+ PrepareEagerCheckpoint(); |
+ interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0); |
+ interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1); |
+ size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); |
+ // Slot index of 0 is used indicate no feedback slot is available. Assert |
+ // the assumption that slot index 0 is never a valid feedback slot. |
+ STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0); |
+ int const slot_id = bytecode_iterator().GetIndexOperand(3); |
+ VectorSlotPair feedback = CreateVectorSlotPair(slot_id); |
+ |
+ Node* new_target = environment()->LookupAccumulator(); |
+ Node* callee = environment()->LookupRegister(callee_reg); |
+ |
+ CallFrequency frequency = ComputeCallFrequency(slot_id); |
+ const Operator* op = javascript()->Construct( |
+ static_cast<uint32_t>(reg_count + 2), frequency, feedback); |
+ int arg_count = static_cast<int>(reg_count); |
+ Node* const* args = GetConstructArgumentsFromRegister(callee, new_target, |
+ first_reg, arg_count); |
+ Node* node = nullptr; |
+ if (Node* simplified = TryBuildSimplifiedConstruct( |
+ op, args, static_cast<int>(arg_count), feedback.slot())) { |
+ if (environment() == nullptr) return; |
+ node = simplified; |
+ } else { |
+ node = ProcessConstructArguments(op, args, 2 + arg_count); |
+ } |
+ environment()->BindAccumulator(node, Environment::kAttachFrameState); |
} |
void BytecodeGraphBuilder::VisitConstructWithSpread() { |
PrepareEagerCheckpoint(); |
interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0); |
- interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
+ interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1); |
size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); |
Node* new_target = environment()->LookupAccumulator(); |
@@ -1612,8 +1647,10 @@ void BytecodeGraphBuilder::VisitConstructWithSpread() { |
const Operator* op = |
javascript()->ConstructWithSpread(static_cast<uint32_t>(reg_count + 2)); |
- Node* value = ProcessConstructWithSpreadArguments(op, callee, new_target, |
- receiver, reg_count); |
+ int arg_count = static_cast<int>(reg_count); |
+ Node* const* args = GetConstructArgumentsFromRegister(callee, new_target, |
+ first_reg, arg_count); |
+ Node* value = ProcessConstructArguments(op, args, 2 + arg_count); |
environment()->BindAccumulator(value, Environment::kAttachFrameState); |
} |
@@ -1630,46 +1667,6 @@ void BytecodeGraphBuilder::VisitInvokeIntrinsic() { |
environment()->BindAccumulator(value, Environment::kAttachFrameState); |
} |
-Node* BytecodeGraphBuilder::ProcessConstructArguments( |
- const Operator* call_new_op, Node* callee, Node* new_target, |
- interpreter::Register receiver, size_t reg_count) { |
- int arg_count = static_cast<int>(reg_count); |
- // arity is args + callee and new target. |
- int arity = arg_count + 2; |
- Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity)); |
- all[0] = callee; |
- int first_arg_index = receiver.index(); |
- for (int i = 0; i < arg_count; ++i) { |
- all[1 + i] = environment()->LookupRegister( |
- interpreter::Register(first_arg_index + i)); |
- } |
- all[arity - 1] = new_target; |
- Node* value = MakeNode(call_new_op, arity, all, false); |
- return value; |
-} |
- |
-void BytecodeGraphBuilder::VisitConstruct() { |
- PrepareEagerCheckpoint(); |
- interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0); |
- interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
- size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); |
- // Slot index of 0 is used indicate no feedback slot is available. Assert |
- // the assumption that slot index 0 is never a valid feedback slot. |
- STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0); |
- int const slot_id = bytecode_iterator().GetIndexOperand(3); |
- VectorSlotPair feedback = CreateVectorSlotPair(slot_id); |
- |
- Node* new_target = environment()->LookupAccumulator(); |
- Node* callee = environment()->LookupRegister(callee_reg); |
- |
- CallFrequency frequency = ComputeCallFrequency(slot_id); |
- const Operator* call = javascript()->Construct( |
- static_cast<uint32_t>(reg_count + 2), frequency, feedback); |
- Node* value = |
- ProcessConstructArguments(call, callee, new_target, receiver, reg_count); |
- environment()->BindAccumulator(value, Environment::kAttachFrameState); |
-} |
- |
void BytecodeGraphBuilder::VisitThrow() { |
BuildLoopExitsForFunctionExit(); |
Node* value = environment()->LookupAccumulator(); |
@@ -2693,6 +2690,25 @@ Node* BytecodeGraphBuilder::TryBuildSimplifiedCall(const Operator* op, |
return nullptr; |
} |
+Node* BytecodeGraphBuilder::TryBuildSimplifiedConstruct(const Operator* op, |
+ Node* const* args, |
+ int arg_count, |
+ FeedbackSlot slot) { |
+ // TODO(mstarzinger,6112): This is a workaround for OSR loop entries being |
+ // pruned from the graph by a soft-deopt. It can happen that a CallIC that |
+ // control-dominates the OSR entry is still in "uninitialized" state. |
+ if (!osr_ast_id_.IsNone()) return nullptr; |
+ Node* effect = environment()->GetEffectDependency(); |
+ Node* control = environment()->GetControlDependency(); |
+ Reduction early_reduction = type_hint_lowering().ReduceConstructOperation( |
+ op, args, arg_count, effect, control, slot); |
+ if (early_reduction.Changed()) { |
+ ApplyEarlyReduction(early_reduction); |
+ return early_reduction.replacement(); |
+ } |
+ return nullptr; |
+} |
+ |
Node* BytecodeGraphBuilder::TryBuildSimplifiedLoadNamed(const Operator* op, |
Node* receiver, |
FeedbackSlot slot) { |