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

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

Issue 10892037: Stop attaching try_index to individual instructions put it at block entry instead. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address Srdjan's comment, make meaning of CatchTryIndex clear Created 8 years, 3 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_test.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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 } 80 }
81 } 81 }
82 if (FLAG_trace_functions) { 82 if (FLAG_trace_functions) {
83 const Function& function = 83 const Function& function =
84 Function::ZoneHandle(compiler->parsed_function().function().raw()); 84 Function::ZoneHandle(compiler->parsed_function().function().raw());
85 __ LoadObject(temp, function); 85 __ LoadObject(temp, function);
86 __ pushq(result); // Preserve result. 86 __ pushq(result); // Preserve result.
87 __ pushq(temp); 87 __ pushq(temp);
88 compiler->GenerateCallRuntime(Isolate::kNoDeoptId, 88 compiler->GenerateCallRuntime(Isolate::kNoDeoptId,
89 0, 89 0,
90 CatchClauseNode::kInvalidTryIndex,
91 kTraceFunctionExitRuntimeEntry, 90 kTraceFunctionExitRuntimeEntry,
92 NULL); 91 NULL);
93 __ popq(temp); // Remove argument. 92 __ popq(temp); // Remove argument.
94 __ popq(result); // Restore result. 93 __ popq(result); // Restore result.
95 } 94 }
96 #if defined(DEBUG) 95 #if defined(DEBUG)
97 // TODO(srdjan): Fix for functions with finally clause. 96 // TODO(srdjan): Fix for functions with finally clause.
98 // A finally clause may leave a previously pushed return value if it 97 // A finally clause may leave a previously pushed return value if it
99 // has its own return instruction. Method that have finally are currently 98 // has its own return instruction. Method that have finally are currently
100 // not optimized. 99 // not optimized.
(...skipping 17 matching lines...) Expand all
118 __ nop(1); 117 __ nop(1);
119 __ nop(1); 118 __ nop(1);
120 __ nop(1); 119 __ nop(1);
121 __ nop(1); 120 __ nop(1);
122 __ nop(1); 121 __ nop(1);
123 __ nop(1); 122 __ nop(1);
124 __ nop(1); 123 __ nop(1);
125 __ nop(1); 124 __ nop(1);
126 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 125 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
127 deopt_id(), 126 deopt_id(),
128 token_pos(), 127 token_pos());
129 CatchClauseNode::kInvalidTryIndex);
130 } 128 }
131 129
132 130
133 LocationSummary* ClosureCallComp::MakeLocationSummary() const { 131 LocationSummary* ClosureCallComp::MakeLocationSummary() const {
134 const intptr_t kNumInputs = 0; 132 const intptr_t kNumInputs = 0;
135 const intptr_t kNumTemps = 1; 133 const intptr_t kNumTemps = 1;
136 LocationSummary* result = 134 LocationSummary* result =
137 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 135 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
138 result->set_out(Location::RegisterLocation(RAX)); 136 result->set_out(Location::RegisterLocation(RAX));
139 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. 137 result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 // Call the runtime if the object is not bool::true or bool::false. 213 // Call the runtime if the object is not bool::true or bool::false.
216 Label done; 214 Label done;
217 __ CompareObject(obj, compiler->bool_true()); 215 __ CompareObject(obj, compiler->bool_true());
218 __ j(EQUAL, &done, Assembler::kNearJump); 216 __ j(EQUAL, &done, Assembler::kNearJump);
219 __ CompareObject(obj, compiler->bool_false()); 217 __ CompareObject(obj, compiler->bool_false());
220 __ j(EQUAL, &done, Assembler::kNearJump); 218 __ j(EQUAL, &done, Assembler::kNearJump);
221 219
222 __ pushq(obj); // Push the source object. 220 __ pushq(obj); // Push the source object.
223 compiler->GenerateCallRuntime(deopt_id(), 221 compiler->GenerateCallRuntime(deopt_id(),
224 token_pos(), 222 token_pos(),
225 try_index(),
226 kConditionTypeErrorRuntimeEntry, 223 kConditionTypeErrorRuntimeEntry,
227 locs()); 224 locs());
228 // We should never return here. 225 // We should never return here.
229 __ int3(); 226 __ int3();
230 __ Bind(&done); 227 __ Bind(&done);
231 } 228 }
232 ASSERT(obj == result); 229 ASSERT(obj == result);
233 } 230 }
234 231
235 232
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 locs->set_in(0, Location::RegisterLocation(RCX)); 277 locs->set_in(0, Location::RegisterLocation(RCX));
281 locs->set_in(1, Location::RegisterLocation(RDX)); 278 locs->set_in(1, Location::RegisterLocation(RDX));
282 locs->set_out(Location::RegisterLocation(RAX)); 279 locs->set_out(Location::RegisterLocation(RAX));
283 return locs; 280 return locs;
284 } 281 }
285 282
286 283
287 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, 284 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
288 intptr_t deopt_id, 285 intptr_t deopt_id,
289 intptr_t token_pos, 286 intptr_t token_pos,
290 intptr_t try_index,
291 Token::Kind kind, 287 Token::Kind kind,
292 LocationSummary* locs) { 288 LocationSummary* locs) {
293 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 289 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
294 deopt_id, 290 deopt_id,
295 token_pos, 291 token_pos);
296 try_index);
297 const String& operator_name = String::ZoneHandle(Symbols::New("==")); 292 const String& operator_name = String::ZoneHandle(Symbols::New("=="));
298 const int kNumberOfArguments = 2; 293 const int kNumberOfArguments = 2;
299 const Array& kNoArgumentNames = Array::Handle(); 294 const Array& kNoArgumentNames = Array::Handle();
300 const int kNumArgumentsChecked = 2; 295 const int kNumArgumentsChecked = 2;
301 296
302 Label done, false_label, true_label; 297 Label done, false_label, true_label;
303 Register left = locs->in(0).reg(); 298 Register left = locs->in(0).reg();
304 Register right = locs->in(1).reg(); 299 Register right = locs->in(1).reg();
305 __ popq(right); 300 __ popq(right);
306 __ popq(left); 301 __ popq(left);
(...skipping 17 matching lines...) Expand all
324 } else { 319 } else {
325 ASSERT(kind == Token::kNE); 320 ASSERT(kind == Token::kNE);
326 __ jmp(&false_label); 321 __ jmp(&false_label);
327 } 322 }
328 323
329 __ Bind(&instance_call); 324 __ Bind(&instance_call);
330 __ pushq(left); 325 __ pushq(left);
331 __ pushq(right); 326 __ pushq(right);
332 compiler->GenerateInstanceCall(deopt_id, 327 compiler->GenerateInstanceCall(deopt_id,
333 token_pos, 328 token_pos,
334 try_index,
335 operator_name, 329 operator_name,
336 kNumberOfArguments, 330 kNumberOfArguments,
337 kNoArgumentNames, 331 kNoArgumentNames,
338 kNumArgumentsChecked, 332 kNumArgumentsChecked,
339 locs); 333 locs);
340 if (kind == Token::kNE) { 334 if (kind == Token::kNE) {
341 // Negate the condition: true label returns false and vice versa. 335 // Negate the condition: true label returns false and vice versa.
342 __ CompareObject(RAX, compiler->bool_true()); 336 __ CompareObject(RAX, compiler->bool_true());
343 __ j(EQUAL, &true_label, Assembler::kNearJump); 337 __ j(EQUAL, &true_label, Assembler::kNearJump);
344 __ Bind(&false_label); 338 __ Bind(&false_label);
345 __ LoadObject(RAX, compiler->bool_true()); 339 __ LoadObject(RAX, compiler->bool_true());
346 __ jmp(&done, Assembler::kNearJump); 340 __ jmp(&done, Assembler::kNearJump);
347 __ Bind(&true_label); 341 __ Bind(&true_label);
348 __ LoadObject(RAX, compiler->bool_false()); 342 __ LoadObject(RAX, compiler->bool_false());
349 } 343 }
350 __ Bind(&done); 344 __ Bind(&done);
351 } 345 }
352 346
353 347
354 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, 348 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
355 const ICData& orig_ic_data, 349 const ICData& orig_ic_data,
356 LocationSummary* locs, 350 LocationSummary* locs,
357 BranchInstr* branch, 351 BranchInstr* branch,
358 Token::Kind kind, 352 Token::Kind kind,
359 intptr_t deopt_id, 353 intptr_t deopt_id,
360 intptr_t token_pos, 354 intptr_t token_pos) {
361 intptr_t try_index) {
362 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 355 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
363 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); 356 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
364 ASSERT(ic_data.NumberOfChecks() > 0); 357 ASSERT(ic_data.NumberOfChecks() > 0);
365 ASSERT(ic_data.num_args_tested() == 1); 358 ASSERT(ic_data.num_args_tested() == 1);
366 Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality); 359 Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality);
367 Register left = locs->in(0).reg(); 360 Register left = locs->in(0).reg();
368 Register right = locs->in(1).reg(); 361 Register right = locs->in(1).reg();
369 __ testq(left, Immediate(kSmiTagMask)); 362 __ testq(left, Immediate(kSmiTagMask));
370 Register temp = locs->temp(0).reg(); 363 Register temp = locs->temp(0).reg();
371 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) { 364 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 __ LoadObject(result, compiler->bool_false()); 398 __ LoadObject(result, compiler->bool_false());
406 __ jmp(&done); 399 __ jmp(&done);
407 __ Bind(&load_true); 400 __ Bind(&load_true);
408 __ LoadObject(result, compiler->bool_true()); 401 __ LoadObject(result, compiler->bool_true());
409 } 402 }
410 } else { 403 } else {
411 const int kNumberOfArguments = 2; 404 const int kNumberOfArguments = 2;
412 const Array& kNoArgumentNames = Array::Handle(); 405 const Array& kNoArgumentNames = Array::Handle();
413 compiler->GenerateStaticCall(deopt_id, 406 compiler->GenerateStaticCall(deopt_id,
414 token_pos, 407 token_pos,
415 try_index,
416 target, 408 target,
417 kNumberOfArguments, 409 kNumberOfArguments,
418 kNoArgumentNames, 410 kNoArgumentNames,
419 locs); 411 locs);
420 if (branch == NULL) { 412 if (branch == NULL) {
421 if (kind == Token::kNE) { 413 if (kind == Token::kNE) {
422 Label false_label; 414 Label false_label;
423 __ CompareObject(RAX, compiler->bool_true()); 415 __ CompareObject(RAX, compiler->bool_true());
424 __ j(EQUAL, &false_label, Assembler::kNearJump); 416 __ j(EQUAL, &false_label, Assembler::kNearJump);
425 __ LoadObject(RAX, compiler->bool_true()); 417 __ LoadObject(RAX, compiler->bool_true());
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 489
498 // First test if receiver is NULL, in which case === is applied. 490 // First test if receiver is NULL, in which case === is applied.
499 // If type feedback was provided (lists of <class-id, target>), do a 491 // If type feedback was provided (lists of <class-id, target>), do a
500 // type by type check (either === or static call to the operator. 492 // type by type check (either === or static call to the operator.
501 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler, 493 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler,
502 LocationSummary* locs, 494 LocationSummary* locs,
503 Token::Kind kind, 495 Token::Kind kind,
504 BranchInstr* branch, 496 BranchInstr* branch,
505 const ICData& ic_data, 497 const ICData& ic_data,
506 intptr_t deopt_id, 498 intptr_t deopt_id,
507 intptr_t token_pos, 499 intptr_t token_pos) {
508 intptr_t try_index) {
509 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 500 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
510 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); 501 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
511 Register left = locs->in(0).reg(); 502 Register left = locs->in(0).reg();
512 Register right = locs->in(1).reg(); 503 Register right = locs->in(1).reg();
513 const Immediate raw_null = 504 const Immediate raw_null =
514 Immediate(reinterpret_cast<intptr_t>(Object::null())); 505 Immediate(reinterpret_cast<intptr_t>(Object::null()));
515 Label done, identity_compare, non_null_compare; 506 Label done, identity_compare, non_null_compare;
516 __ cmpq(right, raw_null); 507 __ cmpq(right, raw_null);
517 __ j(EQUAL, &identity_compare, Assembler::kNearJump); 508 __ j(EQUAL, &identity_compare, Assembler::kNearJump);
518 __ cmpq(left, raw_null); 509 __ cmpq(left, raw_null);
(...skipping 11 matching lines...) Expand all
530 __ LoadObject(result, compiler->bool_false()); 521 __ LoadObject(result, compiler->bool_false());
531 __ jmp(&done); 522 __ jmp(&done);
532 __ Bind(&load_true); 523 __ Bind(&load_true);
533 __ LoadObject(result, compiler->bool_true()); 524 __ LoadObject(result, compiler->bool_true());
534 } 525 }
535 __ jmp(&done); 526 __ jmp(&done);
536 __ Bind(&non_null_compare); // Receiver is not null. 527 __ Bind(&non_null_compare); // Receiver is not null.
537 __ pushq(left); 528 __ pushq(left);
538 __ pushq(right); 529 __ pushq(right);
539 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 530 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
540 deopt_id, token_pos, try_index); 531 deopt_id, token_pos);
541 __ Bind(&done); 532 __ Bind(&done);
542 } 533 }
543 534
544 535
545 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 536 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
546 const LocationSummary& locs, 537 const LocationSummary& locs,
547 Token::Kind kind, 538 Token::Kind kind,
548 BranchInstr* branch, 539 BranchInstr* branch,
549 intptr_t deopt_id) { 540 intptr_t deopt_id) {
550 Register left = locs.in(0).reg(); 541 Register left = locs.in(0).reg();
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 } 626 }
636 const bool is_checked_strict_equal = 627 const bool is_checked_strict_equal =
637 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 628 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
638 if (is_checked_strict_equal) { 629 if (is_checked_strict_equal) {
639 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch, 630 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch,
640 deopt_id()); 631 deopt_id());
641 return; 632 return;
642 } 633 }
643 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 634 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
644 EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(), 635 EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(),
645 deopt_id(), token_pos(), try_index()); 636 deopt_id(), token_pos());
646 return; 637 return;
647 } 638 }
648 Register left = locs()->in(0).reg(); 639 Register left = locs()->in(0).reg();
649 Register right = locs()->in(1).reg(); 640 Register right = locs()->in(1).reg();
650 __ pushq(left); 641 __ pushq(left);
651 __ pushq(right); 642 __ pushq(right);
652 EmitEqualityAsInstanceCall(compiler, 643 EmitEqualityAsInstanceCall(compiler,
653 deopt_id(), 644 deopt_id(),
654 token_pos(), 645 token_pos(),
655 try_index(),
656 kind(), 646 kind(),
657 locs()); 647 locs());
658 ASSERT(locs()->out().reg() == RAX); 648 ASSERT(locs()->out().reg() == RAX);
659 } 649 }
660 650
661 651
662 void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler, 652 void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler,
663 BranchInstr* branch) { 653 BranchInstr* branch) {
664 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 654 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
665 if (receiver_class_id() == kSmiCid) { 655 if (receiver_class_id() == kSmiCid) {
666 // Deoptimizes if both arguments not Smi. 656 // Deoptimizes if both arguments not Smi.
667 EmitSmiComparisonOp(compiler, *locs(), kind(), branch, deopt_id()); 657 EmitSmiComparisonOp(compiler, *locs(), kind(), branch, deopt_id());
668 return; 658 return;
669 } 659 }
670 if (receiver_class_id() == kDoubleCid) { 660 if (receiver_class_id() == kDoubleCid) {
671 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. 661 // Deoptimizes if both arguments are Smi, or if none is Double or Smi.
672 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch, deopt_id()); 662 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch, deopt_id());
673 return; 663 return;
674 } 664 }
675 const bool is_checked_strict_equal = 665 const bool is_checked_strict_equal =
676 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 666 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
677 if (is_checked_strict_equal) { 667 if (is_checked_strict_equal) {
678 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, 668 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch,
679 deopt_id()); 669 deopt_id());
680 return; 670 return;
681 } 671 }
682 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 672 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
683 EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(), 673 EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(),
684 deopt_id(), token_pos(), try_index()); 674 deopt_id(), token_pos());
685 return; 675 return;
686 } 676 }
687 Register left = locs()->in(0).reg(); 677 Register left = locs()->in(0).reg();
688 Register right = locs()->in(1).reg(); 678 Register right = locs()->in(1).reg();
689 __ pushq(left); 679 __ pushq(left);
690 __ pushq(right); 680 __ pushq(right);
691 EmitEqualityAsInstanceCall(compiler, 681 EmitEqualityAsInstanceCall(compiler,
692 deopt_id(), 682 deopt_id(),
693 token_pos(), 683 token_pos(),
694 try_index(),
695 Token::kEQ, // kNE reverse occurs at branch. 684 Token::kEQ, // kNE reverse occurs at branch.
696 locs()); 685 locs());
697 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 686 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
698 __ CompareObject(RAX, compiler->bool_true()); 687 __ CompareObject(RAX, compiler->bool_true());
699 branch->EmitBranchOnCondition(compiler, branch_condition); 688 branch->EmitBranchOnCondition(compiler, branch_condition);
700 } 689 }
701 690
702 691
703 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 692 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
704 const intptr_t kNumInputs = 2; 693 const intptr_t kNumInputs = 2;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 __ LoadClassId(RDI, left); 742 __ LoadClassId(RDI, left);
754 __ Bind(&done); 743 __ Bind(&done);
755 const intptr_t kNumArguments = 2; 744 const intptr_t kNumArguments = 2;
756 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), 745 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
757 RDI, // Class id register. 746 RDI, // Class id register.
758 kNumArguments, 747 kNumArguments,
759 Array::Handle(), // No named arguments. 748 Array::Handle(), // No named arguments.
760 deopt, // Deoptimize target. 749 deopt, // Deoptimize target.
761 deopt_id(), 750 deopt_id(),
762 token_pos(), 751 token_pos(),
763 try_index(),
764 locs()); 752 locs());
765 return; 753 return;
766 } 754 }
767 const String& function_name = 755 const String& function_name =
768 String::ZoneHandle(Symbols::New(Token::Str(kind()))); 756 String::ZoneHandle(Symbols::New(Token::Str(kind())));
769 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 757 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
770 deopt_id(), 758 deopt_id(),
771 token_pos(), 759 token_pos());
772 try_index());
773 const intptr_t kNumArguments = 2; 760 const intptr_t kNumArguments = 2;
774 const intptr_t kNumArgsChecked = 2; // Type-feedback. 761 const intptr_t kNumArgsChecked = 2; // Type-feedback.
775 compiler->GenerateInstanceCall(deopt_id(), 762 compiler->GenerateInstanceCall(deopt_id(),
776 token_pos(), 763 token_pos(),
777 try_index(),
778 function_name, 764 function_name,
779 kNumArguments, 765 kNumArguments,
780 Array::ZoneHandle(), // No optional arguments. 766 Array::ZoneHandle(), // No optional arguments.
781 kNumArgsChecked, 767 kNumArgsChecked,
782 locs()); 768 locs());
783 } 769 }
784 770
785 771
786 void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler, 772 void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler,
787 BranchInstr* branch) { 773 BranchInstr* branch) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 } 813 }
828 if (!has_optional_parameters() && !is_native_instance_closure()) { 814 if (!has_optional_parameters() && !is_native_instance_closure()) {
829 __ leaq(RAX, Address(RBP, (1 + arg_count) * kWordSize)); 815 __ leaq(RAX, Address(RBP, (1 + arg_count) * kWordSize));
830 } else { 816 } else {
831 __ leaq(RAX, 817 __ leaq(RAX,
832 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); 818 Address(RBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize));
833 } 819 }
834 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function()))); 820 __ movq(RBX, Immediate(reinterpret_cast<uword>(native_c_function())));
835 __ movq(R10, Immediate(arg_count)); 821 __ movq(R10, Immediate(arg_count));
836 compiler->GenerateCall(token_pos(), 822 compiler->GenerateCall(token_pos(),
837 try_index(),
838 &StubCode::CallNativeCFunctionLabel(), 823 &StubCode::CallNativeCFunctionLabel(),
839 PcDescriptors::kOther, 824 PcDescriptors::kOther,
840 locs()); 825 locs());
841 __ popq(result); 826 __ popq(result);
842 } 827 }
843 828
844 829
845 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { 830 LocationSummary* LoadIndexedComp::MakeLocationSummary() const {
846 const intptr_t kNumInputs = 2; 831 const intptr_t kNumInputs = 2;
847 if (receiver_type() == kGrowableObjectArrayCid) { 832 if (receiver_type() == kGrowableObjectArrayCid) {
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 } 1035 }
1051 1036
1052 1037
1053 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1038 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1054 ASSERT(locs()->in(0).reg() == RAX); // Value. 1039 ASSERT(locs()->in(0).reg() == RAX); // Value.
1055 ASSERT(locs()->in(1).reg() == RCX); // Instantiator. 1040 ASSERT(locs()->in(1).reg() == RCX); // Instantiator.
1056 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments. 1041 ASSERT(locs()->in(2).reg() == RDX); // Instantiator type arguments.
1057 1042
1058 compiler->GenerateInstanceOf(deopt_id(), 1043 compiler->GenerateInstanceOf(deopt_id(),
1059 token_pos(), 1044 token_pos(),
1060 try_index(),
1061 type(), 1045 type(),
1062 negate_result(), 1046 negate_result(),
1063 locs()); 1047 locs());
1064 ASSERT(locs()->out().reg() == RAX); 1048 ASSERT(locs()->out().reg() == RAX);
1065 } 1049 }
1066 1050
1067 1051
1068 LocationSummary* CreateArrayComp::MakeLocationSummary() const { 1052 LocationSummary* CreateArrayComp::MakeLocationSummary() const {
1069 const intptr_t kNumInputs = 1; 1053 const intptr_t kNumInputs = 1;
1070 const intptr_t kNumTemps = 0; 1054 const intptr_t kNumTemps = 0;
1071 LocationSummary* locs = 1055 LocationSummary* locs =
1072 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1056 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1073 locs->set_in(0, Location::RegisterLocation(RBX)); 1057 locs->set_in(0, Location::RegisterLocation(RBX));
1074 locs->set_out(Location::RegisterLocation(RAX)); 1058 locs->set_out(Location::RegisterLocation(RAX));
1075 return locs; 1059 return locs;
1076 } 1060 }
1077 1061
1078 1062
1079 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1063 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1080 // Allocate the array. R10 = length, RBX = element type. 1064 // Allocate the array. R10 = length, RBX = element type.
1081 ASSERT(locs()->in(0).reg() == RBX); 1065 ASSERT(locs()->in(0).reg() == RBX);
1082 __ movq(R10, Immediate(Smi::RawValue(ArgumentCount()))); 1066 __ movq(R10, Immediate(Smi::RawValue(ArgumentCount())));
1083 compiler->GenerateCall(token_pos(), 1067 compiler->GenerateCall(token_pos(),
1084 try_index(),
1085 &StubCode::AllocateArrayLabel(), 1068 &StubCode::AllocateArrayLabel(),
1086 PcDescriptors::kOther, 1069 PcDescriptors::kOther,
1087 locs()); 1070 locs());
1088 ASSERT(locs()->out().reg() == RAX); 1071 ASSERT(locs()->out().reg() == RAX);
1089 1072
1090 // Pop the element values from the stack into the array. 1073 // Pop the element values from the stack into the array.
1091 __ leaq(R10, FieldAddress(RAX, Array::data_offset())); 1074 __ leaq(R10, FieldAddress(RAX, Array::data_offset()));
1092 for (int i = ArgumentCount() - 1; i >= 0; --i) { 1075 for (int i = ArgumentCount() - 1; i >= 0; --i) {
1093 ASSERT(ArgumentAt(i)->value()->IsUse()); 1076 ASSERT(ArgumentAt(i)->value()->IsUse());
1094 __ popq(Address(R10, i * kWordSize)); 1077 __ popq(Address(R10, i * kWordSize));
(...skipping 21 matching lines...) Expand all
1116 Register instantiator_type_arguments = locs()->in(1).reg(); 1099 Register instantiator_type_arguments = locs()->in(1).reg();
1117 Register result = locs()->out().reg(); 1100 Register result = locs()->out().reg();
1118 1101
1119 // Push the result place holder initialized to NULL. 1102 // Push the result place holder initialized to NULL.
1120 __ PushObject(Object::ZoneHandle()); 1103 __ PushObject(Object::ZoneHandle());
1121 __ PushObject(cls); 1104 __ PushObject(cls);
1122 __ pushq(type_arguments); 1105 __ pushq(type_arguments);
1123 __ pushq(instantiator_type_arguments); 1106 __ pushq(instantiator_type_arguments);
1124 compiler->GenerateCallRuntime(deopt_id(), 1107 compiler->GenerateCallRuntime(deopt_id(),
1125 token_pos(), 1108 token_pos(),
1126 try_index(),
1127 kAllocateObjectWithBoundsCheckRuntimeEntry, 1109 kAllocateObjectWithBoundsCheckRuntimeEntry,
1128 locs()); 1110 locs());
1129 // Pop instantiator type arguments, type arguments, and class. 1111 // Pop instantiator type arguments, type arguments, and class.
1130 __ Drop(3); 1112 __ Drop(3);
1131 __ popq(result); // Pop new instance. 1113 __ popq(result); // Pop new instance.
1132 } 1114 }
1133 1115
1134 1116
1135 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { 1117 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const {
1136 return LocationSummary::Make(1, 1118 return LocationSummary::Make(1,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 Immediate(Smi::RawValue(len))); 1182 Immediate(Smi::RawValue(len)));
1201 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1183 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1202 __ Bind(&type_arguments_uninstantiated); 1184 __ Bind(&type_arguments_uninstantiated);
1203 } 1185 }
1204 // A runtime call to instantiate the type arguments is required. 1186 // A runtime call to instantiate the type arguments is required.
1205 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1187 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1206 __ PushObject(type_arguments()); 1188 __ PushObject(type_arguments());
1207 __ pushq(instantiator_reg); // Push instantiator type arguments. 1189 __ pushq(instantiator_reg); // Push instantiator type arguments.
1208 compiler->GenerateCallRuntime(deopt_id(), 1190 compiler->GenerateCallRuntime(deopt_id(),
1209 token_pos(), 1191 token_pos(),
1210 try_index(),
1211 kInstantiateTypeArgumentsRuntimeEntry, 1192 kInstantiateTypeArgumentsRuntimeEntry,
1212 locs()); 1193 locs());
1213 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 1194 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1214 __ popq(result_reg); // Pop instantiated type arguments. 1195 __ popq(result_reg); // Pop instantiated type arguments.
1215 __ Bind(&type_arguments_instantiated); 1196 __ Bind(&type_arguments_instantiated);
1216 ASSERT(instantiator_reg == result_reg); 1197 ASSERT(instantiator_reg == result_reg);
1217 // 'result_reg': Instantiated type arguments. 1198 // 'result_reg': Instantiated type arguments.
1218 } 1199 }
1219 1200
1220 1201
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1352 1333
1353 1334
1354 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1335 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1355 ASSERT(locs()->temp(0).reg() == R10); 1336 ASSERT(locs()->temp(0).reg() == R10);
1356 ASSERT(locs()->out().reg() == RAX); 1337 ASSERT(locs()->out().reg() == RAX);
1357 1338
1358 __ movq(R10, Immediate(num_context_variables())); 1339 __ movq(R10, Immediate(num_context_variables()));
1359 const ExternalLabel label("alloc_context", 1340 const ExternalLabel label("alloc_context",
1360 StubCode::AllocateContextEntryPoint()); 1341 StubCode::AllocateContextEntryPoint());
1361 compiler->GenerateCall(token_pos(), 1342 compiler->GenerateCall(token_pos(),
1362 try_index(),
1363 &label, 1343 &label,
1364 PcDescriptors::kOther, 1344 PcDescriptors::kOther,
1365 locs()); 1345 locs());
1366 } 1346 }
1367 1347
1368 1348
1369 LocationSummary* CloneContextComp::MakeLocationSummary() const { 1349 LocationSummary* CloneContextComp::MakeLocationSummary() const {
1370 const intptr_t kNumInputs = 1; 1350 const intptr_t kNumInputs = 1;
1371 const intptr_t kNumTemps = 0; 1351 const intptr_t kNumTemps = 0;
1372 LocationSummary* locs = 1352 LocationSummary* locs =
1373 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1353 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1374 locs->set_in(0, Location::RegisterLocation(RAX)); 1354 locs->set_in(0, Location::RegisterLocation(RAX));
1375 locs->set_out(Location::RegisterLocation(RAX)); 1355 locs->set_out(Location::RegisterLocation(RAX));
1376 return locs; 1356 return locs;
1377 } 1357 }
1378 1358
1379 1359
1380 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1360 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1381 Register context_value = locs()->in(0).reg(); 1361 Register context_value = locs()->in(0).reg();
1382 Register result = locs()->out().reg(); 1362 Register result = locs()->out().reg();
1383 1363
1384 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1364 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1385 __ pushq(context_value); 1365 __ pushq(context_value);
1386 compiler->GenerateCallRuntime(deopt_id(), 1366 compiler->GenerateCallRuntime(deopt_id(),
1387 token_pos(), 1367 token_pos(),
1388 try_index(),
1389 kCloneContextRuntimeEntry, 1368 kCloneContextRuntimeEntry,
1390 locs()); 1369 locs());
1391 __ popq(result); // Remove argument. 1370 __ popq(result); // Remove argument.
1392 __ popq(result); // Get result (cloned context). 1371 __ popq(result); // Get result (cloned context).
1393 } 1372 }
1394 1373
1395 1374
1396 LocationSummary* CatchEntryComp::MakeLocationSummary() const { 1375 LocationSummary* CatchEntryComp::MakeLocationSummary() const {
1397 return LocationSummary::Make(0, 1376 return LocationSummary::Make(0,
1398 Location::NoLocation(), 1377 Location::NoLocation(),
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 class CheckStackOverflowSlowPath : public SlowPathCode { 1414 class CheckStackOverflowSlowPath : public SlowPathCode {
1436 public: 1415 public:
1437 explicit CheckStackOverflowSlowPath(CheckStackOverflowComp* computation) 1416 explicit CheckStackOverflowSlowPath(CheckStackOverflowComp* computation)
1438 : computation_(computation) { } 1417 : computation_(computation) { }
1439 1418
1440 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1419 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1441 __ Bind(entry_label()); 1420 __ Bind(entry_label());
1442 compiler->SaveLiveRegisters(computation_->locs()); 1421 compiler->SaveLiveRegisters(computation_->locs());
1443 compiler->GenerateCallRuntime(computation_->deopt_id(), 1422 compiler->GenerateCallRuntime(computation_->deopt_id(),
1444 computation_->token_pos(), 1423 computation_->token_pos(),
1445 computation_->try_index(),
1446 kStackOverflowRuntimeEntry, 1424 kStackOverflowRuntimeEntry,
1447 computation_->locs()); 1425 computation_->locs());
1448 compiler->RestoreLiveRegisters(computation_->locs()); 1426 compiler->RestoreLiveRegisters(computation_->locs());
1449 __ jmp(exit_label()); 1427 __ jmp(exit_label());
1450 } 1428 }
1451 1429
1452 private: 1430 private:
1453 CheckStackOverflowComp* computation_; 1431 CheckStackOverflowComp* computation_;
1454 }; 1432 };
1455 1433
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1625 __ Bind(&call_method); 1603 __ Bind(&call_method);
1626 Function& target = Function::ZoneHandle( 1604 Function& target = Function::ZoneHandle(
1627 ic_data()->GetTargetForReceiverClassId(kSmiCid)); 1605 ic_data()->GetTargetForReceiverClassId(kSmiCid));
1628 ASSERT(!target.IsNull()); 1606 ASSERT(!target.IsNull());
1629 const intptr_t kArgumentCount = 2; 1607 const intptr_t kArgumentCount = 2;
1630 __ pushq(temp); 1608 __ pushq(temp);
1631 __ pushq(right); 1609 __ pushq(right);
1632 compiler->GenerateStaticCall( 1610 compiler->GenerateStaticCall(
1633 instance_call()->deopt_id(), 1611 instance_call()->deopt_id(),
1634 instance_call()->token_pos(), 1612 instance_call()->token_pos(),
1635 instance_call()->try_index(),
1636 target, 1613 target,
1637 kArgumentCount, 1614 kArgumentCount,
1638 Array::Handle(), // No argument names. 1615 Array::Handle(), // No argument names.
1639 locs()); 1616 locs());
1640 ASSERT(result == RAX); 1617 ASSERT(result == RAX);
1641 } 1618 }
1642 __ Bind(&done); 1619 __ Bind(&done);
1643 break; 1620 break;
1644 } 1621 }
1645 case Token::kDIV: { 1622 case Token::kDIV: {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 Function& target = Function::ZoneHandle( 1707 Function& target = Function::ZoneHandle(
1731 ic_data()->GetTargetForReceiverClassId(kSmiCid)); 1708 ic_data()->GetTargetForReceiverClassId(kSmiCid));
1732 if (target.IsNull()) { 1709 if (target.IsNull()) {
1733 __ jmp(deopt); 1710 __ jmp(deopt);
1734 } else { 1711 } else {
1735 __ pushq(left); 1712 __ pushq(left);
1736 __ pushq(right); 1713 __ pushq(right);
1737 compiler->GenerateStaticCall( 1714 compiler->GenerateStaticCall(
1738 instance_call()->deopt_id(), 1715 instance_call()->deopt_id(),
1739 instance_call()->token_pos(), 1716 instance_call()->token_pos(),
1740 instance_call()->try_index(),
1741 target, 1717 target,
1742 instance_call()->ArgumentCount(), 1718 instance_call()->ArgumentCount(),
1743 instance_call()->argument_names(), 1719 instance_call()->argument_names(),
1744 locs()); 1720 locs());
1745 ASSERT(result == RAX); 1721 ASSERT(result == RAX);
1746 __ jmp(&done); 1722 __ jmp(&done);
1747 } 1723 }
1748 } 1724 }
1749 1725
1750 __ Bind(&mint_static_call); 1726 __ Bind(&mint_static_call);
1751 { 1727 {
1752 Function& target = Function::ZoneHandle( 1728 Function& target = Function::ZoneHandle(
1753 ic_data()->GetTargetForReceiverClassId(kMintCid)); 1729 ic_data()->GetTargetForReceiverClassId(kMintCid));
1754 if (target.IsNull()) { 1730 if (target.IsNull()) {
1755 __ jmp(deopt); 1731 __ jmp(deopt);
1756 } else { 1732 } else {
1757 __ pushq(left); 1733 __ pushq(left);
1758 __ pushq(right); 1734 __ pushq(right);
1759 compiler->GenerateStaticCall( 1735 compiler->GenerateStaticCall(
1760 instance_call()->deopt_id(), 1736 instance_call()->deopt_id(),
1761 instance_call()->token_pos(), 1737 instance_call()->token_pos(),
1762 instance_call()->try_index(),
1763 target, 1738 target,
1764 instance_call()->ArgumentCount(), 1739 instance_call()->ArgumentCount(),
1765 instance_call()->argument_names(), 1740 instance_call()->argument_names(),
1766 locs()); 1741 locs());
1767 ASSERT(result == RAX); 1742 ASSERT(result == RAX);
1768 } 1743 }
1769 } 1744 }
1770 __ Bind(&done); 1745 __ Bind(&done);
1771 } 1746 }
1772 1747
1773 1748
1774 LocationSummary* BinaryDoubleOpComp::MakeLocationSummary() const { 1749 LocationSummary* BinaryDoubleOpComp::MakeLocationSummary() const {
1775 return MakeCallSummary(); // Calls into a stub for allocation. 1750 return MakeCallSummary(); // Calls into a stub for allocation.
1776 } 1751 }
1777 1752
1778 1753
1779 void BinaryDoubleOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1754 void BinaryDoubleOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1780 Register left = RBX; 1755 Register left = RBX;
1781 Register right = RCX; 1756 Register right = RCX;
1782 Register temp = RDX; 1757 Register temp = RDX;
1783 Register result = locs()->out().reg(); 1758 Register result = locs()->out().reg();
1784 1759
1785 const Class& double_class = compiler->double_class(); 1760 const Class& double_class = compiler->double_class();
1786 const Code& stub = 1761 const Code& stub =
1787 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1762 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1788 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1763 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1789 compiler->GenerateCall(instance_call()->token_pos(), 1764 compiler->GenerateCall(instance_call()->token_pos(),
1790 instance_call()->try_index(),
1791 &label, 1765 &label,
1792 PcDescriptors::kOther, 1766 PcDescriptors::kOther,
1793 locs()); 1767 locs());
1794 // Newly allocated object is now in the result register (RAX). 1768 // Newly allocated object is now in the result register (RAX).
1795 ASSERT(result == RAX); 1769 ASSERT(result == RAX);
1796 __ movq(right, Address(RSP, 0)); 1770 __ movq(right, Address(RSP, 0));
1797 __ movq(left, Address(RSP, kWordSize)); 1771 __ movq(left, Address(RSP, kWordSize));
1798 1772
1799 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1773 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1800 kDeoptBinaryDoubleOp); 1774 kDeoptBinaryDoubleOp);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1873 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1847 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1874 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1848 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1875 1849
1876 // TODO(vegorov): here stack map needs to be set up correctly to skip 1850 // TODO(vegorov): here stack map needs to be set up correctly to skip
1877 // double registers. 1851 // double registers.
1878 LocationSummary* locs = computation_->locs(); 1852 LocationSummary* locs = computation_->locs();
1879 locs->live_registers()->Remove(locs->out()); 1853 locs->live_registers()->Remove(locs->out());
1880 1854
1881 compiler->SaveLiveRegisters(locs); 1855 compiler->SaveLiveRegisters(locs);
1882 compiler->GenerateCall(computation_->instance_call()->token_pos(), 1856 compiler->GenerateCall(computation_->instance_call()->token_pos(),
1883 computation_->instance_call()->try_index(),
1884 &label, 1857 &label,
1885 PcDescriptors::kOther, 1858 PcDescriptors::kOther,
1886 locs); 1859 locs);
1887 if (RAX != locs->out().reg()) __ movq(locs->out().reg(), RAX); 1860 if (RAX != locs->out().reg()) __ movq(locs->out().reg(), RAX);
1888 compiler->RestoreLiveRegisters(locs); 1861 compiler->RestoreLiveRegisters(locs);
1889 1862
1890 __ jmp(exit_label()); 1863 __ jmp(exit_label());
1891 } 1864 }
1892 1865
1893 private: 1866 private:
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2038 __ j(ZERO, deopt); // Smi. 2011 __ j(ZERO, deopt); // Smi.
2039 __ CompareClassId(value, kDoubleCid); 2012 __ CompareClassId(value, kDoubleCid);
2040 __ j(NOT_EQUAL, deopt); 2013 __ j(NOT_EQUAL, deopt);
2041 // Allocate result object. 2014 // Allocate result object.
2042 const Class& double_class = compiler->double_class(); 2015 const Class& double_class = compiler->double_class();
2043 const Code& stub = 2016 const Code& stub =
2044 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 2017 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2045 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 2018 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
2046 __ pushq(value); 2019 __ pushq(value);
2047 compiler->GenerateCall(instance_call()->token_pos(), 2020 compiler->GenerateCall(instance_call()->token_pos(),
2048 instance_call()->try_index(),
2049 &label, 2021 &label,
2050 PcDescriptors::kOther, 2022 PcDescriptors::kOther,
2051 instance_call()->locs()); 2023 instance_call()->locs());
2052 // Result is in RAX. 2024 // Result is in RAX.
2053 ASSERT(result != temp); 2025 ASSERT(result != temp);
2054 __ movq(result, RAX); 2026 __ movq(result, RAX);
2055 __ popq(temp); 2027 __ popq(temp);
2056 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); 2028 __ movsd(XMM0, FieldAddress(temp, Double::value_offset()));
2057 __ DoubleNegate(XMM0); 2029 __ DoubleNegate(XMM0);
2058 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 2030 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2101 kDeoptIntegerToDouble); 2073 kDeoptIntegerToDouble);
2102 2074
2103 const Class& double_class = compiler->double_class(); 2075 const Class& double_class = compiler->double_class();
2104 const Code& stub = 2076 const Code& stub =
2105 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 2077 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2106 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 2078 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
2107 2079
2108 // TODO(fschneider): Inline new-space allocation and move the call into 2080 // TODO(fschneider): Inline new-space allocation and move the call into
2109 // deferred code. 2081 // deferred code.
2110 compiler->GenerateCall(instance_call()->token_pos(), 2082 compiler->GenerateCall(instance_call()->token_pos(),
2111 instance_call()->try_index(),
2112 &label, 2083 &label,
2113 PcDescriptors::kOther, 2084 PcDescriptors::kOther,
2114 locs()); 2085 locs());
2115 ASSERT(result == RAX); 2086 ASSERT(result == RAX);
2116 Register value = RBX; 2087 Register value = RBX;
2117 // Preserve argument on the stack until after the deoptimization point. 2088 // Preserve argument on the stack until after the deoptimization point.
2118 __ movq(value, Address(RSP, 0)); 2089 __ movq(value, Address(RSP, 0));
2119 2090
2120 __ testq(value, Immediate(kSmiTagMask)); 2091 __ testq(value, Immediate(kSmiTagMask));
2121 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. 2092 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi.
(...skipping 15 matching lines...) Expand all
2137 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) { 2108 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) {
2138 __ jmp(deopt); 2109 __ jmp(deopt);
2139 return; 2110 return;
2140 } 2111 }
2141 ASSERT(HasICData()); 2112 ASSERT(HasICData());
2142 ASSERT(ic_data()->num_args_tested() == 1); 2113 ASSERT(ic_data()->num_args_tested() == 1);
2143 if (!with_checks()) { 2114 if (!with_checks()) {
2144 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); 2115 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0));
2145 compiler->GenerateStaticCall(instance_call()->deopt_id(), 2116 compiler->GenerateStaticCall(instance_call()->deopt_id(),
2146 instance_call()->token_pos(), 2117 instance_call()->token_pos(),
2147 instance_call()->try_index(),
2148 target, 2118 target,
2149 instance_call()->ArgumentCount(), 2119 instance_call()->ArgumentCount(),
2150 instance_call()->argument_names(), 2120 instance_call()->argument_names(),
2151 locs()); 2121 locs());
2152 return; 2122 return;
2153 } 2123 }
2154 2124
2155 // Load receiver into RAX. 2125 // Load receiver into RAX.
2156 __ movq(RAX, 2126 __ movq(RAX,
2157 Address(RSP, (instance_call()->ArgumentCount() - 1) * kWordSize)); 2127 Address(RSP, (instance_call()->ArgumentCount() - 1) * kWordSize));
2158 Label done; 2128 Label done;
2159 __ movq(RDI, Immediate(kSmiCid)); 2129 __ movq(RDI, Immediate(kSmiCid));
2160 __ testq(RAX, Immediate(kSmiTagMask)); 2130 __ testq(RAX, Immediate(kSmiTagMask));
2161 __ j(ZERO, &done); 2131 __ j(ZERO, &done);
2162 __ LoadClassId(RDI, RAX); 2132 __ LoadClassId(RDI, RAX);
2163 __ Bind(&done); 2133 __ Bind(&done);
2164 compiler->EmitTestAndCall(*ic_data(), 2134 compiler->EmitTestAndCall(*ic_data(),
2165 RDI, // Class id register. 2135 RDI, // Class id register.
2166 instance_call()->ArgumentCount(), 2136 instance_call()->ArgumentCount(),
2167 instance_call()->argument_names(), 2137 instance_call()->argument_names(),
2168 deopt, 2138 deopt,
2169 instance_call()->deopt_id(), 2139 instance_call()->deopt_id(),
2170 instance_call()->token_pos(), 2140 instance_call()->token_pos(),
2171 instance_call()->try_index(),
2172 locs()); 2141 locs());
2173 } 2142 }
2174 2143
2175 2144
2176 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2145 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2177 computation()->EmitBranchCode(compiler, this); 2146 computation()->EmitBranchCode(compiler, this);
2178 } 2147 }
2179 2148
2180 2149
2181 LocationSummary* CheckClassComp::MakeLocationSummary() const { 2150 LocationSummary* CheckClassComp::MakeLocationSummary() const {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 } 2233 }
2265 __ j(ABOVE_EQUAL, deopt); 2234 __ j(ABOVE_EQUAL, deopt);
2266 } 2235 }
2267 2236
2268 2237
2269 } // namespace dart 2238 } // namespace dart
2270 2239
2271 #undef __ 2240 #undef __
2272 2241
2273 #endif // defined TARGET_ARCH_X64 2242 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_test.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698