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

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

Issue 17421003: Store arguments descriptor in ICData. Remove loading of arguments descriptor at unoptimized call si… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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/intermediate_language_mips.cc ('k') | runtime/vm/object.h » ('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/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 __ subq(RDX, Immediate(1)); 267 __ subq(RDX, Immediate(1));
268 __ andq(RDX, Immediate( 268 __ andq(RDX, Immediate(
269 Smi::RawValue(true_value) - Smi::RawValue(false_value))); 269 Smi::RawValue(true_value) - Smi::RawValue(false_value)));
270 if (false_value != 0) { 270 if (false_value != 0) {
271 __ addq(RDX, Immediate(Smi::RawValue(false_value))); 271 __ addq(RDX, Immediate(Smi::RawValue(false_value)));
272 } 272 }
273 } 273 }
274 } 274 }
275 275
276 276
277 LocationSummary* ClosureCallInstr::MakeLocationSummary() const {
278 const intptr_t kNumInputs = 0;
279 const intptr_t kNumTemps = 1;
280 LocationSummary* result =
281 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
282 result->set_out(Location::RegisterLocation(RAX));
283 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor.
284 return result;
285 }
286
287
288 LocationSummary* LoadLocalInstr::MakeLocationSummary() const { 277 LocationSummary* LoadLocalInstr::MakeLocationSummary() const {
289 const intptr_t kNumInputs = 0; 278 const intptr_t kNumInputs = 0;
290 return LocationSummary::Make(kNumInputs, 279 return LocationSummary::Make(kNumInputs,
291 Location::RequiresRegister(), 280 Location::RequiresRegister(),
292 LocationSummary::kNoCall); 281 LocationSummary::kNoCall);
293 } 282 }
294 283
295 284
296 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 285 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
297 Register result = locs()->out().reg(); 286 Register result = locs()->out().reg();
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 intptr_t token_pos, 484 intptr_t token_pos,
496 Token::Kind kind, 485 Token::Kind kind,
497 LocationSummary* locs, 486 LocationSummary* locs,
498 const ICData& original_ic_data) { 487 const ICData& original_ic_data) {
499 if (!compiler->is_optimizing()) { 488 if (!compiler->is_optimizing()) {
500 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 489 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
501 deopt_id, 490 deopt_id,
502 token_pos); 491 token_pos);
503 } 492 }
504 const int kNumberOfArguments = 2; 493 const int kNumberOfArguments = 2;
505 const Array& kNoArgumentNames = Array::Handle(); 494 const Array& kNoArgumentNames = Object::null_array();
506 const int kNumArgumentsChecked = 2; 495 const int kNumArgumentsChecked = 2;
507 496
508 const Immediate& raw_null = 497 const Immediate& raw_null =
509 Immediate(reinterpret_cast<intptr_t>(Object::null())); 498 Immediate(reinterpret_cast<intptr_t>(Object::null()));
510 Label check_identity; 499 Label check_identity;
511 __ cmpq(Address(RSP, 0 * kWordSize), raw_null); 500 __ cmpq(Address(RSP, 0 * kWordSize), raw_null);
512 __ j(EQUAL, &check_identity); 501 __ j(EQUAL, &check_identity);
513 __ cmpq(Address(RSP, 1 * kWordSize), raw_null); 502 __ cmpq(Address(RSP, 1 * kWordSize), raw_null);
514 __ j(EQUAL, &check_identity); 503 __ j(EQUAL, &check_identity);
515 504
516 ICData& equality_ic_data = ICData::ZoneHandle(original_ic_data.raw()); 505 ICData& equality_ic_data = ICData::ZoneHandle(original_ic_data.raw());
517 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { 506 if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
518 ASSERT(!original_ic_data.IsNull()); 507 ASSERT(!original_ic_data.IsNull());
519 if (original_ic_data.NumberOfChecks() == 0) { 508 if (original_ic_data.NumberOfChecks() == 0) {
520 // IC call for reoptimization populates original ICData. 509 // IC call for reoptimization populates original ICData.
521 equality_ic_data = original_ic_data.raw(); 510 equality_ic_data = original_ic_data.raw();
522 } else { 511 } else {
523 // Megamorphic call. 512 // Megamorphic call.
524 equality_ic_data = original_ic_data.AsUnaryClassChecks(); 513 equality_ic_data = original_ic_data.AsUnaryClassChecks();
525 } 514 }
526 } else { 515 } else {
516 const Array& arguments_descriptor =
517 Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments,
518 kNoArgumentNames));
527 equality_ic_data = ICData::New(compiler->parsed_function().function(), 519 equality_ic_data = ICData::New(compiler->parsed_function().function(),
528 Symbols::EqualOperator(), 520 Symbols::EqualOperator(),
521 arguments_descriptor,
529 deopt_id, 522 deopt_id,
530 kNumArgumentsChecked); 523 kNumArgumentsChecked);
531 } 524 }
532 compiler->GenerateInstanceCall(deopt_id, 525 compiler->GenerateInstanceCall(deopt_id,
533 token_pos, 526 token_pos,
534 kNumberOfArguments, 527 kNumberOfArguments,
535 kNoArgumentNames, 528 kNoArgumentNames,
536 locs, 529 locs,
537 equality_ic_data); 530 equality_ic_data);
538 Label check_ne; 531 Label check_ne;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 Register result = locs->out().reg(); 639 Register result = locs->out().reg();
647 Label load_true; 640 Label load_true;
648 __ j(cond, &load_true, Assembler::kNearJump); 641 __ j(cond, &load_true, Assembler::kNearJump);
649 __ LoadObject(result, Bool::False()); 642 __ LoadObject(result, Bool::False());
650 __ jmp(&done); 643 __ jmp(&done);
651 __ Bind(&load_true); 644 __ Bind(&load_true);
652 __ LoadObject(result, Bool::True()); 645 __ LoadObject(result, Bool::True());
653 } 646 }
654 } else { 647 } else {
655 const int kNumberOfArguments = 2; 648 const int kNumberOfArguments = 2;
656 const Array& kNoArgumentNames = Array::Handle(); 649 const Array& kNoArgumentNames = Object::null_array();
657 compiler->GenerateStaticCall(deopt_id, 650 compiler->GenerateStaticCall(deopt_id,
658 token_pos, 651 token_pos,
659 target, 652 target,
660 kNumberOfArguments, 653 kNumberOfArguments,
661 kNoArgumentNames, 654 kNoArgumentNames,
662 locs); 655 locs);
663 if (branch == NULL) { 656 if (branch == NULL) {
664 if (kind == Token::kNE) { 657 if (kind == Token::kNE) {
665 Label false_label; 658 Label false_label;
666 __ CompareObject(RAX, Bool::True()); 659 __ CompareObject(RAX, Bool::True());
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
1006 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptRelationalOp); 999 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptRelationalOp);
1007 1000
1008 // Load class into RDI. Since this is a call, any register except 1001 // Load class into RDI. Since this is a call, any register except
1009 // the fixed input registers would be ok. 1002 // the fixed input registers would be ok.
1010 ASSERT((left != RDI) && (right != RDI)); 1003 ASSERT((left != RDI) && (right != RDI));
1011 LoadValueCid(compiler, RDI, left); 1004 LoadValueCid(compiler, RDI, left);
1012 const intptr_t kNumArguments = 2; 1005 const intptr_t kNumArguments = 2;
1013 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), 1006 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
1014 RDI, // Class id register. 1007 RDI, // Class id register.
1015 kNumArguments, 1008 kNumArguments,
1016 Array::Handle(), // No named arguments. 1009 Object::null_array(), // No named arguments.
1017 deopt, // Deoptimize target. 1010 deopt, // Deoptimize target.
1018 deopt_id(), 1011 deopt_id(),
1019 token_pos(), 1012 token_pos(),
1020 locs()); 1013 locs());
1021 return; 1014 return;
1022 } 1015 }
1023 const String& function_name = 1016 const String& function_name =
1024 String::ZoneHandle(Symbols::New(Token::Str(kind()))); 1017 String::ZoneHandle(Symbols::New(Token::Str(kind())));
1025 if (!compiler->is_optimizing()) { 1018 if (!compiler->is_optimizing()) {
1026 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 1019 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
1027 deopt_id(), 1020 deopt_id(),
1028 token_pos()); 1021 token_pos());
1029 } 1022 }
1030 const intptr_t kNumArguments = 2; 1023 const intptr_t kNumArguments = 2;
1031 const intptr_t kNumArgsChecked = 2; // Type-feedback. 1024 const intptr_t kNumArgsChecked = 2; // Type-feedback.
1032 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw()); 1025 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw());
1033 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { 1026 if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
1034 ASSERT(!ic_data()->IsNull()); 1027 ASSERT(!ic_data()->IsNull());
1035 if (ic_data()->NumberOfChecks() == 0) { 1028 if (ic_data()->NumberOfChecks() == 0) {
1036 // IC call for reoptimization populates original ICData. 1029 // IC call for reoptimization populates original ICData.
1037 relational_ic_data = ic_data()->raw(); 1030 relational_ic_data = ic_data()->raw();
1038 } else { 1031 } else {
1039 // Megamorphic call. 1032 // Megamorphic call.
1040 relational_ic_data = ic_data()->AsUnaryClassChecks(); 1033 relational_ic_data = ic_data()->AsUnaryClassChecks();
1041 } 1034 }
1042 } else { 1035 } else {
1036 const Array& arguments_descriptor =
1037 Array::Handle(ArgumentsDescriptor::New(kNumArguments,
1038 Object::null_array()));
1043 relational_ic_data = ICData::New(compiler->parsed_function().function(), 1039 relational_ic_data = ICData::New(compiler->parsed_function().function(),
1044 function_name, 1040 function_name,
1041 arguments_descriptor,
1045 deopt_id(), 1042 deopt_id(),
1046 kNumArgsChecked); 1043 kNumArgsChecked);
1047 } 1044 }
1048 compiler->GenerateInstanceCall(deopt_id(), 1045 compiler->GenerateInstanceCall(deopt_id(),
1049 token_pos(), 1046 token_pos(),
1050 kNumArguments, 1047 kNumArguments,
1051 Array::ZoneHandle(), // No optional arguments. 1048 Object::null_array(), // No optional args.
1052 locs(), 1049 locs(),
1053 relational_ic_data); 1050 relational_ic_data);
1054 } 1051 }
1055 1052
1056 1053
1057 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 1054 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
1058 BranchInstr* branch) { 1055 BranchInstr* branch) {
1059 if (operands_class_id() == kSmiCid) { 1056 if (operands_class_id() == kSmiCid) {
1060 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 1057 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
1061 return; 1058 return;
(...skipping 2725 matching lines...) Expand 10 before | Expand all | Expand 10 after
3787 const ICData& ic_data = *instance_call()->ic_data(); 3784 const ICData& ic_data = *instance_call()->ic_data();
3788 ASSERT((ic_data.NumberOfChecks() == 1)); 3785 ASSERT((ic_data.NumberOfChecks() == 1));
3789 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); 3786 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
3790 3787
3791 const intptr_t kNumberOfArguments = 1; 3788 const intptr_t kNumberOfArguments = 1;
3792 __ pushq(value_obj); 3789 __ pushq(value_obj);
3793 compiler->GenerateStaticCall(deopt_id(), 3790 compiler->GenerateStaticCall(deopt_id(),
3794 instance_call()->token_pos(), 3791 instance_call()->token_pos(),
3795 target, 3792 target,
3796 kNumberOfArguments, 3793 kNumberOfArguments,
3797 Array::Handle(), // No argument names. 3794 Object::null_array(), // No argument names.
3798 locs()); 3795 locs());
3799 __ Bind(&done); 3796 __ Bind(&done);
3800 } 3797 }
3801 3798
3802 3799
3803 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { 3800 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const {
3804 const intptr_t kNumInputs = 1; 3801 const intptr_t kNumInputs = 1;
3805 const intptr_t kNumTemps = 1; 3802 const intptr_t kNumTemps = 1;
3806 LocationSummary* result = new LocationSummary( 3803 LocationSummary* result = new LocationSummary(
3807 kNumInputs, kNumTemps, LocationSummary::kNoCall); 3804 kNumInputs, kNumTemps, LocationSummary::kNoCall);
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
4314 right.reg(), 4311 right.reg(),
4315 needs_number_check(), 4312 needs_number_check(),
4316 token_pos()); 4313 token_pos());
4317 } 4314 }
4318 4315
4319 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL; 4316 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
4320 branch->EmitBranchOnCondition(compiler, true_condition); 4317 branch->EmitBranchOnCondition(compiler, true_condition);
4321 } 4318 }
4322 4319
4323 4320
4321 LocationSummary* ClosureCallInstr::MakeLocationSummary() const {
4322 const intptr_t kNumInputs = 0;
4323 const intptr_t kNumTemps = 1;
4324 LocationSummary* result =
4325 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4326 result->set_out(Location::RegisterLocation(RAX));
4327 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor.
4328 return result;
4329 }
4330
4331
4324 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4332 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4325 // The arguments to the stub include the closure, as does the arguments 4333 // The arguments to the stub include the closure, as does the arguments
4326 // descriptor. 4334 // descriptor.
4327 Register temp_reg = locs()->temp(0).reg(); 4335 Register temp_reg = locs()->temp(0).reg();
4328 int argument_count = ArgumentCount(); 4336 int argument_count = ArgumentCount();
4329 const Array& arguments_descriptor = 4337 const Array& arguments_descriptor =
4330 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, 4338 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
4331 argument_names())); 4339 argument_names()));
4332 __ LoadObject(temp_reg, arguments_descriptor); 4340 __ LoadObject(temp_reg, arguments_descriptor);
4341 ASSERT(temp_reg == R10);
4333 compiler->GenerateDartCall(deopt_id(), 4342 compiler->GenerateDartCall(deopt_id(),
4334 token_pos(), 4343 token_pos(),
4335 &StubCode::CallClosureFunctionLabel(), 4344 &StubCode::CallClosureFunctionLabel(),
4336 PcDescriptors::kClosureCall, 4345 PcDescriptors::kClosureCall,
4337 locs()); 4346 locs());
4338 __ Drop(argument_count); 4347 __ Drop(argument_count);
4339 } 4348 }
4340 4349
4341 4350
4342 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { 4351 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
4437 PcDescriptors::kOther, 4446 PcDescriptors::kOther,
4438 locs()); 4447 locs());
4439 __ Drop(2); // Discard type arguments and receiver. 4448 __ Drop(2); // Discard type arguments and receiver.
4440 } 4449 }
4441 4450
4442 } // namespace dart 4451 } // namespace dart
4443 4452
4444 #undef __ 4453 #undef __
4445 4454
4446 #endif // defined TARGET_ARCH_X64 4455 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698