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

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

Issue 2877713003: Eliminated with_checks variable (Closed)
Patch Set: Removed TODO Created 3 years, 7 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
« no previous file with comments | « runtime/vm/intermediate_language_dbc.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #ifndef DART_PRECOMPILED_RUNTIME 4 #ifndef DART_PRECOMPILED_RUNTIME
5 #include "vm/jit_optimizer.h" 5 #include "vm/jit_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 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 return false; 192 return false;
193 } 193 }
194 194
195 195
196 void JitOptimizer::SpecializePolymorphicInstanceCall( 196 void JitOptimizer::SpecializePolymorphicInstanceCall(
197 PolymorphicInstanceCallInstr* call) { 197 PolymorphicInstanceCallInstr* call) {
198 if (!FLAG_polymorphic_with_deopt) { 198 if (!FLAG_polymorphic_with_deopt) {
199 // Specialization adds receiver checks which can lead to deoptimization. 199 // Specialization adds receiver checks which can lead to deoptimization.
200 return; 200 return;
201 } 201 }
202 if (!call->with_checks()) {
203 return; // Already specialized.
204 }
205 202
206 const intptr_t receiver_cid = 203 const intptr_t receiver_cid =
207 call->PushArgumentAt(0)->value()->Type()->ToCid(); 204 call->PushArgumentAt(0)->value()->Type()->ToCid();
208 if (receiver_cid == kDynamicCid) { 205 if (receiver_cid == kDynamicCid) {
209 return; // No information about receiver was infered. 206 return; // No information about receiver was infered.
210 } 207 }
211 208
212 const ICData& ic_data = *call->instance_call()->ic_data(); 209 const ICData& ic_data = *call->instance_call()->ic_data();
213 210
214 const CallTargets* targets = 211 const CallTargets* targets =
215 FlowGraphCompiler::ResolveCallTargetsForReceiverCid( 212 FlowGraphCompiler::ResolveCallTargetsForReceiverCid(
216 receiver_cid, String::Handle(zone(), ic_data.target_name()), 213 receiver_cid, String::Handle(zone(), ic_data.target_name()),
217 Array::Handle(zone(), ic_data.arguments_descriptor())); 214 Array::Handle(zone(), ic_data.arguments_descriptor()));
218 if (targets == NULL) { 215 if (targets == NULL) {
219 // No specialization. 216 // No specialization.
220 return; 217 return;
221 } 218 }
222 219
223 const bool with_checks = false; 220 ASSERT(targets->HasSingleTarget());
224 const bool complete = false; 221 const Function& target = targets->FirstTarget();
225 PolymorphicInstanceCallInstr* specialized = 222 StaticCallInstr* specialized = StaticCallInstr::FromCall(Z, call, target);
226 new (Z) PolymorphicInstanceCallInstr(call->instance_call(), *targets,
227 with_checks, complete);
228 call->ReplaceWith(specialized, current_iterator()); 223 call->ReplaceWith(specialized, current_iterator());
229 } 224 }
230 225
231 226
232 static bool ClassIdIsOneOf(intptr_t class_id, 227 static bool ClassIdIsOneOf(intptr_t class_id,
233 const GrowableArray<intptr_t>& class_ids) { 228 const GrowableArray<intptr_t>& class_ids) {
234 for (intptr_t i = 0; i < class_ids.length(); i++) { 229 for (intptr_t i = 0; i < class_ids.length(); i++) {
235 ASSERT(class_ids[i] != kIllegalCid); 230 ASSERT(class_ids[i] != kIllegalCid);
236 if (class_ids[i] == class_id) { 231 if (class_ids[i] == class_id) {
237 return true; 232 return true;
(...skipping 1286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1524 const bool polymorphic_target = 1519 const bool polymorphic_target =
1525 MethodRecognizer::PolymorphicTarget(target); 1520 MethodRecognizer::PolymorphicTarget(target);
1526 has_one_target = !polymorphic_target; 1521 has_one_target = !polymorphic_target;
1527 } 1522 }
1528 } 1523 }
1529 1524
1530 if (has_one_target) { 1525 if (has_one_target) {
1531 const Function& target = Function::Handle(Z, unary_checks.GetTargetAt(0)); 1526 const Function& target = Function::Handle(Z, unary_checks.GetTargetAt(0));
1532 const RawFunction::Kind function_kind = target.kind(); 1527 const RawFunction::Kind function_kind = target.kind();
1533 if (!flow_graph()->InstanceCallNeedsClassCheck(instr, function_kind)) { 1528 if (!flow_graph()->InstanceCallNeedsClassCheck(instr, function_kind)) {
1534 PolymorphicInstanceCallInstr* call = 1529 StaticCallInstr* call = StaticCallInstr::FromCall(Z, instr, target);
1535 new (Z) PolymorphicInstanceCallInstr(instr, *targets,
1536 /* call_with_checks = */ false,
1537 /* complete = */ false);
1538 instr->ReplaceWith(call, current_iterator()); 1530 instr->ReplaceWith(call, current_iterator());
1539 return; 1531 return;
1540 } 1532 }
1541 } 1533 }
1542 1534
1543 // If there is only one target we can make this into a deopting class check, 1535 // If there is only one target we can make this into a deopting class check,
1544 // followed by a call instruction that does not check the class of the 1536 // followed by a call instruction that does not check the class of the
1545 // receiver. This enables a lot of optimizations because after the class 1537 // receiver. This enables a lot of optimizations because after the class
1546 // check we can probably inline the call and not worry about side effects. 1538 // check we can probably inline the call and not worry about side effects.
1547 // However, this can fall down if new receiver classes arrive at this call 1539 // However, this can fall down if new receiver classes arrive at this call
1548 // site after we generated optimized code. This causes a deopt, and after a 1540 // site after we generated optimized code. This causes a deopt, and after a
1549 // few deopts we won't optimize this function any more at all. Therefore for 1541 // few deopts we won't optimize this function any more at all. Therefore for
1550 // very polymorphic sites we don't make this optimization, keeping it as a 1542 // very polymorphic sites we don't make this optimization, keeping it as a
1551 // regular checked PolymorphicInstanceCall, which falls back to the slow but 1543 // regular checked PolymorphicInstanceCall, which falls back to the slow but
1552 // non-deopting megamorphic call stub when it sees new receiver classes. 1544 // non-deopting megamorphic call stub when it sees new receiver classes.
1553 bool call_with_checks;
1554 if (has_one_target && FLAG_polymorphic_with_deopt && 1545 if (has_one_target && FLAG_polymorphic_with_deopt &&
1555 (!instr->ic_data()->HasDeoptReason(ICData::kDeoptCheckClass) || 1546 (!instr->ic_data()->HasDeoptReason(ICData::kDeoptCheckClass) ||
1556 unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks)) { 1547 unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks)) {
1557 // Type propagation has not run yet, we cannot eliminate the check. 1548 // Type propagation has not run yet, we cannot eliminate the check.
1558 // TODO(erikcorry): The receiver check should use the off-heap targets 1549 // TODO(erikcorry): The receiver check should use the off-heap targets
1559 // array, not the IC array. 1550 // array, not the IC array.
1560 AddReceiverCheck(instr); 1551 AddReceiverCheck(instr);
1561 // Call can still deoptimize, do not detach environment from instr. 1552 // Call can still deoptimize, do not detach environment from instr.
1562 call_with_checks = false; 1553 const Function& target = Function::Handle(Z, unary_checks.GetTargetAt(0));
1554 StaticCallInstr* call = StaticCallInstr::FromCall(Z, instr, target);
1555 instr->ReplaceWith(call, current_iterator());
1563 } else { 1556 } else {
1564 call_with_checks = true; 1557 PolymorphicInstanceCallInstr* call =
1558 new (Z) PolymorphicInstanceCallInstr(instr, *targets,
1559 /* complete = */ false);
1560 instr->ReplaceWith(call, current_iterator());
1565 } 1561 }
1566 PolymorphicInstanceCallInstr* call =
1567 new (Z) PolymorphicInstanceCallInstr(instr, *targets, call_with_checks,
1568 /* complete = */ false);
1569 instr->ReplaceWith(call, current_iterator());
1570 } 1562 }
1571 1563
1572 1564
1573 void JitOptimizer::VisitStaticCall(StaticCallInstr* call) { 1565 void JitOptimizer::VisitStaticCall(StaticCallInstr* call) {
1574 MethodRecognizer::Kind recognized_kind = 1566 MethodRecognizer::Kind recognized_kind =
1575 MethodRecognizer::RecognizeKind(call->function()); 1567 MethodRecognizer::RecognizeKind(call->function());
1576 switch (recognized_kind) { 1568 switch (recognized_kind) {
1577 case MethodRecognizer::kObjectConstructor: 1569 case MethodRecognizer::kObjectConstructor:
1578 case MethodRecognizer::kObjectArrayAllocate: 1570 case MethodRecognizer::kObjectArrayAllocate:
1579 case MethodRecognizer::kFloat32x4Zero: 1571 case MethodRecognizer::kFloat32x4Zero:
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1813 // Discard the environment from the original instruction because the store 1805 // Discard the environment from the original instruction because the store
1814 // can't deoptimize. 1806 // can't deoptimize.
1815 instr->RemoveEnvironment(); 1807 instr->RemoveEnvironment();
1816 ReplaceCall(instr, store); 1808 ReplaceCall(instr, store);
1817 return true; 1809 return true;
1818 } 1810 }
1819 1811
1820 1812
1821 } // namespace dart 1813 } // namespace dart
1822 #endif // DART_PRECOMPILED_RUNTIME 1814 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_dbc.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698