Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 678763004: Make CTX allocatable by the register allocator. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: incorporated latest comments Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698