| 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) {
|
|
|