Reviewers: Benedikt Meurer,
Message:
First round of comments before I do the ports would be awesome. Thanks!
Description:
Emit exception handler table in TurboFan.
[email protected]
Please review this at https://codereview.chromium.org/943503003/
Base URL: https://chromium.googlesource.com/v8/v8.git@local_trycatch-4
Affected files (+64, -18 lines):
M src/compiler/code-generator.h
M src/compiler/code-generator.cc
M src/compiler/ia32/code-generator-ia32.cc
M src/compiler/ia32/instruction-selector-ia32.cc
M src/compiler/instruction-selector.h
M src/compiler/instruction-selector.cc
M src/compiler/linkage.h
M src/objects.cc
Index: src/compiler/code-generator.cc
diff --git a/src/compiler/code-generator.cc b/src/compiler/code-generator.cc
index
1a4566d60994dbba96e72fcde285c215d5f2120e..9a466cfc77c70d54b4428d1fb699db82b9f9c954
100644
--- a/src/compiler/code-generator.cc
+++ b/src/compiler/code-generator.cc
@@ -42,6 +42,7 @@ CodeGenerator::CodeGenerator(Frame* frame, Linkage*
linkage,
masm_(info->isolate(), NULL, 0),
resolver_(this),
safepoints_(code->zone()),
+ handlers_(code->zone()),
deoptimization_states_(code->zone()),
deoptimization_literals_(code->zone()),
translations_(code->zone()),
@@ -131,6 +132,18 @@ Handle<Code> CodeGenerator::GenerateCode() {
result->set_stack_slots(frame()->GetSpillSlotCount());
result->set_safepoint_table_offset(safepoints()->GetCodeOffset());
+ // Emit exception handler table.
+ if (handlers_.size() > 0) {
+ Handle<FixedArray> table =
+ isolate()->factory()->NewFixedArray(handlers_.size() * 2, TENURED);
+ for (size_t i = 0; i < handlers_.size(); ++i) {
+ int table_index = static_cast<int>(i * 2);
+ table->set(table_index + 0, Smi::FromInt(handlers_[i].pc_offset));
+ table->set(table_index + 1,
Smi::FromInt(handlers_[i].handler->pos()));
+ }
+ result->set_handler_table(*table);
+ }
+
PopulateDeoptimizationData(result);
// Ensure there is space for lazy deoptimization in the relocation info.
@@ -321,7 +334,7 @@ Label* CodeGenerator::AddJumpTable(Label** targets,
size_t target_count) {
}
-void CodeGenerator::AddSafepointAndDeopt(Instruction* instr) {
+void CodeGenerator::AddSafepointAndDeoptAndHandler(Instruction* instr) {
CallDescriptor::Flags flags(MiscField::decode(instr->opcode()));
bool needs_frame_state = (flags & CallDescriptor::kNeedsFrameState);
@@ -330,16 +343,21 @@ void CodeGenerator::AddSafepointAndDeopt(Instruction*
instr) {
instr->pointer_map(), Safepoint::kSimple, 0,
needs_frame_state ? Safepoint::kLazyDeopt : Safepoint::kNoLazyDeopt);
+ if (flags & CallDescriptor::kHasExceptionHandler) {
+ InstructionOperandConverter i(this, instr);
+ BasicBlock::RpoNumber handler_rpo =
+ i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
+ handlers_.push_back({GetLabel(handler_rpo), masm()->pc_offset()});
+ }
+
if (flags & CallDescriptor::kNeedsNopAfterCall) {
AddNopForSmiCodeInlining();
}
if (needs_frame_state) {
MarkLazyDeoptSite();
- // If the frame state is present, it starts at argument 1
- // (just after the code address).
- InstructionOperandConverter converter(this, instr);
- // Deoptimization info starts at argument 1
+ // If the frame state is present, it starts at argument 1 (just after
the
+ // code address).
size_t frame_state_offset = 1;
FrameStateDescriptor* descriptor =
GetFrameStateDescriptor(instr, frame_state_offset);
Index: src/compiler/code-generator.h
diff --git a/src/compiler/code-generator.h b/src/compiler/code-generator.h
index
658394b3217ad79b00bfe632425f495dfd3f13e9..d563ab7a2554c8f6ecc328693b7cb078230b2790
100644
--- a/src/compiler/code-generator.h
+++ b/src/compiler/code-generator.h
@@ -27,6 +27,12 @@ struct BranchInfo {
};
+struct HandlerInfo {
+ Label* handler;
+ int pc_offset;
+};
+
+
// Generates native code for a sequence of instructions.
class CodeGenerator FINAL : public GapResolver::Assembler {
public:
@@ -106,8 +112,10 @@ class CodeGenerator FINAL : public
GapResolver::Assembler {
void AssembleJumpTable(Label** targets, size_t target_count);
//
===========================================================================
- // Deoptimization table construction
- void AddSafepointAndDeopt(Instruction* instr);
+ // ================== Deoptimization table construction.
=====================
+ //
===========================================================================
+
+ void AddSafepointAndDeoptAndHandler(Instruction* instr);
void PopulateDeoptimizationData(Handle<Code> code);
int DefineDeoptimizationLiteral(Handle<Object> literal);
FrameStateDescriptor* GetFrameStateDescriptor(Instruction* instr,
@@ -155,8 +163,9 @@ class CodeGenerator FINAL : public
GapResolver::Assembler {
MacroAssembler masm_;
GapResolver resolver_;
SafepointTableBuilder safepoints_;
+ ZoneVector<HandlerInfo> handlers_;
ZoneDeque<DeoptimizationState*> deoptimization_states_;
- ZoneDeque<Handle<Object> > deoptimization_literals_;
+ ZoneDeque<Handle<Object>> deoptimization_literals_;
TranslationBuffer translations_;
int last_lazy_deopt_pc_;
JumpTable* jump_tables_;
Index: src/compiler/ia32/code-generator-ia32.cc
diff --git a/src/compiler/ia32/code-generator-ia32.cc
b/src/compiler/ia32/code-generator-ia32.cc
index
d20848918d30aad46f247217479f0e6b9e39544c..1bf3ffdb792c13347692350099aa681776396a24
100644
--- a/src/compiler/ia32/code-generator-ia32.cc
+++ b/src/compiler/ia32/code-generator-ia32.cc
@@ -292,7 +292,7 @@ void
CodeGenerator::AssembleArchInstruction(Instruction* instr) {
Register reg = i.InputRegister(0);
__ call(Operand(reg, Code::kHeaderSize - kHeapObjectTag));
}
- AddSafepointAndDeopt(instr);
+ AddSafepointAndDeoptAndHandler(instr);
break;
}
case kArchCallJSFunction: {
@@ -304,7 +304,7 @@ void
CodeGenerator::AssembleArchInstruction(Instruction* instr) {
__ Assert(equal, kWrongFunctionContext);
}
__ call(FieldOperand(func, JSFunction::kCodeEntryOffset));
- AddSafepointAndDeopt(instr);
+ AddSafepointAndDeoptAndHandler(instr);
break;
}
case kArchJmp:
Index: src/compiler/ia32/instruction-selector-ia32.cc
diff --git a/src/compiler/ia32/instruction-selector-ia32.cc
b/src/compiler/ia32/instruction-selector-ia32.cc
index
beec701903ec4598f26fb3d093b7898b2ea27804..2ca56a480e9579b4e023f41d88329d541caaf503
100644
--- a/src/compiler/ia32/instruction-selector-ia32.cc
+++ b/src/compiler/ia32/instruction-selector-ia32.cc
@@ -718,7 +718,7 @@ void
InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
}
-void InstructionSelector::VisitCall(Node* node) {
+void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
IA32OperandGenerator g(this);
const CallDescriptor* descriptor = OpParameter<const
CallDescriptor*>(node);
@@ -745,6 +745,13 @@ void InstructionSelector::VisitCall(Node* node) {
Emit(kIA32Push, g.NoOutput(), value);
}
+ // Pass label of exception handler block.
+ CallDescriptor::Flags flags;
+ if (handler != nullptr) {
+ flags |= CallDescriptor::kHasExceptionHandler;
+ buffer.instruction_args.push_back(g.Label(handler));
+ }
+
// Select the appropriate opcode based on the call type.
InstructionCode opcode;
switch (descriptor->kind()) {
@@ -759,7 +766,7 @@ void InstructionSelector::VisitCall(Node* node) {
UNREACHABLE();
return;
}
- opcode |= MiscField::encode(descriptor->flags());
+ opcode |= MiscField::encode(descriptor->flags() | flags);
// Emit the call instruction.
InstructionOperand* first_output =
Index: src/compiler/instruction-selector.cc
diff --git a/src/compiler/instruction-selector.cc
b/src/compiler/instruction-selector.cc
index
2d0b2bd8af18c44af2b4691d306ee2ed42713045..d007fbf13d57fc00e8b20c6455bc981ad176633a
100644
--- a/src/compiler/instruction-selector.cc
+++ b/src/compiler/instruction-selector.cc
@@ -505,9 +505,8 @@ void InstructionSelector::VisitControl(BasicBlock*
block) {
case BasicBlock::kCall: {
DCHECK_EQ(IrOpcode::kCall, input->opcode());
BasicBlock* success = block->SuccessorAt(0);
- // TODO(mstarzinger): Record location of {exception} in
{handler_table}.
- // BasicBlock* exception = block->SuccessorAt(1);
- return VisitCall(input), VisitGoto(success);
+ BasicBlock* exception = block->SuccessorAt(1);
+ return VisitCall(input, exception), VisitGoto(success);
}
case BasicBlock::kBranch: {
DCHECK_EQ(IrOpcode::kBranch, input->opcode());
@@ -756,7 +755,7 @@ void InstructionSelector::VisitNode(Node* node) {
return VisitConstant(node);
}
case IrOpcode::kCall:
- return VisitCall(node);
+ return VisitCall(node, nullptr);
case IrOpcode::kFrameState:
case IrOpcode::kStateValues:
return;
Index: src/compiler/instruction-selector.h
diff --git a/src/compiler/instruction-selector.h
b/src/compiler/instruction-selector.h
index
5c31db74e9a158dd495283fbfe3f119768850530..0776ec54fc2196db8213197a2bb361779d27a02c
100644
--- a/src/compiler/instruction-selector.h
+++ b/src/compiler/instruction-selector.h
@@ -199,7 +199,7 @@ class InstructionSelector FINAL {
void VisitPhi(Node* node);
void VisitProjection(Node* node);
void VisitConstant(Node* node);
- void VisitCall(Node* call);
+ void VisitCall(Node* call, BasicBlock* handler);
void VisitGoto(BasicBlock* target);
void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch);
void VisitSwitch(Node* node, BasicBlock* default_branch,
Index: src/compiler/linkage.h
diff --git a/src/compiler/linkage.h b/src/compiler/linkage.h
index
a3bdbf9d5bc84671a8441f1ca80c7a5c6c728c9f..a4b587dc4499407ec711d7896d70ed21d9b94736
100644
--- a/src/compiler/linkage.h
+++ b/src/compiler/linkage.h
@@ -56,11 +56,11 @@ class CallDescriptor FINAL : public ZoneObject {
};
enum Flag {
- // TODO(jarin) kLazyDeoptimization and kNeedsFrameState should be
unified.
kNoFlags = 0u,
kNeedsFrameState = 1u << 0,
kPatchableCallSite = 1u << 1,
kNeedsNopAfterCall = 1u << 2,
+ kHasExceptionHandler = 1u << 3,
kPatchableCallSiteWithNop = kPatchableCallSite | kNeedsNopAfterCall
};
typedef base::Flags<Flag> Flags;
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index
7459ed4525b2d96df98729803fddc17fbbdf2227..c5285e6ee6591554f598f858bfab2d218a3accc9
100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -11713,6 +11713,19 @@ void Code::Disassemble(const char* name,
std::ostream& os) { // NOLINT
#endif
}
+ if (handler_table()->length() > 0 && is_turbofanned()) {
+ os << "Handler Table (size = " << handler_table()->Size() << ")\n";
+ for (int i = 0; i < handler_table()->length(); i += 2) {
+ int pc_offset = Smi::cast(handler_table()->get(i))->value();
+ int handler = Smi::cast(handler_table()->get(i + 1))->value();
+ os << static_cast<const void*>(instruction_start() + pc_offset)
<< " ";
+ Vector<char> buf = Vector<char>::New(20);
+ SNPrintF(buf, "%4d %4d\n", pc_offset, handler);
+ os << buf.start();
+ }
+ os << "\n";
+ }
+
os << "RelocInfo (size = " << relocation_size() << ")\n";
for (RelocIterator it(this); !it.done(); it.next()) {
it.rinfo()->Print(GetIsolate(), os);
--
--
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.