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

Side by Side Diff: runtime/vm/intermediate_language_x64.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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 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 __ pushq(result); // Preserve result. 89 __ pushq(result); // Preserve result.
90 __ pushq(temp); 90 __ pushq(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 NULL);
Vyacheslav Egorov (Google) 2012/08/13 12:54:46 ReturnInstr is marked as NoCall. This code is susp
95 __ popq(temp); // Remove argument. 96 __ popq(temp); // Remove argument.
96 __ popq(result); // Restore result. 97 __ popq(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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 Label done; 218 Label done;
218 __ CompareObject(obj, compiler->bool_true()); 219 __ CompareObject(obj, compiler->bool_true());
219 __ j(EQUAL, &done, Assembler::kNearJump); 220 __ j(EQUAL, &done, Assembler::kNearJump);
220 __ CompareObject(obj, compiler->bool_false()); 221 __ CompareObject(obj, compiler->bool_false());
221 __ j(EQUAL, &done, Assembler::kNearJump); 222 __ j(EQUAL, &done, Assembler::kNearJump);
222 223
223 __ pushq(obj); // Push the source object. 224 __ pushq(obj); // Push the source object.
224 compiler->GenerateCallRuntime(deopt_id(), 225 compiler->GenerateCallRuntime(deopt_id(),
225 token_pos(), 226 token_pos(),
226 try_index(), 227 try_index(),
227 kConditionTypeErrorRuntimeEntry); 228 kConditionTypeErrorRuntimeEntry,
229 locs()->stack_bitmap());
228 // We should never return here. 230 // We should never return here.
229 __ int3(); 231 __ int3();
230 232
231 __ Bind(&done); 233 __ Bind(&done);
232 ASSERT(obj == result); 234 ASSERT(obj == result);
233 } 235 }
234 236
235 237
236 static Condition TokenKindToSmiCondition(Token::Kind kind) { 238 static Condition TokenKindToSmiCondition(Token::Kind kind) {
237 switch (kind) { 239 switch (kind) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 const int kNumberOfArguments = 2; 294 const int kNumberOfArguments = 2;
293 const Array& kNoArgumentNames = Array::Handle(); 295 const Array& kNoArgumentNames = Array::Handle();
294 const int kNumArgumentsChecked = 2; 296 const int kNumArgumentsChecked = 2;
295 297
296 compiler->GenerateInstanceCall(comp->deopt_id(), 298 compiler->GenerateInstanceCall(comp->deopt_id(),
297 comp->token_pos(), 299 comp->token_pos(),
298 comp->try_index(), 300 comp->try_index(),
299 operator_name, 301 operator_name,
300 kNumberOfArguments, 302 kNumberOfArguments,
301 kNoArgumentNames, 303 kNoArgumentNames,
302 kNumArgumentsChecked); 304 kNumArgumentsChecked,
305 comp->locs()->stack_bitmap());
303 ASSERT(comp->locs()->out().reg() == RAX); 306 ASSERT(comp->locs()->out().reg() == RAX);
304 if (comp->kind() == Token::kNE) { 307 if (comp->kind() == Token::kNE) {
305 Label done, false_label; 308 Label done, false_label;
306 __ CompareObject(RAX, compiler->bool_true()); 309 __ CompareObject(RAX, compiler->bool_true());
307 __ j(EQUAL, &false_label, Assembler::kNearJump); 310 __ j(EQUAL, &false_label, Assembler::kNearJump);
308 __ LoadObject(RAX, compiler->bool_true()); 311 __ LoadObject(RAX, compiler->bool_true());
309 __ jmp(&done, Assembler::kNearJump); 312 __ jmp(&done, Assembler::kNearJump);
310 __ Bind(&false_label); 313 __ Bind(&false_label);
311 __ LoadObject(RAX, compiler->bool_false()); 314 __ LoadObject(RAX, compiler->bool_false());
312 __ Bind(&done); 315 __ Bind(&done);
313 } 316 }
314 } 317 }
315 318
316 319
317 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, 320 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
318 const ICData& orig_ic_data, 321 const ICData& orig_ic_data,
319 const LocationSummary& locs, 322 const LocationSummary& locs,
320 BranchInstr* branch, 323 BranchInstr* branch,
321 Token::Kind kind, 324 Token::Kind kind,
322 intptr_t deopt_id, 325 intptr_t deopt_id,
323 intptr_t token_pos, 326 intptr_t token_pos,
324 intptr_t try_index) { 327 intptr_t try_index,
328 BitmapBuilder* stack_bitmap) {
325 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 329 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
326 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); 330 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
327 ASSERT(ic_data.NumberOfChecks() > 0); 331 ASSERT(ic_data.NumberOfChecks() > 0);
328 ASSERT(ic_data.num_args_tested() == 1); 332 ASSERT(ic_data.num_args_tested() == 1);
329 Label* deopt = compiler->AddDeoptStub(deopt_id, try_index, kDeoptEquality); 333 Label* deopt = compiler->AddDeoptStub(deopt_id, try_index, kDeoptEquality);
330 Register left = locs.in(0).reg(); 334 Register left = locs.in(0).reg();
331 Register right = locs.in(1).reg(); 335 Register right = locs.in(1).reg();
332 __ testq(left, Immediate(kSmiTagMask)); 336 __ testq(left, Immediate(kSmiTagMask));
333 Register temp = locs.temp(0).reg(); 337 Register temp = locs.temp(0).reg();
334 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) { 338 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 __ LoadObject(result, compiler->bool_true()); 373 __ LoadObject(result, compiler->bool_true());
370 } 374 }
371 } else { 375 } else {
372 const int kNumberOfArguments = 2; 376 const int kNumberOfArguments = 2;
373 const Array& kNoArgumentNames = Array::Handle(); 377 const Array& kNoArgumentNames = Array::Handle();
374 compiler->GenerateStaticCall(deopt_id, 378 compiler->GenerateStaticCall(deopt_id,
375 token_pos, 379 token_pos,
376 try_index, 380 try_index,
377 target, 381 target,
378 kNumberOfArguments, 382 kNumberOfArguments,
379 kNoArgumentNames); 383 kNoArgumentNames,
384 stack_bitmap);
380 if (branch == NULL) { 385 if (branch == NULL) {
381 if (kind == Token::kNE) { 386 if (kind == Token::kNE) {
382 Label false_label; 387 Label false_label;
383 __ CompareObject(RAX, compiler->bool_true()); 388 __ CompareObject(RAX, compiler->bool_true());
384 __ j(EQUAL, &false_label, Assembler::kNearJump); 389 __ j(EQUAL, &false_label, Assembler::kNearJump);
385 __ LoadObject(RAX, compiler->bool_true()); 390 __ LoadObject(RAX, compiler->bool_true());
386 __ jmp(&done); 391 __ jmp(&done);
387 __ Bind(&false_label); 392 __ Bind(&false_label);
388 __ LoadObject(RAX, compiler->bool_false()); 393 __ LoadObject(RAX, compiler->bool_false());
389 __ jmp(&done); 394 __ jmp(&done);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 __ LoadObject(result, compiler->bool_false()); 439 __ LoadObject(result, compiler->bool_false());
435 __ jmp(&done); 440 __ jmp(&done);
436 __ Bind(&load_true); 441 __ Bind(&load_true);
437 __ LoadObject(result, compiler->bool_true()); 442 __ LoadObject(result, compiler->bool_true());
438 } 443 }
439 __ jmp(&done); 444 __ jmp(&done);
440 __ Bind(&non_null_compare); // Receiver is not null. 445 __ Bind(&non_null_compare); // Receiver is not null.
441 __ pushq(left); 446 __ pushq(left);
442 __ pushq(right); 447 __ pushq(right);
443 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 448 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
444 deopt_id, token_pos, try_index); 449 deopt_id, token_pos, try_index,
450 locs.stack_bitmap());
445 __ Bind(&done); 451 __ Bind(&done);
446 } 452 }
447 453
448 454
449 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 455 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
450 const LocationSummary& locs, 456 const LocationSummary& locs,
451 Token::Kind kind, 457 Token::Kind kind,
452 BranchInstr* branch, 458 BranchInstr* branch,
453 intptr_t deopt_id, 459 intptr_t deopt_id,
454 intptr_t token_pos, 460 intptr_t token_pos,
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 __ LoadClassId(RDI, RAX); 601 __ LoadClassId(RDI, RAX);
596 __ Bind(&done); 602 __ Bind(&done);
597 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), 603 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
598 RDI, // Class id register. 604 RDI, // Class id register.
599 kNumArguments, 605 kNumArguments,
600 Array::Handle(), // No named arguments. 606 Array::Handle(), // No named arguments.
601 deopt, // Deoptimize target. 607 deopt, // Deoptimize target.
602 NULL, // Fallthrough when done. 608 NULL, // Fallthrough when done.
603 deopt_id(), 609 deopt_id(),
604 token_pos(), 610 token_pos(),
605 try_index()); 611 try_index(),
612 locs()->stack_bitmap());
606 return; 613 return;
607 } 614 }
608 const String& function_name = 615 const String& function_name =
609 String::ZoneHandle(Symbols::New(Token::Str(kind()))); 616 String::ZoneHandle(Symbols::New(Token::Str(kind())));
610 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 617 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
611 deopt_id(), 618 deopt_id(),
612 token_pos(), 619 token_pos(),
613 try_index()); 620 try_index());
614 const intptr_t kNumArguments = 2; 621 const intptr_t kNumArguments = 2;
615 const intptr_t kNumArgsChecked = 2; // Type-feedback. 622 const intptr_t kNumArgsChecked = 2; // Type-feedback.
616 compiler->GenerateInstanceCall(deopt_id(), 623 compiler->GenerateInstanceCall(deopt_id(),
617 token_pos(), 624 token_pos(),
618 try_index(), 625 try_index(),
619 function_name, 626 function_name,
620 kNumArguments, 627 kNumArguments,
621 Array::ZoneHandle(), // No optional arguments. 628 Array::ZoneHandle(), // No optional arguments.
622 kNumArgsChecked); 629 kNumArgsChecked,
630 locs()->stack_bitmap());
623 ASSERT(locs()->out().reg() == RAX); 631 ASSERT(locs()->out().reg() == RAX);
624 } 632 }
625 633
626 634
627 LocationSummary* NativeCallComp::MakeLocationSummary() const { 635 LocationSummary* NativeCallComp::MakeLocationSummary() const {
628 const intptr_t kNumInputs = 0; 636 const intptr_t kNumInputs = 0;
629 const intptr_t kNumTemps = 3; 637 const intptr_t kNumTemps = 3;
630 LocationSummary* locs = 638 LocationSummary* locs =
631 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 639 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
632 locs->set_temp(0, Location::RegisterLocation(RAX)); 640 locs->set_temp(0, Location::RegisterLocation(RAX));
(...skipping 21 matching lines...) Expand all
654 __ leaq(RAX, Address(RBP, (1 + arg_count) * kWordSize)); 662 __ leaq(RAX, Address(RBP, (1 + arg_count) * kWordSize));
655 } else { 663 } else {
656 __ leaq(RAX, 664 __ leaq(RAX,
657 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); 665 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize));
658 } 666 }
659 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); 667 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function())));
660 __ movq(R10, Immediate(arg_count)); 668 __ movq(R10, Immediate(arg_count));
661 compiler->GenerateCall(token_pos(), 669 compiler->GenerateCall(token_pos(),
662 try_index(), 670 try_index(),
663 &StubCode::CallNativeCFunctionLabel(), 671 &StubCode::CallNativeCFunctionLabel(),
664 PcDescriptors::kOther); 672 PcDescriptors::kOther,
673 locs()->stack_bitmap());
665 __ popq(result); 674 __ popq(result);
666 } 675 }
667 676
668 677
669 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { 678 LocationSummary* LoadIndexedComp::MakeLocationSummary() const {
670 const intptr_t kNumInputs = 2; 679 const intptr_t kNumInputs = 2;
671 if (receiver_type() == kGrowableObjectArrayCid) { 680 if (receiver_type() == kGrowableObjectArrayCid) {
672 const intptr_t kNumTemps = 1; 681 const intptr_t kNumTemps = 1;
673 LocationSummary* locs = 682 LocationSummary* locs =
674 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 683 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
675 locs->set_in(0, Location::RequiresRegister()); 684 locs->set_in(0, Location::RequiresRegister());
676 locs->set_in(1, Location::RequiresRegister()); 685 locs->set_in(1, Location::RequiresRegister());
677 locs->set_temp(0, Location::RequiresRegister()); 686 locs->set_temp(0, Location::RequiresRegister());
678 locs->set_out(Location::RequiresRegister()); 687 locs->set_out(Location::RequiresRegister());
679 return locs; 688 return locs;
680 } else if ((receiver_type() == kArrayCid) || 689 } else if ((receiver_type() == kArrayCid) ||
681 (receiver_type() == kImmutableArrayCid)) { 690 (receiver_type() == kImmutableArrayCid)) {
682 return LocationSummary::Make(kNumInputs, 691 return LocationSummary::Make(kNumInputs,
683 Location::RequiresRegister(), 692 Location::RequiresRegister(),
684 LocationSummary::kNoCall); 693 LocationSummary::kNoCall);
685 } else { 694 } else {
686 ASSERT(receiver_type() == kIllegalCid); 695 ASSERT(receiver_type() == kIllegalCid);
687 return MakeCallSummary(); 696 return MakeCallSummary();
688 } 697 }
689 } 698 }
690 699
691 700
692 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, 701 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler,
693 LoadIndexedComp* comp) { 702 LoadIndexedComp* comp) {
694 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), 703 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
695 comp->try_index(), 704 comp->try_index(),
696 kDeoptLoadIndexedPolymorphic); 705 kDeoptLoadIndexedPolymorphic);
697 ASSERT(comp->ic_data()->NumberOfChecks() > 0); 706 ASSERT(comp->ic_data()->NumberOfChecks() > 0);
698 ASSERT(comp->HasICData()); 707 ASSERT(comp->HasICData());
699 const ICData& ic_data = *comp->ic_data(); 708 const ICData& ic_data = *comp->ic_data();
700 ASSERT(ic_data.num_args_tested() == 1); 709 ASSERT(ic_data.num_args_tested() == 1);
701 // No indexed access on Smi. 710 // No indexed access on Smi.
702 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); 711 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid);
703 // Load receiver into RAX. 712 // Load receiver into RAX.
704 const intptr_t kNumArguments = 2; 713 const intptr_t kNumArguments = 2;
705 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); 714 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize));
706 __ testq(RAX, Immediate(kSmiTagMask)); 715 __ testq(RAX, Immediate(kSmiTagMask));
707 __ j(ZERO, deopt); 716 __ j(ZERO, deopt);
708 __ LoadClassId(RDI, RAX); 717 __ LoadClassId(RDI, RAX);
709 compiler->EmitTestAndCall(ic_data, 718 compiler->EmitTestAndCall(ic_data,
710 RDI, // Class id register. 719 RDI, // Class id register.
711 kNumArguments, 720 kNumArguments,
712 Array::Handle(), // No named arguments. 721 Array::Handle(), // No named arguments.
713 deopt, // Deoptimize target. 722 deopt, // Deoptimize target.
714 NULL, // Fallthrough when done. 723 NULL, // Fallthrough when done.
715 comp->deopt_id(), 724 comp->deopt_id(),
716 comp->token_pos(), 725 comp->token_pos(),
717 comp->try_index()); 726 comp->try_index(),
727 comp->locs()->stack_bitmap());
718 } 728 }
719 729
720 730
721 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 731 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
722 if (receiver_type() == kIllegalCid) { 732 if (receiver_type() == kIllegalCid) {
723 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 733 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
724 EmitLoadIndexedPolymorphic(compiler, this); 734 EmitLoadIndexedPolymorphic(compiler, this);
725 } else { 735 } else {
726 compiler->EmitLoadIndexedGeneric(this); 736 compiler->EmitLoadIndexedGeneric(this);
727 } 737 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 comp->try_index()); 825 comp->try_index());
816 826
817 const intptr_t kNumArguments = 3; 827 const intptr_t kNumArguments = 3;
818 const intptr_t kNumArgsChecked = 1; // Type-feedback. 828 const intptr_t kNumArgsChecked = 1; // Type-feedback.
819 compiler->GenerateInstanceCall(comp->deopt_id(), 829 compiler->GenerateInstanceCall(comp->deopt_id(),
820 comp->token_pos(), 830 comp->token_pos(),
821 comp->try_index(), 831 comp->try_index(),
822 function_name, 832 function_name,
823 kNumArguments, 833 kNumArguments,
824 Array::ZoneHandle(), // No named arguments. 834 Array::ZoneHandle(), // No named arguments.
825 kNumArgsChecked); 835 kNumArgsChecked,
836 comp->locs()->stack_bitmap());
826 } 837 }
827 838
828 839
829 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler, 840 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler,
830 StoreIndexedComp* comp) { 841 StoreIndexedComp* comp) {
831 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(), 842 Label* deopt = compiler->AddDeoptStub(comp->deopt_id(),
832 comp->try_index(), 843 comp->try_index(),
833 kDeoptStoreIndexedPolymorphic); 844 kDeoptStoreIndexedPolymorphic);
834 ASSERT(comp->ic_data()->NumberOfChecks() > 0); 845 ASSERT(comp->ic_data()->NumberOfChecks() > 0);
835 ASSERT(comp->HasICData()); 846 ASSERT(comp->HasICData());
836 const ICData& ic_data = *comp->ic_data(); 847 const ICData& ic_data = *comp->ic_data();
837 ASSERT(ic_data.num_args_tested() == 1); 848 ASSERT(ic_data.num_args_tested() == 1);
838 // No indexed access on Smi. 849 // No indexed access on Smi.
839 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid); 850 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmiCid);
840 // Load receiver into RAX. 851 // Load receiver into RAX.
841 const intptr_t kNumArguments = 3; 852 const intptr_t kNumArguments = 3;
842 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize)); 853 __ movq(RAX, Address(RSP, (kNumArguments - 1) * kWordSize));
843 __ testq(RAX, Immediate(kSmiTagMask)); 854 __ testq(RAX, Immediate(kSmiTagMask));
844 __ j(ZERO, deopt); 855 __ j(ZERO, deopt);
845 __ LoadClassId(RDI, RAX); 856 __ LoadClassId(RDI, RAX);
846 compiler->EmitTestAndCall(ic_data, 857 compiler->EmitTestAndCall(ic_data,
847 RDI, // Class id register. 858 RDI, // Class id register.
848 kNumArguments, 859 kNumArguments,
849 Array::Handle(), // No named arguments. 860 Array::Handle(), // No named arguments.
850 deopt, // deoptimize label. 861 deopt, // deoptimize label.
851 NULL, // fallthrough when done. 862 NULL, // fallthrough when done.
852 comp->deopt_id(), 863 comp->deopt_id(),
853 comp->token_pos(), 864 comp->token_pos(),
854 comp->try_index()); 865 comp->try_index(),
866 comp->locs()->stack_bitmap());
855 } 867 }
856 868
857 869
858 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 870 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
859 if (receiver_type() == kIllegalCid) { 871 if (receiver_type() == kIllegalCid) {
860 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 872 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
861 EmitStoreIndexedPolymorphic(compiler, this); 873 EmitStoreIndexedPolymorphic(compiler, this);
862 } else { 874 } else {
863 EmitStoreIndexedGeneric(compiler, this); 875 EmitStoreIndexedGeneric(compiler, this);
864 } 876 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 989
978 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { 990 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) {
979 ASSERT(locs()->in(0).reg() == RAX); // Value. 991 ASSERT(locs()->in(0).reg() == RAX); // Value.
980 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. 992 ASSERT(locs()->in(1).reg() == RCX); // Instantiator.
981 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. 993 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments.
982 994
983 compiler->GenerateInstanceOf(deopt_id(), 995 compiler->GenerateInstanceOf(deopt_id(),
984 token_pos(), 996 token_pos(),
985 try_index(), 997 try_index(),
986 type(), 998 type(),
987 negate_result()); 999 negate_result(),
1000 locs()->stack_bitmap());
988 ASSERT(locs()->out().reg() == RAX); 1001 ASSERT(locs()->out().reg() == RAX);
989 } 1002 }
990 1003
991 1004
992 LocationSummary* CreateArrayComp::MakeLocationSummary() const { 1005 LocationSummary* CreateArrayComp::MakeLocationSummary() const {
993 const intptr_t kNumInputs = 1; 1006 const intptr_t kNumInputs = 1;
994 const intptr_t kNumTemps = 0; 1007 const intptr_t kNumTemps = 0;
995 LocationSummary* locs = 1008 LocationSummary* locs =
996 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1009 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
997 locs->set_in(0, Location::RegisterLocation(RBX)); 1010 locs->set_in(0, Location::RegisterLocation(RBX));
998 locs->set_out(Location::RegisterLocation(RAX)); 1011 locs->set_out(Location::RegisterLocation(RAX));
999 return locs; 1012 return locs;
1000 } 1013 }
1001 1014
1002 1015
1003 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1016 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1004 // Allocate the array. R10 = length, RBX = element type. 1017 // Allocate the array. R10 = length, RBX = element type.
1005 ASSERT(locs()->in(0).reg() == RBX); 1018 ASSERT(locs()->in(0).reg() == RBX);
1006 __ movq(R10, Immediate(Smi::RawValue(ElementCount()))); 1019 __ movq(R10, Immediate(Smi::RawValue(ElementCount())));
1007 compiler->GenerateCall(token_pos(), 1020 compiler->GenerateCall(token_pos(),
1008 try_index(), 1021 try_index(),
1009 &StubCode::AllocateArrayLabel(), 1022 &StubCode::AllocateArrayLabel(),
1010 PcDescriptors::kOther); 1023 PcDescriptors::kOther,
1024 locs()->stack_bitmap());
1011 ASSERT(locs()->out().reg() == RAX); 1025 ASSERT(locs()->out().reg() == RAX);
1012 1026
1013 // Pop the element values from the stack into the array. 1027 // Pop the element values from the stack into the array.
1014 __ leaq(R10, FieldAddress(RAX, Array::data_offset())); 1028 __ leaq(R10, FieldAddress(RAX, Array::data_offset()));
1015 for (int i = ElementCount() - 1; i >= 0; --i) { 1029 for (int i = ElementCount() - 1; i >= 0; --i) {
1016 ASSERT(ElementAt(i)->IsUse()); 1030 ASSERT(ElementAt(i)->IsUse());
1017 __ popq(Address(R10, i * kWordSize)); 1031 __ popq(Address(R10, i * kWordSize));
1018 } 1032 }
1019 } 1033 }
1020 1034
(...skipping 19 matching lines...) Expand all
1040 Register result = locs()->out().reg(); 1054 Register result = locs()->out().reg();
1041 1055
1042 // Push the result place holder initialized to NULL. 1056 // Push the result place holder initialized to NULL.
1043 __ PushObject(Object::ZoneHandle()); 1057 __ PushObject(Object::ZoneHandle());
1044 __ PushObject(cls); 1058 __ PushObject(cls);
1045 __ pushq(type_arguments); 1059 __ pushq(type_arguments);
1046 __ pushq(instantiator_type_arguments); 1060 __ pushq(instantiator_type_arguments);
1047 compiler->GenerateCallRuntime(deopt_id(), 1061 compiler->GenerateCallRuntime(deopt_id(),
1048 token_pos(), 1062 token_pos(),
1049 try_index(), 1063 try_index(),
1050 kAllocateObjectWithBoundsCheckRuntimeEntry); 1064 kAllocateObjectWithBoundsCheckRuntimeEntry,
1065 locs()->stack_bitmap());
1051 // Pop instantiator type arguments, type arguments, and class. 1066 // Pop instantiator type arguments, type arguments, and class.
1052 __ Drop(3); 1067 __ Drop(3);
1053 __ popq(result); // Pop new instance. 1068 __ popq(result); // Pop new instance.
1054 } 1069 }
1055 1070
1056 1071
1057 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { 1072 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const {
1058 return LocationSummary::Make(1, 1073 return LocationSummary::Make(1,
1059 Location::RequiresRegister(), 1074 Location::RequiresRegister(),
1060 LocationSummary::kNoCall); 1075 LocationSummary::kNoCall);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1140 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1126 __ Bind(&type_arguments_uninstantiated); 1141 __ Bind(&type_arguments_uninstantiated);
1127 } 1142 }
1128 // A runtime call to instantiate the type arguments is required. 1143 // A runtime call to instantiate the type arguments is required.
1129 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1144 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1130 __ PushObject(type_arguments()); 1145 __ PushObject(type_arguments());
1131 __ pushq(instantiator_reg); // Push instantiator type arguments. 1146 __ pushq(instantiator_reg); // Push instantiator type arguments.
1132 compiler->GenerateCallRuntime(deopt_id(), 1147 compiler->GenerateCallRuntime(deopt_id(),
1133 token_pos(), 1148 token_pos(),
1134 try_index(), 1149 try_index(),
1135 kInstantiateTypeArgumentsRuntimeEntry); 1150 kInstantiateTypeArgumentsRuntimeEntry,
1151 locs()->stack_bitmap());
1136 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 1152 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1137 __ popq(result_reg); // Pop instantiated type arguments. 1153 __ popq(result_reg); // Pop instantiated type arguments.
1138 __ Bind(&type_arguments_instantiated); 1154 __ Bind(&type_arguments_instantiated);
1139 ASSERT(instantiator_reg == result_reg); 1155 ASSERT(instantiator_reg == result_reg);
1140 // 'result_reg': Instantiated type arguments. 1156 // 'result_reg': Instantiated type arguments.
1141 } 1157 }
1142 1158
1143 1159
1144 LocationSummary* 1160 LocationSummary*
1145 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const { 1161 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const {
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1293 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1278 ASSERT(locs()->temp(0).reg() == R10); 1294 ASSERT(locs()->temp(0).reg() == R10);
1279 ASSERT(locs()->out().reg() == RAX); 1295 ASSERT(locs()->out().reg() == RAX);
1280 1296
1281 __ movq(R10, Immediate(num_context_variables())); 1297 __ movq(R10, Immediate(num_context_variables()));
1282 const ExternalLabel label("alloc_context", 1298 const ExternalLabel label("alloc_context",
1283 StubCode::AllocateContextEntryPoint()); 1299 StubCode::AllocateContextEntryPoint());
1284 compiler->GenerateCall(token_pos(), 1300 compiler->GenerateCall(token_pos(),
1285 try_index(), 1301 try_index(),
1286 &label, 1302 &label,
1287 PcDescriptors::kOther); 1303 PcDescriptors::kOther,
1304 locs()->stack_bitmap());
1288 } 1305 }
1289 1306
1290 1307
1291 LocationSummary* CloneContextComp::MakeLocationSummary() const { 1308 LocationSummary* CloneContextComp::MakeLocationSummary() const {
1292 const intptr_t kNumInputs = 1; 1309 const intptr_t kNumInputs = 1;
1293 const intptr_t kNumTemps = 0; 1310 const intptr_t kNumTemps = 0;
1294 LocationSummary* locs = 1311 LocationSummary* locs =
1295 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1312 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1296 locs->set_in(0, Location::RegisterLocation(RAX)); 1313 locs->set_in(0, Location::RegisterLocation(RAX));
1297 locs->set_out(Location::RegisterLocation(RAX)); 1314 locs->set_out(Location::RegisterLocation(RAX));
1298 return locs; 1315 return locs;
1299 } 1316 }
1300 1317
1301 1318
1302 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1319 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1303 Register context_value = locs()->in(0).reg(); 1320 Register context_value = locs()->in(0).reg();
1304 Register result = locs()->out().reg(); 1321 Register result = locs()->out().reg();
1305 1322
1306 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1323 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1307 __ pushq(context_value); 1324 __ pushq(context_value);
1308 compiler->GenerateCallRuntime(deopt_id(), 1325 compiler->GenerateCallRuntime(deopt_id(),
1309 token_pos(), 1326 token_pos(),
1310 try_index(), 1327 try_index(),
1311 kCloneContextRuntimeEntry); 1328 kCloneContextRuntimeEntry,
1329 locs()->stack_bitmap());
1312 __ popq(result); // Remove argument. 1330 __ popq(result); // Remove argument.
1313 __ popq(result); // Get result (cloned context). 1331 __ popq(result); // Get result (cloned context).
1314 } 1332 }
1315 1333
1316 1334
1317 LocationSummary* CatchEntryComp::MakeLocationSummary() const { 1335 LocationSummary* CatchEntryComp::MakeLocationSummary() const {
1318 return LocationSummary::Make(0, 1336 return LocationSummary::Make(0,
1319 Location::NoLocation(), 1337 Location::NoLocation(),
1320 LocationSummary::kNoCall); 1338 LocationSummary::kNoCall);
1321 } 1339 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1375 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1358 Register temp = locs()->temp(0).reg(); 1376 Register temp = locs()->temp(0).reg();
1359 // Generate stack overflow check. 1377 // Generate stack overflow check.
1360 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address())); 1378 __ movq(temp, Immediate(Isolate::Current()->stack_limit_address()));
1361 __ cmpq(RSP, Address(temp, 0)); 1379 __ cmpq(RSP, Address(temp, 0));
1362 Label no_stack_overflow; 1380 Label no_stack_overflow;
1363 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); 1381 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
1364 compiler->GenerateCallRuntime(deopt_id(), 1382 compiler->GenerateCallRuntime(deopt_id(),
1365 token_pos(), 1383 token_pos(),
1366 try_index(), 1384 try_index(),
1367 kStackOverflowRuntimeEntry); 1385 kStackOverflowRuntimeEntry,
1386 locs()->stack_bitmap());
1368 __ Bind(&no_stack_overflow); 1387 __ Bind(&no_stack_overflow);
1369 } 1388 }
1370 1389
1371 1390
1372 LocationSummary* BinaryOpComp::MakeLocationSummary() const { 1391 LocationSummary* BinaryOpComp::MakeLocationSummary() const {
1373 const intptr_t kNumInputs = 2; 1392 const intptr_t kNumInputs = 2;
1374 1393
1375 // Double operation are handled in DoubleBinaryOpComp. 1394 // Double operation are handled in DoubleBinaryOpComp.
1376 ASSERT(operands_type() != kDoubleOperands); 1395 ASSERT(operands_type() != kDoubleOperands);
1377 1396
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1542 __ shlq(left, right_temp); 1561 __ shlq(left, right_temp);
1543 __ jmp(&done); 1562 __ jmp(&done);
1544 { 1563 {
1545 __ Bind(&call_method); 1564 __ Bind(&call_method);
1546 Function& target = Function::ZoneHandle( 1565 Function& target = Function::ZoneHandle(
1547 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid)); 1566 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid));
1548 ASSERT(!target.IsNull()); 1567 ASSERT(!target.IsNull());
1549 const intptr_t kArgumentCount = 2; 1568 const intptr_t kArgumentCount = 2;
1550 __ pushq(temp); 1569 __ pushq(temp);
1551 __ pushq(right); 1570 __ pushq(right);
1552 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), 1571 compiler->GenerateStaticCall(
1553 comp->instance_call()->token_pos(), 1572 comp->instance_call()->deopt_id(),
1554 comp->instance_call()->try_index(), 1573 comp->instance_call()->token_pos(),
1555 target, 1574 comp->instance_call()->try_index(),
1556 kArgumentCount, 1575 target,
1557 Array::Handle()); // No argument names. 1576 kArgumentCount,
1577 Array::Handle(), // No argument names.
1578 comp->locs()->stack_bitmap());
1558 ASSERT(result == RAX); 1579 ASSERT(result == RAX);
1559 } 1580 }
1560 __ Bind(&done); 1581 __ Bind(&done);
1561 break; 1582 break;
1562 } 1583 }
1563 case Token::kDIV: { 1584 case Token::kDIV: {
1564 // Dispatches to 'Double./'. 1585 // Dispatches to 'Double./'.
1565 // TODO(srdjan): Implement as conversion to double and double division. 1586 // TODO(srdjan): Implement as conversion to double and double division.
1566 UNREACHABLE(); 1587 UNREACHABLE();
1567 break; 1588 break;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1635 1656
1636 __ Bind(&smi_static_call); 1657 __ Bind(&smi_static_call);
1637 { 1658 {
1638 Function& target = Function::ZoneHandle( 1659 Function& target = Function::ZoneHandle(
1639 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid)); 1660 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid));
1640 if (target.IsNull()) { 1661 if (target.IsNull()) {
1641 __ jmp(deopt); 1662 __ jmp(deopt);
1642 } else { 1663 } else {
1643 __ pushq(left); 1664 __ pushq(left);
1644 __ pushq(right); 1665 __ pushq(right);
1645 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), 1666 compiler->GenerateStaticCall(
1646 comp->instance_call()->token_pos(), 1667 comp->instance_call()->deopt_id(),
1647 comp->instance_call()->try_index(), 1668 comp->instance_call()->token_pos(),
1648 target, 1669 comp->instance_call()->try_index(),
1649 comp->instance_call()->ArgumentCount(), 1670 target,
1650 comp->instance_call()->argument_names()); 1671 comp->instance_call()->ArgumentCount(),
1672 comp->instance_call()->argument_names(),
1673 comp->locs()->stack_bitmap());
1651 ASSERT(result == RAX); 1674 ASSERT(result == RAX);
1652 __ jmp(&done); 1675 __ jmp(&done);
1653 } 1676 }
1654 } 1677 }
1655 1678
1656 __ Bind(&mint_static_call); 1679 __ Bind(&mint_static_call);
1657 { 1680 {
1658 Function& target = Function::ZoneHandle( 1681 Function& target = Function::ZoneHandle(
1659 comp->ic_data()->GetTargetForReceiverClassId(kMintCid)); 1682 comp->ic_data()->GetTargetForReceiverClassId(kMintCid));
1660 if (target.IsNull()) { 1683 if (target.IsNull()) {
1661 __ jmp(deopt); 1684 __ jmp(deopt);
1662 } else { 1685 } else {
1663 __ pushq(left); 1686 __ pushq(left);
1664 __ pushq(right); 1687 __ pushq(right);
1665 compiler->GenerateStaticCall(comp->instance_call()->deopt_id(), 1688 compiler->GenerateStaticCall(
1666 comp->instance_call()->token_pos(), 1689 comp->instance_call()->deopt_id(),
1667 comp->instance_call()->try_index(), 1690 comp->instance_call()->token_pos(),
1668 target, 1691 comp->instance_call()->try_index(),
1669 comp->instance_call()->ArgumentCount(), 1692 target,
1670 comp->instance_call()->argument_names()); 1693 comp->instance_call()->ArgumentCount(),
1694 comp->instance_call()->argument_names(),
1695 comp->locs()->stack_bitmap());
1671 ASSERT(result == RAX); 1696 ASSERT(result == RAX);
1672 } 1697 }
1673 } 1698 }
1674 __ Bind(&done); 1699 __ Bind(&done);
1675 } 1700 }
1676 1701
1677 1702
1678 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1703 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1679 switch (operands_type()) { 1704 switch (operands_type()) {
1680 case kSmiOperands: 1705 case kSmiOperands:
(...skipping 21 matching lines...) Expand all
1702 Register temp = RDX; 1727 Register temp = RDX;
1703 Register result = locs()->out().reg(); 1728 Register result = locs()->out().reg();
1704 1729
1705 const Class& double_class = compiler->double_class(); 1730 const Class& double_class = compiler->double_class();
1706 const Code& stub = 1731 const Code& stub =
1707 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1732 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1708 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1733 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1709 compiler->GenerateCall(instance_call()->token_pos(), 1734 compiler->GenerateCall(instance_call()->token_pos(),
1710 instance_call()->try_index(), 1735 instance_call()->try_index(),
1711 &label, 1736 &label,
1712 PcDescriptors::kOther); 1737 PcDescriptors::kOther,
1738 locs()->stack_bitmap());
1713 // Newly allocated object is now in the result register (RAX). 1739 // Newly allocated object is now in the result register (RAX).
1714 ASSERT(result == RAX); 1740 ASSERT(result == RAX);
1715 __ popq(right); 1741 __ popq(right);
1716 __ popq(left); 1742 __ popq(left);
1717 1743
1718 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1744 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1719 instance_call()->try_index(), 1745 instance_call()->try_index(),
1720 kDeoptDoubleBinaryOp, 1746 kDeoptDoubleBinaryOp,
1721 left, 1747 left,
1722 right); 1748 right);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1829 __ j(NOT_EQUAL, deopt); 1855 __ j(NOT_EQUAL, deopt);
1830 // Allocate result object. 1856 // Allocate result object.
1831 const Class& double_class = compiler->double_class(); 1857 const Class& double_class = compiler->double_class();
1832 const Code& stub = 1858 const Code& stub =
1833 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1859 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1834 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1860 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1835 __ pushq(value); 1861 __ pushq(value);
1836 compiler->GenerateCall(instance_call()->token_pos(), 1862 compiler->GenerateCall(instance_call()->token_pos(),
1837 instance_call()->try_index(), 1863 instance_call()->try_index(),
1838 &label, 1864 &label,
1839 PcDescriptors::kOther); 1865 PcDescriptors::kOther,
1866 instance_call()->locs()->stack_bitmap());
1840 // Result is in RAX. 1867 // Result is in RAX.
1841 ASSERT(result != temp); 1868 ASSERT(result != temp);
1842 __ movq(result, RAX); 1869 __ movq(result, RAX);
1843 __ popq(temp); 1870 __ popq(temp);
1844 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); 1871 __ movsd(XMM0, FieldAddress(temp, Double::value_offset()));
1845 __ DoubleNegate(XMM0); 1872 __ DoubleNegate(XMM0);
1846 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 1873 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
1847 } else { 1874 } else {
1848 UNREACHABLE(); 1875 UNREACHABLE();
1849 } 1876 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1890 1917
1891 const Class& double_class = compiler->double_class(); 1918 const Class& double_class = compiler->double_class();
1892 const Code& stub = 1919 const Code& stub =
1893 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1920 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1894 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1921 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1895 1922
1896 // TODO(vegorov): allocate box in the driver loop to avoid spilling. 1923 // TODO(vegorov): allocate box in the driver loop to avoid spilling.
1897 compiler->GenerateCall(instance_call()->token_pos(), 1924 compiler->GenerateCall(instance_call()->token_pos(),
1898 instance_call()->try_index(), 1925 instance_call()->try_index(),
1899 &label, 1926 &label,
1900 PcDescriptors::kOther); 1927 PcDescriptors::kOther,
1928 locs()->stack_bitmap());
1901 ASSERT(result == RAX); 1929 ASSERT(result == RAX);
1902 __ popq(value); 1930 __ popq(value);
1903 1931
1904 __ testq(value, Immediate(kSmiTagMask)); 1932 __ testq(value, Immediate(kSmiTagMask));
1905 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. 1933 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi.
1906 __ SmiUntag(value); 1934 __ SmiUntag(value);
1907 __ cvtsi2sd(XMM0, value); 1935 __ cvtsi2sd(XMM0, value);
1908 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 1936 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
1909 } 1937 }
1910 1938
(...skipping 25 matching lines...) Expand all
1936 Label done; 1964 Label done;
1937 __ LoadClassId(RDI, RAX); 1965 __ LoadClassId(RDI, RAX);
1938 compiler->EmitTestAndCall(*ic_data(), 1966 compiler->EmitTestAndCall(*ic_data(),
1939 RDI, // Class id register. 1967 RDI, // Class id register.
1940 instance_call()->ArgumentCount(), 1968 instance_call()->ArgumentCount(),
1941 instance_call()->argument_names(), 1969 instance_call()->argument_names(),
1942 deopt, 1970 deopt,
1943 (is_smi_label == &handle_smi) ? &done : NULL, 1971 (is_smi_label == &handle_smi) ? &done : NULL,
1944 instance_call()->deopt_id(), 1972 instance_call()->deopt_id(),
1945 instance_call()->token_pos(), 1973 instance_call()->token_pos(),
1946 instance_call()->try_index()); 1974 instance_call()->try_index(),
1975 locs()->stack_bitmap());
1947 if (is_smi_label == &handle_smi) { 1976 if (is_smi_label == &handle_smi) {
1948 __ Bind(&handle_smi); 1977 __ Bind(&handle_smi);
1949 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmiCid); 1978 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmiCid);
1950 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); 1979 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0));
1951 compiler->GenerateStaticCall(instance_call()->deopt_id(), 1980 compiler->GenerateStaticCall(instance_call()->deopt_id(),
1952 instance_call()->token_pos(), 1981 instance_call()->token_pos(),
1953 instance_call()->try_index(), 1982 instance_call()->try_index(),
1954 target, 1983 target,
1955 instance_call()->ArgumentCount(), 1984 instance_call()->ArgumentCount(),
1956 instance_call()->argument_names()); 1985 instance_call()->argument_names(),
1986 locs()->stack_bitmap());
1957 } 1987 }
1958 __ Bind(&done); 1988 __ Bind(&done);
1959 } 1989 }
1960 1990
1961 1991
1962 // TODO(srdjan): Move to shared. 1992 // TODO(srdjan): Move to shared.
1963 static bool ICDataWithBothClassIds(const ICData& ic_data, intptr_t class_id) { 1993 static bool ICDataWithBothClassIds(const ICData& ic_data, intptr_t class_id) {
1964 if (ic_data.num_args_tested() != 2) return false; 1994 if (ic_data.num_args_tested() != 2) return false;
1965 if (ic_data.NumberOfChecks() != 1) return false; 1995 if (ic_data.NumberOfChecks() != 1) return false;
1966 Function& target = Function::Handle(); 1996 Function& target = Function::Handle();
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2048 token_pos(), 2078 token_pos(),
2049 try_index()); 2079 try_index());
2050 const intptr_t kNumArguments = 2; 2080 const intptr_t kNumArguments = 2;
2051 const intptr_t kNumArgsChecked = 2; // Type-feedback. 2081 const intptr_t kNumArgsChecked = 2; // Type-feedback.
2052 compiler->GenerateInstanceCall(deopt_id(), 2082 compiler->GenerateInstanceCall(deopt_id(),
2053 token_pos(), 2083 token_pos(),
2054 try_index(), 2084 try_index(),
2055 function_name, 2085 function_name,
2056 kNumArguments, 2086 kNumArguments,
2057 Array::ZoneHandle(), // No optional arguments. 2087 Array::ZoneHandle(), // No optional arguments.
2058 kNumArgsChecked); 2088 kNumArgsChecked,
2089 locs()->stack_bitmap());
2059 ASSERT(locs()->out().reg() == RAX); 2090 ASSERT(locs()->out().reg() == RAX);
2060 __ CompareObject(locs()->out().reg(), compiler->bool_true()); 2091 __ CompareObject(locs()->out().reg(), compiler->bool_true());
2061 EmitBranchOnCondition(compiler, branch_condition); 2092 EmitBranchOnCondition(compiler, branch_condition);
2062 } 2093 }
2063 2094
2064 } // namespace dart 2095 } // namespace dart
2065 2096
2066 #undef __ 2097 #undef __
2067 2098
2068 #endif // defined TARGET_ARCH_X64 2099 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698