| 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 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 } | 498 } |
| 499 | 499 |
| 500 | 500 |
| 501 HConstant* HGraph::GetConstantFalse() { | 501 HConstant* HGraph::GetConstantFalse() { |
| 502 return GetConstant(&constant_false_, Heap::false_value()); | 502 return GetConstant(&constant_false_, Heap::false_value()); |
| 503 } | 503 } |
| 504 | 504 |
| 505 | 505 |
| 506 void HSubgraph::AppendOptional(HSubgraph* graph, | 506 void HSubgraph::AppendOptional(HSubgraph* graph, |
| 507 bool on_true_branch, | 507 bool on_true_branch, |
| 508 HValue* boolean_value) { | 508 HValue* value) { |
| 509 ASSERT(HasExit() && graph->HasExit()); | 509 ASSERT(HasExit() && graph->HasExit()); |
| 510 HBasicBlock* other_block = graph_->CreateBasicBlock(); | 510 HBasicBlock* other_block = graph_->CreateBasicBlock(); |
| 511 HBasicBlock* join_block = graph_->CreateBasicBlock(); | 511 HBasicBlock* join_block = graph_->CreateBasicBlock(); |
| 512 | 512 |
| 513 HBasicBlock* true_branch = other_block; | 513 HTest* test = on_true_branch |
| 514 HBasicBlock* false_branch = graph->entry_block(); | 514 ? new HTest(value, graph->entry_block(), other_block) |
| 515 if (on_true_branch) { | 515 : new HTest(value, other_block, graph->entry_block()); |
| 516 true_branch = graph->entry_block(); | 516 exit_block_->Finish(test); |
| 517 false_branch = other_block; | |
| 518 } | |
| 519 | |
| 520 exit_block_->Finish(new HBranch(true_branch, false_branch, boolean_value)); | |
| 521 other_block->Goto(join_block); | 517 other_block->Goto(join_block); |
| 522 graph->exit_block()->Goto(join_block); | 518 graph->exit_block()->Goto(join_block); |
| 523 exit_block_ = join_block; | 519 exit_block_ = join_block; |
| 524 } | 520 } |
| 525 | 521 |
| 526 | 522 |
| 527 void HSubgraph::AppendJoin(HSubgraph* then_graph, | 523 void HSubgraph::AppendJoin(HSubgraph* then_graph, |
| 528 HSubgraph* else_graph, | 524 HSubgraph* else_graph, |
| 529 AstNode* node) { | 525 AstNode* node) { |
| 530 if (then_graph->HasExit() && else_graph->HasExit()) { | 526 if (then_graph->HasExit() && else_graph->HasExit()) { |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 928 | 924 |
| 929 class HRangeAnalysis BASE_EMBEDDED { | 925 class HRangeAnalysis BASE_EMBEDDED { |
| 930 public: | 926 public: |
| 931 explicit HRangeAnalysis(HGraph* graph) : graph_(graph), changed_ranges_(16) {} | 927 explicit HRangeAnalysis(HGraph* graph) : graph_(graph), changed_ranges_(16) {} |
| 932 | 928 |
| 933 void Analyze(); | 929 void Analyze(); |
| 934 | 930 |
| 935 private: | 931 private: |
| 936 void TraceRange(const char* msg, ...); | 932 void TraceRange(const char* msg, ...); |
| 937 void Analyze(HBasicBlock* block); | 933 void Analyze(HBasicBlock* block); |
| 938 void InferControlFlowRange(HBranch* branch, HBasicBlock* dest); | 934 void InferControlFlowRange(HTest* test, HBasicBlock* dest); |
| 939 void InferControlFlowRange(Token::Value op, HValue* value, HValue* other); | 935 void InferControlFlowRange(Token::Value op, HValue* value, HValue* other); |
| 940 void InferPhiRange(HPhi* phi); | 936 void InferPhiRange(HPhi* phi); |
| 941 void InferRange(HValue* value); | 937 void InferRange(HValue* value); |
| 942 void RollBackTo(int index); | 938 void RollBackTo(int index); |
| 943 void AddRange(HValue* value, Range* range); | 939 void AddRange(HValue* value, Range* range); |
| 944 | 940 |
| 945 HGraph* graph_; | 941 HGraph* graph_; |
| 946 ZoneList<HValue*> changed_ranges_; | 942 ZoneList<HValue*> changed_ranges_; |
| 947 }; | 943 }; |
| 948 | 944 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 964 | 960 |
| 965 | 961 |
| 966 void HRangeAnalysis::Analyze(HBasicBlock* block) { | 962 void HRangeAnalysis::Analyze(HBasicBlock* block) { |
| 967 TraceRange("Analyzing block B%d\n", block->block_id()); | 963 TraceRange("Analyzing block B%d\n", block->block_id()); |
| 968 | 964 |
| 969 int last_changed_range = changed_ranges_.length() - 1; | 965 int last_changed_range = changed_ranges_.length() - 1; |
| 970 | 966 |
| 971 // Infer range based on control flow. | 967 // Infer range based on control flow. |
| 972 if (block->predecessors()->length() == 1) { | 968 if (block->predecessors()->length() == 1) { |
| 973 HBasicBlock* pred = block->predecessors()->first(); | 969 HBasicBlock* pred = block->predecessors()->first(); |
| 974 if (pred->end()->IsBranch()) { | 970 if (pred->end()->IsTest()) { |
| 975 InferControlFlowRange(HBranch::cast(pred->end()), block); | 971 InferControlFlowRange(HTest::cast(pred->end()), block); |
| 976 } | 972 } |
| 977 } | 973 } |
| 978 | 974 |
| 979 // Process phi instructions. | 975 // Process phi instructions. |
| 980 for (int i = 0; i < block->phis()->length(); ++i) { | 976 for (int i = 0; i < block->phis()->length(); ++i) { |
| 981 HPhi* phi = block->phis()->at(i); | 977 HPhi* phi = block->phis()->at(i); |
| 982 InferPhiRange(phi); | 978 InferPhiRange(phi); |
| 983 } | 979 } |
| 984 | 980 |
| 985 // Go through all instructions of the current block. | 981 // Go through all instructions of the current block. |
| 986 HInstruction* instr = block->first(); | 982 HInstruction* instr = block->first(); |
| 987 while (instr != block->end()) { | 983 while (instr != block->end()) { |
| 988 InferRange(instr); | 984 InferRange(instr); |
| 989 instr = instr->next(); | 985 instr = instr->next(); |
| 990 } | 986 } |
| 991 | 987 |
| 992 // Continue analysis in all dominated blocks. | 988 // Continue analysis in all dominated blocks. |
| 993 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { | 989 for (int i = 0; i < block->dominated_blocks()->length(); ++i) { |
| 994 Analyze(block->dominated_blocks()->at(i)); | 990 Analyze(block->dominated_blocks()->at(i)); |
| 995 } | 991 } |
| 996 | 992 |
| 997 RollBackTo(last_changed_range); | 993 RollBackTo(last_changed_range); |
| 998 } | 994 } |
| 999 | 995 |
| 1000 | 996 |
| 1001 void HRangeAnalysis::InferControlFlowRange(HBranch* branch, HBasicBlock* dest) { | 997 void HRangeAnalysis::InferControlFlowRange(HTest* test, HBasicBlock* dest) { |
| 1002 ASSERT(branch->FirstSuccessor() == dest || branch->SecondSuccessor() == dest); | 998 ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest)); |
| 1003 ASSERT(branch->FirstSuccessor() != dest || branch->SecondSuccessor() != dest); | 999 if (test->value()->IsCompare()) { |
| 1004 | 1000 HCompare* compare = HCompare::cast(test->value()); |
| 1005 if (branch->value()->IsCompare()) { | |
| 1006 HCompare* compare = HCompare::cast(branch->value()); | |
| 1007 Token::Value op = compare->token(); | 1001 Token::Value op = compare->token(); |
| 1008 if (branch->SecondSuccessor() == dest) { | 1002 if (test->SecondSuccessor() == dest) { |
| 1009 op = Token::NegateCompareOp(op); | 1003 op = Token::NegateCompareOp(op); |
| 1010 } | 1004 } |
| 1011 Token::Value inverted_op = Token::InvertCompareOp(op); | 1005 Token::Value inverted_op = Token::InvertCompareOp(op); |
| 1012 InferControlFlowRange(op, compare->left(), compare->right()); | 1006 InferControlFlowRange(op, compare->left(), compare->right()); |
| 1013 InferControlFlowRange(inverted_op, compare->right(), compare->left()); | 1007 InferControlFlowRange(inverted_op, compare->right(), compare->left()); |
| 1014 } | 1008 } |
| 1015 } | 1009 } |
| 1016 | 1010 |
| 1017 | 1011 |
| 1018 // We know that value [op] other. Use this information to update the range on | 1012 // We know that value [op] other. Use this information to update the range on |
| (...skipping 1042 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2061 | 2055 |
| 2062 | 2056 |
| 2063 void TestContext::BuildBranch(HValue* value) { | 2057 void TestContext::BuildBranch(HValue* value) { |
| 2064 // We expect the graph to be in edge-split form: there is no edge that | 2058 // We expect the graph to be in edge-split form: there is no edge that |
| 2065 // connects a branch node to a join node. We conservatively ensure that | 2059 // connects a branch node to a join node. We conservatively ensure that |
| 2066 // property by always adding an empty block on the outgoing edges of this | 2060 // property by always adding an empty block on the outgoing edges of this |
| 2067 // branch. | 2061 // branch. |
| 2068 HGraphBuilder* builder = owner(); | 2062 HGraphBuilder* builder = owner(); |
| 2069 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); | 2063 HBasicBlock* empty_true = builder->graph()->CreateBasicBlock(); |
| 2070 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); | 2064 HBasicBlock* empty_false = builder->graph()->CreateBasicBlock(); |
| 2071 HBranch* branch = new HBranch(empty_true, empty_false, value); | 2065 HTest* test = new HTest(value, empty_true, empty_false); |
| 2072 builder->CurrentBlock()->Finish(branch); | 2066 builder->CurrentBlock()->Finish(test); |
| 2073 | 2067 |
| 2074 HValue* const no_return_value = NULL; | 2068 HValue* const no_return_value = NULL; |
| 2075 HBasicBlock* true_target = if_true(); | 2069 HBasicBlock* true_target = if_true(); |
| 2076 if (true_target->IsInlineReturnTarget()) { | 2070 if (true_target->IsInlineReturnTarget()) { |
| 2077 empty_true->AddLeaveInlined(no_return_value, true_target); | 2071 empty_true->AddLeaveInlined(no_return_value, true_target); |
| 2078 } else { | 2072 } else { |
| 2079 empty_true->Goto(true_target); | 2073 empty_true->Goto(true_target); |
| 2080 } | 2074 } |
| 2081 | 2075 |
| 2082 HBasicBlock* false_target = if_false(); | 2076 HBasicBlock* false_target = if_false(); |
| (...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2590 CaseClause* clause = clauses->at(i); | 2584 CaseClause* clause = clauses->at(i); |
| 2591 if (clause->is_default()) continue; | 2585 if (clause->is_default()) continue; |
| 2592 | 2586 |
| 2593 // Finish the previous graph by connecting it to the current. | 2587 // Finish the previous graph by connecting it to the current. |
| 2594 HSubgraph* subgraph = compare_graphs.at(i); | 2588 HSubgraph* subgraph = compare_graphs.at(i); |
| 2595 if (prev_compare_inst == NULL) { | 2589 if (prev_compare_inst == NULL) { |
| 2596 ASSERT(prev_graph == current_subgraph_); | 2590 ASSERT(prev_graph == current_subgraph_); |
| 2597 prev_graph->exit_block()->Finish(new HGoto(subgraph->entry_block())); | 2591 prev_graph->exit_block()->Finish(new HGoto(subgraph->entry_block())); |
| 2598 } else { | 2592 } else { |
| 2599 HBasicBlock* empty = graph()->CreateBasicBlock(); | 2593 HBasicBlock* empty = graph()->CreateBasicBlock(); |
| 2600 prev_graph->exit_block()->Finish(new HBranch(empty, | 2594 prev_graph->exit_block()->Finish(new HTest(prev_compare_inst, |
| 2601 subgraph->entry_block(), | 2595 empty, |
| 2602 prev_compare_inst)); | 2596 subgraph->entry_block())); |
| 2603 } | 2597 } |
| 2604 | 2598 |
| 2605 // Build instructions for current subgraph. | 2599 // Build instructions for current subgraph. |
| 2606 ASSERT(clause->IsSmiCompare()); | 2600 ASSERT(clause->IsSmiCompare()); |
| 2607 prev_compare_inst = BuildSwitchCompare(subgraph, switch_value, clause); | 2601 prev_compare_inst = BuildSwitchCompare(subgraph, switch_value, clause); |
| 2608 if (HasStackOverflow()) return; | 2602 if (HasStackOverflow()) return; |
| 2609 | 2603 |
| 2610 prev_graph = subgraph; | 2604 prev_graph = subgraph; |
| 2611 } | 2605 } |
| 2612 | 2606 |
| 2613 // Finish last comparison if there was at least one comparison. | 2607 // Finish last comparison if there was at least one comparison. |
| 2614 // last_false_block is the (empty) false-block of the last comparison. If | 2608 // last_false_block is the (empty) false-block of the last comparison. If |
| 2615 // there are no comparisons at all (a single default clause), it is just | 2609 // there are no comparisons at all (a single default clause), it is just |
| 2616 // the last block of the current subgraph. | 2610 // the last block of the current subgraph. |
| 2617 HBasicBlock* last_false_block = current_subgraph_->exit_block(); | 2611 HBasicBlock* last_false_block = current_subgraph_->exit_block(); |
| 2618 if (prev_graph != current_subgraph_) { | 2612 if (prev_graph != current_subgraph_) { |
| 2619 last_false_block = graph()->CreateBasicBlock(); | 2613 last_false_block = graph()->CreateBasicBlock(); |
| 2620 HBasicBlock* empty = graph()->CreateBasicBlock(); | 2614 HBasicBlock* empty = graph()->CreateBasicBlock(); |
| 2621 prev_graph->exit_block()->Finish(new HBranch(empty, | 2615 prev_graph->exit_block()->Finish(new HTest(prev_compare_inst, |
| 2622 last_false_block, | 2616 empty, |
| 2623 prev_compare_inst)); | 2617 last_false_block)); |
| 2624 } | 2618 } |
| 2625 | 2619 |
| 2626 // If we have a non-smi compare clause, we deoptimize after trying | 2620 // If we have a non-smi compare clause, we deoptimize after trying |
| 2627 // all the previous compares. | 2621 // all the previous compares. |
| 2628 if (num_smi_clauses < num_clauses) { | 2622 if (num_smi_clauses < num_clauses) { |
| 2629 last_false_block->Finish(new HDeoptimize); | 2623 last_false_block->Finish(new HDeoptimize); |
| 2630 } | 2624 } |
| 2631 | 2625 |
| 2632 // Build statement blocks, connect them to their comparison block and | 2626 // Build statement blocks, connect them to their comparison block and |
| 2633 // to the previous statement block, if there is a fall-through. | 2627 // to the previous statement block, if there is a fall-through. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2696 return statement->OsrEntryId() == info()->osr_ast_id(); | 2690 return statement->OsrEntryId() == info()->osr_ast_id(); |
| 2697 } | 2691 } |
| 2698 | 2692 |
| 2699 | 2693 |
| 2700 void HSubgraph::PreProcessOsrEntry(IterationStatement* statement) { | 2694 void HSubgraph::PreProcessOsrEntry(IterationStatement* statement) { |
| 2701 if (!graph()->HasOsrEntryAt(statement)) return; | 2695 if (!graph()->HasOsrEntryAt(statement)) return; |
| 2702 | 2696 |
| 2703 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); | 2697 HBasicBlock* non_osr_entry = graph()->CreateBasicBlock(); |
| 2704 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); | 2698 HBasicBlock* osr_entry = graph()->CreateBasicBlock(); |
| 2705 HValue* true_value = graph()->GetConstantTrue(); | 2699 HValue* true_value = graph()->GetConstantTrue(); |
| 2706 HBranch* branch = new HBranch(non_osr_entry, osr_entry, true_value); | 2700 HTest* test = new HTest(true_value, non_osr_entry, osr_entry); |
| 2707 exit_block()->Finish(branch); | 2701 exit_block()->Finish(test); |
| 2708 | 2702 |
| 2709 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 2703 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
| 2710 non_osr_entry->Goto(loop_predecessor); | 2704 non_osr_entry->Goto(loop_predecessor); |
| 2711 | 2705 |
| 2712 int osr_entry_id = statement->OsrEntryId(); | 2706 int osr_entry_id = statement->OsrEntryId(); |
| 2713 // We want the correct environment at the OsrEntry instruction. Build | 2707 // We want the correct environment at the OsrEntry instruction. Build |
| 2714 // it explicitly. The expression stack should be empty. | 2708 // it explicitly. The expression stack should be empty. |
| 2715 int count = osr_entry->last_environment()->length(); | 2709 int count = osr_entry->last_environment()->length(); |
| 2716 ASSERT(count == (osr_entry->last_environment()->parameter_count() + | 2710 ASSERT(count == (osr_entry->last_environment()->parameter_count() + |
| 2717 osr_entry->last_environment()->local_count())); | 2711 osr_entry->last_environment()->local_count())); |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3099 | 3093 |
| 3100 // Build map compare subgraphs for all but the first map. | 3094 // Build map compare subgraphs for all but the first map. |
| 3101 ZoneList<HSubgraph*> map_compare_subgraphs(maps->length() - 1); | 3095 ZoneList<HSubgraph*> map_compare_subgraphs(maps->length() - 1); |
| 3102 for (int i = maps->length() - 1; i > 0; --i) { | 3096 for (int i = maps->length() - 1; i > 0; --i) { |
| 3103 HSubgraph* subgraph = CreateBranchSubgraph(environment()); | 3097 HSubgraph* subgraph = CreateBranchSubgraph(environment()); |
| 3104 SubgraphScope scope(this, subgraph); | 3098 SubgraphScope scope(this, subgraph); |
| 3105 HSubgraph* else_subgraph = | 3099 HSubgraph* else_subgraph = |
| 3106 (i == (maps->length() - 1)) | 3100 (i == (maps->length() - 1)) |
| 3107 ? subgraphs->last() | 3101 ? subgraphs->last() |
| 3108 : map_compare_subgraphs.last(); | 3102 : map_compare_subgraphs.last(); |
| 3109 current_subgraph_->exit_block()->Finish( | 3103 HCompareMap* compare = new HCompareMap(receiver, |
| 3110 new HCompareMapAndBranch(receiver, | 3104 maps->at(i), |
| 3111 maps->at(i), | 3105 subgraphs->at(i)->entry_block(), |
| 3112 subgraphs->at(i)->entry_block(), | 3106 else_subgraph->entry_block()); |
| 3113 else_subgraph->entry_block())); | 3107 current_subgraph_->exit_block()->Finish(compare); |
| 3114 map_compare_subgraphs.Add(subgraph); | 3108 map_compare_subgraphs.Add(subgraph); |
| 3115 } | 3109 } |
| 3116 | 3110 |
| 3117 // Generate first map check to end the current block. | 3111 // Generate first map check to end the current block. |
| 3118 AddInstruction(new HCheckNonSmi(receiver)); | 3112 AddInstruction(new HCheckNonSmi(receiver)); |
| 3119 HSubgraph* else_subgraph = | 3113 HSubgraph* else_subgraph = |
| 3120 (maps->length() == 1) ? subgraphs->at(1) : map_compare_subgraphs.last(); | 3114 (maps->length() == 1) ? subgraphs->at(1) : map_compare_subgraphs.last(); |
| 3121 current_subgraph_->exit_block()->Finish( | 3115 HCompareMap* compare = new HCompareMap(receiver, |
| 3122 new HCompareMapAndBranch(receiver, | 3116 Handle<Map>(maps->first()), |
| 3123 Handle<Map>(maps->first()), | 3117 subgraphs->first()->entry_block(), |
| 3124 subgraphs->first()->entry_block(), | 3118 else_subgraph->entry_block()); |
| 3125 else_subgraph->entry_block())); | 3119 current_subgraph_->exit_block()->Finish(compare); |
| 3126 | 3120 |
| 3127 // Join all the call subgraphs in a new basic block and make | 3121 // Join all the call subgraphs in a new basic block and make |
| 3128 // this basic block the current basic block. | 3122 // this basic block the current basic block. |
| 3129 HBasicBlock* join_block = graph_->CreateBasicBlock(); | 3123 HBasicBlock* join_block = graph_->CreateBasicBlock(); |
| 3130 for (int i = 0; i < subgraphs->length(); ++i) { | 3124 for (int i = 0; i < subgraphs->length(); ++i) { |
| 3131 HSubgraph* subgraph = subgraphs->at(i); | 3125 HSubgraph* subgraph = subgraphs->at(i); |
| 3132 if (subgraph->HasExit()) { | 3126 if (subgraph->HasExit()) { |
| 3133 // In an effect context the value of the type switch is not needed. | 3127 // In an effect context the value of the type switch is not needed. |
| 3134 // There is no need to merge it at the join block only to discard it. | 3128 // There is no need to merge it at the join block only to discard it. |
| 3135 HBasicBlock* subgraph_exit = subgraph->exit_block(); | 3129 HBasicBlock* subgraph_exit = subgraph->exit_block(); |
| (...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4069 ASSERT(function_return_ != NULL); | 4063 ASSERT(function_return_ != NULL); |
| 4070 body->exit_block()->AddLeaveInlined(return_value, function_return_); | 4064 body->exit_block()->AddLeaveInlined(return_value, function_return_); |
| 4071 } else { | 4065 } else { |
| 4072 // The graph builder assumes control can reach both branches of a | 4066 // The graph builder assumes control can reach both branches of a |
| 4073 // test, so we materialize the undefined value and test it rather than | 4067 // test, so we materialize the undefined value and test it rather than |
| 4074 // simply jumping to the false target. | 4068 // simply jumping to the false target. |
| 4075 // | 4069 // |
| 4076 // TODO(3168478): refactor to avoid this. | 4070 // TODO(3168478): refactor to avoid this. |
| 4077 HBasicBlock* empty_true = graph()->CreateBasicBlock(); | 4071 HBasicBlock* empty_true = graph()->CreateBasicBlock(); |
| 4078 HBasicBlock* empty_false = graph()->CreateBasicBlock(); | 4072 HBasicBlock* empty_false = graph()->CreateBasicBlock(); |
| 4079 HBranch* branch = | 4073 HTest* test = new HTest(return_value, empty_true, empty_false); |
| 4080 new HBranch(empty_true, empty_false, return_value); | 4074 body->exit_block()->Finish(test); |
| 4081 body->exit_block()->Finish(branch); | |
| 4082 | 4075 |
| 4083 HValue* const no_return_value = NULL; | 4076 HValue* const no_return_value = NULL; |
| 4084 empty_true->AddLeaveInlined(no_return_value, test_context->if_true()); | 4077 empty_true->AddLeaveInlined(no_return_value, test_context->if_true()); |
| 4085 empty_false->AddLeaveInlined(no_return_value, test_context->if_false()); | 4078 empty_false->AddLeaveInlined(no_return_value, test_context->if_false()); |
| 4086 } | 4079 } |
| 4087 body->set_exit_block(NULL); | 4080 body->set_exit_block(NULL); |
| 4088 } | 4081 } |
| 4089 | 4082 |
| 4090 // Record the environment at the inlined function call. | 4083 // Record the environment at the inlined function call. |
| 4091 AddSimulate(expr->ReturnId()); | 4084 AddSimulate(expr->ReturnId()); |
| (...skipping 1775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5867 } | 5860 } |
| 5868 } | 5861 } |
| 5869 | 5862 |
| 5870 #ifdef DEBUG | 5863 #ifdef DEBUG |
| 5871 if (graph_ != NULL) graph_->Verify(); | 5864 if (graph_ != NULL) graph_->Verify(); |
| 5872 if (allocator_ != NULL) allocator_->Verify(); | 5865 if (allocator_ != NULL) allocator_->Verify(); |
| 5873 #endif | 5866 #endif |
| 5874 } | 5867 } |
| 5875 | 5868 |
| 5876 } } // namespace v8::internal | 5869 } } // namespace v8::internal |
| OLD | NEW |