OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
84 } | 84 } |
85 if (FLAG_trace_functions) { | 85 if (FLAG_trace_functions) { |
86 const Function& function = | 86 const Function& function = |
87 Function::ZoneHandle(compiler->parsed_function().function().raw()); | 87 Function::ZoneHandle(compiler->parsed_function().function().raw()); |
88 __ LoadObject(temp, function); | 88 __ LoadObject(temp, function); |
89 __ pushl(result); // Preserve result. | 89 __ pushl(result); // Preserve result. |
90 __ pushl(temp); | 90 __ pushl(temp); |
91 compiler->GenerateCallRuntime(Isolate::kNoDeoptId, | 91 compiler->GenerateCallRuntime(Isolate::kNoDeoptId, |
92 0, | 92 0, |
93 CatchClauseNode::kInvalidTryIndex, | 93 CatchClauseNode::kInvalidTryIndex, |
94 kTraceFunctionExitRuntimeEntry); | 94 kTraceFunctionExitRuntimeEntry, |
95 locs()->stack_bitmap()); | |
Vyacheslav Egorov (Google)
2012/08/13 12:54:46
ReturnInstr is marked as NoCall. This code is susp
Kevin Millikin (Google)
2012/08/13 15:10:37
I know. We really don't want it to be a call beca
| |
95 __ popl(temp); // Remove argument. | 96 __ popl(temp); // Remove argument. |
96 __ popl(result); // Restore result. | 97 __ popl(result); // Restore result. |
97 } | 98 } |
98 #if defined(DEBUG) | 99 #if defined(DEBUG) |
99 // TODO(srdjan): Fix for functions with finally clause. | 100 // TODO(srdjan): Fix for functions with finally clause. |
100 // A finally clause may leave a previously pushed return value if it | 101 // A finally clause may leave a previously pushed return value if it |
101 // has its own return instruction. Method that have finally are currently | 102 // has its own return instruction. Method that have finally are currently |
102 // not optimized. | 103 // not optimized. |
103 if (!compiler->HasFinally()) { | 104 if (!compiler->HasFinally()) { |
104 Label done; | 105 Label done; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
209 Label done; | 210 Label done; |
210 __ CompareObject(obj, compiler->bool_true()); | 211 __ CompareObject(obj, compiler->bool_true()); |
211 __ j(EQUAL, &done, Assembler::kNearJump); | 212 __ j(EQUAL, &done, Assembler::kNearJump); |
212 __ CompareObject(obj, compiler->bool_false()); | 213 __ CompareObject(obj, compiler->bool_false()); |
213 __ j(EQUAL, &done, Assembler::kNearJump); | 214 __ j(EQUAL, &done, Assembler::kNearJump); |
214 | 215 |
215 __ pushl(obj); // Push the source object. | 216 __ pushl(obj); // Push the source object. |
216 compiler->GenerateCallRuntime(deopt_id(), | 217 compiler->GenerateCallRuntime(deopt_id(), |
217 token_pos(), | 218 token_pos(), |
218 try_index(), | 219 try_index(), |
219 kConditionTypeErrorRuntimeEntry); | 220 kConditionTypeErrorRuntimeEntry, |
221 locs()->stack_bitmap()); | |
220 // We should never return here. | 222 // We should never return here. |
221 __ int3(); | 223 __ int3(); |
222 | 224 |
223 __ Bind(&done); | 225 __ Bind(&done); |
224 ASSERT(obj == result); | 226 ASSERT(obj == result); |
225 } | 227 } |
226 | 228 |
227 | 229 |
228 static Condition TokenKindToSmiCondition(Token::Kind kind) { | 230 static Condition TokenKindToSmiCondition(Token::Kind kind) { |
229 switch (kind) { | 231 switch (kind) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
284 const int kNumberOfArguments = 2; | 286 const int kNumberOfArguments = 2; |
285 const Array& kNoArgumentNames = Array::Handle(); | 287 const Array& kNoArgumentNames = Array::Handle(); |
286 const int kNumArgumentsChecked = 2; | 288 const int kNumArgumentsChecked = 2; |
287 | 289 |
288 compiler->GenerateInstanceCall(comp->deopt_id(), | 290 compiler->GenerateInstanceCall(comp->deopt_id(), |
289 comp->token_pos(), | 291 comp->token_pos(), |
290 comp->try_index(), | 292 comp->try_index(), |
291 operator_name, | 293 operator_name, |
292 kNumberOfArguments, | 294 kNumberOfArguments, |
293 kNoArgumentNames, | 295 kNoArgumentNames, |
294 kNumArgumentsChecked); | 296 kNumArgumentsChecked, |
297 comp->locs()->stack_bitmap()); | |
295 ASSERT(comp->locs()->out().reg() == EAX); | 298 ASSERT(comp->locs()->out().reg() == EAX); |
296 if (comp->kind() == Token::kNE) { | 299 if (comp->kind() == Token::kNE) { |
297 Label done, false_label; | 300 Label done, false_label; |
298 __ CompareObject(EAX, compiler->bool_true()); | 301 __ CompareObject(EAX, compiler->bool_true()); |
299 __ j(EQUAL, &false_label, Assembler::kNearJump); | 302 __ j(EQUAL, &false_label, Assembler::kNearJump); |
300 __ LoadObject(EAX, compiler->bool_true()); | 303 __ LoadObject(EAX, compiler->bool_true()); |
301 __ jmp(&done, Assembler::kNearJump); | 304 __ jmp(&done, Assembler::kNearJump); |
302 __ Bind(&false_label); | 305 __ Bind(&false_label); |
303 __ LoadObject(EAX, compiler->bool_false()); | 306 __ LoadObject(EAX, compiler->bool_false()); |
304 __ Bind(&done); | 307 __ Bind(&done); |
305 } | 308 } |
306 } | 309 } |
307 | 310 |
308 | 311 |
309 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, | 312 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, |
310 const ICData& orig_ic_data, | 313 const ICData& orig_ic_data, |
311 const LocationSummary& locs, | 314 const LocationSummary& locs, |
312 BranchInstr* branch, | 315 BranchInstr* branch, |
313 Token::Kind kind, | 316 Token::Kind kind, |
314 intptr_t deopt_id, | 317 intptr_t deopt_id, |
315 intptr_t token_pos, | 318 intptr_t token_pos, |
316 intptr_t try_index) { | 319 intptr_t try_index, |
320 BitmapBuilder* stack_bitmap) { | |
317 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); | 321 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); |
318 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); | 322 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); |
319 ASSERT(ic_data.NumberOfChecks() > 0); | 323 ASSERT(ic_data.NumberOfChecks() > 0); |
320 ASSERT(ic_data.num_args_tested() == 1); | 324 ASSERT(ic_data.num_args_tested() == 1); |
321 Label* deopt = compiler->AddDeoptStub(deopt_id, try_index, kDeoptEquality); | 325 Label* deopt = compiler->AddDeoptStub(deopt_id, try_index, kDeoptEquality); |
322 Register left = locs.in(0).reg(); | 326 Register left = locs.in(0).reg(); |
323 Register right = locs.in(1).reg(); | 327 Register right = locs.in(1).reg(); |
324 __ testl(left, Immediate(kSmiTagMask)); | 328 __ testl(left, Immediate(kSmiTagMask)); |
325 Register temp = locs.temp(0).reg(); | 329 Register temp = locs.temp(0).reg(); |
326 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) { | 330 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
361 __ LoadObject(result, compiler->bool_true()); | 365 __ LoadObject(result, compiler->bool_true()); |
362 } | 366 } |
363 } else { | 367 } else { |
364 const int kNumberOfArguments = 2; | 368 const int kNumberOfArguments = 2; |
365 const Array& kNoArgumentNames = Array::Handle(); | 369 const Array& kNoArgumentNames = Array::Handle(); |
366 compiler->GenerateStaticCall(deopt_id, | 370 compiler->GenerateStaticCall(deopt_id, |
367 token_pos, | 371 token_pos, |
368 try_index, | 372 try_index, |
369 target, | 373 target, |
370 kNumberOfArguments, | 374 kNumberOfArguments, |
371 kNoArgumentNames); | 375 kNoArgumentNames, |
376 stack_bitmap); | |
372 if (branch == NULL) { | 377 if (branch == NULL) { |
373 if (kind == Token::kNE) { | 378 if (kind == Token::kNE) { |
374 Label false_label; | 379 Label false_label; |
375 __ CompareObject(EAX, compiler->bool_true()); | 380 __ CompareObject(EAX, compiler->bool_true()); |
376 __ j(EQUAL, &false_label, Assembler::kNearJump); | 381 __ j(EQUAL, &false_label, Assembler::kNearJump); |
377 __ LoadObject(EAX, compiler->bool_true()); | 382 __ LoadObject(EAX, compiler->bool_true()); |
378 __ jmp(&done); | 383 __ jmp(&done); |
379 __ Bind(&false_label); | 384 __ Bind(&false_label); |
380 __ LoadObject(EAX, compiler->bool_false()); | 385 __ LoadObject(EAX, compiler->bool_false()); |
381 __ jmp(&done); | 386 __ jmp(&done); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
426 __ LoadObject(result, compiler->bool_false()); | 431 __ LoadObject(result, compiler->bool_false()); |
427 __ jmp(&done); | 432 __ jmp(&done); |
428 __ Bind(&load_true); | 433 __ Bind(&load_true); |
429 __ LoadObject(result, compiler->bool_true()); | 434 __ LoadObject(result, compiler->bool_true()); |
430 } | 435 } |
431 __ jmp(&done); | 436 __ jmp(&done); |
432 __ Bind(&non_null_compare); // Receiver is not null. | 437 __ Bind(&non_null_compare); // Receiver is not null. |
433 __ pushl(left); | 438 __ pushl(left); |
434 __ pushl(right); | 439 __ pushl(right); |
435 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, | 440 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, |
436 deopt_id, token_pos, try_index); | 441 deopt_id, token_pos, try_index, |
442 locs.stack_bitmap()); | |
437 __ Bind(&done); | 443 __ Bind(&done); |
438 } | 444 } |
439 | 445 |
440 | 446 |
441 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, | 447 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, |
442 const LocationSummary& locs, | 448 const LocationSummary& locs, |
443 Token::Kind kind, | 449 Token::Kind kind, |
444 BranchInstr* branch, | 450 BranchInstr* branch, |
445 intptr_t deopt_id, | 451 intptr_t deopt_id, |
446 intptr_t token_pos, | 452 intptr_t token_pos, |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
587 __ LoadClassId(EDI, EAX); | 593 __ LoadClassId(EDI, EAX); |
588 __ Bind(&done); | 594 __ Bind(&done); |
589 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), | 595 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), |
590 EDI, // Class id register. | 596 EDI, // Class id register. |
591 kNumArguments, | 597 kNumArguments, |
592 Array::Handle(), // No named arguments. | 598 Array::Handle(), // No named arguments. |
593 deopt, // Deoptimize target. | 599 deopt, // Deoptimize target. |
594 NULL, // Fallthrough when done. | 600 NULL, // Fallthrough when done. |
595 deopt_id(), | 601 deopt_id(), |
596 token_pos(), | 602 token_pos(), |
597 try_index()); | 603 try_index(), |
604 locs()->stack_bitmap()); | |
598 return; | 605 return; |
599 } | 606 } |
600 const String& function_name = | 607 const String& function_name = |
601 String::ZoneHandle(Symbols::New(Token::Str(kind()))); | 608 String::ZoneHandle(Symbols::New(Token::Str(kind()))); |
602 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 609 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
603 deopt_id(), | 610 deopt_id(), |
604 token_pos(), | 611 token_pos(), |
605 try_index()); | 612 try_index()); |
606 const intptr_t kNumArguments = 2; | 613 const intptr_t kNumArguments = 2; |
607 const intptr_t kNumArgsChecked = 2; // Type-feedback. | 614 const intptr_t kNumArgsChecked = 2; // Type-feedback. |
608 compiler->GenerateInstanceCall(deopt_id(), | 615 compiler->GenerateInstanceCall(deopt_id(), |
609 token_pos(), | 616 token_pos(), |
610 try_index(), | 617 try_index(), |
611 function_name, | 618 function_name, |
612 kNumArguments, | 619 kNumArguments, |
613 Array::ZoneHandle(), // No optional arguments. | 620 Array::ZoneHandle(), // No optional arguments. |
614 kNumArgsChecked); | 621 kNumArgsChecked, |
622 locs()->stack_bitmap()); | |
615 ASSERT(locs()->out().reg() == EAX); | 623 ASSERT(locs()->out().reg() == EAX); |
616 } | 624 } |
617 | 625 |
618 | 626 |
619 LocationSummary* NativeCallComp::MakeLocationSummary() const { | 627 LocationSummary* NativeCallComp::MakeLocationSummary() const { |
620 const intptr_t kNumInputs = 0; | 628 const intptr_t kNumInputs = 0; |
621 const intptr_t kNumTemps = 3; | 629 const intptr_t kNumTemps = 3; |
622 LocationSummary* locs = | 630 LocationSummary* locs = |
623 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 631 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
624 locs->set_temp(0, Location::RegisterLocation(EAX)); | 632 locs->set_temp(0, Location::RegisterLocation(EAX)); |
(...skipping 21 matching lines...) Expand all Loading... | |
646 __ leal(EAX, Address(EBP, (1 + arg_count) * kWordSize)); | 654 __ leal(EAX, Address(EBP, (1 + arg_count) * kWordSize)); |
647 } else { | 655 } else { |
648 __ leal(EAX, | 656 __ leal(EAX, |
649 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); | 657 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); |
650 } | 658 } |
651 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); | 659 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); |
652 __ movl(EDX, Immediate(arg_count)); | 660 __ movl(EDX, Immediate(arg_count)); |
653 compiler->GenerateCall(token_pos(), | 661 compiler->GenerateCall(token_pos(), |
654 try_index(), | 662 try_index(), |
655 &StubCode::CallNativeCFunctionLabel(), | 663 &StubCode::CallNativeCFunctionLabel(), |
656 PcDescriptors::kOther); | 664 PcDescriptors::kOther, |
665 locs()->stack_bitmap()); | |
657 __ popl(result); | 666 __ popl(result); |
658 } | 667 } |
659 | 668 |
660 | 669 |
661 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { | 670 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { |
662 const intptr_t kNumInputs = 2; | 671 const intptr_t kNumInputs = 2; |
663 if ((receiver_type() == kGrowableObjectArrayCid) || | 672 if ((receiver_type() == kGrowableObjectArrayCid) || |
664 (receiver_type() == kArrayCid) || | 673 (receiver_type() == kArrayCid) || |
665 (receiver_type() == kImmutableArrayCid)) { | 674 (receiver_type() == kImmutableArrayCid)) { |
666 const intptr_t kNumTemps = 1; | 675 const intptr_t kNumTemps = 1; |
667 LocationSummary* locs = | 676 LocationSummary* locs = |
668 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 677 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
669 locs->set_in(0, Location::RequiresRegister()); | 678 locs->set_in(0, Location::RequiresRegister()); |
670 locs->set_in(1, Location::RequiresRegister()); | 679 locs->set_in(1, Location::RequiresRegister()); |
671 locs->set_temp(0, Location::RequiresRegister()); | 680 locs->set_temp(0, Location::RequiresRegister()); |
672 locs->set_out(Location::RequiresRegister()); | 681 locs->set_out(Location::RequiresRegister()); |
673 return locs; | 682 return locs; |
674 } else { | 683 } else { |
675 ASSERT(receiver_type() == kIllegalCid); | 684 ASSERT(receiver_type() == kIllegalCid); |
676 return MakeCallSummary(); | 685 return MakeCallSummary(); |
677 } | 686 } |
678 } | 687 } |
679 | 688 |
680 | 689 |
681 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, | 690 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, |
682 LoadIndexedComp* comp) { | 691 LoadIndexedComp* comp) { |
683 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), | 692 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), |
684 comp->try_index(), | 693 comp->try_index(), |
685 kDeoptLoadIndexedPolymorphic); | 694 kDeoptLoadIndexedPolymorphic); |
686 ASSERT(comp->ic_data()->NumberOfChecks() > 0); | 695 ASSERT(comp->ic_data()->NumberOfChecks() > 0); |
687 ASSERT(comp->HasICData()); | 696 ASSERT(comp->HasICData()); |
688 const ICData& ic_data = *comp->ic_data(); | 697 const ICData& ic_data = *comp->ic_data(); |
689 ASSERT(ic_data.num_args_tested() == 1); | 698 ASSERT(ic_data.num_args_tested() == 1); |
690 // No indexed access on Smi. | 699 // No indexed access on Smi. |
691 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); | 700 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); |
692 // Load receiver into EAX. | 701 // Load receiver into EAX. |
693 const intptr_t kNumArguments = 2; | 702 const intptr_t kNumArguments = 2; |
694 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); | 703 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); |
695 __ testl(EAX, Immediate(kSmiTagMask)); | 704 __ testl(EAX, Immediate(kSmiTagMask)); |
696 __ j(ZERO, deopt); | 705 __ j(ZERO, deopt); |
697 __ LoadClassId(EDI, EAX); | 706 __ LoadClassId(EDI, EAX); |
698 compiler->EmitTestAndCall(ic_data, | 707 compiler->EmitTestAndCall(ic_data, |
699 EDI, // Class id register. | 708 EDI, // Class id register. |
700 kNumArguments, | 709 kNumArguments, |
701 Array::Handle(), // No named arguments. | 710 Array::Handle(), // No named arguments. |
702 deopt, // Deoptimize target. | 711 deopt, // Deoptimize target. |
703 NULL, // Fallthrough when done. | 712 NULL, // Fallthrough when done. |
704 comp->deopt_id(), | 713 comp->deopt_id(), |
705 comp->token_pos(), | 714 comp->token_pos(), |
706 comp->try_index()); | 715 comp->try_index(), |
716 comp->locs()->stack_bitmap()); | |
707 } | 717 } |
708 | 718 |
709 | 719 |
710 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 720 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
711 if (receiver_type() == kIllegalCid) { | 721 if (receiver_type() == kIllegalCid) { |
712 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | 722 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
713 EmitLoadIndexedPolymorphic(compiler, this); | 723 EmitLoadIndexedPolymorphic(compiler, this); |
714 } else { | 724 } else { |
715 compiler->EmitLoadIndexedGeneric(this); | 725 compiler->EmitLoadIndexedGeneric(this); |
716 } | 726 } |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
802 comp->try_index()); | 812 comp->try_index()); |
803 | 813 |
804 const intptr_t kNumArguments = 3; | 814 const intptr_t kNumArguments = 3; |
805 const intptr_t kNumArgsChecked = 1; // Type-feedback. | 815 const intptr_t kNumArgsChecked = 1; // Type-feedback. |
806 compiler->GenerateInstanceCall(comp->deopt_id(), | 816 compiler->GenerateInstanceCall(comp->deopt_id(), |
807 comp->token_pos(), | 817 comp->token_pos(), |
808 comp->try_index(), | 818 comp->try_index(), |
809 function_name, | 819 function_name, |
810 kNumArguments, | 820 kNumArguments, |
811 Array::ZoneHandle(), // No named arguments. | 821 Array::ZoneHandle(), // No named arguments. |
812 kNumArgsChecked); | 822 kNumArgsChecked, |
823 comp->locs()->stack_bitmap()); | |
813 } | 824 } |
814 | 825 |
815 | 826 |
816 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler, | 827 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler, |
817 StoreIndexedComp* comp) { | 828 StoreIndexedComp* comp) { |
818 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), | 829 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), |
819 comp->try_index(), | 830 comp->try_index(), |
820 kDeoptStoreIndexedPolymorphic); | 831 kDeoptStoreIndexedPolymorphic); |
821 ASSERT(comp->ic_data()->NumberOfChecks() > 0); | 832 ASSERT(comp->ic_data()->NumberOfChecks() > 0); |
822 ASSERT(comp->HasICData()); | 833 ASSERT(comp->HasICData()); |
823 const ICData& ic_data = *comp->ic_data(); | 834 const ICData& ic_data = *comp->ic_data(); |
824 ASSERT(ic_data.num_args_tested() == 1); | 835 ASSERT(ic_data.num_args_tested() == 1); |
825 // No indexed access on Smi. | 836 // No indexed access on Smi. |
826 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); | 837 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); |
827 // Load receiver into EAX. | 838 // Load receiver into EAX. |
828 const intptr_t kNumArguments = 3; | 839 const intptr_t kNumArguments = 3; |
829 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); | 840 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); |
830 __ testl(EAX, Immediate(kSmiTagMask)); | 841 __ testl(EAX, Immediate(kSmiTagMask)); |
831 __ j(ZERO, deopt); | 842 __ j(ZERO, deopt); |
832 __ LoadClassId(EDI, EAX); | 843 __ LoadClassId(EDI, EAX); |
833 compiler->EmitTestAndCall(ic_data, | 844 compiler->EmitTestAndCall(ic_data, |
834 EDI, // Class id register. | 845 EDI, // Class id register. |
835 kNumArguments, | 846 kNumArguments, |
836 Array::Handle(), // No named arguments. | 847 Array::Handle(), // No named arguments. |
837 deopt, // Deoptimize target. | 848 deopt, // Deoptimize target. |
838 NULL, // Fallthrough when done. | 849 NULL, // Fallthrough when done. |
839 comp->deopt_id(), | 850 comp->deopt_id(), |
840 comp->token_pos(), | 851 comp->token_pos(), |
841 comp->try_index()); | 852 comp->try_index(), |
853 comp->locs()->stack_bitmap()); | |
842 } | 854 } |
843 | 855 |
844 | 856 |
845 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 857 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
846 if (receiver_type() == kIllegalCid) { | 858 if (receiver_type() == kIllegalCid) { |
847 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | 859 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
848 EmitStoreIndexedPolymorphic(compiler, this); | 860 EmitStoreIndexedPolymorphic(compiler, this); |
849 } else { | 861 } else { |
850 EmitStoreIndexedGeneric(compiler, this); | 862 EmitStoreIndexedGeneric(compiler, this); |
851 } | 863 } |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
964 | 976 |
965 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 977 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
966 ASSERT(locs()->in(0).reg() == EAX); // Value. | 978 ASSERT(locs()->in(0).reg() == EAX); // Value. |
967 ASSERT(locs()->in(1).reg() == ECX); // Instantiator. | 979 ASSERT(locs()->in(1).reg() == ECX); // Instantiator. |
968 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. | 980 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. |
969 | 981 |
970 compiler->GenerateInstanceOf(deopt_id(), | 982 compiler->GenerateInstanceOf(deopt_id(), |
971 token_pos(), | 983 token_pos(), |
972 try_index(), | 984 try_index(), |
973 type(), | 985 type(), |
974 negate_result()); | 986 negate_result(), |
987 locs()->stack_bitmap()); | |
975 ASSERT(locs()->out().reg() == EAX); | 988 ASSERT(locs()->out().reg() == EAX); |
976 } | 989 } |
977 | 990 |
978 | 991 |
979 LocationSummary* CreateArrayComp::MakeLocationSummary() const { | 992 LocationSummary* CreateArrayComp::MakeLocationSummary() const { |
980 const intptr_t kNumInputs = 1; | 993 const intptr_t kNumInputs = 1; |
981 const intptr_t kNumTemps = 0; | 994 const intptr_t kNumTemps = 0; |
982 LocationSummary* locs = | 995 LocationSummary* locs = |
983 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 996 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
984 locs->set_in(0, Location::RegisterLocation(ECX)); | 997 locs->set_in(0, Location::RegisterLocation(ECX)); |
985 locs->set_out(Location::RegisterLocation(EAX)); | 998 locs->set_out(Location::RegisterLocation(EAX)); |
986 return locs; | 999 return locs; |
987 } | 1000 } |
988 | 1001 |
989 | 1002 |
990 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1003 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
991 // Allocate the array. EDX = length, ECX = element type. | 1004 // Allocate the array. EDX = length, ECX = element type. |
992 ASSERT(locs()->in(0).reg() == ECX); | 1005 ASSERT(locs()->in(0).reg() == ECX); |
993 __ movl(EDX, Immediate(Smi::RawValue(ElementCount()))); | 1006 __ movl(EDX, Immediate(Smi::RawValue(ElementCount()))); |
994 compiler->GenerateCall(token_pos(), | 1007 compiler->GenerateCall(token_pos(), |
995 try_index(), | 1008 try_index(), |
996 &StubCode::AllocateArrayLabel(), | 1009 &StubCode::AllocateArrayLabel(), |
997 PcDescriptors::kOther); | 1010 PcDescriptors::kOther, |
1011 locs()->stack_bitmap()); | |
998 ASSERT(locs()->out().reg() == EAX); | 1012 ASSERT(locs()->out().reg() == EAX); |
999 | 1013 |
1000 // Pop the element values from the stack into the array. | 1014 // Pop the element values from the stack into the array. |
1001 __ leal(EDX, FieldAddress(EAX, Array::data_offset())); | 1015 __ leal(EDX, FieldAddress(EAX, Array::data_offset())); |
1002 for (int i = ElementCount() - 1; i >= 0; --i) { | 1016 for (int i = ElementCount() - 1; i >= 0; --i) { |
1003 ASSERT(ElementAt(i)->IsUse()); | 1017 ASSERT(ElementAt(i)->IsUse()); |
1004 __ popl(Address(EDX, i * kWordSize)); | 1018 __ popl(Address(EDX, i * kWordSize)); |
1005 } | 1019 } |
1006 } | 1020 } |
1007 | 1021 |
(...skipping 19 matching lines...) Expand all Loading... | |
1027 Register result = locs()->out().reg(); | 1041 Register result = locs()->out().reg(); |
1028 | 1042 |
1029 // Push the result place holder initialized to NULL. | 1043 // Push the result place holder initialized to NULL. |
1030 __ PushObject(Object::ZoneHandle()); | 1044 __ PushObject(Object::ZoneHandle()); |
1031 __ PushObject(cls); | 1045 __ PushObject(cls); |
1032 __ pushl(type_arguments); | 1046 __ pushl(type_arguments); |
1033 __ pushl(instantiator_type_arguments); | 1047 __ pushl(instantiator_type_arguments); |
1034 compiler->GenerateCallRuntime(deopt_id(), | 1048 compiler->GenerateCallRuntime(deopt_id(), |
1035 token_pos(), | 1049 token_pos(), |
1036 try_index(), | 1050 try_index(), |
1037 kAllocateObjectWithBoundsCheckRuntimeEntry); | 1051 kAllocateObjectWithBoundsCheckRuntimeEntry, |
1052 locs()->stack_bitmap()); | |
1038 // Pop instantiator type arguments, type arguments, and class. | 1053 // Pop instantiator type arguments, type arguments, and class. |
1039 // source location. | 1054 // source location. |
1040 __ Drop(3); | 1055 __ Drop(3); |
1041 __ popl(result); // Pop new instance. | 1056 __ popl(result); // Pop new instance. |
1042 } | 1057 } |
1043 | 1058 |
1044 | 1059 |
1045 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { | 1060 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { |
1046 return LocationSummary::Make(1, | 1061 return LocationSummary::Make(1, |
1047 Location::RequiresRegister(), | 1062 Location::RequiresRegister(), |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1115 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); | 1130 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); |
1116 __ Bind(&type_arguments_uninstantiated); | 1131 __ Bind(&type_arguments_uninstantiated); |
1117 } | 1132 } |
1118 // A runtime call to instantiate the type arguments is required. | 1133 // A runtime call to instantiate the type arguments is required. |
1119 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 1134 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
1120 __ PushObject(type_arguments()); | 1135 __ PushObject(type_arguments()); |
1121 __ pushl(instantiator_reg); // Push instantiator type arguments. | 1136 __ pushl(instantiator_reg); // Push instantiator type arguments. |
1122 compiler->GenerateCallRuntime(deopt_id(), | 1137 compiler->GenerateCallRuntime(deopt_id(), |
1123 token_pos(), | 1138 token_pos(), |
1124 try_index(), | 1139 try_index(), |
1125 kInstantiateTypeArgumentsRuntimeEntry); | 1140 kInstantiateTypeArgumentsRuntimeEntry, |
1141 locs()->stack_bitmap()); | |
1126 __ Drop(2); // Drop instantiator and uninstantiated type arguments. | 1142 __ Drop(2); // Drop instantiator and uninstantiated type arguments. |
1127 __ popl(result_reg); // Pop instantiated type arguments. | 1143 __ popl(result_reg); // Pop instantiated type arguments. |
1128 __ Bind(&type_arguments_instantiated); | 1144 __ Bind(&type_arguments_instantiated); |
1129 ASSERT(instantiator_reg == result_reg); | 1145 ASSERT(instantiator_reg == result_reg); |
1130 // 'result_reg': Instantiated type arguments. | 1146 // 'result_reg': Instantiated type arguments. |
1131 } | 1147 } |
1132 | 1148 |
1133 | 1149 |
1134 LocationSummary* | 1150 LocationSummary* |
1135 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const { | 1151 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1271 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1287 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1272 ASSERT(locs()->temp(0).reg() == EDX); | 1288 ASSERT(locs()->temp(0).reg() == EDX); |
1273 ASSERT(locs()->out().reg() == EAX); | 1289 ASSERT(locs()->out().reg() == EAX); |
1274 | 1290 |
1275 __ movl(EDX, Immediate(num_context_variables())); | 1291 __ movl(EDX, Immediate(num_context_variables())); |
1276 const ExternalLabel label("alloc_context", | 1292 const ExternalLabel label("alloc_context", |
1277 StubCode::AllocateContextEntryPoint()); | 1293 StubCode::AllocateContextEntryPoint()); |
1278 compiler->GenerateCall(token_pos(), | 1294 compiler->GenerateCall(token_pos(), |
1279 try_index(), | 1295 try_index(), |
1280 &label, | 1296 &label, |
1281 PcDescriptors::kOther); | 1297 PcDescriptors::kOther, |
1298 locs()->stack_bitmap()); | |
1282 } | 1299 } |
1283 | 1300 |
1284 | 1301 |
1285 LocationSummary* CloneContextComp::MakeLocationSummary() const { | 1302 LocationSummary* CloneContextComp::MakeLocationSummary() const { |
1286 const intptr_t kNumInputs = 1; | 1303 const intptr_t kNumInputs = 1; |
1287 const intptr_t kNumTemps = 0; | 1304 const intptr_t kNumTemps = 0; |
1288 LocationSummary* locs = | 1305 LocationSummary* locs = |
1289 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 1306 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
1290 locs->set_in(0, Location::RegisterLocation(EAX)); | 1307 locs->set_in(0, Location::RegisterLocation(EAX)); |
1291 locs->set_out(Location::RegisterLocation(EAX)); | 1308 locs->set_out(Location::RegisterLocation(EAX)); |
1292 return locs; | 1309 return locs; |
1293 } | 1310 } |
1294 | 1311 |
1295 | 1312 |
1296 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1313 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1297 Register context_value = locs()->in(0).reg(); | 1314 Register context_value = locs()->in(0).reg(); |
1298 Register result = locs()->out().reg(); | 1315 Register result = locs()->out().reg(); |
1299 | 1316 |
1300 __ PushObject(Object::ZoneHandle()); // Make room for the result. | 1317 __ PushObject(Object::ZoneHandle()); // Make room for the result. |
1301 __ pushl(context_value); | 1318 __ pushl(context_value); |
1302 compiler->GenerateCallRuntime(deopt_id(), | 1319 compiler->GenerateCallRuntime(deopt_id(), |
1303 token_pos(), | 1320 token_pos(), |
1304 try_index(), | 1321 try_index(), |
1305 kCloneContextRuntimeEntry); | 1322 kCloneContextRuntimeEntry, |
1323 locs()->stack_bitmap()); | |
1306 __ popl(result); // Remove argument. | 1324 __ popl(result); // Remove argument. |
1307 __ popl(result); // Get result (cloned context). | 1325 __ popl(result); // Get result (cloned context). |
1308 } | 1326 } |
1309 | 1327 |
1310 | 1328 |
1311 LocationSummary* CatchEntryComp::MakeLocationSummary() const { | 1329 LocationSummary* CatchEntryComp::MakeLocationSummary() const { |
1312 return LocationSummary::Make(0, | 1330 return LocationSummary::Make(0, |
1313 Location::NoLocation(), | 1331 Location::NoLocation(), |
1314 LocationSummary::kNoCall); | 1332 LocationSummary::kNoCall); |
1315 } | 1333 } |
(...skipping 30 matching lines...) Expand all Loading... | |
1346 | 1364 |
1347 | 1365 |
1348 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1366 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1349 __ cmpl(ESP, | 1367 __ cmpl(ESP, |
1350 Address::Absolute(Isolate::Current()->stack_limit_address())); | 1368 Address::Absolute(Isolate::Current()->stack_limit_address())); |
1351 Label no_stack_overflow; | 1369 Label no_stack_overflow; |
1352 __ j(ABOVE, &no_stack_overflow); | 1370 __ j(ABOVE, &no_stack_overflow); |
1353 compiler->GenerateCallRuntime(deopt_id(), | 1371 compiler->GenerateCallRuntime(deopt_id(), |
1354 token_pos(), | 1372 token_pos(), |
1355 try_index(), | 1373 try_index(), |
1356 kStackOverflowRuntimeEntry); | 1374 kStackOverflowRuntimeEntry, |
1375 locs()->stack_bitmap()); | |
1357 __ Bind(&no_stack_overflow); | 1376 __ Bind(&no_stack_overflow); |
1358 } | 1377 } |
1359 | 1378 |
1360 | 1379 |
1361 LocationSummary* BinaryOpComp::MakeLocationSummary() const { | 1380 LocationSummary* BinaryOpComp::MakeLocationSummary() const { |
1362 const intptr_t kNumInputs = 2; | 1381 const intptr_t kNumInputs = 2; |
1363 | 1382 |
1364 // Double operation are handled in DoubleBinaryOpComp. | 1383 // Double operation are handled in DoubleBinaryOpComp. |
1365 ASSERT(operands_type() != kDoubleOperands); | 1384 ASSERT(operands_type() != kDoubleOperands); |
1366 | 1385 |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1532 __ shll(left, right_temp); | 1551 __ shll(left, right_temp); |
1533 __ jmp(&done); | 1552 __ jmp(&done); |
1534 { | 1553 { |
1535 __ Bind(&call_method); | 1554 __ Bind(&call_method); |
1536 Function& target = Function::ZoneHandle( | 1555 Function& target = Function::ZoneHandle( |
1537 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid)); | 1556 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid)); |
1538 ASSERT(!target.IsNull()); | 1557 ASSERT(!target.IsNull()); |
1539 const intptr_t kArgumentCount = 2; | 1558 const intptr_t kArgumentCount = 2; |
1540 __ pushl(temp); | 1559 __ pushl(temp); |
1541 __ pushl(right); | 1560 __ pushl(right); |
1542 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), | 1561 compiler->GenerateStaticCall( |
1543 comp->instance_call()->token_pos(), | 1562 comp->instance_call()->deopt_id(), |
1544 comp->instance_call()->try_index(), | 1563 comp->instance_call()->token_pos(), |
1545 target, | 1564 comp->instance_call()->try_index(), |
1546 kArgumentCount, | 1565 target, |
1547 Array::Handle()); // No argument names. | 1566 kArgumentCount, |
1567 Array::Handle(), // No argument names. | |
1568 comp->locs()->stack_bitmap()); | |
1548 ASSERT(result == EAX); | 1569 ASSERT(result == EAX); |
1549 } | 1570 } |
1550 __ Bind(&done); | 1571 __ Bind(&done); |
1551 break; | 1572 break; |
1552 } | 1573 } |
1553 case Token::kDIV: { | 1574 case Token::kDIV: { |
1554 // Dispatches to 'Double./'. | 1575 // Dispatches to 'Double./'. |
1555 // TODO(srdjan): Implement as conversion to double and double division. | 1576 // TODO(srdjan): Implement as conversion to double and double division. |
1556 UNREACHABLE(); | 1577 UNREACHABLE(); |
1557 break; | 1578 break; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1626 | 1647 |
1627 __ Bind(&smi_static_call); | 1648 __ Bind(&smi_static_call); |
1628 { | 1649 { |
1629 Function& target = Function::ZoneHandle( | 1650 Function& target = Function::ZoneHandle( |
1630 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid)); | 1651 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid)); |
1631 if (target.IsNull()) { | 1652 if (target.IsNull()) { |
1632 __ jmp(deopt); | 1653 __ jmp(deopt); |
1633 } else { | 1654 } else { |
1634 __ pushl(left); | 1655 __ pushl(left); |
1635 __ pushl(right); | 1656 __ pushl(right); |
1636 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), | 1657 compiler->GenerateStaticCall( |
1637 comp->instance_call()->token_pos(), | 1658 comp->instance_call()->deopt_id(), |
1638 comp->instance_call()->try_index(), | 1659 comp->instance_call()->token_pos(), |
1639 target, | 1660 comp->instance_call()->try_index(), |
1640 comp->instance_call()->ArgumentCount(), | 1661 target, |
1641 comp->instance_call()->argument_names()); | 1662 comp->instance_call()->ArgumentCount(), |
1663 comp->instance_call()->argument_names(), | |
1664 comp->locs()->stack_bitmap()); | |
1642 ASSERT(result == EAX); | 1665 ASSERT(result == EAX); |
1643 __ jmp(&done); | 1666 __ jmp(&done); |
1644 } | 1667 } |
1645 } | 1668 } |
1646 | 1669 |
1647 __ Bind(&mint_static_call); | 1670 __ Bind(&mint_static_call); |
1648 { | 1671 { |
1649 Function& target = Function::ZoneHandle( | 1672 Function& target = Function::ZoneHandle( |
1650 comp->ic_data()->GetTargetForReceiverClassId(kMintCid)); | 1673 comp->ic_data()->GetTargetForReceiverClassId(kMintCid)); |
1651 if (target.IsNull()) { | 1674 if (target.IsNull()) { |
1652 __ jmp(deopt); | 1675 __ jmp(deopt); |
1653 } else { | 1676 } else { |
1654 __ pushl(left); | 1677 __ pushl(left); |
1655 __ pushl(right); | 1678 __ pushl(right); |
1656 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), | 1679 compiler->GenerateStaticCall( |
1657 comp->instance_call()->token_pos(), | 1680 comp->instance_call()->deopt_id(), |
1658 comp->instance_call()->try_index(), | 1681 comp->instance_call()->token_pos(), |
1659 target, | 1682 comp->instance_call()->try_index(), |
1660 comp->instance_call()->ArgumentCount(), | 1683 target, |
1661 comp->instance_call()->argument_names()); | 1684 comp->instance_call()->ArgumentCount(), |
1685 comp->instance_call()->argument_names(), | |
1686 comp->locs()->stack_bitmap()); | |
1662 ASSERT(result == EAX); | 1687 ASSERT(result == EAX); |
1663 } | 1688 } |
1664 } | 1689 } |
1665 __ Bind(&done); | 1690 __ Bind(&done); |
1666 } | 1691 } |
1667 | 1692 |
1668 | 1693 |
1669 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1694 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
1670 switch (operands_type()) { | 1695 switch (operands_type()) { |
1671 case kSmiOperands: | 1696 case kSmiOperands: |
(...skipping 21 matching lines...) Expand all Loading... | |
1693 Register temp = EDX; | 1718 Register temp = EDX; |
1694 Register result = locs()->out().reg(); | 1719 Register result = locs()->out().reg(); |
1695 | 1720 |
1696 const Class& double_class = compiler->double_class(); | 1721 const Class& double_class = compiler->double_class(); |
1697 const Code& stub = | 1722 const Code& stub = |
1698 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 1723 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
1699 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | 1724 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
1700 compiler->GenerateCall(instance_call()->token_pos(), | 1725 compiler->GenerateCall(instance_call()->token_pos(), |
1701 instance_call()->try_index(), | 1726 instance_call()->try_index(), |
1702 &label, | 1727 &label, |
1703 PcDescriptors::kOther); | 1728 PcDescriptors::kOther, |
1729 locs()->stack_bitmap()); | |
1704 // Newly allocated object is now in the result register (RAX). | 1730 // Newly allocated object is now in the result register (RAX). |
1705 ASSERT(result == EAX); | 1731 ASSERT(result == EAX); |
1706 __ popl(right); | 1732 __ popl(right); |
1707 __ popl(left); | 1733 __ popl(left); |
1708 | 1734 |
1709 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), | 1735 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), |
1710 instance_call()->try_index(), | 1736 instance_call()->try_index(), |
1711 kDeoptDoubleBinaryOp, | 1737 kDeoptDoubleBinaryOp, |
1712 left, | 1738 left, |
1713 right); | 1739 right); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1820 __ j(NOT_EQUAL, deopt); | 1846 __ j(NOT_EQUAL, deopt); |
1821 // Allocate result object. | 1847 // Allocate result object. |
1822 const Class& double_class = compiler->double_class(); | 1848 const Class& double_class = compiler->double_class(); |
1823 const Code& stub = | 1849 const Code& stub = |
1824 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 1850 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
1825 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | 1851 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
1826 __ pushl(value); | 1852 __ pushl(value); |
1827 compiler->GenerateCall(instance_call()->token_pos(), | 1853 compiler->GenerateCall(instance_call()->token_pos(), |
1828 instance_call()->try_index(), | 1854 instance_call()->try_index(), |
1829 &label, | 1855 &label, |
1830 PcDescriptors::kOther); | 1856 PcDescriptors::kOther, |
1857 locs()->stack_bitmap()); | |
1831 // Result is in EAX. | 1858 // Result is in EAX. |
1832 ASSERT(result != temp); | 1859 ASSERT(result != temp); |
1833 __ movl(result, EAX); | 1860 __ movl(result, EAX); |
1834 __ popl(temp); | 1861 __ popl(temp); |
1835 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); | 1862 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); |
1836 __ DoubleNegate(XMM0); | 1863 __ DoubleNegate(XMM0); |
1837 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 1864 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
1838 } else { | 1865 } else { |
1839 UNREACHABLE(); | 1866 UNREACHABLE(); |
1840 } | 1867 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1884 | 1911 |
1885 const Class& double_class = compiler->double_class(); | 1912 const Class& double_class = compiler->double_class(); |
1886 const Code& stub = | 1913 const Code& stub = |
1887 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 1914 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
1888 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); | 1915 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
1889 | 1916 |
1890 // TODO(vegorov): allocate box in the driver loop to avoid spilling. | 1917 // TODO(vegorov): allocate box in the driver loop to avoid spilling. |
1891 compiler->GenerateCall(instance_call()->token_pos(), | 1918 compiler->GenerateCall(instance_call()->token_pos(), |
1892 instance_call()->try_index(), | 1919 instance_call()->try_index(), |
1893 &label, | 1920 &label, |
1894 PcDescriptors::kOther); | 1921 PcDescriptors::kOther, |
1922 locs()->stack_bitmap()); | |
1895 ASSERT(result == EAX); | 1923 ASSERT(result == EAX); |
1896 __ popl(value); | 1924 __ popl(value); |
1897 | 1925 |
1898 __ testl(value, Immediate(kSmiTagMask)); | 1926 __ testl(value, Immediate(kSmiTagMask)); |
1899 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. | 1927 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. |
1900 __ SmiUntag(value); | 1928 __ SmiUntag(value); |
1901 __ cvtsi2sd(XMM0, value); | 1929 __ cvtsi2sd(XMM0, value); |
1902 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 1930 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
1903 } | 1931 } |
1904 | 1932 |
(...skipping 25 matching lines...) Expand all Loading... | |
1930 Label done; | 1958 Label done; |
1931 __ LoadClassId(EDI, EAX); | 1959 __ LoadClassId(EDI, EAX); |
1932 compiler->EmitTestAndCall(*ic_data(), | 1960 compiler->EmitTestAndCall(*ic_data(), |
1933 EDI, // Class id register. | 1961 EDI, // Class id register. |
1934 instance_call()->ArgumentCount(), | 1962 instance_call()->ArgumentCount(), |
1935 instance_call()->argument_names(), | 1963 instance_call()->argument_names(), |
1936 deopt, | 1964 deopt, |
1937 (is_smi_label == &handle_smi) ? &done : NULL, | 1965 (is_smi_label == &handle_smi) ? &done : NULL, |
1938 instance_call()->deopt_id(), | 1966 instance_call()->deopt_id(), |
1939 instance_call()->token_pos(), | 1967 instance_call()->token_pos(), |
1940 instance_call()->try_index()); | 1968 instance_call()->try_index(), |
1969 locs()->stack_bitmap()); | |
1941 if (is_smi_label == &handle_smi) { | 1970 if (is_smi_label == &handle_smi) { |
1942 __ Bind(&handle_smi); | 1971 __ Bind(&handle_smi); |
1943 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmiCid); | 1972 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmiCid); |
1944 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); | 1973 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); |
1945 compiler->GenerateStaticCall(instance_call()->deopt_id(), | 1974 compiler->GenerateStaticCall(instance_call()->deopt_id(), |
1946 instance_call()->token_pos(), | 1975 instance_call()->token_pos(), |
1947 instance_call()->try_index(), | 1976 instance_call()->try_index(), |
1948 target, | 1977 target, |
1949 instance_call()->ArgumentCount(), | 1978 instance_call()->ArgumentCount(), |
1950 instance_call()->argument_names()); | 1979 instance_call()->argument_names(), |
1980 locs()->stack_bitmap()); | |
1951 } | 1981 } |
1952 __ Bind(&done); | 1982 __ Bind(&done); |
1953 } | 1983 } |
1954 | 1984 |
1955 | 1985 |
1956 // TODO(srdjan): Move to shared. | 1986 // TODO(srdjan): Move to shared. |
1957 static bool ICDataWithBothClassIds(const ICData& ic_data, intptr_t class_id) { | 1987 static bool ICDataWithBothClassIds(const ICData& ic_data, intptr_t class_id) { |
1958 if (ic_data.num_args_tested() != 2) return false; | 1988 if (ic_data.num_args_tested() != 2) return false; |
1959 if (ic_data.NumberOfChecks() != 1) return false; | 1989 if (ic_data.NumberOfChecks() != 1) return false; |
1960 Function& target = Function::Handle(); | 1990 Function& target = Function::Handle(); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2042 token_pos(), | 2072 token_pos(), |
2043 try_index()); | 2073 try_index()); |
2044 const intptr_t kNumArguments = 2; | 2074 const intptr_t kNumArguments = 2; |
2045 const intptr_t kNumArgsChecked = 2; // Type-feedback. | 2075 const intptr_t kNumArgsChecked = 2; // Type-feedback. |
2046 compiler->GenerateInstanceCall(deopt_id(), | 2076 compiler->GenerateInstanceCall(deopt_id(), |
2047 token_pos(), | 2077 token_pos(), |
2048 try_index(), | 2078 try_index(), |
2049 function_name, | 2079 function_name, |
2050 kNumArguments, | 2080 kNumArguments, |
2051 Array::ZoneHandle(), // No optional arguments. | 2081 Array::ZoneHandle(), // No optional arguments. |
2052 kNumArgsChecked); | 2082 kNumArgsChecked, |
2083 locs()->stack_bitmap()); | |
2053 ASSERT(locs()->out().reg() == EAX); | 2084 ASSERT(locs()->out().reg() == EAX); |
2054 __ CompareObject(locs()->out().reg(), compiler->bool_true()); | 2085 __ CompareObject(locs()->out().reg(), compiler->bool_true()); |
2055 EmitBranchOnCondition(compiler, branch_condition); | 2086 EmitBranchOnCondition(compiler, branch_condition); |
2056 } | 2087 } |
2057 | 2088 |
2058 } // namespace dart | 2089 } // namespace dart |
2059 | 2090 |
2060 #undef __ | 2091 #undef __ |
2061 | 2092 |
2062 #endif // defined TARGET_ARCH_X64 | 2093 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |