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

Side by Side Diff: runtime/vm/intermediate_language_ia32.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.cc ('k') | runtime/vm/intermediate_language_test.cc » ('j') | 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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 } 79 }
80 } 80 }
81 if (FLAG_trace_functions) { 81 if (FLAG_trace_functions) {
82 const Function& function = 82 const Function& function =
83 Function::ZoneHandle(compiler->parsed_function().function().raw()); 83 Function::ZoneHandle(compiler->parsed_function().function().raw());
84 __ LoadObject(temp, function); 84 __ LoadObject(temp, function);
85 __ pushl(result); // Preserve result. 85 __ pushl(result); // Preserve result.
86 __ pushl(temp); 86 __ pushl(temp);
87 compiler->GenerateCallRuntime(Isolate::kNoDeoptId, 87 compiler->GenerateCallRuntime(Isolate::kNoDeoptId,
88 0, 88 0,
89 CatchClauseNode::kInvalidTryIndex,
90 kTraceFunctionExitRuntimeEntry, 89 kTraceFunctionExitRuntimeEntry,
91 locs()); 90 locs());
92 __ popl(temp); // Remove argument. 91 __ popl(temp); // Remove argument.
93 __ popl(result); // Restore result. 92 __ popl(result); // Restore result.
94 } 93 }
95 #if defined(DEBUG) 94 #if defined(DEBUG)
96 // TODO(srdjan): Fix for functions with finally clause. 95 // TODO(srdjan): Fix for functions with finally clause.
97 // A finally clause may leave a previously pushed return value if it 96 // A finally clause may leave a previously pushed return value if it
98 // has its own return instruction. Method that have finally are currently 97 // has its own return instruction. Method that have finally are currently
99 // not optimized. 98 // not optimized.
100 if (!compiler->HasFinally()) { 99 if (!compiler->HasFinally()) {
101 Label done; 100 Label done;
102 __ movl(EDI, EBP); 101 __ movl(EDI, EBP);
103 __ subl(EDI, ESP); 102 __ subl(EDI, ESP);
104 // + 1 for Pc marker. 103 // + 1 for Pc marker.
105 __ cmpl(EDI, Immediate((compiler->StackSize() + 1) * kWordSize)); 104 __ cmpl(EDI, Immediate((compiler->StackSize() + 1) * kWordSize));
106 __ j(EQUAL, &done, Assembler::kNearJump); 105 __ j(EQUAL, &done, Assembler::kNearJump);
107 __ int3(); 106 __ int3();
108 __ Bind(&done); 107 __ Bind(&done);
109 } 108 }
110 #endif 109 #endif
111 __ LeaveFrame(); 110 __ LeaveFrame();
112 __ ret(); 111 __ ret();
113 112
114 // Generate 1 byte NOP so that the debugger can patch the 113 // Generate 1 byte NOP so that the debugger can patch the
115 // return pattern with a call to the debug stub. 114 // return pattern with a call to the debug stub.
116 __ nop(1); 115 __ nop(1);
117 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 116 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
118 deopt_id(), 117 deopt_id(),
119 token_pos(), 118 token_pos());
120 CatchClauseNode::kInvalidTryIndex);
121 } 119 }
122 120
123 121
124 LocationSummary* ClosureCallComp::MakeLocationSummary() const { 122 LocationSummary* ClosureCallComp::MakeLocationSummary() const {
125 const intptr_t kNumInputs = 0; 123 const intptr_t kNumInputs = 0;
126 const intptr_t kNumTemps = 1; 124 const intptr_t kNumTemps = 1;
127 LocationSummary* result = 125 LocationSummary* result =
128 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 126 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
129 result->set_out(Location::RegisterLocation(EAX)); 127 result->set_out(Location::RegisterLocation(EAX));
130 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor. 128 result->set_temp(0, Location::RegisterLocation(EDX)); // Arg. descriptor.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 // Call the runtime if the object is not bool::true or bool::false. 204 // Call the runtime if the object is not bool::true or bool::false.
207 Label done; 205 Label done;
208 __ CompareObject(obj, compiler->bool_true()); 206 __ CompareObject(obj, compiler->bool_true());
209 __ j(EQUAL, &done, Assembler::kNearJump); 207 __ j(EQUAL, &done, Assembler::kNearJump);
210 __ CompareObject(obj, compiler->bool_false()); 208 __ CompareObject(obj, compiler->bool_false());
211 __ j(EQUAL, &done, Assembler::kNearJump); 209 __ j(EQUAL, &done, Assembler::kNearJump);
212 210
213 __ pushl(obj); // Push the source object. 211 __ pushl(obj); // Push the source object.
214 compiler->GenerateCallRuntime(deopt_id(), 212 compiler->GenerateCallRuntime(deopt_id(),
215 token_pos(), 213 token_pos(),
216 try_index(),
217 kConditionTypeErrorRuntimeEntry, 214 kConditionTypeErrorRuntimeEntry,
218 locs()); 215 locs());
219 // We should never return here. 216 // We should never return here.
220 __ int3(); 217 __ int3();
221 __ Bind(&done); 218 __ Bind(&done);
222 } 219 }
223 ASSERT(obj == result); 220 ASSERT(obj == result);
224 } 221 }
225 222
226 223
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 locs->set_in(0, Location::RegisterLocation(ECX)); 268 locs->set_in(0, Location::RegisterLocation(ECX));
272 locs->set_in(1, Location::RegisterLocation(EDX)); 269 locs->set_in(1, Location::RegisterLocation(EDX));
273 locs->set_out(Location::RegisterLocation(EAX)); 270 locs->set_out(Location::RegisterLocation(EAX));
274 return locs; 271 return locs;
275 } 272 }
276 273
277 274
278 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, 275 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
279 intptr_t deopt_id, 276 intptr_t deopt_id,
280 intptr_t token_pos, 277 intptr_t token_pos,
281 intptr_t try_index,
282 Token::Kind kind, 278 Token::Kind kind,
283 LocationSummary* locs) { 279 LocationSummary* locs) {
284 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 280 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
285 deopt_id, 281 deopt_id,
286 token_pos, 282 token_pos);
287 try_index);
288 const String& operator_name = String::ZoneHandle(Symbols::New("==")); 283 const String& operator_name = String::ZoneHandle(Symbols::New("=="));
289 const int kNumberOfArguments = 2; 284 const int kNumberOfArguments = 2;
290 const Array& kNoArgumentNames = Array::Handle(); 285 const Array& kNoArgumentNames = Array::Handle();
291 const int kNumArgumentsChecked = 2; 286 const int kNumArgumentsChecked = 2;
292 287
293 Label done, false_label, true_label; 288 Label done, false_label, true_label;
294 Register left = locs->in(0).reg(); 289 Register left = locs->in(0).reg();
295 Register right = locs->in(1).reg(); 290 Register right = locs->in(1).reg();
296 __ popl(right); 291 __ popl(right);
297 __ popl(left); 292 __ popl(left);
(...skipping 17 matching lines...) Expand all
315 } else { 310 } else {
316 ASSERT(kind == Token::kNE); 311 ASSERT(kind == Token::kNE);
317 __ jmp(&false_label); 312 __ jmp(&false_label);
318 } 313 }
319 314
320 __ Bind(&instance_call); 315 __ Bind(&instance_call);
321 __ pushl(left); 316 __ pushl(left);
322 __ pushl(right); 317 __ pushl(right);
323 compiler->GenerateInstanceCall(deopt_id, 318 compiler->GenerateInstanceCall(deopt_id,
324 token_pos, 319 token_pos,
325 try_index,
326 operator_name, 320 operator_name,
327 kNumberOfArguments, 321 kNumberOfArguments,
328 kNoArgumentNames, 322 kNoArgumentNames,
329 kNumArgumentsChecked, 323 kNumArgumentsChecked,
330 locs); 324 locs);
331 if (kind == Token::kNE) { 325 if (kind == Token::kNE) {
332 // Negate the condition: true label returns false and vice versa. 326 // Negate the condition: true label returns false and vice versa.
333 __ CompareObject(EAX, compiler->bool_true()); 327 __ CompareObject(EAX, compiler->bool_true());
334 __ j(EQUAL, &true_label, Assembler::kNearJump); 328 __ j(EQUAL, &true_label, Assembler::kNearJump);
335 __ Bind(&false_label); 329 __ Bind(&false_label);
336 __ LoadObject(EAX, compiler->bool_true()); 330 __ LoadObject(EAX, compiler->bool_true());
337 __ jmp(&done, Assembler::kNearJump); 331 __ jmp(&done, Assembler::kNearJump);
338 __ Bind(&true_label); 332 __ Bind(&true_label);
339 __ LoadObject(EAX, compiler->bool_false()); 333 __ LoadObject(EAX, compiler->bool_false());
340 } 334 }
341 __ Bind(&done); 335 __ Bind(&done);
342 } 336 }
343 337
344 338
345 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, 339 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
346 const ICData& orig_ic_data, 340 const ICData& orig_ic_data,
347 LocationSummary* locs, 341 LocationSummary* locs,
348 BranchInstr* branch, 342 BranchInstr* branch,
349 Token::Kind kind, 343 Token::Kind kind,
350 intptr_t deopt_id, 344 intptr_t deopt_id,
351 intptr_t token_pos, 345 intptr_t token_pos) {
352 intptr_t try_index) {
353 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 346 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
354 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); 347 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
355 ASSERT(ic_data.NumberOfChecks() > 0); 348 ASSERT(ic_data.NumberOfChecks() > 0);
356 ASSERT(ic_data.num_args_tested() == 1); 349 ASSERT(ic_data.num_args_tested() == 1);
357 Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality); 350 Label* deopt = compiler->AddDeoptStub(deopt_id, kDeoptEquality);
358 Register left = locs->in(0).reg(); 351 Register left = locs->in(0).reg();
359 Register right = locs->in(1).reg(); 352 Register right = locs->in(1).reg();
360 __ testl(left, Immediate(kSmiTagMask)); 353 __ testl(left, Immediate(kSmiTagMask));
361 Register temp = locs->temp(0).reg(); 354 Register temp = locs->temp(0).reg();
362 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) { 355 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 __ LoadObject(result, compiler->bool_false()); 388 __ LoadObject(result, compiler->bool_false());
396 __ jmp(&done); 389 __ jmp(&done);
397 __ Bind(&load_true); 390 __ Bind(&load_true);
398 __ LoadObject(result, compiler->bool_true()); 391 __ LoadObject(result, compiler->bool_true());
399 } 392 }
400 } else { 393 } else {
401 const int kNumberOfArguments = 2; 394 const int kNumberOfArguments = 2;
402 const Array& kNoArgumentNames = Array::Handle(); 395 const Array& kNoArgumentNames = Array::Handle();
403 compiler->GenerateStaticCall(deopt_id, 396 compiler->GenerateStaticCall(deopt_id,
404 token_pos, 397 token_pos,
405 try_index,
406 target, 398 target,
407 kNumberOfArguments, 399 kNumberOfArguments,
408 kNoArgumentNames, 400 kNoArgumentNames,
409 locs); 401 locs);
410 if (branch == NULL) { 402 if (branch == NULL) {
411 if (kind == Token::kNE) { 403 if (kind == Token::kNE) {
412 Label false_label; 404 Label false_label;
413 __ CompareObject(EAX, compiler->bool_true()); 405 __ CompareObject(EAX, compiler->bool_true());
414 __ j(EQUAL, &false_label, Assembler::kNearJump); 406 __ j(EQUAL, &false_label, Assembler::kNearJump);
415 __ LoadObject(EAX, compiler->bool_true()); 407 __ LoadObject(EAX, compiler->bool_true());
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 479
488 // First test if receiver is NULL, in which case === is applied. 480 // First test if receiver is NULL, in which case === is applied.
489 // If type feedback was provided (lists of <class-id, target>), do a 481 // If type feedback was provided (lists of <class-id, target>), do a
490 // type by type check (either === or static call to the operator. 482 // type by type check (either === or static call to the operator.
491 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler, 483 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler,
492 LocationSummary* locs, 484 LocationSummary* locs,
493 Token::Kind kind, 485 Token::Kind kind,
494 BranchInstr* branch, 486 BranchInstr* branch,
495 const ICData& ic_data, 487 const ICData& ic_data,
496 intptr_t deopt_id, 488 intptr_t deopt_id,
497 intptr_t token_pos, 489 intptr_t token_pos) {
498 intptr_t try_index) {
499 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 490 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
500 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); 491 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
501 Register left = locs->in(0).reg(); 492 Register left = locs->in(0).reg();
502 Register right = locs->in(1).reg(); 493 Register right = locs->in(1).reg();
503 const Immediate raw_null = 494 const Immediate raw_null =
504 Immediate(reinterpret_cast<intptr_t>(Object::null())); 495 Immediate(reinterpret_cast<intptr_t>(Object::null()));
505 Label done, identity_compare, non_null_compare; 496 Label done, identity_compare, non_null_compare;
506 __ cmpl(right, raw_null); 497 __ cmpl(right, raw_null);
507 __ j(EQUAL, &identity_compare, Assembler::kNearJump); 498 __ j(EQUAL, &identity_compare, Assembler::kNearJump);
508 __ cmpl(left, raw_null); 499 __ cmpl(left, raw_null);
(...skipping 11 matching lines...) Expand all
520 __ LoadObject(result, compiler->bool_false()); 511 __ LoadObject(result, compiler->bool_false());
521 __ jmp(&done); 512 __ jmp(&done);
522 __ Bind(&load_true); 513 __ Bind(&load_true);
523 __ LoadObject(result, compiler->bool_true()); 514 __ LoadObject(result, compiler->bool_true());
524 } 515 }
525 __ jmp(&done); 516 __ jmp(&done);
526 __ Bind(&non_null_compare); // Receiver is not null. 517 __ Bind(&non_null_compare); // Receiver is not null.
527 __ pushl(left); 518 __ pushl(left);
528 __ pushl(right); 519 __ pushl(right);
529 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 520 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
530 deopt_id, token_pos, try_index); 521 deopt_id, token_pos);
531 __ Bind(&done); 522 __ Bind(&done);
532 } 523 }
533 524
534 525
535 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 526 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
536 const LocationSummary& locs, 527 const LocationSummary& locs,
537 Token::Kind kind, 528 Token::Kind kind,
538 BranchInstr* branch, 529 BranchInstr* branch,
539 intptr_t deopt_id) { 530 intptr_t deopt_id) {
540 Register left = locs.in(0).reg(); 531 Register left = locs.in(0).reg();
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 } 616 }
626 const bool is_checked_strict_equal = 617 const bool is_checked_strict_equal =
627 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 618 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
628 if (is_checked_strict_equal) { 619 if (is_checked_strict_equal) {
629 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch, 620 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), kNoBranch,
630 deopt_id()); 621 deopt_id());
631 return; 622 return;
632 } 623 }
633 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 624 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
634 EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(), 625 EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(),
635 deopt_id(), token_pos(), try_index()); 626 deopt_id(), token_pos());
636 return; 627 return;
637 } 628 }
638 Register left = locs()->in(0).reg(); 629 Register left = locs()->in(0).reg();
639 Register right = locs()->in(1).reg(); 630 Register right = locs()->in(1).reg();
640 __ pushl(left); 631 __ pushl(left);
641 __ pushl(right); 632 __ pushl(right);
642 EmitEqualityAsInstanceCall(compiler, 633 EmitEqualityAsInstanceCall(compiler, deopt_id(), token_pos(), kind(), locs());
643 deopt_id(),
644 token_pos(),
645 try_index(),
646 kind(),
647 locs());
648 ASSERT(locs()->out().reg() == EAX); 634 ASSERT(locs()->out().reg() == EAX);
649 } 635 }
650 636
651 637
652 void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler, 638 void EqualityCompareComp::EmitBranchCode(FlowGraphCompiler* compiler,
653 BranchInstr* branch) { 639 BranchInstr* branch) {
654 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 640 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
655 if (receiver_class_id() == kSmiCid) { 641 if (receiver_class_id() == kSmiCid) {
656 // Deoptimizes if both arguments not Smi. 642 // Deoptimizes if both arguments not Smi.
657 EmitSmiComparisonOp(compiler, *locs(), kind(), branch, deopt_id()); 643 EmitSmiComparisonOp(compiler, *locs(), kind(), branch, deopt_id());
658 return; 644 return;
659 } 645 }
660 if (receiver_class_id() == kDoubleCid) { 646 if (receiver_class_id() == kDoubleCid) {
661 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. 647 // Deoptimizes if both arguments are Smi, or if none is Double or Smi.
662 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch, deopt_id()); 648 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch, deopt_id());
663 return; 649 return;
664 } 650 }
665 const bool is_checked_strict_equal = 651 const bool is_checked_strict_equal =
666 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 652 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
667 if (is_checked_strict_equal) { 653 if (is_checked_strict_equal) {
668 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch, 654 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), branch,
669 deopt_id()); 655 deopt_id());
670 return; 656 return;
671 } 657 }
672 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 658 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
673 EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(), 659 EmitGenericEqualityCompare(compiler, locs(), kind(), branch, *ic_data(),
674 deopt_id(), token_pos(), try_index()); 660 deopt_id(), token_pos());
675 return; 661 return;
676 } 662 }
677 Register left = locs()->in(0).reg(); 663 Register left = locs()->in(0).reg();
678 Register right = locs()->in(1).reg(); 664 Register right = locs()->in(1).reg();
679 __ pushl(left); 665 __ pushl(left);
680 __ pushl(right); 666 __ pushl(right);
681 EmitEqualityAsInstanceCall(compiler, 667 EmitEqualityAsInstanceCall(compiler,
682 deopt_id(), 668 deopt_id(),
683 token_pos(), 669 token_pos(),
684 try_index(),
685 Token::kEQ, // kNE reverse occurs at branch. 670 Token::kEQ, // kNE reverse occurs at branch.
686 locs()); 671 locs());
687 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 672 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
688 __ CompareObject(EAX, compiler->bool_true()); 673 __ CompareObject(EAX, compiler->bool_true());
689 branch->EmitBranchOnCondition(compiler, branch_condition); 674 branch->EmitBranchOnCondition(compiler, branch_condition);
690 } 675 }
691 676
692 677
693 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 678 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
694 const intptr_t kNumInputs = 2; 679 const intptr_t kNumInputs = 2;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 __ j(ZERO, &done); 727 __ j(ZERO, &done);
743 __ LoadClassId(EDI, left); 728 __ LoadClassId(EDI, left);
744 __ Bind(&done); 729 __ Bind(&done);
745 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), 730 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
746 EDI, // Class id register. 731 EDI, // Class id register.
747 kNumArguments, 732 kNumArguments,
748 Array::Handle(), // No named arguments. 733 Array::Handle(), // No named arguments.
749 deopt, // Deoptimize target. 734 deopt, // Deoptimize target.
750 deopt_id(), 735 deopt_id(),
751 token_pos(), 736 token_pos(),
752 try_index(),
753 locs()); 737 locs());
754 return; 738 return;
755 } 739 }
756 const String& function_name = 740 const String& function_name =
757 String::ZoneHandle(Symbols::New(Token::Str(kind()))); 741 String::ZoneHandle(Symbols::New(Token::Str(kind())));
758 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 742 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
759 deopt_id(), 743 deopt_id(),
760 token_pos(), 744 token_pos());
761 try_index());
762 const intptr_t kNumArguments = 2; 745 const intptr_t kNumArguments = 2;
763 const intptr_t kNumArgsChecked = 2; // Type-feedback. 746 const intptr_t kNumArgsChecked = 2; // Type-feedback.
764 compiler->GenerateInstanceCall(deopt_id(), 747 compiler->GenerateInstanceCall(deopt_id(),
765 token_pos(), 748 token_pos(),
766 try_index(),
767 function_name, 749 function_name,
768 kNumArguments, 750 kNumArguments,
769 Array::ZoneHandle(), // No optional arguments. 751 Array::ZoneHandle(), // No optional arguments.
770 kNumArgsChecked, 752 kNumArgsChecked,
771 locs()); 753 locs());
772 } 754 }
773 755
774 756
775 void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler, 757 void RelationalOpComp::EmitBranchCode(FlowGraphCompiler* compiler,
776 BranchInstr* branch) { 758 BranchInstr* branch) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 } 798 }
817 if (!has_optional_parameters() && !is_native_instance_closure()) { 799 if (!has_optional_parameters() && !is_native_instance_closure()) {
818 __ leal(EAX, Address(EBP, (1 + arg_count) * kWordSize)); 800 __ leal(EAX, Address(EBP, (1 + arg_count) * kWordSize));
819 } else { 801 } else {
820 __ leal(EAX, 802 __ leal(EAX,
821 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); 803 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize));
822 } 804 }
823 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); 805 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function())));
824 __ movl(EDX, Immediate(arg_count)); 806 __ movl(EDX, Immediate(arg_count));
825 compiler->GenerateCall(token_pos(), 807 compiler->GenerateCall(token_pos(),
826 try_index(),
827 &StubCode::CallNativeCFunctionLabel(), 808 &StubCode::CallNativeCFunctionLabel(),
828 PcDescriptors::kOther, 809 PcDescriptors::kOther,
829 locs()); 810 locs());
830 __ popl(result); 811 __ popl(result);
831 } 812 }
832 813
833 814
834 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { 815 LocationSummary* LoadIndexedComp::MakeLocationSummary() const {
835 ASSERT((receiver_type() == kGrowableObjectArrayCid) || 816 ASSERT((receiver_type() == kGrowableObjectArrayCid) ||
836 (receiver_type() == kArrayCid) || 817 (receiver_type() == kArrayCid) ||
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 } 1014 }
1034 1015
1035 1016
1036 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1017 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1037 ASSERT(locs()->in(0).reg() == EAX); // Value. 1018 ASSERT(locs()->in(0).reg() == EAX); // Value.
1038 ASSERT(locs()->in(1).reg() == ECX); // Instantiator. 1019 ASSERT(locs()->in(1).reg() == ECX); // Instantiator.
1039 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. 1020 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments.
1040 1021
1041 compiler->GenerateInstanceOf(deopt_id(), 1022 compiler->GenerateInstanceOf(deopt_id(),
1042 token_pos(), 1023 token_pos(),
1043 try_index(),
1044 type(), 1024 type(),
1045 negate_result(), 1025 negate_result(),
1046 locs()); 1026 locs());
1047 ASSERT(locs()->out().reg() == EAX); 1027 ASSERT(locs()->out().reg() == EAX);
1048 } 1028 }
1049 1029
1050 1030
1051 LocationSummary* CreateArrayComp::MakeLocationSummary() const { 1031 LocationSummary* CreateArrayComp::MakeLocationSummary() const {
1052 const intptr_t kNumInputs = 1; 1032 const intptr_t kNumInputs = 1;
1053 const intptr_t kNumTemps = 0; 1033 const intptr_t kNumTemps = 0;
1054 LocationSummary* locs = 1034 LocationSummary* locs =
1055 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1035 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1056 locs->set_in(0, Location::RegisterLocation(ECX)); 1036 locs->set_in(0, Location::RegisterLocation(ECX));
1057 locs->set_out(Location::RegisterLocation(EAX)); 1037 locs->set_out(Location::RegisterLocation(EAX));
1058 return locs; 1038 return locs;
1059 } 1039 }
1060 1040
1061 1041
1062 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1042 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1063 // Allocate the array. EDX = length, ECX = element type. 1043 // Allocate the array. EDX = length, ECX = element type.
1064 ASSERT(locs()->in(0).reg() == ECX); 1044 ASSERT(locs()->in(0).reg() == ECX);
1065 __ movl(EDX, Immediate(Smi::RawValue(ArgumentCount()))); 1045 __ movl(EDX, Immediate(Smi::RawValue(ArgumentCount())));
1066 compiler->GenerateCall(token_pos(), 1046 compiler->GenerateCall(token_pos(),
1067 try_index(),
1068 &StubCode::AllocateArrayLabel(), 1047 &StubCode::AllocateArrayLabel(),
1069 PcDescriptors::kOther, 1048 PcDescriptors::kOther,
1070 locs()); 1049 locs());
1071 ASSERT(locs()->out().reg() == EAX); 1050 ASSERT(locs()->out().reg() == EAX);
1072 1051
1073 // Pop the element values from the stack into the array. 1052 // Pop the element values from the stack into the array.
1074 __ leal(EDX, FieldAddress(EAX, Array::data_offset())); 1053 __ leal(EDX, FieldAddress(EAX, Array::data_offset()));
1075 for (int i = ArgumentCount() - 1; i >= 0; --i) { 1054 for (int i = ArgumentCount() - 1; i >= 0; --i) {
1076 ASSERT(ArgumentAt(i)->value()->IsUse()); 1055 ASSERT(ArgumentAt(i)->value()->IsUse());
1077 __ popl(Address(EDX, i * kWordSize)); 1056 __ popl(Address(EDX, i * kWordSize));
(...skipping 21 matching lines...) Expand all
1099 Register instantiator_type_arguments = locs()->in(1).reg(); 1078 Register instantiator_type_arguments = locs()->in(1).reg();
1100 Register result = locs()->out().reg(); 1079 Register result = locs()->out().reg();
1101 1080
1102 // Push the result place holder initialized to NULL. 1081 // Push the result place holder initialized to NULL.
1103 __ PushObject(Object::ZoneHandle()); 1082 __ PushObject(Object::ZoneHandle());
1104 __ PushObject(cls); 1083 __ PushObject(cls);
1105 __ pushl(type_arguments); 1084 __ pushl(type_arguments);
1106 __ pushl(instantiator_type_arguments); 1085 __ pushl(instantiator_type_arguments);
1107 compiler->GenerateCallRuntime(deopt_id(), 1086 compiler->GenerateCallRuntime(deopt_id(),
1108 token_pos(), 1087 token_pos(),
1109 try_index(),
1110 kAllocateObjectWithBoundsCheckRuntimeEntry, 1088 kAllocateObjectWithBoundsCheckRuntimeEntry,
1111 locs()); 1089 locs());
1112 // Pop instantiator type arguments, type arguments, and class. 1090 // Pop instantiator type arguments, type arguments, and class.
1113 // source location. 1091 // source location.
1114 __ Drop(3); 1092 __ Drop(3);
1115 __ popl(result); // Pop new instance. 1093 __ popl(result); // Pop new instance.
1116 } 1094 }
1117 1095
1118 1096
1119 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { 1097 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 Immediate(Smi::RawValue(len))); 1164 Immediate(Smi::RawValue(len)));
1187 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1165 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1188 __ Bind(&type_arguments_uninstantiated); 1166 __ Bind(&type_arguments_uninstantiated);
1189 } 1167 }
1190 // A runtime call to instantiate the type arguments is required. 1168 // A runtime call to instantiate the type arguments is required.
1191 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1169 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1192 __ PushObject(type_arguments()); 1170 __ PushObject(type_arguments());
1193 __ pushl(instantiator_reg); // Push instantiator type arguments. 1171 __ pushl(instantiator_reg); // Push instantiator type arguments.
1194 compiler->GenerateCallRuntime(deopt_id(), 1172 compiler->GenerateCallRuntime(deopt_id(),
1195 token_pos(), 1173 token_pos(),
1196 try_index(),
1197 kInstantiateTypeArgumentsRuntimeEntry, 1174 kInstantiateTypeArgumentsRuntimeEntry,
1198 locs()); 1175 locs());
1199 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 1176 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1200 __ popl(result_reg); // Pop instantiated type arguments. 1177 __ popl(result_reg); // Pop instantiated type arguments.
1201 __ Bind(&type_arguments_instantiated); 1178 __ Bind(&type_arguments_instantiated);
1202 ASSERT(instantiator_reg == result_reg); 1179 ASSERT(instantiator_reg == result_reg);
1203 // 'result_reg': Instantiated type arguments. 1180 // 'result_reg': Instantiated type arguments.
1204 } 1181 }
1205 1182
1206 1183
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1342 1319
1343 1320
1344 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1321 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1345 ASSERT(locs()->temp(0).reg() == EDX); 1322 ASSERT(locs()->temp(0).reg() == EDX);
1346 ASSERT(locs()->out().reg() == EAX); 1323 ASSERT(locs()->out().reg() == EAX);
1347 1324
1348 __ movl(EDX, Immediate(num_context_variables())); 1325 __ movl(EDX, Immediate(num_context_variables()));
1349 const ExternalLabel label("alloc_context", 1326 const ExternalLabel label("alloc_context",
1350 StubCode::AllocateContextEntryPoint()); 1327 StubCode::AllocateContextEntryPoint());
1351 compiler->GenerateCall(token_pos(), 1328 compiler->GenerateCall(token_pos(),
1352 try_index(),
1353 &label, 1329 &label,
1354 PcDescriptors::kOther, 1330 PcDescriptors::kOther,
1355 locs()); 1331 locs());
1356 } 1332 }
1357 1333
1358 1334
1359 LocationSummary* CloneContextComp::MakeLocationSummary() const { 1335 LocationSummary* CloneContextComp::MakeLocationSummary() const {
1360 const intptr_t kNumInputs = 1; 1336 const intptr_t kNumInputs = 1;
1361 const intptr_t kNumTemps = 0; 1337 const intptr_t kNumTemps = 0;
1362 LocationSummary* locs = 1338 LocationSummary* locs =
1363 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1339 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1364 locs->set_in(0, Location::RegisterLocation(EAX)); 1340 locs->set_in(0, Location::RegisterLocation(EAX));
1365 locs->set_out(Location::RegisterLocation(EAX)); 1341 locs->set_out(Location::RegisterLocation(EAX));
1366 return locs; 1342 return locs;
1367 } 1343 }
1368 1344
1369 1345
1370 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1346 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1371 Register context_value = locs()->in(0).reg(); 1347 Register context_value = locs()->in(0).reg();
1372 Register result = locs()->out().reg(); 1348 Register result = locs()->out().reg();
1373 1349
1374 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1350 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1375 __ pushl(context_value); 1351 __ pushl(context_value);
1376 compiler->GenerateCallRuntime(deopt_id(), 1352 compiler->GenerateCallRuntime(deopt_id(),
1377 token_pos(), 1353 token_pos(),
1378 try_index(),
1379 kCloneContextRuntimeEntry, 1354 kCloneContextRuntimeEntry,
1380 locs()); 1355 locs());
1381 __ popl(result); // Remove argument. 1356 __ popl(result); // Remove argument.
1382 __ popl(result); // Get result (cloned context). 1357 __ popl(result); // Get result (cloned context).
1383 } 1358 }
1384 1359
1385 1360
1386 LocationSummary* CatchEntryComp::MakeLocationSummary() const { 1361 LocationSummary* CatchEntryComp::MakeLocationSummary() const {
1387 return LocationSummary::Make(0, 1362 return LocationSummary::Make(0,
1388 Location::NoLocation(), 1363 Location::NoLocation(),
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 class CheckStackOverflowSlowPath : public SlowPathCode { 1399 class CheckStackOverflowSlowPath : public SlowPathCode {
1425 public: 1400 public:
1426 explicit CheckStackOverflowSlowPath(CheckStackOverflowComp* computation) 1401 explicit CheckStackOverflowSlowPath(CheckStackOverflowComp* computation)
1427 : computation_(computation) { } 1402 : computation_(computation) { }
1428 1403
1429 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1404 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1430 __ Bind(entry_label()); 1405 __ Bind(entry_label());
1431 compiler->SaveLiveRegisters(computation_->locs()); 1406 compiler->SaveLiveRegisters(computation_->locs());
1432 compiler->GenerateCallRuntime(computation_->deopt_id(), 1407 compiler->GenerateCallRuntime(computation_->deopt_id(),
1433 computation_->token_pos(), 1408 computation_->token_pos(),
1434 computation_->try_index(),
1435 kStackOverflowRuntimeEntry, 1409 kStackOverflowRuntimeEntry,
1436 computation_->locs()); 1410 computation_->locs());
1437 compiler->RestoreLiveRegisters(computation_->locs()); 1411 compiler->RestoreLiveRegisters(computation_->locs());
1438 __ jmp(exit_label()); 1412 __ jmp(exit_label());
1439 } 1413 }
1440 1414
1441 private: 1415 private:
1442 CheckStackOverflowComp* computation_; 1416 CheckStackOverflowComp* computation_;
1443 }; 1417 };
1444 1418
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1613 __ Bind(&call_method); 1587 __ Bind(&call_method);
1614 Function& target = Function::ZoneHandle( 1588 Function& target = Function::ZoneHandle(
1615 ic_data()->GetTargetForReceiverClassId(kSmiCid)); 1589 ic_data()->GetTargetForReceiverClassId(kSmiCid));
1616 ASSERT(!target.IsNull()); 1590 ASSERT(!target.IsNull());
1617 const intptr_t kArgumentCount = 2; 1591 const intptr_t kArgumentCount = 2;
1618 __ pushl(temp); 1592 __ pushl(temp);
1619 __ pushl(right); 1593 __ pushl(right);
1620 compiler->GenerateStaticCall( 1594 compiler->GenerateStaticCall(
1621 instance_call()->deopt_id(), 1595 instance_call()->deopt_id(),
1622 instance_call()->token_pos(), 1596 instance_call()->token_pos(),
1623 instance_call()->try_index(),
1624 target, 1597 target,
1625 kArgumentCount, 1598 kArgumentCount,
1626 Array::Handle(), // No argument names. 1599 Array::Handle(), // No argument names.
1627 locs()); 1600 locs());
1628 ASSERT(result == EAX); 1601 ASSERT(result == EAX);
1629 } 1602 }
1630 __ Bind(&done); 1603 __ Bind(&done);
1631 break; 1604 break;
1632 } 1605 }
1633 case Token::kDIV: { 1606 case Token::kDIV: {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1720 Function& target = Function::ZoneHandle( 1693 Function& target = Function::ZoneHandle(
1721 ic_data()->GetTargetForReceiverClassId(kSmiCid)); 1694 ic_data()->GetTargetForReceiverClassId(kSmiCid));
1722 if (target.IsNull()) { 1695 if (target.IsNull()) {
1723 __ jmp(deopt); 1696 __ jmp(deopt);
1724 } else { 1697 } else {
1725 __ pushl(left); 1698 __ pushl(left);
1726 __ pushl(right); 1699 __ pushl(right);
1727 compiler->GenerateStaticCall( 1700 compiler->GenerateStaticCall(
1728 instance_call()->deopt_id(), 1701 instance_call()->deopt_id(),
1729 instance_call()->token_pos(), 1702 instance_call()->token_pos(),
1730 instance_call()->try_index(),
1731 target, 1703 target,
1732 instance_call()->ArgumentCount(), 1704 instance_call()->ArgumentCount(),
1733 instance_call()->argument_names(), 1705 instance_call()->argument_names(),
1734 locs()); 1706 locs());
1735 ASSERT(result == EAX); 1707 ASSERT(result == EAX);
1736 __ jmp(&done); 1708 __ jmp(&done);
1737 } 1709 }
1738 } 1710 }
1739 1711
1740 __ Bind(&mint_static_call); 1712 __ Bind(&mint_static_call);
1741 { 1713 {
1742 Function& target = Function::ZoneHandle( 1714 Function& target = Function::ZoneHandle(
1743 ic_data()->GetTargetForReceiverClassId(kMintCid)); 1715 ic_data()->GetTargetForReceiverClassId(kMintCid));
1744 if (target.IsNull()) { 1716 if (target.IsNull()) {
1745 __ jmp(deopt); 1717 __ jmp(deopt);
1746 } else { 1718 } else {
1747 __ pushl(left); 1719 __ pushl(left);
1748 __ pushl(right); 1720 __ pushl(right);
1749 compiler->GenerateStaticCall( 1721 compiler->GenerateStaticCall(
1750 instance_call()->deopt_id(), 1722 instance_call()->deopt_id(),
1751 instance_call()->token_pos(), 1723 instance_call()->token_pos(),
1752 instance_call()->try_index(),
1753 target, 1724 target,
1754 instance_call()->ArgumentCount(), 1725 instance_call()->ArgumentCount(),
1755 instance_call()->argument_names(), 1726 instance_call()->argument_names(),
1756 locs()); 1727 locs());
1757 ASSERT(result == EAX); 1728 ASSERT(result == EAX);
1758 } 1729 }
1759 } 1730 }
1760 __ Bind(&done); 1731 __ Bind(&done);
1761 } 1732 }
1762 1733
1763 1734
1764 LocationSummary* BinaryDoubleOpComp::MakeLocationSummary() const { 1735 LocationSummary* BinaryDoubleOpComp::MakeLocationSummary() const {
1765 return MakeCallSummary(); // Calls into a stub for allocation. 1736 return MakeCallSummary(); // Calls into a stub for allocation.
1766 } 1737 }
1767 1738
1768 1739
1769 void BinaryDoubleOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1740 void BinaryDoubleOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1770 Register left = EBX; 1741 Register left = EBX;
1771 Register right = ECX; 1742 Register right = ECX;
1772 Register temp = EDX; 1743 Register temp = EDX;
1773 Register result = locs()->out().reg(); 1744 Register result = locs()->out().reg();
1774 1745
1775 const Class& double_class = compiler->double_class(); 1746 const Class& double_class = compiler->double_class();
1776 const Code& stub = 1747 const Code& stub =
1777 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1748 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1778 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1749 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1779 compiler->GenerateCall(instance_call()->token_pos(), 1750 compiler->GenerateCall(instance_call()->token_pos(),
1780 instance_call()->try_index(),
1781 &label, 1751 &label,
1782 PcDescriptors::kOther, 1752 PcDescriptors::kOther,
1783 locs()); 1753 locs());
1784 // Newly allocated object is now in the result register (RAX). 1754 // Newly allocated object is now in the result register (RAX).
1785 ASSERT(result == EAX); 1755 ASSERT(result == EAX);
1786 __ movl(right, Address(ESP, 0)); 1756 __ movl(right, Address(ESP, 0));
1787 __ movl(left, Address(ESP, kWordSize)); 1757 __ movl(left, Address(ESP, kWordSize));
1788 1758
1789 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1759 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1790 kDeoptBinaryDoubleOp); 1760 kDeoptBinaryDoubleOp);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1863 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1833 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1864 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1834 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1865 1835
1866 // TODO(vegorov): here stack map needs to be set up correctly to skip 1836 // TODO(vegorov): here stack map needs to be set up correctly to skip
1867 // double registers. 1837 // double registers.
1868 LocationSummary* locs = computation_->locs(); 1838 LocationSummary* locs = computation_->locs();
1869 locs->live_registers()->Remove(locs->out()); 1839 locs->live_registers()->Remove(locs->out());
1870 1840
1871 compiler->SaveLiveRegisters(locs); 1841 compiler->SaveLiveRegisters(locs);
1872 compiler->GenerateCall(computation_->instance_call()->token_pos(), 1842 compiler->GenerateCall(computation_->instance_call()->token_pos(),
1873 computation_->instance_call()->try_index(),
1874 &label, 1843 &label,
1875 PcDescriptors::kOther, 1844 PcDescriptors::kOther,
1876 locs); 1845 locs);
1877 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX); 1846 if (EAX != locs->out().reg()) __ movl(locs->out().reg(), EAX);
1878 compiler->RestoreLiveRegisters(locs); 1847 compiler->RestoreLiveRegisters(locs);
1879 1848
1880 __ jmp(exit_label()); 1849 __ jmp(exit_label());
1881 } 1850 }
1882 1851
1883 private: 1852 private:
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2028 __ j(ZERO, deopt); // Smi. 1997 __ j(ZERO, deopt); // Smi.
2029 __ CompareClassId(value, kDoubleCid, temp); 1998 __ CompareClassId(value, kDoubleCid, temp);
2030 __ j(NOT_EQUAL, deopt); 1999 __ j(NOT_EQUAL, deopt);
2031 // Allocate result object. 2000 // Allocate result object.
2032 const Class& double_class = compiler->double_class(); 2001 const Class& double_class = compiler->double_class();
2033 const Code& stub = 2002 const Code& stub =
2034 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 2003 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2035 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 2004 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
2036 __ pushl(value); 2005 __ pushl(value);
2037 compiler->GenerateCall(instance_call()->token_pos(), 2006 compiler->GenerateCall(instance_call()->token_pos(),
2038 instance_call()->try_index(),
2039 &label, 2007 &label,
2040 PcDescriptors::kOther, 2008 PcDescriptors::kOther,
2041 locs()); 2009 locs());
2042 // Result is in EAX. 2010 // Result is in EAX.
2043 ASSERT(result != temp); 2011 ASSERT(result != temp);
2044 __ movl(result, EAX); 2012 __ movl(result, EAX);
2045 __ popl(temp); 2013 __ popl(temp);
2046 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); 2014 __ movsd(XMM0, FieldAddress(temp, Double::value_offset()));
2047 __ DoubleNegate(XMM0); 2015 __ DoubleNegate(XMM0);
2048 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 2016 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2091 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 2059 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
2092 kDeoptIntegerToDouble); 2060 kDeoptIntegerToDouble);
2093 2061
2094 const Class& double_class = compiler->double_class(); 2062 const Class& double_class = compiler->double_class();
2095 const Code& stub = 2063 const Code& stub =
2096 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 2064 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
2097 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 2065 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
2098 2066
2099 // TODO(vegorov): allocate box in the driver loop to avoid spilling. 2067 // TODO(vegorov): allocate box in the driver loop to avoid spilling.
2100 compiler->GenerateCall(instance_call()->token_pos(), 2068 compiler->GenerateCall(instance_call()->token_pos(),
2101 instance_call()->try_index(),
2102 &label, 2069 &label,
2103 PcDescriptors::kOther, 2070 PcDescriptors::kOther,
2104 locs()); 2071 locs());
2105 ASSERT(result == EAX); 2072 ASSERT(result == EAX);
2106 Register value = EBX; 2073 Register value = EBX;
2107 // Preserve argument on the stack until after the deoptimization point. 2074 // Preserve argument on the stack until after the deoptimization point.
2108 __ movl(value, Address(ESP, 0)); 2075 __ movl(value, Address(ESP, 0));
2109 2076
2110 __ testl(value, Immediate(kSmiTagMask)); 2077 __ testl(value, Immediate(kSmiTagMask));
2111 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. 2078 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi.
(...skipping 15 matching lines...) Expand all
2127 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) { 2094 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) {
2128 __ jmp(deopt); 2095 __ jmp(deopt);
2129 return; 2096 return;
2130 } 2097 }
2131 ASSERT(HasICData()); 2098 ASSERT(HasICData());
2132 ASSERT(ic_data()->num_args_tested() == 1); 2099 ASSERT(ic_data()->num_args_tested() == 1);
2133 if (!with_checks()) { 2100 if (!with_checks()) {
2134 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); 2101 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0));
2135 compiler->GenerateStaticCall(instance_call()->deopt_id(), 2102 compiler->GenerateStaticCall(instance_call()->deopt_id(),
2136 instance_call()->token_pos(), 2103 instance_call()->token_pos(),
2137 instance_call()->try_index(),
2138 target, 2104 target,
2139 instance_call()->ArgumentCount(), 2105 instance_call()->ArgumentCount(),
2140 instance_call()->argument_names(), 2106 instance_call()->argument_names(),
2141 locs()); 2107 locs());
2142 return; 2108 return;
2143 } 2109 }
2144 2110
2145 // Load receiver into EAX. 2111 // Load receiver into EAX.
2146 __ movl(EAX, 2112 __ movl(EAX,
2147 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize)); 2113 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize));
2148 2114
2149 Label done; 2115 Label done;
2150 __ movl(EDI, Immediate(kSmiCid)); 2116 __ movl(EDI, Immediate(kSmiCid));
2151 __ testl(EAX, Immediate(kSmiTagMask)); 2117 __ testl(EAX, Immediate(kSmiTagMask));
2152 __ j(ZERO, &done); 2118 __ j(ZERO, &done);
2153 __ LoadClassId(EDI, EAX); 2119 __ LoadClassId(EDI, EAX);
2154 __ Bind(&done); 2120 __ Bind(&done);
2155 2121
2156 compiler->EmitTestAndCall(*ic_data(), 2122 compiler->EmitTestAndCall(*ic_data(),
2157 EDI, // Class id register. 2123 EDI, // Class id register.
2158 instance_call()->ArgumentCount(), 2124 instance_call()->ArgumentCount(),
2159 instance_call()->argument_names(), 2125 instance_call()->argument_names(),
2160 deopt, 2126 deopt,
2161 instance_call()->deopt_id(), 2127 instance_call()->deopt_id(),
2162 instance_call()->token_pos(), 2128 instance_call()->token_pos(),
2163 instance_call()->try_index(),
2164 locs()); 2129 locs());
2165 } 2130 }
2166 2131
2167 2132
2168 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2133 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2169 computation()->EmitBranchCode(compiler, this); 2134 computation()->EmitBranchCode(compiler, this);
2170 } 2135 }
2171 2136
2172 2137
2173 LocationSummary* CheckClassComp::MakeLocationSummary() const { 2138 LocationSummary* CheckClassComp::MakeLocationSummary() const {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
2256 } 2221 }
2257 __ j(ABOVE_EQUAL, deopt); 2222 __ j(ABOVE_EQUAL, deopt);
2258 } 2223 }
2259 2224
2260 2225
2261 } // namespace dart 2226 } // namespace dart
2262 2227
2263 #undef __ 2228 #undef __
2264 2229
2265 #endif // defined TARGET_ARCH_X64 2230 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698