| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/bit_vector.h" | 8 #include "vm/bit_vector.h" |
| 9 #include "vm/code_descriptors.h" | 9 #include "vm/code_descriptors.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 } | 44 } |
| 45 | 45 |
| 46 | 46 |
| 47 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { | 47 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { |
| 48 ASSERT(is_open()); | 48 ASSERT(is_open()); |
| 49 if (other_fragment.is_empty()) return; | 49 if (other_fragment.is_empty()) return; |
| 50 if (is_empty()) { | 50 if (is_empty()) { |
| 51 entry_ = other_fragment.entry(); | 51 entry_ = other_fragment.entry(); |
| 52 exit_ = other_fragment.exit(); | 52 exit_ = other_fragment.exit(); |
| 53 } else { | 53 } else { |
| 54 exit()->SetSuccessor(other_fragment.entry()); | 54 Instruction* successor = other_fragment.entry(); |
| 55 exit()->SetSuccessor(successor->IsBlockEntry() |
| 56 ? new GotoInstr(successor->AsBlockEntry()) |
| 57 : successor); |
| 55 exit_ = other_fragment.exit(); | 58 exit_ = other_fragment.exit(); |
| 56 } | 59 } |
| 57 temp_index_ = other_fragment.temp_index(); | 60 temp_index_ = other_fragment.temp_index(); |
| 58 } | 61 } |
| 59 | 62 |
| 60 | 63 |
| 61 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { | 64 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { |
| 62 ASSERT(is_open()); | 65 ASSERT(is_open()); |
| 66 ASSERT(!instruction->IsBlockEntry()); |
| 63 DeallocateTempIndex(instruction->InputCount()); | 67 DeallocateTempIndex(instruction->InputCount()); |
| 64 if (instruction->IsDefinition()) { | 68 if (instruction->IsDefinition()) { |
| 65 instruction->AsDefinition()->set_temp_index(AllocateTempIndex()); | 69 instruction->AsDefinition()->set_temp_index(AllocateTempIndex()); |
| 66 } | 70 } |
| 67 if (is_empty()) { | 71 if (is_empty()) { |
| 68 entry_ = exit_ = instruction; | 72 entry_ = exit_ = instruction; |
| 69 } else { | 73 } else { |
| 70 exit()->SetSuccessor(instruction); | 74 exit()->SetSuccessor(instruction); |
| 71 exit_ = instruction; | 75 exit_ = instruction; |
| 72 } | 76 } |
| 73 } | 77 } |
| 74 | 78 |
| 75 | 79 |
| 80 void EffectGraphVisitor::AddBlockEntry(BlockEntryInstr* instruction) { |
| 81 ASSERT(is_open()); |
| 82 if (is_empty()) { |
| 83 entry_ = exit_ = instruction; |
| 84 } else { |
| 85 ASSERT(exit()->IsGraphEntry() || |
| 86 exit()->IsGoto()); |
| 87 exit()->SetSuccessor(instruction); |
| 88 exit_ = instruction; |
| 89 } |
| 90 } |
| 91 |
| 92 |
| 76 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment, | 93 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment, |
| 77 const EffectGraphVisitor& true_fragment, | 94 const EffectGraphVisitor& true_fragment, |
| 78 const EffectGraphVisitor& false_fragment) { | 95 const EffectGraphVisitor& false_fragment) { |
| 79 // We have: a test graph fragment with zero, one, or two available exits; | 96 // We have: a test graph fragment with zero, one, or two available exits; |
| 80 // and a pair of effect graph fragments with zero or one available exits. | 97 // and a pair of effect graph fragments with zero or one available exits. |
| 81 // We want to append the branch and (if necessary) a join node to this | 98 // We want to append the branch and (if necessary) a join node to this |
| 82 // graph fragment. | 99 // graph fragment. |
| 83 ASSERT(is_open()); | 100 ASSERT(is_open()); |
| 84 | 101 |
| 85 // 1. Connect the test to this graph. | 102 // 1. Connect the test to this graph. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 101 | 118 |
| 102 // 3. Add a join or select one (or neither) of the arms as exit. | 119 // 3. Add a join or select one (or neither) of the arms as exit. |
| 103 if (true_exit == NULL) { | 120 if (true_exit == NULL) { |
| 104 exit_ = false_exit; // May be NULL. | 121 exit_ = false_exit; // May be NULL. |
| 105 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); | 122 if (false_exit != NULL) temp_index_ = false_fragment.temp_index(); |
| 106 } else if (false_exit == NULL) { | 123 } else if (false_exit == NULL) { |
| 107 exit_ = true_exit; | 124 exit_ = true_exit; |
| 108 temp_index_ = true_fragment.temp_index(); | 125 temp_index_ = true_fragment.temp_index(); |
| 109 } else { | 126 } else { |
| 110 exit_ = new JoinEntryInstr(); | 127 exit_ = new JoinEntryInstr(); |
| 111 true_exit->SetSuccessor(exit_); | 128 true_exit->SetSuccessor(new GotoInstr(exit_->AsBlockEntry())); |
| 112 false_exit->SetSuccessor(exit_); | 129 false_exit->SetSuccessor(new GotoInstr(exit_->AsBlockEntry())); |
| 113 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); | 130 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); |
| 114 temp_index_ = true_fragment.temp_index(); | 131 temp_index_ = true_fragment.temp_index(); |
| 115 } | 132 } |
| 116 } | 133 } |
| 117 | 134 |
| 118 | 135 |
| 119 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, | 136 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, |
| 120 const EffectGraphVisitor& body_fragment) { | 137 const EffectGraphVisitor& body_fragment) { |
| 121 // We have: a test graph fragment with zero, one, or two available exits; | 138 // We have: a test graph fragment with zero, one, or two available exits; |
| 122 // and an effect graph fragment with zero or one available exits. We want | 139 // and an effect graph fragment with zero or one available exits. We want |
| 123 // to append the 'while loop' consisting of the test graph fragment as | 140 // to append the 'while loop' consisting of the test graph fragment as |
| 124 // condition and the effect graph fragment as body. | 141 // condition and the effect graph fragment as body. |
| 125 ASSERT(is_open()); | 142 ASSERT(is_open()); |
| 126 | 143 |
| 127 // 1. Connect the body to the test if it is reachable, and if so record | 144 // 1. Connect the body to the test if it is reachable, and if so record |
| 128 // its exit (if any). | 145 // its exit (if any). |
| 129 Instruction* body_exit = NULL; | 146 Instruction* body_exit = NULL; |
| 130 TargetEntryInstr* body_entry = new TargetEntryInstr(); | 147 TargetEntryInstr* body_entry = new TargetEntryInstr(); |
| 131 *test_fragment.true_successor_address() = body_entry; | 148 *test_fragment.true_successor_address() = body_entry; |
| 132 body_entry->SetSuccessor(body_fragment.entry()); | 149 body_entry->SetSuccessor(body_fragment.entry()); |
| 133 body_exit = body_fragment.is_empty() ? body_entry : body_fragment.exit(); | 150 body_exit = body_fragment.is_empty() ? body_entry : body_fragment.exit(); |
| 134 | 151 |
| 135 // 2. Connect the test to this graph, including the body if reachable and | 152 // 2. Connect the test to this graph, including the body if reachable and |
| 136 // using a fresh join node if the body is reachable and has an open exit. | 153 // using a fresh join node if the body is reachable and has an open exit. |
| 137 if (body_exit == NULL) { | 154 if (body_exit == NULL) { |
| 138 Append(test_fragment); | 155 Append(test_fragment); |
| 139 } else { | 156 } else { |
| 140 JoinEntryInstr* join = new JoinEntryInstr(); | 157 JoinEntryInstr* join = new JoinEntryInstr(); |
| 141 AddInstruction(join); | 158 AddInstruction(new GotoInstr(join)); |
| 159 AddBlockEntry(join); |
| 142 join->SetSuccessor(test_fragment.entry()); | 160 join->SetSuccessor(test_fragment.entry()); |
| 143 body_exit->SetSuccessor(join); | 161 body_exit->SetSuccessor(new GotoInstr(join)); |
| 144 } | 162 } |
| 145 | 163 |
| 146 // 3. Set the exit to the graph to be the false successor of the test, a | 164 // 3. Set the exit to the graph to be the false successor of the test, a |
| 147 // fresh target node | 165 // fresh target node |
| 148 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr(); | 166 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr(); |
| 149 } | 167 } |
| 150 | 168 |
| 151 | 169 |
| 152 Computation* EffectGraphVisitor::BuildStoreLocal( | 170 Computation* EffectGraphVisitor::BuildStoreLocal( |
| 153 const LocalVariable& local, Value* value) { | 171 const LocalVariable& local, Value* value) { |
| (...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 956 Join(for_test, for_true, for_false); | 974 Join(for_test, for_true, for_false); |
| 957 } | 975 } |
| 958 | 976 |
| 959 | 977 |
| 960 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { | 978 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { |
| 961 EffectGraphVisitor switch_body(owner(), temp_index()); | 979 EffectGraphVisitor switch_body(owner(), temp_index()); |
| 962 node->body()->Visit(&switch_body); | 980 node->body()->Visit(&switch_body); |
| 963 Append(switch_body); | 981 Append(switch_body); |
| 964 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { | 982 if ((node->label() != NULL) && (node->label()->join_for_break() != NULL)) { |
| 965 if (is_open()) { | 983 if (is_open()) { |
| 966 AddInstruction(node->label()->join_for_break()); | 984 AddInstruction(new GotoInstr(node->label()->join_for_break())); |
| 985 AddBlockEntry(node->label()->join_for_break()); |
| 967 } else { | 986 } else { |
| 968 exit_ = node->label()->join_for_break(); | 987 exit_ = node->label()->join_for_break(); |
| 969 } | 988 } |
| 970 } | 989 } |
| 971 // No continue label allowed. | 990 // No continue label allowed. |
| 972 ASSERT((node->label() == NULL) || | 991 ASSERT((node->label() == NULL) || |
| 973 (node->label()->join_for_continue() == NULL)); | 992 (node->label()->join_for_continue() == NULL)); |
| 974 } | 993 } |
| 975 | 994 |
| 976 | 995 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1008 // allocate JoinNode here and use it as statement start. | 1027 // allocate JoinNode here and use it as statement start. |
| 1009 if (node->label()->join_for_continue() == NULL) { | 1028 if (node->label()->join_for_continue() == NULL) { |
| 1010 node->label()->set_join_for_continue(new JoinEntryInstr()); | 1029 node->label()->set_join_for_continue(new JoinEntryInstr()); |
| 1011 } | 1030 } |
| 1012 statement_start = node->label()->join_for_continue(); | 1031 statement_start = node->label()->join_for_continue(); |
| 1013 } else if (needs_join_at_statement_entry) { | 1032 } else if (needs_join_at_statement_entry) { |
| 1014 statement_start = new JoinEntryInstr(); | 1033 statement_start = new JoinEntryInstr(); |
| 1015 } else { | 1034 } else { |
| 1016 statement_start = new TargetEntryInstr(); | 1035 statement_start = new TargetEntryInstr(); |
| 1017 } | 1036 } |
| 1018 for_case_statements.AddInstruction(statement_start); | 1037 for_case_statements.AddBlockEntry(statement_start); |
| 1019 node->statements()->Visit(&for_case_statements); | 1038 node->statements()->Visit(&for_case_statements); |
| 1020 if (is_open() && (len == 0)) { | 1039 if (is_open() && (len == 0)) { |
| 1021 ASSERT(node->contains_default()); | 1040 ASSERT(node->contains_default()); |
| 1022 // Default only case node. | 1041 // Default only case node. |
| 1023 Append(for_case_statements); | 1042 Append(for_case_statements); |
| 1024 return; | 1043 return; |
| 1025 } | 1044 } |
| 1026 | 1045 |
| 1027 // Generate instructions for all case expressions and collect data to | 1046 // Generate instructions for all case expressions and collect data to |
| 1028 // connect them. | 1047 // connect them. |
| 1029 GrowableArray<TargetEntryInstr**> case_true_addresses; | 1048 GrowableArray<TargetEntryInstr**> case_true_addresses; |
| 1030 GrowableArray<TargetEntryInstr**> case_false_addresses; | 1049 GrowableArray<TargetEntryInstr**> case_false_addresses; |
| 1031 GrowableArray<TargetEntryInstr*> case_entries; | 1050 GrowableArray<TargetEntryInstr*> case_entries; |
| 1032 for (intptr_t i = 0; i < len; i++) { | 1051 for (intptr_t i = 0; i < len; i++) { |
| 1033 AstNode* case_expr = node->case_expressions()->NodeAt(i); | 1052 AstNode* case_expr = node->case_expressions()->NodeAt(i); |
| 1034 TestGraphVisitor for_case_expression(owner(), | 1053 TestGraphVisitor for_case_expression(owner(), |
| 1035 temp_index(), | 1054 temp_index(), |
| 1036 case_expr->token_pos()); | 1055 case_expr->token_pos()); |
| 1037 if (i == 0) { | 1056 if (i == 0) { |
| 1038 case_entries.Add(NULL); // Not to be used | 1057 case_entries.Add(NULL); // Not to be used |
| 1039 case_expr->Visit(&for_case_expression); | 1058 case_expr->Visit(&for_case_expression); |
| 1040 // Append only the first one, everything else is connected from it. | 1059 // Append only the first one, everything else is connected from it. |
| 1041 Append(for_case_expression); | 1060 Append(for_case_expression); |
| 1042 } else { | 1061 } else { |
| 1043 TargetEntryInstr* case_entry_target = new TargetEntryInstr(); | 1062 TargetEntryInstr* case_entry_target = new TargetEntryInstr(); |
| 1044 case_entries.Add(case_entry_target); | 1063 case_entries.Add(case_entry_target); |
| 1045 for_case_expression.AddInstruction(case_entry_target); | 1064 for_case_expression.AddBlockEntry(case_entry_target); |
| 1046 case_expr->Visit(&for_case_expression); | 1065 case_expr->Visit(&for_case_expression); |
| 1047 } | 1066 } |
| 1048 case_true_addresses.Add(for_case_expression.true_successor_address()); | 1067 case_true_addresses.Add(for_case_expression.true_successor_address()); |
| 1049 case_false_addresses.Add(for_case_expression.false_successor_address()); | 1068 case_false_addresses.Add(for_case_expression.false_successor_address()); |
| 1050 } | 1069 } |
| 1051 | 1070 |
| 1052 // Once a test fragment has been added, this fragment is closed. | 1071 // Once a test fragment has been added, this fragment is closed. |
| 1053 ASSERT(!is_open()); | 1072 ASSERT(!is_open()); |
| 1054 | 1073 |
| 1055 // Connect all test cases except the last one. | 1074 // Connect all test cases except the last one. |
| 1056 for (intptr_t i = 0; i < (len - 1); i++) { | 1075 for (intptr_t i = 0; i < (len - 1); i++) { |
| 1057 ASSERT(needs_join_at_statement_entry); | 1076 ASSERT(needs_join_at_statement_entry); |
| 1058 *case_false_addresses[i] = case_entries[i + 1]; | 1077 *case_false_addresses[i] = case_entries[i + 1]; |
| 1059 TargetEntryInstr* true_target = new TargetEntryInstr(); | 1078 TargetEntryInstr* true_target = new TargetEntryInstr(); |
| 1060 *case_true_addresses[i] = true_target; | 1079 *case_true_addresses[i] = true_target; |
| 1061 true_target->SetSuccessor(statement_start); | 1080 true_target->SetSuccessor(new GotoInstr(statement_start)); |
| 1062 } | 1081 } |
| 1063 | 1082 |
| 1064 BlockEntryInstr* exit_instruction = NULL; | 1083 BlockEntryInstr* exit_instruction = NULL; |
| 1065 // Handle last (or only) case: false goes to exit or to statement if this | 1084 // Handle last (or only) case: false goes to exit or to statement if this |
| 1066 // node contains default. | 1085 // node contains default. |
| 1067 if (len > 0) { | 1086 if (len > 0) { |
| 1068 if (statement_start->IsTargetEntry()) { | 1087 if (statement_start->IsTargetEntry()) { |
| 1069 *case_true_addresses[len - 1] = statement_start->AsTargetEntry(); | 1088 *case_true_addresses[len - 1] = statement_start->AsTargetEntry(); |
| 1070 } else { | 1089 } else { |
| 1071 TargetEntryInstr* true_target = new TargetEntryInstr(); | 1090 TargetEntryInstr* true_target = new TargetEntryInstr(); |
| 1072 *case_true_addresses[len - 1] = true_target; | 1091 *case_true_addresses[len - 1] = true_target; |
| 1073 true_target->SetSuccessor(statement_start); | 1092 true_target->SetSuccessor(new GotoInstr(statement_start)); |
| 1074 } | 1093 } |
| 1075 TargetEntryInstr* false_target = new TargetEntryInstr(); | 1094 TargetEntryInstr* false_target = new TargetEntryInstr(); |
| 1076 *case_false_addresses[len - 1] = false_target; | 1095 *case_false_addresses[len - 1] = false_target; |
| 1077 if (node->contains_default()) { | 1096 if (node->contains_default()) { |
| 1078 // True and false go to statement start. | 1097 // True and false go to statement start. |
| 1079 false_target->SetSuccessor(statement_start); | 1098 false_target->SetSuccessor(new GotoInstr(statement_start)); |
| 1080 if (for_case_statements.is_open()) { | 1099 if (for_case_statements.is_open()) { |
| 1081 exit_instruction = new TargetEntryInstr(); | 1100 exit_instruction = new TargetEntryInstr(); |
| 1082 for_case_statements.exit()->SetSuccessor(exit_instruction); | 1101 for_case_statements.exit()->SetSuccessor( |
| 1102 new GotoInstr(exit_instruction)); |
| 1083 } | 1103 } |
| 1084 } else { | 1104 } else { |
| 1085 if (for_case_statements.is_open()) { | 1105 if (for_case_statements.is_open()) { |
| 1086 exit_instruction = new JoinEntryInstr(); | 1106 exit_instruction = new JoinEntryInstr(); |
| 1087 for_case_statements.exit()->SetSuccessor(exit_instruction); | 1107 for_case_statements.exit()->SetSuccessor( |
| 1108 new GotoInstr(exit_instruction)); |
| 1088 } else { | 1109 } else { |
| 1089 exit_instruction = new TargetEntryInstr(); | 1110 exit_instruction = new TargetEntryInstr(); |
| 1090 } | 1111 } |
| 1091 false_target->SetSuccessor(exit_instruction); | 1112 false_target->SetSuccessor(new GotoInstr(exit_instruction)); |
| 1092 } | 1113 } |
| 1093 } else { | 1114 } else { |
| 1094 // A CaseNode without case expressions must contain default. | 1115 // A CaseNode without case expressions must contain default. |
| 1095 ASSERT(node->contains_default()); | 1116 ASSERT(node->contains_default()); |
| 1096 AddInstruction(statement_start); | 1117 AddInstruction(new GotoInstr(statement_start)); |
| 1118 AddBlockEntry(statement_start); |
| 1097 } | 1119 } |
| 1098 | 1120 |
| 1099 ASSERT(!is_open()); | 1121 ASSERT(!is_open()); |
| 1100 exit_ = exit_instruction; | 1122 exit_ = exit_instruction; |
| 1101 } | 1123 } |
| 1102 | 1124 |
| 1103 | 1125 |
| 1104 // <Statement> ::= While { label: SourceLabel | 1126 // <Statement> ::= While { label: SourceLabel |
| 1105 // condition: <Expression> | 1127 // condition: <Expression> |
| 1106 // body: <Sequence> } | 1128 // body: <Sequence> } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1122 EffectGraphVisitor for_body(owner(), temp_index()); | 1144 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1123 CheckStackOverflowComp* comp = | 1145 CheckStackOverflowComp* comp = |
| 1124 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()); | 1146 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()); |
| 1125 for_body.AddInstruction(new DoInstr(comp)); | 1147 for_body.AddInstruction(new DoInstr(comp)); |
| 1126 node->body()->Visit(&for_body); | 1148 node->body()->Visit(&for_body); |
| 1127 | 1149 |
| 1128 // Labels are set after body traversal. | 1150 // Labels are set after body traversal. |
| 1129 SourceLabel* lbl = node->label(); | 1151 SourceLabel* lbl = node->label(); |
| 1130 ASSERT(lbl != NULL); | 1152 ASSERT(lbl != NULL); |
| 1131 if (lbl->join_for_continue() != NULL) { | 1153 if (lbl->join_for_continue() != NULL) { |
| 1132 AddInstruction(lbl->join_for_continue()); | 1154 AddInstruction(new GotoInstr(lbl->join_for_continue())); |
| 1155 AddBlockEntry(lbl->join_for_continue()); |
| 1133 } | 1156 } |
| 1134 TieLoop(for_test, for_body); | 1157 TieLoop(for_test, for_body); |
| 1135 if (lbl->join_for_break() != NULL) { | 1158 if (lbl->join_for_break() != NULL) { |
| 1136 AddInstruction(lbl->join_for_break()); | 1159 AddInstruction(new GotoInstr(lbl->join_for_break())); |
| 1160 AddBlockEntry(lbl->join_for_break()); |
| 1137 } | 1161 } |
| 1138 } | 1162 } |
| 1139 | 1163 |
| 1140 | 1164 |
| 1141 // The fragment is composed as follows: | 1165 // The fragment is composed as follows: |
| 1142 // a) body-entry-join | 1166 // a) body-entry-join |
| 1143 // b) [ body ] | 1167 // b) [ body ] |
| 1144 // c) test-entry (continue-join or body-exit-target) | 1168 // c) test-entry (continue-join or body-exit-target) |
| 1145 // d) [ test-entry ] -> (back-target, loop-exit-target) | 1169 // d) [ test-entry ] -> (back-target, loop-exit-target) |
| 1146 // e) back-target -> (body-entry-join) | 1170 // e) back-target -> (body-entry-join) |
| 1147 // f) loop-exit-target | 1171 // f) loop-exit-target |
| 1148 // g) break-join | 1172 // g) break-join |
| 1149 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { | 1173 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { |
| 1150 // Traverse body first in order to generate continue and break labels. | 1174 // Traverse body first in order to generate continue and break labels. |
| 1151 EffectGraphVisitor for_body(owner(), temp_index()); | 1175 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1152 CheckStackOverflowComp* comp = | 1176 CheckStackOverflowComp* comp = |
| 1153 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()); | 1177 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()); |
| 1154 for_body.AddInstruction(new DoInstr(comp)); | 1178 for_body.AddInstruction(new DoInstr(comp)); |
| 1155 node->body()->Visit(&for_body); | 1179 node->body()->Visit(&for_body); |
| 1156 | 1180 |
| 1157 TestGraphVisitor for_test(owner(), | 1181 TestGraphVisitor for_test(owner(), |
| 1158 temp_index(), | 1182 temp_index(), |
| 1159 node->condition()->token_pos()); | 1183 node->condition()->token_pos()); |
| 1160 node->condition()->Visit(&for_test); | 1184 node->condition()->Visit(&for_test); |
| 1161 ASSERT(is_open()); | 1185 ASSERT(is_open()); |
| 1162 | 1186 |
| 1163 // Tie do-while loop (test is after the body). | 1187 // Tie do-while loop (test is after the body). |
| 1164 JoinEntryInstr* body_entry_join = new JoinEntryInstr(); | 1188 JoinEntryInstr* body_entry_join = new JoinEntryInstr(); |
| 1165 AddInstruction(body_entry_join); | 1189 AddInstruction(new GotoInstr(body_entry_join)); |
| 1190 AddBlockEntry(body_entry_join); |
| 1166 body_entry_join->SetSuccessor(for_body.entry()); | 1191 body_entry_join->SetSuccessor(for_body.entry()); |
| 1167 Instruction* body_exit = | 1192 Instruction* body_exit = |
| 1168 for_body.is_empty() ? body_entry_join : for_body.exit(); | 1193 for_body.is_empty() ? body_entry_join : for_body.exit(); |
| 1169 | 1194 |
| 1170 if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) { | 1195 if (for_body.is_open() || (node->label()->join_for_continue() != NULL)) { |
| 1171 BlockEntryInstr* test_entry = NULL; | 1196 BlockEntryInstr* test_entry = NULL; |
| 1172 if (node->label()->join_for_continue() == NULL) { | 1197 if (node->label()->join_for_continue() == NULL) { |
| 1173 test_entry = new TargetEntryInstr(); | 1198 test_entry = new TargetEntryInstr(); |
| 1174 } else { | 1199 } else { |
| 1175 test_entry = node->label()->join_for_continue(); | 1200 test_entry = node->label()->join_for_continue(); |
| 1176 } | 1201 } |
| 1177 test_entry->SetSuccessor(for_test.entry()); | 1202 test_entry->SetSuccessor(for_test.entry()); |
| 1178 if (body_exit != NULL) { | 1203 if (body_exit != NULL) { |
| 1179 body_exit->SetSuccessor(test_entry); | 1204 body_exit->SetSuccessor(new GotoInstr(test_entry)); |
| 1180 } | 1205 } |
| 1181 } | 1206 } |
| 1182 | 1207 |
| 1183 TargetEntryInstr* back_target_entry = new TargetEntryInstr(); | 1208 TargetEntryInstr* back_target_entry = new TargetEntryInstr(); |
| 1184 *for_test.true_successor_address() = back_target_entry; | 1209 *for_test.true_successor_address() = back_target_entry; |
| 1185 back_target_entry->SetSuccessor(body_entry_join); | 1210 back_target_entry->SetSuccessor(new GotoInstr(body_entry_join)); |
| 1186 TargetEntryInstr* loop_exit_target = new TargetEntryInstr(); | 1211 TargetEntryInstr* loop_exit_target = new TargetEntryInstr(); |
| 1187 *for_test.false_successor_address() = loop_exit_target; | 1212 *for_test.false_successor_address() = loop_exit_target; |
| 1188 if (node->label()->join_for_break() == NULL) { | 1213 if (node->label()->join_for_break() == NULL) { |
| 1189 exit_ = loop_exit_target; | 1214 exit_ = loop_exit_target; |
| 1190 } else { | 1215 } else { |
| 1191 loop_exit_target->SetSuccessor(node->label()->join_for_break()); | 1216 loop_exit_target->SetSuccessor( |
| 1217 new GotoInstr(node->label()->join_for_break())); |
| 1192 exit_ = node->label()->join_for_break(); | 1218 exit_ = node->label()->join_for_break(); |
| 1193 } | 1219 } |
| 1194 } | 1220 } |
| 1195 | 1221 |
| 1196 | 1222 |
| 1197 // A ForNode can contain break and continue jumps. 'break' joins to | 1223 // A ForNode can contain break and continue jumps. 'break' joins to |
| 1198 // ForNode exit, 'continue' joins at increment entry. The fragment is composed | 1224 // ForNode exit, 'continue' joins at increment entry. The fragment is composed |
| 1199 // as follows: | 1225 // as follows: |
| 1200 // a) [ initializer ] | 1226 // a) [ initializer ] |
| 1201 // b) loop-join | 1227 // b) loop-join |
| 1202 // c) [ test ] -> (body-entry-target, loop-exit-target) | 1228 // c) [ test ] -> (body-entry-target, loop-exit-target) |
| 1203 // d) body-entry-target | 1229 // d) body-entry-target |
| 1204 // e) [ body ] | 1230 // e) [ body ] |
| 1205 // f) continue-join (optional) | 1231 // f) continue-join (optional) |
| 1206 // g) [ increment ] -> (loop-join) | 1232 // g) [ increment ] -> (loop-join) |
| 1207 // h) loop-exit-target | 1233 // h) loop-exit-target |
| 1208 // i) break-join | 1234 // i) break-join |
| 1209 void EffectGraphVisitor::VisitForNode(ForNode* node) { | 1235 void EffectGraphVisitor::VisitForNode(ForNode* node) { |
| 1210 EffectGraphVisitor for_initializer(owner(), temp_index()); | 1236 EffectGraphVisitor for_initializer(owner(), temp_index()); |
| 1211 node->initializer()->Visit(&for_initializer); | 1237 node->initializer()->Visit(&for_initializer); |
| 1212 Append(for_initializer); | 1238 Append(for_initializer); |
| 1213 ASSERT(is_open()); | 1239 ASSERT(is_open()); |
| 1214 | 1240 |
| 1215 // Compose body to set any jump labels. | 1241 // Compose body to set any jump labels. |
| 1216 EffectGraphVisitor for_body(owner(), temp_index()); | 1242 EffectGraphVisitor for_body(owner(), temp_index()); |
| 1217 TargetEntryInstr* body_entry = new TargetEntryInstr(); | 1243 TargetEntryInstr* body_entry = new TargetEntryInstr(); |
| 1218 for_body.AddInstruction(body_entry); | 1244 for_body.AddBlockEntry(body_entry); |
| 1219 CheckStackOverflowComp* comp = | 1245 CheckStackOverflowComp* comp = |
| 1220 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()); | 1246 new CheckStackOverflowComp(node->token_pos(), owner()->try_index()); |
| 1221 for_body.AddInstruction(new DoInstr(comp)); | 1247 for_body.AddInstruction(new DoInstr(comp)); |
| 1222 node->body()->Visit(&for_body); | 1248 node->body()->Visit(&for_body); |
| 1223 | 1249 |
| 1224 // Join loop body, increment and compute their end instruction. | 1250 // Join loop body, increment and compute their end instruction. |
| 1225 ASSERT(!for_body.is_empty()); | 1251 ASSERT(!for_body.is_empty()); |
| 1226 Instruction* loop_increment_end = NULL; | 1252 Instruction* loop_increment_end = NULL; |
| 1227 EffectGraphVisitor for_increment(owner(), temp_index()); | 1253 EffectGraphVisitor for_increment(owner(), temp_index()); |
| 1228 if ((node->label()->join_for_continue() == NULL) && for_body.is_open()) { | 1254 if ((node->label()->join_for_continue() == NULL) && for_body.is_open()) { |
| 1229 // Do not insert an extra basic block. | 1255 // Do not insert an extra basic block. |
| 1230 node->increment()->Visit(&for_increment); | 1256 node->increment()->Visit(&for_increment); |
| 1231 for_body.Append(for_increment); | 1257 for_body.Append(for_increment); |
| 1232 loop_increment_end = for_body.exit(); | 1258 loop_increment_end = for_body.exit(); |
| 1233 // 'for_body' contains at least the TargetInstruction 'body_entry'. | 1259 // 'for_body' contains at least the TargetInstruction 'body_entry'. |
| 1234 ASSERT(loop_increment_end != NULL); | 1260 ASSERT(loop_increment_end != NULL); |
| 1235 } else if (node->label()->join_for_continue() != NULL) { | 1261 } else if (node->label()->join_for_continue() != NULL) { |
| 1236 // Insert join between body and increment. | 1262 // Insert join between body and increment. |
| 1237 if (for_body.is_open()) { | 1263 if (for_body.is_open()) { |
| 1238 for_body.exit()->SetSuccessor(node->label()->join_for_continue()); | 1264 for_body.exit()->SetSuccessor( |
| 1265 new GotoInstr(node->label()->join_for_continue())); |
| 1239 } | 1266 } |
| 1240 for_increment.AddInstruction(node->label()->join_for_continue()); | 1267 for_increment.AddBlockEntry(node->label()->join_for_continue()); |
| 1241 node->increment()->Visit(&for_increment); | 1268 node->increment()->Visit(&for_increment); |
| 1242 loop_increment_end = for_increment.exit(); | 1269 loop_increment_end = for_increment.exit(); |
| 1243 ASSERT(loop_increment_end != NULL); | 1270 ASSERT(loop_increment_end != NULL); |
| 1244 } else { | 1271 } else { |
| 1245 loop_increment_end = NULL; | 1272 loop_increment_end = NULL; |
| 1246 ASSERT(!for_body.is_open() && node->label()->join_for_continue() == NULL); | 1273 ASSERT(!for_body.is_open() && node->label()->join_for_continue() == NULL); |
| 1247 } | 1274 } |
| 1248 | 1275 |
| 1249 // 'loop_increment_end' is NULL only if there is no join for continue and the | 1276 // 'loop_increment_end' is NULL only if there is no join for continue and the |
| 1250 // body is not open, i.e., no backward branch exists. | 1277 // body is not open, i.e., no backward branch exists. |
| 1251 if (loop_increment_end != NULL) { | 1278 if (loop_increment_end != NULL) { |
| 1252 JoinEntryInstr* loop_start = new JoinEntryInstr(); | 1279 JoinEntryInstr* loop_start = new JoinEntryInstr(); |
| 1253 AddInstruction(loop_start); | 1280 AddInstruction(new GotoInstr(loop_start)); |
| 1254 loop_increment_end->SetSuccessor(loop_start); | 1281 AddBlockEntry(loop_start); |
| 1282 loop_increment_end->SetSuccessor(new GotoInstr(loop_start)); |
| 1255 } | 1283 } |
| 1256 | 1284 |
| 1257 if (node->condition() == NULL) { | 1285 if (node->condition() == NULL) { |
| 1258 // Endless loop, no test. | 1286 // Endless loop, no test. |
| 1259 Append(for_body); | 1287 Append(for_body); |
| 1260 if (node->label()->join_for_break() == NULL) { | 1288 if (node->label()->join_for_break() == NULL) { |
| 1261 CloseFragment(); | 1289 CloseFragment(); |
| 1262 } else { | 1290 } else { |
| 1263 // Control flow of ForLoop continues into join_for_break. | 1291 // Control flow of ForLoop continues into join_for_break. |
| 1264 exit_ = node->label()->join_for_break(); | 1292 exit_ = node->label()->join_for_break(); |
| 1265 } | 1293 } |
| 1266 } else { | 1294 } else { |
| 1267 TargetEntryInstr* loop_exit = new TargetEntryInstr(); | 1295 TargetEntryInstr* loop_exit = new TargetEntryInstr(); |
| 1268 TestGraphVisitor for_test(owner(), | 1296 TestGraphVisitor for_test(owner(), |
| 1269 temp_index(), | 1297 temp_index(), |
| 1270 node->condition()->token_pos()); | 1298 node->condition()->token_pos()); |
| 1271 node->condition()->Visit(&for_test); | 1299 node->condition()->Visit(&for_test); |
| 1272 Append(for_test); | 1300 Append(for_test); |
| 1273 *for_test.true_successor_address() = body_entry; | 1301 *for_test.true_successor_address() = body_entry; |
| 1274 *for_test.false_successor_address() = loop_exit; | 1302 *for_test.false_successor_address() = loop_exit; |
| 1275 if (node->label()->join_for_break() == NULL) { | 1303 if (node->label()->join_for_break() == NULL) { |
| 1276 exit_ = loop_exit; | 1304 exit_ = loop_exit; |
| 1277 } else { | 1305 } else { |
| 1278 loop_exit->SetSuccessor(node->label()->join_for_break()); | 1306 loop_exit->SetSuccessor(new GotoInstr(node->label()->join_for_break())); |
| 1279 exit_ = node->label()->join_for_break(); | 1307 exit_ = node->label()->join_for_break(); |
| 1280 } | 1308 } |
| 1281 } | 1309 } |
| 1282 } | 1310 } |
| 1283 | 1311 |
| 1284 | 1312 |
| 1285 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { | 1313 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { |
| 1286 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 1314 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 1287 EffectGraphVisitor for_effect(owner(), temp_index()); | 1315 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 1288 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 1316 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1311 target_context_level = target_scope->context_level(); | 1339 target_context_level = target_scope->context_level(); |
| 1312 } | 1340 } |
| 1313 } | 1341 } |
| 1314 ASSERT(target_context_level >= 0); | 1342 ASSERT(target_context_level >= 0); |
| 1315 intptr_t current_context_level = owner()->context_level(); | 1343 intptr_t current_context_level = owner()->context_level(); |
| 1316 ASSERT(current_context_level >= target_context_level); | 1344 ASSERT(current_context_level >= target_context_level); |
| 1317 while (current_context_level-- > target_context_level) { | 1345 while (current_context_level-- > target_context_level) { |
| 1318 UnchainContext(); | 1346 UnchainContext(); |
| 1319 } | 1347 } |
| 1320 | 1348 |
| 1321 Instruction* jump_target = NULL; | 1349 BlockEntryInstr* jump_target = NULL; |
| 1322 if (node->kind() == Token::kBREAK) { | 1350 if (node->kind() == Token::kBREAK) { |
| 1323 if (node->label()->join_for_break() == NULL) { | 1351 if (node->label()->join_for_break() == NULL) { |
| 1324 node->label()->set_join_for_break(new JoinEntryInstr()); | 1352 node->label()->set_join_for_break(new JoinEntryInstr()); |
| 1325 } | 1353 } |
| 1326 jump_target = node->label()->join_for_break(); | 1354 jump_target = node->label()->join_for_break(); |
| 1327 } else { | 1355 } else { |
| 1328 if (node->label()->join_for_continue() == NULL) { | 1356 if (node->label()->join_for_continue() == NULL) { |
| 1329 node->label()->set_join_for_continue(new JoinEntryInstr()); | 1357 node->label()->set_join_for_continue(new JoinEntryInstr()); |
| 1330 } | 1358 } |
| 1331 jump_target = node->label()->join_for_continue(); | 1359 jump_target = node->label()->join_for_continue(); |
| 1332 } | 1360 } |
| 1333 AddInstruction(jump_target); | 1361 AddInstruction(new GotoInstr(jump_target)); |
| 1362 AddBlockEntry(jump_target); |
| 1334 CloseFragment(); | 1363 CloseFragment(); |
| 1335 } | 1364 } |
| 1336 | 1365 |
| 1337 | 1366 |
| 1338 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { | 1367 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { |
| 1339 UNREACHABLE(); | 1368 UNREACHABLE(); |
| 1340 } | 1369 } |
| 1341 | 1370 |
| 1342 | 1371 |
| 1343 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 1372 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| (...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2219 } | 2248 } |
| 2220 | 2249 |
| 2221 // No continue on sequence allowed. | 2250 // No continue on sequence allowed. |
| 2222 ASSERT((node->label() == NULL) || | 2251 ASSERT((node->label() == NULL) || |
| 2223 (node->label()->join_for_continue() == NULL)); | 2252 (node->label()->join_for_continue() == NULL)); |
| 2224 // If this node sequence is labeled, a break out of the sequence will have | 2253 // If this node sequence is labeled, a break out of the sequence will have |
| 2225 // taken care of unchaining the context. | 2254 // taken care of unchaining the context. |
| 2226 if ((node->label() != NULL) && | 2255 if ((node->label() != NULL) && |
| 2227 (node->label()->join_for_break() != NULL)) { | 2256 (node->label()->join_for_break() != NULL)) { |
| 2228 if (is_open()) { | 2257 if (is_open()) { |
| 2229 AddInstruction(node->label()->join_for_break()); | 2258 AddInstruction(new GotoInstr(node->label()->join_for_break())); |
| 2259 AddBlockEntry(node->label()->join_for_break()); |
| 2230 } else { | 2260 } else { |
| 2231 exit_ = node->label()->join_for_break(); | 2261 exit_ = node->label()->join_for_break(); |
| 2232 } | 2262 } |
| 2233 } | 2263 } |
| 2234 | 2264 |
| 2235 // The outermost function sequence cannot contain a label. | 2265 // The outermost function sequence cannot contain a label. |
| 2236 ASSERT((node->label() == NULL) || | 2266 ASSERT((node->label() == NULL) || |
| 2237 (node != owner()->parsed_function().node_sequence())); | 2267 (node != owner()->parsed_function().node_sequence())); |
| 2238 owner()->set_context_level(previous_context_level); | 2268 owner()->set_context_level(previous_context_level); |
| 2239 } | 2269 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2270 owner()->set_try_index(old_try_index); | 2300 owner()->set_try_index(old_try_index); |
| 2271 | 2301 |
| 2272 CatchClauseNode* catch_block = node->catch_block(); | 2302 CatchClauseNode* catch_block = node->catch_block(); |
| 2273 if (catch_block != NULL) { | 2303 if (catch_block != NULL) { |
| 2274 // Set the corresponding try index for this catch block so | 2304 // Set the corresponding try index for this catch block so |
| 2275 // that we can set the appropriate handler pc when we generate | 2305 // that we can set the appropriate handler pc when we generate |
| 2276 // code for this catch block. | 2306 // code for this catch block. |
| 2277 catch_block->set_try_index(try_index); | 2307 catch_block->set_try_index(try_index); |
| 2278 EffectGraphVisitor for_catch_block(owner(), temp_index()); | 2308 EffectGraphVisitor for_catch_block(owner(), temp_index()); |
| 2279 TargetEntryInstr* catch_entry = new TargetEntryInstr(try_index); | 2309 TargetEntryInstr* catch_entry = new TargetEntryInstr(try_index); |
| 2280 for_catch_block.AddInstruction(catch_entry); | 2310 for_catch_block.AddBlockEntry(catch_entry); |
| 2281 catch_block->Visit(&for_catch_block); | 2311 catch_block->Visit(&for_catch_block); |
| 2282 owner()->AddCatchEntry(catch_entry); | 2312 owner()->AddCatchEntry(catch_entry); |
| 2283 ASSERT(!for_catch_block.is_open()); | 2313 ASSERT(!for_catch_block.is_open()); |
| 2284 if ((node->end_catch_label() != NULL) && | 2314 if ((node->end_catch_label() != NULL) && |
| 2285 (node->end_catch_label()->join_for_continue() != NULL)) { | 2315 (node->end_catch_label()->join_for_continue() != NULL)) { |
| 2286 if (is_open()) { | 2316 if (is_open()) { |
| 2287 AddInstruction(node->end_catch_label()->join_for_continue()); | 2317 AddInstruction( |
| 2318 new GotoInstr(node->end_catch_label()->join_for_continue())); |
| 2319 AddBlockEntry(node->end_catch_label()->join_for_continue()); |
| 2288 } else { | 2320 } else { |
| 2289 exit_ = node->end_catch_label()->join_for_continue(); | 2321 exit_ = node->end_catch_label()->join_for_continue(); |
| 2290 } | 2322 } |
| 2291 } | 2323 } |
| 2292 } | 2324 } |
| 2293 | 2325 |
| 2294 // Generate code for the finally block if one exists. | 2326 // Generate code for the finally block if one exists. |
| 2295 if ((node->finally_block() != NULL) && is_open()) { | 2327 if ((node->finally_block() != NULL) && is_open()) { |
| 2296 EffectGraphVisitor for_finally_block(owner(), temp_index()); | 2328 EffectGraphVisitor for_finally_block(owner(), temp_index()); |
| 2297 node->finally_block()->Visit(&for_finally_block); | 2329 node->finally_block()->Visit(&for_finally_block); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2358 void FlowGraphBuilder::BuildGraph(bool for_optimized, bool use_ssa) { | 2390 void FlowGraphBuilder::BuildGraph(bool for_optimized, bool use_ssa) { |
| 2359 if (FLAG_print_ast) { | 2391 if (FLAG_print_ast) { |
| 2360 // Print the function ast before IL generation. | 2392 // Print the function ast before IL generation. |
| 2361 AstPrinter::PrintFunctionNodes(parsed_function()); | 2393 AstPrinter::PrintFunctionNodes(parsed_function()); |
| 2362 } | 2394 } |
| 2363 // Compilation can be nested, preserve the computation-id. | 2395 // Compilation can be nested, preserve the computation-id. |
| 2364 const Function& function = parsed_function().function(); | 2396 const Function& function = parsed_function().function(); |
| 2365 TargetEntryInstr* normal_entry = new TargetEntryInstr(); | 2397 TargetEntryInstr* normal_entry = new TargetEntryInstr(); |
| 2366 graph_entry_ = new GraphEntryInstr(normal_entry); | 2398 graph_entry_ = new GraphEntryInstr(normal_entry); |
| 2367 EffectGraphVisitor for_effect(this, 0); | 2399 EffectGraphVisitor for_effect(this, 0); |
| 2368 for_effect.AddInstruction(normal_entry); | 2400 for_effect.AddBlockEntry(normal_entry); |
| 2369 parsed_function().node_sequence()->Visit(&for_effect); | 2401 parsed_function().node_sequence()->Visit(&for_effect); |
| 2370 // Check that the graph is properly terminated. | 2402 // Check that the graph is properly terminated. |
| 2371 ASSERT(!for_effect.is_open()); | 2403 ASSERT(!for_effect.is_open()); |
| 2372 GrowableArray<intptr_t> parent; | 2404 GrowableArray<intptr_t> parent; |
| 2373 GrowableArray<BitVector*> assigned_vars; | 2405 GrowableArray<BitVector*> assigned_vars; |
| 2374 intptr_t variable_count = parsed_function_.function().num_fixed_parameters() + | 2406 intptr_t variable_count = parsed_function_.function().num_fixed_parameters() + |
| 2375 parsed_function_.copied_parameter_count() + | 2407 parsed_function_.copied_parameter_count() + |
| 2376 parsed_function_.stack_local_count(); | 2408 parsed_function_.stack_local_count(); |
| 2377 // Perform a depth-first traversal of the graph to build preorder and | 2409 // Perform a depth-first traversal of the graph to build preorder and |
| 2378 // postorder block orders. | 2410 // postorder block orders. |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2767 char* chars = reinterpret_cast<char*>( | 2799 char* chars = reinterpret_cast<char*>( |
| 2768 Isolate::Current()->current_zone()->Allocate(len)); | 2800 Isolate::Current()->current_zone()->Allocate(len)); |
| 2769 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2801 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2770 const Error& error = Error::Handle( | 2802 const Error& error = Error::Handle( |
| 2771 LanguageError::New(String::Handle(String::New(chars)))); | 2803 LanguageError::New(String::Handle(String::New(chars)))); |
| 2772 Isolate::Current()->long_jump_base()->Jump(1, error); | 2804 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2773 } | 2805 } |
| 2774 | 2806 |
| 2775 | 2807 |
| 2776 } // namespace dart | 2808 } // namespace dart |
| OLD | NEW |