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

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

Issue 10873027: Use the location summary to represent safepoint information. (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
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 __ CompareObject(obj, compiler->bool_true()); 217 __ CompareObject(obj, compiler->bool_true());
218 __ j(EQUAL, &done, Assembler::kNearJump); 218 __ j(EQUAL, &done, Assembler::kNearJump);
219 __ CompareObject(obj, compiler->bool_false()); 219 __ CompareObject(obj, compiler->bool_false());
220 __ j(EQUAL, &done, Assembler::kNearJump); 220 __ j(EQUAL, &done, Assembler::kNearJump);
221 221
222 __ pushq(obj); // Push the source object. 222 __ pushq(obj); // Push the source object.
223 compiler->GenerateCallRuntime(deopt_id(), 223 compiler->GenerateCallRuntime(deopt_id(),
224 token_pos(), 224 token_pos(),
225 try_index(), 225 try_index(),
226 kConditionTypeErrorRuntimeEntry, 226 kConditionTypeErrorRuntimeEntry,
227 locs()->stack_bitmap()); 227 locs());
228 // We should never return here. 228 // We should never return here.
229 __ int3(); 229 __ int3();
230 __ Bind(&done); 230 __ Bind(&done);
231 } 231 }
232 ASSERT(obj == result); 232 ASSERT(obj == result);
233 } 233 }
234 234
235 235
236 static Condition TokenKindToSmiCondition(Token::Kind kind) { 236 static Condition TokenKindToSmiCondition(Token::Kind kind) {
237 switch (kind) { 237 switch (kind) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 locs->set_out(Location::RegisterLocation(RAX)); 282 locs->set_out(Location::RegisterLocation(RAX));
283 return locs; 283 return locs;
284 } 284 }
285 285
286 286
287 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, 287 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
288 intptr_t deopt_id, 288 intptr_t deopt_id,
289 intptr_t token_pos, 289 intptr_t token_pos,
290 intptr_t try_index, 290 intptr_t try_index,
291 Token::Kind kind, 291 Token::Kind kind,
292 const LocationSummary& locs) { 292 LocationSummary* locs) {
293 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 293 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
294 deopt_id, 294 deopt_id,
295 token_pos, 295 token_pos,
296 try_index); 296 try_index);
297 const String& operator_name = String::ZoneHandle(Symbols::New("==")); 297 const String& operator_name = String::ZoneHandle(Symbols::New("=="));
298 const int kNumberOfArguments = 2; 298 const int kNumberOfArguments = 2;
299 const Array& kNoArgumentNames = Array::Handle(); 299 const Array& kNoArgumentNames = Array::Handle();
300 const int kNumArgumentsChecked = 2; 300 const int kNumArgumentsChecked = 2;
301 301
302 Label done, false_label, true_label; 302 Label done, false_label, true_label;
303 Register left = locs.in(0).reg(); 303 Register left = locs->in(0).reg();
304 Register right = locs.in(1).reg(); 304 Register right = locs->in(1).reg();
305 __ popq(right); 305 __ popq(right);
306 __ popq(left); 306 __ popq(left);
307 const Immediate raw_null = 307 const Immediate raw_null =
308 Immediate(reinterpret_cast<intptr_t>(Object::null())); 308 Immediate(reinterpret_cast<intptr_t>(Object::null()));
309 Label check_identity, instance_call; 309 Label check_identity, instance_call;
310 __ cmpq(right, raw_null); 310 __ cmpq(right, raw_null);
311 __ j(EQUAL, &check_identity, Assembler::kNearJump); 311 __ j(EQUAL, &check_identity, Assembler::kNearJump);
312 __ cmpq(left, raw_null); 312 __ cmpq(left, raw_null);
313 __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump); 313 __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump);
314 314
(...skipping 14 matching lines...) Expand all
329 __ Bind(&instance_call); 329 __ Bind(&instance_call);
330 __ pushq(left); 330 __ pushq(left);
331 __ pushq(right); 331 __ pushq(right);
332 compiler->GenerateInstanceCall(deopt_id, 332 compiler->GenerateInstanceCall(deopt_id,
333 token_pos, 333 token_pos,
334 try_index, 334 try_index,
335 operator_name, 335 operator_name,
336 kNumberOfArguments, 336 kNumberOfArguments,
337 kNoArgumentNames, 337 kNoArgumentNames,
338 kNumArgumentsChecked, 338 kNumArgumentsChecked,
339 locs.stack_bitmap()); 339 locs);
340 if (kind == Token::kNE) { 340 if (kind == Token::kNE) {
341 // Negate the condition: true label returns false and vice versa. 341 // Negate the condition: true label returns false and vice versa.
342 __ CompareObject(RAX, compiler->bool_true()); 342 __ CompareObject(RAX, compiler->bool_true());
343 __ j(EQUAL, &true_label, Assembler::kNearJump); 343 __ j(EQUAL, &true_label, Assembler::kNearJump);
344 __ Bind(&false_label); 344 __ Bind(&false_label);
345 __ LoadObject(RAX, compiler->bool_true()); 345 __ LoadObject(RAX, compiler->bool_true());
346 __ jmp(&done, Assembler::kNearJump); 346 __ jmp(&done, Assembler::kNearJump);
347 __ Bind(&true_label); 347 __ Bind(&true_label);
348 __ LoadObject(RAX, compiler->bool_false()); 348 __ LoadObject(RAX, compiler->bool_false());
349 } 349 }
350 __ Bind(&done); 350 __ Bind(&done);
351 } 351 }
352 352
353 353
354 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, 354 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
355 const ICData& orig_ic_data, 355 const ICData& orig_ic_data,
356 const LocationSummary& locs, 356 LocationSummary* locs,
357 BranchInstr* branch, 357 BranchInstr* branch,
358 Token::Kind kind, 358 Token::Kind kind,
359 intptr_t deopt_id, 359 intptr_t deopt_id,
360 intptr_t token_pos, 360 intptr_t token_pos,
361 intptr_t try_index, 361 intptr_t try_index) {
362 BitmapBuilder* stack_bitmap) {
363 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 362 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
364 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); 363 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
365 ASSERT(ic_data.NumberOfChecks() > 0); 364 ASSERT(ic_data.NumberOfChecks() > 0);
366 ASSERT(ic_data.num_args_tested() == 1); 365 ASSERT(ic_data.num_args_tested() == 1);
367 Label* deopt = compiler->AddDeoptStub(deopt_id, try_index, kDeoptEquality); 366 Label* deopt = compiler->AddDeoptStub(deopt_id, try_index, kDeoptEquality);
368 Register left = locs.in(0).reg(); 367 Register left = locs->in(0).reg();
369 Register right = locs.in(1).reg(); 368 Register right = locs->in(1).reg();
370 __ testq(left, Immediate(kSmiTagMask)); 369 __ testq(left, Immediate(kSmiTagMask));
371 Register temp = locs.temp(0).reg(); 370 Register temp = locs->temp(0).reg();
372 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) { 371 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) {
373 Label done, load_class_id; 372 Label done, load_class_id;
374 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump); 373 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump);
375 __ movq(temp, Immediate(kSmiCid)); 374 __ movq(temp, Immediate(kSmiCid));
376 __ jmp(&done, Assembler::kNearJump); 375 __ jmp(&done, Assembler::kNearJump);
377 __ Bind(&load_class_id); 376 __ Bind(&load_class_id);
378 __ LoadClassId(temp, left); 377 __ LoadClassId(temp, left);
379 __ Bind(&done); 378 __ Bind(&done);
380 } else { 379 } else {
381 __ j(ZERO, deopt); // Smi deopts. 380 __ j(ZERO, deopt); // Smi deopts.
(...skipping 11 matching lines...) Expand all
393 __ j(NOT_EQUAL, &next_test); 392 __ j(NOT_EQUAL, &next_test);
394 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); 393 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i));
395 if (target.Owner() == object_store->object_class()) { 394 if (target.Owner() == object_store->object_class()) {
396 // Object.== is same as ===. 395 // Object.== is same as ===.
397 __ Drop(2); 396 __ Drop(2);
398 __ cmpq(left, right); 397 __ cmpq(left, right);
399 if (branch != NULL) { 398 if (branch != NULL) {
400 branch->EmitBranchOnCondition(compiler, cond); 399 branch->EmitBranchOnCondition(compiler, cond);
401 } else { 400 } else {
402 // This case should be rare. 401 // This case should be rare.
403 Register result = locs.out().reg(); 402 Register result = locs->out().reg();
404 Label load_true; 403 Label load_true;
405 __ j(cond, &load_true, Assembler::kNearJump); 404 __ j(cond, &load_true, Assembler::kNearJump);
406 __ LoadObject(result, compiler->bool_false()); 405 __ LoadObject(result, compiler->bool_false());
407 __ jmp(&done); 406 __ jmp(&done);
408 __ Bind(&load_true); 407 __ Bind(&load_true);
409 __ LoadObject(result, compiler->bool_true()); 408 __ LoadObject(result, compiler->bool_true());
410 } 409 }
411 } else { 410 } else {
412 const int kNumberOfArguments = 2; 411 const int kNumberOfArguments = 2;
413 const Array& kNoArgumentNames = Array::Handle(); 412 const Array& kNoArgumentNames = Array::Handle();
414 compiler->GenerateStaticCall(deopt_id, 413 compiler->GenerateStaticCall(deopt_id,
415 token_pos, 414 token_pos,
416 try_index, 415 try_index,
417 target, 416 target,
418 kNumberOfArguments, 417 kNumberOfArguments,
419 kNoArgumentNames, 418 kNoArgumentNames,
420 stack_bitmap); 419 locs);
421 if (branch == NULL) { 420 if (branch == NULL) {
422 if (kind == Token::kNE) { 421 if (kind == Token::kNE) {
423 Label false_label; 422 Label false_label;
424 __ CompareObject(RAX, compiler->bool_true()); 423 __ CompareObject(RAX, compiler->bool_true());
425 __ j(EQUAL, &false_label, Assembler::kNearJump); 424 __ j(EQUAL, &false_label, Assembler::kNearJump);
426 __ LoadObject(RAX, compiler->bool_true()); 425 __ LoadObject(RAX, compiler->bool_true());
427 __ jmp(&done); 426 __ jmp(&done);
428 __ Bind(&false_label); 427 __ Bind(&false_label);
429 __ LoadObject(RAX, compiler->bool_false()); 428 __ LoadObject(RAX, compiler->bool_false());
430 __ jmp(&done); 429 __ jmp(&done);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 Condition cond = TokenKindToSmiCondition(kind); 496 Condition cond = TokenKindToSmiCondition(kind);
498 branch->EmitBranchOnCondition(compiler, cond); 497 branch->EmitBranchOnCondition(compiler, cond);
499 } 498 }
500 } 499 }
501 500
502 501
503 // First test if receiver is NULL, in which case === is applied. 502 // First test if receiver is NULL, in which case === is applied.
504 // If type feedback was provided (lists of <class-id, target>), do a 503 // If type feedback was provided (lists of <class-id, target>), do a
505 // type by type check (either === or static call to the operator. 504 // type by type check (either === or static call to the operator.
506 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler, 505 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler,
507 const LocationSummary& locs, 506 LocationSummary* locs,
508 Token::Kind kind, 507 Token::Kind kind,
509 BranchInstr* branch, 508 BranchInstr* branch,
510 const ICData& ic_data, 509 const ICData& ic_data,
511 intptr_t deopt_id, 510 intptr_t deopt_id,
512 intptr_t token_pos, 511 intptr_t token_pos,
513 intptr_t try_index) { 512 intptr_t try_index) {
514 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 513 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
515 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); 514 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
516 Register left = locs.in(0).reg(); 515 Register left = locs->in(0).reg();
517 Register right = locs.in(1).reg(); 516 Register right = locs->in(1).reg();
518 const Immediate raw_null = 517 const Immediate raw_null =
519 Immediate(reinterpret_cast<intptr_t>(Object::null())); 518 Immediate(reinterpret_cast<intptr_t>(Object::null()));
520 Label done, identity_compare, non_null_compare; 519 Label done, identity_compare, non_null_compare;
521 __ cmpq(right, raw_null); 520 __ cmpq(right, raw_null);
522 __ j(EQUAL, &identity_compare, Assembler::kNearJump); 521 __ j(EQUAL, &identity_compare, Assembler::kNearJump);
523 __ cmpq(left, raw_null); 522 __ cmpq(left, raw_null);
524 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); 523 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump);
525 // Comparison with NULL is "===". 524 // Comparison with NULL is "===".
526 __ Bind(&identity_compare); 525 __ Bind(&identity_compare);
527 __ cmpq(left, right); 526 __ cmpq(left, right);
528 Condition cond = TokenKindToSmiCondition(kind); 527 Condition cond = TokenKindToSmiCondition(kind);
529 if (branch != NULL) { 528 if (branch != NULL) {
530 branch->EmitBranchOnCondition(compiler, cond); 529 branch->EmitBranchOnCondition(compiler, cond);
531 } else { 530 } else {
532 Register result = locs.out().reg(); 531 Register result = locs->out().reg();
533 Label load_true; 532 Label load_true;
534 __ j(cond, &load_true, Assembler::kNearJump); 533 __ j(cond, &load_true, Assembler::kNearJump);
535 __ LoadObject(result, compiler->bool_false()); 534 __ LoadObject(result, compiler->bool_false());
536 __ jmp(&done); 535 __ jmp(&done);
537 __ Bind(&load_true); 536 __ Bind(&load_true);
538 __ LoadObject(result, compiler->bool_true()); 537 __ LoadObject(result, compiler->bool_true());
539 } 538 }
540 __ jmp(&done); 539 __ jmp(&done);
541 __ Bind(&non_null_compare); // Receiver is not null. 540 __ Bind(&non_null_compare); // Receiver is not null.
542 __ pushq(left); 541 __ pushq(left);
543 __ pushq(right); 542 __ pushq(right);
544 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 543 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
545 deopt_id, token_pos, try_index, 544 deopt_id, token_pos, try_index);
546 locs.stack_bitmap());
547 __ Bind(&done); 545 __ Bind(&done);
548 } 546 }
549 547
550 548
551 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 549 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
552 const LocationSummary& locs, 550 const LocationSummary& locs,
553 Token::Kind kind, 551 Token::Kind kind,
554 BranchInstr* branch, 552 BranchInstr* branch,
555 intptr_t deopt_id, 553 intptr_t deopt_id,
556 intptr_t token_pos, 554 intptr_t token_pos,
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 return; 645 return;
648 } 646 }
649 const bool is_checked_strict_equal = 647 const bool is_checked_strict_equal =
650 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 648 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
651 if (is_checked_strict_equal) { 649 if (is_checked_strict_equal) {
652 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), NULL, 650 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), NULL,
653 deopt_id(), token_pos(), try_index()); 651 deopt_id(), token_pos(), try_index());
654 return; 652 return;
655 } 653 }
656 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 654 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
657 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(), 655 EmitGenericEqualityCompare(compiler, locs(), kind(), NULL, *ic_data(),
658 deopt_id(), token_pos(), try_index()); 656 deopt_id(), token_pos(), try_index());
659 } else { 657 } else {
660 Register left = locs()->in(0).reg(); 658 Register left = locs()->in(0).reg();
661 Register right = locs()->in(1).reg(); 659 Register right = locs()->in(1).reg();
662 __ pushq(left); 660 __ pushq(left);
663 __ pushq(right); 661 __ pushq(right);
664 EmitEqualityAsInstanceCall(compiler, 662 EmitEqualityAsInstanceCall(compiler,
665 deopt_id(), 663 deopt_id(),
666 token_pos(), 664 token_pos(),
667 try_index(), 665 try_index(),
668 kind(), 666 kind(),
669 *locs()); 667 locs());
670 ASSERT(locs()->out().reg() == RAX); 668 ASSERT(locs()->out().reg() == RAX);
671 } 669 }
672 } 670 }
673 671
674 672
675 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 673 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
676 const intptr_t kNumInputs = 2; 674 const intptr_t kNumInputs = 2;
677 if (operands_class_id() == kSmiCid || operands_class_id() == kDoubleCid) { 675 if (operands_class_id() == kSmiCid || operands_class_id() == kDoubleCid) {
678 const intptr_t kNumTemps = 1; 676 const intptr_t kNumTemps = 1;
679 LocationSummary* summary = 677 LocationSummary* summary =
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 const intptr_t kNumArguments = 2; 729 const intptr_t kNumArguments = 2;
732 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), 730 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
733 RDI, // Class id register. 731 RDI, // Class id register.
734 kNumArguments, 732 kNumArguments,
735 Array::Handle(), // No named arguments. 733 Array::Handle(), // No named arguments.
736 deopt, // Deoptimize target. 734 deopt, // Deoptimize target.
737 NULL, // Fallthrough when done. 735 NULL, // Fallthrough when done.
738 deopt_id(), 736 deopt_id(),
739 token_pos(), 737 token_pos(),
740 try_index(), 738 try_index(),
741 locs()->stack_bitmap()); 739 locs());
742 ASSERT(locs()->out().reg() == RAX); 740 ASSERT(locs()->out().reg() == RAX);
743 return; 741 return;
744 } 742 }
745 const String& function_name = 743 const String& function_name =
746 String::ZoneHandle(Symbols::New(Token::Str(kind()))); 744 String::ZoneHandle(Symbols::New(Token::Str(kind())));
747 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 745 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
748 deopt_id(), 746 deopt_id(),
749 token_pos(), 747 token_pos(),
750 try_index()); 748 try_index());
751 const intptr_t kNumArguments = 2; 749 const intptr_t kNumArguments = 2;
752 const intptr_t kNumArgsChecked = 2; // Type-feedback. 750 const intptr_t kNumArgsChecked = 2; // Type-feedback.
753 compiler->GenerateInstanceCall(deopt_id(), 751 compiler->GenerateInstanceCall(deopt_id(),
754 token_pos(), 752 token_pos(),
755 try_index(), 753 try_index(),
756 function_name, 754 function_name,
757 kNumArguments, 755 kNumArguments,
758 Array::ZoneHandle(), // No optional arguments. 756 Array::ZoneHandle(), // No optional arguments.
759 kNumArgsChecked, 757 kNumArgsChecked,
760 locs()->stack_bitmap()); 758 locs());
761 ASSERT(locs()->out().reg() == RAX); 759 ASSERT(locs()->out().reg() == RAX);
762 } 760 }
763 761
764 762
765 LocationSummary* NativeCallComp::MakeLocationSummary() const { 763 LocationSummary* NativeCallComp::MakeLocationSummary() const {
766 const intptr_t kNumInputs = 0; 764 const intptr_t kNumInputs = 0;
767 const intptr_t kNumTemps = 3; 765 const intptr_t kNumTemps = 3;
768 LocationSummary* locs = 766 LocationSummary* locs =
769 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 767 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
770 locs->set_temp(0, Location::RegisterLocation(RAX)); 768 locs->set_temp(0, Location::RegisterLocation(RAX));
(...skipping 22 matching lines...) Expand all
793 } else { 791 } else {
794 __ leaq(RAX, 792 __ leaq(RAX,
795 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); 793 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize));
796 } 794 }
797 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); 795 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function())));
798 __ movq(R10, Immediate(arg_count)); 796 __ movq(R10, Immediate(arg_count));
799 compiler->GenerateCall(token_pos(), 797 compiler->GenerateCall(token_pos(),
800 try_index(), 798 try_index(),
801 &StubCode::CallNativeCFunctionLabel(), 799 &StubCode::CallNativeCFunctionLabel(),
802 PcDescriptors::kOther, 800 PcDescriptors::kOther,
803 locs()->stack_bitmap()); 801 locs());
804 __ popq(result); 802 __ popq(result);
805 } 803 }
806 804
807 805
808 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { 806 LocationSummary* LoadIndexedComp::MakeLocationSummary() const {
809 const intptr_t kNumInputs = 2; 807 const intptr_t kNumInputs = 2;
810 if (receiver_type() == kGrowableObjectArrayCid) { 808 if (receiver_type() == kGrowableObjectArrayCid) {
811 const intptr_t kNumTemps = 1; 809 const intptr_t kNumTemps = 1;
812 LocationSummary* locs = 810 LocationSummary* locs =
813 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 811 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1008 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1006 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1009 ASSERT(locs()->in(0).reg() == RAX); // Value. 1007 ASSERT(locs()->in(0).reg() == RAX); // Value.
1010 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. 1008 ASSERT(locs()->in(1).reg() == RCX); // Instantiator.
1011 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. 1009 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments.
1012 1010
1013 compiler->GenerateInstanceOf(deopt_id(), 1011 compiler->GenerateInstanceOf(deopt_id(),
1014 token_pos(), 1012 token_pos(),
1015 try_index(), 1013 try_index(),
1016 type(), 1014 type(),
1017 negate_result(), 1015 negate_result(),
1018 locs()->stack_bitmap()); 1016 locs());
1019 ASSERT(locs()->out().reg() == RAX); 1017 ASSERT(locs()->out().reg() == RAX);
1020 } 1018 }
1021 1019
1022 1020
1023 LocationSummary* CreateArrayComp::MakeLocationSummary() const { 1021 LocationSummary* CreateArrayComp::MakeLocationSummary() const {
1024 const intptr_t kNumInputs = 1; 1022 const intptr_t kNumInputs = 1;
1025 const intptr_t kNumTemps = 0; 1023 const intptr_t kNumTemps = 0;
1026 LocationSummary* locs = 1024 LocationSummary* locs =
1027 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1025 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1028 locs->set_in(0, Location::RegisterLocation(RBX)); 1026 locs->set_in(0, Location::RegisterLocation(RBX));
1029 locs->set_out(Location::RegisterLocation(RAX)); 1027 locs->set_out(Location::RegisterLocation(RAX));
1030 return locs; 1028 return locs;
1031 } 1029 }
1032 1030
1033 1031
1034 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1032 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1035 // Allocate the array. R10 = length, RBX = element type. 1033 // Allocate the array. R10 = length, RBX = element type.
1036 ASSERT(locs()->in(0).reg() == RBX); 1034 ASSERT(locs()->in(0).reg() == RBX);
1037 __ movq(R10, Immediate(Smi::RawValue(ArgumentCount()))); 1035 __ movq(R10, Immediate(Smi::RawValue(ArgumentCount())));
1038 compiler->GenerateCall(token_pos(), 1036 compiler->GenerateCall(token_pos(),
1039 try_index(), 1037 try_index(),
1040 &StubCode::AllocateArrayLabel(), 1038 &StubCode::AllocateArrayLabel(),
1041 PcDescriptors::kOther, 1039 PcDescriptors::kOther,
1042 locs()->stack_bitmap()); 1040 locs());
1043 ASSERT(locs()->out().reg() == RAX); 1041 ASSERT(locs()->out().reg() == RAX);
1044 1042
1045 // Pop the element values from the stack into the array. 1043 // Pop the element values from the stack into the array.
1046 __ leaq(R10, FieldAddress(RAX, Array::data_offset())); 1044 __ leaq(R10, FieldAddress(RAX, Array::data_offset()));
1047 for (int i = ArgumentCount() - 1; i >= 0; --i) { 1045 for (int i = ArgumentCount() - 1; i >= 0; --i) {
1048 ASSERT(ArgumentAt(i)->value()->IsUse()); 1046 ASSERT(ArgumentAt(i)->value()->IsUse());
1049 __ popq(Address(R10, i * kWordSize)); 1047 __ popq(Address(R10, i * kWordSize));
1050 } 1048 }
1051 } 1049 }
1052 1050
(...skipping 20 matching lines...) Expand all
1073 1071
1074 // Push the result place holder initialized to NULL. 1072 // Push the result place holder initialized to NULL.
1075 __ PushObject(Object::ZoneHandle()); 1073 __ PushObject(Object::ZoneHandle());
1076 __ PushObject(cls); 1074 __ PushObject(cls);
1077 __ pushq(type_arguments); 1075 __ pushq(type_arguments);
1078 __ pushq(instantiator_type_arguments); 1076 __ pushq(instantiator_type_arguments);
1079 compiler->GenerateCallRuntime(deopt_id(), 1077 compiler->GenerateCallRuntime(deopt_id(),
1080 token_pos(), 1078 token_pos(),
1081 try_index(), 1079 try_index(),
1082 kAllocateObjectWithBoundsCheckRuntimeEntry, 1080 kAllocateObjectWithBoundsCheckRuntimeEntry,
1083 locs()->stack_bitmap()); 1081 locs());
1084 // Pop instantiator type arguments, type arguments, and class. 1082 // Pop instantiator type arguments, type arguments, and class.
1085 __ Drop(3); 1083 __ Drop(3);
1086 __ popq(result); // Pop new instance. 1084 __ popq(result); // Pop new instance.
1087 } 1085 }
1088 1086
1089 1087
1090 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { 1088 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const {
1091 return LocationSummary::Make(1, 1089 return LocationSummary::Make(1,
1092 Location::RequiresRegister(), 1090 Location::RequiresRegister(),
1093 LocationSummary::kNoCall); 1091 LocationSummary::kNoCall);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 __ Bind(&type_arguments_uninstantiated); 1156 __ Bind(&type_arguments_uninstantiated);
1159 } 1157 }
1160 // A runtime call to instantiate the type arguments is required. 1158 // A runtime call to instantiate the type arguments is required.
1161 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1159 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1162 __ PushObject(type_arguments()); 1160 __ PushObject(type_arguments());
1163 __ pushq(instantiator_reg); // Push instantiator type arguments. 1161 __ pushq(instantiator_reg); // Push instantiator type arguments.
1164 compiler->GenerateCallRuntime(deopt_id(), 1162 compiler->GenerateCallRuntime(deopt_id(),
1165 token_pos(), 1163 token_pos(),
1166 try_index(), 1164 try_index(),
1167 kInstantiateTypeArgumentsRuntimeEntry, 1165 kInstantiateTypeArgumentsRuntimeEntry,
1168 locs()->stack_bitmap()); 1166 locs());
1169 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 1167 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1170 __ popq(result_reg); // Pop instantiated type arguments. 1168 __ popq(result_reg); // Pop instantiated type arguments.
1171 __ Bind(&type_arguments_instantiated); 1169 __ Bind(&type_arguments_instantiated);
1172 ASSERT(instantiator_reg == result_reg); 1170 ASSERT(instantiator_reg == result_reg);
1173 // 'result_reg': Instantiated type arguments. 1171 // 'result_reg': Instantiated type arguments.
1174 } 1172 }
1175 1173
1176 1174
1177 LocationSummary* 1175 LocationSummary*
1178 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const { 1176 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1311 ASSERT(locs()->temp(0).reg() == R10); 1309 ASSERT(locs()->temp(0).reg() == R10);
1312 ASSERT(locs()->out().reg() == RAX); 1310 ASSERT(locs()->out().reg() == RAX);
1313 1311
1314 __ movq(R10, Immediate(num_context_variables())); 1312 __ movq(R10, Immediate(num_context_variables()));
1315 const ExternalLabel label("alloc_context", 1313 const ExternalLabel label("alloc_context",
1316 StubCode::AllocateContextEntryPoint()); 1314 StubCode::AllocateContextEntryPoint());
1317 compiler->GenerateCall(token_pos(), 1315 compiler->GenerateCall(token_pos(),
1318 try_index(), 1316 try_index(),
1319 &label, 1317 &label,
1320 PcDescriptors::kOther, 1318 PcDescriptors::kOther,
1321 locs()->stack_bitmap()); 1319 locs());
1322 } 1320 }
1323 1321
1324 1322
1325 LocationSummary* CloneContextComp::MakeLocationSummary() const { 1323 LocationSummary* CloneContextComp::MakeLocationSummary() const {
1326 const intptr_t kNumInputs = 1; 1324 const intptr_t kNumInputs = 1;
1327 const intptr_t kNumTemps = 0; 1325 const intptr_t kNumTemps = 0;
1328 LocationSummary* locs = 1326 LocationSummary* locs =
1329 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1327 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1330 locs->set_in(0, Location::RegisterLocation(RAX)); 1328 locs->set_in(0, Location::RegisterLocation(RAX));
1331 locs->set_out(Location::RegisterLocation(RAX)); 1329 locs->set_out(Location::RegisterLocation(RAX));
1332 return locs; 1330 return locs;
1333 } 1331 }
1334 1332
1335 1333
1336 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1334 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1337 Register context_value = locs()->in(0).reg(); 1335 Register context_value = locs()->in(0).reg();
1338 Register result = locs()->out().reg(); 1336 Register result = locs()->out().reg();
1339 1337
1340 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1338 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1341 __ pushq(context_value); 1339 __ pushq(context_value);
1342 compiler->GenerateCallRuntime(deopt_id(), 1340 compiler->GenerateCallRuntime(deopt_id(),
1343 token_pos(), 1341 token_pos(),
1344 try_index(), 1342 try_index(),
1345 kCloneContextRuntimeEntry, 1343 kCloneContextRuntimeEntry,
1346 locs()->stack_bitmap()); 1344 locs());
1347 __ popq(result); // Remove argument. 1345 __ popq(result); // Remove argument.
1348 __ popq(result); // Get result (cloned context). 1346 __ popq(result); // Get result (cloned context).
1349 } 1347 }
1350 1348
1351 1349
1352 LocationSummary* CatchEntryComp::MakeLocationSummary() const { 1350 LocationSummary* CatchEntryComp::MakeLocationSummary() const {
1353 return LocationSummary::Make(0, 1351 return LocationSummary::Make(0,
1354 Location::NoLocation(), 1352 Location::NoLocation(),
1355 LocationSummary::kNoCall); 1353 LocationSummary::kNoCall);
1356 } 1354 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1393 explicit CheckStackOverflowSlowPath(CheckStackOverflowComp* computation) 1391 explicit CheckStackOverflowSlowPath(CheckStackOverflowComp* computation)
1394 : computation_(computation) { } 1392 : computation_(computation) { }
1395 1393
1396 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1394 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1397 __ Bind(entry_label()); 1395 __ Bind(entry_label());
1398 compiler->SaveLiveRegisters(computation_->locs()); 1396 compiler->SaveLiveRegisters(computation_->locs());
1399 compiler->GenerateCallRuntime(computation_->deopt_id(), 1397 compiler->GenerateCallRuntime(computation_->deopt_id(),
1400 computation_->token_pos(), 1398 computation_->token_pos(),
1401 computation_->try_index(), 1399 computation_->try_index(),
1402 kStackOverflowRuntimeEntry, 1400 kStackOverflowRuntimeEntry,
1403 computation_->locs()->stack_bitmap()); 1401 computation_->locs());
1404 compiler->RestoreLiveRegisters(computation_->locs()); 1402 compiler->RestoreLiveRegisters(computation_->locs());
1405 __ jmp(exit_label()); 1403 __ jmp(exit_label());
1406 } 1404 }
1407 1405
1408 private: 1406 private:
1409 CheckStackOverflowComp* computation_; 1407 CheckStackOverflowComp* computation_;
1410 }; 1408 };
1411 1409
1412 1410
1413 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1411 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1586 const intptr_t kArgumentCount = 2; 1584 const intptr_t kArgumentCount = 2;
1587 __ pushq(temp); 1585 __ pushq(temp);
1588 __ pushq(right); 1586 __ pushq(right);
1589 compiler->GenerateStaticCall( 1587 compiler->GenerateStaticCall(
1590 instance_call()->deopt_id(), 1588 instance_call()->deopt_id(),
1591 instance_call()->token_pos(), 1589 instance_call()->token_pos(),
1592 instance_call()->try_index(), 1590 instance_call()->try_index(),
1593 target, 1591 target,
1594 kArgumentCount, 1592 kArgumentCount,
1595 Array::Handle(), // No argument names. 1593 Array::Handle(), // No argument names.
1596 locs()->stack_bitmap()); 1594 locs());
1597 ASSERT(result == RAX); 1595 ASSERT(result == RAX);
1598 } 1596 }
1599 __ Bind(&done); 1597 __ Bind(&done);
1600 break; 1598 break;
1601 } 1599 }
1602 case Token::kDIV: { 1600 case Token::kDIV: {
1603 // Dispatches to 'Double./'. 1601 // Dispatches to 'Double./'.
1604 // TODO(srdjan): Implement as conversion to double and double division. 1602 // TODO(srdjan): Implement as conversion to double and double division.
1605 UNREACHABLE(); 1603 UNREACHABLE();
1606 break; 1604 break;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1692 } else { 1690 } else {
1693 __ pushq(left); 1691 __ pushq(left);
1694 __ pushq(right); 1692 __ pushq(right);
1695 compiler->GenerateStaticCall( 1693 compiler->GenerateStaticCall(
1696 instance_call()->deopt_id(), 1694 instance_call()->deopt_id(),
1697 instance_call()->token_pos(), 1695 instance_call()->token_pos(),
1698 instance_call()->try_index(), 1696 instance_call()->try_index(),
1699 target, 1697 target,
1700 instance_call()->ArgumentCount(), 1698 instance_call()->ArgumentCount(),
1701 instance_call()->argument_names(), 1699 instance_call()->argument_names(),
1702 locs()->stack_bitmap()); 1700 locs());
1703 ASSERT(result == RAX); 1701 ASSERT(result == RAX);
1704 __ jmp(&done); 1702 __ jmp(&done);
1705 } 1703 }
1706 } 1704 }
1707 1705
1708 __ Bind(&mint_static_call); 1706 __ Bind(&mint_static_call);
1709 { 1707 {
1710 Function& target = Function::ZoneHandle( 1708 Function& target = Function::ZoneHandle(
1711 ic_data()->GetTargetForReceiverClassId(kMintCid)); 1709 ic_data()->GetTargetForReceiverClassId(kMintCid));
1712 if (target.IsNull()) { 1710 if (target.IsNull()) {
1713 __ jmp(deopt); 1711 __ jmp(deopt);
1714 } else { 1712 } else {
1715 __ pushq(left); 1713 __ pushq(left);
1716 __ pushq(right); 1714 __ pushq(right);
1717 compiler->GenerateStaticCall( 1715 compiler->GenerateStaticCall(
1718 instance_call()->deopt_id(), 1716 instance_call()->deopt_id(),
1719 instance_call()->token_pos(), 1717 instance_call()->token_pos(),
1720 instance_call()->try_index(), 1718 instance_call()->try_index(),
1721 target, 1719 target,
1722 instance_call()->ArgumentCount(), 1720 instance_call()->ArgumentCount(),
1723 instance_call()->argument_names(), 1721 instance_call()->argument_names(),
1724 locs()->stack_bitmap()); 1722 locs());
1725 ASSERT(result == RAX); 1723 ASSERT(result == RAX);
1726 } 1724 }
1727 } 1725 }
1728 __ Bind(&done); 1726 __ Bind(&done);
1729 } 1727 }
1730 1728
1731 1729
1732 LocationSummary* BinaryDoubleOpComp::MakeLocationSummary() const { 1730 LocationSummary* BinaryDoubleOpComp::MakeLocationSummary() const {
1733 return MakeCallSummary(); // Calls into a stub for allocation. 1731 return MakeCallSummary(); // Calls into a stub for allocation.
1734 } 1732 }
1735 1733
1736 1734
1737 void BinaryDoubleOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1735 void BinaryDoubleOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1738 Register left = RBX; 1736 Register left = RBX;
1739 Register right = RCX; 1737 Register right = RCX;
1740 Register temp = RDX; 1738 Register temp = RDX;
1741 Register result = locs()->out().reg(); 1739 Register result = locs()->out().reg();
1742 1740
1743 const Class& double_class = compiler->double_class(); 1741 const Class& double_class = compiler->double_class();
1744 const Code& stub = 1742 const Code& stub =
1745 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1743 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1746 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1744 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1747 compiler->GenerateCall(instance_call()->token_pos(), 1745 compiler->GenerateCall(instance_call()->token_pos(),
1748 instance_call()->try_index(), 1746 instance_call()->try_index(),
1749 &label, 1747 &label,
1750 PcDescriptors::kOther, 1748 PcDescriptors::kOther,
1751 locs()->stack_bitmap()); 1749 locs());
1752 // Newly allocated object is now in the result register (RAX). 1750 // Newly allocated object is now in the result register (RAX).
1753 ASSERT(result == RAX); 1751 ASSERT(result == RAX);
1754 __ movq(right, Address(RSP, 0)); 1752 __ movq(right, Address(RSP, 0));
1755 __ movq(left, Address(RSP, kWordSize)); 1753 __ movq(left, Address(RSP, kWordSize));
1756 1754
1757 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1755 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1758 instance_call()->try_index(), 1756 instance_call()->try_index(),
1759 kDeoptBinaryDoubleOp); 1757 kDeoptBinaryDoubleOp);
1760 1758
1761 // Binary operation of two Smi's produces a Smi not a double. 1759 // Binary operation of two Smi's produces a Smi not a double.
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1867 // Allocate result object. 1865 // Allocate result object.
1868 const Class& double_class = compiler->double_class(); 1866 const Class& double_class = compiler->double_class();
1869 const Code& stub = 1867 const Code& stub =
1870 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1868 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1871 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1869 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1872 __ pushq(value); 1870 __ pushq(value);
1873 compiler->GenerateCall(instance_call()->token_pos(), 1871 compiler->GenerateCall(instance_call()->token_pos(),
1874 instance_call()->try_index(), 1872 instance_call()->try_index(),
1875 &label, 1873 &label,
1876 PcDescriptors::kOther, 1874 PcDescriptors::kOther,
1877 instance_call()->locs()->stack_bitmap()); 1875 instance_call()->locs());
1878 // Result is in RAX. 1876 // Result is in RAX.
1879 ASSERT(result != temp); 1877 ASSERT(result != temp);
1880 __ movq(result, RAX); 1878 __ movq(result, RAX);
1881 __ popq(temp); 1879 __ popq(temp);
1882 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); 1880 __ movsd(XMM0, FieldAddress(temp, Double::value_offset()));
1883 __ DoubleNegate(XMM0); 1881 __ DoubleNegate(XMM0);
1884 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 1882 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
1885 } else { 1883 } else {
1886 UNREACHABLE(); 1884 UNREACHABLE();
1887 } 1885 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1932 const Code& stub = 1930 const Code& stub =
1933 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1931 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1934 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1932 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1935 1933
1936 // TODO(fschneider): Inline new-space allocation and move the call into 1934 // TODO(fschneider): Inline new-space allocation and move the call into
1937 // deferred code. 1935 // deferred code.
1938 compiler->GenerateCall(instance_call()->token_pos(), 1936 compiler->GenerateCall(instance_call()->token_pos(),
1939 instance_call()->try_index(), 1937 instance_call()->try_index(),
1940 &label, 1938 &label,
1941 PcDescriptors::kOther, 1939 PcDescriptors::kOther,
1942 locs()->stack_bitmap()); 1940 locs());
1943 ASSERT(result == RAX); 1941 ASSERT(result == RAX);
1944 Register value = RBX; 1942 Register value = RBX;
1945 // Preserve argument on the stack until after the deoptimization point. 1943 // Preserve argument on the stack until after the deoptimization point.
1946 __ movq(value, Address(RSP, 0)); 1944 __ movq(value, Address(RSP, 0));
1947 1945
1948 __ testq(value, Immediate(kSmiTagMask)); 1946 __ testq(value, Immediate(kSmiTagMask));
1949 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. 1947 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi.
1950 __ SmiUntag(value); 1948 __ SmiUntag(value);
1951 __ cvtsi2sd(XMM0, value); 1949 __ cvtsi2sd(XMM0, value);
1952 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 1950 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
(...skipping 29 matching lines...) Expand all
1982 __ LoadClassId(RDI, RAX); 1980 __ LoadClassId(RDI, RAX);
1983 compiler->EmitTestAndCall(*ic_data(), 1981 compiler->EmitTestAndCall(*ic_data(),
1984 RDI, // Class id register. 1982 RDI, // Class id register.
1985 instance_call()->ArgumentCount(), 1983 instance_call()->ArgumentCount(),
1986 instance_call()->argument_names(), 1984 instance_call()->argument_names(),
1987 deopt, 1985 deopt,
1988 (is_smi_label == &handle_smi) ? &done : NULL, 1986 (is_smi_label == &handle_smi) ? &done : NULL,
1989 instance_call()->deopt_id(), 1987 instance_call()->deopt_id(),
1990 instance_call()->token_pos(), 1988 instance_call()->token_pos(),
1991 instance_call()->try_index(), 1989 instance_call()->try_index(),
1992 locs()->stack_bitmap()); 1990 locs());
1993 if (is_smi_label == &handle_smi) { 1991 if (is_smi_label == &handle_smi) {
1994 __ Bind(&handle_smi); 1992 __ Bind(&handle_smi);
1995 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmiCid); 1993 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmiCid);
1996 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); 1994 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0));
1997 compiler->GenerateStaticCall(instance_call()->deopt_id(), 1995 compiler->GenerateStaticCall(instance_call()->deopt_id(),
1998 instance_call()->token_pos(), 1996 instance_call()->token_pos(),
1999 instance_call()->try_index(), 1997 instance_call()->try_index(),
2000 target, 1998 target,
2001 instance_call()->ArgumentCount(), 1999 instance_call()->ArgumentCount(),
2002 instance_call()->argument_names(), 2000 instance_call()->argument_names(),
2003 locs()->stack_bitmap()); 2001 locs());
2004 } 2002 }
2005 __ Bind(&done); 2003 __ Bind(&done);
2006 } 2004 }
2007 2005
2008 2006
2009 // TODO(srdjan): Move to shared. 2007 // TODO(srdjan): Move to shared.
2010 static bool ICDataWithBothClassIds(const ICData& ic_data, intptr_t class_id) { 2008 static bool ICDataWithBothClassIds(const ICData& ic_data, intptr_t class_id) {
2011 if (ic_data.num_args_tested() != 2) return false; 2009 if (ic_data.num_args_tested() != 2) return false;
2012 if (ic_data.NumberOfChecks() != 1) return false; 2010 if (ic_data.NumberOfChecks() != 1) return false;
2013 Function& target = Function::Handle(); 2011 Function& target = Function::Handle();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2092 deopt_id(), token_pos(), try_index()); 2090 deopt_id(), token_pos(), try_index());
2093 return; 2091 return;
2094 } 2092 }
2095 if (IsCheckedStrictEquals(*ic_data(), kind())) { 2093 if (IsCheckedStrictEquals(*ic_data(), kind())) {
2096 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), this, 2094 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), this,
2097 deopt_id(), token_pos(), try_index()); 2095 deopt_id(), token_pos(), try_index());
2098 return; 2096 return;
2099 } 2097 }
2100 // TODO(srdjan): Add Smi/Double, Double/Smi comparisons. 2098 // TODO(srdjan): Add Smi/Double, Double/Smi comparisons.
2101 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { 2099 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) {
2102 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(), 2100 EmitGenericEqualityCompare(compiler, locs(), kind(), this, *ic_data(),
2103 deopt_id(), token_pos(), try_index()); 2101 deopt_id(), token_pos(), try_index());
2104 return; 2102 return;
2105 } 2103 }
2106 // Otherwise polymorphic dispatch? 2104 // Otherwise polymorphic dispatch?
2107 } 2105 }
2108 Register left = locs()->in(0).reg(); 2106 Register left = locs()->in(0).reg();
2109 Register right = locs()->in(1).reg(); 2107 Register right = locs()->in(1).reg();
2110 __ pushq(left); 2108 __ pushq(left);
2111 __ pushq(right); 2109 __ pushq(right);
2112 if ((kind() == Token::kNE) || (kind() == Token::kEQ)) { 2110 if ((kind() == Token::kNE) || (kind() == Token::kEQ)) {
2113 EmitEqualityAsInstanceCall(compiler, 2111 EmitEqualityAsInstanceCall(compiler,
2114 deopt_id(), 2112 deopt_id(),
2115 token_pos(), 2113 token_pos(),
2116 try_index(), 2114 try_index(),
2117 Token::kEQ, // kNE reverse occurs at branch. 2115 Token::kEQ, // kNE reverse occurs at branch.
2118 *locs()); 2116 locs());
2119 } else { 2117 } else {
2120 const String& function_name = 2118 const String& function_name =
2121 String::ZoneHandle(Symbols::New(Token::Str(kind()))); 2119 String::ZoneHandle(Symbols::New(Token::Str(kind())));
2122 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 2120 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
2123 deopt_id(), 2121 deopt_id(),
2124 token_pos(), 2122 token_pos(),
2125 try_index()); 2123 try_index());
2126 const intptr_t kNumArguments = 2; 2124 const intptr_t kNumArguments = 2;
2127 const intptr_t kNumArgsChecked = 2; // Type-feedback. 2125 const intptr_t kNumArgsChecked = 2; // Type-feedback.
2128 compiler->GenerateInstanceCall(deopt_id(), 2126 compiler->GenerateInstanceCall(deopt_id(),
2129 token_pos(), 2127 token_pos(),
2130 try_index(), 2128 try_index(),
2131 function_name, 2129 function_name,
2132 kNumArguments, 2130 kNumArguments,
2133 Array::ZoneHandle(), // No optional args. 2131 Array::ZoneHandle(), // No optional args.
2134 kNumArgsChecked, 2132 kNumArgsChecked,
2135 locs()->stack_bitmap()); 2133 locs());
2136 } 2134 }
2137 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 2135 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
2138 __ CompareObject(RAX, compiler->bool_true()); 2136 __ CompareObject(RAX, compiler->bool_true());
2139 EmitBranchOnCondition(compiler, branch_condition); 2137 EmitBranchOnCondition(compiler, branch_condition);
2140 } 2138 }
2141 2139
2142 2140
2143 LocationSummary* CheckClassComp::MakeLocationSummary() const { 2141 LocationSummary* CheckClassComp::MakeLocationSummary() const {
2144 const intptr_t kNumInputs = 1; 2142 const intptr_t kNumInputs = 1;
2145 const intptr_t kNumTemps = 1; 2143 const intptr_t kNumTemps = 1;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2205 __ testq(value, Immediate(kSmiTagMask)); 2203 __ testq(value, Immediate(kSmiTagMask));
2206 __ j(NOT_ZERO, deopt); 2204 __ j(NOT_ZERO, deopt);
2207 } 2205 }
2208 2206
2209 2207
2210 } // namespace dart 2208 } // namespace dart
2211 2209
2212 #undef __ 2210 #undef __
2213 2211
2214 #endif // defined TARGET_ARCH_X64 2212 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698