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

Unified Diff: src/hydrogen.cc

Issue 20680002: Rebase of partial ia32 implementation of optimized try/catch (started by Kevin Millikin, continued … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix detection of CATCH frames (fixes debuger exception reporting anf breaks another assertion...). Created 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 8d3a0ac813a90a6014ac6185473406c2ca5e8927..7c5c5e9b4eeac6d8a33a318416d2a29bd9bc41cb 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -4740,7 +4740,7 @@ void HOptimizedGraphBuilder::VisitBlock(Block* stmt) {
if (stmt->scope() != NULL) {
return Bailout("ScopedBlock");
}
- BreakAndContinueInfo break_info(stmt);
+ BreakAndContinueInfo break_info(stmt, 0);
{ BreakAndContinueScope push(&break_info, this);
CHECK_BAILOUT(VisitStatements(stmt->statements()));
}
@@ -4808,20 +4808,41 @@ void HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) {
}
-HBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get(
- BreakableStatement* stmt,
- BreakType type,
- int* drop_extra) {
- *drop_extra = 0;
+void HOptimizedGraphBuilder::BreakAndContinueScope::UnwindReturn() {
BreakAndContinueScope* current = this;
- while (current != NULL && current->info()->target() != stmt) {
- *drop_extra += current->info()->drop_extra();
+ while (current != NULL) {
+ TryCatchStatement* try_catch =
+ current->info()->statement()->AsTryCatchStatement();
+ if (try_catch != NULL) {
+ HLeaveTry* leave = new(owner()->zone()) HLeaveTry;
+ owner()->AddInstruction(leave);
+ owner()->environment()->RemoveExceptionHandler();
+ owner()->AddSimulate(try_catch->TryExitId());
+ }
+ current = current->next();
+ }
+}
+
+
+void HOptimizedGraphBuilder::BreakAndContinueScope::Unwind(BreakableStatement* target,
+ BreakType type) {
+ BreakAndContinueScope* current = this;
+ while (current != NULL && current->info()->statement() != target) {
+ TryCatchStatement* try_catch =
+ current->info()->statement()->AsTryCatchStatement();
+ if (try_catch != NULL) {
+ HLeaveTry* leave = new(owner()->zone()) HLeaveTry;
+ owner()->AddInstruction(leave);
+ owner()->environment()->RemoveExceptionHandler();
+ owner()->AddSimulate(try_catch->TryExitId());
+ }
+ owner()->Drop(current->info()->drop_extra());
current = current->next();
}
ASSERT(current != NULL); // Always found (unless stack is malformed).
if (type == BREAK) {
- *drop_extra += current->info()->drop_extra();
+ owner()->Drop(current->info()->drop_extra());
}
HBasicBlock* block = NULL;
@@ -4842,8 +4863,8 @@ HBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get(
}
break;
}
-
- return block;
+ owner()->current_block()->Goto(block);
+ owner()->set_current_block(NULL);
}
@@ -4852,12 +4873,7 @@ void HOptimizedGraphBuilder::VisitContinueStatement(
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
- int drop_extra = 0;
- HBasicBlock* continue_block = break_scope()->Get(
- stmt->target(), BreakAndContinueScope::CONTINUE, &drop_extra);
- Drop(drop_extra);
- current_block()->Goto(continue_block);
- set_current_block(NULL);
+ break_scope()->Unwind(stmt->target(), BreakAndContinueScope::CONTINUE);
}
@@ -4865,12 +4881,7 @@ void HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
- int drop_extra = 0;
- HBasicBlock* break_block = break_scope()->Get(
- stmt->target(), BreakAndContinueScope::BREAK, &drop_extra);
- Drop(drop_extra);
- current_block()->Goto(break_block);
- set_current_block(NULL);
+ break_scope()->Unwind(stmt->target(), BreakAndContinueScope::BREAK);
}
@@ -4884,6 +4895,7 @@ void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
// Not an inlined return, so an actual one.
CHECK_ALIVE(VisitForValue(stmt->expression()));
HValue* result = environment()->Pop();
+ break_scope()->UnwindReturn();
AddReturn(result);
} else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) {
// Return from an inlined construct call. In a test context the return value
@@ -5053,7 +5065,7 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
HBasicBlock* curr_test_block = first_test_block;
HBasicBlock* fall_through_block = NULL;
- BreakAndContinueInfo break_info(stmt);
+ BreakAndContinueInfo break_info(stmt, 0);
{ BreakAndContinueScope push(&break_info, this);
for (int i = 0; i < clause_count; ++i) {
CaseClause* clause = clauses->at(i);
@@ -5198,7 +5210,7 @@ void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
set_current_block(loop_entry);
if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
- BreakAndContinueInfo break_info(stmt);
+ BreakAndContinueInfo break_info(stmt, 0);
CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
HBasicBlock* body_exit =
JoinContinue(stmt, current_block(), break_info.continue_block());
@@ -5259,7 +5271,7 @@ void HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
}
}
- BreakAndContinueInfo break_info(stmt);
+ BreakAndContinueInfo break_info(stmt, 0);
if (current_block() != NULL) {
CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
}
@@ -5304,7 +5316,7 @@ void HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) {
}
}
- BreakAndContinueInfo break_info(stmt);
+ BreakAndContinueInfo break_info(stmt, 0);
if (current_block() != NULL) {
CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
}
@@ -5459,7 +5471,24 @@ void HOptimizedGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
- return Bailout("TryCatchStatement");
+ if (!FLAG_crankshaft_try_support) {
+ Bailout("try statement support disabled");
+ return;
+ }
+ HEnterTry* enter = new(zone()) HEnterTry(stmt->index());
+ AddInstruction(enter);
+ environment()->AddExceptionHandler();
+ AddSimulate(stmt->TryEntryId());
+ BreakAndContinueInfo try_info(stmt, 0);
+ { BreakAndContinueScope push(&try_info, this);
+ CHECK_BAILOUT(Visit(stmt->try_block()));
+ }
+ if (current_block() != NULL) {
+ HLeaveTry* leave = new(zone()) HLeaveTry;
+ AddInstruction(leave);
+ environment()->RemoveExceptionHandler();
+ AddSimulate(stmt->TryExitId());
+ }
}
@@ -10916,6 +10945,7 @@ HEnvironment::HEnvironment(HEnvironment* outer,
parameter_count_(0),
specials_count_(1),
local_count_(0),
+ handler_count_(0),
outer_(outer),
entry_(NULL),
pop_count_(0),
@@ -10948,6 +10978,7 @@ HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone)
parameter_count_(0),
specials_count_(0),
local_count_(0),
+ handler_count_(0),
outer_(NULL),
entry_(NULL),
pop_count_(0),
@@ -10969,6 +11000,7 @@ HEnvironment::HEnvironment(HEnvironment* outer,
parameter_count_(arguments),
specials_count_(0),
local_count_(0),
+ handler_count_(0),
outer_(outer),
entry_(NULL),
pop_count_(0),
@@ -10998,6 +11030,7 @@ void HEnvironment::Initialize(const HEnvironment* other) {
frame_type_ = other->frame_type_;
parameter_count_ = other->parameter_count_;
local_count_ = other->local_count_;
+ handler_count_ = other->handler_count_;
if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy.
entry_ = other->entry_;
pop_count_ = other->pop_count_;
@@ -11010,6 +11043,7 @@ void HEnvironment::Initialize(const HEnvironment* other) {
void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) {
ASSERT(!block->IsLoopHeader());
ASSERT(values_.length() == other->values_.length());
+ ASSERT(handler_count_ == other->handler_count_);
int length = values_.length();
for (int i = 0; i < length; ++i) {
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698