| OLD | NEW |
| 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/aot_optimizer.h" | 5 #include "vm/aot_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/branch_optimizer.h" | 8 #include "vm/branch_optimizer.h" |
| 9 #include "vm/cha.h" | 9 #include "vm/cha.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 current_iterator_ = ⁢ | 101 current_iterator_ = ⁢ |
| 102 for (; !it.Done(); it.Advance()) { | 102 for (; !it.Done(); it.Advance()) { |
| 103 Instruction* instr = it.Current(); | 103 Instruction* instr = it.Current(); |
| 104 if (instr->IsInstanceCall()) { | 104 if (instr->IsInstanceCall()) { |
| 105 InstanceCallInstr* call = instr->AsInstanceCall(); | 105 InstanceCallInstr* call = instr->AsInstanceCall(); |
| 106 if (call->HasICData()) { | 106 if (call->HasICData()) { |
| 107 if (TryCreateICData(call)) { | 107 if (TryCreateICData(call)) { |
| 108 VisitInstanceCall(call); | 108 VisitInstanceCall(call); |
| 109 } | 109 } |
| 110 } | 110 } |
| 111 } else if (instr->IsPolymorphicInstanceCall()) { | |
| 112 SpecializePolymorphicInstanceCall(instr->AsPolymorphicInstanceCall()); | |
| 113 } | 111 } |
| 114 } | 112 } |
| 115 current_iterator_ = NULL; | 113 current_iterator_ = NULL; |
| 116 } | 114 } |
| 117 } | 115 } |
| 118 | 116 |
| 119 | 117 |
| 120 // TODO(srdjan): Test/support other number types as well. | 118 // TODO(srdjan): Test/support other number types as well. |
| 121 static bool IsNumberCid(intptr_t cid) { | 119 static bool IsNumberCid(intptr_t cid) { |
| 122 return (cid == kSmiCid) || (cid == kDoubleCid); | 120 return (cid == kSmiCid) || (cid == kDoubleCid); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 ic_data.NumArgsTested())); | 259 ic_data.NumArgsTested())); |
| 262 new_ic_data.SetDeoptReasons(ic_data.DeoptReasons()); | 260 new_ic_data.SetDeoptReasons(ic_data.DeoptReasons()); |
| 263 new_ic_data.AddReceiverCheck(cid, function); | 261 new_ic_data.AddReceiverCheck(cid, function); |
| 264 return new_ic_data; | 262 return new_ic_data; |
| 265 } | 263 } |
| 266 | 264 |
| 267 return ic_data; | 265 return ic_data; |
| 268 } | 266 } |
| 269 | 267 |
| 270 | 268 |
| 271 void AotOptimizer::SpecializePolymorphicInstanceCall( | |
| 272 PolymorphicInstanceCallInstr* call) { | |
| 273 if (!FLAG_polymorphic_with_deopt) { | |
| 274 // Specialization adds receiver checks which can lead to deoptimization. | |
| 275 return; | |
| 276 } | |
| 277 if (!call->with_checks()) { | |
| 278 return; // Already specialized. | |
| 279 } | |
| 280 | |
| 281 const intptr_t receiver_cid = | |
| 282 call->PushArgumentAt(0)->value()->Type()->ToCid(); | |
| 283 if (receiver_cid == kDynamicCid) { | |
| 284 return; // No information about receiver was infered. | |
| 285 } | |
| 286 | |
| 287 const ICData& ic_data = TrySpecializeICData(call->ic_data(), receiver_cid); | |
| 288 if (ic_data.raw() == call->ic_data().raw()) { | |
| 289 // No specialization. | |
| 290 return; | |
| 291 } | |
| 292 | |
| 293 PolymorphicInstanceCallInstr* specialized = | |
| 294 new(Z) PolymorphicInstanceCallInstr(call->instance_call(), | |
| 295 ic_data, | |
| 296 /* with_checks = */ false, | |
| 297 /* complete = */ false); | |
| 298 call->ReplaceWith(specialized, current_iterator()); | |
| 299 } | |
| 300 | |
| 301 | |
| 302 static BinarySmiOpInstr* AsSmiShiftLeftInstruction(Definition* d) { | 269 static BinarySmiOpInstr* AsSmiShiftLeftInstruction(Definition* d) { |
| 303 BinarySmiOpInstr* instr = d->AsBinarySmiOp(); | 270 BinarySmiOpInstr* instr = d->AsBinarySmiOp(); |
| 304 if ((instr != NULL) && (instr->op_kind() == Token::kSHL)) { | 271 if ((instr != NULL) && (instr->op_kind() == Token::kSHL)) { |
| 305 return instr; | 272 return instr; |
| 306 } | 273 } |
| 307 return NULL; | 274 return NULL; |
| 308 } | 275 } |
| 309 | 276 |
| 310 | 277 |
| 311 static bool IsPositiveOrZeroSmiConst(Definition* d) { | 278 static bool IsPositiveOrZeroSmiConst(Definition* d) { |
| (...skipping 2474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2786 | 2753 |
| 2787 // Discard the environment from the original instruction because the store | 2754 // Discard the environment from the original instruction because the store |
| 2788 // can't deoptimize. | 2755 // can't deoptimize. |
| 2789 instr->RemoveEnvironment(); | 2756 instr->RemoveEnvironment(); |
| 2790 ReplaceCall(instr, store); | 2757 ReplaceCall(instr, store); |
| 2791 return true; | 2758 return true; |
| 2792 } | 2759 } |
| 2793 | 2760 |
| 2794 | 2761 |
| 2795 } // namespace dart | 2762 } // namespace dart |
| OLD | NEW |