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

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

Issue 436643002: Faster IC stubs by specializing them for Binary Smi operations (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
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/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 2373 matching lines...) Expand 10 before | Expand all | Expand 10 after
2384 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT)); 2384 ASSERT((kind == Token::kEQ_STRICT) || (kind == Token::kNE_STRICT));
2385 } 2385 }
2386 2386
2387 2387
2388 LocationSummary* InstanceCallInstr::MakeLocationSummary(Isolate* isolate, 2388 LocationSummary* InstanceCallInstr::MakeLocationSummary(Isolate* isolate,
2389 bool optimizing) const { 2389 bool optimizing) const {
2390 return MakeCallSummary(); 2390 return MakeCallSummary();
2391 } 2391 }
2392 2392
2393 2393
2394 static uword TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) {
2395 StubCode* stub_code = Isolate::Current()->stub_code();
2396 switch (kind) {
2397 case Token::kADD: return stub_code->SmiAddInlineCacheEntryPoint();
2398 case Token::kSUB: return stub_code->SmiSubInlineCacheEntryPoint();
2399 case Token::kEQ: return stub_code->SmiEqualInlineCacheEntryPoint();
2400 default: return 0;
2401 }
2402 }
2403
2404
2394 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2405 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2406 Isolate* isolate = compiler->isolate();
2395 const ICData* call_ic_data = NULL; 2407 const ICData* call_ic_data = NULL;
2396 if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) { 2408 if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) {
2397 const Array& arguments_descriptor = 2409 const Array& arguments_descriptor =
2398 Array::Handle(ArgumentsDescriptor::New(ArgumentCount(), 2410 Array::Handle(isolate, ArgumentsDescriptor::New(ArgumentCount(),
2399 argument_names())); 2411 argument_names()));
2400 call_ic_data = compiler->GetOrAddInstanceCallICData( 2412 call_ic_data = compiler->GetOrAddInstanceCallICData(
2401 deopt_id(), function_name(), arguments_descriptor, 2413 deopt_id(), function_name(), arguments_descriptor,
2402 checked_argument_count()); 2414 checked_argument_count());
2403 } else { 2415 } else {
2404 call_ic_data = &ICData::ZoneHandle(ic_data()->raw()); 2416 call_ic_data = &ICData::ZoneHandle(isolate, ic_data()->raw());
2405 } 2417 }
2406 if (compiler->is_optimizing()) { 2418 if (compiler->is_optimizing()) {
2407 ASSERT(HasICData()); 2419 ASSERT(HasICData());
2408 if (ic_data()->NumberOfChecks() > 0) { 2420 if (ic_data()->NumberOfChecks() > 0) {
2409 const ICData& unary_ic_data = 2421 const ICData& unary_ic_data =
2410 ICData::ZoneHandle(ic_data()->AsUnaryClassChecks()); 2422 ICData::ZoneHandle(isolate, ic_data()->AsUnaryClassChecks());
2411 compiler->GenerateInstanceCall(deopt_id(), 2423 compiler->GenerateInstanceCall(deopt_id(),
2412 token_pos(), 2424 token_pos(),
2413 ArgumentCount(), 2425 ArgumentCount(),
2414 locs(), 2426 locs(),
2415 unary_ic_data); 2427 unary_ic_data);
2416 } else { 2428 } else {
2417 // Call was not visited yet, use original ICData in order to populate it. 2429 // Call was not visited yet, use original ICData in order to populate it.
2418 compiler->GenerateInstanceCall(deopt_id(), 2430 compiler->GenerateInstanceCall(deopt_id(),
2419 token_pos(), 2431 token_pos(),
2420 ArgumentCount(), 2432 ArgumentCount(),
2421 locs(), 2433 locs(),
2422 *call_ic_data); 2434 *call_ic_data);
2423 } 2435 }
2424 } else { 2436 } else {
2425 // Unoptimized code. 2437 // Unoptimized code.
2426 ASSERT(!HasICData()); 2438 ASSERT(!HasICData());
2427 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, 2439 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
2428 deopt_id(), 2440 deopt_id(),
2429 token_pos()); 2441 token_pos());
2430 compiler->GenerateInstanceCall(deopt_id(), 2442 bool is_smi_two_args_op = false;
2431 token_pos(), 2443 const uword label_address = TwoArgsSmiOpInlineCacheEntry(token_kind());
2432 ArgumentCount(), 2444 if (label_address != 0) {
Cutch 2014/08/15 21:23:28 != NULL ?
Ivan Posva 2014/08/15 21:32:34 uword is an integer type.
2433 locs(), 2445 // We have a dedicated inline cache stub for this operation, add an
2434 *call_ic_data); 2446 // an initial Smi/Smi check with count 0.
2447 ASSERT(call_ic_data->NumArgsTested() == 2);
2448 const String& name = String::Handle(isolate, call_ic_data->target_name());
2449 const Class& smi_class = Class::Handle(isolate, Smi::Class());
2450 const Function& smi_op_target =
2451 Function::Handle(Resolver::ResolveDynamicAnyArgs(smi_class, name));
2452 if (call_ic_data->NumberOfChecks() == 0) {
2453 GrowableArray<intptr_t> class_ids(2);
2454 class_ids.Add(kSmiCid);
2455 class_ids.Add(kSmiCid);
2456 call_ic_data->AddCheck(class_ids, smi_op_target);
2457 // 'AddCheck' sets the initial count to 1.
2458 call_ic_data->SetCountAt(0, 0);
2459 is_smi_two_args_op = true;
2460 } else if (call_ic_data->NumberOfChecks() == 1) {
2461 GrowableArray<intptr_t> class_ids(2);
2462 Function& target = Function::Handle(isolate);
2463 call_ic_data->GetCheckAt(0, &class_ids, &target);
2464 if ((target.raw() == smi_op_target.raw()) &&
2465 (class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) {
2466 is_smi_two_args_op = true;
2467 }
2468 }
2469 }
2470 if (is_smi_two_args_op) {
2471 ASSERT(ArgumentCount() == 2);
2472 ExternalLabel target_label(label_address);
2473 compiler->EmitInstanceCall(&target_label, *call_ic_data, ArgumentCount(),
2474 deopt_id(), token_pos(), locs());
2475 } else {
2476 compiler->GenerateInstanceCall(deopt_id(),
2477 token_pos(),
2478 ArgumentCount(),
2479 locs(),
2480 *call_ic_data);
2481 }
2435 } 2482 }
2436 } 2483 }
2437 2484
2438 2485
2439 bool PolymorphicInstanceCallInstr::HasSingleRecognizedTarget() const { 2486 bool PolymorphicInstanceCallInstr::HasSingleRecognizedTarget() const {
2440 return ic_data().HasOneTarget() && 2487 return ic_data().HasOneTarget() &&
2441 (MethodRecognizer::RecognizeKind( 2488 (MethodRecognizer::RecognizeKind(
2442 Function::Handle(ic_data().GetTargetAt(0))) != 2489 Function::Handle(ic_data().GetTargetAt(0))) !=
2443 MethodRecognizer::kUnknown); 2490 MethodRecognizer::kUnknown);
2444 } 2491 }
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
2962 case Token::kTRUNCDIV: return 0; 3009 case Token::kTRUNCDIV: return 0;
2963 case Token::kMOD: return 1; 3010 case Token::kMOD: return 1;
2964 default: UNIMPLEMENTED(); return -1; 3011 default: UNIMPLEMENTED(); return -1;
2965 } 3012 }
2966 } 3013 }
2967 3014
2968 3015
2969 #undef __ 3016 #undef __
2970 3017
2971 } // namespace dart 3018 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/il_printer.cc ('k') | runtime/vm/object.h » ('j') | runtime/vm/object.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698