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

Side by Side Diff: src/hydrogen.cc

Issue 6532088: Partial refactoring of subgraphs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge/build/ia32
Patch Set: Created 9 years, 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 478
479 479
480 HConstant* HGraph::GetConstantFalse() { 480 HConstant* HGraph::GetConstantFalse() {
481 return GetConstant(&constant_false_, Heap::false_value()); 481 return GetConstant(&constant_false_, Heap::false_value());
482 } 482 }
483 483
484 484
485 void HSubgraph::AppendJoin(HSubgraph* then_graph, 485 void HSubgraph::AppendJoin(HSubgraph* then_graph,
486 HSubgraph* else_graph, 486 HSubgraph* else_graph,
487 AstNode* node) { 487 AstNode* node) {
488 if (then_graph->HasExit() && else_graph->HasExit()) { 488 if (then_graph->exit_block() != NULL &&
489 else_graph->exit_block() != NULL) {
489 // We need to merge, create new merge block. 490 // We need to merge, create new merge block.
490 HBasicBlock* join_block = graph_->CreateBasicBlock(); 491 HBasicBlock* join_block = graph_->CreateBasicBlock();
491 then_graph->exit_block()->Goto(join_block); 492 then_graph->exit_block()->Goto(join_block);
492 else_graph->exit_block()->Goto(join_block); 493 else_graph->exit_block()->Goto(join_block);
493 join_block->SetJoinId(node->id()); 494 join_block->SetJoinId(node->id());
494 exit_block_ = join_block; 495 exit_block_ = join_block;
495 } else if (then_graph->HasExit()) { 496 } else if (then_graph->exit_block() != NULL) {
496 exit_block_ = then_graph->exit_block_; 497 exit_block_ = then_graph->exit_block_;
497 } else if (else_graph->HasExit()) { 498 } else if (else_graph->exit_block() != NULL) {
498 exit_block_ = else_graph->exit_block_; 499 exit_block_ = else_graph->exit_block_;
499 } else { 500 } else {
500 exit_block_ = NULL; 501 exit_block_ = NULL;
501 } 502 }
502 } 503 }
503 504
504 505
505 void HSubgraph::ResolveContinue(IterationStatement* statement, 506 void HSubgraph::ResolveContinue(IterationStatement* statement,
506 HBasicBlock* continue_block) { 507 HBasicBlock* continue_block) {
507 if (continue_block != NULL) { 508 if (continue_block != NULL) {
(...skipping 11 matching lines...) Expand all
519 a->Goto(target); 520 a->Goto(target);
520 b->Goto(target); 521 b->Goto(target);
521 target->SetJoinId(id); 522 target->SetJoinId(id);
522 return target; 523 return target;
523 } 524 }
524 525
525 526
526 void HSubgraph::AppendEndless(HSubgraph* body, 527 void HSubgraph::AppendEndless(HSubgraph* body,
527 IterationStatement* statement, 528 IterationStatement* statement,
528 HBasicBlock* break_block) { 529 HBasicBlock* break_block) {
529 ConnectExitTo(body->entry_block()); 530 if (exit_block() != NULL) {
530 body->ConnectExitTo(body->entry_block(), true); 531 exit_block()->Goto(body->entry_block(), false);
532 }
533 if (body->exit_block() != NULL) {
534 body->exit_block()->Goto(body->entry_block(), true);
535 }
531 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); 536 if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
532 exit_block_ = break_block; 537 exit_block_ = break_block;
533 body->entry_block()->PostProcessLoopHeader(statement); 538 body->entry_block()->PostProcessLoopHeader(statement);
534 } 539 }
535 540
536 541
537 void HSubgraph::AppendDoWhile(HSubgraph* body, 542 void HSubgraph::AppendDoWhile(HSubgraph* body,
538 IterationStatement* statement, 543 IterationStatement* statement,
539 HSubgraph* go_back, 544 HSubgraph* go_back,
540 HSubgraph* exit, 545 HSubgraph* exit,
541 HBasicBlock* break_block) { 546 HBasicBlock* break_block) {
542 ConnectExitTo(body->entry_block()); 547 if (exit_block() != NULL) {
543 go_back->ConnectExitTo(body->entry_block(), true); 548 exit_block()->Goto(body->entry_block(), false);
549 }
550 if (go_back->exit_block() != NULL) {
551 go_back->exit_block()->Goto(body->entry_block(), true);
552 }
544 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); 553 if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
545 exit_block_ = 554 exit_block_ =
546 JoinBlocks(exit->exit_block(), break_block, statement->ExitId()); 555 JoinBlocks(exit->exit_block(), break_block, statement->ExitId());
547 body->entry_block()->PostProcessLoopHeader(statement); 556 body->entry_block()->PostProcessLoopHeader(statement);
548 } 557 }
549 558
550 559
551 void HSubgraph::AppendWhile(HSubgraph* condition, 560 void HSubgraph::AppendWhile(HSubgraph* condition,
552 HSubgraph* body, 561 HSubgraph* body,
553 IterationStatement* statement, 562 IterationStatement* statement,
554 HSubgraph* continue_subgraph, 563 HSubgraph* continue_subgraph,
555 HSubgraph* exit, 564 HSubgraph* exit,
556 HBasicBlock* break_block) { 565 HBasicBlock* break_block) {
557 ConnectExitTo(condition->entry_block()); 566 if (exit_block() != NULL) {
567 exit_block()->Goto(condition->entry_block(), false);
568 }
558 569
559 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); 570 if (break_block != NULL) break_block->SetJoinId(statement->ExitId());
560 exit_block_ = 571 exit_block_ =
561 JoinBlocks(exit->exit_block(), break_block, statement->ExitId()); 572 JoinBlocks(exit->exit_block(), break_block, statement->ExitId());
562 573
563 if (continue_subgraph != NULL) { 574 if (continue_subgraph != NULL) {
564 body->ConnectExitTo(continue_subgraph->entry_block(), true); 575 if (body->exit_block() != NULL) {
576 body->exit_block()->Goto(continue_subgraph->entry_block(), true);
577 }
565 continue_subgraph->entry_block()->SetJoinId(statement->EntryId()); 578 continue_subgraph->entry_block()->SetJoinId(statement->EntryId());
566 exit_block_ = JoinBlocks(exit_block_, 579 exit_block_ = JoinBlocks(exit_block_,
567 continue_subgraph->exit_block(), 580 continue_subgraph->exit_block(),
568 statement->ExitId()); 581 statement->ExitId());
569 } else { 582 } else {
570 body->ConnectExitTo(condition->entry_block(), true); 583 if (body->exit_block() != NULL) {
584 body->exit_block()->Goto(condition->entry_block(), true);
585 }
571 } 586 }
572 condition->entry_block()->PostProcessLoopHeader(statement); 587 condition->entry_block()->PostProcessLoopHeader(statement);
573 } 588 }
574 589
575 590
576 void HSubgraph::Append(HSubgraph* next, 591 void HSubgraph::Append(HSubgraph* next,
577 BreakableStatement* stmt, 592 BreakableStatement* stmt,
578 HBasicBlock* break_block) { 593 HBasicBlock* break_block) {
579 exit_block_->Goto(next->entry_block()); 594 exit_block_->Goto(next->entry_block());
580 exit_block_ = next->exit_block_; 595 exit_block_ = next->exit_block_;
581 596
582 if (stmt != NULL) { 597 if (stmt != NULL) {
583 next->entry_block()->SetJoinId(stmt->EntryId()); 598 next->entry_block()->SetJoinId(stmt->EntryId());
584 if (break_block != NULL) break_block->SetJoinId(stmt->EntryId()); 599 if (break_block != NULL) break_block->SetJoinId(stmt->EntryId());
585 exit_block_ = JoinBlocks(exit_block(), break_block, stmt->ExitId()); 600 exit_block_ = JoinBlocks(exit_block(), break_block, stmt->ExitId());
586 } 601 }
587 } 602 }
588 603
589 604
590 void HSubgraph::FinishExit(HControlInstruction* instruction) { 605 void HSubgraph::FinishExit(HControlInstruction* instruction) {
591 ASSERT(HasExit()); 606 ASSERT(exit_block() != NULL);
592 exit_block_->Finish(instruction); 607 exit_block_->Finish(instruction);
593 exit_block_->ClearEnvironment(); 608 exit_block_->ClearEnvironment();
594 exit_block_ = NULL; 609 exit_block_ = NULL;
595 } 610 }
596 611
597 612
598 HGraph::HGraph(CompilationInfo* info) 613 HGraph::HGraph(CompilationInfo* info)
599 : HSubgraph(this), 614 : HSubgraph(this),
600 next_block_id_(0), 615 next_block_id_(0),
601 info_(info), 616 info_(info),
(...skipping 1327 matching lines...) Expand 10 before | Expand all | Expand 10 after
1929 } 1944 }
1930 1945
1931 1946
1932 AstContext::~AstContext() { 1947 AstContext::~AstContext() {
1933 owner_->set_ast_context(outer_); // Pop. 1948 owner_->set_ast_context(outer_); // Pop.
1934 } 1949 }
1935 1950
1936 1951
1937 EffectContext::~EffectContext() { 1952 EffectContext::~EffectContext() {
1938 ASSERT(owner()->HasStackOverflow() || 1953 ASSERT(owner()->HasStackOverflow() ||
1939 !owner()->subgraph()->HasExit() || 1954 owner()->current_block() == NULL ||
1940 owner()->environment()->length() == original_length_); 1955 owner()->environment()->length() == original_length_);
1941 } 1956 }
1942 1957
1943 1958
1944 ValueContext::~ValueContext() { 1959 ValueContext::~ValueContext() {
1945 ASSERT(owner()->HasStackOverflow() || 1960 ASSERT(owner()->HasStackOverflow() ||
1946 !owner()->subgraph()->HasExit() || 1961 owner()->current_block() == NULL ||
1947 owner()->environment()->length() == original_length_ + 1); 1962 owner()->environment()->length() == original_length_ + 1);
1948 } 1963 }
1949 1964
1950 1965
1951 void EffectContext::ReturnValue(HValue* value) { 1966 void EffectContext::ReturnValue(HValue* value) {
1952 // The value is simply ignored. 1967 // The value is simply ignored.
1953 } 1968 }
1954 1969
1955 1970
1956 void ValueContext::ReturnValue(HValue* value) { 1971 void ValueContext::ReturnValue(HValue* value) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1994 2009
1995 void TestContext::BuildBranch(HValue* value) { 2010 void TestContext::BuildBranch(HValue* value) {
1996 // We expect the graph to be in edge-split form: there is no edge that 2011 // We expect the graph to be in edge-split form: there is no edge that
1997 // connects a branch node to a join node. We conservatively ensure that 2012 // connects a branch node to a join node. We conservatively ensure that
1998 // property by always adding an empty block on the outgoing edges of this 2013 // property by always adding an empty block on the outgoing edges of this
1999 // branch. 2014 // branch.
2000 HGraphBuilder* builder = owner(); 2015 HGraphBuilder* builder = owner();
2001 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); 2016 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
2002 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); 2017 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
2003 HTest* test = new HTest(value, empty_true, empty_false); 2018 HTest* test = new HTest(value, empty_true, empty_false);
2004 builder->CurrentBlock()->Finish(test); 2019 builder->current_block()->Finish(test);
2005 2020
2006 HValue* const no_return_value = NULL; 2021 HValue* const no_return_value = NULL;
2007 HBasicBlock* true_target = if_true(); 2022 HBasicBlock* true_target = if_true();
2008 if (true_target->IsInlineReturnTarget()) { 2023 if (true_target->IsInlineReturnTarget()) {
2009 empty_true->AddLeaveInlined(no_return_value, true_target); 2024 empty_true->AddLeaveInlined(no_return_value, true_target);
2010 } else { 2025 } else {
2011 empty_true->Goto(true_target); 2026 empty_true->Goto(true_target);
2012 } 2027 }
2013 2028
2014 HBasicBlock* false_target = if_false(); 2029 HBasicBlock* false_target = if_false();
2015 if (false_target->IsInlineReturnTarget()) { 2030 if (false_target->IsInlineReturnTarget()) {
2016 empty_false->AddLeaveInlined(no_return_value, false_target); 2031 empty_false->AddLeaveInlined(no_return_value, false_target);
2017 } else { 2032 } else {
2018 empty_false->Goto(false_target); 2033 empty_false->Goto(false_target);
2019 } 2034 }
2020 builder->subgraph()->set_exit_block(NULL); 2035 builder->set_current_block(NULL);
2021 } 2036 }
2022 2037
2023 2038
2024 // HGraphBuilder infrastructure for bailing out and checking bailouts. 2039 // HGraphBuilder infrastructure for bailing out and checking bailouts.
2025 #define BAILOUT(reason) \ 2040 #define BAILOUT(reason) \
2026 do { \ 2041 do { \
2027 Bailout(reason); \ 2042 Bailout(reason); \
2028 return; \ 2043 return; \
2029 } while (false) 2044 } while (false)
2030 2045
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2117 2132
2118 void HGraphBuilder::VisitArgument(Expression* expr) { 2133 void HGraphBuilder::VisitArgument(Expression* expr) {
2119 VISIT_FOR_VALUE(expr); 2134 VISIT_FOR_VALUE(expr);
2120 Push(AddInstruction(new HPushArgument(Pop()))); 2135 Push(AddInstruction(new HPushArgument(Pop())));
2121 } 2136 }
2122 2137
2123 2138
2124 void HGraphBuilder::VisitArgumentList(ZoneList<Expression*>* arguments) { 2139 void HGraphBuilder::VisitArgumentList(ZoneList<Expression*>* arguments) {
2125 for (int i = 0; i < arguments->length(); i++) { 2140 for (int i = 0; i < arguments->length(); i++) {
2126 VisitArgument(arguments->at(i)); 2141 VisitArgument(arguments->at(i));
2127 if (HasStackOverflow() || !current_subgraph_->HasExit()) return; 2142 if (HasStackOverflow() || current_block() == NULL) return;
2128 } 2143 }
2129 } 2144 }
2130 2145
2131 2146
2132 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { 2147 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) {
2133 for (int i = 0; i < exprs->length(); ++i) { 2148 for (int i = 0; i < exprs->length(); ++i) {
2134 VISIT_FOR_VALUE(exprs->at(i)); 2149 VISIT_FOR_VALUE(exprs->at(i));
2135 } 2150 }
2136 } 2151 }
2137 2152
(...skipping 13 matching lines...) Expand all
2151 2166
2152 AddInstruction(new HStackCheck()); 2167 AddInstruction(new HStackCheck());
2153 2168
2154 ZoneList<Statement*>* stmts = info->function()->body(); 2169 ZoneList<Statement*>* stmts = info->function()->body();
2155 HSubgraph* body = CreateGotoSubgraph(environment()); 2170 HSubgraph* body = CreateGotoSubgraph(environment());
2156 AddToSubgraph(body, stmts); 2171 AddToSubgraph(body, stmts);
2157 if (HasStackOverflow()) return NULL; 2172 if (HasStackOverflow()) return NULL;
2158 current_subgraph_->Append(body, NULL, NULL); 2173 current_subgraph_->Append(body, NULL, NULL);
2159 body->entry_block()->SetJoinId(info->function()->id()); 2174 body->entry_block()->SetJoinId(info->function()->id());
2160 2175
2161 if (graph_->HasExit()) { 2176 if (graph()->exit_block() != NULL) {
2162 graph_->FinishExit(new HReturn(graph_->GetConstantUndefined())); 2177 graph_->FinishExit(new HReturn(graph_->GetConstantUndefined()));
2163 } 2178 }
2164 } 2179 }
2165 2180
2166 graph_->OrderBlocks(); 2181 graph_->OrderBlocks();
2167 graph_->AssignDominators(); 2182 graph_->AssignDominators();
2168 graph_->EliminateRedundantPhis(); 2183 graph_->EliminateRedundantPhis();
2169 if (!graph_->CollectPhis()) { 2184 if (!graph_->CollectPhis()) {
2170 Bailout("Phi-use of arguments object"); 2185 Bailout("Phi-use of arguments object");
2171 return NULL; 2186 return NULL;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2212 2227
2213 2228
2214 void HGraphBuilder::AddToSubgraph(HSubgraph* graph, 2229 void HGraphBuilder::AddToSubgraph(HSubgraph* graph,
2215 ZoneList<Statement*>* stmts) { 2230 ZoneList<Statement*>* stmts) {
2216 SubgraphScope scope(this, graph); 2231 SubgraphScope scope(this, graph);
2217 VisitStatements(stmts); 2232 VisitStatements(stmts);
2218 } 2233 }
2219 2234
2220 2235
2221 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { 2236 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
2222 ASSERT(current_subgraph_->HasExit()); 2237 ASSERT(current_block() != NULL);
2223 current_subgraph_->exit_block()->AddInstruction(instr); 2238 current_block()->AddInstruction(instr);
2224 return instr; 2239 return instr;
2225 } 2240 }
2226 2241
2227 2242
2228 void HGraphBuilder::AddSimulate(int id) { 2243 void HGraphBuilder::AddSimulate(int id) {
2229 ASSERT(current_subgraph_->HasExit()); 2244 ASSERT(current_block() != NULL);
2230 current_subgraph_->exit_block()->AddSimulate(id); 2245 current_block()->AddSimulate(id);
2231 } 2246 }
2232 2247
2233 2248
2234 void HGraphBuilder::AddPhi(HPhi* instr) { 2249 void HGraphBuilder::AddPhi(HPhi* instr) {
2235 ASSERT(current_subgraph_->HasExit()); 2250 ASSERT(current_block() != NULL);
2236 current_subgraph_->exit_block()->AddPhi(instr); 2251 current_block()->AddPhi(instr);
2237 } 2252 }
2238 2253
2239 2254
2240 void HGraphBuilder::PushAndAdd(HInstruction* instr) { 2255 void HGraphBuilder::PushAndAdd(HInstruction* instr) {
2241 Push(instr); 2256 Push(instr);
2242 AddInstruction(instr); 2257 AddInstruction(instr);
2243 } 2258 }
2244 2259
2245 2260
2246 void HGraphBuilder::PreProcessCall(HCall* call) { 2261 void HGraphBuilder::PreProcessCall(HCall* call) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2289 graph()->SetArgumentsObject(object); 2304 graph()->SetArgumentsObject(object);
2290 environment()->Bind(scope->arguments(), object); 2305 environment()->Bind(scope->arguments(), object);
2291 environment()->Bind(scope->arguments_shadow(), object); 2306 environment()->Bind(scope->arguments_shadow(), object);
2292 } 2307 }
2293 } 2308 }
2294 2309
2295 2310
2296 void HGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { 2311 void HGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) {
2297 for (int i = 0; i < statements->length(); i++) { 2312 for (int i = 0; i < statements->length(); i++) {
2298 Visit(statements->at(i)); 2313 Visit(statements->at(i));
2299 if (HasStackOverflow() || !current_subgraph_->HasExit()) break; 2314 if (HasStackOverflow() || current_block() == NULL) break;
2300 } 2315 }
2301 } 2316 }
2302 2317
2303 2318
2304 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { 2319 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
2305 HBasicBlock* b = graph()->CreateBasicBlock(); 2320 HBasicBlock* b = graph()->CreateBasicBlock();
2306 b->SetInitialEnvironment(env); 2321 b->SetInitialEnvironment(env);
2307 return b; 2322 return b;
2308 } 2323 }
2309 2324
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2428 } 2443 }
2429 break; 2444 break;
2430 } 2445 }
2431 2446
2432 return block; 2447 return block;
2433 } 2448 }
2434 2449
2435 2450
2436 void HGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) { 2451 void HGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
2437 HBasicBlock* continue_block = break_scope()->Get(stmt->target(), CONTINUE); 2452 HBasicBlock* continue_block = break_scope()->Get(stmt->target(), CONTINUE);
2438 subgraph()->exit_block()->Goto(continue_block); 2453 current_block()->Goto(continue_block);
2439 subgraph()->set_exit_block(NULL); 2454 set_current_block(NULL);
2440 } 2455 }
2441 2456
2442 2457
2443 void HGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { 2458 void HGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
2444 HBasicBlock* break_block = break_scope()->Get(stmt->target(), BREAK); 2459 HBasicBlock* break_block = break_scope()->Get(stmt->target(), BREAK);
2445 subgraph()->exit_block()->Goto(break_block); 2460 current_block()->Goto(break_block);
2446 subgraph()->set_exit_block(NULL); 2461 set_current_block(NULL);
2447 } 2462 }
2448 2463
2449 2464
2450 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 2465 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
2451 AstContext* context = call_context(); 2466 AstContext* context = call_context();
2452 if (context == NULL) { 2467 if (context == NULL) {
2453 // Not an inlined return, so an actual one. 2468 // Not an inlined return, so an actual one.
2454 VISIT_FOR_VALUE(stmt->expression()); 2469 VISIT_FOR_VALUE(stmt->expression());
2455 HValue* result = environment()->Pop(); 2470 HValue* result = environment()->Pop();
2456 subgraph()->FinishExit(new HReturn(result)); 2471 subgraph()->FinishExit(new HReturn(result));
2457 } else { 2472 } else {
2458 // Return from an inlined function, visit the subexpression in the 2473 // Return from an inlined function, visit the subexpression in the
2459 // expression context of the call. 2474 // expression context of the call.
2460 if (context->IsTest()) { 2475 if (context->IsTest()) {
2461 TestContext* test = TestContext::cast(context); 2476 TestContext* test = TestContext::cast(context);
2462 VisitForControl(stmt->expression(), 2477 VisitForControl(stmt->expression(),
2463 test->if_true(), 2478 test->if_true(),
2464 test->if_false()); 2479 test->if_false());
2465 } else { 2480 } else {
2466 HValue* return_value = NULL; 2481 HValue* return_value = NULL;
2467 if (context->IsEffect()) { 2482 if (context->IsEffect()) {
2468 VISIT_FOR_EFFECT(stmt->expression()); 2483 VISIT_FOR_EFFECT(stmt->expression());
2469 return_value = graph()->GetConstantUndefined(); 2484 return_value = graph()->GetConstantUndefined();
2470 } else { 2485 } else {
2471 ASSERT(context->IsValue()); 2486 ASSERT(context->IsValue());
2472 VISIT_FOR_VALUE(stmt->expression()); 2487 VISIT_FOR_VALUE(stmt->expression());
2473 return_value = environment()->Pop(); 2488 return_value = environment()->Pop();
2474 } 2489 }
2475 subgraph()->exit_block()->AddLeaveInlined(return_value, 2490 current_block()->AddLeaveInlined(return_value,
2476 function_return_); 2491 function_return_);
2477 subgraph()->set_exit_block(NULL); 2492 set_current_block(NULL);
2478 } 2493 }
2479 } 2494 }
2480 } 2495 }
2481 2496
2482 2497
2483 void HGraphBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) { 2498 void HGraphBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) {
2484 BAILOUT("WithEnterStatement"); 2499 BAILOUT("WithEnterStatement");
2485 } 2500 }
2486 2501
2487 2502
2488 void HGraphBuilder::VisitWithExitStatement(WithExitStatement* stmt) { 2503 void HGraphBuilder::VisitWithExitStatement(WithExitStatement* stmt) {
2489 BAILOUT("WithExitStatement"); 2504 BAILOUT("WithExitStatement");
2490 } 2505 }
2491 2506
2492 2507
2493 HCompare* HGraphBuilder::BuildSwitchCompare(HSubgraph* subgraph, 2508 HCompare* HGraphBuilder::BuildSwitchCompare(HSubgraph* subgraph,
2494 HValue* switch_value, 2509 HValue* switch_value,
2495 CaseClause* clause) { 2510 CaseClause* clause) {
2496 AddToSubgraph(subgraph, clause->label()); 2511 AddToSubgraph(subgraph, clause->label());
2497 if (HasStackOverflow()) return NULL; 2512 if (HasStackOverflow()) return NULL;
2498 HValue* clause_value = subgraph->environment()->Pop(); 2513 HValue* clause_value = subgraph->exit_block()->last_environment()->Pop();
2499 HCompare* compare = new HCompare(switch_value, 2514 HCompare* compare = new HCompare(switch_value,
2500 clause_value, 2515 clause_value,
2501 Token::EQ_STRICT); 2516 Token::EQ_STRICT);
2502 compare->SetInputRepresentation(Representation::Integer32()); 2517 compare->SetInputRepresentation(Representation::Integer32());
2503 subgraph->exit_block()->AddInstruction(compare); 2518 subgraph->exit_block()->AddInstruction(compare);
2504 return compare; 2519 return compare;
2505 } 2520 }
2506 2521
2507 2522
2508 void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { 2523 void HGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2569 prev_compare_inst = BuildSwitchCompare(subgraph, switch_value, clause); 2584 prev_compare_inst = BuildSwitchCompare(subgraph, switch_value, clause);
2570 if (HasStackOverflow()) return; 2585 if (HasStackOverflow()) return;
2571 2586
2572 prev_graph = subgraph; 2587 prev_graph = subgraph;
2573 } 2588 }
2574 2589
2575 // Finish last comparison if there was at least one comparison. 2590 // Finish last comparison if there was at least one comparison.
2576 // last_false_block is the (empty) false-block of the last comparison. If 2591 // last_false_block is the (empty) false-block of the last comparison. If
2577 // there are no comparisons at all (a single default clause), it is just 2592 // there are no comparisons at all (a single default clause), it is just
2578 // the last block of the current subgraph. 2593 // the last block of the current subgraph.
2579 HBasicBlock* last_false_block = current_subgraph_->exit_block(); 2594 HBasicBlock* last_false_block = current_block();
2580 if (prev_graph != current_subgraph_) { 2595 if (prev_graph != current_subgraph_) {
2581 last_false_block = graph()->CreateBasicBlock(); 2596 last_false_block = graph()->CreateBasicBlock();
2582 HBasicBlock* empty = graph()->CreateBasicBlock(); 2597 HBasicBlock* empty = graph()->CreateBasicBlock();
2583 prev_graph->exit_block()->Finish(new HTest(prev_compare_inst, 2598 prev_graph->exit_block()->Finish(new HTest(prev_compare_inst,
2584 empty, 2599 empty,
2585 last_false_block)); 2600 last_false_block));
2586 } 2601 }
2587 2602
2588 // If we have a non-smi compare clause, we deoptimize after trying 2603 // If we have a non-smi compare clause, we deoptimize after trying
2589 // all the previous compares. 2604 // all the previous compares.
(...skipping 22 matching lines...) Expand all
2612 ASSERT(clause->IsSmiCompare()); 2627 ASSERT(clause->IsSmiCompare());
2613 // Connect with the corresponding comparison. 2628 // Connect with the corresponding comparison.
2614 subgraph = CreateEmptySubgraph(); 2629 subgraph = CreateEmptySubgraph();
2615 HBasicBlock* empty = 2630 HBasicBlock* empty =
2616 compare_graphs.at(i)->exit_block()->end()->FirstSuccessor(); 2631 compare_graphs.at(i)->exit_block()->end()->FirstSuccessor();
2617 empty->Finish(new HGoto(subgraph->entry_block())); 2632 empty->Finish(new HGoto(subgraph->entry_block()));
2618 } 2633 }
2619 } 2634 }
2620 2635
2621 // Check for fall-through from previous statement block. 2636 // Check for fall-through from previous statement block.
2622 if (previous_subgraph != NULL && previous_subgraph->HasExit()) { 2637 if (previous_subgraph != NULL && previous_subgraph->exit_block() != NULL) {
2623 if (subgraph == NULL) subgraph = CreateEmptySubgraph(); 2638 if (subgraph == NULL) subgraph = CreateEmptySubgraph();
2624 previous_subgraph->exit_block()-> 2639 previous_subgraph->exit_block()->
2625 Finish(new HGoto(subgraph->entry_block())); 2640 Finish(new HGoto(subgraph->entry_block()));
2626 } 2641 }
2627 2642
2628 if (subgraph != NULL) { 2643 if (subgraph != NULL) {
2629 BreakAndContinueInfo break_info(stmt); 2644 BreakAndContinueInfo break_info(stmt);
2630 { BreakAndContinueScope push(&break_info, this); 2645 { BreakAndContinueScope push(&break_info, this);
2631 ADD_TO_SUBGRAPH(subgraph, clause->statements()); 2646 ADD_TO_SUBGRAPH(subgraph, clause->statements());
2632 } 2647 }
2633 if (break_info.break_block() != NULL) { 2648 if (break_info.break_block() != NULL) {
2634 break_info.break_block()->SetJoinId(stmt->ExitId()); 2649 break_info.break_block()->SetJoinId(stmt->ExitId());
2635 break_info.break_block()->Finish(new HGoto(single_exit_block)); 2650 break_info.break_block()->Finish(new HGoto(single_exit_block));
2636 } 2651 }
2637 } 2652 }
2638 2653
2639 previous_subgraph = subgraph; 2654 previous_subgraph = subgraph;
2640 } 2655 }
2641 2656
2642 // If the last statement block has a fall-through, connect it to the 2657 // If the last statement block has a fall-through, connect it to the
2643 // single exit block. 2658 // single exit block.
2644 if (previous_subgraph != NULL && previous_subgraph->HasExit()) { 2659 if (previous_subgraph != NULL && previous_subgraph->exit_block() != NULL) {
2645 previous_subgraph->exit_block()->Finish(new HGoto(single_exit_block)); 2660 previous_subgraph->exit_block()->Finish(new HGoto(single_exit_block));
2646 } 2661 }
2647 2662
2648 // If there is no default clause finish the last comparison's false target. 2663 // If there is no default clause finish the last comparison's false target.
2649 if (!last_false_block->IsFinished()) { 2664 if (!last_false_block->IsFinished()) {
2650 last_false_block->Finish(new HGoto(single_exit_block)); 2665 last_false_block->Finish(new HGoto(single_exit_block));
2651 } 2666 }
2652 2667
2653 if (single_exit_block->HasPredecessor()) { 2668 if (single_exit_block->HasPredecessor()) {
2654 current_subgraph_->set_exit_block(single_exit_block); 2669 set_current_block(single_exit_block);
2655 } else { 2670 } else {
2656 current_subgraph_->set_exit_block(NULL); 2671 set_current_block(NULL);
2657 } 2672 }
2658 } 2673 }
2659 2674
2660 bool HGraph::HasOsrEntryAt(IterationStatement* statement) { 2675 bool HGraph::HasOsrEntryAt(IterationStatement* statement) {
2661 return statement->OsrEntryId() == info()->osr_ast_id(); 2676 return statement->OsrEntryId() == info()->osr_ast_id();
2662 } 2677 }
2663 2678
2664 2679
2665 void HSubgraph::PreProcessOsrEntry(IterationStatement* statement) { 2680 void HSubgraph::PreProcessOsrEntry(IterationStatement* statement) {
2666 if (!graph()->HasOsrEntryAt(statement)) return; 2681 if (!graph()->HasOsrEntryAt(statement)) return;
(...skipping 21 matching lines...) Expand all
2688 2703
2689 osr_entry->AddSimulate(osr_entry_id); 2704 osr_entry->AddSimulate(osr_entry_id);
2690 osr_entry->AddInstruction(new HOsrEntry(osr_entry_id)); 2705 osr_entry->AddInstruction(new HOsrEntry(osr_entry_id));
2691 osr_entry->Goto(loop_predecessor); 2706 osr_entry->Goto(loop_predecessor);
2692 loop_predecessor->SetJoinId(statement->EntryId()); 2707 loop_predecessor->SetJoinId(statement->EntryId());
2693 set_exit_block(loop_predecessor); 2708 set_exit_block(loop_predecessor);
2694 } 2709 }
2695 2710
2696 2711
2697 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 2712 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
2698 ASSERT(subgraph()->HasExit()); 2713 ASSERT(current_block() != NULL);
2699 subgraph()->PreProcessOsrEntry(stmt); 2714 subgraph()->PreProcessOsrEntry(stmt);
2700 2715
2701 HSubgraph* body_graph = CreateLoopHeaderSubgraph(environment()); 2716 HSubgraph* body_graph = CreateLoopHeaderSubgraph(environment());
2702 BreakAndContinueInfo break_info(stmt); 2717 BreakAndContinueInfo break_info(stmt);
2703 { BreakAndContinueScope push(&break_info, this); 2718 { BreakAndContinueScope push(&break_info, this);
2704 ADD_TO_SUBGRAPH(body_graph, stmt->body()); 2719 ADD_TO_SUBGRAPH(body_graph, stmt->body());
2705 } 2720 }
2706 body_graph->ResolveContinue(stmt, break_info.continue_block()); 2721 body_graph->ResolveContinue(stmt, break_info.continue_block());
2707 2722
2708 if (!body_graph->HasExit() || stmt->cond()->ToBooleanIsTrue()) { 2723 if (body_graph->exit_block() == NULL || stmt->cond()->ToBooleanIsTrue()) {
2709 subgraph()->AppendEndless(body_graph, stmt, break_info.break_block()); 2724 subgraph()->AppendEndless(body_graph, stmt, break_info.break_block());
2710 } else { 2725 } else {
2711 HSubgraph* go_back = CreateEmptySubgraph(); 2726 HSubgraph* go_back = CreateEmptySubgraph();
2712 HSubgraph* exit = CreateEmptySubgraph(); 2727 HSubgraph* exit = CreateEmptySubgraph();
2713 { 2728 {
2714 SubgraphScope scope(this, body_graph); 2729 SubgraphScope scope(this, body_graph);
2715 VISIT_FOR_CONTROL(stmt->cond(), 2730 VISIT_FOR_CONTROL(stmt->cond(),
2716 go_back->entry_block(), 2731 go_back->entry_block(),
2717 exit->entry_block()); 2732 exit->entry_block());
2718 go_back->entry_block()->SetJoinId(stmt->BackEdgeId()); 2733 go_back->entry_block()->SetJoinId(stmt->BackEdgeId());
2719 exit->entry_block()->SetJoinId(stmt->ExitId()); 2734 exit->entry_block()->SetJoinId(stmt->ExitId());
2720 } 2735 }
2721 subgraph()->AppendDoWhile(body_graph, stmt, go_back, exit, 2736 subgraph()->AppendDoWhile(body_graph, stmt, go_back, exit,
2722 break_info.break_block()); 2737 break_info.break_block());
2723 } 2738 }
2724 } 2739 }
2725 2740
2726 2741
2727 bool HGraphBuilder::ShouldPeel(HSubgraph* cond, HSubgraph* body) { 2742 bool HGraphBuilder::ShouldPeel(HSubgraph* cond, HSubgraph* body) {
2728 return FLAG_use_peeling; 2743 return FLAG_use_peeling;
2729 } 2744 }
2730 2745
2731 2746
2732 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { 2747 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
2733 ASSERT(subgraph()->HasExit()); 2748 ASSERT(current_block() != NULL);
2734 subgraph()->PreProcessOsrEntry(stmt); 2749 subgraph()->PreProcessOsrEntry(stmt);
2735 2750
2736 HSubgraph* cond_graph = NULL; 2751 HSubgraph* cond_graph = NULL;
2737 HSubgraph* body_graph = NULL; 2752 HSubgraph* body_graph = NULL;
2738 HSubgraph* exit_graph = NULL; 2753 HSubgraph* exit_graph = NULL;
2739 2754
2740 // If the condition is constant true, do not generate a condition subgraph. 2755 // If the condition is constant true, do not generate a condition subgraph.
2741 if (stmt->cond()->ToBooleanIsTrue()) { 2756 if (stmt->cond()->ToBooleanIsTrue()) {
2742 body_graph = CreateLoopHeaderSubgraph(environment()); 2757 body_graph = CreateLoopHeaderSubgraph(environment());
2743 } else { 2758 } else {
(...skipping 25 matching lines...) Expand all
2769 } 2784 }
2770 } 2785 }
2771 2786
2772 2787
2773 void HGraphBuilder::AppendPeeledWhile(IterationStatement* stmt, 2788 void HGraphBuilder::AppendPeeledWhile(IterationStatement* stmt,
2774 HSubgraph* cond_graph, 2789 HSubgraph* cond_graph,
2775 HSubgraph* body_graph, 2790 HSubgraph* body_graph,
2776 HSubgraph* exit_graph, 2791 HSubgraph* exit_graph,
2777 HBasicBlock* break_block) { 2792 HBasicBlock* break_block) {
2778 HSubgraph* loop = NULL; 2793 HSubgraph* loop = NULL;
2779 if (body_graph->HasExit() && stmt != peeled_statement_ && 2794 if (body_graph->exit_block() != NULL && stmt != peeled_statement_ &&
2780 ShouldPeel(cond_graph, body_graph)) { 2795 ShouldPeel(cond_graph, body_graph)) {
2781 // Save the last peeled iteration statement to prevent infinite recursion. 2796 // Save the last peeled iteration statement to prevent infinite recursion.
2782 IterationStatement* outer_peeled_statement = peeled_statement_; 2797 IterationStatement* outer_peeled_statement = peeled_statement_;
2783 peeled_statement_ = stmt; 2798 peeled_statement_ = stmt;
2784 loop = CreateGotoSubgraph(body_graph->environment()); 2799 loop = CreateGotoSubgraph(body_graph->exit_block()->last_environment());
2785 ADD_TO_SUBGRAPH(loop, stmt); 2800 ADD_TO_SUBGRAPH(loop, stmt);
2786 peeled_statement_ = outer_peeled_statement; 2801 peeled_statement_ = outer_peeled_statement;
2787 } 2802 }
2788 subgraph()->AppendWhile(cond_graph, body_graph, stmt, loop, exit_graph, 2803 subgraph()->AppendWhile(cond_graph, body_graph, stmt, loop, exit_graph,
2789 break_block); 2804 break_block);
2790 } 2805 }
2791 2806
2792 2807
2793 void HGraphBuilder::VisitForStatement(ForStatement* stmt) { 2808 void HGraphBuilder::VisitForStatement(ForStatement* stmt) {
2794 // Only visit the init statement in the peeled part of the loop. 2809 // Only visit the init statement in the peeled part of the loop.
2795 if (stmt->init() != NULL && peeled_statement_ != stmt) { 2810 if (stmt->init() != NULL && peeled_statement_ != stmt) {
2796 Visit(stmt->init()); 2811 Visit(stmt->init());
2797 CHECK_BAILOUT; 2812 CHECK_BAILOUT;
2798 } 2813 }
2799 ASSERT(subgraph()->HasExit()); 2814 ASSERT(current_block() != NULL);
2800 subgraph()->PreProcessOsrEntry(stmt); 2815 subgraph()->PreProcessOsrEntry(stmt);
2801 2816
2802 HSubgraph* cond_graph = NULL; 2817 HSubgraph* cond_graph = NULL;
2803 HSubgraph* body_graph = NULL; 2818 HSubgraph* body_graph = NULL;
2804 HSubgraph* exit_graph = NULL; 2819 HSubgraph* exit_graph = NULL;
2805 if (stmt->cond() != NULL) { 2820 if (stmt->cond() != NULL) {
2806 cond_graph = CreateLoopHeaderSubgraph(environment()); 2821 cond_graph = CreateLoopHeaderSubgraph(environment());
2807 body_graph = CreateEmptySubgraph(); 2822 body_graph = CreateEmptySubgraph();
2808 exit_graph = CreateEmptySubgraph(); 2823 exit_graph = CreateEmptySubgraph();
2809 { 2824 {
2810 SubgraphScope scope(this, cond_graph); 2825 SubgraphScope scope(this, cond_graph);
2811 VISIT_FOR_CONTROL(stmt->cond(), 2826 VISIT_FOR_CONTROL(stmt->cond(),
2812 body_graph->entry_block(), 2827 body_graph->entry_block(),
2813 exit_graph->entry_block()); 2828 exit_graph->entry_block());
2814 body_graph->entry_block()->SetJoinId(stmt->BodyId()); 2829 body_graph->entry_block()->SetJoinId(stmt->BodyId());
2815 exit_graph->entry_block()->SetJoinId(stmt->ExitId()); 2830 exit_graph->entry_block()->SetJoinId(stmt->ExitId());
2816 } 2831 }
2817 } else { 2832 } else {
2818 body_graph = CreateLoopHeaderSubgraph(environment()); 2833 body_graph = CreateLoopHeaderSubgraph(environment());
2819 } 2834 }
2820 BreakAndContinueInfo break_info(stmt); 2835 BreakAndContinueInfo break_info(stmt);
2821 { BreakAndContinueScope push(&break_info, this); 2836 { BreakAndContinueScope push(&break_info, this);
2822 ADD_TO_SUBGRAPH(body_graph, stmt->body()); 2837 ADD_TO_SUBGRAPH(body_graph, stmt->body());
2823 } 2838 }
2824 2839
2825 HSubgraph* next_graph = NULL; 2840 HSubgraph* next_graph = NULL;
2826 body_graph->ResolveContinue(stmt, break_info.continue_block()); 2841 body_graph->ResolveContinue(stmt, break_info.continue_block());
2827 2842
2828 if (stmt->next() != NULL && body_graph->HasExit()) { 2843 if (stmt->next() != NULL && body_graph->exit_block() != NULL) {
2829 next_graph = CreateGotoSubgraph(body_graph->environment()); 2844 next_graph =
2845 CreateGotoSubgraph(body_graph->exit_block()->last_environment());
2830 ADD_TO_SUBGRAPH(next_graph, stmt->next()); 2846 ADD_TO_SUBGRAPH(next_graph, stmt->next());
2831 body_graph->Append(next_graph, NULL, NULL); 2847 body_graph->Append(next_graph, NULL, NULL);
2832 next_graph->entry_block()->SetJoinId(stmt->ContinueId()); 2848 next_graph->entry_block()->SetJoinId(stmt->ContinueId());
2833 } 2849 }
2834 2850
2835 if (cond_graph != NULL) { 2851 if (cond_graph != NULL) {
2836 AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph, 2852 AppendPeeledWhile(stmt, cond_graph, body_graph, exit_graph,
2837 break_info.break_block()); 2853 break_info.break_block());
2838 } else { 2854 } else {
2839 subgraph()->AppendEndless(body_graph, stmt, break_info.break_block()); 2855 subgraph()->AppendEndless(body_graph, stmt, break_info.break_block());
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
3096 // block. Use the default as a target of the last branch. 3112 // block. Use the default as a target of the last branch.
3097 HSubgraph* if_true = body_graphs->at(i); 3113 HSubgraph* if_true = body_graphs->at(i);
3098 HSubgraph* if_false = (i == maps->length() - 1) 3114 HSubgraph* if_false = (i == maps->length() - 1)
3099 ? default_graph 3115 ? default_graph
3100 : CreateBranchSubgraph(environment()); 3116 : CreateBranchSubgraph(environment());
3101 HCompareMap* compare = 3117 HCompareMap* compare =
3102 new HCompareMap(receiver, 3118 new HCompareMap(receiver,
3103 maps->at(i), 3119 maps->at(i),
3104 if_true->entry_block(), 3120 if_true->entry_block(),
3105 if_false->entry_block()); 3121 if_false->entry_block());
3106 subgraph()->exit_block()->Finish(compare); 3122 current_block()->Finish(compare);
3107 3123
3108 if (if_true->HasExit()) { 3124 if (if_true->exit_block() != NULL) {
3109 // In an effect context the value of the type switch is not needed. 3125 // In an effect context the value of the type switch is not needed.
3110 // There is no need to merge it at the join block only to discard it. 3126 // There is no need to merge it at the join block only to discard it.
3111 if (ast_context()->IsEffect()) { 3127 if (ast_context()->IsEffect()) {
3112 if_true->exit_block()->last_environment()->Drop(1); 3128 if_true->exit_block()->last_environment()->Drop(1);
3113 } 3129 }
3114 if_true->exit_block()->Goto(join_block); 3130 if_true->exit_block()->Goto(join_block);
3115 } 3131 }
3116 3132
3117 subgraph()->set_exit_block(if_false->exit_block()); 3133 set_current_block(if_false->exit_block());
3118 } 3134 }
3119 3135
3120 // Connect the default if necessary. 3136 // Connect the default if necessary.
3121 if (subgraph()->HasExit()) { 3137 if (current_block() != NULL) {
3122 if (ast_context()->IsEffect()) { 3138 if (ast_context()->IsEffect()) {
3123 environment()->Drop(1); 3139 environment()->Drop(1);
3124 } 3140 }
3125 subgraph()->exit_block()->Goto(join_block); 3141 current_block()->Goto(join_block);
3126 } 3142 }
3127 3143
3128 if (join_block->predecessors()->is_empty()) return NULL; 3144 if (join_block->predecessors()->is_empty()) return NULL;
3129 join_block->SetJoinId(join_id); 3145 join_block->SetJoinId(join_id);
3130 return join_block; 3146 return join_block;
3131 } 3147 }
3132 3148
3133 3149
3134 // Sets the lookup result and returns true if the store can be inlined. 3150 // Sets the lookup result and returns true if the store can be inlined.
3135 static bool ComputeStoredField(Handle<Map> type, 3151 static bool ComputeStoredField(Handle<Map> type,
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
3272 } else { 3288 } else {
3273 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); 3289 HInstruction* instr = BuildStoreNamedGeneric(object, name, value);
3274 Push(value); 3290 Push(value);
3275 instr->set_position(expr->position()); 3291 instr->set_position(expr->position());
3276 AddInstruction(instr); 3292 AddInstruction(instr);
3277 } 3293 }
3278 } 3294 }
3279 3295
3280 HBasicBlock* new_exit_block = 3296 HBasicBlock* new_exit_block =
3281 BuildTypeSwitch(object, &maps, &subgraphs, default_graph, expr->id()); 3297 BuildTypeSwitch(object, &maps, &subgraphs, default_graph, expr->id());
3282 subgraph()->set_exit_block(new_exit_block); 3298 set_current_block(new_exit_block);
3283 // In an effect context, we did not materialized the value in the 3299 // In an effect context, we did not materialized the value in the
3284 // predecessor environments so there's no need to handle it here. 3300 // predecessor environments so there's no need to handle it here.
3285 if (subgraph()->HasExit() && !ast_context()->IsEffect()) { 3301 if (current_block() != NULL && !ast_context()->IsEffect()) {
3286 ast_context()->ReturnValue(Pop()); 3302 ast_context()->ReturnValue(Pop());
3287 } 3303 }
3288 } 3304 }
3289 } 3305 }
3290 3306
3291 3307
3292 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 3308 void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
3293 Property* prop = expr->target()->AsProperty(); 3309 Property* prop = expr->target()->AsProperty();
3294 ASSERT(prop != NULL); 3310 ASSERT(prop != NULL);
3295 expr->RecordTypeFeedback(oracle()); 3311 expr->RecordTypeFeedback(oracle());
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
3606 default_graph->FinishExit(new HDeoptimize()); 3622 default_graph->FinishExit(new HDeoptimize());
3607 } else { 3623 } else {
3608 HInstruction* instr = BuildLoadNamedGeneric(object, expr); 3624 HInstruction* instr = BuildLoadNamedGeneric(object, expr);
3609 instr->set_position(expr->position()); 3625 instr->set_position(expr->position());
3610 PushAndAdd(instr); 3626 PushAndAdd(instr);
3611 } 3627 }
3612 } 3628 }
3613 3629
3614 HBasicBlock* new_exit_block = 3630 HBasicBlock* new_exit_block =
3615 BuildTypeSwitch(object, &maps, &subgraphs, default_graph, expr->id()); 3631 BuildTypeSwitch(object, &maps, &subgraphs, default_graph, expr->id());
3616 subgraph()->set_exit_block(new_exit_block); 3632 set_current_block(new_exit_block);
3617 // In an effect context, we did not materialized the value in the 3633 // In an effect context, we did not materialized the value in the
3618 // predecessor environments so there's no need to handle it here. 3634 // predecessor environments so there's no need to handle it here.
3619 if (subgraph()->HasExit() && !ast_context()->IsEffect()) { 3635 if (current_block() != NULL && !ast_context()->IsEffect()) {
3620 ast_context()->ReturnValue(Pop()); 3636 ast_context()->ReturnValue(Pop());
3621 } 3637 }
3622 } 3638 }
3623 } 3639 }
3624 3640
3625 3641
3626 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, 3642 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
3627 Property* expr, 3643 Property* expr,
3628 Handle<Map> type, 3644 Handle<Map> type,
3629 LookupResult* lookup, 3645 LookupResult* lookup,
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
3966 AddInstruction(context); 3982 AddInstruction(context);
3967 HCall* call = new HCallNamed(context, name, argument_count); 3983 HCall* call = new HCallNamed(context, name, argument_count);
3968 call->set_position(expr->position()); 3984 call->set_position(expr->position());
3969 PreProcessCall(call); 3985 PreProcessCall(call);
3970 PushAndAdd(call); 3986 PushAndAdd(call);
3971 } 3987 }
3972 } 3988 }
3973 3989
3974 HBasicBlock* new_exit_block = 3990 HBasicBlock* new_exit_block =
3975 BuildTypeSwitch(receiver, &maps, &subgraphs, default_graph, expr->id()); 3991 BuildTypeSwitch(receiver, &maps, &subgraphs, default_graph, expr->id());
3976 subgraph()->set_exit_block(new_exit_block); 3992 set_current_block(new_exit_block);
3977 // In an effect context, we did not materialized the value in the 3993 // In an effect context, we did not materialized the value in the
3978 // predecessor environments so there's no need to handle it here. 3994 // predecessor environments so there's no need to handle it here.
3979 if (new_exit_block != NULL && !ast_context()->IsEffect()) { 3995 if (new_exit_block != NULL && !ast_context()->IsEffect()) {
3980 ast_context()->ReturnValue(Pop()); 3996 ast_context()->ReturnValue(Pop());
3981 } 3997 }
3982 } 3998 }
3983 } 3999 }
3984 4000
3985 4001
3986 void HGraphBuilder::TraceInline(Handle<JSFunction> target, bool result) { 4002 void HGraphBuilder::TraceInline(Handle<JSFunction> target, bool result) {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
4135 oracle_ = saved_oracle; 4151 oracle_ = saved_oracle;
4136 graph()->info()->SetOsrAstId(saved_osr_ast_id); 4152 graph()->info()->SetOsrAstId(saved_osr_ast_id);
4137 return false; 4153 return false;
4138 } 4154 }
4139 4155
4140 // Update inlined nodes count. 4156 // Update inlined nodes count.
4141 inlined_count_ += nodes_added; 4157 inlined_count_ += nodes_added;
4142 4158
4143 if (FLAG_trace_inlining) TraceInline(target, true); 4159 if (FLAG_trace_inlining) TraceInline(target, true);
4144 4160
4145 if (body->HasExit()) { 4161 if (body->exit_block() != NULL) {
4146 // Add a return of undefined if control can fall off the body. In a 4162 // Add a return of undefined if control can fall off the body. In a
4147 // test context, undefined is false. 4163 // test context, undefined is false.
4148 HValue* return_value = graph()->GetConstantUndefined(); 4164 HValue* return_value = graph()->GetConstantUndefined();
4149 if (test_context == NULL) { 4165 if (test_context == NULL) {
4150 ASSERT(function_return_ != NULL); 4166 ASSERT(function_return_ != NULL);
4151 body->exit_block()->AddLeaveInlined(return_value, function_return_); 4167 body->exit_block()->AddLeaveInlined(return_value, function_return_);
4152 } else { 4168 } else {
4153 // The graph builder assumes control can reach both branches of a 4169 // The graph builder assumes control can reach both branches of a
4154 // test, so we materialize the undefined value and test it rather than 4170 // test, so we materialize the undefined value and test it rather than
4155 // simply jumping to the false target. 4171 // simply jumping to the false target.
4156 // 4172 //
4157 // TODO(3168478): refactor to avoid this. 4173 // TODO(3168478): refactor to avoid this.
4158 HBasicBlock* empty_true = graph()->CreateBasicBlock(); 4174 HBasicBlock* empty_true = graph()->CreateBasicBlock();
4159 HBasicBlock* empty_false = graph()->CreateBasicBlock(); 4175 HBasicBlock* empty_false = graph()->CreateBasicBlock();
4160 HTest* test = new HTest(return_value, empty_true, empty_false); 4176 HTest* test = new HTest(return_value, empty_true, empty_false);
4161 body->exit_block()->Finish(test); 4177 body->exit_block()->Finish(test);
4162 4178
4163 HValue* const no_return_value = NULL; 4179 HValue* const no_return_value = NULL;
4164 empty_true->AddLeaveInlined(no_return_value, test_context->if_true()); 4180 empty_true->AddLeaveInlined(no_return_value, test_context->if_true());
4165 empty_false->AddLeaveInlined(no_return_value, test_context->if_false()); 4181 empty_false->AddLeaveInlined(no_return_value, test_context->if_false());
4166 } 4182 }
4167 body->set_exit_block(NULL); 4183 body->set_exit_block(NULL);
4168 } 4184 }
4169 4185
4170 // Record the environment at the inlined function call. 4186 // Record the environment at the inlined function call.
4171 AddSimulate(expr->ReturnId()); 4187 AddSimulate(expr->ReturnId());
4172 4188
4173 // Jump to the function entry (without re-recording the environment). 4189 // Jump to the function entry (without re-recording the environment).
4174 subgraph()->exit_block()->Finish(new HGoto(body->entry_block())); 4190 current_block()->Finish(new HGoto(body->entry_block()));
4175 4191
4176 // Fix up the function exits. 4192 // Fix up the function exits.
4177 if (test_context != NULL) { 4193 if (test_context != NULL) {
4178 HBasicBlock* if_true = test_context->if_true(); 4194 HBasicBlock* if_true = test_context->if_true();
4179 HBasicBlock* if_false = test_context->if_false(); 4195 HBasicBlock* if_false = test_context->if_false();
4180 if_true->SetJoinId(expr->id()); 4196 if_true->SetJoinId(expr->id());
4181 if_false->SetJoinId(expr->id()); 4197 if_false->SetJoinId(expr->id());
4182 ASSERT(ast_context() == test_context); 4198 ASSERT(ast_context() == test_context);
4183 delete test_context; // Destructor pops from expression context stack. 4199 delete test_context; // Destructor pops from expression context stack.
4184 4200
4185 // Forward to the real test context. 4201 // Forward to the real test context.
4186 HValue* const no_return_value = NULL; 4202 HValue* const no_return_value = NULL;
4187 HBasicBlock* true_target = TestContext::cast(ast_context())->if_true(); 4203 HBasicBlock* true_target = TestContext::cast(ast_context())->if_true();
4188 if (true_target->IsInlineReturnTarget()) { 4204 if (true_target->IsInlineReturnTarget()) {
4189 if_true->AddLeaveInlined(no_return_value, true_target); 4205 if_true->AddLeaveInlined(no_return_value, true_target);
4190 } else { 4206 } else {
4191 if_true->Goto(true_target); 4207 if_true->Goto(true_target);
4192 } 4208 }
4193 4209
4194 HBasicBlock* false_target = TestContext::cast(ast_context())->if_false(); 4210 HBasicBlock* false_target = TestContext::cast(ast_context())->if_false();
4195 if (false_target->IsInlineReturnTarget()) { 4211 if (false_target->IsInlineReturnTarget()) {
4196 if_false->AddLeaveInlined(no_return_value, false_target); 4212 if_false->AddLeaveInlined(no_return_value, false_target);
4197 } else { 4213 } else {
4198 if_false->Goto(false_target); 4214 if_false->Goto(false_target);
4199 } 4215 }
4200 4216
4201 // TODO(kmillikin): Come up with a better way to handle this. It is too 4217 // TODO(kmillikin): Come up with a better way to handle this. It is too
4202 // subtle. NULL here indicates that the enclosing context has no control 4218 // subtle. NULL here indicates that the enclosing context has no control
4203 // flow to handle. 4219 // flow to handle.
4204 subgraph()->set_exit_block(NULL); 4220 set_current_block(NULL);
4205 4221
4206 } else { 4222 } else {
4207 function_return_->SetJoinId(expr->id()); 4223 function_return_->SetJoinId(expr->id());
4208 subgraph()->set_exit_block(function_return_); 4224 set_current_block(function_return_);
4209 } 4225 }
4210 4226
4211 call_context_ = saved_call_context; 4227 call_context_ = saved_call_context;
4212 function_return_ = saved_function_return; 4228 function_return_ = saved_function_return;
4213 oracle_ = saved_oracle; 4229 oracle_ = saved_oracle;
4214 graph()->info()->SetOsrAstId(saved_osr_ast_id); 4230 graph()->info()->SetOsrAstId(saved_osr_ast_id);
4215 4231
4216 return true; 4232 return true;
4217 } 4233 }
4218 4234
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
4427 // When the target has a custom call IC generator, use the IC, 4443 // When the target has a custom call IC generator, use the IC,
4428 // because it is likely to generate better code. Also use the 4444 // because it is likely to generate better code. Also use the
4429 // IC when a primitive receiver check is required. 4445 // IC when a primitive receiver check is required.
4430 HContext* context = new HContext; 4446 HContext* context = new HContext;
4431 AddInstruction(context); 4447 AddInstruction(context);
4432 call = new HCallNamed(context, name, argument_count); 4448 call = new HCallNamed(context, name, argument_count);
4433 } else { 4449 } else {
4434 AddCheckConstantFunction(expr, receiver, receiver_map, true); 4450 AddCheckConstantFunction(expr, receiver, receiver_map, true);
4435 4451
4436 if (TryInline(expr)) { 4452 if (TryInline(expr)) {
4437 if (subgraph()->HasExit()) { 4453 if (current_block() != NULL) {
4438 HValue* return_value = Pop(); 4454 HValue* return_value = Pop();
4439 // If we inlined a function in a test context then we need to emit 4455 // If we inlined a function in a test context then we need to emit
4440 // a simulate here to shadow the ones at the end of the 4456 // a simulate here to shadow the ones at the end of the
4441 // predecessor blocks. Those environments contain the return 4457 // predecessor blocks. Those environments contain the return
4442 // value on top and do not correspond to any actual state of the 4458 // value on top and do not correspond to any actual state of the
4443 // unoptimized code. 4459 // unoptimized code.
4444 if (ast_context()->IsEffect()) AddSimulate(expr->id()); 4460 if (ast_context()->IsEffect()) AddSimulate(expr->id());
4445 ast_context()->ReturnValue(return_value); 4461 ast_context()->ReturnValue(return_value);
4446 } 4462 }
4447 return; 4463 return;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4498 // Replace the global object with the global receiver. 4514 // Replace the global object with the global receiver.
4499 HGlobalReceiver* global_receiver = new HGlobalReceiver(global_object); 4515 HGlobalReceiver* global_receiver = new HGlobalReceiver(global_object);
4500 // Index of the receiver from the top of the expression stack. 4516 // Index of the receiver from the top of the expression stack.
4501 const int receiver_index = argument_count - 1; 4517 const int receiver_index = argument_count - 1;
4502 AddInstruction(global_receiver); 4518 AddInstruction(global_receiver);
4503 ASSERT(environment()->ExpressionStackAt(receiver_index)-> 4519 ASSERT(environment()->ExpressionStackAt(receiver_index)->
4504 IsGlobalObject()); 4520 IsGlobalObject());
4505 environment()->SetExpressionStackAt(receiver_index, global_receiver); 4521 environment()->SetExpressionStackAt(receiver_index, global_receiver);
4506 4522
4507 if (TryInline(expr)) { 4523 if (TryInline(expr)) {
4508 if (subgraph()->HasExit()) { 4524 if (current_block() != NULL) {
4509 HValue* return_value = Pop(); 4525 HValue* return_value = Pop();
4510 // If we inlined a function in a test context then we need to 4526 // If we inlined a function in a test context then we need to
4511 // emit a simulate here to shadow the ones at the end of the 4527 // emit a simulate here to shadow the ones at the end of the
4512 // predecessor blocks. Those environments contain the return 4528 // predecessor blocks. Those environments contain the return
4513 // value on top and do not correspond to any actual state of the 4529 // value on top and do not correspond to any actual state of the
4514 // unoptimized code. 4530 // unoptimized code.
4515 if (ast_context()->IsEffect()) AddSimulate(expr->id()); 4531 if (ast_context()->IsEffect()) AddSimulate(expr->id());
4516 ast_context()->ReturnValue(return_value); 4532 ast_context()->ReturnValue(return_value);
4517 } 4533 }
4518 return; 4534 return;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
4666 VisitForControl(expr->expression(), 4682 VisitForControl(expr->expression(),
4667 context->if_false(), 4683 context->if_false(),
4668 context->if_true()); 4684 context->if_true());
4669 } else if (ast_context()->IsValue()) { 4685 } else if (ast_context()->IsValue()) {
4670 HSubgraph* true_graph = CreateEmptySubgraph(); 4686 HSubgraph* true_graph = CreateEmptySubgraph();
4671 HSubgraph* false_graph = CreateEmptySubgraph(); 4687 HSubgraph* false_graph = CreateEmptySubgraph();
4672 VISIT_FOR_CONTROL(expr->expression(), 4688 VISIT_FOR_CONTROL(expr->expression(),
4673 false_graph->entry_block(), 4689 false_graph->entry_block(),
4674 true_graph->entry_block()); 4690 true_graph->entry_block());
4675 true_graph->entry_block()->SetJoinId(expr->expression()->id()); 4691 true_graph->entry_block()->SetJoinId(expr->expression()->id());
4676 true_graph->environment()->Push(graph_->GetConstantTrue()); 4692 true_graph->exit_block()->last_environment()->Push(
4693 graph_->GetConstantTrue());
4677 4694
4678 false_graph->entry_block()->SetJoinId(expr->expression()->id()); 4695 false_graph->entry_block()->SetJoinId(expr->expression()->id());
4679 false_graph->environment()->Push(graph_->GetConstantFalse()); 4696 false_graph->exit_block()->last_environment()->Push(
4697 graph_->GetConstantFalse());
4680 4698
4681 current_subgraph_->AppendJoin(true_graph, false_graph, expr); 4699 current_subgraph_->AppendJoin(true_graph, false_graph, expr);
4682 ast_context()->ReturnValue(Pop()); 4700 ast_context()->ReturnValue(Pop());
4683 } else { 4701 } else {
4684 ASSERT(ast_context()->IsEffect()); 4702 ASSERT(ast_context()->IsEffect());
4685 VISIT_FOR_EFFECT(expr->expression()); 4703 VISIT_FOR_EFFECT(expr->expression());
4686 } 4704 }
4687 4705
4688 } else if (op == Token::BIT_NOT || op == Token::SUB) { 4706 } else if (op == Token::BIT_NOT || op == Token::SUB) {
4689 VISIT_FOR_VALUE(expr->expression()); 4707 VISIT_FOR_VALUE(expr->expression());
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
4966 HBasicBlock* eval_right = graph()->CreateBasicBlock(); 4984 HBasicBlock* eval_right = graph()->CreateBasicBlock();
4967 if (is_logical_and) { 4985 if (is_logical_and) {
4968 VISIT_FOR_CONTROL(expr->left(), eval_right, context->if_false()); 4986 VISIT_FOR_CONTROL(expr->left(), eval_right, context->if_false());
4969 } else { 4987 } else {
4970 VISIT_FOR_CONTROL(expr->left(), context->if_true(), eval_right); 4988 VISIT_FOR_CONTROL(expr->left(), context->if_true(), eval_right);
4971 } 4989 }
4972 eval_right->SetJoinId(expr->RightId()); 4990 eval_right->SetJoinId(expr->RightId());
4973 4991
4974 // Translate right subexpression by visiting it in the same AST 4992 // Translate right subexpression by visiting it in the same AST
4975 // context as the entire expression. 4993 // context as the entire expression.
4976 subgraph()->set_exit_block(eval_right); 4994 set_current_block(eval_right);
4977 Visit(expr->right()); 4995 Visit(expr->right());
4978 4996
4979 } else if (ast_context()->IsValue()) { 4997 } else if (ast_context()->IsValue()) {
4980 VISIT_FOR_VALUE(expr->left()); 4998 VISIT_FOR_VALUE(expr->left());
4981 ASSERT(current_subgraph_->HasExit()); 4999 ASSERT(current_block() != NULL);
4982 5000
4983 HValue* left = Top(); 5001 HValue* left = Top();
4984 HEnvironment* environment_copy = environment()->Copy(); 5002 HEnvironment* environment_copy = environment()->Copy();
4985 environment_copy->Pop(); 5003 environment_copy->Pop();
4986 HSubgraph* right_subgraph; 5004 HSubgraph* right_subgraph;
4987 right_subgraph = CreateBranchSubgraph(environment_copy); 5005 right_subgraph = CreateBranchSubgraph(environment_copy);
4988 ADD_TO_SUBGRAPH(right_subgraph, expr->right()); 5006 ADD_TO_SUBGRAPH(right_subgraph, expr->right());
4989 5007
4990 ASSERT(subgraph()->HasExit() && right_subgraph->HasExit()); 5008 ASSERT(current_block() != NULL &&
5009 right_subgraph->exit_block() != NULL);
4991 // We need an extra block to maintain edge-split form. 5010 // We need an extra block to maintain edge-split form.
4992 HBasicBlock* empty_block = graph()->CreateBasicBlock(); 5011 HBasicBlock* empty_block = graph()->CreateBasicBlock();
4993 HBasicBlock* join_block = graph()->CreateBasicBlock(); 5012 HBasicBlock* join_block = graph()->CreateBasicBlock();
4994 5013
4995 HTest* test = is_logical_and 5014 HTest* test = is_logical_and
4996 ? new HTest(left, right_subgraph->entry_block(), empty_block) 5015 ? new HTest(left, right_subgraph->entry_block(), empty_block)
4997 : new HTest(left, empty_block, right_subgraph->entry_block()); 5016 : new HTest(left, empty_block, right_subgraph->entry_block());
4998 subgraph()->exit_block()->Finish(test); 5017 current_block()->Finish(test);
4999 empty_block->Goto(join_block); 5018 empty_block->Goto(join_block);
5000 right_subgraph->exit_block()->Goto(join_block); 5019 right_subgraph->exit_block()->Goto(join_block);
5001 join_block->SetJoinId(expr->id()); 5020 join_block->SetJoinId(expr->id());
5002 subgraph()->set_exit_block(join_block); 5021 set_current_block(join_block);
5003 ast_context()->ReturnValue(Pop()); 5022 ast_context()->ReturnValue(Pop());
5004 } else { 5023 } else {
5005 ASSERT(ast_context()->IsEffect()); 5024 ASSERT(ast_context()->IsEffect());
5006 // In an effect context, we don't need the value of the left 5025 // In an effect context, we don't need the value of the left
5007 // subexpression, only its control flow and side effects. We need an 5026 // subexpression, only its control flow and side effects. We need an
5008 // extra block to maintain edge-split form. 5027 // extra block to maintain edge-split form.
5009 HBasicBlock* empty_block = graph()->CreateBasicBlock(); 5028 HBasicBlock* empty_block = graph()->CreateBasicBlock();
5010 HBasicBlock* right_block = graph()->CreateBasicBlock(); 5029 HBasicBlock* right_block = graph()->CreateBasicBlock();
5011 HBasicBlock* join_block = graph()->CreateBasicBlock(); 5030 HBasicBlock* join_block = graph()->CreateBasicBlock();
5012 if (is_logical_and) { 5031 if (is_logical_and) {
5013 VISIT_FOR_CONTROL(expr->left(), right_block, empty_block); 5032 VISIT_FOR_CONTROL(expr->left(), right_block, empty_block);
5014 } else { 5033 } else {
5015 VISIT_FOR_CONTROL(expr->left(), empty_block, right_block); 5034 VISIT_FOR_CONTROL(expr->left(), empty_block, right_block);
5016 } 5035 }
5017 // TODO(kmillikin): Find a way to fix this. It's ugly that there are 5036 // TODO(kmillikin): Find a way to fix this. It's ugly that there are
5018 // actually two empty blocks (one here and one inserted by 5037 // actually two empty blocks (one here and one inserted by
5019 // TestContext::BuildBranch, and that they both have an HSimulate 5038 // TestContext::BuildBranch, and that they both have an HSimulate
5020 // though the second one is not a merge node, and that we really have 5039 // though the second one is not a merge node, and that we really have
5021 // no good AST ID to put on that first HSimulate. 5040 // no good AST ID to put on that first HSimulate.
5022 empty_block->SetJoinId(expr->id()); 5041 empty_block->SetJoinId(expr->id());
5023 right_block->SetJoinId(expr->RightId()); 5042 right_block->SetJoinId(expr->RightId());
5024 subgraph()->set_exit_block(right_block); 5043 set_current_block(right_block);
5025 VISIT_FOR_EFFECT(expr->right()); 5044 VISIT_FOR_EFFECT(expr->right());
5026 5045
5027 empty_block->Goto(join_block); 5046 empty_block->Goto(join_block);
5028 subgraph()->exit_block()->Goto(join_block); 5047 current_block()->Goto(join_block);
5029 join_block->SetJoinId(expr->id()); 5048 join_block->SetJoinId(expr->id());
5030 subgraph()->set_exit_block(join_block); 5049 set_current_block(join_block);
5031 // We did not materialize any value in the predecessor environments, 5050 // We did not materialize any value in the predecessor environments,
5032 // so there is no need to handle it here. 5051 // so there is no need to handle it here.
5033 } 5052 }
5034 5053
5035 } else { 5054 } else {
5036 VISIT_FOR_VALUE(expr->left()); 5055 VISIT_FOR_VALUE(expr->left());
5037 VISIT_FOR_VALUE(expr->right()); 5056 VISIT_FOR_VALUE(expr->right());
5038 5057
5039 HValue* right = Pop(); 5058 HValue* right = Pop();
5040 HValue* left = Pop(); 5059 HValue* left = Pop();
(...skipping 1030 matching lines...) Expand 10 before | Expand all | Expand 10 after
6071 } 6090 }
6072 } 6091 }
6073 6092
6074 #ifdef DEBUG 6093 #ifdef DEBUG
6075 if (graph_ != NULL) graph_->Verify(); 6094 if (graph_ != NULL) graph_->Verify();
6076 if (allocator_ != NULL) allocator_->Verify(); 6095 if (allocator_ != NULL) allocator_->Verify();
6077 #endif 6096 #endif
6078 } 6097 }
6079 6098
6080 } } // namespace v8::internal 6099 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698