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

Side by Side Diff: runtime/vm/intermediate_language_ia32.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_arm.cc ('k') | runtime/vm/intermediate_language_mips.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/globals.h" // Needed here to get TARGET_ARCH_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 101
102 // Generate 1 byte NOP so that the debugger can patch the 102 // Generate 1 byte NOP so that the debugger can patch the
103 // return pattern with a call to the debug stub. 103 // return pattern with a call to the debug stub.
104 __ nop(1); 104 __ nop(1);
105 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 105 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
106 Isolate::kNoDeoptId, 106 Isolate::kNoDeoptId,
107 token_pos()); 107 token_pos());
108 } 108 }
109 109
110 110
111 LocationSummary* ClosureCallInstr::MakeLocationSummary() const {
112 const intptr_t kNumInputs = 0;
113 const intptr_t kNumTemps = 1;
114 LocationSummary* result =
115 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
116 result->set_out(Location::RegisterLocation(EAX));
117 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor.
118 return result;
119 }
120
121
122 LocationSummary* LoadLocalInstr::MakeLocationSummary() const { 111 LocationSummary* LoadLocalInstr::MakeLocationSummary() const {
123 const intptr_t kNumInputs = 0; 112 const intptr_t kNumInputs = 0;
124 return LocationSummary::Make(kNumInputs, 113 return LocationSummary::Make(kNumInputs,
125 Location::RequiresRegister(), 114 Location::RequiresRegister(),
126 LocationSummary::kNoCall); 115 LocationSummary::kNoCall);
127 } 116 }
128 117
129 118
130 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 119 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
131 Register result = locs()->out().reg(); 120 Register result = locs()->out().reg();
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 intptr_t token_pos, 328 intptr_t token_pos,
340 Token::Kind kind, 329 Token::Kind kind,
341 LocationSummary* locs, 330 LocationSummary* locs,
342 const ICData& original_ic_data) { 331 const ICData& original_ic_data) {
343 if (!compiler->is_optimizing()) { 332 if (!compiler->is_optimizing()) {
344 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 333 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
345 deopt_id, 334 deopt_id,
346 token_pos); 335 token_pos);
347 } 336 }
348 const int kNumberOfArguments = 2; 337 const int kNumberOfArguments = 2;
349 const Array& kNoArgumentNames = Array::Handle(); 338 const Array& kNoArgumentNames = Object::null_array();
350 const int kNumArgumentsChecked = 2; 339 const int kNumArgumentsChecked = 2;
351 340
352 const Immediate& raw_null = 341 const Immediate& raw_null =
353 Immediate(reinterpret_cast<intptr_t>(Object::null())); 342 Immediate(reinterpret_cast<intptr_t>(Object::null()));
354 Label check_identity; 343 Label check_identity;
355 __ cmpl(Address(ESP, 0 * kWordSize), raw_null); 344 __ cmpl(Address(ESP, 0 * kWordSize), raw_null);
356 __ j(EQUAL, &check_identity); 345 __ j(EQUAL, &check_identity);
357 __ cmpl(Address(ESP, 1 * kWordSize), raw_null); 346 __ cmpl(Address(ESP, 1 * kWordSize), raw_null);
358 __ j(EQUAL, &check_identity); 347 __ j(EQUAL, &check_identity);
359 348
360 ICData& equality_ic_data = ICData::ZoneHandle(); 349 ICData& equality_ic_data = ICData::ZoneHandle();
361 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { 350 if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
362 ASSERT(!original_ic_data.IsNull()); 351 ASSERT(!original_ic_data.IsNull());
363 if (original_ic_data.NumberOfChecks() == 0) { 352 if (original_ic_data.NumberOfChecks() == 0) {
364 // IC call for reoptimization populates original ICData. 353 // IC call for reoptimization populates original ICData.
365 equality_ic_data = original_ic_data.raw(); 354 equality_ic_data = original_ic_data.raw();
366 } else { 355 } else {
367 // Megamorphic call. 356 // Megamorphic call.
368 equality_ic_data = original_ic_data.AsUnaryClassChecks(); 357 equality_ic_data = original_ic_data.AsUnaryClassChecks();
369 } 358 }
370 } else { 359 } else {
360 const Array& arguments_descriptor =
361 Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments,
362 kNoArgumentNames));
371 equality_ic_data = ICData::New(compiler->parsed_function().function(), 363 equality_ic_data = ICData::New(compiler->parsed_function().function(),
372 Symbols::EqualOperator(), 364 Symbols::EqualOperator(),
365 arguments_descriptor,
373 deopt_id, 366 deopt_id,
374 kNumArgumentsChecked); 367 kNumArgumentsChecked);
375 } 368 }
376 compiler->GenerateInstanceCall(deopt_id, 369 compiler->GenerateInstanceCall(deopt_id,
377 token_pos, 370 token_pos,
378 kNumberOfArguments, 371 kNumberOfArguments,
379 kNoArgumentNames, 372 kNoArgumentNames,
380 locs, 373 locs,
381 equality_ic_data); 374 equality_ic_data);
382 Label check_ne; 375 Label check_ne;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 Register result = locs->out().reg(); 482 Register result = locs->out().reg();
490 Label load_true; 483 Label load_true;
491 __ j(cond, &load_true, Assembler::kNearJump); 484 __ j(cond, &load_true, Assembler::kNearJump);
492 __ LoadObject(result, Bool::False()); 485 __ LoadObject(result, Bool::False());
493 __ jmp(&done); 486 __ jmp(&done);
494 __ Bind(&load_true); 487 __ Bind(&load_true);
495 __ LoadObject(result, Bool::True()); 488 __ LoadObject(result, Bool::True());
496 } 489 }
497 } else { 490 } else {
498 const int kNumberOfArguments = 2; 491 const int kNumberOfArguments = 2;
499 const Array& kNoArgumentNames = Array::Handle(); 492 const Array& kNoArgumentNames = Object::null_array();
500 compiler->GenerateStaticCall(deopt_id, 493 compiler->GenerateStaticCall(deopt_id,
501 token_pos, 494 token_pos,
502 target, 495 target,
503 kNumberOfArguments, 496 kNumberOfArguments,
504 kNoArgumentNames, 497 kNoArgumentNames,
505 locs); 498 locs);
506 if (branch == NULL) { 499 if (branch == NULL) {
507 if (kind == Token::kNE) { 500 if (kind == Token::kNE) {
508 Label false_label; 501 Label false_label;
509 __ CompareObject(EAX, Bool::True()); 502 __ CompareObject(EAX, Bool::True());
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 971 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
979 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptRelationalOp); 972 Label* deopt = compiler->AddDeoptStub(deopt_id(), kDeoptRelationalOp);
980 // Load class into EDI. Since this is a call, any register except 973 // Load class into EDI. Since this is a call, any register except
981 // the fixed input registers would be ok. 974 // the fixed input registers would be ok.
982 ASSERT((left != EDI) && (right != EDI)); 975 ASSERT((left != EDI) && (right != EDI));
983 const intptr_t kNumArguments = 2; 976 const intptr_t kNumArguments = 2;
984 LoadValueCid(compiler, EDI, left); 977 LoadValueCid(compiler, EDI, left);
985 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), 978 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
986 EDI, // Class id register. 979 EDI, // Class id register.
987 kNumArguments, 980 kNumArguments,
988 Array::Handle(), // No named arguments. 981 Object::null_array(), // No named arguments.
989 deopt, // Deoptimize target. 982 deopt, // Deoptimize target.
990 deopt_id(), 983 deopt_id(),
991 token_pos(), 984 token_pos(),
992 locs()); 985 locs());
993 return; 986 return;
994 } 987 }
995 const String& function_name = 988 const String& function_name =
996 String::ZoneHandle(Symbols::New(Token::Str(kind()))); 989 String::ZoneHandle(Symbols::New(Token::Str(kind())));
997 if (!compiler->is_optimizing()) { 990 if (!compiler->is_optimizing()) {
998 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 991 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
999 deopt_id(), 992 deopt_id(),
1000 token_pos()); 993 token_pos());
1001 } 994 }
1002 const intptr_t kNumArguments = 2; 995 const intptr_t kNumArguments = 2;
1003 const intptr_t kNumArgsChecked = 2; // Type-feedback. 996 const intptr_t kNumArgsChecked = 2; // Type-feedback.
1004 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw()); 997 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw());
1005 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { 998 if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
1006 ASSERT(!ic_data()->IsNull()); 999 ASSERT(!ic_data()->IsNull());
1007 if (ic_data()->NumberOfChecks() == 0) { 1000 if (ic_data()->NumberOfChecks() == 0) {
1008 // IC call for reoptimization populates original ICData. 1001 // IC call for reoptimization populates original ICData.
1009 relational_ic_data = ic_data()->raw(); 1002 relational_ic_data = ic_data()->raw();
1010 } else { 1003 } else {
1011 // Megamorphic call. 1004 // Megamorphic call.
1012 relational_ic_data = ic_data()->AsUnaryClassChecks(); 1005 relational_ic_data = ic_data()->AsUnaryClassChecks();
1013 } 1006 }
1014 } else { 1007 } else {
1008 const Array& arguments_descriptor =
1009 Array::Handle(ArgumentsDescriptor::New(kNumArguments,
1010 Object::null_array()));
1015 relational_ic_data = ICData::New(compiler->parsed_function().function(), 1011 relational_ic_data = ICData::New(compiler->parsed_function().function(),
1016 function_name, 1012 function_name,
1013 arguments_descriptor,
1017 deopt_id(), 1014 deopt_id(),
1018 kNumArgsChecked); 1015 kNumArgsChecked);
1019 } 1016 }
1020 compiler->GenerateInstanceCall(deopt_id(), 1017 compiler->GenerateInstanceCall(deopt_id(),
1021 token_pos(), 1018 token_pos(),
1022 kNumArguments, 1019 kNumArguments,
1023 Array::ZoneHandle(), // No optional arguments. 1020 Object::null_array(), // No optional args.
1024 locs(), 1021 locs(),
1025 relational_ic_data); 1022 relational_ic_data);
1026 } 1023 }
1027 1024
1028 1025
1029 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 1026 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
1030 BranchInstr* branch) { 1027 BranchInstr* branch) {
1031 if (operands_class_id() == kSmiCid) { 1028 if (operands_class_id() == kSmiCid) {
1032 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 1029 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
1033 return; 1030 return;
(...skipping 2690 matching lines...) Expand 10 before | Expand all | Expand 10 after
3724 ASSERT(instance_call()->HasICData()); 3721 ASSERT(instance_call()->HasICData());
3725 const ICData& ic_data = *instance_call()->ic_data(); 3722 const ICData& ic_data = *instance_call()->ic_data();
3726 ASSERT((ic_data.NumberOfChecks() == 1)); 3723 ASSERT((ic_data.NumberOfChecks() == 1));
3727 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); 3724 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
3728 3725
3729 const intptr_t kNumberOfArguments = 1; 3726 const intptr_t kNumberOfArguments = 1;
3730 compiler->GenerateStaticCall(deopt_id(), 3727 compiler->GenerateStaticCall(deopt_id(),
3731 instance_call()->token_pos(), 3728 instance_call()->token_pos(),
3732 target, 3729 target,
3733 kNumberOfArguments, 3730 kNumberOfArguments,
3734 Array::Handle(), // No argument names., 3731 Object::null_array(), // No argument names.,
3735 locs()); 3732 locs());
3736 __ Bind(&done); 3733 __ Bind(&done);
3737 } 3734 }
3738 3735
3739 3736
3740 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { 3737 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const {
3741 const intptr_t kNumInputs = 1; 3738 const intptr_t kNumInputs = 1;
3742 const intptr_t kNumTemps = 0; 3739 const intptr_t kNumTemps = 0;
3743 LocationSummary* result = new LocationSummary( 3740 LocationSummary* result = new LocationSummary(
3744 kNumInputs, kNumTemps, LocationSummary::kNoCall); 3741 kNumInputs, kNumTemps, LocationSummary::kNoCall);
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after
4644 __ subl(EDX, Immediate(1)); 4641 __ subl(EDX, Immediate(1));
4645 __ andl(EDX, Immediate( 4642 __ andl(EDX, Immediate(
4646 Smi::RawValue(true_value) - Smi::RawValue(false_value))); 4643 Smi::RawValue(true_value) - Smi::RawValue(false_value)));
4647 if (false_value != 0) { 4644 if (false_value != 0) {
4648 __ addl(EDX, Immediate(Smi::RawValue(false_value))); 4645 __ addl(EDX, Immediate(Smi::RawValue(false_value)));
4649 } 4646 }
4650 } 4647 }
4651 } 4648 }
4652 4649
4653 4650
4651 LocationSummary* ClosureCallInstr::MakeLocationSummary() const {
4652 const intptr_t kNumInputs = 0;
4653 const intptr_t kNumTemps = 1;
4654 LocationSummary* result =
4655 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
4656 result->set_out(Location::RegisterLocation(EAX));
4657 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor.
4658 return result;
4659 }
4660
4661
4654 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4662 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4655 // The arguments to the stub include the closure, as does the arguments 4663 // The arguments to the stub include the closure, as does the arguments
4656 // descriptor. 4664 // descriptor.
4657 Register temp_reg = locs()->temp(0).reg(); 4665 Register temp_reg = locs()->temp(0).reg();
4658 int argument_count = ArgumentCount(); 4666 int argument_count = ArgumentCount();
4659 const Array& arguments_descriptor = 4667 const Array& arguments_descriptor =
4660 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count, 4668 Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
4661 argument_names())); 4669 argument_names()));
4662 __ LoadObject(temp_reg, arguments_descriptor); 4670 __ LoadObject(temp_reg, arguments_descriptor);
4671 ASSERT(temp_reg == EDX);
4663 compiler->GenerateDartCall(deopt_id(), 4672 compiler->GenerateDartCall(deopt_id(),
4664 token_pos(), 4673 token_pos(),
4665 &StubCode::CallClosureFunctionLabel(), 4674 &StubCode::CallClosureFunctionLabel(),
4666 PcDescriptors::kClosureCall, 4675 PcDescriptors::kClosureCall,
4667 locs()); 4676 locs());
4668 __ Drop(argument_count); 4677 __ Drop(argument_count);
4669 } 4678 }
4670 4679
4671 4680
4672 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const { 4681 LocationSummary* BooleanNegateInstr::MakeLocationSummary() const {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
4767 PcDescriptors::kOther, 4776 PcDescriptors::kOther,
4768 locs()); 4777 locs());
4769 __ Drop(2); // Discard type arguments and receiver. 4778 __ Drop(2); // Discard type arguments and receiver.
4770 } 4779 }
4771 4780
4772 } // namespace dart 4781 } // namespace dart
4773 4782
4774 #undef __ 4783 #undef __
4775 4784
4776 #endif // defined TARGET_ARCH_IA32 4785 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698