Chromium Code Reviews| 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/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 159 const AbstractType& type = | 159 const AbstractType& type = |
| 160 AbstractType::ZoneHandle( | 160 AbstractType::ZoneHandle( |
| 161 owner()->parsed_function().function().result_type()); | 161 owner()->parsed_function().function().result_type()); |
| 162 AssertAssignableComp* assert = | 162 AssertAssignableComp* assert = |
| 163 new AssertAssignableComp(return_value, type); | 163 new AssertAssignableComp(return_value, type); |
| 164 AddInstruction(new BindInstr(temp_index(), assert)); | 164 AddInstruction(new BindInstr(temp_index(), assert)); |
| 165 return_value = new TempVal(temp_index()); | 165 return_value = new TempVal(temp_index()); |
| 166 } | 166 } |
| 167 } | 167 } |
| 168 | 168 |
| 169 intptr_t current_context_level = owner()->context_level(); | |
| 170 ASSERT(current_context_level >= 0); | |
| 171 if (owner()->parsed_function().saved_context_var() != NULL) { | |
| 172 // CTX on entry was saved, but not linked as context parent. | |
| 173 LoadLocalComp* load_comp = | |
| 174 new LoadLocalComp(*owner()->parsed_function().saved_context_var(), 0); | |
| 175 AddInstruction(new BindInstr(temp_index(), load_comp)); | |
| 176 TempVal* local_value = new TempVal(temp_index()); | |
| 177 StoreContextComp* store_context = new StoreContextComp(local_value); | |
| 178 AddInstruction(new DoInstr(store_context)); | |
| 179 } else { | |
| 180 while (current_context_level-- > 0) { | |
| 181 UnchainContext(); | |
| 182 } | |
| 183 } | |
| 184 | |
| 185 | |
| 169 AddInstruction(new ReturnInstr(return_value, node->token_index())); | 186 AddInstruction(new ReturnInstr(return_value, node->token_index())); |
| 170 CloseFragment(); | 187 CloseFragment(); |
| 171 } | 188 } |
| 172 | 189 |
| 173 | 190 |
| 174 // <Expression> ::= Literal { literal: Instance } | 191 // <Expression> ::= Literal { literal: Instance } |
| 175 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { | 192 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { |
| 176 return; | 193 return; |
| 177 } | 194 } |
| 178 | 195 |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 380 ReturnComputation(call); | 397 ReturnComputation(call); |
| 381 } | 398 } |
| 382 | 399 |
| 383 | 400 |
| 384 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { | 401 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { |
| 385 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 402 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 386 // In an effect context, treat postincrement as if it were preincrement | 403 // In an effect context, treat postincrement as if it were preincrement |
| 387 // because its value is not needed. | 404 // because its value is not needed. |
| 388 | 405 |
| 389 // 1. Load the value. | 406 // 1. Load the value. |
| 390 LoadLocalComp* load = new LoadLocalComp(node->local()); | 407 LoadLocalComp* load = new LoadLocalComp(node->local(), |
| 408 owner()->context_level()); | |
| 391 AddInstruction(new BindInstr(temp_index(), load)); | 409 AddInstruction(new BindInstr(temp_index(), load)); |
| 392 // 2. Increment. | 410 // 2. Increment. |
| 393 BuildIncrOpIncrement(node->kind(), node->id(), node->token_index(), | 411 BuildIncrOpIncrement(node->kind(), node->id(), node->token_index(), |
| 394 temp_index() + 1); | 412 temp_index() + 1); |
| 395 // 3. Perform the store, resulting in the new value. | 413 // 3. Perform the store, resulting in the new value. |
| 396 StoreLocalComp* store = | 414 StoreLocalComp* store = new StoreLocalComp( |
| 397 new StoreLocalComp(node->local(), new TempVal(temp_index())); | 415 node->local(), new TempVal(temp_index()), owner()->context_level()); |
| 398 ReturnComputation(store); | 416 ReturnComputation(store); |
| 399 } | 417 } |
| 400 | 418 |
| 401 | 419 |
| 402 void ValueGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { | 420 void ValueGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { |
| 403 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 421 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 404 if (node->prefix()) { | 422 if (node->prefix()) { |
| 405 // Base class handles preincrement. | 423 // Base class handles preincrement. |
| 406 EffectGraphVisitor::VisitIncrOpLocalNode(node); | 424 EffectGraphVisitor::VisitIncrOpLocalNode(node); |
| 407 return; | 425 return; |
| 408 } | 426 } |
| 409 // For postincrement, duplicate the original value to use one copy as the | 427 // For postincrement, duplicate the original value to use one copy as the |
| 410 // result. | 428 // result. |
| 411 // | 429 // |
| 412 // 1. Load the value. | 430 // 1. Load the value. |
| 413 LoadLocalComp* load = new LoadLocalComp(node->local()); | 431 LoadLocalComp* load = new LoadLocalComp(node->local(), |
| 432 owner()->context_level()); | |
| 414 AddInstruction(new BindInstr(temp_index(), load)); | 433 AddInstruction(new BindInstr(temp_index(), load)); |
| 415 // 2. Duplicate it to increment. | 434 // 2. Duplicate it to increment. |
| 416 AddInstruction(new PickTempInstr(temp_index() + 1, temp_index())); | 435 AddInstruction(new PickTempInstr(temp_index() + 1, temp_index())); |
| 417 // 3. Increment. | 436 // 3. Increment. |
| 418 BuildIncrOpIncrement(node->kind(), node->id(), node->token_index(), | 437 BuildIncrOpIncrement(node->kind(), node->id(), node->token_index(), |
| 419 temp_index() + 2); | 438 temp_index() + 2); |
| 420 // 4. Perform the store and return the original value. | 439 // 4. Perform the store and return the original value. |
| 421 StoreLocalComp* store = | 440 StoreLocalComp* store = new StoreLocalComp( |
| 422 new StoreLocalComp(node->local(), new TempVal(temp_index() + 1)); | 441 node->local(), new TempVal(temp_index() + 1), owner()->context_level()); |
| 423 AddInstruction(new DoInstr(store)); | 442 AddInstruction(new DoInstr(store)); |
| 424 ReturnValue(new TempVal(AllocateTempIndex())); | 443 ReturnValue(new TempVal(AllocateTempIndex())); |
| 425 } | 444 } |
| 426 | 445 |
| 427 | 446 |
| 428 int EffectGraphVisitor::BuildIncrOpFieldLoad(IncrOpInstanceFieldNode* node, | 447 int EffectGraphVisitor::BuildIncrOpFieldLoad(IncrOpInstanceFieldNode* node, |
| 429 intptr_t start_index) { | 448 intptr_t start_index) { |
| 430 // Evaluate the receiver and duplicate it (it has two uses). | 449 // Evaluate the receiver and duplicate it (it has two uses). |
| 431 // t_n <- ... receiver ... | 450 // t_n <- ... receiver ... |
| 432 // t_n+1 <- Pick(t_n) | 451 // t_n+1 <- Pick(t_n) |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 718 | 737 |
| 719 if (body_exit != NULL) { | 738 if (body_exit != NULL) { |
| 720 TargetEntryInstr* target_entry = new TargetEntryInstr(); | 739 TargetEntryInstr* target_entry = new TargetEntryInstr(); |
| 721 target_entry->SetSuccessor(for_test.entry()); | 740 target_entry->SetSuccessor(for_test.entry()); |
| 722 body_exit->SetSuccessor(target_entry); | 741 body_exit->SetSuccessor(target_entry); |
| 723 } | 742 } |
| 724 | 743 |
| 725 TargetEntryInstr* back_target_entry = new TargetEntryInstr(); | 744 TargetEntryInstr* back_target_entry = new TargetEntryInstr(); |
| 726 *for_test.true_successor_address() = back_target_entry; | 745 *for_test.true_successor_address() = back_target_entry; |
| 727 back_target_entry->SetSuccessor(join); | 746 back_target_entry->SetSuccessor(join); |
| 728 exit_ = *for_test.false_successor_address() = new TargetEntryInstr(); | 747 exit_ = |
| 748 *for_test.false_successor_address() = new TargetEntryInstr(); | |
| 729 } | 749 } |
| 730 | 750 |
| 731 | 751 |
| 732 void EffectGraphVisitor::VisitForNode(ForNode* node) { | 752 void EffectGraphVisitor::VisitForNode(ForNode* node) { |
| 733 EffectGraphVisitor for_initializer(owner(), temp_index()); | 753 EffectGraphVisitor for_initializer(owner(), temp_index()); |
| 734 node->initializer()->Visit(&for_initializer); | 754 node->initializer()->Visit(&for_initializer); |
| 735 Append(for_initializer); | 755 Append(for_initializer); |
| 736 ASSERT(is_open()); | 756 ASSERT(is_open()); |
| 737 | 757 |
| 738 EffectGraphVisitor for_body(owner(), temp_index()); | 758 EffectGraphVisitor for_body(owner(), temp_index()); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 793 CreateArrayComp* create = new CreateArrayComp(node, values); | 813 CreateArrayComp* create = new CreateArrayComp(node, values); |
| 794 ReturnComputation(create); | 814 ReturnComputation(create); |
| 795 } | 815 } |
| 796 | 816 |
| 797 | 817 |
| 798 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { | 818 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
| 799 const Function& function = node->function(); | 819 const Function& function = node->function(); |
| 800 | 820 |
| 801 int next_index = temp_index(); | 821 int next_index = temp_index(); |
| 802 if (function.IsNonImplicitClosureFunction()) { | 822 if (function.IsNonImplicitClosureFunction()) { |
| 803 const int context_level = 0; // Only because we don't handle nesting yet. | |
| 804 const ContextScope& context_scope = ContextScope::ZoneHandle( | 823 const ContextScope& context_scope = ContextScope::ZoneHandle( |
| 805 node->scope()->PreserveOuterScope(context_level)); | 824 node->scope()->PreserveOuterScope(owner()->context_level())); |
| 806 ASSERT(!function.HasCode()); | 825 ASSERT(!function.HasCode()); |
| 807 ASSERT(function.context_scope() == ContextScope::null()); | 826 ASSERT(function.context_scope() == ContextScope::null()); |
| 808 function.set_context_scope(context_scope); | 827 function.set_context_scope(context_scope); |
| 809 } else if (function.IsImplicitInstanceClosureFunction()) { | 828 } else if (function.IsImplicitInstanceClosureFunction()) { |
| 810 ValueGraphVisitor for_receiver(owner(), temp_index()); | 829 ValueGraphVisitor for_receiver(owner(), temp_index()); |
| 811 node->receiver()->Visit(&for_receiver); | 830 node->receiver()->Visit(&for_receiver); |
| 812 Append(for_receiver); | 831 Append(for_receiver); |
| 813 if (!for_receiver.value()->IsTemp()) { | 832 if (!for_receiver.value()->IsTemp()) { |
| 814 AddInstruction(new BindInstr(temp_index(), for_receiver.value())); | 833 AddInstruction(new BindInstr(temp_index(), for_receiver.value())); |
| 815 } | 834 } |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1149 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { | 1168 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { |
| 1150 Bailout("EffectGraphVisitor::VisitPrimaryNode"); | 1169 Bailout("EffectGraphVisitor::VisitPrimaryNode"); |
| 1151 } | 1170 } |
| 1152 | 1171 |
| 1153 | 1172 |
| 1154 // <Expression> ::= LoadLocal { local: LocalVariable } | 1173 // <Expression> ::= LoadLocal { local: LocalVariable } |
| 1155 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 1174 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 1156 return; | 1175 return; |
| 1157 } | 1176 } |
| 1158 | 1177 |
| 1178 | |
| 1159 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 1179 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 1160 LoadLocalComp* load = new LoadLocalComp(node->local()); | 1180 LoadLocalComp* load = new LoadLocalComp(node->local(), |
| 1181 owner()->context_level()); | |
| 1161 ReturnComputation(load); | 1182 ReturnComputation(load); |
| 1162 } | 1183 } |
| 1163 | 1184 |
| 1185 | |
| 1164 void TestGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { | 1186 void TestGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { |
| 1165 LoadLocalComp* load = new LoadLocalComp(node->local()); | 1187 LoadLocalComp* load = new LoadLocalComp(node->local(), |
| 1188 owner()->context_level()); | |
| 1166 ReturnComputation(load); | 1189 ReturnComputation(load); |
| 1167 } | 1190 } |
| 1168 | 1191 |
| 1169 | 1192 |
| 1170 // <Expression> ::= StoreLocal { local: LocalVariable | 1193 // <Expression> ::= StoreLocal { local: LocalVariable |
| 1171 // value: <Expression> } | 1194 // value: <Expression> } |
| 1172 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { | 1195 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { |
| 1173 ValueGraphVisitor for_value(owner(), temp_index()); | 1196 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1174 node->value()->Visit(&for_value); | 1197 node->value()->Visit(&for_value); |
| 1175 Append(for_value); | 1198 Append(for_value); |
| 1176 | 1199 |
| 1177 Value* value = for_value.value(); | 1200 Value* value = for_value.value(); |
| 1178 if (FLAG_enable_type_checks) { | 1201 if (FLAG_enable_type_checks) { |
| 1179 AssertAssignableComp* assert = | 1202 AssertAssignableComp* assert = |
| 1180 new AssertAssignableComp(value, node->local().type()); | 1203 new AssertAssignableComp(value, node->local().type()); |
| 1181 AddInstruction(new BindInstr(temp_index(), assert)); | 1204 AddInstruction(new BindInstr(temp_index(), assert)); |
| 1182 value = new TempVal(temp_index()); | 1205 value = new TempVal(temp_index()); |
| 1183 } | 1206 } |
| 1184 | 1207 |
| 1185 StoreLocalComp* store = new StoreLocalComp(node->local(), value); | 1208 StoreLocalComp* store = |
| 1209 new StoreLocalComp(node->local(), value, owner()->context_level()); | |
| 1186 ReturnComputation(store); | 1210 ReturnComputation(store); |
| 1187 } | 1211 } |
| 1188 | 1212 |
| 1189 | 1213 |
| 1190 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 1214 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| 1191 LoadInstanceFieldNode* node) { | 1215 LoadInstanceFieldNode* node) { |
| 1192 ValueGraphVisitor for_instance(owner(), temp_index()); | 1216 ValueGraphVisitor for_instance(owner(), temp_index()); |
| 1193 node->instance()->Visit(&for_instance); | 1217 node->instance()->Visit(&for_instance); |
| 1194 Append(for_instance); | 1218 Append(for_instance); |
| 1195 LoadInstanceFieldComp* load = | 1219 LoadInstanceFieldComp* load = |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1273 Append(for_value); | 1297 Append(for_value); |
| 1274 StoreIndexedComp* store = new StoreIndexedComp(node->id(), | 1298 StoreIndexedComp* store = new StoreIndexedComp(node->id(), |
| 1275 node->token_index(), | 1299 node->token_index(), |
| 1276 for_array.value(), | 1300 for_array.value(), |
| 1277 for_index.value(), | 1301 for_index.value(), |
| 1278 for_value.value()); | 1302 for_value.value()); |
| 1279 ReturnComputation(store); | 1303 ReturnComputation(store); |
| 1280 } | 1304 } |
| 1281 | 1305 |
| 1282 | 1306 |
| 1307 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { | |
| 1308 return (node == owner()->parsed_function().node_sequence()) && | |
| 1309 (owner()->parsed_function().saved_context_var() != NULL); | |
| 1310 } | |
| 1311 | |
| 1312 | |
| 1313 void EffectGraphVisitor::UnchainContext() { | |
| 1314 AddInstruction(new BindInstr(temp_index(), new CurrentContextComp())); | |
| 1315 TempVal* temp_ctx = new TempVal(temp_index()); | |
| 1316 NativeLoadFieldComp* load = new NativeLoadFieldComp( | |
| 1317 temp_ctx, Context::parent_offset()); | |
| 1318 AddInstruction(new BindInstr(temp_index(), load)); | |
| 1319 TempVal* parent_ctx = new TempVal(temp_index()); | |
| 1320 AddInstruction(new DoInstr(new StoreContextComp(parent_ctx))); | |
| 1321 } | |
| 1322 | |
| 1323 | |
| 1283 // <Statement> ::= Sequence { scope: LocalScope | 1324 // <Statement> ::= Sequence { scope: LocalScope |
| 1284 // nodes: <Statement>* | 1325 // nodes: <Statement>* |
| 1285 // label: SourceLabel } | 1326 // label: SourceLabel } |
| 1286 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { | 1327 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
| 1287 LocalScope* scope = node->scope(); | 1328 LocalScope* scope = node->scope(); |
| 1288 const intptr_t num_context_variables = | 1329 const intptr_t num_context_variables = |
| 1289 (scope != NULL) ? scope->num_context_variables() : 0; | 1330 (scope != NULL) ? scope->num_context_variables() : 0; |
| 1290 int previous_context_level = owner()->context_level(); | 1331 int previous_context_level = owner()->context_level(); |
| 1291 if (num_context_variables > 0) { | 1332 if (num_context_variables > 0) { |
| 1292 // The loop local scope declares variables that are captured. | 1333 // The loop local scope declares variables that are captured. |
| 1293 // Allocate and chain a new context. | 1334 // Allocate and chain a new context. |
| 1294 // Allocate context computation. | 1335 // Allocate context computation (uses current CTX) |
| 1295 // Chain Context computation (maybe introduce a new variable). | 1336 AllocateContextComp* comp = new AllocateContextComp(node->token_index(), |
| 1296 Bailout("Sequence needs a context. Gotta have a context."); | 1337 num_context_variables); |
| 1338 AddInstruction(new BindInstr(temp_index(), comp)); | |
| 1339 Value* allocated_context_value = new TempVal(temp_index()); | |
| 1340 | |
| 1341 // If this node_sequence is the body of the function being compiled, and if | |
| 1342 // this function is not a closure, do not link the current context as the | |
| 1343 // parent of the newly allocated context, as it is not accessible. Instead, | |
| 1344 // save it in a pre-allocated variable and restore it on exit. | |
| 1345 if (MustSaveRestoreContext(node)) { | |
| 1346 AddInstruction(new BindInstr(temp_index() + 1, new CurrentContextComp())); | |
| 1347 StoreLocalComp* store_local = new StoreLocalComp( | |
| 1348 *owner()->parsed_function().saved_context_var(), | |
| 1349 new TempVal(temp_index() + 1), | |
| 1350 0); | |
| 1351 AddInstruction(new DoInstr(store_local)); | |
| 1352 StoreContextComp* store_context = | |
| 1353 new StoreContextComp(new ConstantVal(Object::ZoneHandle())); | |
| 1354 AddInstruction(new DoInstr(store_context)); | |
| 1355 } | |
| 1356 | |
| 1357 ChainContextComp* chain_context = new ChainContextComp( | |
| 1358 allocated_context_value); | |
| 1359 AddInstruction(new DoInstr(chain_context)); | |
| 1360 owner()->set_context_level(scope->context_level()); | |
| 1361 | |
| 1362 // If this node_sequence is the body of the function being compiled, copy | |
| 1363 // the captured parameters from the frame into the context. | |
| 1364 if (node == owner()->parsed_function().node_sequence()) { | |
| 1365 ASSERT(scope->context_level() == 1); | |
| 1366 const Immediate raw_null = | |
| 1367 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 1368 const Function& function = owner()->parsed_function().function(); | |
| 1369 const int num_params = function.NumberOfParameters(); | |
| 1370 int param_frame_index = | |
| 1371 (num_params == function.num_fixed_parameters()) ? 1 + num_params : -1; | |
| 1372 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { | |
| 1373 const LocalVariable& parameter = *scope->VariableAt(pos); | |
| 1374 ASSERT(parameter.owner() == scope); | |
| 1375 if (parameter.is_captured()) { | |
| 1376 // Create a temporary local describing the original position. | |
| 1377 const String& temp_name = String::ZoneHandle(String::Concat( | |
| 1378 parameter.name(), String::Handle(String::NewSymbol("-orig")))); | |
| 1379 LocalVariable* temp_local = new LocalVariable( | |
| 1380 0, // Token index. | |
| 1381 temp_name, | |
| 1382 Type::ZoneHandle(Type::DynamicType())); // Type. | |
| 1383 temp_local->set_index(param_frame_index); | |
| 1384 | |
| 1385 // Copy parameter from local frame to current context. | |
| 1386 LoadLocalComp* load_comp = new LoadLocalComp( | |
| 1387 *temp_local, owner()->context_level()); | |
| 1388 AddInstruction(new BindInstr(temp_index(), load_comp)); | |
| 1389 StoreLocalComp* store_local = new StoreLocalComp( | |
| 1390 parameter, | |
| 1391 new TempVal(temp_index()), | |
| 1392 owner()->context_level()); | |
| 1393 AddInstruction(new DoInstr(store_local)); | |
| 1394 // Write NULL to the source location to detect buggy accesses and | |
| 1395 // allow GC of passed value if it gets overwritten by a new value in | |
| 1396 // the function. | |
| 1397 StoreLocalComp* clear_local = new StoreLocalComp( | |
| 1398 *temp_local, | |
| 1399 new ConstantVal(Object::ZoneHandle()), | |
| 1400 owner()->context_level()); | |
| 1401 AddInstruction(new DoInstr(clear_local)); | |
| 1402 } | |
| 1403 } | |
| 1404 } | |
| 1297 } | 1405 } |
| 1298 | 1406 |
| 1299 if (FLAG_enable_type_checks && | 1407 if (FLAG_enable_type_checks && |
| 1300 (node == owner()->parsed_function().node_sequence())) { | 1408 (node == owner()->parsed_function().node_sequence())) { |
| 1301 Bailout("VisitSequenceNode GenerateArgumentTypeChecks()"); | 1409 Bailout("VisitSequenceNode GenerateArgumentTypeChecks()"); |
| 1302 } | 1410 } |
| 1303 | 1411 |
| 1304 intptr_t i = 0; | 1412 intptr_t i = 0; |
| 1305 while (is_open() && (i < node->length())) { | 1413 while (is_open() && (i < node->length())) { |
| 1306 EffectGraphVisitor for_effect(owner(), temp_index()); | 1414 EffectGraphVisitor for_effect(owner(), temp_index()); |
| 1307 node->NodeAt(i++)->Visit(&for_effect); | 1415 node->NodeAt(i++)->Visit(&for_effect); |
| 1308 Append(for_effect); | 1416 Append(for_effect); |
| 1309 } | 1417 } |
| 1418 | |
| 1419 if (is_open()) { | |
| 1420 if (MustSaveRestoreContext(node)) { | |
| 1421 ASSERT(num_context_variables > 0); | |
| 1422 LoadLocalComp* load_comp = | |
| 1423 new LoadLocalComp(*owner()->parsed_function().saved_context_var(), 0); | |
| 1424 AddInstruction(new BindInstr(temp_index(), load_comp)); | |
| 1425 TempVal* local_value = new TempVal(temp_index()); | |
| 1426 StoreContextComp* store_context = new StoreContextComp(local_value); | |
| 1427 AddInstruction(new DoInstr(store_context)); | |
| 1428 } else if (num_context_variables > 0) { | |
| 1429 UnchainContext(); | |
| 1430 } | |
| 1431 } | |
| 1432 | |
| 1433 // If this node sequence is labeled, a break out of the sequence will have | |
| 1434 // taken care of unchaining the context. | |
| 1435 if (node->label() != NULL) { | |
| 1436 // TODO(srdjan): Check that the break label is bound? Is this a jump? | |
| 1437 Bailout("VisitSequenceNode bind break and unchain CTX"); | |
| 1438 } | |
| 1310 owner()->set_context_level(previous_context_level); | 1439 owner()->set_context_level(previous_context_level); |
| 1311 } | 1440 } |
| 1312 | 1441 |
| 1313 | 1442 |
| 1314 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { | 1443 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
| 1315 Bailout("EffectGraphVisitor::VisitCatchClauseNode"); | 1444 Bailout("EffectGraphVisitor::VisitCatchClauseNode"); |
| 1316 } | 1445 } |
| 1317 | 1446 |
| 1318 | 1447 |
| 1319 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 1448 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1467 String::Handle(comp->function().name()).ToCString()); | 1596 String::Handle(comp->function().name()).ToCString()); |
| 1468 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) { | 1597 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) { |
| 1469 OS::Print(", "); | 1598 OS::Print(", "); |
| 1470 comp->ArgumentAt(i)->Accept(this); | 1599 comp->ArgumentAt(i)->Accept(this); |
| 1471 } | 1600 } |
| 1472 OS::Print(")"); | 1601 OS::Print(")"); |
| 1473 } | 1602 } |
| 1474 | 1603 |
| 1475 | 1604 |
| 1476 void FlowGraphPrinter::VisitLoadLocal(LoadLocalComp* comp) { | 1605 void FlowGraphPrinter::VisitLoadLocal(LoadLocalComp* comp) { |
| 1477 OS::Print("LoadLocal(%s)", comp->local().name().ToCString()); | 1606 OS::Print("LoadLocal(%s lvl:%d)", |
| 1607 comp->local().name().ToCString(), comp->context_level()); | |
| 1478 } | 1608 } |
| 1479 | 1609 |
| 1480 | 1610 |
| 1481 void FlowGraphPrinter::VisitStoreLocal(StoreLocalComp* comp) { | 1611 void FlowGraphPrinter::VisitStoreLocal(StoreLocalComp* comp) { |
| 1482 OS::Print("StoreLocal(%s, ", comp->local().name().ToCString()); | 1612 OS::Print("StoreLocal(%s, ", comp->local().name().ToCString()); |
| 1483 comp->value()->Accept(this); | 1613 comp->value()->Accept(this); |
| 1484 OS::Print(")"); | 1614 OS::Print(", lvl: %d)", comp->context_level()); |
| 1485 } | 1615 } |
| 1486 | 1616 |
| 1487 | 1617 |
| 1488 void FlowGraphPrinter::VisitNativeCall(NativeCallComp* comp) { | 1618 void FlowGraphPrinter::VisitNativeCall(NativeCallComp* comp) { |
| 1489 OS::Print("NativeCall(%s)", comp->native_name().ToCString()); | 1619 OS::Print("NativeCall(%s)", comp->native_name().ToCString()); |
| 1490 } | 1620 } |
| 1491 | 1621 |
| 1492 | 1622 |
| 1493 void FlowGraphPrinter::VisitLoadInstanceField(LoadInstanceFieldComp* comp) { | 1623 void FlowGraphPrinter::VisitLoadInstanceField(LoadInstanceFieldComp* comp) { |
| 1494 OS::Print("LoadInstanceField(%s, ", | 1624 OS::Print("LoadInstanceField(%s, ", |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1615 void FlowGraphPrinter::VisitExtractConstructorInstantiator( | 1745 void FlowGraphPrinter::VisitExtractConstructorInstantiator( |
| 1616 ExtractConstructorInstantiatorComp* comp) { | 1746 ExtractConstructorInstantiatorComp* comp) { |
| 1617 OS::Print("ExtractConstructorInstantiator("); | 1747 OS::Print("ExtractConstructorInstantiator("); |
| 1618 comp->instantiator()->Accept(this); | 1748 comp->instantiator()->Accept(this); |
| 1619 OS::Print(", "); | 1749 OS::Print(", "); |
| 1620 comp->discard_value()->Accept(this); | 1750 comp->discard_value()->Accept(this); |
| 1621 OS::Print(")"); | 1751 OS::Print(")"); |
| 1622 } | 1752 } |
| 1623 | 1753 |
| 1624 | 1754 |
| 1755 void FlowGraphPrinter::VisitAllocateContext(AllocateContextComp* comp) { | |
| 1756 OS::Print("AllocateContext(%d)", comp->num_context_variables()); | |
| 1757 } | |
| 1758 | |
| 1759 | |
| 1760 void FlowGraphPrinter::VisitChainContext(ChainContextComp* comp) { | |
| 1761 OS::Print("ChainContext("); | |
| 1762 comp->context_value()->Accept(this); | |
| 1763 OS::Print(")"); | |
| 1764 } | |
| 1765 | |
| 1766 | |
| 1767 void FlowGraphPrinter::VisitStoreContext(StoreContextComp* comp) { | |
| 1768 OS::Print("StoreContext("); | |
| 1769 comp->value()->Accept(this); | |
| 1770 OS::Print(")"); | |
| 1771 } | |
| 1772 | |
| 1773 | |
| 1625 void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) { | 1774 void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) { |
| 1626 OS::Print("%2d: [join]", reverse_index(instr->postorder_number())); | 1775 OS::Print("%2d: [join]", reverse_index(instr->postorder_number())); |
| 1627 } | 1776 } |
| 1628 | 1777 |
| 1629 | 1778 |
| 1630 void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) { | 1779 void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) { |
| 1631 OS::Print("%2d: [target]", reverse_index(instr->postorder_number())); | 1780 OS::Print("%2d: [target]", reverse_index(instr->postorder_number())); |
| 1632 } | 1781 } |
| 1633 | 1782 |
| 1634 | 1783 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1800 CompressPath(start_index, next_index, parent, label); | 1949 CompressPath(start_index, next_index, parent, label); |
| 1801 (*label)[current_index] = | 1950 (*label)[current_index] = |
| 1802 Utils::Minimum((*label)[current_index], (*label)[next_index]); | 1951 Utils::Minimum((*label)[current_index], (*label)[next_index]); |
| 1803 (*parent)[current_index] = (*parent)[next_index]; | 1952 (*parent)[current_index] = (*parent)[next_index]; |
| 1804 } | 1953 } |
| 1805 } | 1954 } |
| 1806 | 1955 |
| 1807 | 1956 |
| 1808 void FlowGraphBuilder::Bailout(const char* reason) { | 1957 void FlowGraphBuilder::Bailout(const char* reason) { |
| 1809 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; | 1958 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; |
| 1810 const char* function_name = parsed_function_.function().ToCString(); | 1959 const char* function_name = |
| 1960 parsed_function_.function().ToCString(); | |
|
regis
2012/03/23 20:50:25
New line not needed.
srdjan
2012/03/23 21:22:19
Done.
| |
| 1811 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 1961 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 1812 char* chars = reinterpret_cast<char*>( | 1962 char* chars = reinterpret_cast<char*>( |
| 1813 Isolate::Current()->current_zone()->Allocate(len)); | 1963 Isolate::Current()->current_zone()->Allocate(len)); |
| 1814 OS::SNPrint(chars, len, kFormat, function_name, reason); | 1964 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 1815 const Error& error = Error::Handle( | 1965 const Error& error = Error::Handle( |
| 1816 LanguageError::New(String::Handle(String::New(chars)))); | 1966 LanguageError::New(String::Handle(String::New(chars)))); |
| 1817 Isolate::Current()->long_jump_base()->Jump(1, error); | 1967 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 1818 } | 1968 } |
| 1819 | 1969 |
| 1820 | 1970 |
| 1821 } // namespace dart | 1971 } // namespace dart |
| OLD | NEW |