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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
752 } | 752 } |
753 | 753 |
754 | 754 |
755 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, | 755 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, |
756 Value* value) { | 756 Value* value) { |
757 if (local.is_captured()) { | 757 if (local.is_captured()) { |
758 LocalVariable* tmp_var = EnterTempLocalScope(value); | 758 LocalVariable* tmp_var = EnterTempLocalScope(value); |
759 intptr_t delta = | 759 intptr_t delta = |
760 owner()->context_level() - local.owner()->context_level(); | 760 owner()->context_level() - local.owner()->context_level(); |
761 ASSERT(delta >= 0); | 761 ASSERT(delta >= 0); |
762 Value* context = Bind(new(I) CurrentContextInstr()); | 762 Value* context = Bind(BuildCurrentContext()); |
763 while (delta-- > 0) { | 763 while (delta-- > 0) { |
764 context = Bind(new(I) LoadFieldInstr( | 764 context = Bind(new(I) LoadFieldInstr( |
765 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), | 765 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), |
766 Scanner::kNoSourcePos)); | 766 Scanner::kNoSourcePos)); |
767 } | 767 } |
768 Value* tmp_val = Bind(new(I) LoadLocalInstr(*tmp_var)); | 768 Value* tmp_val = Bind(new(I) LoadLocalInstr(*tmp_var)); |
769 StoreInstanceFieldInstr* store = | 769 StoreInstanceFieldInstr* store = |
770 new(I) StoreInstanceFieldInstr(Context::variable_offset(local.index()), | 770 new(I) StoreInstanceFieldInstr(Context::variable_offset(local.index()), |
771 context, | 771 context, |
772 tmp_val, | 772 tmp_val, |
773 kEmitStoreBarrier, | 773 kEmitStoreBarrier, |
774 Scanner::kNoSourcePos); | 774 Scanner::kNoSourcePos); |
775 Do(store); | 775 Do(store); |
776 return ExitTempLocalScope(tmp_var); | 776 return ExitTempLocalScope(tmp_var); |
777 } else { | 777 } else { |
778 return new(I) StoreLocalInstr(local, value); | 778 return new(I) StoreLocalInstr(local, value); |
779 } | 779 } |
780 } | 780 } |
781 | 781 |
782 | 782 |
783 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { | 783 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { |
784 if (local.IsConst()) { | 784 if (local.IsConst()) { |
785 return new(I) ConstantInstr(*local.ConstValue()); | 785 return new(I) ConstantInstr(*local.ConstValue()); |
786 } else if (local.is_captured()) { | 786 } else if (local.is_captured()) { |
787 intptr_t delta = | 787 intptr_t delta = |
788 owner()->context_level() - local.owner()->context_level(); | 788 owner()->context_level() - local.owner()->context_level(); |
789 ASSERT(delta >= 0); | 789 ASSERT(delta >= 0); |
790 Value* context = Bind(new(I) CurrentContextInstr()); | 790 Value* context = Bind(BuildCurrentContext()); |
791 while (delta-- > 0) { | 791 while (delta-- > 0) { |
792 context = Bind(new(I) LoadFieldInstr( | 792 context = Bind(new(I) LoadFieldInstr( |
793 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), | 793 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), |
794 Scanner::kNoSourcePos)); | 794 Scanner::kNoSourcePos)); |
795 } | 795 } |
796 return new(I) LoadFieldInstr(context, | 796 return new(I) LoadFieldInstr(context, |
797 Context::variable_offset(local.index()), | 797 Context::variable_offset(local.index()), |
798 local.type(), | 798 local.type(), |
799 Scanner::kNoSourcePos); | 799 Scanner::kNoSourcePos); |
800 } else { | 800 } else { |
801 return new(I) LoadLocalInstr(local); | 801 return new(I) LoadLocalInstr(local); |
802 } | 802 } |
803 } | 803 } |
804 | 804 |
805 | 805 |
806 // Stores current context into the 'variable' | 806 // Stores current context into the 'variable' |
807 void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable) { | 807 void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable) { |
808 Value* context = Bind(new(I) CurrentContextInstr()); | 808 Value* context = Bind(BuildCurrentContext()); |
809 Do(BuildStoreLocal(variable, context)); | 809 Do(BuildStoreLocal(variable, context)); |
810 } | 810 } |
811 | 811 |
812 | 812 |
813 // Loads context saved in 'context_variable' into the current context. | 813 // Loads context saved in 'context_variable' into the current context. |
814 void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable) { | 814 void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable) { |
815 Value* load_saved_context = Bind(BuildLoadLocal(variable)); | 815 Value* load_saved_context = Bind(BuildLoadLocal(variable)); |
816 AddInstruction(new(I) StoreContextInstr(load_saved_context)); | 816 Do(BuildStoreContext(load_saved_context)); |
| 817 } |
| 818 |
| 819 |
| 820 Definition* EffectGraphVisitor::BuildStoreContext(Value* value) { |
| 821 return new(I) StoreLocalInstr( |
| 822 *owner()->parsed_function()->current_context_var(), value); |
| 823 } |
| 824 |
| 825 |
| 826 Definition* EffectGraphVisitor::BuildCurrentContext() { |
| 827 return new(I) LoadLocalInstr( |
| 828 *owner()->parsed_function()->current_context_var()); |
817 } | 829 } |
818 | 830 |
819 | 831 |
820 void TestGraphVisitor::ConnectBranchesTo( | 832 void TestGraphVisitor::ConnectBranchesTo( |
821 const GrowableArray<TargetEntryInstr**>& branches, | 833 const GrowableArray<TargetEntryInstr**>& branches, |
822 JoinEntryInstr* join) const { | 834 JoinEntryInstr* join) const { |
823 ASSERT(!branches.is_empty()); | 835 ASSERT(!branches.is_empty()); |
824 for (intptr_t i = 0; i < branches.length(); i++) { | 836 for (intptr_t i = 0; i < branches.length(); i++) { |
825 TargetEntryInstr* target = | 837 TargetEntryInstr* target = |
826 new(I) TargetEntryInstr(owner()->AllocateBlockId(), | 838 new(I) TargetEntryInstr(owner()->AllocateBlockId(), |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1261 Append(for_right_value); | 1273 Append(for_right_value); |
1262 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 1274 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
1263 | 1275 |
1264 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1276 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
1265 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); | 1277 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); |
1266 arguments->Add(push_left); | 1278 arguments->Add(push_left); |
1267 arguments->Add(push_right); | 1279 arguments->Add(push_right); |
1268 const String& name = String::ZoneHandle(I, Symbols::New(node->TokenName())); | 1280 const String& name = String::ZoneHandle(I, Symbols::New(node->TokenName())); |
1269 const intptr_t kNumArgsChecked = 2; | 1281 const intptr_t kNumArgsChecked = 2; |
1270 InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(), | 1282 InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(), |
1271 name, | 1283 name, |
1272 node->kind(), | 1284 node->kind(), |
1273 arguments, | 1285 arguments, |
1274 Object::null_array(), | 1286 Object::null_array(), |
1275 kNumArgsChecked, | 1287 kNumArgsChecked, |
1276 owner()->ic_data_array()); | 1288 owner()->ic_data_array()); |
1277 ReturnDefinition(call); | 1289 ReturnDefinition(call); |
1278 } | 1290 } |
1279 | 1291 |
1280 | 1292 |
1281 // Special handling for AND/OR. | 1293 // Special handling for AND/OR. |
1282 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { | 1294 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { |
1283 // Operators "&&" and "||" cannot be overloaded therefore do not call | 1295 // Operators "&&" and "||" cannot be overloaded therefore do not call |
1284 // operator. | 1296 // operator. |
1285 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { | 1297 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { |
1286 // Implement short-circuit logic: do not evaluate right if evaluation | 1298 // Implement short-circuit logic: do not evaluate right if evaluation |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1359 PushArgumentInstr* push_mask = PushArgument(mask_value); | 1371 PushArgumentInstr* push_mask = PushArgument(mask_value); |
1360 | 1372 |
1361 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1373 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
1362 new(I) ZoneGrowableArray<PushArgumentInstr*>(3); | 1374 new(I) ZoneGrowableArray<PushArgumentInstr*>(3); |
1363 arguments->Add(push_left); | 1375 arguments->Add(push_left); |
1364 arguments->Add(push_right); | 1376 arguments->Add(push_right); |
1365 // Call to special method 'BinaryOpAndMaskName(node)'. | 1377 // Call to special method 'BinaryOpAndMaskName(node)'. |
1366 arguments->Add(push_mask); | 1378 arguments->Add(push_mask); |
1367 const intptr_t kNumArgsChecked = 2; | 1379 const intptr_t kNumArgsChecked = 2; |
1368 InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(), | 1380 InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(), |
1369 BinaryOpAndMaskName(node), | 1381 BinaryOpAndMaskName(node), |
1370 Token::kILLEGAL, | 1382 Token::kILLEGAL, |
1371 arguments, | 1383 arguments, |
1372 Object::null_array(), | 1384 Object::null_array(), |
1373 kNumArgsChecked, | 1385 kNumArgsChecked, |
1374 owner()->ic_data_array()); | 1386 owner()->ic_data_array()); |
1375 ReturnDefinition(call); | 1387 ReturnDefinition(call); |
1376 } | 1388 } |
1377 | 1389 |
1378 | 1390 |
1379 void EffectGraphVisitor::BuildTypecheckPushArguments( | 1391 void EffectGraphVisitor::BuildTypecheckPushArguments( |
1380 intptr_t token_pos, | 1392 intptr_t token_pos, |
1381 PushArgumentInstr** push_instantiator_result, | 1393 PushArgumentInstr** push_instantiator_result, |
1382 PushArgumentInstr** push_instantiator_type_arguments_result) { | 1394 PushArgumentInstr** push_instantiator_type_arguments_result) { |
1383 const Class& instantiator_class = Class::Handle( | 1395 const Class& instantiator_class = Class::Handle( |
1384 I, owner()->parsed_function()->function().Owner()); | 1396 I, owner()->parsed_function()->function().Owner()); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1489 BuildRestoreContext(*old_context); | 1501 BuildRestoreContext(*old_context); |
1490 | 1502 |
1491 // Pass over the continuation result. | 1503 // Pass over the continuation result. |
1492 | 1504 |
1493 // FlowGraphBuilder is at top context level, but the await target has possibly | 1505 // FlowGraphBuilder is at top context level, but the await target has possibly |
1494 // been recorded in a nested context (old_ctx_level). We need to unroll | 1506 // been recorded in a nested context (old_ctx_level). We need to unroll |
1495 // manually here. | 1507 // manually here. |
1496 intptr_t delta = old_ctx_level - | 1508 intptr_t delta = old_ctx_level - |
1497 continuation_result->owner()->context_level(); | 1509 continuation_result->owner()->context_level(); |
1498 ASSERT(delta >= 0); | 1510 ASSERT(delta >= 0); |
1499 Value* context = Bind(new(I) CurrentContextInstr()); | 1511 Value* context = Bind(BuildCurrentContext()); |
1500 while (delta-- > 0) { | 1512 while (delta-- > 0) { |
1501 context = Bind(new(I) LoadFieldInstr( | 1513 context = Bind(new(I) LoadFieldInstr( |
1502 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), | 1514 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), |
1503 Scanner::kNoSourcePos)); | 1515 Scanner::kNoSourcePos)); |
1504 } | 1516 } |
1505 LocalVariable* temp_context_var = EnterTempLocalScope(context); | 1517 LocalVariable* temp_context_var = EnterTempLocalScope(context); |
1506 | 1518 |
1507 Value* context_val = Bind(new(I) LoadLocalInstr(*temp_context_var)); | 1519 Value* context_val = Bind(new(I) LoadLocalInstr(*temp_context_var)); |
1508 Value* store_val = Bind(new(I) LoadLocalInstr(*temp_result_var)); | 1520 Value* store_val = Bind(new(I) LoadLocalInstr(*temp_result_var)); |
1509 StoreInstanceFieldInstr* store = new(I) StoreInstanceFieldInstr( | 1521 StoreInstanceFieldInstr* store = new(I) StoreInstanceFieldInstr( |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1737 Append(for_left_value); | 1749 Append(for_left_value); |
1738 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 1750 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
1739 arguments->Add(push_left); | 1751 arguments->Add(push_left); |
1740 | 1752 |
1741 ValueGraphVisitor for_right_value(owner()); | 1753 ValueGraphVisitor for_right_value(owner()); |
1742 node->right()->Visit(&for_right_value); | 1754 node->right()->Visit(&for_right_value); |
1743 Append(for_right_value); | 1755 Append(for_right_value); |
1744 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 1756 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
1745 arguments->Add(push_right); | 1757 arguments->Add(push_right); |
1746 | 1758 |
1747 Definition* result = | 1759 Definition* result = new(I) InstanceCallInstr( |
1748 new(I) InstanceCallInstr(node->token_pos(), | 1760 node->token_pos(), |
1749 Symbols::EqualOperator(), | 1761 Symbols::EqualOperator(), |
1750 Token::kEQ, // Result is negated later for kNE. | 1762 Token::kEQ, // Result is negated later for kNE. |
1751 arguments, | 1763 arguments, |
1752 Object::null_array(), | 1764 Object::null_array(), |
1753 2, | 1765 2, |
1754 owner()->ic_data_array()); | 1766 owner()->ic_data_array()); |
1755 if (node->kind() == Token::kNE) { | 1767 if (node->kind() == Token::kNE) { |
1756 if (FLAG_enable_type_checks) { | 1768 if (FLAG_enable_type_checks) { |
1757 Value* value = Bind(result); | 1769 Value* value = Bind(result); |
1758 result = new(I) AssertBooleanInstr(node->token_pos(), value); | 1770 result = new(I) AssertBooleanInstr(node->token_pos(), value); |
1759 } | 1771 } |
1760 Value* value = Bind(result); | 1772 Value* value = Bind(result); |
1761 result = new(I) BooleanNegateInstr(value); | 1773 result = new(I) BooleanNegateInstr(value); |
1762 } | 1774 } |
1763 ReturnDefinition(result); | 1775 ReturnDefinition(result); |
1764 return; | 1776 return; |
1765 } | 1777 } |
1766 | 1778 |
1767 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1779 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
1768 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); | 1780 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); |
1769 | 1781 |
1770 ValueGraphVisitor for_left_value(owner()); | 1782 ValueGraphVisitor for_left_value(owner()); |
1771 node->left()->Visit(&for_left_value); | 1783 node->left()->Visit(&for_left_value); |
1772 Append(for_left_value); | 1784 Append(for_left_value); |
1773 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 1785 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
1774 arguments->Add(push_left); | 1786 arguments->Add(push_left); |
1775 | 1787 |
1776 ValueGraphVisitor for_right_value(owner()); | 1788 ValueGraphVisitor for_right_value(owner()); |
1777 node->right()->Visit(&for_right_value); | 1789 node->right()->Visit(&for_right_value); |
1778 Append(for_right_value); | 1790 Append(for_right_value); |
1779 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 1791 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
1780 arguments->Add(push_right); | 1792 arguments->Add(push_right); |
1781 | 1793 |
1782 ASSERT(Token::IsRelationalOperator(node->kind())); | 1794 ASSERT(Token::IsRelationalOperator(node->kind())); |
1783 InstanceCallInstr* comp = | 1795 InstanceCallInstr* comp = new(I) InstanceCallInstr( |
1784 new(I) InstanceCallInstr(node->token_pos(), | 1796 node->token_pos(), |
1785 String::ZoneHandle( | 1797 String::ZoneHandle(I, Symbols::New(node->TokenName())), |
1786 I, Symbols::New(node->TokenName())), | 1798 node->kind(), |
1787 node->kind(), | 1799 arguments, |
1788 arguments, | 1800 Object::null_array(), |
1789 Object::null_array(), | 1801 2, |
1790 2, | 1802 owner()->ic_data_array()); |
1791 owner()->ic_data_array()); | |
1792 ReturnDefinition(comp); | 1803 ReturnDefinition(comp); |
1793 } | 1804 } |
1794 | 1805 |
1795 | 1806 |
1796 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 1807 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
1797 // "!" cannot be overloaded, therefore do not call operator. | 1808 // "!" cannot be overloaded, therefore do not call operator. |
1798 if (node->kind() == Token::kNOT) { | 1809 if (node->kind() == Token::kNOT) { |
1799 ValueGraphVisitor for_value(owner()); | 1810 ValueGraphVisitor for_value(owner()); |
1800 node->operand()->Visit(&for_value); | 1811 node->operand()->Visit(&for_value); |
1801 Append(for_value); | 1812 Append(for_value); |
1802 Value* value = for_value.value(); | 1813 Value* value = for_value.value(); |
1803 if (FLAG_enable_type_checks) { | 1814 if (FLAG_enable_type_checks) { |
1804 value = | 1815 value = |
1805 Bind(new(I) AssertBooleanInstr(node->operand()->token_pos(), value)); | 1816 Bind(new(I) AssertBooleanInstr(node->operand()->token_pos(), value)); |
1806 } | 1817 } |
1807 BooleanNegateInstr* negate = new(I) BooleanNegateInstr(value); | 1818 BooleanNegateInstr* negate = new(I) BooleanNegateInstr(value); |
1808 ReturnDefinition(negate); | 1819 ReturnDefinition(negate); |
1809 return; | 1820 return; |
1810 } | 1821 } |
1811 | 1822 |
1812 ValueGraphVisitor for_value(owner()); | 1823 ValueGraphVisitor for_value(owner()); |
1813 node->operand()->Visit(&for_value); | 1824 node->operand()->Visit(&for_value); |
1814 Append(for_value); | 1825 Append(for_value); |
1815 PushArgumentInstr* push_value = PushArgument(for_value.value()); | 1826 PushArgumentInstr* push_value = PushArgument(for_value.value()); |
1816 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1827 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
1817 new(I) ZoneGrowableArray<PushArgumentInstr*>(1); | 1828 new(I) ZoneGrowableArray<PushArgumentInstr*>(1); |
1818 arguments->Add(push_value); | 1829 arguments->Add(push_value); |
1819 InstanceCallInstr* call = | 1830 InstanceCallInstr* call = new(I) InstanceCallInstr( |
1820 new(I) InstanceCallInstr(node->token_pos(), | 1831 node->token_pos(), |
1821 String::ZoneHandle( | 1832 String::ZoneHandle(I, Symbols::New(node->TokenName())), |
1822 I, Symbols::New(node->TokenName())), | 1833 node->kind(), |
1823 node->kind(), | 1834 arguments, |
1824 arguments, | 1835 Object::null_array(), |
1825 Object::null_array(), | 1836 1, |
1826 1, | 1837 owner()->ic_data_array()); |
1827 owner()->ic_data_array()); | |
1828 ReturnDefinition(call); | 1838 ReturnDefinition(call); |
1829 } | 1839 } |
1830 | 1840 |
1831 | 1841 |
1832 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 1842 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
1833 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); | 1843 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); |
1834 node->condition()->Visit(&for_test); | 1844 node->condition()->Visit(&for_test); |
1835 | 1845 |
1836 // Translate the subexpressions for their effects. | 1846 // Translate the subexpressions for their effects. |
1837 EffectGraphVisitor for_true(owner()); | 1847 EffectGraphVisitor for_true(owner()); |
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2518 Do(new(I) StoreInstanceFieldInstr(Closure::context_offset(), | 2528 Do(new(I) StoreInstanceFieldInstr(Closure::context_offset(), |
2519 closure_tmp_val, | 2529 closure_tmp_val, |
2520 context_tmp_val, | 2530 context_tmp_val, |
2521 kEmitStoreBarrier, | 2531 kEmitStoreBarrier, |
2522 node->token_pos())); | 2532 node->token_pos())); |
2523 Do(ExitTempLocalScope(context_tmp_var)); | 2533 Do(ExitTempLocalScope(context_tmp_var)); |
2524 } | 2534 } |
2525 } else { | 2535 } else { |
2526 // Store current context in closure. | 2536 // Store current context in closure. |
2527 closure_tmp_val = Bind(new(I) LoadLocalInstr(*closure_tmp_var)); | 2537 closure_tmp_val = Bind(new(I) LoadLocalInstr(*closure_tmp_var)); |
2528 Value* context = Bind(new(I) CurrentContextInstr()); | 2538 Value* context = Bind(BuildCurrentContext()); |
2529 Do(new(I) StoreInstanceFieldInstr(Closure::context_offset(), | 2539 Do(new(I) StoreInstanceFieldInstr(Closure::context_offset(), |
2530 closure_tmp_val, | 2540 closure_tmp_val, |
2531 context, | 2541 context, |
2532 kEmitStoreBarrier, | 2542 kEmitStoreBarrier, |
2533 node->token_pos())); | 2543 node->token_pos())); |
2534 } | 2544 } |
2535 ReturnDefinition(ExitTempLocalScope(closure_tmp_var)); | 2545 ReturnDefinition(ExitTempLocalScope(closure_tmp_var)); |
2536 } | 2546 } |
2537 } | 2547 } |
2538 | 2548 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2604 | 2614 |
2605 | 2615 |
2606 // <Expression> ::= StaticCall { function: Function | 2616 // <Expression> ::= StaticCall { function: Function |
2607 // arguments: <ArgumentList> } | 2617 // arguments: <ArgumentList> } |
2608 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { | 2618 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { |
2609 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2619 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
2610 new(I) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 2620 new(I) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
2611 BuildPushArguments(*node->arguments(), arguments); | 2621 BuildPushArguments(*node->arguments(), arguments); |
2612 StaticCallInstr* call = | 2622 StaticCallInstr* call = |
2613 new(I) StaticCallInstr(node->token_pos(), | 2623 new(I) StaticCallInstr(node->token_pos(), |
2614 node->function(), | 2624 node->function(), |
2615 node->arguments()->names(), | 2625 node->arguments()->names(), |
2616 arguments, | 2626 arguments, |
2617 owner()->ic_data_array()); | 2627 owner()->ic_data_array()); |
2618 if (node->function().is_native()) { | 2628 if (node->function().is_native()) { |
2619 const intptr_t result_cid = GetResultCidOfNativeFactory(node->function()); | 2629 const intptr_t result_cid = GetResultCidOfNativeFactory(node->function()); |
2620 if (result_cid != kDynamicCid) { | 2630 if (result_cid != kDynamicCid) { |
2621 call->set_result_cid(result_cid); | 2631 call->set_result_cid(result_cid); |
2622 call->set_is_native_list_factory(true); | 2632 call->set_is_native_list_factory(true); |
2623 } | 2633 } |
2624 } | 2634 } |
2625 ReturnDefinition(call); | 2635 ReturnDefinition(call); |
2626 } | 2636 } |
2627 | 2637 |
2628 | 2638 |
2629 void EffectGraphVisitor::BuildClosureCall( | 2639 void EffectGraphVisitor::BuildClosureCall( |
2630 ClosureCallNode* node, bool result_needed) { | 2640 ClosureCallNode* node, bool result_needed) { |
2631 ValueGraphVisitor for_closure(owner()); | 2641 ValueGraphVisitor for_closure(owner()); |
2632 node->closure()->Visit(&for_closure); | 2642 node->closure()->Visit(&for_closure); |
2633 Append(for_closure); | 2643 Append(for_closure); |
2634 | 2644 |
2635 LocalVariable* tmp_var = EnterTempLocalScope(for_closure.value()); | 2645 LocalVariable* tmp_var = EnterTempLocalScope(for_closure.value()); |
2636 | 2646 |
2637 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2647 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
2638 new(I) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 2648 new(I) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
2639 Value* closure_val = Bind(new(I) LoadLocalInstr(*tmp_var)); | 2649 Value* closure_val = Bind(new(I) LoadLocalInstr(*tmp_var)); |
2640 PushArgumentInstr* push_closure = PushArgument(closure_val); | 2650 PushArgumentInstr* push_closure = PushArgument(closure_val); |
2641 arguments->Add(push_closure); | 2651 arguments->Add(push_closure); |
2642 BuildPushArguments(*node->arguments(), arguments); | 2652 BuildPushArguments(*node->arguments(), arguments); |
2643 | 2653 |
2644 // Save context around the call. | |
2645 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); | |
2646 BuildSaveContext(*owner()->parsed_function()->saved_current_context_var()); | |
2647 closure_val = Bind(new(I) LoadLocalInstr(*tmp_var)); | |
2648 LoadFieldInstr* context_load = new(I) LoadFieldInstr( | |
2649 closure_val, | |
2650 Closure::context_offset(), | |
2651 AbstractType::ZoneHandle(I, AbstractType::null()), | |
2652 node->token_pos()); | |
2653 context_load->set_is_immutable(true); | |
2654 Value* context_val = Bind(context_load); | |
2655 AddInstruction(new(I) StoreContextInstr(context_val)); | |
2656 closure_val = Bind(new(I) LoadLocalInstr(*tmp_var)); | 2654 closure_val = Bind(new(I) LoadLocalInstr(*tmp_var)); |
2657 LoadFieldInstr* function_load = new(I) LoadFieldInstr( | 2655 LoadFieldInstr* function_load = new(I) LoadFieldInstr( |
2658 closure_val, | 2656 closure_val, |
2659 Closure::function_offset(), | 2657 Closure::function_offset(), |
2660 AbstractType::ZoneHandle(I, AbstractType::null()), | 2658 AbstractType::ZoneHandle(I, AbstractType::null()), |
2661 node->token_pos()); | 2659 node->token_pos()); |
2662 function_load->set_is_immutable(true); | 2660 function_load->set_is_immutable(true); |
2663 Value* function_val = Bind(function_load); | 2661 Value* function_val = Bind(function_load); |
| 2662 |
2664 Definition* closure_call = | 2663 Definition* closure_call = |
2665 new(I) ClosureCallInstr(function_val, node, arguments); | 2664 new(I) ClosureCallInstr(function_val, node, arguments); |
2666 if (result_needed) { | 2665 if (result_needed) { |
2667 Value* result = Bind(closure_call); | 2666 Value* result = Bind(closure_call); |
2668 Do(new(I) StoreLocalInstr(*tmp_var, result)); | 2667 Do(new(I) StoreLocalInstr(*tmp_var, result)); |
2669 // Restore context from temp. | |
2670 BuildRestoreContext( | |
2671 *owner()->parsed_function()->saved_current_context_var()); | |
2672 ReturnDefinition(ExitTempLocalScope(tmp_var)); | |
2673 } else { | 2668 } else { |
2674 Do(closure_call); | 2669 Do(closure_call); |
2675 // Restore context from saved location. | |
2676 BuildRestoreContext( | |
2677 *owner()->parsed_function()->saved_current_context_var()); | |
2678 Do(ExitTempLocalScope(tmp_var)); | |
2679 } | 2670 } |
| 2671 ReturnDefinition(ExitTempLocalScope(tmp_var)); |
2680 } | 2672 } |
2681 | 2673 |
2682 | 2674 |
2683 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 2675 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
2684 BuildClosureCall(node, false); | 2676 BuildClosureCall(node, false); |
2685 } | 2677 } |
2686 | 2678 |
2687 | 2679 |
2688 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 2680 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
2689 BuildClosureCall(node, true); | 2681 BuildClosureCall(node, true); |
2690 } | 2682 } |
2691 | 2683 |
2692 | 2684 |
2693 void EffectGraphVisitor::VisitInitStaticFieldNode(InitStaticFieldNode* node) { | 2685 void EffectGraphVisitor::VisitInitStaticFieldNode(InitStaticFieldNode* node) { |
2694 Value* field = Bind(new(I) ConstantInstr(node->field())); | 2686 Value* field = Bind(new(I) ConstantInstr(node->field())); |
2695 AddInstruction(new(I) InitStaticFieldInstr(field, node->field())); | 2687 AddInstruction(new(I) InitStaticFieldInstr(field, node->field())); |
2696 } | 2688 } |
2697 | 2689 |
2698 | 2690 |
2699 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 2691 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
2700 Value* context = Bind(new(I) CurrentContextInstr()); | 2692 Value* context = Bind(BuildCurrentContext()); |
2701 Value* clone = Bind(new(I) CloneContextInstr(node->token_pos(), context)); | 2693 Value* clone = Bind(new(I) CloneContextInstr(node->token_pos(), context)); |
2702 AddInstruction(new(I) StoreContextInstr(clone)); | 2694 Do(BuildStoreContext(clone)); |
2703 } | 2695 } |
2704 | 2696 |
2705 | 2697 |
2706 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) { | 2698 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) { |
2707 const Class& cls = Class::ZoneHandle(I, node->constructor().Owner()); | 2699 const Class& cls = Class::ZoneHandle(I, node->constructor().Owner()); |
2708 const bool cls_is_parameterized = cls.NumTypeArguments() > 0; | 2700 const bool cls_is_parameterized = cls.NumTypeArguments() > 0; |
2709 | 2701 |
2710 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = | 2702 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = |
2711 new(I) ZoneGrowableArray<PushArgumentInstr*>( | 2703 new(I) ZoneGrowableArray<PushArgumentInstr*>( |
2712 cls_is_parameterized ? 1 : 0); | 2704 cls_is_parameterized ? 1 : 0); |
(...skipping 19 matching lines...) Expand all Loading... |
2732 Smi::ZoneHandle(I, Smi::New(Function::kCtorPhaseAll)))); | 2724 Smi::ZoneHandle(I, Smi::New(Function::kCtorPhaseAll)))); |
2733 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); | 2725 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); |
2734 | 2726 |
2735 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2727 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
2736 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); | 2728 new(I) ZoneGrowableArray<PushArgumentInstr*>(2); |
2737 arguments->Add(push_alloc_value); | 2729 arguments->Add(push_alloc_value); |
2738 arguments->Add(push_ctor_arg); | 2730 arguments->Add(push_ctor_arg); |
2739 | 2731 |
2740 BuildPushArguments(*node->arguments(), arguments); | 2732 BuildPushArguments(*node->arguments(), arguments); |
2741 Do(new(I) StaticCallInstr(node->token_pos(), | 2733 Do(new(I) StaticCallInstr(node->token_pos(), |
2742 node->constructor(), | 2734 node->constructor(), |
2743 node->arguments()->names(), | 2735 node->arguments()->names(), |
2744 arguments, | 2736 arguments, |
2745 owner()->ic_data_array())); | 2737 owner()->ic_data_array())); |
2746 } | 2738 } |
2747 | 2739 |
2748 | 2740 |
2749 static intptr_t GetResultCidOfListFactory(ConstructorCallNode* node) { | 2741 static intptr_t GetResultCidOfListFactory(ConstructorCallNode* node) { |
2750 const Function& function = node->constructor(); | 2742 const Function& function = node->constructor(); |
2751 const Class& function_class = Class::Handle(function.Owner()); | 2743 const Class& function_class = Class::Handle(function.Owner()); |
2752 | 2744 |
2753 if ((function_class.library() != Library::CoreLibrary()) && | 2745 if ((function_class.library() != Library::CoreLibrary()) && |
2754 (function_class.library() != Library::TypedDataLibrary())) { | 2746 (function_class.library() != Library::TypedDataLibrary())) { |
2755 return kDynamicCid; | 2747 return kDynamicCid; |
(...skipping 19 matching lines...) Expand all Loading... |
2775 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2767 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
2776 new(I) ZoneGrowableArray<PushArgumentInstr*>(); | 2768 new(I) ZoneGrowableArray<PushArgumentInstr*>(); |
2777 PushArgumentInstr* push_type_arguments = PushArgument( | 2769 PushArgumentInstr* push_type_arguments = PushArgument( |
2778 BuildInstantiatedTypeArguments(node->token_pos(), | 2770 BuildInstantiatedTypeArguments(node->token_pos(), |
2779 node->type_arguments())); | 2771 node->type_arguments())); |
2780 arguments->Add(push_type_arguments); | 2772 arguments->Add(push_type_arguments); |
2781 ASSERT(arguments->length() == 1); | 2773 ASSERT(arguments->length() == 1); |
2782 BuildPushArguments(*node->arguments(), arguments); | 2774 BuildPushArguments(*node->arguments(), arguments); |
2783 StaticCallInstr* call = | 2775 StaticCallInstr* call = |
2784 new(I) StaticCallInstr(node->token_pos(), | 2776 new(I) StaticCallInstr(node->token_pos(), |
2785 node->constructor(), | 2777 node->constructor(), |
2786 node->arguments()->names(), | 2778 node->arguments()->names(), |
2787 arguments, | 2779 arguments, |
2788 owner()->ic_data_array()); | 2780 owner()->ic_data_array()); |
2789 const intptr_t result_cid = GetResultCidOfListFactory(node); | 2781 const intptr_t result_cid = GetResultCidOfListFactory(node); |
2790 if (result_cid != kDynamicCid) { | 2782 if (result_cid != kDynamicCid) { |
2791 call->set_result_cid(result_cid); | 2783 call->set_result_cid(result_cid); |
2792 call->set_is_known_list_constructor(true); | 2784 call->set_is_known_list_constructor(true); |
2793 // Recognized fixed length array factory must have two arguments: | 2785 // Recognized fixed length array factory must have two arguments: |
2794 // (0) type-arguments, (1) length. | 2786 // (0) type-arguments, (1) length. |
2795 ASSERT(!LoadFieldInstr::IsFixedLengthArrayCid(result_cid) || | 2787 ASSERT(!LoadFieldInstr::IsFixedLengthArrayCid(result_cid) || |
2796 arguments->length() == 2); | 2788 arguments->length() == 2); |
2797 } | 2789 } |
2798 ReturnDefinition(call); | 2790 ReturnDefinition(call); |
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3529 arguments->Add(PushArgument(for_array.value())); | 3521 arguments->Add(PushArgument(for_array.value())); |
3530 | 3522 |
3531 ValueGraphVisitor for_index(owner()); | 3523 ValueGraphVisitor for_index(owner()); |
3532 node->index_expr()->Visit(&for_index); | 3524 node->index_expr()->Visit(&for_index); |
3533 Append(for_index); | 3525 Append(for_index); |
3534 arguments->Add(PushArgument(for_index.value())); | 3526 arguments->Add(PushArgument(for_index.value())); |
3535 | 3527 |
3536 if (super_function != NULL) { | 3528 if (super_function != NULL) { |
3537 // Generate static call to super operator. | 3529 // Generate static call to super operator. |
3538 StaticCallInstr* load = new(I) StaticCallInstr(node->token_pos(), | 3530 StaticCallInstr* load = new(I) StaticCallInstr(node->token_pos(), |
3539 *super_function, | 3531 *super_function, |
3540 Object::null_array(), | 3532 Object::null_array(), |
3541 arguments, | 3533 arguments, |
3542 owner()->ic_data_array()); | 3534 owner()->ic_data_array()); |
3543 ReturnDefinition(load); | 3535 ReturnDefinition(load); |
3544 } else { | 3536 } else { |
3545 // Generate dynamic call to index operator. | 3537 // Generate dynamic call to index operator. |
3546 const intptr_t checked_argument_count = 1; | 3538 const intptr_t checked_argument_count = 1; |
3547 InstanceCallInstr* load = new(I) InstanceCallInstr(node->token_pos(), | 3539 InstanceCallInstr* load = new(I) InstanceCallInstr( |
3548 Symbols::IndexToken(), | 3540 node->token_pos(), |
3549 Token::kINDEX, | 3541 Symbols::IndexToken(), |
3550 arguments, | 3542 Token::kINDEX, |
3551 Object::null_array(), | 3543 arguments, |
3552 checked_argument_count, | 3544 Object::null_array(), |
3553 owner()->ic_data_array()); | 3545 checked_argument_count, |
| 3546 owner()->ic_data_array()); |
3554 ReturnDefinition(load); | 3547 ReturnDefinition(load); |
3555 } | 3548 } |
3556 } | 3549 } |
3557 | 3550 |
3558 | 3551 |
3559 Definition* EffectGraphVisitor::BuildStoreIndexedValues( | 3552 Definition* EffectGraphVisitor::BuildStoreIndexedValues( |
3560 StoreIndexedNode* node, | 3553 StoreIndexedNode* node, |
3561 bool result_is_needed) { | 3554 bool result_is_needed) { |
3562 Function* super_function = NULL; | 3555 Function* super_function = NULL; |
3563 if (node->IsSuperStore()) { | 3556 if (node->IsSuperStore()) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3610 } else { | 3603 } else { |
3611 value = for_value.value(); | 3604 value = for_value.value(); |
3612 } | 3605 } |
3613 arguments->Add(PushArgument(value)); | 3606 arguments->Add(PushArgument(value)); |
3614 | 3607 |
3615 if (super_function != NULL) { | 3608 if (super_function != NULL) { |
3616 // Generate static call to super operator []=. | 3609 // Generate static call to super operator []=. |
3617 | 3610 |
3618 StaticCallInstr* store = | 3611 StaticCallInstr* store = |
3619 new(I) StaticCallInstr(node->token_pos(), | 3612 new(I) StaticCallInstr(node->token_pos(), |
3620 *super_function, | 3613 *super_function, |
3621 Object::null_array(), | 3614 Object::null_array(), |
3622 arguments, | 3615 arguments, |
3623 owner()->ic_data_array()); | 3616 owner()->ic_data_array()); |
3624 if (result_is_needed) { | 3617 if (result_is_needed) { |
3625 Do(store); | 3618 Do(store); |
3626 return BuildLoadExprTemp(); | 3619 return BuildLoadExprTemp(); |
3627 } else { | 3620 } else { |
3628 return store; | 3621 return store; |
3629 } | 3622 } |
3630 } else { | 3623 } else { |
3631 // Generate dynamic call to operator []=. | 3624 // Generate dynamic call to operator []=. |
3632 const intptr_t checked_argument_count = 3; | 3625 const intptr_t checked_argument_count = 3; |
3633 const String& name = | 3626 const String& name = |
3634 String::ZoneHandle(I, Symbols::New(Token::Str(Token::kASSIGN_INDEX))); | 3627 String::ZoneHandle(I, Symbols::New(Token::Str(Token::kASSIGN_INDEX))); |
3635 InstanceCallInstr* store = | 3628 InstanceCallInstr* store = |
3636 new(I) InstanceCallInstr(node->token_pos(), | 3629 new(I) InstanceCallInstr(node->token_pos(), |
3637 name, | 3630 name, |
3638 Token::kASSIGN_INDEX, | 3631 Token::kASSIGN_INDEX, |
3639 arguments, | 3632 arguments, |
3640 Object::null_array(), | 3633 Object::null_array(), |
3641 checked_argument_count, | 3634 checked_argument_count, |
3642 owner()->ic_data_array()); | 3635 owner()->ic_data_array()); |
3643 if (result_is_needed) { | 3636 if (result_is_needed) { |
3644 Do(store); | 3637 Do(store); |
3645 return BuildLoadExprTemp(); | 3638 return BuildLoadExprTemp(); |
3646 } else { | 3639 } else { |
3647 return store; | 3640 return store; |
3648 } | 3641 } |
3649 } | 3642 } |
3650 } | 3643 } |
3651 | 3644 |
3652 | 3645 |
3653 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 3646 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
3654 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded)); | 3647 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded)); |
3655 } | 3648 } |
3656 | 3649 |
3657 | 3650 |
3658 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 3651 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
3659 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded)); | 3652 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded)); |
3660 } | 3653 } |
3661 | 3654 |
3662 | 3655 |
3663 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { | 3656 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { |
3664 return (node == owner()->parsed_function()->node_sequence()) && | 3657 return (node == owner()->parsed_function()->node_sequence()) && |
3665 (owner()->parsed_function()->saved_entry_context_var() != NULL); | 3658 (owner()->parsed_function()->saved_entry_context_var() != NULL); |
3666 } | 3659 } |
3667 | 3660 |
3668 | 3661 |
3669 void EffectGraphVisitor::UnchainContexts(intptr_t n) { | 3662 void EffectGraphVisitor::UnchainContexts(intptr_t n) { |
3670 if (n > 0) { | 3663 if (n > 0) { |
3671 Value* context = Bind(new(I) CurrentContextInstr()); | 3664 Value* context = Bind(BuildCurrentContext()); |
3672 while (n-- > 0) { | 3665 while (n-- > 0) { |
3673 context = Bind( | 3666 context = Bind( |
3674 new(I) LoadFieldInstr(context, | 3667 new(I) LoadFieldInstr(context, |
3675 Context::parent_offset(), | 3668 Context::parent_offset(), |
3676 // Not an instance, no type. | 3669 // Not an instance, no type. |
3677 Type::ZoneHandle(I, Type::null()), | 3670 Type::ZoneHandle(I, Type::null()), |
3678 Scanner::kNoSourcePos)); | 3671 Scanner::kNoSourcePos)); |
3679 } | 3672 } |
3680 AddInstruction(new(I) StoreContextInstr(context)); | 3673 Do(BuildStoreContext(context)); |
3681 } | 3674 } |
3682 } | 3675 } |
3683 | 3676 |
3684 | 3677 |
3685 // <Statement> ::= Sequence { scope: LocalScope | 3678 // <Statement> ::= Sequence { scope: LocalScope |
3686 // nodes: <Statement>* | 3679 // nodes: <Statement>* |
3687 // label: SourceLabel } | 3680 // label: SourceLabel } |
3688 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { | 3681 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
3689 LocalScope* scope = node->scope(); | 3682 LocalScope* scope = node->scope(); |
3690 const intptr_t num_context_variables = | 3683 const intptr_t num_context_variables = |
3691 (scope != NULL) ? scope->num_context_variables() : 0; | 3684 (scope != NULL) ? scope->num_context_variables() : 0; |
3692 // The outermost function sequence cannot contain a label. | 3685 // The outermost function sequence cannot contain a label. |
3693 ASSERT((node->label() == NULL) || | 3686 ASSERT((node->label() == NULL) || |
3694 (node != owner()->parsed_function()->node_sequence())); | 3687 (node != owner()->parsed_function()->node_sequence())); |
3695 NestedBlock nested_block(owner(), node); | 3688 NestedBlock nested_block(owner(), node); |
3696 | 3689 |
3697 if (num_context_variables > 0) { | 3690 if (num_context_variables > 0) { |
3698 // The loop local scope declares variables that are captured. | 3691 // The loop local scope declares variables that are captured. |
3699 // Allocate and chain a new context. | 3692 // Allocate and chain a new context. |
3700 // Allocate context computation (uses current CTX) | 3693 // Allocate context computation (uses current context) |
3701 Value* allocated_context = | 3694 Value* allocated_context = |
3702 Bind(new(I) AllocateContextInstr(node->token_pos(), | 3695 Bind(new(I) AllocateContextInstr(node->token_pos(), |
3703 num_context_variables)); | 3696 num_context_variables)); |
3704 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); | 3697 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); |
3705 // If this node_sequence is the body of the function being compiled, and | 3698 // If this node_sequence is the body of the function being compiled, and |
3706 // if this function allocates context variables, but none of its enclosing | 3699 // if this function allocates context variables, but none of its enclosing |
3707 // functions do, the context on entry is not linked as parent of the | 3700 // functions do, the context on entry is not linked as parent of the |
3708 // allocated context but saved on entry and restored on exit as to prevent | 3701 // allocated context but saved on entry and restored on exit as to prevent |
3709 // memory leaks. | 3702 // memory leaks. |
3710 // In this case, the parser pre-allocates a variable to save the context. | 3703 // In this case, the parser pre-allocates a variable to save the context. |
3711 Value* tmp_val = Bind(new(I) LoadLocalInstr(*tmp_var)); | 3704 Value* tmp_val = Bind(new(I) LoadLocalInstr(*tmp_var)); |
3712 Value* parent_context = NULL; | 3705 Value* parent_context = NULL; |
3713 if (MustSaveRestoreContext(node)) { | 3706 if (MustSaveRestoreContext(node)) { |
3714 BuildSaveContext( | 3707 BuildSaveContext( |
3715 *owner()->parsed_function()->saved_entry_context_var()); | 3708 *owner()->parsed_function()->saved_entry_context_var()); |
3716 parent_context = Bind( | 3709 parent_context = Bind( |
3717 new(I) ConstantInstr(Object::ZoneHandle(I, Object::null()))); | 3710 new(I) ConstantInstr(Object::ZoneHandle(I, Object::null()))); |
3718 } else { | 3711 } else { |
3719 parent_context = Bind(new(I) CurrentContextInstr()); | 3712 parent_context = Bind(BuildCurrentContext()); |
3720 } | 3713 } |
3721 Do(new(I) StoreInstanceFieldInstr(Context::parent_offset(), | 3714 Do(new(I) StoreInstanceFieldInstr(Context::parent_offset(), |
3722 tmp_val, | 3715 tmp_val, |
3723 parent_context, | 3716 parent_context, |
3724 kEmitStoreBarrier, | 3717 kEmitStoreBarrier, |
3725 Scanner::kNoSourcePos)); | 3718 Scanner::kNoSourcePos)); |
3726 AddInstruction( | 3719 Do(BuildStoreContext(Bind(ExitTempLocalScope(tmp_var)))); |
3727 new(I) StoreContextInstr(Bind(ExitTempLocalScope(tmp_var)))); | |
3728 } | 3720 } |
3729 | 3721 |
3730 // If this node_sequence is the body of the function being compiled, copy | 3722 // If this node_sequence is the body of the function being compiled, copy |
3731 // the captured parameters from the frame into the context. | 3723 // the captured parameters from the frame into the context. |
3732 if (node == owner()->parsed_function()->node_sequence()) { | 3724 if (node == owner()->parsed_function()->node_sequence()) { |
3733 ASSERT(scope->context_level() == 1); | 3725 ASSERT(scope->context_level() == 1); |
3734 const Function& function = owner()->parsed_function()->function(); | 3726 const Function& function = owner()->parsed_function()->function(); |
3735 const int num_params = function.NumParameters(); | 3727 const int num_params = function.NumParameters(); |
3736 int param_frame_index = (num_params == function.num_fixed_parameters()) ? | 3728 int param_frame_index = (num_params == function.num_fixed_parameters()) ? |
3737 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; | 3729 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; |
(...skipping 27 matching lines...) Expand all Loading... |
3765 } | 3757 } |
3766 } | 3758 } |
3767 } | 3759 } |
3768 } else if (MustSaveRestoreContext(node)) { | 3760 } else if (MustSaveRestoreContext(node)) { |
3769 // Even when the current scope has no context variables, we may | 3761 // Even when the current scope has no context variables, we may |
3770 // still need to save the current context if, for example, there | 3762 // still need to save the current context if, for example, there |
3771 // are loop scopes below this which will allocate a context | 3763 // are loop scopes below this which will allocate a context |
3772 // object. | 3764 // object. |
3773 BuildSaveContext( | 3765 BuildSaveContext( |
3774 *owner()->parsed_function()->saved_entry_context_var()); | 3766 *owner()->parsed_function()->saved_entry_context_var()); |
3775 AddInstruction( | 3767 Do(BuildStoreContext(Bind(new(I) ConstantInstr(Object::ZoneHandle( |
3776 new(I) StoreContextInstr(Bind(new(I) ConstantInstr(Object::ZoneHandle( | 3768 I, I->object_store()->empty_context()))))); |
3777 I, I->object_store()->empty_context()))))); | |
3778 } | 3769 } |
3779 | 3770 |
3780 // This check may be deleted if the generated code is leaf. | 3771 // This check may be deleted if the generated code is leaf. |
3781 // Native functions don't need a stack check at entry. | 3772 // Native functions don't need a stack check at entry. |
3782 const Function& function = owner()->parsed_function()->function(); | 3773 const Function& function = owner()->parsed_function()->function(); |
3783 if ((node == owner()->parsed_function()->node_sequence()) && | 3774 if ((node == owner()->parsed_function()->node_sequence()) && |
3784 !function.is_native()) { | 3775 !function.is_native()) { |
3785 // Always allocate CheckOverflowInstr so that deopt-ids match regardless | 3776 // Always allocate CheckOverflowInstr so that deopt-ids match regardless |
3786 // if we inline or not. | 3777 // if we inline or not. |
3787 if (!function.IsImplicitGetterFunction() && | 3778 if (!function.IsImplicitGetterFunction() && |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3936 // taken care of unchaining the context. | 3927 // taken care of unchaining the context. |
3937 if (nested_block.break_target() != NULL) { | 3928 if (nested_block.break_target() != NULL) { |
3938 if (is_open()) Goto(nested_block.break_target()); | 3929 if (is_open()) Goto(nested_block.break_target()); |
3939 exit_ = nested_block.break_target(); | 3930 exit_ = nested_block.break_target(); |
3940 } | 3931 } |
3941 } | 3932 } |
3942 | 3933 |
3943 | 3934 |
3944 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { | 3935 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
3945 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); | 3936 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); |
3946 // Restores CTX from local variable ':saved_context'. | 3937 // Restores current context from local variable ':saved_context'. |
3947 BuildRestoreContext(node->context_var()); | 3938 BuildRestoreContext(node->context_var()); |
3948 | 3939 |
3949 EffectGraphVisitor for_catch(owner()); | 3940 EffectGraphVisitor for_catch(owner()); |
3950 node->VisitChildren(&for_catch); | 3941 node->VisitChildren(&for_catch); |
3951 Append(for_catch); | 3942 Append(for_catch); |
3952 } | 3943 } |
3953 | 3944 |
3954 | 3945 |
3955 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 3946 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
3956 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); | 3947 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); |
3957 intptr_t original_handler_index = owner()->try_index(); | 3948 intptr_t original_handler_index = owner()->try_index(); |
3958 const intptr_t try_handler_index = node->try_index(); | 3949 const intptr_t try_handler_index = node->try_index(); |
3959 ASSERT(try_handler_index != original_handler_index); | 3950 ASSERT(try_handler_index != original_handler_index); |
3960 owner()->set_try_index(try_handler_index); | 3951 owner()->set_try_index(try_handler_index); |
3961 | 3952 |
3962 // Preserve CTX into local variable '%saved_context'. | 3953 // Preserve current context into local variable '%saved_context'. |
3963 BuildSaveContext(node->context_var()); | 3954 BuildSaveContext(node->context_var()); |
3964 | 3955 |
3965 EffectGraphVisitor for_try(owner()); | 3956 EffectGraphVisitor for_try(owner()); |
3966 node->try_block()->Visit(&for_try); | 3957 node->try_block()->Visit(&for_try); |
3967 | 3958 |
3968 if (for_try.is_open()) { | 3959 if (for_try.is_open()) { |
3969 JoinEntryInstr* after_try = | 3960 JoinEntryInstr* after_try = |
3970 new(I) JoinEntryInstr(owner()->AllocateBlockId(), | 3961 new(I) JoinEntryInstr(owner()->AllocateBlockId(), |
3971 original_handler_index); | 3962 original_handler_index); |
3972 for_try.Goto(after_try); | 3963 for_try.Goto(after_try); |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4291 Report::MessageF(Report::kBailout, | 4282 Report::MessageF(Report::kBailout, |
4292 Script::Handle(function.script()), | 4283 Script::Handle(function.script()), |
4293 function.token_pos(), | 4284 function.token_pos(), |
4294 "FlowGraphBuilder Bailout: %s %s", | 4285 "FlowGraphBuilder Bailout: %s %s", |
4295 String::Handle(function.name()).ToCString(), | 4286 String::Handle(function.name()).ToCString(), |
4296 reason); | 4287 reason); |
4297 UNREACHABLE(); | 4288 UNREACHABLE(); |
4298 } | 4289 } |
4299 | 4290 |
4300 } // namespace dart | 4291 } // namespace dart |
OLD | NEW |