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

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, RawFunction::Kind kind) const {
2271 ASSERT(kind == RawFunction::kRegularFunction ||
2272 kind == RawFunction::kMethodExtractor);
2271 if (!FLAG_use_cha) return true; 2273 if (!FLAG_use_cha) return true;
2272 Definition* callee_receiver = call->ArgumentAt(0); 2274 Definition* callee_receiver = call->ArgumentAt(0);
2273 ASSERT(callee_receiver != NULL); 2275 ASSERT(callee_receiver != NULL);
2274 const Function& function = flow_graph_->parsed_function().function(); 2276 const Function& function = flow_graph_->parsed_function().function();
2275 if (function.IsDynamicFunction() && 2277 if (function.IsDynamicFunction() &&
2276 callee_receiver->IsParameter() && 2278 callee_receiver->IsParameter() &&
2277 (callee_receiver->AsParameter()->index() == 0)) { 2279 (callee_receiver->AsParameter()->index() == 0)) {
2280 const String& name = (kind == RawFunction::kMethodExtractor)
2281 ? String::Handle(I, Field::NameFromGetter(call->function_name()))
2282 : call->function_name();
2278 return isolate()->cha()->HasOverride(Class::Handle(I, function.Owner()), 2283 return isolate()->cha()->HasOverride(Class::Handle(I, function.Owner()),
2279 call->function_name()); 2284 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 } 2285 }
2299 return true; 2286 return true;
2300 } 2287 }
2301 2288
2302 2289
2303 void FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) { 2290 void FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) {
2304 ASSERT(call->HasICData()); 2291 ASSERT(call->HasICData());
2305 const ICData& ic_data = *call->ic_data(); 2292 const ICData& ic_data = *call->ic_data();
2306 ASSERT(ic_data.HasOneTarget()); 2293 ASSERT(ic_data.HasOneTarget());
2307 Function& target = Function::Handle(I); 2294 Function& target = Function::Handle(I);
2308 GrowableArray<intptr_t> class_ids; 2295 GrowableArray<intptr_t> class_ids;
2309 ic_data.GetCheckAt(0, &class_ids, &target); 2296 ic_data.GetCheckAt(0, &class_ids, &target);
2310 ASSERT(class_ids.length() == 1); 2297 ASSERT(class_ids.length() == 1);
2311 // Inline implicit instance getter. 2298 // Inline implicit instance getter.
2312 const String& field_name = 2299 const String& field_name =
2313 String::Handle(I, Field::NameFromGetter(call->function_name())); 2300 String::Handle(I, Field::NameFromGetter(call->function_name()));
2314 const Field& field = 2301 const Field& field =
2315 Field::ZoneHandle(I, GetField(class_ids[0], field_name)); 2302 Field::ZoneHandle(I, GetField(class_ids[0], field_name));
2316 ASSERT(!field.IsNull()); 2303 ASSERT(!field.IsNull());
2317 2304
2318 if (InstanceCallNeedsClassCheck(call)) { 2305 if (InstanceCallNeedsClassCheck(call, RawFunction::kRegularFunction)) {
2319 AddReceiverCheck(call); 2306 AddReceiverCheck(call);
2320 } 2307 }
2321 LoadFieldInstr* load = new(I) LoadFieldInstr( 2308 LoadFieldInstr* load = new(I) LoadFieldInstr(
2322 new(I) Value(call->ArgumentAt(0)), 2309 new(I) Value(call->ArgumentAt(0)),
2323 &field, 2310 &field,
2324 AbstractType::ZoneHandle(I, field.type()), 2311 AbstractType::ZoneHandle(I, field.type()),
2325 call->token_pos()); 2312 call->token_pos());
2326 load->set_is_immutable(field.is_final()); 2313 load->set_is_immutable(field.is_final());
2327 if (field.guarded_cid() != kIllegalCid) { 2314 if (field.guarded_cid() != kIllegalCid) {
2328 if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) { 2315 if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) {
(...skipping 1817 matching lines...) Expand 10 before | Expand all | Expand 10 after
4146 return; 4133 return;
4147 } 4134 }
4148 4135
4149 const ICData& unary_checks = 4136 const ICData& unary_checks =
4150 ICData::ZoneHandle(I, instr->ic_data()->AsUnaryClassChecks()); 4137 ICData::ZoneHandle(I, instr->ic_data()->AsUnaryClassChecks());
4151 4138
4152 intptr_t max_checks = (op_kind == Token::kEQ) 4139 intptr_t max_checks = (op_kind == Token::kEQ)
4153 ? FLAG_max_equality_polymorphic_checks 4140 ? FLAG_max_equality_polymorphic_checks
4154 : FLAG_max_polymorphic_checks; 4141 : FLAG_max_polymorphic_checks;
4155 if ((unary_checks.NumberOfChecks() > max_checks) && 4142 if ((unary_checks.NumberOfChecks() > max_checks) &&
4156 InstanceCallNeedsClassCheck(instr)) { 4143 InstanceCallNeedsClassCheck(instr, RawFunction::kRegularFunction)) {
4157 // Too many checks, it will be megamorphic which needs unary checks. 4144 // Too many checks, it will be megamorphic which needs unary checks.
4158 instr->set_ic_data(&unary_checks); 4145 instr->set_ic_data(&unary_checks);
4159 return; 4146 return;
4160 } 4147 }
4161 4148
4162 if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithStoreIndexed(instr)) { 4149 if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithStoreIndexed(instr)) {
4163 return; 4150 return;
4164 } 4151 }
4165 if ((op_kind == Token::kINDEX) && TryReplaceWithLoadIndexed(instr)) { 4152 if ((op_kind == Token::kINDEX) && TryReplaceWithLoadIndexed(instr)) {
4166 return; 4153 return;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
4199 if (has_one_target) { 4186 if (has_one_target) {
4200 // Check if the single target is a polymorphic target, if it is, 4187 // Check if the single target is a polymorphic target, if it is,
4201 // we don't have one target. 4188 // we don't have one target.
4202 const Function& target = 4189 const Function& target =
4203 Function::Handle(I, unary_checks.GetTargetAt(0)); 4190 Function::Handle(I, unary_checks.GetTargetAt(0));
4204 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target); 4191 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target);
4205 has_one_target = !polymorphic_target; 4192 has_one_target = !polymorphic_target;
4206 } 4193 }
4207 4194
4208 if (has_one_target) { 4195 if (has_one_target) {
4209 const bool is_method_extraction = 4196 RawFunction::Kind function_kind =
4210 Function::Handle(I, unary_checks.GetTargetAt(0)).IsMethodExtractor(); 4197 Function::Handle(I, unary_checks.GetTargetAt(0)).kind();
4211 4198 if (!InstanceCallNeedsClassCheck(instr, function_kind)) {
4212 if ((is_method_extraction && !MethodExtractorNeedsClassCheck(instr)) ||
4213 (!is_method_extraction && !InstanceCallNeedsClassCheck(instr))) {
4214 const bool call_with_checks = false; 4199 const bool call_with_checks = false;
4215 PolymorphicInstanceCallInstr* call = 4200 PolymorphicInstanceCallInstr* call =
4216 new(I) PolymorphicInstanceCallInstr(instr, unary_checks, 4201 new(I) PolymorphicInstanceCallInstr(instr, unary_checks,
4217 call_with_checks); 4202 call_with_checks);
4218 instr->ReplaceWith(call, current_iterator()); 4203 instr->ReplaceWith(call, current_iterator());
4219 return; 4204 return;
4220 } 4205 }
4221 } 4206 }
4222 4207
4223 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { 4208 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. 4450 // Non-implicit setter are inlined like normal method calls.
4466 return false; 4451 return false;
4467 } 4452 }
4468 // Inline implicit instance setter. 4453 // Inline implicit instance setter.
4469 const String& field_name = 4454 const String& field_name =
4470 String::Handle(I, Field::NameFromSetter(instr->function_name())); 4455 String::Handle(I, Field::NameFromSetter(instr->function_name()));
4471 const Field& field = 4456 const Field& field =
4472 Field::ZoneHandle(I, GetField(class_id, field_name)); 4457 Field::ZoneHandle(I, GetField(class_id, field_name));
4473 ASSERT(!field.IsNull()); 4458 ASSERT(!field.IsNull());
4474 4459
4475 if (InstanceCallNeedsClassCheck(instr)) { 4460 if (InstanceCallNeedsClassCheck(instr, RawFunction::kRegularFunction)) {
4476 AddReceiverCheck(instr); 4461 AddReceiverCheck(instr);
4477 } 4462 }
4478 StoreBarrierType needs_store_barrier = kEmitStoreBarrier; 4463 StoreBarrierType needs_store_barrier = kEmitStoreBarrier;
4479 if (ArgIsAlways(kSmiCid, *instr->ic_data(), 1)) { 4464 if (ArgIsAlways(kSmiCid, *instr->ic_data(), 1)) {
4480 InsertBefore(instr, 4465 InsertBefore(instr,
4481 new(I) CheckSmiInstr( 4466 new(I) CheckSmiInstr(
4482 new(I) Value(instr->ArgumentAt(1)), 4467 new(I) Value(instr->ArgumentAt(1)),
4483 instr->deopt_id(), 4468 instr->deopt_id(),
4484 instr->token_pos()), 4469 instr->token_pos()),
4485 instr->env(), 4470 instr->env(),
(...skipping 5052 matching lines...) Expand 10 before | Expand all | Expand 10 after
9538 9523
9539 // Insert materializations at environment uses. 9524 // Insert materializations at environment uses.
9540 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 9525 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
9541 CreateMaterializationAt( 9526 CreateMaterializationAt(
9542 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); 9527 exits_collector_.exits()[i], alloc, alloc->cls(), *slots);
9543 } 9528 }
9544 } 9529 }
9545 9530
9546 9531
9547 } // namespace dart 9532 } // 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