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

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

Issue 235013002: Fix polymorphic inlining of method dispatchers. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 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/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 3700 matching lines...) Expand 10 before | Expand all | Expand 10 after
3711 if (prev.IsNull()) { 3711 if (prev.IsNull()) {
3712 prev = Bool::Get(is_subtype).raw(); 3712 prev = Bool::Get(is_subtype).raw();
3713 } else { 3713 } else {
3714 if (is_subtype != prev.value()) return Bool::null(); 3714 if (is_subtype != prev.value()) return Bool::null();
3715 } 3715 }
3716 } 3716 }
3717 return prev.raw(); 3717 return prev.raw();
3718 } 3718 }
3719 3719
3720 3720
3721 static Definition* OriginalDefinition(Definition* defn) {
3722 while (defn->IsRedefinition() || defn->IsAssertAssignable()) {
3723 if (defn->IsRedefinition()) {
3724 defn = defn->AsRedefinition()->value()->definition();
3725 } else {
3726 defn = defn->AsAssertAssignable()->value()->definition();
3727 }
3728 }
3729 return defn;
3730 }
3731
3732
3733 // Returns true if checking against this type is a direct class id comparison. 3721 // Returns true if checking against this type is a direct class id comparison.
3734 static bool TypeCheckAsClassEquality(const AbstractType& type) { 3722 static bool TypeCheckAsClassEquality(const AbstractType& type) {
3735 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); 3723 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
3736 // Requires CHA. 3724 // Requires CHA.
3737 if (!FLAG_use_cha) return false; 3725 if (!FLAG_use_cha) return false;
3738 if (!type.IsInstantiated()) return false; 3726 if (!type.IsInstantiated()) return false;
3739 const Class& type_class = Class::Handle(type.type_class()); 3727 const Class& type_class = Class::Handle(type.type_class());
3740 // Signature classes have different type checking rules. 3728 // Signature classes have different type checking rules.
3741 if (type_class.IsSignatureClass()) return false; 3729 if (type_class.IsSignatureClass()) return false;
3742 // Could be an interface check? 3730 // Could be an interface check?
(...skipping 18 matching lines...) Expand all
3761 3749
3762 // TODO(srdjan): Use ICData to check if always true or false. 3750 // TODO(srdjan): Use ICData to check if always true or false.
3763 void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { 3751 void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
3764 ASSERT(Token::IsTypeTestOperator(call->token_kind())); 3752 ASSERT(Token::IsTypeTestOperator(call->token_kind()));
3765 Definition* left = call->ArgumentAt(0); 3753 Definition* left = call->ArgumentAt(0);
3766 Definition* instantiator = call->ArgumentAt(1); 3754 Definition* instantiator = call->ArgumentAt(1);
3767 Definition* type_args = call->ArgumentAt(2); 3755 Definition* type_args = call->ArgumentAt(2);
3768 const AbstractType& type = 3756 const AbstractType& type =
3769 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()); 3757 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value());
3770 const bool negate = Bool::Cast( 3758 const bool negate = Bool::Cast(
3771 OriginalDefinition(call->ArgumentAt(4))->AsConstant()->value()).value(); 3759 call->ArgumentAt(4)->OriginalDefinition()->AsConstant()->value()).value();
3772 const ICData& unary_checks = 3760 const ICData& unary_checks =
3773 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()); 3761 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks());
3774 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { 3762 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) {
3775 Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type)); 3763 Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type));
3776 if (!as_bool.IsNull()) { 3764 if (!as_bool.IsNull()) {
3777 AddReceiverCheck(call); 3765 AddReceiverCheck(call);
3778 if (negate) { 3766 if (negate) {
3779 as_bool = Bool::Get(!as_bool.value()).raw(); 3767 as_bool = Bool::Get(!as_bool.value()).raw();
3780 } 3768 }
3781 ConstantInstr* bool_const = flow_graph()->GetConstant(as_bool); 3769 ConstantInstr* bool_const = flow_graph()->GetConstant(as_bool);
(...skipping 1386 matching lines...) Expand 10 before | Expand all | Expand 10 after
5168 Place(Instruction* instr, bool* is_load) 5156 Place(Instruction* instr, bool* is_load)
5169 : kind_(kNone), 5157 : kind_(kNone),
5170 representation_(kNoRepresentation), 5158 representation_(kNoRepresentation),
5171 instance_(NULL), 5159 instance_(NULL),
5172 raw_selector_(0), 5160 raw_selector_(0),
5173 id_(0) { 5161 id_(0) {
5174 switch (instr->tag()) { 5162 switch (instr->tag()) {
5175 case Instruction::kLoadField: { 5163 case Instruction::kLoadField: {
5176 LoadFieldInstr* load_field = instr->AsLoadField(); 5164 LoadFieldInstr* load_field = instr->AsLoadField();
5177 representation_ = load_field->representation(); 5165 representation_ = load_field->representation();
5178 instance_ = OriginalDefinition(load_field->instance()->definition()); 5166 instance_ = load_field->instance()->definition()->OriginalDefinition();
5179 if (load_field->field() != NULL) { 5167 if (load_field->field() != NULL) {
5180 kind_ = kField; 5168 kind_ = kField;
5181 field_ = load_field->field(); 5169 field_ = load_field->field();
5182 } else { 5170 } else {
5183 kind_ = kVMField; 5171 kind_ = kVMField;
5184 offset_in_bytes_ = load_field->offset_in_bytes(); 5172 offset_in_bytes_ = load_field->offset_in_bytes();
5185 } 5173 }
5186 *is_load = true; 5174 *is_load = true;
5187 break; 5175 break;
5188 } 5176 }
5189 5177
5190 case Instruction::kStoreInstanceField: { 5178 case Instruction::kStoreInstanceField: {
5191 StoreInstanceFieldInstr* store = 5179 StoreInstanceFieldInstr* store =
5192 instr->AsStoreInstanceField(); 5180 instr->AsStoreInstanceField();
5193 representation_ = store->RequiredInputRepresentation( 5181 representation_ = store->RequiredInputRepresentation(
5194 StoreInstanceFieldInstr::kValuePos); 5182 StoreInstanceFieldInstr::kValuePos);
5195 instance_ = OriginalDefinition(store->instance()->definition()); 5183 instance_ = store->instance()->definition()->OriginalDefinition();
5196 if (!store->field().IsNull()) { 5184 if (!store->field().IsNull()) {
5197 kind_ = kField; 5185 kind_ = kField;
5198 field_ = &store->field(); 5186 field_ = &store->field();
5199 } else { 5187 } else {
5200 kind_ = kVMField; 5188 kind_ = kVMField;
5201 offset_in_bytes_ = store->offset_in_bytes(); 5189 offset_in_bytes_ = store->offset_in_bytes();
5202 } 5190 }
5203 break; 5191 break;
5204 } 5192 }
5205 5193
5206 case Instruction::kLoadStaticField: 5194 case Instruction::kLoadStaticField:
5207 kind_ = kField; 5195 kind_ = kField;
5208 representation_ = instr->AsLoadStaticField()->representation(); 5196 representation_ = instr->AsLoadStaticField()->representation();
5209 field_ = &instr->AsLoadStaticField()->StaticField(); 5197 field_ = &instr->AsLoadStaticField()->StaticField();
5210 *is_load = true; 5198 *is_load = true;
5211 break; 5199 break;
5212 5200
5213 case Instruction::kStoreStaticField: 5201 case Instruction::kStoreStaticField:
5214 kind_ = kField; 5202 kind_ = kField;
5215 representation_ = instr->AsStoreStaticField()-> 5203 representation_ = instr->AsStoreStaticField()->
5216 RequiredInputRepresentation(StoreStaticFieldInstr::kValuePos); 5204 RequiredInputRepresentation(StoreStaticFieldInstr::kValuePos);
5217 field_ = &instr->AsStoreStaticField()->field(); 5205 field_ = &instr->AsStoreStaticField()->field();
5218 break; 5206 break;
5219 5207
5220 case Instruction::kLoadIndexed: { 5208 case Instruction::kLoadIndexed: {
5221 LoadIndexedInstr* load_indexed = instr->AsLoadIndexed(); 5209 LoadIndexedInstr* load_indexed = instr->AsLoadIndexed();
5222 kind_ = kIndexed; 5210 kind_ = kIndexed;
5223 representation_ = load_indexed->representation(); 5211 representation_ = load_indexed->representation();
5224 instance_ = OriginalDefinition(load_indexed->array()->definition()); 5212 instance_ = load_indexed->array()->definition()->OriginalDefinition();
5225 index_ = load_indexed->index()->definition(); 5213 index_ = load_indexed->index()->definition();
5226 *is_load = true; 5214 *is_load = true;
5227 break; 5215 break;
5228 } 5216 }
5229 5217
5230 case Instruction::kStoreIndexed: { 5218 case Instruction::kStoreIndexed: {
5231 StoreIndexedInstr* store_indexed = instr->AsStoreIndexed(); 5219 StoreIndexedInstr* store_indexed = instr->AsStoreIndexed();
5232 kind_ = kIndexed; 5220 kind_ = kIndexed;
5233 representation_ = store_indexed-> 5221 representation_ = store_indexed->
5234 RequiredInputRepresentation(StoreIndexedInstr::kValuePos); 5222 RequiredInputRepresentation(StoreIndexedInstr::kValuePos);
5235 instance_ = OriginalDefinition(store_indexed->array()->definition()); 5223 instance_ = store_indexed->array()->definition()->OriginalDefinition();
5236 index_ = store_indexed->index()->definition(); 5224 index_ = store_indexed->index()->definition();
5237 break; 5225 break;
5238 } 5226 }
5239 5227
5240 case Instruction::kCurrentContext: 5228 case Instruction::kCurrentContext:
5241 kind_ = kContext; 5229 kind_ = kContext;
5242 ASSERT(instr->AsCurrentContext()->representation() == kTagged); 5230 ASSERT(instr->AsCurrentContext()->representation() == kTagged);
5243 representation_ = kTagged; 5231 representation_ = kTagged;
5244 *is_load = true; 5232 *is_load = true;
5245 break; 5233 break;
(...skipping 17 matching lines...) Expand all
5263 5251
5264 Representation representation() const { return representation_; } 5252 Representation representation() const { return representation_; }
5265 5253
5266 Definition* instance() const { 5254 Definition* instance() const {
5267 ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed)); 5255 ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed));
5268 return instance_; 5256 return instance_;
5269 } 5257 }
5270 5258
5271 void set_instance(Definition* def) { 5259 void set_instance(Definition* def) {
5272 ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed)); 5260 ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed));
5273 instance_ = OriginalDefinition(def); 5261 instance_ = def->OriginalDefinition();
5274 } 5262 }
5275 5263
5276 const Field& field() const { 5264 const Field& field() const {
5277 ASSERT(kind_ == kField); 5265 ASSERT(kind_ == kField);
5278 return *field_; 5266 return *field_;
5279 } 5267 }
5280 5268
5281 intptr_t offset_in_bytes() const { 5269 intptr_t offset_in_bytes() const {
5282 ASSERT(kind_ == kVMField); 5270 ASSERT(kind_ == kVMField);
5283 return offset_in_bytes_; 5271 return offset_in_bytes_;
(...skipping 3769 matching lines...) Expand 10 before | Expand all | Expand 10 after
9053 } 9041 }
9054 9042
9055 // Insert materializations at environment uses. 9043 // Insert materializations at environment uses.
9056 for (intptr_t i = 0; i < exits.length(); i++) { 9044 for (intptr_t i = 0; i < exits.length(); i++) {
9057 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); 9045 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots);
9058 } 9046 }
9059 } 9047 }
9060 9048
9061 9049
9062 } // namespace dart 9050 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698