| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 2465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2476 LocalVariable* var = | 2476 LocalVariable* var = |
| 2477 new(Z) LocalVariable(0, | 2477 new(Z) LocalVariable(0, |
| 2478 String::ZoneHandle(Z, Symbols::New(name)), | 2478 String::ZoneHandle(Z, Symbols::New(name)), |
| 2479 *value->Type()->ToAbstractType()); | 2479 *value->Type()->ToAbstractType()); |
| 2480 var->set_index(index); | 2480 var->set_index(index); |
| 2481 return var; | 2481 return var; |
| 2482 } | 2482 } |
| 2483 | 2483 |
| 2484 | 2484 |
| 2485 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) { | 2485 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) { |
| 2486 Value* tmp = Bind(new(Z) LoadLocalInstr(*var)); | 2486 Value* tmp = Bind(new(Z) LoadLocalInstr(*var)); |
| 2487 owner()->DeallocateTemps(1); | 2487 owner()->DeallocateTemps(1); |
| 2488 ASSERT(GetCurrentTempLocalIndex() == var->index()); | 2488 ASSERT(GetCurrentTempLocalIndex() == var->index()); |
| 2489 return new(Z) DropTempsInstr(1, tmp); | 2489 return new(Z) DropTempsInstr(1, tmp); |
| 2490 } | 2490 } |
| 2491 | 2491 |
| 2492 | 2492 |
| 2493 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { | 2493 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { |
| 2494 intptr_t num_temps = node->num_temps(); | 2494 intptr_t num_temps = node->num_temps(); |
| 2495 for (intptr_t i = 0; i < num_temps; ++i) { | 2495 for (intptr_t i = 0; i < num_temps; ++i) { |
| 2496 ValueGraphVisitor for_value(owner()); | 2496 ValueGraphVisitor for_value(owner()); |
| 2497 node->InitializerAt(i)->Visit(&for_value); | 2497 node->InitializerAt(i)->Visit(&for_value); |
| 2498 Append(for_value); | 2498 Append(for_value); |
| 2499 Value* temp_val = for_value.value(); | 2499 Value* temp_val = for_value.value(); |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2754 for (intptr_t i = 0; i < node.length(); ++i) { | 2754 for (intptr_t i = 0; i < node.length(); ++i) { |
| 2755 ValueGraphVisitor for_argument(owner()); | 2755 ValueGraphVisitor for_argument(owner()); |
| 2756 node.NodeAt(i)->Visit(&for_argument); | 2756 node.NodeAt(i)->Visit(&for_argument); |
| 2757 Append(for_argument); | 2757 Append(for_argument); |
| 2758 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); | 2758 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); |
| 2759 values->Add(push_arg); | 2759 values->Add(push_arg); |
| 2760 } | 2760 } |
| 2761 } | 2761 } |
| 2762 | 2762 |
| 2763 | 2763 |
| 2764 void EffectGraphVisitor::BuildInstanceCallConditional(InstanceCallNode* node) { |
| 2765 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); |
| 2766 LoadLocalNode* load_temp = |
| 2767 new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var); |
| 2768 |
| 2769 LiteralNode* null_constant = |
| 2770 new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance()); |
| 2771 ComparisonNode* check_is_null = |
| 2772 new(Z) ComparisonNode(Scanner::kNoSourcePos, |
| 2773 Token::kEQ, |
| 2774 load_temp, |
| 2775 null_constant); |
| 2776 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); |
| 2777 check_is_null->Visit(&for_test); |
| 2778 |
| 2779 EffectGraphVisitor for_true(owner()); |
| 2780 EffectGraphVisitor for_false(owner()); |
| 2781 |
| 2782 StoreLocalNode* store_null = |
| 2783 new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, null_constant); |
| 2784 store_null->Visit(&for_true); |
| 2785 |
| 2786 InstanceCallNode* call = |
| 2787 new(Z) InstanceCallNode(node->token_pos(), |
| 2788 load_temp, |
| 2789 node->function_name(), |
| 2790 node->arguments()); |
| 2791 StoreLocalNode* store_result = |
| 2792 new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, call); |
| 2793 store_result->Visit(&for_false); |
| 2794 |
| 2795 Join(for_test, for_true, for_false); |
| 2796 } |
| 2797 |
| 2798 |
| 2799 void ValueGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 2800 if (node->is_conditional()) { |
| 2801 ValueGraphVisitor for_receiver(owner()); |
| 2802 node->receiver()->Visit(&for_receiver); |
| 2803 Append(for_receiver); |
| 2804 Do(BuildStoreExprTemp(for_receiver.value())); |
| 2805 BuildInstanceCallConditional(node); |
| 2806 ReturnDefinition(BuildLoadExprTemp()); |
| 2807 } else { |
| 2808 EffectGraphVisitor::VisitInstanceCallNode(node); |
| 2809 } |
| 2810 } |
| 2811 |
| 2812 |
| 2764 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 2813 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 2765 ValueGraphVisitor for_receiver(owner()); | 2814 ValueGraphVisitor for_receiver(owner()); |
| 2766 node->receiver()->Visit(&for_receiver); | 2815 node->receiver()->Visit(&for_receiver); |
| 2767 Append(for_receiver); | 2816 Append(for_receiver); |
| 2768 if (node->is_conditional()) { | 2817 if (node->is_conditional()) { |
| 2769 Do(BuildStoreExprTemp(for_receiver.value())); | 2818 Do(BuildStoreExprTemp(for_receiver.value())); |
| 2770 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); | 2819 BuildInstanceCallConditional(node); |
| 2771 LoadLocalNode* load_temp = | |
| 2772 new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var); | |
| 2773 | |
| 2774 LiteralNode* null_constant = | |
| 2775 new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance()); | |
| 2776 ComparisonNode* check_is_null = | |
| 2777 new(Z) ComparisonNode(Scanner::kNoSourcePos, | |
| 2778 Token::kEQ, | |
| 2779 load_temp, | |
| 2780 null_constant); | |
| 2781 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); | |
| 2782 check_is_null->Visit(&for_test); | |
| 2783 | |
| 2784 EffectGraphVisitor for_true(owner()); | |
| 2785 EffectGraphVisitor for_false(owner()); | |
| 2786 | |
| 2787 StoreLocalNode* store_null = | |
| 2788 new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, null_constant); | |
| 2789 store_null->Visit(&for_true); | |
| 2790 | |
| 2791 InstanceCallNode* call = | |
| 2792 new(Z) InstanceCallNode(node->token_pos(), | |
| 2793 load_temp, | |
| 2794 node->function_name(), | |
| 2795 node->arguments()); | |
| 2796 StoreLocalNode* store_result = | |
| 2797 new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, call); | |
| 2798 store_result->Visit(&for_false); | |
| 2799 | |
| 2800 Join(for_test, for_true, for_false); | |
| 2801 ReturnDefinition(BuildLoadExprTemp()); | |
| 2802 } else { | 2820 } else { |
| 2803 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 2821 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 2804 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2822 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2805 new(Z) ZoneGrowableArray<PushArgumentInstr*>( | 2823 new(Z) ZoneGrowableArray<PushArgumentInstr*>( |
| 2806 node->arguments()->length() + 1); | 2824 node->arguments()->length() + 1); |
| 2807 arguments->Add(push_receiver); | 2825 arguments->Add(push_receiver); |
| 2808 | 2826 |
| 2809 BuildPushArguments(*node->arguments(), arguments); | 2827 BuildPushArguments(*node->arguments(), arguments); |
| 2810 InstanceCallInstr* call = new(Z) InstanceCallInstr( | 2828 InstanceCallInstr* call = new(Z) InstanceCallInstr( |
| 2811 node->token_pos(), | 2829 node->token_pos(), |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3150 Value* allocate = BuildObjectAllocation(node); | 3168 Value* allocate = BuildObjectAllocation(node); |
| 3151 { LocalVariable* tmp_var = EnterTempLocalScope(allocate); | 3169 { LocalVariable* tmp_var = EnterTempLocalScope(allocate); |
| 3152 Value* allocated_tmp = Bind(new(Z) LoadLocalInstr(*tmp_var)); | 3170 Value* allocated_tmp = Bind(new(Z) LoadLocalInstr(*tmp_var)); |
| 3153 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); | 3171 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); |
| 3154 BuildConstructorCall(node, push_allocated_value); | 3172 BuildConstructorCall(node, push_allocated_value); |
| 3155 ReturnDefinition(ExitTempLocalScope(tmp_var)); | 3173 ReturnDefinition(ExitTempLocalScope(tmp_var)); |
| 3156 } | 3174 } |
| 3157 } | 3175 } |
| 3158 | 3176 |
| 3159 | 3177 |
| 3178 |
| 3179 void EffectGraphVisitor::BuildInstanceGetterConditional( |
| 3180 InstanceGetterNode* node) { |
| 3181 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); |
| 3182 LoadLocalNode* load_temp = |
| 3183 new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var); |
| 3184 |
| 3185 LiteralNode* null_constant = |
| 3186 new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance()); |
| 3187 ComparisonNode* check_is_null = |
| 3188 new(Z) ComparisonNode(Scanner::kNoSourcePos, |
| 3189 Token::kEQ, |
| 3190 load_temp, |
| 3191 null_constant); |
| 3192 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); |
| 3193 check_is_null->Visit(&for_test); |
| 3194 |
| 3195 EffectGraphVisitor for_true(owner()); |
| 3196 EffectGraphVisitor for_false(owner()); |
| 3197 |
| 3198 StoreLocalNode* store_null = |
| 3199 new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, null_constant); |
| 3200 store_null->Visit(&for_true); |
| 3201 |
| 3202 InstanceGetterNode* getter = |
| 3203 new(Z) InstanceGetterNode(node->token_pos(), |
| 3204 load_temp, |
| 3205 node->field_name()); |
| 3206 StoreLocalNode* store_getter = |
| 3207 new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, getter); |
| 3208 store_getter->Visit(&for_false); |
| 3209 |
| 3210 Join(for_test, for_true, for_false); |
| 3211 } |
| 3212 |
| 3213 |
| 3214 void ValueGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 3215 if (node->is_conditional()) { |
| 3216 ValueGraphVisitor for_receiver(owner()); |
| 3217 node->receiver()->Visit(&for_receiver); |
| 3218 Append(for_receiver); |
| 3219 Do(BuildStoreExprTemp(for_receiver.value())); |
| 3220 BuildInstanceGetterConditional(node); |
| 3221 ReturnDefinition(BuildLoadExprTemp()); |
| 3222 } else { |
| 3223 EffectGraphVisitor::VisitInstanceGetterNode(node); |
| 3224 } |
| 3225 } |
| 3226 |
| 3227 |
| 3160 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 3228 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 3161 ValueGraphVisitor for_receiver(owner()); | 3229 ValueGraphVisitor for_receiver(owner()); |
| 3162 node->receiver()->Visit(&for_receiver); | 3230 node->receiver()->Visit(&for_receiver); |
| 3163 Append(for_receiver); | 3231 Append(for_receiver); |
| 3164 if (node->is_conditional()) { | 3232 if (node->is_conditional()) { |
| 3165 Do(BuildStoreExprTemp(for_receiver.value())); | 3233 Do(BuildStoreExprTemp(for_receiver.value())); |
| 3166 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); | 3234 BuildInstanceGetterConditional(node); |
| 3167 LoadLocalNode* load_temp = | |
| 3168 new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var); | |
| 3169 | |
| 3170 LiteralNode* null_constant = | |
| 3171 new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance()); | |
| 3172 ComparisonNode* check_is_null = | |
| 3173 new(Z) ComparisonNode(Scanner::kNoSourcePos, | |
| 3174 Token::kEQ, | |
| 3175 load_temp, | |
| 3176 null_constant); | |
| 3177 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); | |
| 3178 check_is_null->Visit(&for_test); | |
| 3179 | |
| 3180 EffectGraphVisitor for_true(owner()); | |
| 3181 EffectGraphVisitor for_false(owner()); | |
| 3182 | |
| 3183 StoreLocalNode* store_null = | |
| 3184 new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, null_constant); | |
| 3185 store_null->Visit(&for_true); | |
| 3186 | |
| 3187 InstanceGetterNode* getter = | |
| 3188 new(Z) InstanceGetterNode(node->token_pos(), | |
| 3189 load_temp, | |
| 3190 node->field_name()); | |
| 3191 StoreLocalNode* store_getter = | |
| 3192 new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, getter); | |
| 3193 store_getter->Visit(&for_false); | |
| 3194 | |
| 3195 Join(for_test, for_true, for_false); | |
| 3196 ReturnDefinition(BuildLoadExprTemp()); | |
| 3197 } else { | 3235 } else { |
| 3198 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 3236 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 3199 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 3237 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3200 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); | 3238 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); |
| 3201 arguments->Add(push_receiver); | 3239 arguments->Add(push_receiver); |
| 3202 const String& name = | 3240 const String& name = |
| 3203 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name())); | 3241 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name())); |
| 3204 InstanceCallInstr* call = new(Z) InstanceCallInstr( | 3242 InstanceCallInstr* call = new(Z) InstanceCallInstr( |
| 3205 node->token_pos(), | 3243 node->token_pos(), |
| 3206 name, | 3244 name, |
| (...skipping 1520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4727 Report::MessageF(Report::kBailout, | 4765 Report::MessageF(Report::kBailout, |
| 4728 Script::Handle(function.script()), | 4766 Script::Handle(function.script()), |
| 4729 function.token_pos(), | 4767 function.token_pos(), |
| 4730 "FlowGraphBuilder Bailout: %s %s", | 4768 "FlowGraphBuilder Bailout: %s %s", |
| 4731 String::Handle(function.name()).ToCString(), | 4769 String::Handle(function.name()).ToCString(), |
| 4732 reason); | 4770 reason); |
| 4733 UNREACHABLE(); | 4771 UNREACHABLE(); |
| 4734 } | 4772 } |
| 4735 | 4773 |
| 4736 } // namespace dart | 4774 } // namespace dart |
| OLD | NEW |