OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |