Revision: 22924
Author: [email protected]
Date: Wed Aug 6 11:49:02 2014 UTC
Log: Add deoptimization translations.
BUG=
[email protected], [email protected]
Review URL: https://codereview.chromium.org/442253002
http://code.google.com/p/v8/source/detail?r=22924
Modified:
/branches/bleeding_edge/src/compiler/ast-graph-builder.cc
/branches/bleeding_edge/src/compiler/ast-graph-builder.h
/branches/bleeding_edge/src/compiler/code-generator.cc
/branches/bleeding_edge/src/compiler/code-generator.h
/branches/bleeding_edge/src/compiler/common-operator.h
/branches/bleeding_edge/src/compiler/instruction-selector.cc
/branches/bleeding_edge/src/compiler/instruction-selector.h
/branches/bleeding_edge/src/compiler/instruction.cc
/branches/bleeding_edge/src/compiler/instruction.h
/branches/bleeding_edge/src/compiler/opcodes.h
/branches/bleeding_edge/src/compiler/typer.cc
/branches/bleeding_edge/test/cctest/cctest.status
/branches/bleeding_edge/test/cctest/compiler/test-codegen-deopt.cc
/branches/bleeding_edge/test/cctest/compiler/test-run-deopt.cc
/branches/bleeding_edge/test/cctest/compiler/test-scheduler.cc
=======================================
--- /branches/bleeding_edge/src/compiler/ast-graph-builder.cc Wed Aug 6
08:50:57 2014 UTC
+++ /branches/bleeding_edge/src/compiler/ast-graph-builder.cc Wed Aug 6
11:49:02 2014 UTC
@@ -172,9 +172,9 @@
parameters_node_(NULL),
locals_node_(NULL),
stack_node_(NULL),
- parameters_dirty_(false),
- locals_dirty_(false),
- stack_dirty_(false) {
+ parameters_dirty_(true),
+ locals_dirty_(true),
+ stack_dirty_(true) {
DCHECK_EQ(scope->num_parameters() + 1, parameters_count());
// Bind the receiver variable.
@@ -210,22 +210,40 @@
Node* AstGraphBuilder::Environment::Checkpoint(BailoutId ast_id) {
- UNIMPLEMENTED(); // TODO(mstarzinger): Implementation below is
incomplete.
if (parameters_dirty_) {
- Node** parameters = &values()->front();
- parameters_node_ = graph()->NewNode(NULL, parameters_count(),
parameters);
+ Operator* op = common()->StateValues(parameters_count());
+ if (parameters_count() != 0) {
+ Node** parameters = &values()->front();
+ parameters_node_ = graph()->NewNode(op, parameters_count(),
parameters);
+ } else {
+ parameters_node_ = graph()->NewNode(op);
+ }
parameters_dirty_ = false;
}
if (locals_dirty_) {
- Node** locals = &values()->at(parameters_count_);
- locals_node_ = graph()->NewNode(NULL, locals_count(), locals);
+ Operator* op = common()->StateValues(locals_count());
+ if (locals_count() != 0) {
+ Node** locals = &values()->at(parameters_count_);
+ locals_node_ = graph()->NewNode(op, locals_count(), locals);
+ } else {
+ locals_node_ = graph()->NewNode(op);
+ }
locals_dirty_ = false;
}
- FrameStateDescriptor descriptor(ast_id);
- // TODO(jarin): add environment to the node.
- Operator* op = common()->FrameState(descriptor);
+ if (stack_dirty_) {
+ Operator* op = common()->StateValues(stack_height());
+ if (stack_height() != 0) {
+ Node** stack = &values()->at(parameters_count_ + locals_count_);
+ stack_node_ = graph()->NewNode(op, stack_height(), stack);
+ } else {
+ stack_node_ = graph()->NewNode(op);
+ }
+ stack_dirty_ = false;
+ }
+
+ Operator* op = common()->FrameState(ast_id);
- return graph()->NewNode(op);
+ return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_);
}
@@ -1951,8 +1969,7 @@
NewNode(common()->LazyDeoptimization());
- FrameStateDescriptor stateDescriptor(ast_id);
- Node* state_node = NewNode(common()->FrameState(stateDescriptor));
+ Node* state_node = environment()->Checkpoint(ast_id);
Node* deoptimize_node = NewNode(common()->Deoptimize(), state_node);
=======================================
--- /branches/bleeding_edge/src/compiler/ast-graph-builder.h Mon Aug 4
11:34:54 2014 UTC
+++ /branches/bleeding_edge/src/compiler/ast-graph-builder.h Wed Aug 6
11:49:02 2014 UTC
@@ -236,6 +236,7 @@
DCHECK(stack_height() > 0);
Node* back = values()->back();
values()->pop_back();
+ stack_dirty_ = true;
return back;
}
@@ -244,6 +245,7 @@
DCHECK(depth >= 0 && depth < stack_height());
int index = static_cast<int>(values()->size()) - depth - 1;
values()->at(index) = node;
+ stack_dirty_ = true;
}
Node* Peek(int depth) {
DCHECK(depth >= 0 && depth < stack_height());
@@ -253,6 +255,7 @@
void Drop(int depth) {
DCHECK(depth >= 0 && depth <= stack_height());
values()->erase(values()->end() - depth, values()->end());
+ stack_dirty_ = true;
}
// Preserve a checkpoint of the environment for the IR graph. Any
=======================================
--- /branches/bleeding_edge/src/compiler/code-generator.cc Tue Aug 5
11:53:32 2014 UTC
+++ /branches/bleeding_edge/src/compiler/code-generator.cc Wed Aug 6
11:49:02 2014 UTC
@@ -213,8 +213,8 @@
// Populate deoptimization entries.
for (int i = 0; i < deopt_count; i++) {
- FrameStateDescriptor descriptor = code()->GetDeoptimizationEntry(i);
- data->SetAstId(i, descriptor.bailout_id());
+ FrameStateDescriptor* descriptor = code()->GetDeoptimizationEntry(i);
+ data->SetAstId(i, descriptor->bailout_id());
data->SetTranslationIndex(i, Smi::FromInt(0));
data->SetArgumentsStackHeight(i, Smi::FromInt(0));
data->SetPc(i, Smi::FromInt(-1));
@@ -269,23 +269,60 @@
// We should build translation only once.
DCHECK_EQ(NULL, deoptimization_states_[deoptimization_id]);
- // TODO(jarin) This should build translation codes from the instruction
inputs
- // and from the framestate descriptor. At the moment, we only create a
dummy
- // translation.
-
- FrameStateDescriptor descriptor =
+ FrameStateDescriptor* descriptor =
code()->GetDeoptimizationEntry(deoptimization_id);
Translation translation(&translations_, 1, 1, zone());
- translation.BeginJSFrame(descriptor.bailout_id(),
Translation::kSelfLiteralId,
- 0);
- int undefined_literal_id =
- DefineDeoptimizationLiteral(isolate()->factory()->undefined_value());
- translation.StoreLiteral(undefined_literal_id);
+ translation.BeginJSFrame(descriptor->bailout_id(),
+ Translation::kSelfLiteralId,
+ descriptor->size() -
descriptor->parameters_count());
+
+ for (int i = 0; i < descriptor->size(); i++) {
+ AddTranslationForOperand(&translation, instr, instr->InputAt(i));
+ }
deoptimization_states_[deoptimization_id] =
new (zone()) DeoptimizationState(translation.index());
}
+
+void CodeGenerator::AddTranslationForOperand(Translation* translation,
+ Instruction* instr,
+ InstructionOperand* op) {
+ if (op->IsStackSlot()) {
+ translation->StoreStackSlot(op->index());
+ } else if (op->IsDoubleStackSlot()) {
+ translation->StoreDoubleStackSlot(op->index());
+ } else if (op->IsRegister()) {
+ InstructionOperandConverter converter(this, instr);
+ translation->StoreRegister(converter.ToRegister(op));
+ } else if (op->IsDoubleRegister()) {
+ InstructionOperandConverter converter(this, instr);
+ translation->StoreDoubleRegister(converter.ToDoubleRegister(op));
+ } else if (op->IsImmediate()) {
+ InstructionOperandConverter converter(this, instr);
+ Constant constant = converter.ToConstant(op);
+ Handle<Object> constant_object;
+ switch (constant.type()) {
+ case Constant::kInt32:
+ constant_object =
+ isolate()->factory()->NewNumberFromInt(constant.ToInt32());
+ break;
+ case Constant::kFloat64:
+ constant_object =
+ isolate()->factory()->NewHeapNumber(constant.ToFloat64());
+ break;
+ case Constant::kHeapObject:
+ constant_object = constant.ToHeapObject();
+ break;
+ default:
+ UNREACHABLE();
+ }
+ int literal_id = DefineDeoptimizationLiteral(constant_object);
+ translation->StoreLiteral(literal_id);
+ } else {
+ UNREACHABLE();
+ }
+}
#if !V8_TURBOFAN_BACKEND
@@ -337,7 +374,6 @@
#endif // !V8_TURBOFAN_BACKEND
-
} // namespace compiler
} // namespace internal
} // namespace v8
=======================================
--- /branches/bleeding_edge/src/compiler/code-generator.h Wed Jul 30
13:54:45 2014 UTC
+++ /branches/bleeding_edge/src/compiler/code-generator.h Wed Aug 6
11:49:02 2014 UTC
@@ -85,6 +85,8 @@
void PopulateDeoptimizationData(Handle<Code> code);
int DefineDeoptimizationLiteral(Handle<Object> literal);
void BuildTranslation(Instruction* instr, int deoptimization_id);
+ void AddTranslationForOperand(Translation* translation, Instruction*
instr,
+ InstructionOperand* op);
void AddNopForSmiCodeInlining();
#if DEBUG
static bool IsNopForSmiCodeInlining(Handle<Code> code, int start_pc,
=======================================
--- /branches/bleeding_edge/src/compiler/common-operator.h Tue Aug 5
08:47:39 2014 UTC
+++ /branches/bleeding_edge/src/compiler/common-operator.h Wed Aug 6
11:49:02 2014 UTC
@@ -43,17 +43,6 @@
}
};
-class FrameStateDescriptor {
- public:
- explicit FrameStateDescriptor(BailoutId bailout_id)
- : bailout_id_(bailout_id) {}
-
- BailoutId bailout_id() const { return bailout_id_; }
-
- private:
- BailoutId bailout_id_;
-};
-
// Interface for building common operators that can be used at any level
of IR,
// including JavaScript, mid-level, and low-level.
// TODO(titzer): Move the mnemonics into SimpleOperator and Operator1
classes.
@@ -141,9 +130,13 @@
return new (zone_) Operator1<int>(IrOpcode::kEffectPhi,
Operator::kPure, 0,
0, "EffectPhi", arguments);
}
- Operator* FrameState(const FrameStateDescriptor& descriptor) {
- return new (zone_) Operator1<FrameStateDescriptor>(
- IrOpcode::kFrameState, Operator::kPure, 0, 1, "FrameState",
descriptor);
+ Operator* StateValues(int arguments) {
+ return new (zone_) Operator1<int>(IrOpcode::kStateValues,
Operator::kPure,
+ arguments, 1, "StateValues",
arguments);
+ }
+ Operator* FrameState(BailoutId ast_id) {
+ return new (zone_) Operator1<BailoutId>(
+ IrOpcode::kFrameState, Operator::kPure, 3, 1, "FrameState",
ast_id);
}
Operator* Call(CallDescriptor* descriptor) {
return new (zone_) CallOperator(descriptor, "Call");
=======================================
--- /branches/bleeding_edge/src/compiler/instruction-selector.cc Tue Aug 5
13:26:55 2014 UTC
+++ /branches/bleeding_edge/src/compiler/instruction-selector.cc Wed Aug 6
11:49:02 2014 UTC
@@ -423,7 +423,7 @@
case BasicBlockData::kThrow:
return VisitThrow(input);
case BasicBlockData::kDeoptimize:
- return VisitDeoptimization(input);
+ return VisitDeoptimize(input);
case BasicBlockData::kCall: {
BasicBlock* deoptimization = block->SuccessorAt(0);
BasicBlock* continuation = block->SuccessorAt(1);
@@ -490,7 +490,7 @@
case IrOpcode::kCall:
return VisitCall(node, NULL, NULL);
case IrOpcode::kFrameState:
- // TODO(titzer): state nodes should be combined into their users.
+ case IrOpcode::kStateValues:
return;
case IrOpcode::kLoad: {
MachineRepresentation load_rep =
OpParameter<MachineRepresentation>(node);
@@ -953,15 +953,56 @@
}
-void InstructionSelector::VisitDeoptimization(Node* deopt) {
+static InstructionOperand* UseOrImmediate(OperandGenerator* g, Node*
input) {
+ switch (input->opcode()) {
+ case IrOpcode::kInt32Constant:
+ case IrOpcode::kNumberConstant:
+ case IrOpcode::kFloat64Constant:
+ case IrOpcode::kHeapConstant:
+ return g->UseImmediate(input);
+ default:
+ return g->Use(input);
+ }
+}
+
+
+void InstructionSelector::VisitDeoptimize(Node* deopt) {
DCHECK(deopt->op()->opcode() == IrOpcode::kDeoptimize);
Node* state = deopt->InputAt(0);
DCHECK(state->op()->opcode() == IrOpcode::kFrameState);
- FrameStateDescriptor descriptor =
OpParameter<FrameStateDescriptor>(state);
- // TODO(jarin) We should also add an instruction input for every input to
- // the framestate node (and recurse for the inlined framestates).
+ BailoutId ast_id = OpParameter<BailoutId>(state);
+
+ // Add the inputs.
+ Node* parameters = state->InputAt(0);
+ int parameters_count = OpParameter<int>(parameters);
+
+ Node* locals = state->InputAt(1);
+ int locals_count = OpParameter<int>(locals);
+
+ Node* stack = state->InputAt(2);
+ int stack_count = OpParameter<int>(stack);
+
+ OperandGenerator g(this);
+ std::vector<InstructionOperand*> inputs;
+ inputs.reserve(parameters_count + locals_count + stack_count);
+ for (int i = 0; i < parameters_count; i++) {
+ inputs.push_back(UseOrImmediate(&g, parameters->InputAt(i)));
+ }
+ for (int i = 0; i < locals_count; i++) {
+ inputs.push_back(UseOrImmediate(&g, locals->InputAt(i)));
+ }
+ for (int i = 0; i < stack_count; i++) {
+ inputs.push_back(UseOrImmediate(&g, stack->InputAt(i)));
+ }
+
+ FrameStateDescriptor* descriptor = new (instruction_zone())
+ FrameStateDescriptor(ast_id, parameters_count, locals_count,
stack_count);
+
+ DCHECK_EQ(descriptor->size(), inputs.size());
+
int deoptimization_id = sequence()->AddDeoptimizationEntry(descriptor);
- Emit(kArchDeoptimize | MiscField::encode(deoptimization_id), NULL);
+ Emit(kArchDeoptimize | MiscField::encode(deoptimization_id), 0, NULL,
+ inputs.size(), &inputs.front(), 0, NULL);
}
=======================================
--- /branches/bleeding_edge/src/compiler/instruction-selector.h Tue Aug 5
13:26:55 2014 UTC
+++ /branches/bleeding_edge/src/compiler/instruction-selector.h Wed Aug 6
11:49:02 2014 UTC
@@ -179,7 +179,7 @@
void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch);
void VisitReturn(Node* value);
void VisitThrow(Node* value);
- void VisitDeoptimization(Node* deopt);
+ void VisitDeoptimize(Node* deopt);
//
===========================================================================
=======================================
--- /branches/bleeding_edge/src/compiler/instruction.cc Mon Aug 4 11:34:54
2014 UTC
+++ /branches/bleeding_edge/src/compiler/instruction.cc Wed Aug 6 11:49:02
2014 UTC
@@ -394,13 +394,13 @@
int InstructionSequence::AddDeoptimizationEntry(
- const FrameStateDescriptor& descriptor) {
+ FrameStateDescriptor* descriptor) {
int deoptimization_id = static_cast<int>(deoptimization_entries_.size());
deoptimization_entries_.push_back(descriptor);
return deoptimization_id;
}
-FrameStateDescriptor InstructionSequence::GetDeoptimizationEntry(
+FrameStateDescriptor* InstructionSequence::GetDeoptimizationEntry(
int deoptimization_id) {
return deoptimization_entries_[deoptimization_id];
}
=======================================
--- /branches/bleeding_edge/src/compiler/instruction.h Mon Aug 4 11:34:54
2014 UTC
+++ /branches/bleeding_edge/src/compiler/instruction.h Wed Aug 6 11:49:02
2014 UTC
@@ -694,6 +694,30 @@
int64_t value_;
};
+
+class FrameStateDescriptor : public ZoneObject {
+ public:
+ FrameStateDescriptor(BailoutId bailout_id, int parameters_count,
+ int locals_count, int stack_count)
+ : bailout_id_(bailout_id),
+ parameters_count_(parameters_count),
+ locals_count_(locals_count),
+ stack_count_(stack_count) {}
+
+ BailoutId bailout_id() const { return bailout_id_; }
+ int parameters_count() { return parameters_count_; }
+ int locals_count() { return locals_count_; }
+ int stack_count() { return stack_count_; }
+
+ int size() { return parameters_count_ + locals_count_ + stack_count_; }
+
+ private:
+ BailoutId bailout_id_;
+ int parameters_count_;
+ int locals_count_;
+ int stack_count_;
+};
+
OStream& operator<<(OStream& os, const Constant& constant);
typedef std::deque<Constant, zone_allocator<Constant> > ConstantDeque;
@@ -704,7 +728,8 @@
typedef std::deque<Instruction*, zone_allocator<Instruction*> >
InstructionDeque;
typedef std::deque<PointerMap*, zone_allocator<PointerMap*> >
PointerMapDeque;
-typedef std::vector<FrameStateDescriptor,
zone_allocator<FrameStateDescriptor> >
+typedef std::vector<FrameStateDescriptor*,
+ zone_allocator<FrameStateDescriptor*> >
DeoptimizationVector;
@@ -814,8 +839,8 @@
return immediates_[index];
}
- int AddDeoptimizationEntry(const FrameStateDescriptor& descriptor);
- FrameStateDescriptor GetDeoptimizationEntry(int deoptimization_id);
+ int AddDeoptimizationEntry(FrameStateDescriptor* descriptor);
+ FrameStateDescriptor* GetDeoptimizationEntry(int deoptimization_id);
int GetDeoptimizationEntryCount();
private:
=======================================
--- /branches/bleeding_edge/src/compiler/opcodes.h Tue Aug 5 08:47:39 2014
UTC
+++ /branches/bleeding_edge/src/compiler/opcodes.h Wed Aug 6 11:49:02 2014
UTC
@@ -34,6 +34,7 @@
V(Phi) \
V(EffectPhi) \
V(FrameState) \
+ V(StateValues) \
V(Call) \
V(Parameter) \
V(Projection)
=======================================
--- /branches/bleeding_edge/src/compiler/typer.cc Tue Aug 5 13:19:32 2014
UTC
+++ /branches/bleeding_edge/src/compiler/typer.cc Wed Aug 6 11:49:02 2014
UTC
@@ -270,6 +270,11 @@
Bounds Typer::Visitor::TypeFrameState(Node* node) {
return Bounds(Type::None(zone()));
}
+
+
+Bounds Typer::Visitor::TypeStateValues(Node* node) {
+ return Bounds(Type::None(zone()));
+}
Bounds Typer::Visitor::TypeCall(Node* node) {
=======================================
--- /branches/bleeding_edge/test/cctest/cctest.status Wed Aug 6 11:38:51
2014 UTC
+++ /branches/bleeding_edge/test/cctest/cctest.status Wed Aug 6 11:49:02
2014 UTC
@@ -79,9 +79,6 @@
##############################################################################
# TurboFan compiler failures.
- # TODO(jarin): Lazy deoptimization test.
- 'test-run-deopt/TurboSimpleDeopt': [SKIP],
-
# TODO(mstarzinger): These need investigation and are not categorized
yet.
'test-cpu-profiler/*': [SKIP],
'test-heap/NextCodeLinkIsWeak': [PASS, NO_VARIANTS],
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-codegen-deopt.cc Mon
Aug 4 11:34:54 2014 UTC
+++ /branches/bleeding_edge/test/cctest/compiler/test-codegen-deopt.cc Wed
Aug 6 11:49:02 2014 UTC
@@ -149,8 +149,12 @@
m.NewNode(common.LazyDeoptimization(), call);
bailout_id = GetCallBailoutId();
- FrameStateDescriptor stateDescriptor(bailout_id);
- Node* state_node = m.NewNode(common.FrameState(stateDescriptor));
+ Node* parameters = m.NewNode(common.StateValues(1), undef_node);
+ Node* locals = m.NewNode(common.StateValues(0));
+ Node* stack = m.NewNode(common.StateValues(0));
+
+ Node* state_node =
+ m.NewNode(common.FrameState(bailout_id), parameters, locals,
stack);
m.Deoptimize(state_node);
// Schedule the graph:
@@ -280,8 +284,12 @@
m.NewNode(common.LazyDeoptimization(), call);
bailout_id = GetCallBailoutId();
- FrameStateDescriptor stateDescriptor(bailout_id);
- Node* state_node = m.NewNode(common.FrameState(stateDescriptor));
+ Node* parameters = m.NewNode(common.StateValues(1), undef_node);
+ Node* locals = m.NewNode(common.StateValues(0));
+ Node* stack = m.NewNode(common.StateValues(0));
+
+ Node* state_node =
+ m.NewNode(common.FrameState(bailout_id), parameters, locals,
stack);
m.Deoptimize(state_node);
// Schedule the graph:
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-run-deopt.cc Wed Jul
30 15:35:29 2014 UTC
+++ /branches/bleeding_edge/test/cctest/compiler/test-run-deopt.cc Wed Aug
6 11:49:02 2014 UTC
@@ -9,6 +9,7 @@
using namespace v8::internal;
using namespace v8::internal::compiler;
+#if V8_TURBOFAN_TARGET
TEST(TurboSimpleDeopt) {
FLAG_allow_natives_syntax = true;
@@ -26,6 +27,24 @@
}
+TEST(TurboSimpleDeoptInExpr) {
+ FLAG_allow_natives_syntax = true;
+ FLAG_turbo_deoptimization = true;
+
+ FunctionTester T(
+ "(function f(a) {"
+ "var b = 1;"
+ "var c = 2;"
+ "if (!%IsOptimized()) return 0;"
+ "var d = b + (%DeoptimizeFunction(f), c);"
+ "if (%IsOptimized()) return 0;"
+ "return d + a; })");
+
+ T.CheckCall(T.Val(6), T.Val(3));
+}
+
+#endif
+
TEST(TurboTrivialDeopt) {
FLAG_allow_natives_syntax = true;
FLAG_turbo_deoptimization = true;
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-scheduler.cc Tue Aug
5 11:53:32 2014 UTC
+++ /branches/bleeding_edge/test/cctest/compiler/test-scheduler.cc Wed Aug
6 11:49:02 2014 UTC
@@ -1716,7 +1716,7 @@
HandleAndZoneScope scope;
Isolate* isolate = scope.main_isolate();
Graph graph(scope.main_zone());
- CommonOperatorBuilder common_builder(scope.main_zone());
+ CommonOperatorBuilder common(scope.main_zone());
JSOperatorBuilder js_builder(scope.main_zone());
InitializedHandleScope handles;
@@ -1761,37 +1761,40 @@
PrintableUnique<Object>::CreateUninitialized(scope.main_zone(),
undef_object);
- Node* undef_node =
graph.NewNode(common_builder.HeapConstant(undef_constant));
+ Node* undef_node = graph.NewNode(common.HeapConstant(undef_constant));
- Node* start_node = graph.NewNode(common_builder.Start(0));
+ Node* start_node = graph.NewNode(common.Start(0));
CallDescriptor* descriptor = linkage.GetJSCallDescriptor(0);
- Node* call_node = graph.NewNode(common_builder.Call(descriptor),
+ Node* call_node = graph.NewNode(common.Call(descriptor),
undef_node, // function
undef_node, // context
start_node, // effect
start_node); // control
- Node* cont_node = graph.NewNode(common_builder.Continuation(),
call_node);
- Node* lazy_deopt_node =
- graph.NewNode(common_builder.LazyDeoptimization(), call_node);
+ Node* cont_node = graph.NewNode(common.Continuation(), call_node);
+ Node* lazy_deopt_node = graph.NewNode(common.LazyDeoptimization(),
call_node);
- FrameStateDescriptor stateDescriptor(BailoutId(1234));
- Node* state_node =
graph.NewNode(common_builder.FrameState(stateDescriptor));
+ Node* parameters = graph.NewNode(common.StateValues(1), undef_node);
+ Node* locals = graph.NewNode(common.StateValues(0));
+ Node* stack = graph.NewNode(common.StateValues(0));
- Node* return_node = graph.NewNode(common_builder.Return(),
+ Node* state_node = graph.NewNode(common.FrameState(BailoutId(1234)),
+ parameters, locals, stack);
+
+ Node* return_node = graph.NewNode(common.Return(),
undef_node, // return value
call_node, // effect
cont_node); // control
- Node* deoptimization_node = graph.NewNode(common_builder.Deoptimize(),
+ Node* deoptimization_node = graph.NewNode(common.Deoptimize(),
state_node, // deopt
environment
call_node, // effect
lazy_deopt_node); // control
Node* merge_node =
- graph.NewNode(common_builder.Merge(2), return_node,
deoptimization_node);
+ graph.NewNode(common.Merge(2), return_node, deoptimization_node);
- Node* end_node = graph.NewNode(common_builder.End(), merge_node);
+ Node* end_node = graph.NewNode(common.End(), merge_node);
graph.SetStart(start_node);
graph.SetEnd(end_node);
@@ -1824,9 +1827,12 @@
CHECK(!cont_block->deferred_);
// The lazy deopt block contains framestate + bailout (and nothing else).
CHECK_EQ(deoptimization_node, deopt_block->control_input_);
- CHECK_EQ(2, static_cast<int>(deopt_block->nodes_.size()));
+ CHECK_EQ(5, static_cast<int>(deopt_block->nodes_.size()));
CHECK_EQ(lazy_deopt_node, deopt_block->nodes_[0]);
- CHECK_EQ(state_node, deopt_block->nodes_[1]);
+ CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[1]->op()->opcode());
+ CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[2]->op()->opcode());
+ CHECK_EQ(IrOpcode::kStateValues, deopt_block->nodes_[3]->op()->opcode());
+ CHECK_EQ(state_node, deopt_block->nodes_[4]);
}
#endif
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.