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

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

Issue 1211593004: Fix (optimizer) crashes in conditional nodes when result is not needed. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: z Created 5 years, 6 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
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | tests/language/nullaware_opt_test.dart » ('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 "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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | tests/language/nullaware_opt_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698