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

Unified 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_builder.cc
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 2f98cfc779350ab0180d947fa380644b2e1926be..0329ca3a2828dc5813f541b8e3be6387355833ac 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -2483,10 +2483,10 @@ LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) {
Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) {
- Value* tmp = Bind(new(Z) LoadLocalInstr(*var));
- owner()->DeallocateTemps(1);
- ASSERT(GetCurrentTempLocalIndex() == var->index());
- return new(Z) DropTempsInstr(1, tmp);
+ Value* tmp = Bind(new(Z) LoadLocalInstr(*var));
+ owner()->DeallocateTemps(1);
+ ASSERT(GetCurrentTempLocalIndex() == var->index());
+ return new(Z) DropTempsInstr(1, tmp);
}
@@ -2761,45 +2761,63 @@ void EffectGraphVisitor::BuildPushArguments(
}
-void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
- ValueGraphVisitor for_receiver(owner());
- node->receiver()->Visit(&for_receiver);
- Append(for_receiver);
- if (node->is_conditional()) {
- Do(BuildStoreExprTemp(for_receiver.value()));
- LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
- LoadLocalNode* load_temp =
- new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var);
+void EffectGraphVisitor::BuildInstanceCallConditional(InstanceCallNode* node) {
+ LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
+ LoadLocalNode* load_temp =
+ new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var);
- LiteralNode* null_constant =
- new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance());
- ComparisonNode* check_is_null =
- new(Z) ComparisonNode(Scanner::kNoSourcePos,
- Token::kEQ,
- load_temp,
- null_constant);
- TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
- check_is_null->Visit(&for_test);
+ LiteralNode* null_constant =
+ new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance());
+ ComparisonNode* check_is_null =
+ new(Z) ComparisonNode(Scanner::kNoSourcePos,
+ Token::kEQ,
+ load_temp,
+ null_constant);
+ TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
+ check_is_null->Visit(&for_test);
- EffectGraphVisitor for_true(owner());
- EffectGraphVisitor for_false(owner());
+ EffectGraphVisitor for_true(owner());
+ EffectGraphVisitor for_false(owner());
- StoreLocalNode* store_null =
- new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, null_constant);
- store_null->Visit(&for_true);
+ StoreLocalNode* store_null =
+ new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, null_constant);
+ store_null->Visit(&for_true);
- InstanceCallNode* call =
- new(Z) InstanceCallNode(node->token_pos(),
- load_temp,
- node->function_name(),
- node->arguments());
- StoreLocalNode* store_result =
- new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, call);
- store_result->Visit(&for_false);
+ InstanceCallNode* call =
+ new(Z) InstanceCallNode(node->token_pos(),
+ load_temp,
+ node->function_name(),
+ node->arguments());
+ StoreLocalNode* store_result =
+ new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, call);
+ store_result->Visit(&for_false);
- Join(for_test, for_true, for_false);
+ Join(for_test, for_true, for_false);
+}
+
+
+void ValueGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
+ if (node->is_conditional()) {
+ ValueGraphVisitor for_receiver(owner());
+ node->receiver()->Visit(&for_receiver);
+ Append(for_receiver);
+ Do(BuildStoreExprTemp(for_receiver.value()));
+ BuildInstanceCallConditional(node);
ReturnDefinition(BuildLoadExprTemp());
} else {
+ EffectGraphVisitor::VisitInstanceCallNode(node);
+ }
+}
+
+
+void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
+ ValueGraphVisitor for_receiver(owner());
+ node->receiver()->Visit(&for_receiver);
+ Append(for_receiver);
+ if (node->is_conditional()) {
+ Do(BuildStoreExprTemp(for_receiver.value()));
+ BuildInstanceCallConditional(node);
+ } else {
PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
ZoneGrowableArray<PushArgumentInstr*>* arguments =
new(Z) ZoneGrowableArray<PushArgumentInstr*>(
@@ -3157,44 +3175,64 @@ void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
}
-void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
- ValueGraphVisitor for_receiver(owner());
- node->receiver()->Visit(&for_receiver);
- Append(for_receiver);
- if (node->is_conditional()) {
- Do(BuildStoreExprTemp(for_receiver.value()));
- LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
- LoadLocalNode* load_temp =
- new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var);
- LiteralNode* null_constant =
- new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance());
- ComparisonNode* check_is_null =
- new(Z) ComparisonNode(Scanner::kNoSourcePos,
- Token::kEQ,
- load_temp,
- null_constant);
- TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
- check_is_null->Visit(&for_test);
+void EffectGraphVisitor::BuildInstanceGetterConditional(
+ InstanceGetterNode* node) {
+ LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
+ LoadLocalNode* load_temp =
+ new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var);
- EffectGraphVisitor for_true(owner());
- EffectGraphVisitor for_false(owner());
+ LiteralNode* null_constant =
+ new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance());
+ ComparisonNode* check_is_null =
+ new(Z) ComparisonNode(Scanner::kNoSourcePos,
+ Token::kEQ,
+ load_temp,
+ null_constant);
+ TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
+ check_is_null->Visit(&for_test);
- StoreLocalNode* store_null =
- new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, null_constant);
- store_null->Visit(&for_true);
+ EffectGraphVisitor for_true(owner());
+ EffectGraphVisitor for_false(owner());
- InstanceGetterNode* getter =
- new(Z) InstanceGetterNode(node->token_pos(),
- load_temp,
- node->field_name());
- StoreLocalNode* store_getter =
- new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, getter);
- store_getter->Visit(&for_false);
+ StoreLocalNode* store_null =
+ new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, null_constant);
+ store_null->Visit(&for_true);
- Join(for_test, for_true, for_false);
+ InstanceGetterNode* getter =
+ new(Z) InstanceGetterNode(node->token_pos(),
+ load_temp,
+ node->field_name());
+ StoreLocalNode* store_getter =
+ new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, getter);
+ store_getter->Visit(&for_false);
+
+ Join(for_test, for_true, for_false);
+}
+
+
+void ValueGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
+ if (node->is_conditional()) {
+ ValueGraphVisitor for_receiver(owner());
+ node->receiver()->Visit(&for_receiver);
+ Append(for_receiver);
+ Do(BuildStoreExprTemp(for_receiver.value()));
+ BuildInstanceGetterConditional(node);
ReturnDefinition(BuildLoadExprTemp());
} else {
+ EffectGraphVisitor::VisitInstanceGetterNode(node);
+ }
+}
+
+
+void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
+ ValueGraphVisitor for_receiver(owner());
+ node->receiver()->Visit(&for_receiver);
+ Append(for_receiver);
+ if (node->is_conditional()) {
+ Do(BuildStoreExprTemp(for_receiver.value()));
+ BuildInstanceGetterConditional(node);
+ } else {
PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
ZoneGrowableArray<PushArgumentInstr*>* arguments =
new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
« 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