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 |