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

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

Issue 23480005: Change Bool::Get to return a handle instead of a pointer to a raw object. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 2521 matching lines...) Expand 10 before | Expand all | Expand 10 after
2532 Bool& prev = Bool::Handle(); 2532 Bool& prev = Bool::Handle();
2533 Class& cls = Class::Handle(); 2533 Class& cls = Class::Handle();
2534 for (int i = 0; i < ic_data.NumberOfChecks(); i++) { 2534 for (int i = 0; i < ic_data.NumberOfChecks(); i++) {
2535 cls = class_table.At(ic_data.GetReceiverClassIdAt(i)); 2535 cls = class_table.At(ic_data.GetReceiverClassIdAt(i));
2536 if (cls.HasTypeArguments()) return Bool::null(); 2536 if (cls.HasTypeArguments()) return Bool::null();
2537 const bool is_subtype = cls.IsSubtypeOf(TypeArguments::Handle(), 2537 const bool is_subtype = cls.IsSubtypeOf(TypeArguments::Handle(),
2538 type_class, 2538 type_class,
2539 TypeArguments::Handle(), 2539 TypeArguments::Handle(),
2540 NULL); 2540 NULL);
2541 if (prev.IsNull()) { 2541 if (prev.IsNull()) {
2542 prev = is_subtype ? Bool::True().raw() : Bool::False().raw(); 2542 prev = Bool::Get(is_subtype).raw();
2543 } else { 2543 } else {
2544 if (is_subtype != prev.value()) return Bool::null(); 2544 if (is_subtype != prev.value()) return Bool::null();
2545 } 2545 }
2546 } 2546 }
2547 return prev.raw(); 2547 return prev.raw();
2548 } 2548 }
2549 2549
2550 2550
2551 // TODO(srdjan): Use ICData to check if always true or false. 2551 // TODO(srdjan): Use ICData to check if always true or false.
2552 void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { 2552 void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
2553 ASSERT(Token::IsTypeTestOperator(call->token_kind())); 2553 ASSERT(Token::IsTypeTestOperator(call->token_kind()));
2554 Definition* left = call->ArgumentAt(0); 2554 Definition* left = call->ArgumentAt(0);
2555 Definition* instantiator = call->ArgumentAt(1); 2555 Definition* instantiator = call->ArgumentAt(1);
2556 Definition* type_args = call->ArgumentAt(2); 2556 Definition* type_args = call->ArgumentAt(2);
2557 const AbstractType& type = 2557 const AbstractType& type =
2558 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()); 2558 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value());
2559 const bool negate = 2559 const bool negate =
2560 Bool::Cast(call->ArgumentAt(4)->AsConstant()->value()).value(); 2560 Bool::Cast(call->ArgumentAt(4)->AsConstant()->value()).value();
2561 const ICData& unary_checks = 2561 const ICData& unary_checks =
2562 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()); 2562 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks());
2563 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { 2563 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) {
2564 Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type)); 2564 Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type));
2565 if (!as_bool.IsNull()) { 2565 if (!as_bool.IsNull()) {
2566 AddReceiverCheck(call); 2566 AddReceiverCheck(call);
2567 if (negate) { 2567 if (negate) {
2568 as_bool = Bool::Get(!as_bool.value()); 2568 as_bool = Bool::Get(!as_bool.value()).raw();
2569 } 2569 }
2570 ConstantInstr* bool_const = flow_graph()->GetConstant(as_bool); 2570 ConstantInstr* bool_const = flow_graph()->GetConstant(as_bool);
2571 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { 2571 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
2572 PushArgumentInstr* push = call->PushArgumentAt(i); 2572 PushArgumentInstr* push = call->PushArgumentAt(i);
2573 push->ReplaceUsesWith(push->value()->definition()); 2573 push->ReplaceUsesWith(push->value()->definition());
2574 push->RemoveFromGraph(); 2574 push->RemoveFromGraph();
2575 } 2575 }
2576 call->ReplaceUsesWith(bool_const); 2576 call->ReplaceUsesWith(bool_const);
2577 ASSERT(current_iterator()->Current() == call); 2577 ASSERT(current_iterator()->Current() == call);
2578 current_iterator()->RemoveCurrentFromGraph(); 2578 current_iterator()->RemoveCurrentFromGraph();
(...skipping 3412 matching lines...) Expand 10 before | Expand all | Expand 10 after
5991 } 5991 }
5992 } 5992 }
5993 5993
5994 5994
5995 void ConstantPropagator::VisitStrictCompare(StrictCompareInstr* instr) { 5995 void ConstantPropagator::VisitStrictCompare(StrictCompareInstr* instr) {
5996 const Object& left = instr->left()->definition()->constant_value(); 5996 const Object& left = instr->left()->definition()->constant_value();
5997 const Object& right = instr->right()->definition()->constant_value(); 5997 const Object& right = instr->right()->definition()->constant_value();
5998 5998
5999 if (instr->left()->definition() == instr->right()->definition()) { 5999 if (instr->left()->definition() == instr->right()->definition()) {
6000 // Fold x === x, and x !== x to true/false. 6000 // Fold x === x, and x !== x to true/false.
6001 SetValue(instr, 6001 SetValue(instr, Bool::Get(instr->kind() == Token::kEQ_STRICT));
6002 (instr->kind() == Token::kEQ_STRICT)
6003 ? Bool::True()
6004 : Bool::False());
6005 return; 6002 return;
6006 } 6003 }
6007 6004
6008 if (IsNonConstant(left) || IsNonConstant(right)) { 6005 if (IsNonConstant(left) || IsNonConstant(right)) {
6009 // TODO(vegorov): incorporate nullability information into the lattice. 6006 // TODO(vegorov): incorporate nullability information into the lattice.
6010 if ((left.IsNull() && instr->right()->Type()->HasDecidableNullability()) || 6007 if ((left.IsNull() && instr->right()->Type()->HasDecidableNullability()) ||
6011 (right.IsNull() && instr->left()->Type()->HasDecidableNullability())) { 6008 (right.IsNull() && instr->left()->Type()->HasDecidableNullability())) {
6012 bool result = left.IsNull() ? instr->right()->Type()->IsNull() 6009 bool result = left.IsNull() ? instr->right()->Type()->IsNull()
6013 : instr->left()->Type()->IsNull(); 6010 : instr->left()->Type()->IsNull();
6014 if (instr->kind() == Token::kNE_STRICT) result = !result; 6011 if (instr->kind() == Token::kNE_STRICT) result = !result;
6015 SetValue(instr, result ? Bool::True() : Bool::False()); 6012 SetValue(instr, Bool::Get(result));
6016 } else { 6013 } else {
6017 SetValue(instr, non_constant_); 6014 SetValue(instr, non_constant_);
6018 } 6015 }
6019 } else if (IsConstant(left) && IsConstant(right)) { 6016 } else if (IsConstant(left) && IsConstant(right)) {
6020 bool result = (left.raw() == right.raw()); 6017 bool result = (left.raw() == right.raw());
6021 if (instr->kind() == Token::kNE_STRICT) result = !result; 6018 if (instr->kind() == Token::kNE_STRICT) result = !result;
6022 SetValue(instr, result ? Bool::True() : Bool::False()); 6019 SetValue(instr, Bool::Get(result));
6023 } 6020 }
6024 } 6021 }
6025 6022
6026 6023
6027 static bool CompareIntegers(Token::Kind kind, 6024 static bool CompareIntegers(Token::Kind kind,
6028 const Integer& left, 6025 const Integer& left,
6029 const Integer& right) { 6026 const Integer& right) {
6030 const int result = left.CompareWith(right); 6027 const int result = left.CompareWith(right);
6031 switch (kind) { 6028 switch (kind) {
6032 case Token::kEQ: return (result == 0); 6029 case Token::kEQ: return (result == 0);
(...skipping 11 matching lines...) Expand all
6044 6041
6045 void ConstantPropagator::VisitEqualityCompare(EqualityCompareInstr* instr) { 6042 void ConstantPropagator::VisitEqualityCompare(EqualityCompareInstr* instr) {
6046 const Object& left = instr->left()->definition()->constant_value(); 6043 const Object& left = instr->left()->definition()->constant_value();
6047 const Object& right = instr->right()->definition()->constant_value(); 6044 const Object& right = instr->right()->definition()->constant_value();
6048 6045
6049 if (instr->left()->definition() == instr->right()->definition()) { 6046 if (instr->left()->definition() == instr->right()->definition()) {
6050 // Fold x == x, and x != x to true/false for numbers and checked strict 6047 // Fold x == x, and x != x to true/false for numbers and checked strict
6051 // comparisons. 6048 // comparisons.
6052 if (instr->IsCheckedStrictEqual() || 6049 if (instr->IsCheckedStrictEqual() ||
6053 RawObject::IsIntegerClassId(instr->operation_cid())) { 6050 RawObject::IsIntegerClassId(instr->operation_cid())) {
6054 return SetValue(instr, 6051 return SetValue(instr, Bool::Get(instr->kind() == Token::kEQ));
6055 (instr->kind() == Token::kEQ)
6056 ? Bool::True()
6057 : Bool::False());
6058 } 6052 }
6059 } 6053 }
6060 6054
6061 if (IsNonConstant(left) || IsNonConstant(right)) { 6055 if (IsNonConstant(left) || IsNonConstant(right)) {
6062 SetValue(instr, non_constant_); 6056 SetValue(instr, non_constant_);
6063 } else if (IsConstant(left) && IsConstant(right)) { 6057 } else if (IsConstant(left) && IsConstant(right)) {
6064 if (left.IsInteger() && right.IsInteger()) { 6058 if (left.IsInteger() && right.IsInteger()) {
6065 const bool result = CompareIntegers(instr->kind(), 6059 const bool result = CompareIntegers(instr->kind(),
6066 Integer::Cast(left), 6060 Integer::Cast(left),
6067 Integer::Cast(right)); 6061 Integer::Cast(right));
6068 SetValue(instr, result ? Bool::True() : Bool::False()); 6062 SetValue(instr, Bool::Get(result));
6069 } else if (left.IsString() && right.IsString()) { 6063 } else if (left.IsString() && right.IsString()) {
6070 const bool result = String::Cast(left).Equals(String::Cast(right)); 6064 const bool result = String::Cast(left).Equals(String::Cast(right));
6071 SetValue(instr, 6065 SetValue(instr, Bool::Get((instr->kind() == Token::kEQ) == result));
6072 ((instr->kind() == Token::kEQ) == result)
6073 ? Bool::True()
6074 : Bool::False());
6075 } else { 6066 } else {
6076 SetValue(instr, non_constant_); 6067 SetValue(instr, non_constant_);
6077 } 6068 }
6078 } 6069 }
6079 } 6070 }
6080 6071
6081 6072
6082 void ConstantPropagator::VisitRelationalOp(RelationalOpInstr* instr) { 6073 void ConstantPropagator::VisitRelationalOp(RelationalOpInstr* instr) {
6083 const Object& left = instr->left()->definition()->constant_value(); 6074 const Object& left = instr->left()->definition()->constant_value();
6084 const Object& right = instr->right()->definition()->constant_value(); 6075 const Object& right = instr->right()->definition()->constant_value();
6085 if (IsNonConstant(left) || IsNonConstant(right)) { 6076 if (IsNonConstant(left) || IsNonConstant(right)) {
6086 SetValue(instr, non_constant_); 6077 SetValue(instr, non_constant_);
6087 } else if (IsConstant(left) && IsConstant(right)) { 6078 } else if (IsConstant(left) && IsConstant(right)) {
6088 if (left.IsInteger() && right.IsInteger()) { 6079 if (left.IsInteger() && right.IsInteger()) {
6089 const bool result = CompareIntegers(instr->kind(), 6080 const bool result = CompareIntegers(instr->kind(),
6090 Integer::Cast(left), 6081 Integer::Cast(left),
6091 Integer::Cast(right)); 6082 Integer::Cast(right));
6092 SetValue(instr, result ? Bool::True() : Bool::False()); 6083 SetValue(instr, Bool::Get(result));
6093 } else { 6084 } else {
6094 SetValue(instr, non_constant_); 6085 SetValue(instr, non_constant_);
6095 } 6086 }
6096 } 6087 }
6097 } 6088 }
6098 6089
6099 6090
6100 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) { 6091 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) {
6101 SetValue(instr, non_constant_); 6092 SetValue(instr, non_constant_);
6102 } 6093 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
6142 SetValue(instr, instr->value()->definition()->constant_value()); 6133 SetValue(instr, instr->value()->definition()->constant_value());
6143 } 6134 }
6144 6135
6145 6136
6146 void ConstantPropagator::VisitBooleanNegate(BooleanNegateInstr* instr) { 6137 void ConstantPropagator::VisitBooleanNegate(BooleanNegateInstr* instr) {
6147 const Object& value = instr->value()->definition()->constant_value(); 6138 const Object& value = instr->value()->definition()->constant_value();
6148 if (IsNonConstant(value)) { 6139 if (IsNonConstant(value)) {
6149 SetValue(instr, non_constant_); 6140 SetValue(instr, non_constant_);
6150 } else if (IsConstant(value)) { 6141 } else if (IsConstant(value)) {
6151 bool val = value.raw() != Bool::True().raw(); 6142 bool val = value.raw() != Bool::True().raw();
6152 SetValue(instr, val ? Bool::True() : Bool::False()); 6143 SetValue(instr, Bool::Get(val));
6153 } 6144 }
6154 } 6145 }
6155 6146
6156 6147
6157 void ConstantPropagator::VisitInstanceOf(InstanceOfInstr* instr) { 6148 void ConstantPropagator::VisitInstanceOf(InstanceOfInstr* instr) {
6158 const Object& value = instr->value()->definition()->constant_value(); 6149 const Object& value = instr->value()->definition()->constant_value();
6159 if (IsNonConstant(value)) { 6150 if (IsNonConstant(value)) {
6160 SetValue(instr, non_constant_); 6151 SetValue(instr, non_constant_);
6161 } else if (IsConstant(value)) { 6152 } else if (IsConstant(value)) {
6162 // TODO(kmillikin): Handle instanceof on constants. 6153 // TODO(kmillikin): Handle instanceof on constants.
(...skipping 1380 matching lines...) Expand 10 before | Expand all | Expand 10 after
7543 } 7534 }
7544 7535
7545 // Insert materializations at environment uses. 7536 // Insert materializations at environment uses.
7546 for (intptr_t i = 0; i < exits.length(); i++) { 7537 for (intptr_t i = 0; i < exits.length(); i++) {
7547 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 7538 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
7548 } 7539 }
7549 } 7540 }
7550 7541
7551 7542
7552 } // namespace dart 7543 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698