Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/code_descriptors.h" | 8 #include "vm/code_descriptors.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 756 ReturnComputation(call); | 756 ReturnComputation(call); |
| 757 } | 757 } |
| 758 | 758 |
| 759 | 759 |
| 760 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { | 760 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { |
| 761 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 761 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 762 // In an effect context, treat postincrement as if it were preincrement | 762 // In an effect context, treat postincrement as if it were preincrement |
| 763 // because its value is not needed. | 763 // because its value is not needed. |
| 764 | 764 |
| 765 // 1. Load the value. | 765 // 1. Load the value. |
| 766 LoadLocalComp* load = new LoadLocalComp(node->local(), | 766 BindInstr* load = |
| 767 owner()->context_level()); | 767 new BindInstr(temp_index(), |
| 768 AddInstruction(new BindInstr(temp_index(), load)); | 768 new LoadLocalComp(node->local(), owner()->context_level())); |
| 769 AddInstruction(load); | |
| 770 AllocateTempIndex(); | |
| 769 // 2. Increment. | 771 // 2. Increment. |
| 770 BuildIncrOpIncrement(node->kind(), node->id(), node->token_index(), | 772 Definition* incr = |
| 771 temp_index() + 1); | 773 BuildIncrOpIncrement(node->kind(), node->id(), node->token_index(), |
| 774 new UseVal(load)); | |
| 772 // 3. Perform the store, resulting in the new value. | 775 // 3. Perform the store, resulting in the new value. |
| 776 DeallocateTempIndex(); // Consuming incr. | |
| 773 StoreLocalComp* store = new StoreLocalComp( | 777 StoreLocalComp* store = new StoreLocalComp( |
| 774 node->local(), new TempVal(temp_index()), owner()->context_level()); | 778 node->local(), new UseVal(incr), owner()->context_level()); |
| 775 ReturnComputation(store); | 779 ReturnComputation(store); |
| 776 } | 780 } |
| 777 | 781 |
| 778 | 782 |
| 779 void ValueGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { | 783 void ValueGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { |
| 780 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 784 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 781 if (node->prefix()) { | 785 if (node->prefix()) { |
| 782 // Base class handles preincrement. | 786 // Base class handles preincrement. |
| 783 EffectGraphVisitor::VisitIncrOpLocalNode(node); | 787 EffectGraphVisitor::VisitIncrOpLocalNode(node); |
| 784 return; | 788 return; |
| 785 } | 789 } |
| 786 // For postincrement, duplicate the original value to use one copy as the | 790 // For postincrement, duplicate the original value to use one copy as the |
| 787 // result. | 791 // result. |
| 788 // | 792 // |
| 789 // 1. Load the value. | 793 // 1. Load the value. |
| 790 LoadLocalComp* load = new LoadLocalComp(node->local(), | 794 BindInstr* load = |
| 791 owner()->context_level()); | 795 new BindInstr(temp_index(), |
| 792 AddInstruction(new BindInstr(temp_index(), load)); | 796 new LoadLocalComp(node->local(), owner()->context_level())); |
| 797 AddInstruction(load); | |
| 798 AllocateTempIndex(); | |
| 793 // 2. Duplicate it to increment. | 799 // 2. Duplicate it to increment. |
| 794 AddInstruction(new PickTempInstr(temp_index() + 1, temp_index())); | 800 PickTempInstr* duplicate = |
| 801 new PickTempInstr(temp_index(), load->temp_index()); | |
|
srdjan
2012/04/25 23:38:19
What is the plan with Pick and Tuck instructions?
| |
| 802 AddInstruction(duplicate); | |
| 803 AllocateTempIndex(); | |
| 795 // 3. Increment. | 804 // 3. Increment. |
| 796 BuildIncrOpIncrement(node->kind(), node->id(), node->token_index(), | 805 Definition* incr = |
| 797 temp_index() + 2); | 806 BuildIncrOpIncrement(node->kind(), node->id(), node->token_index(), |
| 807 new UseVal(duplicate)); | |
| 798 // 4. Perform the store and return the original value. | 808 // 4. Perform the store and return the original value. |
| 809 DeallocateTempIndex(); // Consuming incr. | |
| 799 StoreLocalComp* store = new StoreLocalComp( | 810 StoreLocalComp* store = new StoreLocalComp( |
| 800 node->local(), new TempVal(temp_index() + 1), owner()->context_level()); | 811 node->local(), new UseVal(incr), owner()->context_level()); |
| 801 AddInstruction(new DoInstr(store)); | 812 AddInstruction(new DoInstr(store)); |
| 802 ReturnValue(new TempVal(AllocateTempIndex())); | 813 ReturnValue(new UseVal(load)); |
| 803 } | 814 } |
| 804 | 815 |
| 805 | 816 |
| 806 int EffectGraphVisitor::BuildIncrOpFieldLoad(IncrOpInstanceFieldNode* node, | 817 Definition* EffectGraphVisitor::BuildIncrOpFieldLoad( |
| 807 intptr_t start_index) { | 818 IncrOpInstanceFieldNode* node, |
| 819 Value** receiver) { | |
| 808 // Evaluate the receiver and duplicate it (it has two uses). | 820 // Evaluate the receiver and duplicate it (it has two uses). |
| 809 // t_n <- ... receiver ... | 821 // t_n <- ... receiver ... |
| 810 // t_n+1 <- Pick(t_n) | 822 // t_n+1 <- Pick(t_n) |
| 811 ArgumentGraphVisitor for_receiver(owner(), start_index); | 823 ArgumentGraphVisitor for_receiver(owner(), temp_index()); |
| 812 node->receiver()->Visit(&for_receiver); | 824 node->receiver()->Visit(&for_receiver); |
| 813 Append(for_receiver); | 825 Append(for_receiver); |
| 814 const int next_index = for_receiver.temp_index(); | 826 AllocateTempIndex(); |
| 815 ASSERT(next_index == start_index + 1); | 827 ASSERT(temp_index() == for_receiver.temp_index()); |
| 816 AddInstruction(new PickTempInstr(next_index, start_index)); | 828 PickTempInstr* duplicate = |
| 829 new PickTempInstr(temp_index(), temp_index() - 1); | |
| 830 AddInstruction(duplicate); | |
| 817 | 831 |
| 818 // Load the value. | 832 // Load the value. |
| 819 // t_n+1 <- InstanceCall(get:name, t_n+1) | 833 // t_n+1 <- InstanceCall(get:name, t_n+1) |
| 820 const String& getter_name = | 834 const String& getter_name = |
| 821 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 835 String::ZoneHandle(Field::GetterSymbol(node->field_name())); |
| 822 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); | 836 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); |
| 823 arguments->Add(new TempVal(next_index)); | 837 arguments->Add(new UseVal(duplicate)); |
| 824 InstanceCallComp* load = new InstanceCallComp( | 838 BindInstr* load = |
| 825 node->getter_id(), node->token_index(), owner()->try_index(), | 839 new BindInstr(temp_index(), |
| 826 getter_name, arguments, Array::ZoneHandle(), 1); | 840 new InstanceCallComp( |
| 827 AddInstruction(new BindInstr(next_index, load)); | 841 node->getter_id(), node->token_index(), |
| 842 owner()->try_index(), getter_name, arguments, | |
| 843 Array::ZoneHandle(), 1)); | |
| 844 AddInstruction(load); | |
| 845 AllocateTempIndex(); | |
| 828 | 846 |
| 829 return next_index; | 847 *receiver = for_receiver.value(); |
| 848 return load; | |
| 830 } | 849 } |
| 831 | 850 |
| 832 | 851 |
| 833 void EffectGraphVisitor::BuildIncrOpIncrement(Token::Kind kind, | 852 Definition* EffectGraphVisitor::BuildIncrOpIncrement(Token::Kind kind, |
| 834 intptr_t node_id, | 853 intptr_t node_id, |
| 835 intptr_t token_index, | 854 intptr_t token_index, |
| 836 intptr_t start_index) { | 855 Value* original) { |
| 837 ASSERT((kind == Token::kINCR) || (kind == Token::kDECR)); | 856 ASSERT((kind == Token::kINCR) || (kind == Token::kDECR)); |
| 838 // Assumed that t_n-1 (where n is start_index) is the field value. | 857 // Assumed that t_n-1 (where n is start_index) is the field value. |
| 839 // t_n <- #1 | 858 // t_n <- #1 |
| 840 // t_n-1 <- InstanceCall(op, t_n-1, t_n) | 859 // t_n-1 <- InstanceCall(op, t_n-1, t_n) |
| 841 const Smi& one = Smi::ZoneHandle(Smi::New(1)); | 860 BindInstr* one = |
| 842 AddInstruction(new BindInstr(start_index, new ConstantVal(one))); | 861 new BindInstr(temp_index(), |
| 862 new ConstantVal(Smi::ZoneHandle(Smi::New(1)))); | |
| 863 AddInstruction(one); | |
| 843 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 864 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 844 arguments->Add(new TempVal(start_index - 1)); | 865 arguments->Add(original); |
| 845 arguments->Add(new TempVal(start_index)); | 866 arguments->Add(new UseVal(one)); |
| 846 const String& op_name = | 867 const String& op_name = |
| 847 String::ZoneHandle(String::NewSymbol((kind == Token::kINCR) ? "+" : "-")); | 868 String::ZoneHandle(String::NewSymbol((kind == Token::kINCR) ? "+" : "-")); |
| 848 InstanceCallComp* add = new InstanceCallComp( | 869 DeallocateTempIndex(); // Consuming original. |
| 849 node_id, token_index, owner()->try_index(), op_name, | 870 BindInstr* add = |
| 850 arguments, Array::ZoneHandle(), 2); | 871 new BindInstr(temp_index(), |
| 851 AddInstruction(new BindInstr(start_index - 1, add)); | 872 new InstanceCallComp( |
| 873 node_id, token_index, owner()->try_index(), op_name, | |
| 874 arguments, Array::ZoneHandle(), 2)); | |
| 875 AddInstruction(add); | |
| 876 AllocateTempIndex(); | |
| 877 return add; | |
| 852 } | 878 } |
| 853 | 879 |
| 854 | 880 |
| 855 void EffectGraphVisitor::VisitIncrOpInstanceFieldNode( | 881 void EffectGraphVisitor::VisitIncrOpInstanceFieldNode( |
| 856 IncrOpInstanceFieldNode* node) { | 882 IncrOpInstanceFieldNode* node) { |
| 857 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 883 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 858 // In an effect context, treat postincrement as if it were preincrement | 884 // In an effect context, treat postincrement as if it were preincrement |
| 859 // because its value is not needed. | 885 // because its value is not needed. |
| 860 | 886 |
| 861 // 1. Load the value. | 887 // 1. Load the value. |
| 862 const int value_index = BuildIncrOpFieldLoad(node, temp_index()); | 888 Value* receiver = NULL; |
| 889 Definition* load = BuildIncrOpFieldLoad(node, &receiver); | |
| 863 // 2. Increment. | 890 // 2. Increment. |
| 864 BuildIncrOpIncrement(node->kind(), node->operator_id(), node->token_index(), | 891 Definition* incr = |
| 865 value_index + 1); | 892 BuildIncrOpIncrement(node->kind(), node->operator_id(), |
| 893 node->token_index(), new UseVal(load)); | |
| 866 // 3. Perform the store, returning the stored value. | 894 // 3. Perform the store, returning the stored value. |
| 867 InstanceSetterComp* store = | 895 InstanceSetterComp* store = |
| 868 new InstanceSetterComp(node->setter_id(), | 896 new InstanceSetterComp(node->setter_id(), |
| 869 node->token_index(), | 897 node->token_index(), |
| 870 owner()->try_index(), | 898 owner()->try_index(), |
| 871 node->field_name(), | 899 node->field_name(), |
| 872 new TempVal(value_index - 1), | 900 receiver, |
| 873 new TempVal(value_index)); | 901 new UseVal(incr)); |
| 902 DeallocateTempIndex(); // Consuming incr. | |
| 903 DeallocateTempIndex(); // Consuming receiver. | |
| 874 ReturnComputation(store); | 904 ReturnComputation(store); |
| 875 } | 905 } |
| 876 | 906 |
| 877 | 907 |
| 878 void ValueGraphVisitor::VisitIncrOpInstanceFieldNode( | 908 void ValueGraphVisitor::VisitIncrOpInstanceFieldNode( |
| 879 IncrOpInstanceFieldNode* node) { | 909 IncrOpInstanceFieldNode* node) { |
| 880 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 910 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 881 if (node->prefix()) { | 911 if (node->prefix()) { |
| 882 // Base class handles preincrement. | 912 // Base class handles preincrement. |
| 883 EffectGraphVisitor::VisitIncrOpInstanceFieldNode(node); | 913 EffectGraphVisitor::VisitIncrOpInstanceFieldNode(node); |
| 884 return; | 914 return; |
| 885 } | 915 } |
| 886 // For postincrement, preallocate a temporary to preserve the original | 916 // For postincrement, preallocate a temporary to preserve the original |
| 887 // value. | 917 // value. |
| 888 // | 918 // |
| 889 // 1. Name a placeholder. | 919 // 1. Name a placeholder. |
| 890 const Smi& placeholder = Smi::ZoneHandle(Smi::New(0)); | 920 BindInstr* placeholder = |
| 891 AddInstruction(new BindInstr(temp_index(), new ConstantVal(placeholder))); | 921 new BindInstr(temp_index(), |
| 922 new ConstantVal(Smi::ZoneHandle(Smi::New(0)))); | |
| 923 AddInstruction(placeholder); | |
| 924 AllocateTempIndex(); | |
| 892 // 2. Load the value. | 925 // 2. Load the value. |
| 893 const int value_index = BuildIncrOpFieldLoad(node, temp_index() + 1); | 926 Value* receiver = NULL; |
| 927 Definition* load = BuildIncrOpFieldLoad(node, &receiver); | |
| 894 // 3. Preserve the original value. | 928 // 3. Preserve the original value. |
| 895 AddInstruction(new TuckTempInstr(temp_index(), value_index)); | 929 AddInstruction(new TuckTempInstr(placeholder->temp_index(), |
| 930 load->temp_index())); | |
| 896 // 4. Increment. | 931 // 4. Increment. |
| 897 BuildIncrOpIncrement(node->kind(), node->operator_id(), node->token_index(), | 932 Definition* incr = |
| 898 value_index + 1); | 933 BuildIncrOpIncrement(node->kind(), node->operator_id(), |
| 934 node->token_index(), new UseVal(load)); | |
| 899 // 5. Perform the store and return the original value. | 935 // 5. Perform the store and return the original value. |
| 900 const String& setter_name = | 936 const String& setter_name = |
| 901 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 937 String::ZoneHandle(Field::SetterSymbol(node->field_name())); |
| 902 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 938 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 903 arguments->Add(new TempVal(value_index - 1)); | 939 arguments->Add(receiver); |
| 904 arguments->Add(new TempVal(value_index)); | 940 arguments->Add(new UseVal(incr)); |
| 905 InstanceCallComp* store = new InstanceCallComp( | 941 InstanceCallComp* store = new InstanceCallComp( |
| 906 node->setter_id(), node->token_index(), owner()->try_index(), | 942 node->setter_id(), node->token_index(), owner()->try_index(), |
| 907 setter_name, arguments, Array::ZoneHandle(), 1); | 943 setter_name, arguments, Array::ZoneHandle(), 1); |
| 944 DeallocateTempIndex(); // Consuming incr. | |
| 945 DeallocateTempIndex(); // Consuming receiver. | |
| 908 AddInstruction(new DoInstr(store)); | 946 AddInstruction(new DoInstr(store)); |
| 909 ReturnValue(new TempVal(AllocateTempIndex())); | 947 ReturnValue(new UseVal(placeholder)); |
| 910 } | 948 } |
| 911 | 949 |
| 912 | 950 |
| 913 int EffectGraphVisitor::BuildIncrOpIndexedLoad(IncrOpIndexedNode* node, | 951 Definition* EffectGraphVisitor::BuildIncrOpIndexedLoad( |
| 914 intptr_t start_index) { | 952 IncrOpIndexedNode* node, |
| 953 Value** receiver, | |
| 954 Value** index) { | |
| 915 // Evaluate the receiver and index. | 955 // Evaluate the receiver and index. |
| 916 // t_n <- ... receiver ... | 956 // t_n <- ... receiver ... |
| 917 // t_n+1 <- ... index ... | 957 // t_n+1 <- ... index ... |
| 918 ArgumentGraphVisitor for_receiver(owner(), start_index); | 958 ArgumentGraphVisitor for_receiver(owner(), temp_index()); |
| 919 node->array()->Visit(&for_receiver); | 959 node->array()->Visit(&for_receiver); |
| 920 Append(for_receiver); | 960 Append(for_receiver); |
| 921 ASSERT(for_receiver.temp_index() == start_index + 1); | 961 AllocateTempIndex(); |
| 922 ArgumentGraphVisitor for_index(owner(), start_index + 1); | 962 ASSERT(temp_index() == for_receiver.temp_index()); |
| 963 | |
| 964 ArgumentGraphVisitor for_index(owner(), temp_index()); | |
| 923 node->index()->Visit(&for_index); | 965 node->index()->Visit(&for_index); |
| 924 Append(for_index); | 966 Append(for_index); |
| 925 ASSERT(for_index.temp_index() == start_index + 2); | 967 AllocateTempIndex(); |
| 968 ASSERT(temp_index() == for_index.temp_index()); | |
| 926 | 969 |
| 927 // Duplicate the receiver and index values, load the value. | 970 // Duplicate the receiver and index values, load the value. |
| 928 // t_n+2 <- Pick(t_n) | 971 // t_n+2 <- Pick(t_n) |
| 929 // t_n+3 <- Pick(t_n+1) | 972 // t_n+3 <- Pick(t_n+1) |
| 930 // t_n+2 <- InstanceCall([], t_n+2, t_n+3) | 973 // t_n+2 <- InstanceCall([], t_n+2, t_n+3) |
| 931 const int next_index = start_index + 2; | 974 PickTempInstr* duplicate_receiver = |
| 932 AddInstruction(new PickTempInstr(next_index, start_index)); | 975 new PickTempInstr(temp_index(), temp_index() - 2); |
| 933 AddInstruction(new PickTempInstr(next_index + 1, start_index + 1)); | 976 AddInstruction(duplicate_receiver); |
| 977 PickTempInstr* duplicate_index = | |
| 978 new PickTempInstr(temp_index() + 1, temp_index() - 1); | |
| 979 AddInstruction(duplicate_index); | |
| 934 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); | 980 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); |
| 935 arguments->Add(new TempVal(next_index)); | 981 arguments->Add(new UseVal(duplicate_receiver)); |
| 936 arguments->Add(new TempVal(next_index + 1)); | 982 arguments->Add(new UseVal(duplicate_index)); |
| 937 const String& load_name = | 983 const String& load_name = |
| 938 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); | 984 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); |
| 939 InstanceCallComp* load = new InstanceCallComp( | 985 BindInstr* load = |
| 940 node->load_id(), node->token_index(), owner()->try_index(), | 986 new BindInstr(temp_index(), |
| 941 load_name, arguments, Array::ZoneHandle(), 1); | 987 new InstanceCallComp( |
| 942 AddInstruction(new BindInstr(next_index, load)); | 988 node->load_id(), node->token_index(), |
| 943 return next_index; | 989 owner()->try_index(), load_name, arguments, |
| 990 Array::ZoneHandle(), 1)); | |
| 991 AddInstruction(load); | |
| 992 AllocateTempIndex(); | |
| 993 | |
| 994 *receiver = for_receiver.value(); | |
| 995 *index = for_index.value(); | |
| 996 return load; | |
| 944 } | 997 } |
| 945 | 998 |
| 946 | 999 |
| 947 void EffectGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { | 1000 void EffectGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { |
| 948 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 1001 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 949 // In an effect context, treat postincrement as if it were preincrement | 1002 // In an effect context, treat postincrement as if it were preincrement |
| 950 // because its value is not needed. | 1003 // because its value is not needed. |
| 951 | 1004 |
| 952 // 1. Load the value. | 1005 // 1. Load the value. |
| 953 const int value_index = BuildIncrOpIndexedLoad(node, temp_index()); | 1006 Value* receiver = NULL; |
| 1007 Value* index = NULL; | |
| 1008 Definition* load = BuildIncrOpIndexedLoad(node, &receiver, &index); | |
| 954 // 2. Increment. | 1009 // 2. Increment. |
| 955 BuildIncrOpIncrement(node->kind(), node->operator_id(), node->token_index(), | 1010 Definition* incr = |
| 956 value_index + 1); | 1011 BuildIncrOpIncrement(node->kind(), node->operator_id(), |
| 1012 node->token_index(), new UseVal(load)); | |
| 957 // 3. Perform the store, returning the stored value. | 1013 // 3. Perform the store, returning the stored value. |
| 958 StoreIndexedComp* store = new StoreIndexedComp(node->store_id(), | 1014 StoreIndexedComp* store = new StoreIndexedComp(node->store_id(), |
| 959 node->token_index(), | 1015 node->token_index(), |
| 960 owner()->try_index(), | 1016 owner()->try_index(), |
| 961 new TempVal(value_index - 2), | 1017 receiver, |
| 962 new TempVal(value_index - 1), | 1018 index, |
| 963 new TempVal(value_index)); | 1019 new UseVal(incr)); |
| 1020 DeallocateTempIndex(); // Consuming incr. | |
| 1021 DeallocateTempIndex(); // Consuming index. | |
| 1022 DeallocateTempIndex(); // Consuming receiver. | |
| 964 ReturnComputation(store); | 1023 ReturnComputation(store); |
| 965 } | 1024 } |
| 966 | 1025 |
| 967 | 1026 |
| 968 void ValueGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { | 1027 void ValueGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { |
| 969 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); | 1028 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); |
| 970 if (node->prefix()) { | 1029 if (node->prefix()) { |
| 971 // Base class handles preincrement. | 1030 // Base class handles preincrement. |
| 972 EffectGraphVisitor::VisitIncrOpIndexedNode(node); | 1031 EffectGraphVisitor::VisitIncrOpIndexedNode(node); |
| 973 return; | 1032 return; |
| 974 } | 1033 } |
| 975 // For postincrement, preallocate a temporary to preserve the original | 1034 // For postincrement, preallocate a temporary to preserve the original |
| 976 // value. | 1035 // value. |
| 977 // | 1036 // |
| 978 // 1. Name a placeholder. | 1037 // 1. Name a placeholder. |
| 979 const Smi& placeholder = Smi::ZoneHandle(Smi::New(0)); | 1038 BindInstr* placeholder = |
| 980 AddInstruction(new BindInstr(temp_index(), new ConstantVal(placeholder))); | 1039 new BindInstr(temp_index(), |
| 1040 new ConstantVal(Smi::ZoneHandle(Smi::New(0)))); | |
| 1041 AddInstruction(placeholder); | |
| 1042 AllocateTempIndex(); | |
| 981 // 2. Load the value. | 1043 // 2. Load the value. |
| 982 const int value_index = BuildIncrOpIndexedLoad(node, temp_index() + 1); | 1044 Value* receiver = NULL; |
| 1045 Value* index = NULL; | |
| 1046 Definition* load = BuildIncrOpIndexedLoad(node, &receiver, &index); | |
| 983 // 3. Preserve the original value. | 1047 // 3. Preserve the original value. |
| 984 AddInstruction(new TuckTempInstr(temp_index(), value_index)); | 1048 AddInstruction(new TuckTempInstr(placeholder->temp_index(), |
| 1049 load->temp_index())); | |
| 985 // 4. Increment. | 1050 // 4. Increment. |
| 986 BuildIncrOpIncrement(node->kind(), node->operator_id(), node->token_index(), | 1051 Definition* incr = |
| 987 value_index + 1); | 1052 BuildIncrOpIncrement(node->kind(), node->operator_id(), |
| 1053 node->token_index(), new UseVal(load)); | |
| 988 // 5. Perform the store and return the original value. | 1054 // 5. Perform the store and return the original value. |
| 989 const String& store_name = | 1055 const String& store_name = |
| 990 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); | 1056 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); |
| 991 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(3); | 1057 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(3); |
| 992 arguments->Add(new TempVal(value_index - 2)); | 1058 arguments->Add(receiver); |
| 993 arguments->Add(new TempVal(value_index - 1)); | 1059 arguments->Add(index); |
| 994 arguments->Add(new TempVal(value_index)); | 1060 arguments->Add(new UseVal(incr)); |
| 995 InstanceCallComp* store = new InstanceCallComp( | 1061 InstanceCallComp* store = new InstanceCallComp( |
| 996 node->store_id(), node->token_index(), owner()->try_index(), | 1062 node->store_id(), node->token_index(), owner()->try_index(), |
| 997 store_name, arguments, Array::ZoneHandle(), 1); | 1063 store_name, arguments, Array::ZoneHandle(), 1); |
| 1064 DeallocateTempIndex(); // Consuming incr. | |
| 1065 DeallocateTempIndex(); // Consuming index. | |
| 1066 DeallocateTempIndex(); // Consuming receiver. | |
| 998 AddInstruction(new DoInstr(store)); | 1067 AddInstruction(new DoInstr(store)); |
| 999 ReturnValue(new TempVal(AllocateTempIndex())); | 1068 ReturnValue(new UseVal(placeholder)); |
| 1000 } | 1069 } |
| 1001 | 1070 |
| 1002 | 1071 |
| 1003 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 1072 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 1004 TestGraphVisitor for_test(owner(), | 1073 TestGraphVisitor for_test(owner(), |
| 1005 temp_index(), | 1074 temp_index(), |
| 1006 node->condition()->id(), | 1075 node->condition()->id(), |
| 1007 node->condition()->token_index()); | 1076 node->condition()->token_index()); |
| 1008 node->condition()->Visit(&for_test); | 1077 node->condition()->Visit(&for_test); |
| 1009 | 1078 |
| (...skipping 1834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2844 char* chars = reinterpret_cast<char*>( | 2913 char* chars = reinterpret_cast<char*>( |
| 2845 Isolate::Current()->current_zone()->Allocate(len)); | 2914 Isolate::Current()->current_zone()->Allocate(len)); |
| 2846 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2915 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2847 const Error& error = Error::Handle( | 2916 const Error& error = Error::Handle( |
| 2848 LanguageError::New(String::Handle(String::New(chars)))); | 2917 LanguageError::New(String::Handle(String::New(chars)))); |
| 2849 Isolate::Current()->long_jump_base()->Jump(1, error); | 2918 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2850 } | 2919 } |
| 2851 | 2920 |
| 2852 | 2921 |
| 2853 } // namespace dart | 2922 } // namespace dart |
| OLD | NEW |