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

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

Issue 475763002: VM: Small cleanup in optimizer and intrinsics code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intrinsifier_arm.cc » ('j') | 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 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 2249 matching lines...) Expand 10 before | Expand all | Expand 10 after
2260 cls = cls.SuperClass(); 2260 cls = cls.SuperClass();
2261 } 2261 }
2262 return Field::null(); 2262 return Field::null();
2263 } 2263 }
2264 2264
2265 2265
2266 // Use CHA to determine if the call needs a class check: if the callee's 2266 // Use CHA to determine if the call needs a class check: if the callee's
2267 // receiver is the same as the caller's receiver and there are no overriden 2267 // receiver is the same as the caller's receiver and there are no overriden
2268 // callee functions, then no class check is needed. 2268 // callee functions, then no class check is needed.
2269 bool FlowGraphOptimizer::InstanceCallNeedsClassCheck( 2269 bool FlowGraphOptimizer::InstanceCallNeedsClassCheck(
2270 InstanceCallInstr* call) const { 2270 InstanceCallInstr* call, bool is_method_extractor) const {
Vyacheslav Egorov (Google) 2014/08/14 14:21:13 I would prefer enum
Florian Schneider 2014/08/15 12:08:37 Done.
2271 if (!FLAG_use_cha) return true; 2271 if (!FLAG_use_cha) return true;
2272 Definition* callee_receiver = call->ArgumentAt(0); 2272 Definition* callee_receiver = call->ArgumentAt(0);
2273 ASSERT(callee_receiver != NULL); 2273 ASSERT(callee_receiver != NULL);
2274 const Function& function = flow_graph_->parsed_function().function(); 2274 const Function& function = flow_graph_->parsed_function().function();
2275 if (function.IsDynamicFunction() && 2275 if (function.IsDynamicFunction() &&
2276 callee_receiver->IsParameter() && 2276 callee_receiver->IsParameter() &&
2277 (callee_receiver->AsParameter()->index() == 0)) { 2277 (callee_receiver->AsParameter()->index() == 0)) {
2278 const String& name = is_method_extractor
2279 ? String::Handle(I, Field::NameFromGetter(call->function_name()))
2280 : call->function_name();
2278 return isolate()->cha()->HasOverride(Class::Handle(I, function.Owner()), 2281 return isolate()->cha()->HasOverride(Class::Handle(I, function.Owner()),
2279 call->function_name()); 2282 name);
2280 }
2281 return true;
2282 }
2283
2284
2285 bool FlowGraphOptimizer::MethodExtractorNeedsClassCheck(
2286 InstanceCallInstr* call) const {
2287 if (!FLAG_use_cha) return true;
2288 Definition* callee_receiver = call->ArgumentAt(0);
2289 ASSERT(callee_receiver != NULL);
2290 const Function& function = flow_graph_->parsed_function().function();
2291 if (function.IsDynamicFunction() &&
2292 callee_receiver->IsParameter() &&
2293 (callee_receiver->AsParameter()->index() == 0)) {
2294 const String& field_name =
2295 String::Handle(I, Field::NameFromGetter(call->function_name()));
2296 return isolate()->cha()->HasOverride(
2297 Class::Handle(I, function.Owner()), field_name);
2298 } 2283 }
2299 return true; 2284 return true;
2300 } 2285 }
2301 2286
2302 2287
2303 void FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) { 2288 void FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) {
2304 ASSERT(call->HasICData()); 2289 ASSERT(call->HasICData());
2305 const ICData& ic_data = *call->ic_data(); 2290 const ICData& ic_data = *call->ic_data();
2306 ASSERT(ic_data.HasOneTarget()); 2291 ASSERT(ic_data.HasOneTarget());
2307 Function& target = Function::Handle(I); 2292 Function& target = Function::Handle(I);
2308 GrowableArray<intptr_t> class_ids; 2293 GrowableArray<intptr_t> class_ids;
2309 ic_data.GetCheckAt(0, &class_ids, &target); 2294 ic_data.GetCheckAt(0, &class_ids, &target);
2310 ASSERT(class_ids.length() == 1); 2295 ASSERT(class_ids.length() == 1);
2311 // Inline implicit instance getter. 2296 // Inline implicit instance getter.
2312 const String& field_name = 2297 const String& field_name =
2313 String::Handle(I, Field::NameFromGetter(call->function_name())); 2298 String::Handle(I, Field::NameFromGetter(call->function_name()));
2314 const Field& field = 2299 const Field& field =
2315 Field::ZoneHandle(I, GetField(class_ids[0], field_name)); 2300 Field::ZoneHandle(I, GetField(class_ids[0], field_name));
2316 ASSERT(!field.IsNull()); 2301 ASSERT(!field.IsNull());
2317 2302
2318 if (InstanceCallNeedsClassCheck(call)) { 2303 if (InstanceCallNeedsClassCheck(call, false)) {
2319 AddReceiverCheck(call); 2304 AddReceiverCheck(call);
2320 } 2305 }
2321 LoadFieldInstr* load = new(I) LoadFieldInstr( 2306 LoadFieldInstr* load = new(I) LoadFieldInstr(
2322 new(I) Value(call->ArgumentAt(0)), 2307 new(I) Value(call->ArgumentAt(0)),
2323 &field, 2308 &field,
2324 AbstractType::ZoneHandle(I, field.type()), 2309 AbstractType::ZoneHandle(I, field.type()),
2325 call->token_pos()); 2310 call->token_pos());
2326 load->set_is_immutable(field.is_final()); 2311 load->set_is_immutable(field.is_final());
2327 if (field.guarded_cid() != kIllegalCid) { 2312 if (field.guarded_cid() != kIllegalCid) {
2328 if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) { 2313 if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) {
(...skipping 1817 matching lines...) Expand 10 before | Expand all | Expand 10 after
4146 return; 4131 return;
4147 } 4132 }
4148 4133
4149 const ICData& unary_checks = 4134 const ICData& unary_checks =
4150 ICData::ZoneHandle(I, instr->ic_data()->AsUnaryClassChecks()); 4135 ICData::ZoneHandle(I, instr->ic_data()->AsUnaryClassChecks());
4151 4136
4152 intptr_t max_checks = (op_kind == Token::kEQ) 4137 intptr_t max_checks = (op_kind == Token::kEQ)
4153 ? FLAG_max_equality_polymorphic_checks 4138 ? FLAG_max_equality_polymorphic_checks
4154 : FLAG_max_polymorphic_checks; 4139 : FLAG_max_polymorphic_checks;
4155 if ((unary_checks.NumberOfChecks() > max_checks) && 4140 if ((unary_checks.NumberOfChecks() > max_checks) &&
4156 InstanceCallNeedsClassCheck(instr)) { 4141 InstanceCallNeedsClassCheck(instr, false)) {
4157 // Too many checks, it will be megamorphic which needs unary checks. 4142 // Too many checks, it will be megamorphic which needs unary checks.
4158 instr->set_ic_data(&unary_checks); 4143 instr->set_ic_data(&unary_checks);
4159 return; 4144 return;
4160 } 4145 }
4161 4146
4162 if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithStoreIndexed(instr)) { 4147 if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithStoreIndexed(instr)) {
4163 return; 4148 return;
4164 } 4149 }
4165 if ((op_kind == Token::kINDEX) && TryReplaceWithLoadIndexed(instr)) { 4150 if ((op_kind == Token::kINDEX) && TryReplaceWithLoadIndexed(instr)) {
4166 return; 4151 return;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
4201 // we don't have one target. 4186 // we don't have one target.
4202 const Function& target = 4187 const Function& target =
4203 Function::Handle(I, unary_checks.GetTargetAt(0)); 4188 Function::Handle(I, unary_checks.GetTargetAt(0));
4204 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target); 4189 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target);
4205 has_one_target = !polymorphic_target; 4190 has_one_target = !polymorphic_target;
4206 } 4191 }
4207 4192
4208 if (has_one_target) { 4193 if (has_one_target) {
4209 const bool is_method_extraction = 4194 const bool is_method_extraction =
4210 Function::Handle(I, unary_checks.GetTargetAt(0)).IsMethodExtractor(); 4195 Function::Handle(I, unary_checks.GetTargetAt(0)).IsMethodExtractor();
4211 4196 if (!InstanceCallNeedsClassCheck(instr, is_method_extraction)) {
4212 if ((is_method_extraction && !MethodExtractorNeedsClassCheck(instr)) ||
4213 (!is_method_extraction && !InstanceCallNeedsClassCheck(instr))) {
4214 const bool call_with_checks = false; 4197 const bool call_with_checks = false;
4215 PolymorphicInstanceCallInstr* call = 4198 PolymorphicInstanceCallInstr* call =
4216 new(I) PolymorphicInstanceCallInstr(instr, unary_checks, 4199 new(I) PolymorphicInstanceCallInstr(instr, unary_checks,
4217 call_with_checks); 4200 call_with_checks);
4218 instr->ReplaceWith(call, current_iterator()); 4201 instr->ReplaceWith(call, current_iterator());
4219 return; 4202 return;
4220 } 4203 }
4221 } 4204 }
4222 4205
4223 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { 4206 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) {
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
4465 // Non-implicit setter are inlined like normal method calls. 4448 // Non-implicit setter are inlined like normal method calls.
4466 return false; 4449 return false;
4467 } 4450 }
4468 // Inline implicit instance setter. 4451 // Inline implicit instance setter.
4469 const String& field_name = 4452 const String& field_name =
4470 String::Handle(I, Field::NameFromSetter(instr->function_name())); 4453 String::Handle(I, Field::NameFromSetter(instr->function_name()));
4471 const Field& field = 4454 const Field& field =
4472 Field::ZoneHandle(I, GetField(class_id, field_name)); 4455 Field::ZoneHandle(I, GetField(class_id, field_name));
4473 ASSERT(!field.IsNull()); 4456 ASSERT(!field.IsNull());
4474 4457
4475 if (InstanceCallNeedsClassCheck(instr)) { 4458 if (InstanceCallNeedsClassCheck(instr, false)) {
4476 AddReceiverCheck(instr); 4459 AddReceiverCheck(instr);
4477 } 4460 }
4478 StoreBarrierType needs_store_barrier = kEmitStoreBarrier; 4461 StoreBarrierType needs_store_barrier = kEmitStoreBarrier;
4479 if (ArgIsAlways(kSmiCid, *instr->ic_data(), 1)) { 4462 if (ArgIsAlways(kSmiCid, *instr->ic_data(), 1)) {
4480 InsertBefore(instr, 4463 InsertBefore(instr,
4481 new(I) CheckSmiInstr( 4464 new(I) CheckSmiInstr(
4482 new(I) Value(instr->ArgumentAt(1)), 4465 new(I) Value(instr->ArgumentAt(1)),
4483 instr->deopt_id(), 4466 instr->deopt_id(),
4484 instr->token_pos()), 4467 instr->token_pos()),
4485 instr->env(), 4468 instr->env(),
(...skipping 5052 matching lines...) Expand 10 before | Expand all | Expand 10 after
9538 9521
9539 // Insert materializations at environment uses. 9522 // Insert materializations at environment uses.
9540 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 9523 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
9541 CreateMaterializationAt( 9524 CreateMaterializationAt(
9542 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); 9525 exits_collector_.exits()[i], alloc, alloc->cls(), *slots);
9543 } 9526 }
9544 } 9527 }
9545 9528
9546 9529
9547 } // namespace dart 9530 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intrinsifier_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698