Finish control flow after throw if not inlined.

R=jkummerow@chromium.org
BUG=v8:2868

Review URL: https://codereview.chromium.org/24768002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16992 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yangguo@chromium.org 2013-09-27 13:48:19 +00:00
parent 7f1fd5e16c
commit 2dec4372d8
6 changed files with 47 additions and 0 deletions

View File

@ -1885,6 +1885,13 @@ LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation(
} }
LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
// The control instruction marking the end of a block that completed
// abruptly (e.g., threw an exception). There is nothing specific to do.
return NULL;
}
LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
LOperand* value = UseFixed(instr->value(), r0); LOperand* value = UseFixed(instr->value(), r0);
return MarkAsCall(new(zone()) LThrow(value), instr); return MarkAsCall(new(zone()) LThrow(value), instr);

View File

@ -64,6 +64,7 @@ class LChunkBuilder;
#define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \ #define HYDROGEN_CONCRETE_INSTRUCTION_LIST(V) \
V(AbnormalExit) \
V(AccessArgumentsAt) \ V(AccessArgumentsAt) \
V(Add) \ V(Add) \
V(Allocate) \ V(Allocate) \
@ -1457,6 +1458,16 @@ class HReturn V8_FINAL : public HTemplateControlInstruction<0, 3> {
}; };
class HAbnormalExit V8_FINAL : public HTemplateControlInstruction<0, 0> {
public:
virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
return Representation::None();
}
DECLARE_CONCRETE_INSTRUCTION(AbnormalExit)
};
class HUnaryOperation : public HTemplateInstruction<1> { class HUnaryOperation : public HTemplateInstruction<1> {
public: public:
HUnaryOperation(HValue* value, HType type = HType::Tagged()) HUnaryOperation(HValue* value, HType type = HType::Tagged())

View File

@ -5491,6 +5491,14 @@ void HOptimizedGraphBuilder::VisitThrow(Throw* expr) {
HThrow* instr = Add<HThrow>(value); HThrow* instr = Add<HThrow>(value);
instr->set_position(expr->position()); instr->set_position(expr->position());
Add<HSimulate>(expr->id()); Add<HSimulate>(expr->id());
// If the throw definitely exits the function, we can finish with a dummy
// control flow at this point. This is not the case if the throw is inside
// an inlined function which may be replaced.
if (call_context() == NULL) {
current_block()->FinishExit(new(zone()) HAbnormalExit);
set_current_block(NULL);
}
} }

View File

@ -1883,6 +1883,13 @@ LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation(
} }
LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
// The control instruction marking the end of a block that completed
// abruptly (e.g., threw an exception). There is nothing specific to do.
return NULL;
}
LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
LOperand* context = UseFixed(instr->context(), esi); LOperand* context = UseFixed(instr->context(), esi);
LOperand* value = UseFixed(instr->value(), eax); LOperand* value = UseFixed(instr->value(), eax);

View File

@ -1786,6 +1786,13 @@ LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation(
} }
LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
// The control instruction marking the end of a block that completed
// abruptly (e.g., threw an exception). There is nothing specific to do.
return NULL;
}
LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
LOperand* value = UseFixed(instr->value(), a0); LOperand* value = UseFixed(instr->value(), a0);
return MarkAsCall(new(zone()) LThrow(value), instr); return MarkAsCall(new(zone()) LThrow(value), instr);

View File

@ -1780,6 +1780,13 @@ LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation(
} }
LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
// The control instruction marking the end of a block that completed
// abruptly (e.g., threw an exception). There is nothing specific to do.
return NULL;
}
LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
LOperand* value = UseFixed(instr->value(), rax); LOperand* value = UseFixed(instr->value(), rax);
return MarkAsCall(new(zone()) LThrow(value), instr); return MarkAsCall(new(zone()) LThrow(value), instr);