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

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

Issue 10831261: Build and use stack maps in the SSA compiler. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698