Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: src/compiler/bytecode-graph-builder.cc

Issue 2958253002: [turbofan] Replace uninitialized JSConstruct nodes with SOFT deopt. (Closed)
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/bytecode-graph-builder.h ('k') | src/compiler/js-call-reducer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/bytecode-graph-builder.h" 5 #include "src/compiler/bytecode-graph-builder.h"
6 6
7 #include "src/ast/ast.h" 7 #include "src/ast/ast.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/compiler/access-builder.h" 9 #include "src/compiler/access-builder.h"
10 #include "src/compiler/compiler-source-position-table.h" 10 #include "src/compiler/compiler-source-position-table.h"
(...skipping 1565 matching lines...) Expand 10 before | Expand all | Expand 10 after
1576 interpreter::Register first_return = 1576 interpreter::Register first_return =
1577 bytecode_iterator().GetRegisterOperand(3); 1577 bytecode_iterator().GetRegisterOperand(3);
1578 1578
1579 // Create node to perform the runtime call. 1579 // Create node to perform the runtime call.
1580 const Operator* call = javascript()->CallRuntime(functionId, reg_count); 1580 const Operator* call = javascript()->CallRuntime(functionId, reg_count);
1581 Node* return_pair = ProcessCallRuntimeArguments(call, receiver, reg_count); 1581 Node* return_pair = ProcessCallRuntimeArguments(call, receiver, reg_count);
1582 environment()->BindRegistersToProjections(first_return, return_pair, 1582 environment()->BindRegistersToProjections(first_return, return_pair,
1583 Environment::kAttachFrameState); 1583 Environment::kAttachFrameState);
1584 } 1584 }
1585 1585
1586 Node* BytecodeGraphBuilder::ProcessConstructWithSpreadArguments( 1586 Node* const* BytecodeGraphBuilder::GetConstructArgumentsFromRegister(
1587 const Operator* op, Node* callee, Node* new_target, 1587 Node* target, Node* new_target, interpreter::Register first_arg,
1588 interpreter::Register receiver, size_t reg_count) { 1588 int arg_count) {
1589 int arg_count = static_cast<int>(reg_count);
1590 // arity is args + callee and new target. 1589 // arity is args + callee and new target.
1591 int arity = arg_count + 2; 1590 int arity = arg_count + 2;
1592 Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity)); 1591 Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
1593 all[0] = callee; 1592 all[0] = target;
1594 int first_arg_index = receiver.index(); 1593 int first_arg_index = first_arg.index();
1595 for (int i = 0; i < arg_count; ++i) { 1594 for (int i = 0; i < arg_count; ++i) {
1596 all[1 + i] = environment()->LookupRegister( 1595 all[1 + i] = environment()->LookupRegister(
1597 interpreter::Register(first_arg_index + i)); 1596 interpreter::Register(first_arg_index + i));
1598 } 1597 }
1599 all[arity - 1] = new_target; 1598 all[arity - 1] = new_target;
1600 Node* value = MakeNode(op, arity, all, false); 1599 return all;
1601 return value; 1600 }
1601
1602 Node* BytecodeGraphBuilder::ProcessConstructArguments(const Operator* op,
1603 Node* const* args,
1604 int arg_count) {
1605 return MakeNode(op, arg_count, args, false);
1606 }
1607
1608 void BytecodeGraphBuilder::VisitConstruct() {
1609 PrepareEagerCheckpoint();
1610 interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
1611 interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
1612 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1613 // Slot index of 0 is used indicate no feedback slot is available. Assert
1614 // the assumption that slot index 0 is never a valid feedback slot.
1615 STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0);
1616 int const slot_id = bytecode_iterator().GetIndexOperand(3);
1617 VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
1618
1619 Node* new_target = environment()->LookupAccumulator();
1620 Node* callee = environment()->LookupRegister(callee_reg);
1621
1622 CallFrequency frequency = ComputeCallFrequency(slot_id);
1623 const Operator* op = javascript()->Construct(
1624 static_cast<uint32_t>(reg_count + 2), frequency, feedback);
1625 int arg_count = static_cast<int>(reg_count);
1626 Node* const* args = GetConstructArgumentsFromRegister(callee, new_target,
1627 first_reg, arg_count);
1628 Node* node = nullptr;
1629 if (Node* simplified = TryBuildSimplifiedConstruct(
1630 op, args, static_cast<int>(arg_count), feedback.slot())) {
1631 if (environment() == nullptr) return;
1632 node = simplified;
1633 } else {
1634 node = ProcessConstructArguments(op, args, 2 + arg_count);
1635 }
1636 environment()->BindAccumulator(node, Environment::kAttachFrameState);
1602 } 1637 }
1603 1638
1604 void BytecodeGraphBuilder::VisitConstructWithSpread() { 1639 void BytecodeGraphBuilder::VisitConstructWithSpread() {
1605 PrepareEagerCheckpoint(); 1640 PrepareEagerCheckpoint();
1606 interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0); 1641 interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
1607 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); 1642 interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
1608 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); 1643 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1609 1644
1610 Node* new_target = environment()->LookupAccumulator(); 1645 Node* new_target = environment()->LookupAccumulator();
1611 Node* callee = environment()->LookupRegister(callee_reg); 1646 Node* callee = environment()->LookupRegister(callee_reg);
1612 1647
1613 const Operator* op = 1648 const Operator* op =
1614 javascript()->ConstructWithSpread(static_cast<uint32_t>(reg_count + 2)); 1649 javascript()->ConstructWithSpread(static_cast<uint32_t>(reg_count + 2));
1615 Node* value = ProcessConstructWithSpreadArguments(op, callee, new_target, 1650 int arg_count = static_cast<int>(reg_count);
1616 receiver, reg_count); 1651 Node* const* args = GetConstructArgumentsFromRegister(callee, new_target,
1652 first_reg, arg_count);
1653 Node* value = ProcessConstructArguments(op, args, 2 + arg_count);
1617 environment()->BindAccumulator(value, Environment::kAttachFrameState); 1654 environment()->BindAccumulator(value, Environment::kAttachFrameState);
1618 } 1655 }
1619 1656
1620 void BytecodeGraphBuilder::VisitInvokeIntrinsic() { 1657 void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
1621 PrepareEagerCheckpoint(); 1658 PrepareEagerCheckpoint();
1622 Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0); 1659 Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0);
1623 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); 1660 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1624 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2); 1661 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1625 1662
1626 // Create node to perform the runtime call. Turbofan will take care of the 1663 // Create node to perform the runtime call. Turbofan will take care of the
1627 // lowering. 1664 // lowering.
1628 const Operator* call = javascript()->CallRuntime(functionId, reg_count); 1665 const Operator* call = javascript()->CallRuntime(functionId, reg_count);
1629 Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count); 1666 Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
1630 environment()->BindAccumulator(value, Environment::kAttachFrameState); 1667 environment()->BindAccumulator(value, Environment::kAttachFrameState);
1631 } 1668 }
1632 1669
1633 Node* BytecodeGraphBuilder::ProcessConstructArguments(
1634 const Operator* call_new_op, Node* callee, Node* new_target,
1635 interpreter::Register receiver, size_t reg_count) {
1636 int arg_count = static_cast<int>(reg_count);
1637 // arity is args + callee and new target.
1638 int arity = arg_count + 2;
1639 Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
1640 all[0] = callee;
1641 int first_arg_index = receiver.index();
1642 for (int i = 0; i < arg_count; ++i) {
1643 all[1 + i] = environment()->LookupRegister(
1644 interpreter::Register(first_arg_index + i));
1645 }
1646 all[arity - 1] = new_target;
1647 Node* value = MakeNode(call_new_op, arity, all, false);
1648 return value;
1649 }
1650
1651 void BytecodeGraphBuilder::VisitConstruct() {
1652 PrepareEagerCheckpoint();
1653 interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
1654 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1655 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1656 // Slot index of 0 is used indicate no feedback slot is available. Assert
1657 // the assumption that slot index 0 is never a valid feedback slot.
1658 STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0);
1659 int const slot_id = bytecode_iterator().GetIndexOperand(3);
1660 VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
1661
1662 Node* new_target = environment()->LookupAccumulator();
1663 Node* callee = environment()->LookupRegister(callee_reg);
1664
1665 CallFrequency frequency = ComputeCallFrequency(slot_id);
1666 const Operator* call = javascript()->Construct(
1667 static_cast<uint32_t>(reg_count + 2), frequency, feedback);
1668 Node* value =
1669 ProcessConstructArguments(call, callee, new_target, receiver, reg_count);
1670 environment()->BindAccumulator(value, Environment::kAttachFrameState);
1671 }
1672
1673 void BytecodeGraphBuilder::VisitThrow() { 1670 void BytecodeGraphBuilder::VisitThrow() {
1674 BuildLoopExitsForFunctionExit(); 1671 BuildLoopExitsForFunctionExit();
1675 Node* value = environment()->LookupAccumulator(); 1672 Node* value = environment()->LookupAccumulator();
1676 Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value); 1673 Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
1677 environment()->BindAccumulator(call, Environment::kAttachFrameState); 1674 environment()->BindAccumulator(call, Environment::kAttachFrameState);
1678 Node* control = NewNode(common()->Throw()); 1675 Node* control = NewNode(common()->Throw());
1679 MergeControlToLeaveFunction(control); 1676 MergeControlToLeaveFunction(control);
1680 } 1677 }
1681 1678
1682 void BytecodeGraphBuilder::VisitReThrow() { 1679 void BytecodeGraphBuilder::VisitReThrow() {
(...skipping 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after
2686 Node* control = environment()->GetControlDependency(); 2683 Node* control = environment()->GetControlDependency();
2687 Reduction early_reduction = type_hint_lowering().ReduceCallOperation( 2684 Reduction early_reduction = type_hint_lowering().ReduceCallOperation(
2688 op, args, arg_count, effect, control, slot); 2685 op, args, arg_count, effect, control, slot);
2689 if (early_reduction.Changed()) { 2686 if (early_reduction.Changed()) {
2690 ApplyEarlyReduction(early_reduction); 2687 ApplyEarlyReduction(early_reduction);
2691 return early_reduction.replacement(); 2688 return early_reduction.replacement();
2692 } 2689 }
2693 return nullptr; 2690 return nullptr;
2694 } 2691 }
2695 2692
2693 Node* BytecodeGraphBuilder::TryBuildSimplifiedConstruct(const Operator* op,
2694 Node* const* args,
2695 int arg_count,
2696 FeedbackSlot slot) {
2697 // TODO(mstarzinger,6112): This is a workaround for OSR loop entries being
2698 // pruned from the graph by a soft-deopt. It can happen that a CallIC that
2699 // control-dominates the OSR entry is still in "uninitialized" state.
2700 if (!osr_ast_id_.IsNone()) return nullptr;
2701 Node* effect = environment()->GetEffectDependency();
2702 Node* control = environment()->GetControlDependency();
2703 Reduction early_reduction = type_hint_lowering().ReduceConstructOperation(
2704 op, args, arg_count, effect, control, slot);
2705 if (early_reduction.Changed()) {
2706 ApplyEarlyReduction(early_reduction);
2707 return early_reduction.replacement();
2708 }
2709 return nullptr;
2710 }
2711
2696 Node* BytecodeGraphBuilder::TryBuildSimplifiedLoadNamed(const Operator* op, 2712 Node* BytecodeGraphBuilder::TryBuildSimplifiedLoadNamed(const Operator* op,
2697 Node* receiver, 2713 Node* receiver,
2698 FeedbackSlot slot) { 2714 FeedbackSlot slot) {
2699 // TODO(mstarzinger,6112): This is a workaround for OSR loop entries being 2715 // TODO(mstarzinger,6112): This is a workaround for OSR loop entries being
2700 // pruned from the graph by a soft-deopt. It can happen that a LoadIC that 2716 // pruned from the graph by a soft-deopt. It can happen that a LoadIC that
2701 // control-dominates the OSR entry is still in "uninitialized" state. 2717 // control-dominates the OSR entry is still in "uninitialized" state.
2702 if (bytecode_analysis()->HasOSREntryPoint()) return nullptr; 2718 if (bytecode_analysis()->HasOSREntryPoint()) return nullptr;
2703 Node* effect = environment()->GetEffectDependency(); 2719 Node* effect = environment()->GetEffectDependency();
2704 Node* control = environment()->GetControlDependency(); 2720 Node* control = environment()->GetControlDependency();
2705 Reduction early_reduction = type_hint_lowering().ReduceLoadNamedOperation( 2721 Reduction early_reduction = type_hint_lowering().ReduceLoadNamedOperation(
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
2979 it->source_position().ScriptOffset(), start_position_.InliningId())); 2995 it->source_position().ScriptOffset(), start_position_.InliningId()));
2980 it->Advance(); 2996 it->Advance();
2981 } else { 2997 } else {
2982 DCHECK_GT(it->code_offset(), offset); 2998 DCHECK_GT(it->code_offset(), offset);
2983 } 2999 }
2984 } 3000 }
2985 3001
2986 } // namespace compiler 3002 } // namespace compiler
2987 } // namespace internal 3003 } // namespace internal
2988 } // namespace v8 3004 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/bytecode-graph-builder.h ('k') | src/compiler/js-call-reducer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698