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

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

Issue 10905182: Refactor building of StoreStaticField and StoreLocal to manually preserve value. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months 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
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "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 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 202
203 203
204 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { 204 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) {
205 PushArgumentInstr* result = new PushArgumentInstr(value); 205 PushArgumentInstr* result = new PushArgumentInstr(value);
206 AddInstruction(result); 206 AddInstruction(result);
207 return result; 207 return result;
208 } 208 }
209 209
210 210
211 Definition* EffectGraphVisitor::BuildStoreLocal( 211 Definition* EffectGraphVisitor::BuildStoreLocal(
212 const LocalVariable& local, Value* value) { 212 const LocalVariable& local, Value* value, bool result_is_needed) {
213 if (local.is_captured()) { 213 if (local.is_captured()) {
214 if (result_is_needed) {
215 value = Bind(
216 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(),
217 value,
218 kResultNeeded));
219 }
220
214 intptr_t delta = 221 intptr_t delta =
215 owner()->context_level() - local.owner()->context_level(); 222 owner()->context_level() - local.owner()->context_level();
216 ASSERT(delta >= 0); 223 ASSERT(delta >= 0);
217 Value* context = Bind(new CurrentContextInstr()); 224 Value* context = Bind(new CurrentContextInstr());
218 while (delta-- > 0) { 225 while (delta-- > 0) {
219 context = Bind(new LoadVMFieldInstr( 226 context = Bind(new LoadVMFieldInstr(
220 context, Context::parent_offset(), Type::ZoneHandle())); 227 context, Context::parent_offset(), Type::ZoneHandle()));
221 } 228 }
222 return new StoreVMFieldInstr( 229
223 context, 230 StoreVMFieldInstr* store =
224 Context::variable_offset(local.index()), 231 new StoreVMFieldInstr(context,
225 value, 232 Context::variable_offset(local.index()),
226 local.type()); 233 value,
234 local.type());
235 if (result_is_needed) {
236 Do(store);
237 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var());
238 } else {
239 return store;
240 }
227 } else { 241 } else {
228 return new StoreLocalInstr(local, value, owner()->context_level()); 242 return new StoreLocalInstr(local, value, owner()->context_level());
229 } 243 }
230 } 244 }
231 245
232 246
233 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { 247 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) {
234 if (local.is_captured()) { 248 if (local.is_captured()) {
235 intptr_t delta = 249 intptr_t delta =
236 owner()->context_level() - local.owner()->context_level(); 250 owner()->context_level() - local.owner()->context_level();
237 ASSERT(delta >= 0); 251 ASSERT(delta >= 0);
238 Value* context = Bind(new CurrentContextInstr()); 252 Value* context = Bind(new CurrentContextInstr());
239 while (delta-- > 0) { 253 while (delta-- > 0) {
240 context = Bind(new LoadVMFieldInstr( 254 context = Bind(new LoadVMFieldInstr(
241 context, Context::parent_offset(), Type::ZoneHandle())); 255 context, Context::parent_offset(), Type::ZoneHandle()));
242 } 256 }
243 return new LoadVMFieldInstr(context, 257 return new LoadVMFieldInstr(context,
244 Context::variable_offset(local.index()), 258 Context::variable_offset(local.index()),
245 local.type()); 259 local.type());
246 } else { 260 } else {
247 return new LoadLocalInstr(local, owner()->context_level()); 261 return new LoadLocalInstr(local, owner()->context_level());
248 } 262 }
249 } 263 }
250 264
251 265
252 // Stores current context into the 'variable' 266 // Stores current context into the 'variable'
253 void EffectGraphVisitor::BuildStoreContext(const LocalVariable& variable) { 267 void EffectGraphVisitor::BuildStoreContext(const LocalVariable& variable) {
254 Value* context = Bind(new CurrentContextInstr()); 268 Value* context = Bind(new CurrentContextInstr());
255 Do(BuildStoreLocal(variable, context)); 269 Do(BuildStoreLocal(variable, context, kResultNotNeeded));
256 } 270 }
257 271
258 272
259 // Loads context saved in 'context_variable' into the current context. 273 // Loads context saved in 'context_variable' into the current context.
260 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) { 274 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) {
261 Value* load_saved_context = Bind(BuildLoadLocal(variable)); 275 Value* load_saved_context = Bind(BuildLoadLocal(variable));
262 Do(new StoreContextInstr(load_saved_context)); 276 Do(new StoreContextInstr(load_saved_context));
263 } 277 }
264 278
265 279
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(), 665 for_right.Bind(new AssertBooleanInstr(node->right()->token_pos(),
652 right_value)); 666 right_value));
653 } 667 }
654 Value* constant_true = for_right.Bind(new ConstantInstr(bool_true)); 668 Value* constant_true = for_right.Bind(new ConstantInstr(bool_true));
655 Value* compare = 669 Value* compare =
656 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT, 670 for_right.Bind(new StrictCompareInstr(Token::kEQ_STRICT,
657 right_value, 671 right_value,
658 constant_true)); 672 constant_true));
659 for_right.Do(BuildStoreLocal( 673 for_right.Do(BuildStoreLocal(
660 *owner()->parsed_function().expression_temp_var(), 674 *owner()->parsed_function().expression_temp_var(),
661 compare)); 675 compare,
676 kResultNotNeeded));
Florian Schneider 2012/09/10 14:38:21 The parameter result_not_needed is not needed when
Vyacheslav Egorov (Google) 2012/09/10 16:00:14 Done.
662 677
663 if (node->kind() == Token::kAND) { 678 if (node->kind() == Token::kAND) {
664 ValueGraphVisitor for_false(owner(), temp_index()); 679 ValueGraphVisitor for_false(owner(), temp_index());
665 Value* constant_false = for_false.Bind(new ConstantInstr(bool_false)); 680 Value* constant_false = for_false.Bind(new ConstantInstr(bool_false));
666 for_false.Do(BuildStoreLocal( 681 for_false.Do(BuildStoreLocal(
667 *owner()->parsed_function().expression_temp_var(), 682 *owner()->parsed_function().expression_temp_var(),
668 constant_false)); 683 constant_false,
684 kResultNotNeeded));
669 Join(for_test, for_right, for_false); 685 Join(for_test, for_right, for_false);
670 } else { 686 } else {
671 ASSERT(node->kind() == Token::kOR); 687 ASSERT(node->kind() == Token::kOR);
672 ValueGraphVisitor for_true(owner(), temp_index()); 688 ValueGraphVisitor for_true(owner(), temp_index());
673 Value* constant_true = for_true.Bind(new ConstantInstr(bool_true)); 689 Value* constant_true = for_true.Bind(new ConstantInstr(bool_true));
674 for_true.Do(BuildStoreLocal( 690 for_true.Do(BuildStoreLocal(
675 *owner()->parsed_function().expression_temp_var(), 691 *owner()->parsed_function().expression_temp_var(),
676 constant_true)); 692 constant_true,
693 kResultNotNeeded));
677 Join(for_test, for_true, for_right); 694 Join(for_test, for_true, for_right);
678 } 695 }
679 ReturnDefinition( 696 ReturnDefinition(
680 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); 697 BuildLoadLocal(*owner()->parsed_function().expression_temp_var()));
681 return; 698 return;
682 } 699 }
683 EffectGraphVisitor::VisitBinaryOpNode(node); 700 EffectGraphVisitor::VisitBinaryOpNode(node);
684 } 701 }
685 702
686 703
(...skipping 11 matching lines...) Expand all
698 instantiator = BuildInstantiator(); 715 instantiator = BuildInstantiator();
699 if (instantiator == NULL) { 716 if (instantiator == NULL) {
700 // No instantiator when inside factory. 717 // No instantiator when inside factory.
701 instantiator = BuildNullValue(); 718 instantiator = BuildNullValue();
702 instantiator_type_arguments = 719 instantiator_type_arguments =
703 BuildInstantiatorTypeArguments(token_pos, NULL); 720 BuildInstantiatorTypeArguments(token_pos, NULL);
704 } else { 721 } else {
705 // Preserve instantiator. 722 // Preserve instantiator.
706 const LocalVariable& expr_temp = 723 const LocalVariable& expr_temp =
707 *owner()->parsed_function().expression_temp_var(); 724 *owner()->parsed_function().expression_temp_var();
708 instantiator = Bind(BuildStoreLocal(expr_temp, instantiator)); 725 instantiator = Bind(BuildStoreLocal(expr_temp,
726 instantiator,
727 kResultNotNeeded));
709 Value* loaded = Bind(BuildLoadLocal(expr_temp)); 728 Value* loaded = Bind(BuildLoadLocal(expr_temp));
710 instantiator_type_arguments = 729 instantiator_type_arguments =
711 BuildInstantiatorTypeArguments(token_pos, loaded); 730 BuildInstantiatorTypeArguments(token_pos, loaded);
712 } 731 }
713 *instantiator_result = instantiator; 732 *instantiator_result = instantiator;
714 *instantiator_type_arguments_result = instantiator_type_arguments; 733 *instantiator_type_arguments_result = instantiator_type_arguments;
715 } 734 }
716 735
717 736
718 Value* EffectGraphVisitor::BuildNullValue() { 737 Value* EffectGraphVisitor::BuildNullValue() {
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 InlineBailout("ValueGraphVisitor::VisitConditionalExprNode"); 1020 InlineBailout("ValueGraphVisitor::VisitConditionalExprNode");
1002 TestGraphVisitor for_test(owner(), 1021 TestGraphVisitor for_test(owner(),
1003 temp_index(), 1022 temp_index(),
1004 node->condition()->token_pos()); 1023 node->condition()->token_pos());
1005 node->condition()->Visit(&for_test); 1024 node->condition()->Visit(&for_test);
1006 1025
1007 ValueGraphVisitor for_true(owner(), temp_index()); 1026 ValueGraphVisitor for_true(owner(), temp_index());
1008 node->true_expr()->Visit(&for_true); 1027 node->true_expr()->Visit(&for_true);
1009 ASSERT(for_true.is_open()); 1028 ASSERT(for_true.is_open());
1010 for_true.Do(BuildStoreLocal( 1029 for_true.Do(BuildStoreLocal(
1011 *owner()->parsed_function().expression_temp_var(), for_true.value())); 1030 *owner()->parsed_function().expression_temp_var(),
1031 for_true.value(),
1032 kResultNotNeeded));
1012 1033
1013 ValueGraphVisitor for_false(owner(), temp_index()); 1034 ValueGraphVisitor for_false(owner(), temp_index());
1014 node->false_expr()->Visit(&for_false); 1035 node->false_expr()->Visit(&for_false);
1015 ASSERT(for_false.is_open()); 1036 ASSERT(for_false.is_open());
1016 for_false.Do(BuildStoreLocal( 1037 for_false.Do(BuildStoreLocal(
1017 *owner()->parsed_function().expression_temp_var(), for_false.value())); 1038 *owner()->parsed_function().expression_temp_var(),
1039 for_false.value(),
1040 kResultNotNeeded));
1018 1041
1019 Join(for_test, for_true, for_false); 1042 Join(for_test, for_true, for_false);
1020 ReturnDefinition( 1043 ReturnDefinition(
1021 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); 1044 BuildLoadLocal(*owner()->parsed_function().expression_temp_var()));
1022 } 1045 }
1023 1046
1024 1047
1025 // <Statement> ::= If { condition: <Expression> 1048 // <Statement> ::= If { condition: <Expression>
1026 // true_branch: <Sequence> 1049 // true_branch: <Sequence>
1027 // false_branch: <Sequence> } 1050 // false_branch: <Sequence> }
(...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 // t_n <- t2 1829 // t_n <- t2
1807 // t_n+1 <- t1 1830 // t_n+1 <- t1
1808 // Use expression_temp_var and node->allocated_object_var() locals to keep 1831 // Use expression_temp_var and node->allocated_object_var() locals to keep
1809 // intermediate results around (t1 and t2 above). 1832 // intermediate results around (t1 and t2 above).
1810 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); 1833 ASSERT(owner()->parsed_function().expression_temp_var() != NULL);
1811 const LocalVariable& t1 = *owner()->parsed_function().expression_temp_var(); 1834 const LocalVariable& t1 = *owner()->parsed_function().expression_temp_var();
1812 const LocalVariable& t2 = node->allocated_object_var(); 1835 const LocalVariable& t2 = node->allocated_object_var();
1813 Value* instantiator_type_arguments = BuildInstantiatorTypeArguments( 1836 Value* instantiator_type_arguments = BuildInstantiatorTypeArguments(
1814 node->token_pos(), NULL); 1837 node->token_pos(), NULL);
1815 Value* stored_instantiator = 1838 Value* stored_instantiator =
1816 Bind(BuildStoreLocal(t1, instantiator_type_arguments)); 1839 Bind(BuildStoreLocal(t1, instantiator_type_arguments, kResultNeeded));
1817 // t1: instantiator type arguments. 1840 // t1: instantiator type arguments.
1818 1841
1819 Value* extract_type_arguments = Bind( 1842 Value* extract_type_arguments = Bind(
1820 new ExtractConstructorTypeArgumentsInstr( 1843 new ExtractConstructorTypeArgumentsInstr(
1821 node->token_pos(), 1844 node->token_pos(),
1822 node->type_arguments(), 1845 node->type_arguments(),
1823 stored_instantiator)); 1846 stored_instantiator));
1824 1847
1825 Do(BuildStoreLocal(t2, extract_type_arguments)); 1848 Do(BuildStoreLocal(t2, extract_type_arguments, kResultNotNeeded));
1826 // t2: extracted constructor type arguments. 1849 // t2: extracted constructor type arguments.
1827 Value* load_instantiator = Bind(BuildLoadLocal(t1)); 1850 Value* load_instantiator = Bind(BuildLoadLocal(t1));
1828 1851
1829 Value* extract_instantiator = 1852 Value* extract_instantiator =
1830 Bind(new ExtractConstructorInstantiatorInstr(node, load_instantiator)); 1853 Bind(new ExtractConstructorInstantiatorInstr(node, load_instantiator));
1831 Do(BuildStoreLocal(t1, extract_instantiator)); 1854 Do(BuildStoreLocal(t1, extract_instantiator, kResultNotNeeded));
1832 // t2: extracted constructor type arguments. 1855 // t2: extracted constructor type arguments.
1833 // t1: extracted constructor instantiator. 1856 // t1: extracted constructor instantiator.
1834 Value* type_arguments_val = Bind(BuildLoadLocal(t2)); 1857 Value* type_arguments_val = Bind(BuildLoadLocal(t2));
1835 if (call_arguments != NULL) { 1858 if (call_arguments != NULL) {
1836 ASSERT(type_arguments == NULL); 1859 ASSERT(type_arguments == NULL);
1837 call_arguments->Add(PushArgument(type_arguments_val)); 1860 call_arguments->Add(PushArgument(type_arguments_val));
1838 } else { 1861 } else {
1839 ASSERT(type_arguments != NULL); 1862 ASSERT(type_arguments != NULL);
1840 *type_arguments = type_arguments_val; 1863 *type_arguments = type_arguments_val;
1841 } 1864 }
(...skipping 20 matching lines...) Expand all
1862 // t_n <- AllocateObject(class) 1885 // t_n <- AllocateObject(class)
1863 // t_n <- StoreLocal(temp, t_n); 1886 // t_n <- StoreLocal(temp, t_n);
1864 // t_n+1 <- ctor-arg 1887 // t_n+1 <- ctor-arg
1865 // t_n+2... <- constructor arguments start here 1888 // t_n+2... <- constructor arguments start here
1866 // StaticCall(constructor, t_n, t_n+1, ...) 1889 // StaticCall(constructor, t_n, t_n+1, ...)
1867 // tn <- LoadLocal(temp) 1890 // tn <- LoadLocal(temp)
1868 1891
1869 Value* allocate = BuildObjectAllocation(node); 1892 Value* allocate = BuildObjectAllocation(node);
1870 Definition* store_allocated = BuildStoreLocal( 1893 Definition* store_allocated = BuildStoreLocal(
1871 node->allocated_object_var(), 1894 node->allocated_object_var(),
1872 allocate); 1895 allocate,
1896 kResultNeeded);
1873 Value* allocated_value = Bind(store_allocated); 1897 Value* allocated_value = Bind(store_allocated);
Florian Schneider 2012/09/10 14:38:21 Maybe rephrase this for consistency: Value* alloc
Vyacheslav Egorov (Google) 2012/09/10 16:00:14 Done.
1874 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); 1898 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value);
1875 BuildConstructorCall(node, push_allocated_value); 1899 BuildConstructorCall(node, push_allocated_value);
1876 Definition* load_allocated = BuildLoadLocal( 1900 Definition* load_allocated = BuildLoadLocal(
1877 node->allocated_object_var()); 1901 node->allocated_object_var());
1878 allocated_value = Bind(load_allocated); 1902 allocated_value = Bind(load_allocated);
1879 ReturnValue(allocated_value); 1903 ReturnValue(allocated_value);
1880 } 1904 }
1881 1905
1882 1906
1883 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { 1907 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
(...skipping 25 matching lines...) Expand all
1909 arguments->Add(PushArgument(for_receiver.value())); 1933 arguments->Add(PushArgument(for_receiver.value()));
1910 1934
1911 ValueGraphVisitor for_value(owner(), temp_index()); 1935 ValueGraphVisitor for_value(owner(), temp_index());
1912 node->value()->Visit(&for_value); 1936 node->value()->Visit(&for_value);
1913 Append(for_value); 1937 Append(for_value);
1914 1938
1915 Value* value = NULL; 1939 Value* value = NULL;
1916 if (result_is_needed) { 1940 if (result_is_needed) {
1917 value = Bind( 1941 value = Bind(
1918 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), 1942 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(),
1919 for_value.value())); 1943 for_value.value(),
1944 kResultNeeded));
1920 } else { 1945 } else {
1921 value = for_value.value(); 1946 value = for_value.value();
1922 } 1947 }
1923 arguments->Add(PushArgument(value)); 1948 arguments->Add(PushArgument(value));
1924 } 1949 }
1925 1950
1926 1951
1927 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 1952 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
1928 InlineBailout("EffectGraphVisitor::VisitInstanceSetterNode"); 1953 InlineBailout("EffectGraphVisitor::VisitInstanceSetterNode");
1929 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1954 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1930 new ZoneGrowableArray<PushArgumentInstr*>(2); 1955 new ZoneGrowableArray<PushArgumentInstr*>(2);
1931 BuildInstanceSetterArguments(node, arguments, false); // Value not used. 1956 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded);
1932 const String& name = 1957 const String& name =
1933 String::ZoneHandle(Field::SetterSymbol(node->field_name())); 1958 String::ZoneHandle(Field::SetterSymbol(node->field_name()));
1934 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), 1959 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(),
1935 name, 1960 name,
1936 Token::kSET, 1961 Token::kSET,
1937 arguments, 1962 arguments,
1938 Array::ZoneHandle(), 1963 Array::ZoneHandle(),
1939 1); // Checked arg count. 1964 1); // Checked arg count.
1940 ReturnDefinition(call); 1965 ReturnDefinition(call);
1941 } 1966 }
1942 1967
1943 1968
1944 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 1969 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
1945 InlineBailout("ValueGraphVisitor::VisitInstanceSetterNode"); 1970 InlineBailout("ValueGraphVisitor::VisitInstanceSetterNode");
1946 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1971 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1947 new ZoneGrowableArray<PushArgumentInstr*>(2); 1972 new ZoneGrowableArray<PushArgumentInstr*>(2);
1948 BuildInstanceSetterArguments(node, arguments, true); // Value used. 1973 BuildInstanceSetterArguments(node, arguments, kResultNeeded);
1949 const String& name = 1974 const String& name =
1950 String::ZoneHandle(Field::SetterSymbol(node->field_name())); 1975 String::ZoneHandle(Field::SetterSymbol(node->field_name()));
1951 Do(new InstanceCallInstr(node->token_pos(), 1976 Do(new InstanceCallInstr(node->token_pos(),
1952 name, 1977 name,
1953 Token::kSET, 1978 Token::kSET,
1954 arguments, 1979 arguments,
1955 Array::ZoneHandle(), 1980 Array::ZoneHandle(),
1956 1)); // Checked argument count. 1981 1)); // Checked argument count.
1957 ReturnDefinition( 1982 ReturnDefinition(
1958 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); 1983 BuildLoadLocal(*owner()->parsed_function().expression_temp_var()));
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2012 Append(for_receiver); 2037 Append(for_receiver);
2013 arguments->Add(PushArgument(for_receiver.value())); 2038 arguments->Add(PushArgument(for_receiver.value()));
2014 } 2039 }
2015 ValueGraphVisitor for_value(owner(), temp_index()); 2040 ValueGraphVisitor for_value(owner(), temp_index());
2016 node->value()->Visit(&for_value); 2041 node->value()->Visit(&for_value);
2017 Append(for_value); 2042 Append(for_value);
2018 Value* value = NULL; 2043 Value* value = NULL;
2019 if (result_is_needed) { 2044 if (result_is_needed) {
2020 value = Bind( 2045 value = Bind(
2021 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), 2046 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(),
2022 for_value.value())); 2047 for_value.value(),
2048 kResultNeeded));
2023 } else { 2049 } else {
2024 value = for_value.value(); 2050 value = for_value.value();
2025 } 2051 }
2026 arguments->Add(PushArgument(value)); 2052 arguments->Add(PushArgument(value));
2027 2053
2028 StaticCallInstr* call = new StaticCallInstr(node->token_pos(), 2054 StaticCallInstr* call = new StaticCallInstr(node->token_pos(),
2029 setter_function, 2055 setter_function,
2030 Array::ZoneHandle(), // No names. 2056 Array::ZoneHandle(), // No names.
2031 arguments); 2057 arguments);
2032 if (result_is_needed) { 2058 if (result_is_needed) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2079 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { 2105 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
2080 InlineBailout("ValueGraphVisitor::VisitLoadLocalNode"); 2106 InlineBailout("ValueGraphVisitor::VisitLoadLocalNode");
2081 EffectGraphVisitor::VisitLoadLocalNode(node); 2107 EffectGraphVisitor::VisitLoadLocalNode(node);
2082 Definition* load = BuildLoadLocal(node->local()); 2108 Definition* load = BuildLoadLocal(node->local());
2083 ReturnDefinition(load); 2109 ReturnDefinition(load);
2084 } 2110 }
2085 2111
2086 2112
2087 // <Expression> ::= StoreLocal { local: LocalVariable 2113 // <Expression> ::= StoreLocal { local: LocalVariable
2088 // value: <Expression> } 2114 // value: <Expression> }
2089 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { 2115 void EffectGraphVisitor::VisitStoreLocal(StoreLocalNode* node,
Florian Schneider 2012/09/10 14:38:21 Maybe HandleStoreLocal, otherwise it looks like a
Vyacheslav Egorov (Google) 2012/09/10 16:00:14 Done.
2116 bool result_is_needed) {
2090 InlineBailout("EffectGraphVisitor::VisitStoreLocalNode"); 2117 InlineBailout("EffectGraphVisitor::VisitStoreLocalNode");
2091 ValueGraphVisitor for_value(owner(), temp_index()); 2118 ValueGraphVisitor for_value(owner(), temp_index());
2092 node->value()->Visit(&for_value); 2119 node->value()->Visit(&for_value);
2093 Append(for_value); 2120 Append(for_value);
2094 Value* store_value = for_value.value(); 2121 Value* store_value = for_value.value();
2095 if (FLAG_enable_type_checks) { 2122 if (FLAG_enable_type_checks) {
2096 store_value = BuildAssignableValue(node->value()->token_pos(), 2123 store_value = BuildAssignableValue(node->value()->token_pos(),
2097 store_value, 2124 store_value,
2098 node->local().type(), 2125 node->local().type(),
2099 node->local().name()); 2126 node->local().name());
2100 } 2127 }
2101 Definition* store = BuildStoreLocal(node->local(), store_value); 2128 Definition* store = BuildStoreLocal(node->local(),
2129 store_value,
2130 result_is_needed);
2102 ReturnDefinition(store); 2131 ReturnDefinition(store);
2103 } 2132 }
2104 2133
2105 2134
2135 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
2136 VisitStoreLocal(node, kResultNotNeeded);
2137 }
2138
2139
2140 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
2141 VisitStoreLocal(node, kResultNeeded);
2142 }
2143
2144
2106 void EffectGraphVisitor::VisitLoadInstanceFieldNode( 2145 void EffectGraphVisitor::VisitLoadInstanceFieldNode(
2107 LoadInstanceFieldNode* node) { 2146 LoadInstanceFieldNode* node) {
2108 InlineBailout("EffectGraphVisitor::VisitLoadInstanceFieldNode"); 2147 InlineBailout("EffectGraphVisitor::VisitLoadInstanceFieldNode");
2109 ValueGraphVisitor for_instance(owner(), temp_index()); 2148 ValueGraphVisitor for_instance(owner(), temp_index());
2110 node->instance()->Visit(&for_instance); 2149 node->instance()->Visit(&for_instance);
2111 Append(for_instance); 2150 Append(for_instance);
2112 LoadInstanceFieldInstr* load = new LoadInstanceFieldInstr( 2151 LoadInstanceFieldInstr* load = new LoadInstanceFieldInstr(
2113 node->field(), for_instance.value()); 2152 node->field(), for_instance.value());
2114 ReturnDefinition(load); 2153 ReturnDefinition(load);
2115 } 2154 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2147 } 2186 }
2148 2187
2149 2188
2150 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { 2189 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
2151 InlineBailout("EffectGraphVisitor::VisitLoadStaticFieldNode"); 2190 InlineBailout("EffectGraphVisitor::VisitLoadStaticFieldNode");
2152 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field()); 2191 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(node->field());
2153 ReturnDefinition(load); 2192 ReturnDefinition(load);
2154 } 2193 }
2155 2194
2156 2195
2157 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { 2196 Definition* EffectGraphVisitor::BuildStoreStaticField(
2197 StoreStaticFieldNode* node, bool result_is_needed) {
2158 InlineBailout("EffectGraphVisitor::VisitStoreStaticFieldNode"); 2198 InlineBailout("EffectGraphVisitor::VisitStoreStaticFieldNode");
2159 ValueGraphVisitor for_value(owner(), temp_index()); 2199 ValueGraphVisitor for_value(owner(), temp_index());
2160 node->value()->Visit(&for_value); 2200 node->value()->Visit(&for_value);
2161 Append(for_value); 2201 Append(for_value);
2162 Value* store_value = for_value.value(); 2202 Value* store_value = NULL;
2203 if (result_is_needed) {
2204 store_value = Bind(
2205 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(),
Florian Schneider 2012/09/10 14:38:21 I'd have a separate helper to avoid confusion: B
Vyacheslav Egorov (Google) 2012/09/10 16:00:14 Done.
2206 for_value.value(),
2207 kResultNeeded));
2208 } else {
2209 store_value = for_value.value();
2210 }
2163 if (FLAG_enable_type_checks) { 2211 if (FLAG_enable_type_checks) {
2164 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); 2212 const AbstractType& type = AbstractType::ZoneHandle(node->field().type());
2165 const String& dst_name = String::ZoneHandle(node->field().name()); 2213 const String& dst_name = String::ZoneHandle(node->field().name());
2166 store_value = BuildAssignableValue(node->value()->token_pos(), 2214 store_value = BuildAssignableValue(node->value()->token_pos(),
2167 store_value, 2215 store_value,
2168 type, 2216 type,
2169 dst_name); 2217 dst_name);
2170 } 2218 }
2171 StoreStaticFieldInstr* store = 2219 StoreStaticFieldInstr* store =
2172 new StoreStaticFieldInstr(node->field(), store_value); 2220 new StoreStaticFieldInstr(node->field(), store_value);
2173 ReturnDefinition(store); 2221
2222 if (result_is_needed) {
2223 Do(store);
2224 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var());
2225 } else {
2226 return store;
2227 }
2174 } 2228 }
2175 2229
2176 2230
2231 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
2232 ReturnDefinition(BuildStoreStaticField(node, kResultNotNeeded));
2233 }
2234
2235
2236 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
2237 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded));
2238 }
2239
2240
2177 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { 2241 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
2178 InlineBailout("EffectGraphVisitor::VisitLoadIndexedNode"); 2242 InlineBailout("EffectGraphVisitor::VisitLoadIndexedNode");
2179 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2243 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2180 new ZoneGrowableArray<PushArgumentInstr*>(2); 2244 new ZoneGrowableArray<PushArgumentInstr*>(2);
2181 ValueGraphVisitor for_array(owner(), temp_index()); 2245 ValueGraphVisitor for_array(owner(), temp_index());
2182 node->array()->Visit(&for_array); 2246 node->array()->Visit(&for_array);
2183 Append(for_array); 2247 Append(for_array);
2184 arguments->Add(PushArgument(for_array.value())); 2248 arguments->Add(PushArgument(for_array.value()));
2185 2249
2186 ValueGraphVisitor for_index(owner(), temp_index()); 2250 ValueGraphVisitor for_index(owner(), temp_index());
(...skipping 30 matching lines...) Expand all
2217 Append(for_index); 2281 Append(for_index);
2218 arguments->Add(PushArgument(for_index.value())); 2282 arguments->Add(PushArgument(for_index.value()));
2219 2283
2220 ValueGraphVisitor for_value(owner(), temp_index()); 2284 ValueGraphVisitor for_value(owner(), temp_index());
2221 node->value()->Visit(&for_value); 2285 node->value()->Visit(&for_value);
2222 Append(for_value); 2286 Append(for_value);
2223 Value* value = NULL; 2287 Value* value = NULL;
2224 if (result_is_needed) { 2288 if (result_is_needed) {
2225 value = Bind( 2289 value = Bind(
2226 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), 2290 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(),
2227 for_value.value())); 2291 for_value.value(),
2292 kResultNeeded));
2228 } else { 2293 } else {
2229 value = for_value.value(); 2294 value = for_value.value();
2230 } 2295 }
2231 arguments->Add(PushArgument(value)); 2296 arguments->Add(PushArgument(value));
2232 2297
2233 const intptr_t checked_argument_count = 1; 2298 const intptr_t checked_argument_count = 1;
2234 const String& name = 2299 const String& name =
2235 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX))); 2300 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX)));
2236 InstanceCallInstr* store = new InstanceCallInstr(node->token_pos(), 2301 InstanceCallInstr* store = new InstanceCallInstr(node->token_pos(),
2237 name, 2302 name,
2238 Token::kASSIGN_INDEX, 2303 Token::kASSIGN_INDEX,
2239 arguments, 2304 arguments,
2240 Array::ZoneHandle(), 2305 Array::ZoneHandle(),
2241 checked_argument_count); 2306 checked_argument_count);
2242 if (result_is_needed) { 2307 if (result_is_needed) {
2243 Do(store); 2308 Do(store);
2244 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var()); 2309 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var());
2245 } else { 2310 } else {
2246 return store; 2311 return store;
2247 } 2312 }
2248 } 2313 }
2249 2314
2250 2315
2251 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { 2316 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
2252 InlineBailout("EffectGraphVisitor::VisitStoreIndexedNode"); 2317 InlineBailout("EffectGraphVisitor::VisitStoreIndexedNode");
2253 ReturnDefinition(BuildStoreIndexedValues(node, 2318 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded));
2254 false)); // Result not needed.
2255 } 2319 }
2256 2320
2257 2321
2258 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { 2322 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
2259 InlineBailout("ValueGraphVisitor::VisitStoreIndexedNode"); 2323 InlineBailout("ValueGraphVisitor::VisitStoreIndexedNode");
2260 ReturnDefinition(BuildStoreIndexedValues(node, 2324 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded));
2261 true)); // Result is needed.
2262 } 2325 }
2263 2326
2264 2327
2265 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { 2328 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const {
2266 return (node == owner()->parsed_function().node_sequence()) && 2329 return (node == owner()->parsed_function().node_sequence()) &&
2267 (owner()->parsed_function().saved_context_var() != NULL); 2330 (owner()->parsed_function().saved_context_var() != NULL);
2268 } 2331 }
2269 2332
2270 2333
2271 void EffectGraphVisitor::UnchainContext() { 2334 void EffectGraphVisitor::UnchainContext() {
(...skipping 24 matching lines...) Expand all
2296 Bind(new AllocateContextInstr(node->token_pos(), 2359 Bind(new AllocateContextInstr(node->token_pos(),
2297 num_context_variables)); 2360 num_context_variables));
2298 2361
2299 // If this node_sequence is the body of the function being compiled, and if 2362 // If this node_sequence is the body of the function being compiled, and if
2300 // this function is not a closure, do not link the current context as the 2363 // this function is not a closure, do not link the current context as the
2301 // parent of the newly allocated context, as it is not accessible. Instead, 2364 // parent of the newly allocated context, as it is not accessible. Instead,
2302 // save it in a pre-allocated variable and restore it on exit. 2365 // save it in a pre-allocated variable and restore it on exit.
2303 if (MustSaveRestoreContext(node)) { 2366 if (MustSaveRestoreContext(node)) {
2304 Value* current_context = Bind(new CurrentContextInstr()); 2367 Value* current_context = Bind(new CurrentContextInstr());
2305 Do(BuildStoreLocal(*owner()->parsed_function().saved_context_var(), 2368 Do(BuildStoreLocal(*owner()->parsed_function().saved_context_var(),
2306 current_context)); 2369 current_context,
2370 kResultNotNeeded));
2307 Value* null_context = Bind(new ConstantInstr(Object::ZoneHandle())); 2371 Value* null_context = Bind(new ConstantInstr(Object::ZoneHandle()));
2308 Do(new StoreContextInstr(null_context)); 2372 Do(new StoreContextInstr(null_context));
2309 } 2373 }
2310 2374
2311 Do(new ChainContextInstr(allocated_context)); 2375 Do(new ChainContextInstr(allocated_context));
2312 owner()->set_context_level(scope->context_level()); 2376 owner()->set_context_level(scope->context_level());
2313 2377
2314 // If this node_sequence is the body of the function being compiled, copy 2378 // If this node_sequence is the body of the function being compiled, copy
2315 // the captured parameters from the frame into the context. 2379 // the captured parameters from the frame into the context.
2316 if (node == owner()->parsed_function().node_sequence()) { 2380 if (node == owner()->parsed_function().node_sequence()) {
(...skipping 15 matching lines...) Expand all
2332 const String& temp_name = String::ZoneHandle(String::Concat( 2396 const String& temp_name = String::ZoneHandle(String::Concat(
2333 parameter.name(), String::Handle(Symbols::New("-orig")))); 2397 parameter.name(), String::Handle(Symbols::New("-orig"))));
2334 LocalVariable* temp_local = new LocalVariable( 2398 LocalVariable* temp_local = new LocalVariable(
2335 0, // Token index. 2399 0, // Token index.
2336 temp_name, 2400 temp_name,
2337 Type::ZoneHandle(Type::DynamicType())); // Type. 2401 Type::ZoneHandle(Type::DynamicType())); // Type.
2338 temp_local->set_index(param_frame_index); 2402 temp_local->set_index(param_frame_index);
2339 2403
2340 // Copy parameter from local frame to current context. 2404 // Copy parameter from local frame to current context.
2341 Value* load = Bind(BuildLoadLocal(*temp_local)); 2405 Value* load = Bind(BuildLoadLocal(*temp_local));
2342 Do(BuildStoreLocal(parameter, load)); 2406 Do(BuildStoreLocal(parameter, load, kResultNotNeeded));
2343 // Write NULL to the source location to detect buggy accesses and 2407 // Write NULL to the source location to detect buggy accesses and
2344 // allow GC of passed value if it gets overwritten by a new value in 2408 // allow GC of passed value if it gets overwritten by a new value in
2345 // the function. 2409 // the function.
2346 Value* null_constant = 2410 Value* null_constant =
2347 Bind(new ConstantInstr(Object::ZoneHandle())); 2411 Bind(new ConstantInstr(Object::ZoneHandle()));
2348 Do(BuildStoreLocal(*temp_local, null_constant)); 2412 Do(BuildStoreLocal(*temp_local, null_constant, kResultNotNeeded));
2349 } 2413 }
2350 } 2414 }
2351 } 2415 }
2352 } 2416 }
2353 2417
2354 if (FLAG_enable_type_checks && 2418 if (FLAG_enable_type_checks &&
2355 (node == owner()->parsed_function().node_sequence())) { 2419 (node == owner()->parsed_function().node_sequence())) {
2356 InlineBailout("EffectGraphVisitor::VisitSequenceNode (type check)"); 2420 InlineBailout("EffectGraphVisitor::VisitSequenceNode (type check)");
2357 const Function& function = owner()->parsed_function().function(); 2421 const Function& function = owner()->parsed_function().function();
2358 const int num_params = function.NumberOfParameters(); 2422 const int num_params = function.NumberOfParameters();
(...skipping 16 matching lines...) Expand all
2375 Value* parameter_value = Bind(BuildLoadLocal(parameter)); 2439 Value* parameter_value = Bind(BuildLoadLocal(parameter));
2376 AssertAssignableInstr* assert_assignable = 2440 AssertAssignableInstr* assert_assignable =
2377 BuildAssertAssignable(parameter.token_pos(), 2441 BuildAssertAssignable(parameter.token_pos(),
2378 parameter_value, 2442 parameter_value,
2379 parameter.type(), 2443 parameter.type(),
2380 parameter.name()); 2444 parameter.name());
2381 parameter_value = Bind(assert_assignable); 2445 parameter_value = Bind(assert_assignable);
2382 // Store the type checked argument back to its corresponding local 2446 // Store the type checked argument back to its corresponding local
2383 // variable so that ssa renaming detects the dependency and makes use 2447 // variable so that ssa renaming detects the dependency and makes use
2384 // of the checked type in type propagation. 2448 // of the checked type in type propagation.
2385 Do(BuildStoreLocal(parameter, parameter_value)); 2449 Do(BuildStoreLocal(parameter, parameter_value, kResultNotNeeded));
2386 } 2450 }
2387 pos++; 2451 pos++;
2388 } 2452 }
2389 } 2453 }
2390 2454
2391 intptr_t i = 0; 2455 intptr_t i = 0;
2392 while (is_open() && (i < node->length())) { 2456 while (is_open() && (i < node->length())) {
2393 EffectGraphVisitor for_effect(owner(), temp_index()); 2457 EffectGraphVisitor for_effect(owner(), temp_index());
2394 node->NodeAt(i++)->Visit(&for_effect); 2458 node->NodeAt(i++)->Visit(&for_effect);
2395 Append(for_effect); 2459 Append(for_effect);
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
2611 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 2675 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
2612 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 2676 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
2613 OS::SNPrint(chars, len, kFormat, function_name, reason); 2677 OS::SNPrint(chars, len, kFormat, function_name, reason);
2614 const Error& error = Error::Handle( 2678 const Error& error = Error::Handle(
2615 LanguageError::New(String::Handle(String::New(chars)))); 2679 LanguageError::New(String::Handle(String::New(chars))));
2616 Isolate::Current()->long_jump_base()->Jump(1, error); 2680 Isolate::Current()->long_jump_base()->Jump(1, error);
2617 } 2681 }
2618 2682
2619 2683
2620 } // namespace dart 2684 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698