| 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 = |
| (...skipping 18 matching lines...) Expand all Loading... |
| 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 503 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 |