Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 475 HConstant* HGraph::GetConstantTrue() { | 475 HConstant* HGraph::GetConstantTrue() { |
| 476 return GetConstant(&constant_true_, Heap::true_value()); | 476 return GetConstant(&constant_true_, Heap::true_value()); |
| 477 } | 477 } |
| 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(HBasicBlock* first, | 485 HBasicBlock* HGraphBuilder::CreateJoin(HBasicBlock* first, |
| 486 HBasicBlock* second, | 486 HBasicBlock* second, |
| 487 int join_id) { | 487 int join_id) { |
| 488 if (first == NULL) { | 488 if (first == NULL) { |
| 489 exit_block_ = second; | 489 return second; |
| 490 } else if (second == NULL) { | 490 } else if (second == NULL) { |
| 491 exit_block_ = first; | 491 return first; |
| 492 } else { | 492 } else { |
| 493 HBasicBlock* join_block = graph_->CreateBasicBlock(); | 493 HBasicBlock* join_block = graph_->CreateBasicBlock(); |
| 494 first->Goto(join_block); | 494 first->Goto(join_block); |
| 495 second->Goto(join_block); | 495 second->Goto(join_block); |
| 496 join_block->SetJoinId(join_id); | 496 join_block->SetJoinId(join_id); |
| 497 exit_block_ = join_block; | 497 return join_block; |
| 498 } | 498 } |
| 499 } | 499 } |
| 500 | 500 |
| 501 | 501 |
| 502 void HSubgraph::ResolveContinue(IterationStatement* statement, | 502 HBasicBlock* HGraphBuilder::JoinContinue(IterationStatement* statement, |
| 503 HBasicBlock* continue_block) { | 503 HBasicBlock* exit_block, |
| 504 HBasicBlock* continue_block) { | |
| 504 if (continue_block != NULL) { | 505 if (continue_block != NULL) { |
| 505 continue_block->SetJoinId(statement->ContinueId()); | 506 continue_block->SetJoinId(statement->ContinueId()); |
| 506 } | 507 } |
| 507 exit_block_ = | 508 return CreateJoin(exit_block, continue_block, statement->ContinueId()); |
| 508 JoinBlocks(exit_block(), continue_block, statement->ContinueId()); | |
| 509 } | 509 } |
| 510 | 510 |
| 511 | 511 |
| 512 HBasicBlock* HSubgraph::JoinBlocks(HBasicBlock* a, HBasicBlock* b, int id) { | 512 HBasicBlock* HGraphBuilder::CreateEndless(IterationStatement* statement, |
| 513 if (a == NULL) return b; | 513 HBasicBlock* body_entry, |
| 514 if (b == NULL) return a; | 514 HBasicBlock* body_exit, |
| 515 HBasicBlock* target = graph_->CreateBasicBlock(); | 515 HBasicBlock* break_block) { |
| 516 a->Goto(target); | 516 if (body_exit != NULL) body_exit->Goto(body_entry, true); |
| 517 b->Goto(target); | 517 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); |
| 518 target->SetJoinId(id); | 518 body_entry->PostProcessLoopHeader(statement); |
| 519 return target; | 519 return break_block; |
| 520 } | 520 } |
| 521 | 521 |
| 522 | 522 |
| 523 void HSubgraph::AppendEndless(IterationStatement* statement, | 523 HBasicBlock* HGraphBuilder::CreateDoWhile(IterationStatement* statement, |
| 524 HBasicBlock* body_entry, | 524 HBasicBlock* body_entry, |
| 525 HBasicBlock* body_exit, | 525 HBasicBlock* go_back, |
| 526 HBasicBlock* break_block) { | 526 HBasicBlock* exit_block, |
| 527 if (exit_block() != NULL) { | 527 HBasicBlock* break_block) { |
| 528 exit_block()->Goto(body_entry, false); | 528 if (go_back != NULL) go_back->Goto(body_entry, true); |
| 529 } | |
| 530 if (body_exit != NULL) { | |
| 531 body_exit->Goto(body_entry, true); | |
| 532 } | |
| 533 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); | 529 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); |
| 534 exit_block_ = break_block; | 530 HBasicBlock* new_exit = |
| 531 CreateJoin(exit_block, break_block, statement->ExitId()); | |
| 535 body_entry->PostProcessLoopHeader(statement); | 532 body_entry->PostProcessLoopHeader(statement); |
| 533 return new_exit; | |
| 536 } | 534 } |
| 537 | 535 |
| 538 | 536 |
| 539 void HSubgraph::AppendDoWhile(IterationStatement* statement, | 537 HBasicBlock* HGraphBuilder::CreateWhile(IterationStatement* statement, |
| 540 HBasicBlock* body_entry, | 538 HBasicBlock* condition_entry, |
| 541 HBasicBlock* go_back, | 539 HBasicBlock* exit_block, |
| 542 HBasicBlock* exit_block, | 540 HBasicBlock* body_exit, |
| 543 HBasicBlock* break_block) { | 541 HBasicBlock* break_block, |
| 544 if (this->exit_block() != NULL) { | 542 HBasicBlock* loop_entry, |
| 545 this->exit_block()->Goto(body_entry, false); | 543 HBasicBlock* loop_exit) { |
| 544 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); | |
| 545 HBasicBlock* new_exit = | |
| 546 CreateJoin(exit_block, break_block, statement->ExitId()); | |
| 547 | |
| 548 if (loop_entry != NULL) { | |
| 549 if (body_exit != NULL) body_exit->Goto(loop_entry, true); | |
| 550 loop_entry->SetJoinId(statement->EntryId()); | |
| 551 new_exit = CreateJoin(new_exit, loop_exit, statement->ExitId()); | |
| 552 } else { | |
|
fschneider
2011/02/24 13:09:44
here you could write
} else if (...) {
}
Kevin Millikin (Chromium)
2011/02/28 08:53:29
Good catch. I'll hold off for now because the "if
| |
| 553 if (body_exit != NULL) body_exit->Goto(condition_entry, true); | |
| 546 } | 554 } |
| 547 if (go_back != NULL) { | 555 condition_entry->PostProcessLoopHeader(statement); |
| 548 go_back->Goto(body_entry, true); | 556 return new_exit; |
| 549 } | |
| 550 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); | |
| 551 exit_block_ = | |
| 552 JoinBlocks(exit_block, break_block, statement->ExitId()); | |
| 553 body_entry->PostProcessLoopHeader(statement); | |
| 554 } | 557 } |
| 555 | 558 |
| 556 | 559 |
| 557 void HSubgraph::AppendWhile(IterationStatement* statement, | 560 void HBasicBlock::FinishExit(HControlInstruction* instruction) { |
| 558 HBasicBlock* condition_entry, | 561 Finish(instruction); |
| 559 HBasicBlock* exit_block, | 562 ClearEnvironment(); |
| 560 HBasicBlock* body_exit, | |
| 561 HBasicBlock* break_block, | |
| 562 HBasicBlock* loop_entry, | |
| 563 HBasicBlock* loop_exit) { | |
| 564 if (this->exit_block() != NULL) { | |
| 565 this->exit_block()->Goto(condition_entry, false); | |
| 566 } | |
| 567 | |
| 568 if (break_block != NULL) break_block->SetJoinId(statement->ExitId()); | |
| 569 exit_block_ = | |
| 570 JoinBlocks(exit_block, break_block, statement->ExitId()); | |
| 571 | |
| 572 if (loop_entry != NULL) { | |
| 573 if (body_exit != NULL) { | |
| 574 body_exit->Goto(loop_entry, true); | |
| 575 } | |
| 576 loop_entry->SetJoinId(statement->EntryId()); | |
| 577 exit_block_ = JoinBlocks(exit_block_, loop_exit, statement->ExitId()); | |
| 578 } else { | |
| 579 if (body_exit != NULL) { | |
| 580 body_exit->Goto(condition_entry, true); | |
| 581 } | |
| 582 } | |
| 583 condition_entry->PostProcessLoopHeader(statement); | |
| 584 } | 563 } |
| 585 | 564 |
| 586 | 565 |
| 587 void HSubgraph::Append(BreakableStatement* stmt, | |
| 588 HBasicBlock* entry_block, | |
| 589 HBasicBlock* exit_block, | |
| 590 HBasicBlock* break_block) { | |
| 591 exit_block_->Goto(entry_block); | |
| 592 exit_block_ = exit_block; | |
| 593 | |
| 594 if (stmt != NULL) { | |
| 595 entry_block->SetJoinId(stmt->EntryId()); | |
| 596 if (break_block != NULL) break_block->SetJoinId(stmt->EntryId()); | |
| 597 exit_block_ = JoinBlocks(exit_block, break_block, stmt->ExitId()); | |
| 598 } | |
| 599 } | |
| 600 | |
| 601 | |
| 602 void HSubgraph::FinishExit(HControlInstruction* instruction) { | |
| 603 ASSERT(exit_block() != NULL); | |
| 604 exit_block_->Finish(instruction); | |
| 605 exit_block_->ClearEnvironment(); | |
| 606 exit_block_ = NULL; | |
| 607 } | |
| 608 | |
| 609 | |
| 610 HGraph::HGraph(CompilationInfo* info) | 566 HGraph::HGraph(CompilationInfo* info) |
| 611 : HSubgraph(this), | 567 : HSubgraph(this), |
| 612 next_block_id_(0), | 568 next_block_id_(0), |
| 613 info_(info), | 569 info_(info), |
| 614 blocks_(8), | 570 blocks_(8), |
| 615 values_(16), | 571 values_(16), |
| 616 phi_list_(NULL) { | 572 phi_list_(NULL) { |
| 617 start_environment_ = new HEnvironment(NULL, info->scope(), info->closure()); | 573 start_environment_ = new HEnvironment(NULL, info->scope(), info->closure()); |
| 618 start_environment_->set_ast_id(info->function()->id()); | 574 start_environment_->set_ast_id(info->function()->id()); |
| 619 } | 575 } |
| (...skipping 1538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2158 current_subgraph_ = graph_; | 2114 current_subgraph_ = graph_; |
| 2159 | 2115 |
| 2160 Scope* scope = info->scope(); | 2116 Scope* scope = info->scope(); |
| 2161 SetupScope(scope); | 2117 SetupScope(scope); |
| 2162 VisitDeclarations(scope->declarations()); | 2118 VisitDeclarations(scope->declarations()); |
| 2163 | 2119 |
| 2164 AddInstruction(new HStackCheck()); | 2120 AddInstruction(new HStackCheck()); |
| 2165 | 2121 |
| 2166 ZoneList<Statement*>* stmts = info->function()->body(); | 2122 ZoneList<Statement*>* stmts = info->function()->body(); |
| 2167 HSubgraph* body = CreateGotoSubgraph(environment()); | 2123 HSubgraph* body = CreateGotoSubgraph(environment()); |
| 2124 current_block()->Goto(body->entry_block()); | |
| 2168 AddToSubgraph(body, stmts); | 2125 AddToSubgraph(body, stmts); |
| 2169 if (HasStackOverflow()) return NULL; | 2126 if (HasStackOverflow()) return NULL; |
| 2170 current_subgraph_->Append(NULL, | |
| 2171 body->entry_block(), | |
| 2172 body->exit_block(), | |
| 2173 NULL); | |
| 2174 body->entry_block()->SetJoinId(info->function()->id()); | 2127 body->entry_block()->SetJoinId(info->function()->id()); |
| 2128 set_current_block(body->exit_block()); | |
| 2175 | 2129 |
| 2176 if (graph()->exit_block() != NULL) { | 2130 if (graph()->exit_block() != NULL) { |
| 2177 graph_->FinishExit(new HReturn(graph_->GetConstantUndefined())); | 2131 HReturn* instr = new HReturn(graph()->GetConstantUndefined()); |
| 2132 graph()->exit_block()->FinishExit(instr); | |
| 2133 graph()->set_exit_block(NULL); | |
| 2178 } | 2134 } |
| 2179 } | 2135 } |
| 2180 | 2136 |
| 2181 graph_->OrderBlocks(); | 2137 graph_->OrderBlocks(); |
| 2182 graph_->AssignDominators(); | 2138 graph_->AssignDominators(); |
| 2183 graph_->EliminateRedundantPhis(); | 2139 graph_->EliminateRedundantPhis(); |
| 2184 if (!graph_->CollectPhis()) { | 2140 if (!graph_->CollectPhis()) { |
| 2185 Bailout("Phi-use of arguments object"); | 2141 Bailout("Phi-use of arguments object"); |
| 2186 return NULL; | 2142 return NULL; |
| 2187 } | 2143 } |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2368 block->SetInitialEnvironment(new_env); | 2324 block->SetInitialEnvironment(new_env); |
| 2369 subgraph->Initialize(block); | 2325 subgraph->Initialize(block); |
| 2370 subgraph->entry_block()->AttachLoopInformation(); | 2326 subgraph->entry_block()->AttachLoopInformation(); |
| 2371 return subgraph; | 2327 return subgraph; |
| 2372 } | 2328 } |
| 2373 | 2329 |
| 2374 | 2330 |
| 2375 void HGraphBuilder::VisitBlock(Block* stmt) { | 2331 void HGraphBuilder::VisitBlock(Block* stmt) { |
| 2376 if (stmt->labels() != NULL) { | 2332 if (stmt->labels() != NULL) { |
| 2377 HSubgraph* block_graph = CreateGotoSubgraph(environment()); | 2333 HSubgraph* block_graph = CreateGotoSubgraph(environment()); |
| 2334 current_block()->Goto(block_graph->entry_block()); | |
| 2335 block_graph->entry_block()->SetJoinId(stmt->EntryId()); | |
| 2378 BreakAndContinueInfo break_info(stmt); | 2336 BreakAndContinueInfo break_info(stmt); |
| 2379 { BreakAndContinueScope push(&break_info, this); | 2337 { BreakAndContinueScope push(&break_info, this); |
| 2380 ADD_TO_SUBGRAPH(block_graph, stmt->statements()); | 2338 ADD_TO_SUBGRAPH(block_graph, stmt->statements()); |
| 2381 } | 2339 } |
| 2382 subgraph()->Append(stmt, | 2340 HBasicBlock* break_block = break_info.break_block(); |
| 2383 block_graph->entry_block(), | 2341 if (break_block != NULL) break_block->SetJoinId(stmt->EntryId()); |
| 2384 block_graph->exit_block(), | 2342 set_current_block(CreateJoin(block_graph->exit_block(), |
| 2385 break_info.break_block()); | 2343 break_block, |
| 2344 stmt->ExitId())); | |
| 2386 } else { | 2345 } else { |
| 2387 VisitStatements(stmt->statements()); | 2346 VisitStatements(stmt->statements()); |
| 2388 } | 2347 } |
| 2389 } | 2348 } |
| 2390 | 2349 |
| 2391 | 2350 |
| 2392 void HGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { | 2351 void HGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) { |
| 2393 VisitForEffect(stmt->expression()); | 2352 VisitForEffect(stmt->expression()); |
| 2394 } | 2353 } |
| 2395 | 2354 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2411 VISIT_FOR_CONTROL(stmt->condition(), | 2370 VISIT_FOR_CONTROL(stmt->condition(), |
| 2412 then_graph->entry_block(), | 2371 then_graph->entry_block(), |
| 2413 else_graph->entry_block()); | 2372 else_graph->entry_block()); |
| 2414 | 2373 |
| 2415 then_graph->entry_block()->SetJoinId(stmt->ThenId()); | 2374 then_graph->entry_block()->SetJoinId(stmt->ThenId()); |
| 2416 ADD_TO_SUBGRAPH(then_graph, stmt->then_statement()); | 2375 ADD_TO_SUBGRAPH(then_graph, stmt->then_statement()); |
| 2417 | 2376 |
| 2418 else_graph->entry_block()->SetJoinId(stmt->ElseId()); | 2377 else_graph->entry_block()->SetJoinId(stmt->ElseId()); |
| 2419 ADD_TO_SUBGRAPH(else_graph, stmt->else_statement()); | 2378 ADD_TO_SUBGRAPH(else_graph, stmt->else_statement()); |
| 2420 | 2379 |
| 2421 current_subgraph_->AppendJoin(then_graph->exit_block(), | 2380 set_current_block(CreateJoin(then_graph->exit_block(), |
| 2422 else_graph->exit_block(), | 2381 else_graph->exit_block(), |
| 2423 stmt->id()); | 2382 stmt->id())); |
| 2424 } | 2383 } |
| 2425 } | 2384 } |
| 2426 | 2385 |
| 2427 | 2386 |
| 2428 HBasicBlock* HGraphBuilder::BreakAndContinueScope::Get( | 2387 HBasicBlock* HGraphBuilder::BreakAndContinueScope::Get( |
| 2429 BreakableStatement* stmt, | 2388 BreakableStatement* stmt, |
| 2430 BreakType type) { | 2389 BreakType type) { |
| 2431 BreakAndContinueScope* current = this; | 2390 BreakAndContinueScope* current = this; |
| 2432 while (current != NULL && current->info()->target() != stmt) { | 2391 while (current != NULL && current->info()->target() != stmt) { |
| 2433 current = current->next(); | 2392 current = current->next(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2469 set_current_block(NULL); | 2428 set_current_block(NULL); |
| 2470 } | 2429 } |
| 2471 | 2430 |
| 2472 | 2431 |
| 2473 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { | 2432 void HGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { |
| 2474 AstContext* context = call_context(); | 2433 AstContext* context = call_context(); |
| 2475 if (context == NULL) { | 2434 if (context == NULL) { |
| 2476 // Not an inlined return, so an actual one. | 2435 // Not an inlined return, so an actual one. |
| 2477 VISIT_FOR_VALUE(stmt->expression()); | 2436 VISIT_FOR_VALUE(stmt->expression()); |
| 2478 HValue* result = environment()->Pop(); | 2437 HValue* result = environment()->Pop(); |
| 2479 subgraph()->FinishExit(new HReturn(result)); | 2438 current_block()->FinishExit(new HReturn(result)); |
| 2439 set_current_block(NULL); | |
| 2480 } else { | 2440 } else { |
| 2481 // Return from an inlined function, visit the subexpression in the | 2441 // Return from an inlined function, visit the subexpression in the |
| 2482 // expression context of the call. | 2442 // expression context of the call. |
| 2483 if (context->IsTest()) { | 2443 if (context->IsTest()) { |
| 2484 TestContext* test = TestContext::cast(context); | 2444 TestContext* test = TestContext::cast(context); |
| 2485 VisitForControl(stmt->expression(), | 2445 VisitForControl(stmt->expression(), |
| 2486 test->if_true(), | 2446 test->if_true(), |
| 2487 test->if_false()); | 2447 test->if_false()); |
| 2488 } else { | 2448 } else { |
| 2489 HValue* return_value = NULL; | 2449 HValue* return_value = NULL; |
| 2490 if (context->IsEffect()) { | 2450 if (context->IsEffect()) { |
| 2491 VISIT_FOR_EFFECT(stmt->expression()); | 2451 VISIT_FOR_EFFECT(stmt->expression()); |
| 2492 return_value = graph()->GetConstantUndefined(); | 2452 return_value = graph()->GetConstantUndefined(); |
| 2493 } else { | 2453 } else { |
| 2494 ASSERT(context->IsValue()); | 2454 ASSERT(context->IsValue()); |
| 2495 VISIT_FOR_VALUE(stmt->expression()); | 2455 VISIT_FOR_VALUE(stmt->expression()); |
| 2496 return_value = environment()->Pop(); | 2456 return_value = environment()->Pop(); |
| 2497 } | 2457 } |
| 2498 current_block()->AddLeaveInlined(return_value, | 2458 current_block()->AddLeaveInlined(return_value, |
| 2499 function_return_); | 2459 function_return_); |
| 2500 set_current_block(NULL); | 2460 set_current_block(NULL); |
| 2501 } | 2461 } |
| 2502 } | 2462 } |
| 2503 } | 2463 } |
| 2504 | 2464 |
| 2505 | 2465 |
| 2506 void HGraphBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) { | 2466 void HGraphBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) { |
| 2507 BAILOUT("WithEnterStatement"); | 2467 BAILOUT("WithEnterStatement"); |
| 2508 } | 2468 } |
| 2509 | 2469 |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2678 } else { | 2638 } else { |
| 2679 set_current_block(NULL); | 2639 set_current_block(NULL); |
| 2680 } | 2640 } |
| 2681 } | 2641 } |
| 2682 | 2642 |
| 2683 bool HGraph::HasOsrEntryAt(IterationStatement* statement) { | 2643 bool HGraph::HasOsrEntryAt(IterationStatement* statement) { |
| 2684 return statement->OsrEntryId() == info()->osr_ast_id(); | 2644 return statement->OsrEntryId() == info()->osr_ast_id(); |
| 2685 } | 2645 } |
| 2686 | 2646 |
| 2687 | 2647 |
| 2688 void HSubgraph::PreProcessOsrEntry(IterationStatement* statement) { | 2648 void HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) { |
| 2689 if (!graph()->HasOsrEntryAt(statement)) return; | 2649 if (!graph()->HasOsrEntryAt(statement)) return; |
| 2690 | 2650 |
| 2691 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); | 2651 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); |
| 2692 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); | 2652 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); |
| 2693 HValue* true_value = graph()->GetConstantTrue(); | 2653 HValue* true_value = graph()->GetConstantTrue(); |
| 2694 HTest* test = new HTest(true_value, non_osr_entry, osr_entry); | 2654 HTest* test = new HTest(true_value, non_osr_entry, osr_entry); |
| 2695 exit_block()->Finish(test); | 2655 current_block()->Finish(test); |
| 2696 | 2656 |
| 2697 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 2657 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
| 2698 non_osr_entry->Goto(loop_predecessor); | 2658 non_osr_entry->Goto(loop_predecessor); |
| 2699 | 2659 |
| 2660 set_current_block(osr_entry); | |
| 2700 int osr_entry_id = statement->OsrEntryId(); | 2661 int osr_entry_id = statement->OsrEntryId(); |
| 2701 // We want the correct environment at the OsrEntry instruction. Build | 2662 // We want the correct environment at the OsrEntry instruction. Build |
| 2702 // it explicitly. The expression stack should be empty. | 2663 // it explicitly. The expression stack should be empty. |
| 2703 int count = osr_entry->last_environment()->length(); | 2664 int count = environment()->length(); |
| 2704 ASSERT(count == (osr_entry->last_environment()->parameter_count() + | 2665 ASSERT(count == |
| 2705 osr_entry->last_environment()->local_count())); | 2666 (environment()->parameter_count() + environment()->local_count())); |
| 2706 for (int i = 0; i < count; ++i) { | 2667 for (int i = 0; i < count; ++i) { |
| 2707 HUnknownOSRValue* unknown = new HUnknownOSRValue; | 2668 HUnknownOSRValue* unknown = new HUnknownOSRValue; |
| 2708 osr_entry->AddInstruction(unknown); | 2669 AddInstruction(unknown); |
| 2709 osr_entry->last_environment()->Bind(i, unknown); | 2670 environment()->Bind(i, unknown); |
| 2710 } | 2671 } |
| 2711 | 2672 |
| 2712 osr_entry->AddSimulate(osr_entry_id); | 2673 AddSimulate(osr_entry_id); |
| 2713 osr_entry->AddInstruction(new HOsrEntry(osr_entry_id)); | 2674 AddInstruction(new HOsrEntry(osr_entry_id)); |
| 2714 osr_entry->Goto(loop_predecessor); | 2675 current_block()->Goto(loop_predecessor); |
| 2715 loop_predecessor->SetJoinId(statement->EntryId()); | 2676 loop_predecessor->SetJoinId(statement->EntryId()); |
| 2716 set_exit_block(loop_predecessor); | 2677 set_current_block(loop_predecessor); |
| 2717 } | 2678 } |
| 2718 | 2679 |
| 2719 | 2680 |
| 2720 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 2681 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 2721 ASSERT(current_block() != NULL); | 2682 ASSERT(current_block() != NULL); |
| 2722 subgraph()->PreProcessOsrEntry(stmt); | 2683 PreProcessOsrEntry(stmt); |
| 2723 | 2684 |
| 2724 HSubgraph* body_graph = CreateLoopHeaderSubgraph(environment()); | 2685 HSubgraph* body_graph = CreateLoopHeaderSubgraph(environment()); |
| 2686 current_block()->Goto(body_graph->entry_block(), false); | |
| 2725 BreakAndContinueInfo break_info(stmt); | 2687 BreakAndContinueInfo break_info(stmt); |
| 2726 { BreakAndContinueScope push(&break_info, this); | 2688 { BreakAndContinueScope push(&break_info, this); |
| 2727 ADD_TO_SUBGRAPH(body_graph, stmt->body()); | 2689 ADD_TO_SUBGRAPH(body_graph, stmt->body()); |
| 2728 } | 2690 } |
| 2729 body_graph->ResolveContinue(stmt, break_info.continue_block()); | 2691 HBasicBlock* body_exit = JoinContinue(stmt, |
| 2692 body_graph->exit_block(), | |
| 2693 break_info.continue_block()); | |
| 2694 body_graph->set_exit_block(body_exit); | |
| 2730 | 2695 |
| 2731 if (body_graph->exit_block() == NULL || stmt->cond()->ToBooleanIsTrue()) { | 2696 if (body_graph->exit_block() == NULL || stmt->cond()->ToBooleanIsTrue()) { |
| 2732 subgraph()->AppendEndless(stmt, | 2697 set_current_block(CreateEndless(stmt, |
| 2733 body_graph->entry_block(), | 2698 body_graph->entry_block(), |
| 2734 body_graph->exit_block(), | 2699 body_graph->exit_block(), |
| 2735 break_info.break_block()); | 2700 break_info.break_block())); |
| 2736 } else { | 2701 } else { |
| 2737 HSubgraph* go_back = CreateEmptySubgraph(); | 2702 HSubgraph* go_back = CreateEmptySubgraph(); |
| 2738 HSubgraph* exit = CreateEmptySubgraph(); | 2703 HSubgraph* exit = CreateEmptySubgraph(); |
| 2739 { | 2704 { |
| 2740 SubgraphScope scope(this, body_graph); | 2705 SubgraphScope scope(this, body_graph); |
| 2741 VISIT_FOR_CONTROL(stmt->cond(), | 2706 VISIT_FOR_CONTROL(stmt->cond(), |
| 2742 go_back->entry_block(), | 2707 go_back->entry_block(), |
| 2743 exit->entry_block()); | 2708 exit->entry_block()); |
| 2744 go_back->entry_block()->SetJoinId(stmt->BackEdgeId()); | 2709 go_back->entry_block()->SetJoinId(stmt->BackEdgeId()); |
| 2745 exit->entry_block()->SetJoinId(stmt->ExitId()); | 2710 exit->entry_block()->SetJoinId(stmt->ExitId()); |
| 2746 } | 2711 } |
| 2747 subgraph()->AppendDoWhile(stmt, | 2712 set_current_block(CreateDoWhile(stmt, |
| 2748 body_graph->entry_block(), | 2713 body_graph->entry_block(), |
| 2749 go_back->exit_block(), | 2714 go_back->exit_block(), |
| 2750 exit->exit_block(), | 2715 exit->exit_block(), |
| 2751 break_info.break_block()); | 2716 break_info.break_block())); |
| 2752 } | 2717 } |
| 2753 } | 2718 } |
| 2754 | 2719 |
| 2755 | 2720 |
| 2756 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { | 2721 void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { |
| 2757 ASSERT(current_block() != NULL); | 2722 ASSERT(current_block() != NULL); |
| 2758 subgraph()->PreProcessOsrEntry(stmt); | 2723 PreProcessOsrEntry(stmt); |
| 2759 | 2724 |
| 2760 HSubgraph* cond_graph = NULL; | 2725 HSubgraph* cond_graph = NULL; |
| 2761 HSubgraph* body_graph = NULL; | 2726 HSubgraph* body_graph = NULL; |
| 2762 HSubgraph* exit_graph = NULL; | 2727 HSubgraph* exit_graph = NULL; |
| 2763 | 2728 |
| 2764 // If the condition is constant true, do not generate a condition subgraph. | 2729 // If the condition is constant true, do not generate a condition subgraph. |
| 2765 if (stmt->cond()->ToBooleanIsTrue()) { | 2730 if (stmt->cond()->ToBooleanIsTrue()) { |
| 2766 body_graph = CreateLoopHeaderSubgraph(environment()); | 2731 body_graph = CreateLoopHeaderSubgraph(environment()); |
| 2732 current_block()->Goto(body_graph->entry_block(), false); | |
| 2767 } else { | 2733 } else { |
| 2768 cond_graph = CreateLoopHeaderSubgraph(environment()); | 2734 cond_graph = CreateLoopHeaderSubgraph(environment()); |
| 2735 current_block()->Goto(cond_graph->entry_block(), false); | |
| 2769 body_graph = CreateEmptySubgraph(); | 2736 body_graph = CreateEmptySubgraph(); |
| 2770 exit_graph = CreateEmptySubgraph(); | 2737 exit_graph = CreateEmptySubgraph(); |
| 2771 { | 2738 { |
| 2772 SubgraphScope scope(this, cond_graph); | 2739 SubgraphScope scope(this, cond_graph); |
| 2773 VISIT_FOR_CONTROL(stmt->cond(), | 2740 VISIT_FOR_CONTROL(stmt->cond(), |
| 2774 body_graph->entry_block(), | 2741 body_graph->entry_block(), |
| 2775 exit_graph->entry_block()); | 2742 exit_graph->entry_block()); |
| 2776 body_graph->entry_block()->SetJoinId(stmt->BodyId()); | 2743 body_graph->entry_block()->SetJoinId(stmt->BodyId()); |
| 2777 exit_graph->entry_block()->SetJoinId(stmt->ExitId()); | 2744 exit_graph->entry_block()->SetJoinId(stmt->ExitId()); |
| 2778 } | 2745 } |
| 2779 } | 2746 } |
| 2780 | 2747 |
| 2781 BreakAndContinueInfo break_info(stmt); | 2748 BreakAndContinueInfo break_info(stmt); |
| 2782 { BreakAndContinueScope push(&break_info, this); | 2749 { BreakAndContinueScope push(&break_info, this); |
| 2783 ADD_TO_SUBGRAPH(body_graph, stmt->body()); | 2750 ADD_TO_SUBGRAPH(body_graph, stmt->body()); |
| 2784 } | 2751 } |
| 2785 body_graph->ResolveContinue(stmt, break_info.continue_block()); | 2752 HBasicBlock* body_exit = JoinContinue(stmt, |
| 2753 body_graph->exit_block(), | |
| 2754 break_info.continue_block()); | |
| 2755 body_graph->set_exit_block(body_exit); | |
| 2786 | 2756 |
| 2787 if (cond_graph != NULL) { | 2757 if (cond_graph != NULL) { |
| 2788 AppendPeeledWhile(stmt, | 2758 set_current_block(CreatePeeledWhile(stmt, |
| 2789 cond_graph->entry_block(), | 2759 cond_graph->entry_block(), |
| 2790 exit_graph->exit_block(), | 2760 exit_graph->exit_block(), |
| 2791 body_graph->exit_block(), | 2761 body_graph->exit_block(), |
| 2792 break_info.break_block()); | 2762 break_info.break_block())); |
| 2793 } else { | 2763 } else { |
| 2794 // TODO(fschneider): Implement peeling for endless loops as well. | 2764 // TODO(fschneider): Implement peeling for endless loops as well. |
| 2795 subgraph()->AppendEndless(stmt, | 2765 set_current_block(CreateEndless(stmt, |
| 2796 body_graph->entry_block(), | 2766 body_graph->entry_block(), |
| 2797 body_graph->exit_block(), | 2767 body_graph->exit_block(), |
| 2798 break_info.break_block()); | 2768 break_info.break_block())); |
| 2799 } | 2769 } |
| 2800 } | 2770 } |
| 2801 | 2771 |
| 2802 | 2772 |
| 2803 void HGraphBuilder::AppendPeeledWhile(IterationStatement* stmt, | 2773 HBasicBlock* HGraphBuilder::CreatePeeledWhile(IterationStatement* stmt, |
| 2804 HBasicBlock* condition_entry, | 2774 HBasicBlock* condition_entry, |
| 2805 HBasicBlock* exit_block, | 2775 HBasicBlock* exit_block, |
| 2806 HBasicBlock* body_exit, | 2776 HBasicBlock* body_exit, |
| 2807 HBasicBlock* break_block) { | 2777 HBasicBlock* break_block) { |
| 2808 HBasicBlock* loop_entry = NULL; | 2778 HBasicBlock* loop_entry = NULL; |
| 2809 HBasicBlock* loop_exit = NULL; | 2779 HBasicBlock* loop_exit = NULL; |
| 2810 if (FLAG_use_peeling && body_exit != NULL && stmt != peeled_statement_) { | 2780 if (FLAG_use_peeling && body_exit != NULL && stmt != peeled_statement_) { |
| 2811 // Save the last peeled iteration statement to prevent infinite recursion. | 2781 // Save the last peeled iteration statement to prevent infinite recursion. |
| 2812 IterationStatement* outer_peeled_statement = peeled_statement_; | 2782 IterationStatement* outer_peeled_statement = peeled_statement_; |
| 2813 peeled_statement_ = stmt; | 2783 peeled_statement_ = stmt; |
| 2814 HSubgraph* loop = CreateGotoSubgraph(body_exit->last_environment()); | 2784 HSubgraph* loop = CreateGotoSubgraph(body_exit->last_environment()); |
| 2815 ADD_TO_SUBGRAPH(loop, stmt); | 2785 AddToSubgraph(loop, stmt); |
| 2816 peeled_statement_ = outer_peeled_statement; | 2786 peeled_statement_ = outer_peeled_statement; |
| 2787 if (HasStackOverflow()) return NULL; | |
| 2817 loop_entry = loop->entry_block(); | 2788 loop_entry = loop->entry_block(); |
| 2818 loop_exit = loop->exit_block(); | 2789 loop_exit = loop->exit_block(); |
| 2819 } | 2790 } |
| 2820 subgraph()->AppendWhile(stmt, | 2791 return CreateWhile(stmt, |
| 2821 condition_entry, | 2792 condition_entry, |
| 2822 exit_block, | 2793 exit_block, |
| 2823 body_exit, | 2794 body_exit, |
| 2824 break_block, | 2795 break_block, |
| 2825 loop_entry, | 2796 loop_entry, |
| 2826 loop_exit); | 2797 loop_exit); |
| 2827 } | 2798 } |
| 2828 | 2799 |
| 2829 | 2800 |
| 2830 void HGraphBuilder::VisitForStatement(ForStatement* stmt) { | 2801 void HGraphBuilder::VisitForStatement(ForStatement* stmt) { |
| 2831 // Only visit the init statement in the peeled part of the loop. | 2802 // Only visit the init statement in the peeled part of the loop. |
| 2832 if (stmt->init() != NULL && peeled_statement_ != stmt) { | 2803 if (stmt->init() != NULL && peeled_statement_ != stmt) { |
| 2833 Visit(stmt->init()); | 2804 Visit(stmt->init()); |
| 2834 CHECK_BAILOUT; | 2805 CHECK_BAILOUT; |
| 2835 } | 2806 } |
| 2836 ASSERT(current_block() != NULL); | 2807 ASSERT(current_block() != NULL); |
| 2837 subgraph()->PreProcessOsrEntry(stmt); | 2808 PreProcessOsrEntry(stmt); |
| 2838 | 2809 |
| 2839 HSubgraph* cond_graph = NULL; | 2810 HSubgraph* cond_graph = NULL; |
| 2840 HSubgraph* body_graph = NULL; | 2811 HSubgraph* body_graph = NULL; |
| 2841 HSubgraph* exit_graph = NULL; | 2812 HSubgraph* exit_graph = NULL; |
| 2842 if (stmt->cond() != NULL) { | 2813 if (stmt->cond() != NULL) { |
| 2843 cond_graph = CreateLoopHeaderSubgraph(environment()); | 2814 cond_graph = CreateLoopHeaderSubgraph(environment()); |
| 2815 current_block()->Goto(cond_graph->entry_block(), false); | |
| 2844 body_graph = CreateEmptySubgraph(); | 2816 body_graph = CreateEmptySubgraph(); |
| 2845 exit_graph = CreateEmptySubgraph(); | 2817 exit_graph = CreateEmptySubgraph(); |
| 2846 { | 2818 { |
| 2847 SubgraphScope scope(this, cond_graph); | 2819 SubgraphScope scope(this, cond_graph); |
| 2848 VISIT_FOR_CONTROL(stmt->cond(), | 2820 VISIT_FOR_CONTROL(stmt->cond(), |
| 2849 body_graph->entry_block(), | 2821 body_graph->entry_block(), |
| 2850 exit_graph->entry_block()); | 2822 exit_graph->entry_block()); |
| 2851 body_graph->entry_block()->SetJoinId(stmt->BodyId()); | 2823 body_graph->entry_block()->SetJoinId(stmt->BodyId()); |
| 2852 exit_graph->entry_block()->SetJoinId(stmt->ExitId()); | 2824 exit_graph->entry_block()->SetJoinId(stmt->ExitId()); |
| 2853 } | 2825 } |
| 2854 } else { | 2826 } else { |
| 2855 body_graph = CreateLoopHeaderSubgraph(environment()); | 2827 body_graph = CreateLoopHeaderSubgraph(environment()); |
| 2828 current_block()->Goto(body_graph->entry_block(), false); | |
| 2856 } | 2829 } |
| 2857 BreakAndContinueInfo break_info(stmt); | 2830 BreakAndContinueInfo break_info(stmt); |
| 2858 { BreakAndContinueScope push(&break_info, this); | 2831 { BreakAndContinueScope push(&break_info, this); |
| 2859 ADD_TO_SUBGRAPH(body_graph, stmt->body()); | 2832 ADD_TO_SUBGRAPH(body_graph, stmt->body()); |
| 2860 } | 2833 } |
| 2861 | 2834 |
| 2862 HSubgraph* next_graph = NULL; | 2835 HSubgraph* next_graph = NULL; |
| 2863 body_graph->ResolveContinue(stmt, break_info.continue_block()); | 2836 HBasicBlock* body_exit = JoinContinue(stmt, |
| 2837 body_graph->exit_block(), | |
| 2838 break_info.continue_block()); | |
| 2839 body_graph->set_exit_block(body_exit); | |
| 2864 | 2840 |
| 2865 if (stmt->next() != NULL && body_graph->exit_block() != NULL) { | 2841 if (stmt->next() != NULL && body_graph->exit_block() != NULL) { |
| 2866 next_graph = | 2842 next_graph = |
| 2867 CreateGotoSubgraph(body_graph->exit_block()->last_environment()); | 2843 CreateGotoSubgraph(body_graph->exit_block()->last_environment()); |
| 2844 body_graph->exit_block()->Goto(next_graph->entry_block()); | |
| 2845 next_graph->entry_block()->SetJoinId(stmt->ContinueId()); | |
| 2868 ADD_TO_SUBGRAPH(next_graph, stmt->next()); | 2846 ADD_TO_SUBGRAPH(next_graph, stmt->next()); |
| 2869 body_graph->Append(NULL, | 2847 body_graph->set_exit_block(next_graph->exit_block()); |
| 2870 next_graph->entry_block(), | |
| 2871 next_graph->exit_block(), | |
| 2872 NULL); | |
| 2873 next_graph->entry_block()->SetJoinId(stmt->ContinueId()); | |
| 2874 } | 2848 } |
| 2875 | 2849 |
| 2876 if (cond_graph != NULL) { | 2850 if (cond_graph != NULL) { |
| 2877 AppendPeeledWhile(stmt, | 2851 set_current_block(CreatePeeledWhile(stmt, |
| 2878 cond_graph->entry_block(), | 2852 cond_graph->entry_block(), |
| 2879 exit_graph->exit_block(), | 2853 exit_graph->exit_block(), |
| 2880 body_graph->exit_block(), | 2854 body_graph->exit_block(), |
| 2881 break_info.break_block()); | 2855 break_info.break_block())); |
| 2882 } else { | 2856 } else { |
| 2883 subgraph()->AppendEndless(stmt, | 2857 set_current_block(CreateEndless(stmt, |
| 2884 body_graph->entry_block(), | 2858 body_graph->entry_block(), |
| 2885 body_graph->exit_block(), | 2859 body_graph->exit_block(), |
| 2886 break_info.break_block()); | 2860 break_info.break_block())); |
| 2887 } | 2861 } |
| 2888 } | 2862 } |
| 2889 | 2863 |
| 2890 | 2864 |
| 2891 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) { | 2865 void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
| 2892 BAILOUT("ForInStatement"); | 2866 BAILOUT("ForInStatement"); |
| 2893 } | 2867 } |
| 2894 | 2868 |
| 2895 | 2869 |
| 2896 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { | 2870 void HGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2930 VISIT_FOR_CONTROL(expr->condition(), | 2904 VISIT_FOR_CONTROL(expr->condition(), |
| 2931 then_graph->entry_block(), | 2905 then_graph->entry_block(), |
| 2932 else_graph->entry_block()); | 2906 else_graph->entry_block()); |
| 2933 | 2907 |
| 2934 then_graph->entry_block()->SetJoinId(expr->ThenId()); | 2908 then_graph->entry_block()->SetJoinId(expr->ThenId()); |
| 2935 ADD_TO_SUBGRAPH(then_graph, expr->then_expression()); | 2909 ADD_TO_SUBGRAPH(then_graph, expr->then_expression()); |
| 2936 | 2910 |
| 2937 else_graph->entry_block()->SetJoinId(expr->ElseId()); | 2911 else_graph->entry_block()->SetJoinId(expr->ElseId()); |
| 2938 ADD_TO_SUBGRAPH(else_graph, expr->else_expression()); | 2912 ADD_TO_SUBGRAPH(else_graph, expr->else_expression()); |
| 2939 | 2913 |
| 2940 current_subgraph_->AppendJoin(then_graph->exit_block(), | 2914 set_current_block(CreateJoin(then_graph->exit_block(), |
| 2941 else_graph->exit_block(), | 2915 else_graph->exit_block(), |
| 2942 expr->id()); | 2916 expr->id())); |
| 2943 ast_context()->ReturnValue(Pop()); | 2917 ast_context()->ReturnValue(Pop()); |
| 2944 } | 2918 } |
| 2945 | 2919 |
| 2946 | 2920 |
| 2947 void HGraphBuilder::LookupGlobalPropertyCell(Variable* var, | 2921 void HGraphBuilder::LookupGlobalPropertyCell(Variable* var, |
| 2948 LookupResult* lookup, | 2922 LookupResult* lookup, |
| 2949 bool is_store) { | 2923 bool is_store) { |
| 2950 if (var->is_this()) { | 2924 if (var->is_this()) { |
| 2951 BAILOUT("global this reference"); | 2925 BAILOUT("global this reference"); |
| 2952 } | 2926 } |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3310 Push(value); | 3284 Push(value); |
| 3311 instr->set_position(expr->position()); | 3285 instr->set_position(expr->position()); |
| 3312 AddInstruction(instr); | 3286 AddInstruction(instr); |
| 3313 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); | 3287 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
| 3314 ast_context()->ReturnValue(Pop()); | 3288 ast_context()->ReturnValue(Pop()); |
| 3315 } else { | 3289 } else { |
| 3316 // Build subgraph for generic store through IC. | 3290 // Build subgraph for generic store through IC. |
| 3317 HSubgraph* default_graph = CreateBranchSubgraph(environment()); | 3291 HSubgraph* default_graph = CreateBranchSubgraph(environment()); |
| 3318 { SubgraphScope scope(this, default_graph); | 3292 { SubgraphScope scope(this, default_graph); |
| 3319 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { | 3293 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { |
| 3320 default_graph->FinishExit(new HDeoptimize()); | 3294 default_graph->exit_block()->FinishExit(new HDeoptimize()); |
| 3295 default_graph->set_exit_block(NULL); | |
| 3321 } else { | 3296 } else { |
| 3322 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); | 3297 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); |
| 3323 Push(value); | 3298 Push(value); |
| 3324 instr->set_position(expr->position()); | 3299 instr->set_position(expr->position()); |
| 3325 AddInstruction(instr); | 3300 AddInstruction(instr); |
| 3326 } | 3301 } |
| 3327 } | 3302 } |
| 3328 | 3303 |
| 3329 HBasicBlock* new_exit_block = | 3304 HBasicBlock* new_exit_block = |
| 3330 BuildTypeSwitch(object, &maps, &subgraphs, default_graph, expr->id()); | 3305 BuildTypeSwitch(object, &maps, &subgraphs, default_graph, expr->id()); |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3597 // assignments, count operations, or for-in. Consequently throw can | 3572 // assignments, count operations, or for-in. Consequently throw can |
| 3598 // currently only occur in an effect context. | 3573 // currently only occur in an effect context. |
| 3599 ASSERT(ast_context()->IsEffect()); | 3574 ASSERT(ast_context()->IsEffect()); |
| 3600 VISIT_FOR_VALUE(expr->exception()); | 3575 VISIT_FOR_VALUE(expr->exception()); |
| 3601 | 3576 |
| 3602 HValue* value = environment()->Pop(); | 3577 HValue* value = environment()->Pop(); |
| 3603 HThrow* instr = new HThrow(value); | 3578 HThrow* instr = new HThrow(value); |
| 3604 instr->set_position(expr->position()); | 3579 instr->set_position(expr->position()); |
| 3605 AddInstruction(instr); | 3580 AddInstruction(instr); |
| 3606 AddSimulate(expr->id()); | 3581 AddSimulate(expr->id()); |
| 3607 current_subgraph_->FinishExit(new HAbnormalExit); | 3582 current_block()->FinishExit(new HAbnormalExit); |
| 3583 set_current_block(NULL); | |
| 3608 } | 3584 } |
| 3609 | 3585 |
| 3610 | 3586 |
| 3611 void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, | 3587 void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, |
| 3612 HValue* object, | 3588 HValue* object, |
| 3613 ZoneMapList* types, | 3589 ZoneMapList* types, |
| 3614 Handle<String> name) { | 3590 Handle<String> name) { |
| 3615 int number_of_types = Min(types->length(), kMaxLoadPolymorphism); | 3591 int number_of_types = Min(types->length(), kMaxLoadPolymorphism); |
| 3616 ZoneMapList maps(number_of_types); | 3592 ZoneMapList maps(number_of_types); |
| 3617 ZoneList<HSubgraph*> subgraphs(number_of_types); | 3593 ZoneList<HSubgraph*> subgraphs(number_of_types); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 3645 // generic load. | 3621 // generic load. |
| 3646 if (maps.length() == 0) { | 3622 if (maps.length() == 0) { |
| 3647 HInstruction* instr = BuildLoadNamedGeneric(object, expr); | 3623 HInstruction* instr = BuildLoadNamedGeneric(object, expr); |
| 3648 instr->set_position(expr->position()); | 3624 instr->set_position(expr->position()); |
| 3649 ast_context()->ReturnInstruction(instr, expr->id()); | 3625 ast_context()->ReturnInstruction(instr, expr->id()); |
| 3650 } else { | 3626 } else { |
| 3651 // Build subgraph for generic load through IC. | 3627 // Build subgraph for generic load through IC. |
| 3652 HSubgraph* default_graph = CreateBranchSubgraph(environment()); | 3628 HSubgraph* default_graph = CreateBranchSubgraph(environment()); |
| 3653 { SubgraphScope scope(this, default_graph); | 3629 { SubgraphScope scope(this, default_graph); |
| 3654 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { | 3630 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { |
| 3655 default_graph->FinishExit(new HDeoptimize()); | 3631 default_graph->exit_block()->FinishExit(new HDeoptimize()); |
| 3632 default_graph->set_exit_block(NULL); | |
| 3656 } else { | 3633 } else { |
| 3657 HInstruction* instr = BuildLoadNamedGeneric(object, expr); | 3634 HInstruction* instr = BuildLoadNamedGeneric(object, expr); |
| 3658 instr->set_position(expr->position()); | 3635 instr->set_position(expr->position()); |
| 3659 PushAndAdd(instr); | 3636 PushAndAdd(instr); |
| 3660 } | 3637 } |
| 3661 } | 3638 } |
| 3662 | 3639 |
| 3663 HBasicBlock* new_exit_block = | 3640 HBasicBlock* new_exit_block = |
| 3664 BuildTypeSwitch(object, &maps, &subgraphs, default_graph, expr->id()); | 3641 BuildTypeSwitch(object, &maps, &subgraphs, default_graph, expr->id()); |
| 3665 set_current_block(new_exit_block); | 3642 set_current_block(new_exit_block); |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4003 AddInstruction(context); | 3980 AddInstruction(context); |
| 4004 HCallNamed* call = new HCallNamed(context, name, argument_count); | 3981 HCallNamed* call = new HCallNamed(context, name, argument_count); |
| 4005 call->set_position(expr->position()); | 3982 call->set_position(expr->position()); |
| 4006 PreProcessCall(call); | 3983 PreProcessCall(call); |
| 4007 ast_context()->ReturnInstruction(call, expr->id()); | 3984 ast_context()->ReturnInstruction(call, expr->id()); |
| 4008 } else { | 3985 } else { |
| 4009 // Build subgraph for generic call through IC. | 3986 // Build subgraph for generic call through IC. |
| 4010 HSubgraph* default_graph = CreateBranchSubgraph(environment()); | 3987 HSubgraph* default_graph = CreateBranchSubgraph(environment()); |
| 4011 { SubgraphScope scope(this, default_graph); | 3988 { SubgraphScope scope(this, default_graph); |
| 4012 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { | 3989 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { |
| 4013 default_graph->FinishExit(new HDeoptimize()); | 3990 default_graph->exit_block()->FinishExit(new HDeoptimize()); |
| 3991 default_graph->set_exit_block(NULL); | |
| 4014 } else { | 3992 } else { |
| 4015 HContext* context = new HContext; | 3993 HContext* context = new HContext; |
| 4016 AddInstruction(context); | 3994 AddInstruction(context); |
| 4017 HCallNamed* call = new HCallNamed(context, name, argument_count); | 3995 HCallNamed* call = new HCallNamed(context, name, argument_count); |
| 4018 call->set_position(expr->position()); | 3996 call->set_position(expr->position()); |
| 4019 PreProcessCall(call); | 3997 PreProcessCall(call); |
| 4020 PushAndAdd(call); | 3998 PushAndAdd(call); |
| 4021 } | 3999 } |
| 4022 } | 4000 } |
| 4023 | 4001 |
| (...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4723 false_graph->entry_block(), | 4701 false_graph->entry_block(), |
| 4724 true_graph->entry_block()); | 4702 true_graph->entry_block()); |
| 4725 true_graph->entry_block()->SetJoinId(expr->expression()->id()); | 4703 true_graph->entry_block()->SetJoinId(expr->expression()->id()); |
| 4726 true_graph->exit_block()->last_environment()->Push( | 4704 true_graph->exit_block()->last_environment()->Push( |
| 4727 graph_->GetConstantTrue()); | 4705 graph_->GetConstantTrue()); |
| 4728 | 4706 |
| 4729 false_graph->entry_block()->SetJoinId(expr->expression()->id()); | 4707 false_graph->entry_block()->SetJoinId(expr->expression()->id()); |
| 4730 false_graph->exit_block()->last_environment()->Push( | 4708 false_graph->exit_block()->last_environment()->Push( |
| 4731 graph_->GetConstantFalse()); | 4709 graph_->GetConstantFalse()); |
| 4732 | 4710 |
| 4733 current_subgraph_->AppendJoin(true_graph->exit_block(), | 4711 set_current_block(CreateJoin(true_graph->exit_block(), |
| 4734 false_graph->exit_block(), | 4712 false_graph->exit_block(), |
| 4735 expr->id()); | 4713 expr->id())); |
| 4736 ast_context()->ReturnValue(Pop()); | 4714 ast_context()->ReturnValue(Pop()); |
| 4737 } else { | 4715 } else { |
| 4738 ASSERT(ast_context()->IsEffect()); | 4716 ASSERT(ast_context()->IsEffect()); |
| 4739 VISIT_FOR_EFFECT(expr->expression()); | 4717 VISIT_FOR_EFFECT(expr->expression()); |
| 4740 } | 4718 } |
| 4741 | 4719 |
| 4742 } else if (op == Token::BIT_NOT || op == Token::SUB) { | 4720 } else if (op == Token::BIT_NOT || op == Token::SUB) { |
| 4743 VISIT_FOR_VALUE(expr->expression()); | 4721 VISIT_FOR_VALUE(expr->expression()); |
| 4744 HValue* value = Pop(); | 4722 HValue* value = Pop(); |
| 4745 HInstruction* instr = NULL; | 4723 HInstruction* instr = NULL; |
| (...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6126 } | 6104 } |
| 6127 } | 6105 } |
| 6128 | 6106 |
| 6129 #ifdef DEBUG | 6107 #ifdef DEBUG |
| 6130 if (graph_ != NULL) graph_->Verify(); | 6108 if (graph_ != NULL) graph_->Verify(); |
| 6131 if (allocator_ != NULL) allocator_->Verify(); | 6109 if (allocator_ != NULL) allocator_->Verify(); |
| 6132 #endif | 6110 #endif |
| 6133 } | 6111 } |
| 6134 | 6112 |
| 6135 } } // namespace v8::internal | 6113 } } // namespace v8::internal |
| OLD | NEW |