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

Unified Diff: src/hydrogen.cc

Issue 307593002: Preliminary support for block contexts in hydrogen. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Port to other architectures Created 6 years, 6 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 36d62d271ce7d1b8451324cc923827a2586b6f26..a3f4b0b2a53d80ca7d2742590712a014cb141c8e 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -4247,13 +4247,52 @@ void HOptimizedGraphBuilder::VisitBlock(Block* stmt) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
- if (stmt->scope() != NULL) {
- return Bailout(kScopedBlock);
- }
- BreakAndContinueInfo break_info(stmt);
+
+ Scope* outer_scope = scope();
+ Scope* scope = stmt->scope();
+ BreakAndContinueInfo break_info(stmt, outer_scope);
+
{ BreakAndContinueScope push(&break_info, this);
+ if (scope != NULL) {
+ // Load the function object.
+ Scope* declaration_scope = scope->DeclarationScope();
+ HInstruction* function;
+ HValue* outer_context = environment()->context();
+ if (declaration_scope->is_global_scope() ||
+ declaration_scope->is_eval_scope()) {
+ function = new(zone()) HLoadContextSlot(
+ outer_context, Context::CLOSURE_INDEX, HLoadContextSlot::kNoCheck);
+ } else {
+ function = New<HThisFunction>();
+ }
+ AddInstruction(function);
+ // Allocate a block context and store it to the stack frame.
+ HInstruction* inner_context = Add<HAllocateBlockContext>(
+ outer_context, function, scope->GetScopeInfo());
+ HInstruction* instr = Add<HStoreFrameContext>(inner_context);
+ if (instr->HasObservableSideEffects()) {
+ AddSimulate(stmt->EntryId(), REMOVABLE_SIMULATE);
+ }
+ set_scope(scope);
+ environment()->BindContext(inner_context);
+ VisitDeclarations(scope->declarations());
+ AddSimulate(stmt->DeclsId(), REMOVABLE_SIMULATE);
+ }
CHECK_BAILOUT(VisitStatements(stmt->statements()));
}
+ set_scope(outer_scope);
+ if (scope != NULL && current_block() != NULL) {
+ HValue* inner_context = environment()->context();
+ HValue* outer_context = Add<HLoadNamedField>(
+ inner_context, static_cast<HValue*>(NULL),
+ HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
+
+ HInstruction* instr = Add<HStoreFrameContext>(outer_context);
+ if (instr->HasObservableSideEffects()) {
+ AddSimulate(stmt->ExitId(), REMOVABLE_SIMULATE);
+ }
+ environment()->BindContext(outer_context);
+ }
HBasicBlock* break_block = break_info.break_block();
if (break_block != NULL) {
if (current_block() != NULL) Goto(break_block);
@@ -4321,6 +4360,7 @@ void HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) {
HBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get(
BreakableStatement* stmt,
BreakType type,
+ Scope** scope,
int* drop_extra) {
*drop_extra = 0;
BreakAndContinueScope* current = this;
@@ -4329,6 +4369,7 @@ HBasicBlock* HOptimizedGraphBuilder::BreakAndContinueScope::Get(
current = current->next();
}
ASSERT(current != NULL); // Always found (unless stack is malformed).
+ *scope = current->info()->scope();
if (type == BREAK) {
*drop_extra += current->info()->drop_extra();
@@ -4362,10 +4403,29 @@ void HOptimizedGraphBuilder::VisitContinueStatement(
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
+ Scope* outer_scope = NULL;
+ Scope* inner_scope = scope();
int drop_extra = 0;
HBasicBlock* continue_block = break_scope()->Get(
- stmt->target(), BreakAndContinueScope::CONTINUE, &drop_extra);
+ stmt->target(), BreakAndContinueScope::CONTINUE,
+ &outer_scope, &drop_extra);
+ HValue* context = environment()->context();
Drop(drop_extra);
+ int context_pop_count = inner_scope->ContextChainLength(outer_scope);
+ if (context_pop_count > 0) {
+ while (context_pop_count-- > 0) {
+ HInstruction* context_instruction = Add<HLoadNamedField>(
+ context, static_cast<HValue*>(NULL),
+ HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
+ context = context_instruction;
+ }
+ HInstruction* instr = Add<HStoreFrameContext>(context);
+ if (instr->HasObservableSideEffects()) {
+ AddSimulate(stmt->target()->EntryId(), REMOVABLE_SIMULATE);
+ }
+ environment()->BindContext(context);
+ }
+
Goto(continue_block);
set_current_block(NULL);
}
@@ -4375,10 +4435,28 @@ void HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
+ Scope* outer_scope = NULL;
+ Scope* inner_scope = scope();
int drop_extra = 0;
HBasicBlock* break_block = break_scope()->Get(
- stmt->target(), BreakAndContinueScope::BREAK, &drop_extra);
+ stmt->target(), BreakAndContinueScope::BREAK,
+ &outer_scope, &drop_extra);
+ HValue* context = environment()->context();
Drop(drop_extra);
+ int context_pop_count = inner_scope->ContextChainLength(outer_scope);
+ if (context_pop_count > 0) {
+ while (context_pop_count-- > 0) {
+ HInstruction* context_instruction = Add<HLoadNamedField>(
+ context, static_cast<HValue*>(NULL),
+ HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
+ context = context_instruction;
+ }
+ HInstruction* instr = Add<HStoreFrameContext>(context);
+ if (instr->HasObservableSideEffects()) {
+ AddSimulate(stmt->target()->ExitId(), REMOVABLE_SIMULATE);
+ }
+ environment()->BindContext(context);
+ }
Goto(break_block);
set_current_block(NULL);
}
@@ -4533,7 +4611,7 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
// translating the clause bodies.
HBasicBlock* fall_through_block = NULL;
- BreakAndContinueInfo break_info(stmt);
+ BreakAndContinueInfo break_info(stmt, scope());
{ BreakAndContinueScope push(&break_info, this);
for (int i = 0; i < clause_count; ++i) {
CaseClause* clause = clauses->at(i);
@@ -4580,9 +4658,7 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt,
- HBasicBlock* loop_entry,
- BreakAndContinueInfo* break_info) {
- BreakAndContinueScope push(break_info, this);
+ HBasicBlock* loop_entry) {
Add<HSimulate>(stmt->StackCheckId());
HStackCheck* stack_check =
HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch));
@@ -4599,8 +4675,11 @@ void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
ASSERT(current_block() != NULL);
HBasicBlock* loop_entry = BuildLoopEntry(stmt);
- BreakAndContinueInfo break_info(stmt);
- CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
+ BreakAndContinueInfo break_info(stmt, scope());
+ {
+ BreakAndContinueScope push(&break_info, this);
+ CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry));
+ }
HBasicBlock* body_exit =
JoinContinue(stmt, current_block(), break_info.continue_block());
HBasicBlock* loop_successor = NULL;
@@ -4661,9 +4740,10 @@ void HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
}
}
- BreakAndContinueInfo break_info(stmt);
+ BreakAndContinueInfo break_info(stmt, scope());
if (current_block() != NULL) {
- CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
+ BreakAndContinueScope push(&break_info, this);
+ CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry));
}
HBasicBlock* body_exit =
JoinContinue(stmt, current_block(), break_info.continue_block());
@@ -4702,9 +4782,10 @@ void HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) {
}
}
- BreakAndContinueInfo break_info(stmt);
+ BreakAndContinueInfo break_info(stmt, scope());
if (current_block() != NULL) {
- CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
+ BreakAndContinueScope push(&break_info, this);
+ CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry));
}
HBasicBlock* body_exit =
JoinContinue(stmt, current_block(), break_info.continue_block());
@@ -4803,8 +4884,11 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
Bind(each_var, key);
- BreakAndContinueInfo break_info(stmt, 5);
- CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
+ BreakAndContinueInfo break_info(stmt, scope(), 5);
+ {
+ BreakAndContinueScope push(&break_info, this);
+ CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry));
+ }
HBasicBlock* body_exit =
JoinContinue(stmt, current_block(), break_info.continue_block());
@@ -4949,7 +5033,7 @@ HOptimizedGraphBuilder::GlobalPropertyAccess
HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) {
ASSERT(var->IsContextSlot());
HValue* context = environment()->context();
- int length = current_info()->scope()->ContextChainLength(var->scope());
+ int length = scope()->ContextChainLength(var->scope());
while (length-- > 0) {
context = Add<HLoadNamedField>(
context, static_cast<HValue*>(NULL),
@@ -5033,7 +5117,21 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
case Variable::CONTEXT: {
HValue* context = BuildContextChainWalk(variable);
- HLoadContextSlot* instr = new(zone()) HLoadContextSlot(context, variable);
+ HLoadContextSlot::Mode mode;
+ switch (variable->mode()) {
+ case LET:
+ case CONST:
+ mode = HLoadContextSlot::kCheckDeoptimize;
+ break;
+ case CONST_LEGACY:
+ mode = HLoadContextSlot::kCheckReturnUndefined;
+ break;
+ default:
+ mode = HLoadContextSlot::kNoCheck;
+ break;
+ }
+ HLoadContextSlot* instr =
+ new(zone()) HLoadContextSlot(context, variable->index(), mode);
return ast_context()->ReturnInstruction(instr, expr->id());
}
@@ -7462,7 +7560,8 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
Add<HSimulate>(BailoutId::None());
current_block()->UpdateEnvironment(inner_env);
-
+ Scope* saved_scope = scope();
+ set_scope(target_info.scope());
HEnterInlined* enter_inlined =
Add<HEnterInlined>(return_id, target, arguments_count, function,
function_state()->inlining_kind(),
@@ -7472,6 +7571,7 @@ bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
VisitDeclarations(target_info.scope()->declarations());
VisitStatements(function->body());
+ set_scope(saved_scope);
if (HasStackOverflow()) {
// Bail out if the inline function did, as we cannot residualize a call
// instead.
@@ -11432,7 +11532,9 @@ HEnvironment::HEnvironment(HEnvironment* outer,
push_count_(0),
ast_id_(BailoutId::None()),
zone_(zone) {
- Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0);
+ Scope* declaration_scope = scope->DeclarationScope();
+ Initialize(declaration_scope->num_parameters() + 1,
+ declaration_scope->num_stack_slots(), 0);
}
« 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