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 |