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

Side by Side Diff: vm/intermediate_language_ia32.cc

Issue 10632009: Make the parser agnostic to the TokenStream implementation. This is the first step towards compacti… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 6 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 | « vm/intermediate_language.cc ('k') | vm/intermediate_language_x64.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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 __ popl(result); // Restore result. 92 __ popl(result); // Restore result.
93 } 93 }
94 __ LeaveFrame(); 94 __ LeaveFrame();
95 __ ret(); 95 __ ret();
96 96
97 // Generate 1 byte NOP so that the debugger can patch the 97 // Generate 1 byte NOP so that the debugger can patch the
98 // return pattern with a call to the debug stub. 98 // return pattern with a call to the debug stub.
99 __ nop(1); 99 __ nop(1);
100 compiler->AddCurrentDescriptor(PcDescriptors::kReturn, 100 compiler->AddCurrentDescriptor(PcDescriptors::kReturn,
101 cid(), 101 cid(),
102 token_index(), 102 token_pos(),
103 CatchClauseNode::kInvalidTryIndex); 103 CatchClauseNode::kInvalidTryIndex);
104 } 104 }
105 105
106 106
107 LocationSummary* ClosureCallComp::MakeLocationSummary() const { 107 LocationSummary* ClosureCallComp::MakeLocationSummary() const {
108 const intptr_t kNumInputs = 0; 108 const intptr_t kNumInputs = 0;
109 const intptr_t kNumTemps = 1; 109 const intptr_t kNumTemps = 1;
110 LocationSummary* result = new LocationSummary(kNumInputs, 110 LocationSummary* result = new LocationSummary(kNumInputs,
111 kNumTemps, 111 kNumTemps,
112 LocationSummary::kCall); 112 LocationSummary::kCall);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 Register result = locs()->out().reg(); 171 Register result = locs()->out().reg();
172 172
173 // Check that the type of the value is allowed in conditional context. 173 // Check that the type of the value is allowed in conditional context.
174 // Call the runtime if the object is not bool::true or bool::false. 174 // Call the runtime if the object is not bool::true or bool::false.
175 Label done; 175 Label done;
176 __ CompareObject(obj, compiler->bool_true()); 176 __ CompareObject(obj, compiler->bool_true());
177 __ j(EQUAL, &done, Assembler::kNearJump); 177 __ j(EQUAL, &done, Assembler::kNearJump);
178 __ CompareObject(obj, compiler->bool_false()); 178 __ CompareObject(obj, compiler->bool_false());
179 __ j(EQUAL, &done, Assembler::kNearJump); 179 __ j(EQUAL, &done, Assembler::kNearJump);
180 180
181 __ pushl(Immediate(Smi::RawValue(token_index()))); // Source location. 181 __ pushl(Immediate(Smi::RawValue(token_pos()))); // Source location.
182 __ pushl(obj); // Push the source object. 182 __ pushl(obj); // Push the source object.
183 compiler->GenerateCallRuntime(cid(), 183 compiler->GenerateCallRuntime(cid(),
184 token_index(), 184 token_pos(),
185 try_index(), 185 try_index(),
186 kConditionTypeErrorRuntimeEntry); 186 kConditionTypeErrorRuntimeEntry);
187 // We should never return here. 187 // We should never return here.
188 __ int3(); 188 __ int3();
189 189
190 __ Bind(&done); 190 __ Bind(&done);
191 ASSERT(obj == result); 191 ASSERT(obj == result);
192 } 192 }
193 193
194 194
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 return locs; 241 return locs;
242 } 242 }
243 243
244 244
245 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler, 245 static void EmitSmiEqualityCompare(FlowGraphCompiler* compiler,
246 EqualityCompareComp* comp) { 246 EqualityCompareComp* comp) {
247 Register left = comp->locs()->in(0).reg(); 247 Register left = comp->locs()->in(0).reg();
248 Register right = comp->locs()->in(1).reg(); 248 Register right = comp->locs()->in(1).reg();
249 Register temp = comp->locs()->temp(0).reg(); 249 Register temp = comp->locs()->temp(0).reg();
250 Label* deopt = compiler->AddDeoptStub(comp->cid(), 250 Label* deopt = compiler->AddDeoptStub(comp->cid(),
251 comp->token_index(), 251 comp->token_pos(),
252 comp->try_index(), 252 comp->try_index(),
253 kDeoptSmiCompareSmis, 253 kDeoptSmiCompareSmis,
254 left, 254 left,
255 right); 255 right);
256 // TODO(srdjan): Should we always include NULL test (common case)? 256 // TODO(srdjan): Should we always include NULL test (common case)?
257 __ movl(temp, left); 257 __ movl(temp, left);
258 __ orl(temp, right); 258 __ orl(temp, right);
259 __ testl(temp, Immediate(kSmiTagMask)); 259 __ testl(temp, Immediate(kSmiTagMask));
260 __ j(NOT_ZERO, deopt); 260 __ j(NOT_ZERO, deopt);
261 __ cmpl(left, right); 261 __ cmpl(left, right);
262 if (comp->is_fused_with_branch()) { 262 if (comp->is_fused_with_branch()) {
263 comp->fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL); 263 comp->fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL);
264 } else { 264 } else {
265 Register result = comp->locs()->out().reg(); 265 Register result = comp->locs()->out().reg();
266 Label load_true, done; 266 Label load_true, done;
267 __ j(EQUAL, &load_true, Assembler::kNearJump); 267 __ j(EQUAL, &load_true, Assembler::kNearJump);
268 __ LoadObject(result, compiler->bool_false()); 268 __ LoadObject(result, compiler->bool_false());
269 __ jmp(&done, Assembler::kNearJump); 269 __ jmp(&done, Assembler::kNearJump);
270 __ Bind(&load_true); 270 __ Bind(&load_true);
271 __ LoadObject(result, compiler->bool_true()); 271 __ LoadObject(result, compiler->bool_true());
272 __ Bind(&done); 272 __ Bind(&done);
273 } 273 }
274 } 274 }
275 275
276 276
277 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, 277 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
278 EqualityCompareComp* comp) { 278 EqualityCompareComp* comp) {
279 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 279 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
280 comp->cid(), 280 comp->cid(),
281 comp->token_index(), 281 comp->token_pos(),
282 comp->try_index()); 282 comp->try_index());
283 const String& operator_name = String::ZoneHandle(String::NewSymbol("==")); 283 const String& operator_name = String::ZoneHandle(String::NewSymbol("=="));
284 const int kNumberOfArguments = 2; 284 const int kNumberOfArguments = 2;
285 const Array& kNoArgumentNames = Array::Handle(); 285 const Array& kNoArgumentNames = Array::Handle();
286 const int kNumArgumentsChecked = 2; 286 const int kNumArgumentsChecked = 2;
287 287
288 compiler->GenerateInstanceCall(comp->cid(), 288 compiler->GenerateInstanceCall(comp->cid(),
289 comp->token_index(), 289 comp->token_pos(),
290 comp->try_index(), 290 comp->try_index(),
291 operator_name, 291 operator_name,
292 kNumberOfArguments, 292 kNumberOfArguments,
293 kNoArgumentNames, 293 kNoArgumentNames,
294 kNumArgumentsChecked); 294 kNumArgumentsChecked);
295 ASSERT(comp->is_fused_with_branch() || (comp->locs()->out().reg() == EAX)); 295 ASSERT(comp->is_fused_with_branch() || (comp->locs()->out().reg() == EAX));
296 296
297 if (comp->is_fused_with_branch()) { 297 if (comp->is_fused_with_branch()) {
298 __ CompareObject(EAX, compiler->bool_true()); 298 __ CompareObject(EAX, compiler->bool_true());
299 comp->fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL); 299 comp->fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL);
300 } 300 }
301 } 301 }
302 302
303 303
304 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, 304 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
305 EqualityCompareComp* comp, 305 EqualityCompareComp* comp,
306 Register left, 306 Register left,
307 Register right) { 307 Register right) {
308 ASSERT(comp->HasICData()); 308 ASSERT(comp->HasICData());
309 const ICData& ic_data = *comp->ic_data(); 309 const ICData& ic_data = *comp->ic_data();
310 ASSERT(ic_data.NumberOfChecks() > 0); 310 ASSERT(ic_data.NumberOfChecks() > 0);
311 ASSERT(ic_data.num_args_tested() == 1); 311 ASSERT(ic_data.num_args_tested() == 1);
312 Label* deopt = compiler->AddDeoptStub(comp->cid(), 312 Label* deopt = compiler->AddDeoptStub(comp->cid(),
313 comp->token_index(), 313 comp->token_pos(),
314 comp->try_index(), 314 comp->try_index(),
315 kDeoptEquality); 315 kDeoptEquality);
316 __ testl(left, Immediate(kSmiTagMask)); 316 __ testl(left, Immediate(kSmiTagMask));
317 Register temp = comp->locs()->temp(0).reg(); 317 Register temp = comp->locs()->temp(0).reg();
318 if (ic_data.GetReceiverClassIdAt(0) == kSmi) { 318 if (ic_data.GetReceiverClassIdAt(0) == kSmi) {
319 Label done, load_class_id; 319 Label done, load_class_id;
320 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump); 320 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump);
321 __ movl(temp, Immediate(kSmi)); 321 __ movl(temp, Immediate(kSmi));
322 __ jmp(&done, Assembler::kNearJump); 322 __ jmp(&done, Assembler::kNearJump);
323 __ Bind(&load_class_id); 323 __ Bind(&load_class_id);
(...skipping 24 matching lines...) Expand all
348 __ j(EQUAL, &load_true, Assembler::kNearJump); 348 __ j(EQUAL, &load_true, Assembler::kNearJump);
349 __ LoadObject(result, compiler->bool_false()); 349 __ LoadObject(result, compiler->bool_false());
350 __ jmp(&done); 350 __ jmp(&done);
351 __ Bind(&load_true); 351 __ Bind(&load_true);
352 __ LoadObject(result, compiler->bool_true()); 352 __ LoadObject(result, compiler->bool_true());
353 } 353 }
354 } else { 354 } else {
355 const int kNumberOfArguments = 2; 355 const int kNumberOfArguments = 2;
356 const Array& kNoArgumentNames = Array::Handle(); 356 const Array& kNoArgumentNames = Array::Handle();
357 compiler->GenerateStaticCall(comp->cid(), 357 compiler->GenerateStaticCall(comp->cid(),
358 comp->token_index(), 358 comp->token_pos(),
359 comp->try_index(), 359 comp->try_index(),
360 target, 360 target,
361 kNumberOfArguments, 361 kNumberOfArguments,
362 kNoArgumentNames); 362 kNoArgumentNames);
363 ASSERT(comp->is_fused_with_branch() || 363 ASSERT(comp->is_fused_with_branch() ||
364 (comp->locs()->out().reg() == EAX)); 364 (comp->locs()->out().reg() == EAX));
365 if (comp->is_fused_with_branch()) { 365 if (comp->is_fused_with_branch()) {
366 __ CompareObject(EAX, compiler->bool_true()); 366 __ CompareObject(EAX, compiler->bool_true());
367 comp->fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL); 367 comp->fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL);
368 } 368 }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 } 466 }
467 } 467 }
468 468
469 469
470 static void EmitSmiRelationalOp(FlowGraphCompiler* compiler, 470 static void EmitSmiRelationalOp(FlowGraphCompiler* compiler,
471 RelationalOpComp* comp) { 471 RelationalOpComp* comp) {
472 Register left = comp->locs()->in(0).reg(); 472 Register left = comp->locs()->in(0).reg();
473 Register right = comp->locs()->in(1).reg(); 473 Register right = comp->locs()->in(1).reg();
474 Register temp = comp->locs()->temp(0).reg(); 474 Register temp = comp->locs()->temp(0).reg();
475 Label* deopt = compiler->AddDeoptStub(comp->cid(), 475 Label* deopt = compiler->AddDeoptStub(comp->cid(),
476 comp->token_index(), 476 comp->token_pos(),
477 comp->try_index(), 477 comp->try_index(),
478 kDeoptSmiCompareSmis, 478 kDeoptSmiCompareSmis,
479 left, 479 left,
480 right); 480 right);
481 __ movl(temp, left); 481 __ movl(temp, left);
482 __ orl(temp, right); 482 __ orl(temp, right);
483 __ testl(temp, Immediate(kSmiTagMask)); 483 __ testl(temp, Immediate(kSmiTagMask));
484 __ j(NOT_ZERO, deopt); 484 __ j(NOT_ZERO, deopt);
485 485
486 Condition true_condition = TokenKindToSmiCondition(comp->kind()); 486 Condition true_condition = TokenKindToSmiCondition(comp->kind());
(...skipping 28 matching lines...) Expand all
515 } 515 }
516 516
517 517
518 static void EmitDoubleRelationalOp(FlowGraphCompiler* compiler, 518 static void EmitDoubleRelationalOp(FlowGraphCompiler* compiler,
519 RelationalOpComp* comp) { 519 RelationalOpComp* comp) {
520 Register left = comp->locs()->in(0).reg(); 520 Register left = comp->locs()->in(0).reg();
521 Register right = comp->locs()->in(1).reg(); 521 Register right = comp->locs()->in(1).reg();
522 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs. 522 // TODO(srdjan): temp is only needed if a conversion Smi->Double occurs.
523 Register temp = comp->locs()->temp(0).reg(); 523 Register temp = comp->locs()->temp(0).reg();
524 Label* deopt = compiler->AddDeoptStub(comp->cid(), 524 Label* deopt = compiler->AddDeoptStub(comp->cid(),
525 comp->token_index(), 525 comp->token_pos(),
526 comp->try_index(), 526 comp->try_index(),
527 kDeoptDoubleComparison, 527 kDeoptDoubleComparison,
528 left, 528 left,
529 right); 529 right);
530 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt); 530 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt);
531 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt); 531 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
532 532
533 Condition true_condition = TokenKindToDoubleCondition(comp->kind()); 533 Condition true_condition = TokenKindToDoubleCondition(comp->kind());
534 __ comisd(XMM0, XMM1); 534 __ comisd(XMM0, XMM1);
535 535
(...skipping 24 matching lines...) Expand all
560 return; 560 return;
561 } 561 }
562 if (operands_class_id() == kDouble) { 562 if (operands_class_id() == kDouble) {
563 EmitDoubleRelationalOp(compiler, this); 563 EmitDoubleRelationalOp(compiler, this);
564 return; 564 return;
565 } 565 }
566 const String& function_name = 566 const String& function_name =
567 String::ZoneHandle(String::NewSymbol(Token::Str(kind()))); 567 String::ZoneHandle(String::NewSymbol(Token::Str(kind())));
568 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 568 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
569 cid(), 569 cid(),
570 token_index(), 570 token_pos(),
571 try_index()); 571 try_index());
572 const intptr_t kNumArguments = 2; 572 const intptr_t kNumArguments = 2;
573 const intptr_t kNumArgsChecked = 2; // Type-feedback. 573 const intptr_t kNumArgsChecked = 2; // Type-feedback.
574 compiler->GenerateInstanceCall(cid(), 574 compiler->GenerateInstanceCall(cid(),
575 token_index(), 575 token_pos(),
576 try_index(), 576 try_index(),
577 function_name, 577 function_name,
578 kNumArguments, 578 kNumArguments,
579 Array::ZoneHandle(), // No optional arguments. 579 Array::ZoneHandle(), // No optional arguments.
580 kNumArgsChecked); 580 kNumArgsChecked);
581 ASSERT(locs()->out().reg() == EAX); 581 ASSERT(locs()->out().reg() == EAX);
582 } 582 }
583 583
584 584
585 LocationSummary* NativeCallComp::MakeLocationSummary() const { 585 LocationSummary* NativeCallComp::MakeLocationSummary() const {
(...skipping 24 matching lines...) Expand all
610 arg_count += 1; 610 arg_count += 1;
611 } 611 }
612 if (!has_optional_parameters() && !is_native_instance_closure()) { 612 if (!has_optional_parameters() && !is_native_instance_closure()) {
613 __ leal(EAX, Address(EBP, (1 + arg_count) * kWordSize)); 613 __ leal(EAX, Address(EBP, (1 + arg_count) * kWordSize));
614 } else { 614 } else {
615 __ leal(EAX, 615 __ leal(EAX,
616 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); 616 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize));
617 } 617 }
618 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); 618 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function())));
619 __ movl(EDX, Immediate(arg_count)); 619 __ movl(EDX, Immediate(arg_count));
620 compiler->GenerateCall(token_index(), 620 compiler->GenerateCall(token_pos(),
621 try_index(), 621 try_index(),
622 &StubCode::CallNativeCFunctionLabel(), 622 &StubCode::CallNativeCFunctionLabel(),
623 PcDescriptors::kOther); 623 PcDescriptors::kOther);
624 __ popl(result); 624 __ popl(result);
625 } 625 }
626 626
627 627
628 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { 628 LocationSummary* LoadIndexedComp::MakeLocationSummary() const {
629 const intptr_t kNumInputs = 2; 629 const intptr_t kNumInputs = 2;
630 if ((receiver_type() == kGrowableObjectArray) || 630 if ((receiver_type() == kGrowableObjectArray) ||
631 (receiver_type() == kArray) || 631 (receiver_type() == kArray) ||
632 (receiver_type() == kImmutableArray)) { 632 (receiver_type() == kImmutableArray)) {
633 const intptr_t kNumTemps = 1; 633 const intptr_t kNumTemps = 1;
634 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); 634 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
635 locs->set_in(0, Location::RequiresRegister()); 635 locs->set_in(0, Location::RequiresRegister());
636 locs->set_in(1, Location::RequiresRegister()); 636 locs->set_in(1, Location::RequiresRegister());
637 locs->set_temp(0, Location::RequiresRegister()); 637 locs->set_temp(0, Location::RequiresRegister());
638 locs->set_out(Location::RequiresRegister()); 638 locs->set_out(Location::RequiresRegister());
639 return locs; 639 return locs;
640 } else { 640 } else {
641 ASSERT(receiver_type() == kIllegalObjectKind); 641 ASSERT(receiver_type() == kIllegalObjectKind);
642 return MakeCallSummary(); 642 return MakeCallSummary();
643 } 643 }
644 } 644 }
645 645
646 646
647 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler, 647 static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler,
648 LoadIndexedComp* comp) { 648 LoadIndexedComp* comp) {
649 Label* deopt = compiler->AddDeoptStub(comp->cid(), 649 Label* deopt = compiler->AddDeoptStub(comp->cid(),
650 comp->token_index(), 650 comp->token_pos(),
651 comp->try_index(), 651 comp->try_index(),
652 kDeoptLoadIndexedPolymorphic); 652 kDeoptLoadIndexedPolymorphic);
653 if (comp->ic_data()->NumberOfChecks() == 0) { 653 if (comp->ic_data()->NumberOfChecks() == 0) {
654 __ jmp(deopt); 654 __ jmp(deopt);
655 return; 655 return;
656 } 656 }
657 ASSERT(comp->HasICData()); 657 ASSERT(comp->HasICData());
658 const ICData& ic_data = *comp->ic_data(); 658 const ICData& ic_data = *comp->ic_data();
659 ASSERT(ic_data.num_args_tested() == 1); 659 ASSERT(ic_data.num_args_tested() == 1);
660 // No indexed access on Smi. 660 // No indexed access on Smi.
661 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi); 661 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi);
662 // Load receiver into EAX. 662 // Load receiver into EAX.
663 const intptr_t kNumArguments = 2; 663 const intptr_t kNumArguments = 2;
664 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); 664 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize));
665 __ testl(EAX, Immediate(kSmiTagMask)); 665 __ testl(EAX, Immediate(kSmiTagMask));
666 __ j(ZERO, deopt); 666 __ j(ZERO, deopt);
667 Label done; 667 Label done;
668 __ LoadClassId(EDI, EAX); 668 __ LoadClassId(EDI, EAX);
669 compiler->EmitTestAndCall(ic_data, 669 compiler->EmitTestAndCall(ic_data,
670 EDI, // Class id register. 670 EDI, // Class id register.
671 kNumArguments, 671 kNumArguments,
672 Array::Handle(), // No named arguments. 672 Array::Handle(), // No named arguments.
673 deopt, &done, // Labels. 673 deopt, &done, // Labels.
674 comp->cid(), 674 comp->cid(),
675 comp->token_index(), 675 comp->token_pos(),
676 comp->try_index()); 676 comp->try_index());
677 __ Bind(&done); 677 __ Bind(&done);
678 } 678 }
679 679
680 680
681 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 681 void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
682 if (receiver_type() == kIllegalObjectKind) { 682 if (receiver_type() == kIllegalObjectKind) {
683 if (HasICData()) { 683 if (HasICData()) {
684 EmitLoadIndexedPolymorphic(compiler, this); 684 EmitLoadIndexedPolymorphic(compiler, this);
685 } else { 685 } else {
686 compiler->EmitLoadIndexedGeneric(this); 686 compiler->EmitLoadIndexedGeneric(this);
687 } 687 }
688 ASSERT(locs()->out().reg() == EAX); 688 ASSERT(locs()->out().reg() == EAX);
689 return; 689 return;
690 } 690 }
691 691
692 Register receiver = locs()->in(0).reg(); 692 Register receiver = locs()->in(0).reg();
693 Register index = locs()->in(1).reg(); 693 Register index = locs()->in(1).reg();
694 Register result = locs()->out().reg(); 694 Register result = locs()->out().reg();
695 Register temp = locs()->temp(0).reg(); 695 Register temp = locs()->temp(0).reg();
696 696
697 const DeoptReasonId deopt_reason = (receiver_type() == kGrowableObjectArray) ? 697 const DeoptReasonId deopt_reason = (receiver_type() == kGrowableObjectArray) ?
698 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray; 698 kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray;
699 699
700 Label* deopt = compiler->AddDeoptStub(cid(), 700 Label* deopt = compiler->AddDeoptStub(cid(),
701 token_index(), 701 token_pos(),
702 try_index(), 702 try_index(),
703 deopt_reason, 703 deopt_reason,
704 receiver, 704 receiver,
705 index); 705 index);
706 706
707 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 707 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
708 __ j(ZERO, deopt); 708 __ j(ZERO, deopt);
709 __ CompareClassId(receiver, receiver_type(), temp); 709 __ CompareClassId(receiver, receiver_type(), temp);
710 __ j(NOT_EQUAL, deopt); 710 __ j(NOT_EQUAL, deopt);
711 711
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
761 } 761 }
762 762
763 763
764 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler, 764 static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler,
765 StoreIndexedComp* comp) { 765 StoreIndexedComp* comp) {
766 const String& function_name = 766 const String& function_name =
767 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); 767 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX)));
768 768
769 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 769 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
770 comp->cid(), 770 comp->cid(),
771 comp->token_index(), 771 comp->token_pos(),
772 comp->try_index()); 772 comp->try_index());
773 773
774 const intptr_t kNumArguments = 3; 774 const intptr_t kNumArguments = 3;
775 const intptr_t kNumArgsChecked = 1; // Type-feedback. 775 const intptr_t kNumArgsChecked = 1; // Type-feedback.
776 compiler->GenerateInstanceCall(comp->cid(), 776 compiler->GenerateInstanceCall(comp->cid(),
777 comp->token_index(), 777 comp->token_pos(),
778 comp->try_index(), 778 comp->try_index(),
779 function_name, 779 function_name,
780 kNumArguments, 780 kNumArguments,
781 Array::ZoneHandle(), // No named arguments. 781 Array::ZoneHandle(), // No named arguments.
782 kNumArgsChecked); 782 kNumArgsChecked);
783 } 783 }
784 784
785 785
786 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler, 786 static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler,
787 StoreIndexedComp* comp) { 787 StoreIndexedComp* comp) {
788 Label* deopt = compiler->AddDeoptStub(comp->cid(), 788 Label* deopt = compiler->AddDeoptStub(comp->cid(),
789 comp->token_index(), 789 comp->token_pos(),
790 comp->try_index(), 790 comp->try_index(),
791 kDeoptStoreIndexedPolymorphic); 791 kDeoptStoreIndexedPolymorphic);
792 if (comp->ic_data()->NumberOfChecks() == 0) { 792 if (comp->ic_data()->NumberOfChecks() == 0) {
793 __ jmp(deopt); 793 __ jmp(deopt);
794 return; 794 return;
795 } 795 }
796 ASSERT(comp->HasICData()); 796 ASSERT(comp->HasICData());
797 const ICData& ic_data = *comp->ic_data(); 797 const ICData& ic_data = *comp->ic_data();
798 ASSERT(ic_data.num_args_tested() == 1); 798 ASSERT(ic_data.num_args_tested() == 1);
799 // No indexed access on Smi. 799 // No indexed access on Smi.
800 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi); 800 ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi);
801 // Load receiver into EAX. 801 // Load receiver into EAX.
802 const intptr_t kNumArguments = 3; 802 const intptr_t kNumArguments = 3;
803 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize)); 803 __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize));
804 __ testl(EAX, Immediate(kSmiTagMask)); 804 __ testl(EAX, Immediate(kSmiTagMask));
805 __ j(ZERO, deopt); 805 __ j(ZERO, deopt);
806 Label done; 806 Label done;
807 __ LoadClassId(EDI, EAX); 807 __ LoadClassId(EDI, EAX);
808 compiler->EmitTestAndCall(ic_data, 808 compiler->EmitTestAndCall(ic_data,
809 EDI, // Class id register. 809 EDI, // Class id register.
810 kNumArguments, 810 kNumArguments,
811 Array::Handle(), // No named arguments. 811 Array::Handle(), // No named arguments.
812 deopt, &done, // Labels. 812 deopt, &done, // Labels.
813 comp->cid(), 813 comp->cid(),
814 comp->token_index(), 814 comp->token_pos(),
815 comp->try_index()); 815 comp->try_index());
816 __ Bind(&done); 816 __ Bind(&done);
817 } 817 }
818 818
819 819
820 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { 820 void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
821 if (receiver_type() == kIllegalObjectKind) { 821 if (receiver_type() == kIllegalObjectKind) {
822 if (HasICData()) { 822 if (HasICData()) {
823 EmitStoreIndexedPolymorphic(compiler, this); 823 EmitStoreIndexedPolymorphic(compiler, this);
824 } else { 824 } else {
825 EmitStoreIndexedGeneric(compiler, this); 825 EmitStoreIndexedGeneric(compiler, this);
826 } 826 }
827 return; 827 return;
828 } 828 }
829 829
830 Register receiver = locs()->in(0).reg(); 830 Register receiver = locs()->in(0).reg();
831 Register index = locs()->in(1).reg(); 831 Register index = locs()->in(1).reg();
832 Register value = locs()->in(2).reg(); 832 Register value = locs()->in(2).reg();
833 Register temp = locs()->temp(0).reg(); 833 Register temp = locs()->temp(0).reg();
834 834
835 Label* deopt = compiler->AddDeoptStub(cid(), 835 Label* deopt = compiler->AddDeoptStub(cid(),
836 token_index(), 836 token_pos(),
837 try_index(), 837 try_index(),
838 kDeoptStoreIndexed, 838 kDeoptStoreIndexed,
839 receiver, 839 receiver,
840 index, 840 index,
841 value); 841 value);
842 842
843 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi. 843 __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
844 __ j(ZERO, deopt); 844 __ j(ZERO, deopt);
845 __ CompareClassId(receiver, receiver_type(), temp); 845 __ CompareClassId(receiver, receiver_type(), temp);
846 __ j(NOT_EQUAL, deopt); 846 __ j(NOT_EQUAL, deopt);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 return MakeCallSummary(); 884 return MakeCallSummary();
885 } 885 }
886 886
887 887
888 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { 888 void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) {
889 const String& function_name = 889 const String& function_name =
890 String::ZoneHandle(Field::SetterSymbol(field_name())); 890 String::ZoneHandle(Field::SetterSymbol(field_name()));
891 891
892 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 892 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
893 cid(), 893 cid(),
894 token_index(), 894 token_pos(),
895 try_index()); 895 try_index());
896 const intptr_t kArgumentCount = 2; 896 const intptr_t kArgumentCount = 2;
897 const intptr_t kCheckedArgumentCount = 1; 897 const intptr_t kCheckedArgumentCount = 1;
898 compiler->GenerateInstanceCall(cid(), 898 compiler->GenerateInstanceCall(cid(),
899 token_index(), 899 token_pos(),
900 try_index(), 900 try_index(),
901 function_name, 901 function_name,
902 kArgumentCount, 902 kArgumentCount,
903 Array::ZoneHandle(), 903 Array::ZoneHandle(),
904 kCheckedArgumentCount); 904 kCheckedArgumentCount);
905 } 905 }
906 906
907 907
908 LocationSummary* StaticSetterComp::MakeLocationSummary() const { 908 LocationSummary* StaticSetterComp::MakeLocationSummary() const {
909 const intptr_t kNumInputs = 1; 909 const intptr_t kNumInputs = 1;
910 return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); 910 return LocationSummary::Make(kNumInputs, Location::RequiresRegister());
911 } 911 }
912 912
913 913
914 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { 914 void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) {
915 Register value = locs()->in(0).reg(); 915 Register value = locs()->in(0).reg();
916 Register result = locs()->out().reg(); 916 Register result = locs()->out().reg();
917 917
918 // Preserve the argument as the result of the computation, 918 // Preserve the argument as the result of the computation,
919 // then call the setter. 919 // then call the setter.
920 920
921 // Duplicate the argument. 921 // Duplicate the argument.
922 // TODO(fschneider): Avoid preserving the value if the result is not used. 922 // TODO(fschneider): Avoid preserving the value if the result is not used.
923 __ pushl(value); 923 __ pushl(value);
924 __ pushl(value); 924 __ pushl(value);
925 compiler->GenerateStaticCall(cid(), 925 compiler->GenerateStaticCall(cid(),
926 token_index(), 926 token_pos(),
927 try_index(), 927 try_index(),
928 setter_function(), 928 setter_function(),
929 1, 929 1,
930 Array::ZoneHandle()); 930 Array::ZoneHandle());
931 __ popl(result); 931 __ popl(result);
932 } 932 }
933 933
934 934
935 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { 935 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const {
936 // TODO(fschneider): For this instruction the input register may be 936 // TODO(fschneider): For this instruction the input register may be
937 // reused for the result (but is not required to) because the input 937 // reused for the result (but is not required to) because the input
938 // is not used after the result is defined. We should consider adding 938 // is not used after the result is defined. We should consider adding
939 // this information to the input policy. 939 // this information to the input policy.
940 return LocationSummary::Make(1, Location::RequiresRegister()); 940 return LocationSummary::Make(1, Location::RequiresRegister());
941 } 941 }
942 942
943 943
944 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 944 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
945 Register instance_reg = locs()->in(0).reg(); 945 Register instance_reg = locs()->in(0).reg();
946 Register result_reg = locs()->out().reg(); 946 Register result_reg = locs()->out().reg();
947 947
948 if (HasICData()) { 948 if (HasICData()) {
949 ASSERT(original() != NULL); 949 ASSERT(original() != NULL);
950 Label* deopt = compiler->AddDeoptStub(original()->cid(), 950 Label* deopt = compiler->AddDeoptStub(original()->cid(),
951 original()->token_index(), 951 original()->token_pos(),
952 original()->try_index(), 952 original()->try_index(),
953 kDeoptInstanceGetterSameTarget, 953 kDeoptInstanceGetterSameTarget,
954 instance_reg); 954 instance_reg);
955 // Smis do not have instance fields (Smi class is always first). 955 // Smis do not have instance fields (Smi class is always first).
956 // Use 'result' as temporary register. 956 // Use 'result' as temporary register.
957 ASSERT(result_reg != instance_reg); 957 ASSERT(result_reg != instance_reg);
958 ASSERT(ic_data() != NULL); 958 ASSERT(ic_data() != NULL);
959 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); 959 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt);
960 } 960 }
961 __ movl(result_reg, FieldAddress(instance_reg, field().Offset())); 961 __ movl(result_reg, FieldAddress(instance_reg, field().Offset()));
(...skipping 21 matching lines...) Expand all
983 return summary; 983 return summary;
984 } 984 }
985 985
986 986
987 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { 987 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) {
988 ASSERT(locs()->in(0).reg() == EAX); // Value. 988 ASSERT(locs()->in(0).reg() == EAX); // Value.
989 ASSERT(locs()->in(1).reg() == ECX); // Instantiator. 989 ASSERT(locs()->in(1).reg() == ECX); // Instantiator.
990 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. 990 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments.
991 991
992 compiler->GenerateInstanceOf(cid(), 992 compiler->GenerateInstanceOf(cid(),
993 token_index(), 993 token_pos(),
994 try_index(), 994 try_index(),
995 type(), 995 type(),
996 negate_result()); 996 negate_result());
997 ASSERT(locs()->out().reg() == EAX); 997 ASSERT(locs()->out().reg() == EAX);
998 } 998 }
999 999
1000 1000
1001 LocationSummary* CreateArrayComp::MakeLocationSummary() const { 1001 LocationSummary* CreateArrayComp::MakeLocationSummary() const {
1002 // TODO(regis): The elements of the array could be considered as arguments to 1002 // TODO(regis): The elements of the array could be considered as arguments to
1003 // CreateArrayComp, thereby making CreateArrayComp a call. 1003 // CreateArrayComp, thereby making CreateArrayComp a call.
(...skipping 12 matching lines...) Expand all
1016 1016
1017 1017
1018 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1018 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1019 Register temp_reg = locs()->temp(0).reg(); 1019 Register temp_reg = locs()->temp(0).reg();
1020 Register result_reg = locs()->out().reg(); 1020 Register result_reg = locs()->out().reg();
1021 1021
1022 // Allocate the array. EDX = length, ECX = element type. 1022 // Allocate the array. EDX = length, ECX = element type.
1023 ASSERT(temp_reg == EDX); 1023 ASSERT(temp_reg == EDX);
1024 ASSERT(locs()->in(0).reg() == ECX); 1024 ASSERT(locs()->in(0).reg() == ECX);
1025 __ movl(temp_reg, Immediate(Smi::RawValue(ElementCount()))); 1025 __ movl(temp_reg, Immediate(Smi::RawValue(ElementCount())));
1026 compiler->GenerateCall(token_index(), 1026 compiler->GenerateCall(token_pos(),
1027 try_index(), 1027 try_index(),
1028 &StubCode::AllocateArrayLabel(), 1028 &StubCode::AllocateArrayLabel(),
1029 PcDescriptors::kOther); 1029 PcDescriptors::kOther);
1030 ASSERT(result_reg == EAX); 1030 ASSERT(result_reg == EAX);
1031 1031
1032 // Pop the element values from the stack into the array. 1032 // Pop the element values from the stack into the array.
1033 __ leal(temp_reg, FieldAddress(result_reg, Array::data_offset())); 1033 __ leal(temp_reg, FieldAddress(result_reg, Array::data_offset()));
1034 for (int i = ElementCount() - 1; i >= 0; --i) { 1034 for (int i = ElementCount() - 1; i >= 0; --i) {
1035 ASSERT(ElementAt(i)->IsUse()); 1035 ASSERT(ElementAt(i)->IsUse());
1036 __ popl(Address(temp_reg, i * kWordSize)); 1036 __ popl(Address(temp_reg, i * kWordSize));
(...skipping 11 matching lines...) Expand all
1048 1048
1049 void AllocateObjectWithBoundsCheckComp::EmitNativeCode( 1049 void AllocateObjectWithBoundsCheckComp::EmitNativeCode(
1050 FlowGraphCompiler* compiler) { 1050 FlowGraphCompiler* compiler) {
1051 const Class& cls = Class::ZoneHandle(constructor().owner()); 1051 const Class& cls = Class::ZoneHandle(constructor().owner());
1052 Register type_arguments = locs()->in(0).reg(); 1052 Register type_arguments = locs()->in(0).reg();
1053 Register instantiator_type_arguments = locs()->in(1).reg(); 1053 Register instantiator_type_arguments = locs()->in(1).reg();
1054 Register result = locs()->out().reg(); 1054 Register result = locs()->out().reg();
1055 1055
1056 // Push the result place holder initialized to NULL. 1056 // Push the result place holder initialized to NULL.
1057 __ PushObject(Object::ZoneHandle()); 1057 __ PushObject(Object::ZoneHandle());
1058 __ pushl(Immediate(Smi::RawValue(token_index()))); 1058 __ pushl(Immediate(Smi::RawValue(token_pos())));
1059 __ PushObject(cls); 1059 __ PushObject(cls);
1060 __ pushl(type_arguments); 1060 __ pushl(type_arguments);
1061 __ pushl(instantiator_type_arguments); 1061 __ pushl(instantiator_type_arguments);
1062 compiler->GenerateCallRuntime(cid(), 1062 compiler->GenerateCallRuntime(cid(),
1063 token_index(), 1063 token_pos(),
1064 try_index(), 1064 try_index(),
1065 kAllocateObjectWithBoundsCheckRuntimeEntry); 1065 kAllocateObjectWithBoundsCheckRuntimeEntry);
1066 // Pop instantiator type arguments, type arguments, class, and 1066 // Pop instantiator type arguments, type arguments, class, and
1067 // source location. 1067 // source location.
1068 __ Drop(4); 1068 __ Drop(4);
1069 __ popl(result); // Pop new instance. 1069 __ popl(result); // Pop new instance.
1070 } 1070 }
1071 1071
1072 1072
1073 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { 1073 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const {
1074 return LocationSummary::Make(1, Location::RequiresRegister()); 1074 return LocationSummary::Make(1, Location::RequiresRegister());
1075 } 1075 }
1076 1076
1077 1077
1078 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1078 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1079 Register instance_reg = locs()->in(0).reg(); 1079 Register instance_reg = locs()->in(0).reg();
1080 Register result_reg = locs()->out().reg(); 1080 Register result_reg = locs()->out().reg();
1081 if (HasICData()) { 1081 if (HasICData()) {
1082 ASSERT(original() != NULL); 1082 ASSERT(original() != NULL);
1083 Label* deopt = compiler->AddDeoptStub(original()->cid(), 1083 Label* deopt = compiler->AddDeoptStub(original()->cid(),
1084 original()->token_index(), 1084 original()->token_pos(),
1085 original()->try_index(), 1085 original()->try_index(),
1086 kDeoptInstanceGetterSameTarget, 1086 kDeoptInstanceGetterSameTarget,
1087 instance_reg); 1087 instance_reg);
1088 // Smis do not have instance fields (Smi class is always first). 1088 // Smis do not have instance fields (Smi class is always first).
1089 // Use 'result' as temporary register. 1089 // Use 'result' as temporary register.
1090 ASSERT(result_reg != instance_reg); 1090 ASSERT(result_reg != instance_reg);
1091 ASSERT(ic_data() != NULL); 1091 ASSERT(ic_data() != NULL);
1092 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt); 1092 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt);
1093 } 1093 }
1094 1094
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()), 1141 __ cmpl(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
1142 Immediate(Smi::RawValue(len))); 1142 Immediate(Smi::RawValue(len)));
1143 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); 1143 __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump);
1144 __ Bind(&type_arguments_uninstantiated); 1144 __ Bind(&type_arguments_uninstantiated);
1145 } 1145 }
1146 // A runtime call to instantiate the type arguments is required. 1146 // A runtime call to instantiate the type arguments is required.
1147 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1147 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1148 __ PushObject(type_arguments()); 1148 __ PushObject(type_arguments());
1149 __ pushl(instantiator_reg); // Push instantiator type arguments. 1149 __ pushl(instantiator_reg); // Push instantiator type arguments.
1150 compiler->GenerateCallRuntime(cid(), 1150 compiler->GenerateCallRuntime(cid(),
1151 token_index(), 1151 token_pos(),
1152 try_index(), 1152 try_index(),
1153 kInstantiateTypeArgumentsRuntimeEntry); 1153 kInstantiateTypeArgumentsRuntimeEntry);
1154 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 1154 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1155 __ popl(result_reg); // Pop instantiated type arguments. 1155 __ popl(result_reg); // Pop instantiated type arguments.
1156 __ Bind(&type_arguments_instantiated); 1156 __ Bind(&type_arguments_instantiated);
1157 ASSERT(instantiator_reg == result_reg); 1157 ASSERT(instantiator_reg == result_reg);
1158 // 'result_reg': Instantiated type arguments. 1158 // 'result_reg': Instantiated type arguments.
1159 } 1159 }
1160 1160
1161 1161
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 } 1295 }
1296 1296
1297 1297
1298 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1298 void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1299 ASSERT(locs()->temp(0).reg() == EDX); 1299 ASSERT(locs()->temp(0).reg() == EDX);
1300 ASSERT(locs()->out().reg() == EAX); 1300 ASSERT(locs()->out().reg() == EAX);
1301 1301
1302 __ movl(EDX, Immediate(num_context_variables())); 1302 __ movl(EDX, Immediate(num_context_variables()));
1303 const ExternalLabel label("alloc_context", 1303 const ExternalLabel label("alloc_context",
1304 StubCode::AllocateContextEntryPoint()); 1304 StubCode::AllocateContextEntryPoint());
1305 compiler->GenerateCall(token_index(), 1305 compiler->GenerateCall(token_pos(),
1306 try_index(), 1306 try_index(),
1307 &label, 1307 &label,
1308 PcDescriptors::kOther); 1308 PcDescriptors::kOther);
1309 } 1309 }
1310 1310
1311 1311
1312 LocationSummary* CloneContextComp::MakeLocationSummary() const { 1312 LocationSummary* CloneContextComp::MakeLocationSummary() const {
1313 return LocationSummary::Make(1, 1313 return LocationSummary::Make(1,
1314 Location::RequiresRegister(), 1314 Location::RequiresRegister(),
1315 LocationSummary::kCall); 1315 LocationSummary::kCall);
1316 } 1316 }
1317 1317
1318 1318
1319 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1319 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1320 Register context_value = locs()->in(0).reg(); 1320 Register context_value = locs()->in(0).reg();
1321 Register result = locs()->out().reg(); 1321 Register result = locs()->out().reg();
1322 1322
1323 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1323 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1324 __ pushl(context_value); 1324 __ pushl(context_value);
1325 compiler->GenerateCallRuntime(cid(), 1325 compiler->GenerateCallRuntime(cid(),
1326 token_index(), 1326 token_pos(),
1327 try_index(), 1327 try_index(),
1328 kCloneContextRuntimeEntry); 1328 kCloneContextRuntimeEntry);
1329 __ popl(result); // Remove argument. 1329 __ popl(result); // Remove argument.
1330 __ popl(result); // Get result (cloned context). 1330 __ popl(result); // Get result (cloned context).
1331 } 1331 }
1332 1332
1333 1333
1334 LocationSummary* CatchEntryComp::MakeLocationSummary() const { 1334 LocationSummary* CatchEntryComp::MakeLocationSummary() const {
1335 return LocationSummary::Make(0, Location::NoLocation()); 1335 return LocationSummary::Make(0, Location::NoLocation());
1336 } 1336 }
(...skipping 25 matching lines...) Expand all
1362 LocationSummary::kCall); 1362 LocationSummary::kCall);
1363 } 1363 }
1364 1364
1365 1365
1366 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1366 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1367 __ cmpl(ESP, 1367 __ cmpl(ESP,
1368 Address::Absolute(Isolate::Current()->stack_limit_address())); 1368 Address::Absolute(Isolate::Current()->stack_limit_address()));
1369 Label no_stack_overflow; 1369 Label no_stack_overflow;
1370 __ j(ABOVE, &no_stack_overflow); 1370 __ j(ABOVE, &no_stack_overflow);
1371 compiler->GenerateCallRuntime(cid(), 1371 compiler->GenerateCallRuntime(cid(),
1372 token_index(), 1372 token_pos(),
1373 try_index(), 1373 try_index(),
1374 kStackOverflowRuntimeEntry); 1374 kStackOverflowRuntimeEntry);
1375 __ Bind(&no_stack_overflow); 1375 __ Bind(&no_stack_overflow);
1376 } 1376 }
1377 1377
1378 1378
1379 LocationSummary* BinaryOpComp::MakeLocationSummary() const { 1379 LocationSummary* BinaryOpComp::MakeLocationSummary() const {
1380 const intptr_t kNumInputs = 2; 1380 const intptr_t kNumInputs = 2;
1381 1381
1382 if (operands_type() == kDoubleOperands) { 1382 if (operands_type() == kDoubleOperands) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1439 } 1439 }
1440 1440
1441 1441
1442 static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { 1442 static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) {
1443 Register left = comp->locs()->in(0).reg(); 1443 Register left = comp->locs()->in(0).reg();
1444 Register right = comp->locs()->in(1).reg(); 1444 Register right = comp->locs()->in(1).reg();
1445 Register result = comp->locs()->out().reg(); 1445 Register result = comp->locs()->out().reg();
1446 Register temp = comp->locs()->temp(0).reg(); 1446 Register temp = comp->locs()->temp(0).reg();
1447 ASSERT(left == result); 1447 ASSERT(left == result);
1448 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(), 1448 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(),
1449 comp->instance_call()->token_index(), 1449 comp->instance_call()->token_pos(),
1450 comp->instance_call()->try_index(), 1450 comp->instance_call()->try_index(),
1451 kDeoptSmiBinaryOp, 1451 kDeoptSmiBinaryOp,
1452 temp, 1452 temp,
1453 right); 1453 right);
1454 // TODO(vegorov): for many binary operations this pattern can be rearranged 1454 // TODO(vegorov): for many binary operations this pattern can be rearranged
1455 // to save one move. 1455 // to save one move.
1456 __ movl(temp, left); 1456 __ movl(temp, left);
1457 __ orl(left, right); 1457 __ orl(left, right);
1458 __ testl(left, Immediate(kSmiTagMask)); 1458 __ testl(left, Immediate(kSmiTagMask));
1459 __ j(NOT_ZERO, deopt); 1459 __ j(NOT_ZERO, deopt);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 __ jmp(&done); 1550 __ jmp(&done);
1551 { 1551 {
1552 __ Bind(&call_method); 1552 __ Bind(&call_method);
1553 Function& target = Function::ZoneHandle( 1553 Function& target = Function::ZoneHandle(
1554 comp->ic_data()->GetTargetForReceiverClassId(kSmi)); 1554 comp->ic_data()->GetTargetForReceiverClassId(kSmi));
1555 ASSERT(!target.IsNull()); 1555 ASSERT(!target.IsNull());
1556 const intptr_t kArgumentCount = 2; 1556 const intptr_t kArgumentCount = 2;
1557 __ pushl(temp); 1557 __ pushl(temp);
1558 __ pushl(right); 1558 __ pushl(right);
1559 compiler->GenerateStaticCall(comp->instance_call()->cid(), 1559 compiler->GenerateStaticCall(comp->instance_call()->cid(),
1560 comp->instance_call()->token_index(), 1560 comp->instance_call()->token_pos(),
1561 comp->instance_call()->try_index(), 1561 comp->instance_call()->try_index(),
1562 target, 1562 target,
1563 kArgumentCount, 1563 kArgumentCount,
1564 Array::Handle()); // No argument names. 1564 Array::Handle()); // No argument names.
1565 ASSERT(result == EAX); 1565 ASSERT(result == EAX);
1566 } 1566 }
1567 __ Bind(&done); 1567 __ Bind(&done);
1568 break; 1568 break;
1569 } 1569 }
1570 case Token::kDIV: { 1570 case Token::kDIV: {
(...skipping 26 matching lines...) Expand all
1597 // receiver and a Mint or Smi argument. We fall back to the run time call if 1597 // receiver and a Mint or Smi argument. We fall back to the run time call if
1598 // both receiver and argument are Mint or if one of them is Mint and the other 1598 // both receiver and argument are Mint or if one of them is Mint and the other
1599 // is a negative Smi. 1599 // is a negative Smi.
1600 Register left = comp->locs()->in(0).reg(); 1600 Register left = comp->locs()->in(0).reg();
1601 Register right = comp->locs()->in(1).reg(); 1601 Register right = comp->locs()->in(1).reg();
1602 Register result = comp->locs()->out().reg(); 1602 Register result = comp->locs()->out().reg();
1603 Register temp = comp->locs()->temp(0).reg(); 1603 Register temp = comp->locs()->temp(0).reg();
1604 ASSERT(left == result); 1604 ASSERT(left == result);
1605 ASSERT(comp->op_kind() == Token::kBIT_AND); 1605 ASSERT(comp->op_kind() == Token::kBIT_AND);
1606 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(), 1606 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(),
1607 comp->instance_call()->token_index(), 1607 comp->instance_call()->token_pos(),
1608 comp->instance_call()->try_index(), 1608 comp->instance_call()->try_index(),
1609 kDeoptMintBinaryOp, 1609 kDeoptMintBinaryOp,
1610 left, 1610 left,
1611 right); 1611 right);
1612 Label mint_static_call, smi_static_call, non_smi, smi_smi, done; 1612 Label mint_static_call, smi_static_call, non_smi, smi_smi, done;
1613 __ testl(left, Immediate(kSmiTagMask)); // Is receiver Smi? 1613 __ testl(left, Immediate(kSmiTagMask)); // Is receiver Smi?
1614 __ j(NOT_ZERO, &non_smi); 1614 __ j(NOT_ZERO, &non_smi);
1615 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi? 1615 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi?
1616 __ j(ZERO, &smi_smi); 1616 __ j(ZERO, &smi_smi);
1617 __ CompareClassId(right, kMint, temp); // Is argument Mint? 1617 __ CompareClassId(right, kMint, temp); // Is argument Mint?
(...skipping 27 matching lines...) Expand all
1645 __ Bind(&smi_static_call); 1645 __ Bind(&smi_static_call);
1646 { 1646 {
1647 Function& target = Function::ZoneHandle( 1647 Function& target = Function::ZoneHandle(
1648 comp->ic_data()->GetTargetForReceiverClassId(kSmi)); 1648 comp->ic_data()->GetTargetForReceiverClassId(kSmi));
1649 if (target.IsNull()) { 1649 if (target.IsNull()) {
1650 __ jmp(deopt); 1650 __ jmp(deopt);
1651 } else { 1651 } else {
1652 __ pushl(left); 1652 __ pushl(left);
1653 __ pushl(right); 1653 __ pushl(right);
1654 compiler->GenerateStaticCall(comp->instance_call()->cid(), 1654 compiler->GenerateStaticCall(comp->instance_call()->cid(),
1655 comp->instance_call()->token_index(), 1655 comp->instance_call()->token_pos(),
1656 comp->instance_call()->try_index(), 1656 comp->instance_call()->try_index(),
1657 target, 1657 target,
1658 comp->instance_call()->ArgumentCount(), 1658 comp->instance_call()->ArgumentCount(),
1659 comp->instance_call()->argument_names()); 1659 comp->instance_call()->argument_names());
1660 ASSERT(result == EAX); 1660 ASSERT(result == EAX);
1661 __ jmp(&done); 1661 __ jmp(&done);
1662 } 1662 }
1663 } 1663 }
1664 1664
1665 __ Bind(&mint_static_call); 1665 __ Bind(&mint_static_call);
1666 { 1666 {
1667 Function& target = Function::ZoneHandle( 1667 Function& target = Function::ZoneHandle(
1668 comp->ic_data()->GetTargetForReceiverClassId(kMint)); 1668 comp->ic_data()->GetTargetForReceiverClassId(kMint));
1669 if (target.IsNull()) { 1669 if (target.IsNull()) {
1670 __ jmp(deopt); 1670 __ jmp(deopt);
1671 } else { 1671 } else {
1672 __ pushl(left); 1672 __ pushl(left);
1673 __ pushl(right); 1673 __ pushl(right);
1674 compiler->GenerateStaticCall(comp->instance_call()->cid(), 1674 compiler->GenerateStaticCall(comp->instance_call()->cid(),
1675 comp->instance_call()->token_index(), 1675 comp->instance_call()->token_pos(),
1676 comp->instance_call()->try_index(), 1676 comp->instance_call()->try_index(),
1677 target, 1677 target,
1678 comp->instance_call()->ArgumentCount(), 1678 comp->instance_call()->ArgumentCount(),
1679 comp->instance_call()->argument_names()); 1679 comp->instance_call()->argument_names());
1680 ASSERT(result == EAX); 1680 ASSERT(result == EAX);
1681 } 1681 }
1682 } 1682 }
1683 __ Bind(&done); 1683 __ Bind(&done);
1684 } 1684 }
1685 1685
1686 1686
1687 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, 1687 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler,
1688 BinaryOpComp* comp) { 1688 BinaryOpComp* comp) {
1689 Register left = EBX; 1689 Register left = EBX;
1690 Register right = ECX; 1690 Register right = ECX;
1691 Register temp = EDX; 1691 Register temp = EDX;
1692 Register result = comp->locs()->out().reg(); 1692 Register result = comp->locs()->out().reg();
1693 1693
1694 const Class& double_class = compiler->double_class(); 1694 const Class& double_class = compiler->double_class();
1695 const Code& stub = 1695 const Code& stub =
1696 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1696 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1697 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1697 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1698 compiler->GenerateCall(comp->instance_call()->token_index(), 1698 compiler->GenerateCall(comp->instance_call()->token_pos(),
1699 comp->instance_call()->try_index(), 1699 comp->instance_call()->try_index(),
1700 &label, 1700 &label,
1701 PcDescriptors::kOther); 1701 PcDescriptors::kOther);
1702 // Newly allocated object is now in the result register (RAX). 1702 // Newly allocated object is now in the result register (RAX).
1703 ASSERT(result == EAX); 1703 ASSERT(result == EAX);
1704 __ popl(right); 1704 __ popl(right);
1705 __ popl(left); 1705 __ popl(left);
1706 1706
1707 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(), 1707 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(),
1708 comp->instance_call()->token_index(), 1708 comp->instance_call()->token_pos(),
1709 comp->instance_call()->try_index(), 1709 comp->instance_call()->try_index(),
1710 kDeoptDoubleBinaryOp, 1710 kDeoptDoubleBinaryOp,
1711 left, 1711 left,
1712 right); 1712 right);
1713 1713
1714 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt); 1714 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt);
1715 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt); 1715 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
1716 1716
1717 switch (comp->op_kind()) { 1717 switch (comp->op_kind()) {
1718 case Token::kADD: __ addsd(XMM0, XMM1); break; 1718 case Token::kADD: __ addsd(XMM0, XMM1); break;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 // TODO(srdjan): Implement for more checks. 1763 // TODO(srdjan): Implement for more checks.
1764 ASSERT(ic_data.NumberOfChecks() == 1); 1764 ASSERT(ic_data.NumberOfChecks() == 1);
1765 intptr_t test_class_id; 1765 intptr_t test_class_id;
1766 Function& target = Function::Handle(); 1766 Function& target = Function::Handle();
1767 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1767 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1768 1768
1769 Register value = locs()->in(0).reg(); 1769 Register value = locs()->in(0).reg();
1770 Register result = locs()->out().reg(); 1770 Register result = locs()->out().reg();
1771 ASSERT(value == result); 1771 ASSERT(value == result);
1772 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1772 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
1773 instance_call()->token_index(), 1773 instance_call()->token_pos(),
1774 instance_call()->try_index(), 1774 instance_call()->try_index(),
1775 kDeoptUnaryOp, 1775 kDeoptUnaryOp,
1776 value); 1776 value);
1777 if (test_class_id == kSmi) { 1777 if (test_class_id == kSmi) {
1778 __ testl(value, Immediate(kSmiTagMask)); 1778 __ testl(value, Immediate(kSmiTagMask));
1779 __ j(NOT_ZERO, deopt); 1779 __ j(NOT_ZERO, deopt);
1780 switch (op_kind()) { 1780 switch (op_kind()) {
1781 case Token::kNEGATE: 1781 case Token::kNEGATE:
1782 __ negl(value); 1782 __ negl(value);
1783 __ j(OVERFLOW, deopt); 1783 __ j(OVERFLOW, deopt);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1816 // TODO(srdjan): Implement for more checks. 1816 // TODO(srdjan): Implement for more checks.
1817 ASSERT(ic_data.NumberOfChecks() == 1); 1817 ASSERT(ic_data.NumberOfChecks() == 1);
1818 intptr_t test_class_id; 1818 intptr_t test_class_id;
1819 Function& target = Function::Handle(); 1819 Function& target = Function::Handle();
1820 ic_data.GetOneClassCheckAt(0, &test_class_id, &target); 1820 ic_data.GetOneClassCheckAt(0, &test_class_id, &target);
1821 1821
1822 Register value = locs()->in(0).reg(); 1822 Register value = locs()->in(0).reg();
1823 Register result = locs()->out().reg(); 1823 Register result = locs()->out().reg();
1824 ASSERT(value == result); 1824 ASSERT(value == result);
1825 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1825 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
1826 instance_call()->token_index(), 1826 instance_call()->token_pos(),
1827 instance_call()->try_index(), 1827 instance_call()->try_index(),
1828 kDeoptUnaryOp, 1828 kDeoptUnaryOp,
1829 value); 1829 value);
1830 if (test_class_id == kDouble) { 1830 if (test_class_id == kDouble) {
1831 Register temp = locs()->temp(0).reg(); 1831 Register temp = locs()->temp(0).reg();
1832 __ testl(value, Immediate(kSmiTagMask)); 1832 __ testl(value, Immediate(kSmiTagMask));
1833 __ j(ZERO, deopt); // Smi. 1833 __ j(ZERO, deopt); // Smi.
1834 __ CompareClassId(value, kDouble, temp); 1834 __ CompareClassId(value, kDouble, temp);
1835 __ j(NOT_EQUAL, deopt); 1835 __ j(NOT_EQUAL, deopt);
1836 // Allocate result object. 1836 // Allocate result object.
1837 const Class& double_class = compiler->double_class(); 1837 const Class& double_class = compiler->double_class();
1838 const Code& stub = 1838 const Code& stub =
1839 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1839 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1840 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1840 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1841 __ pushl(value); 1841 __ pushl(value);
1842 compiler->GenerateCall(instance_call()->token_index(), 1842 compiler->GenerateCall(instance_call()->token_pos(),
1843 instance_call()->try_index(), 1843 instance_call()->try_index(),
1844 &label, 1844 &label,
1845 PcDescriptors::kOther); 1845 PcDescriptors::kOther);
1846 // Result is in EAX. 1846 // Result is in EAX.
1847 ASSERT(result != temp); 1847 ASSERT(result != temp);
1848 __ movl(result, EAX); 1848 __ movl(result, EAX);
1849 __ popl(temp); 1849 __ popl(temp);
1850 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); 1850 __ movsd(XMM0, FieldAddress(temp, Double::value_offset()));
1851 __ DoubleNegate(XMM0); 1851 __ DoubleNegate(XMM0);
1852 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 1852 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
(...skipping 20 matching lines...) Expand all
1873 } 1873 }
1874 1874
1875 1875
1876 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1876 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1877 Register value = (from() == kDouble) ? locs()->in(0).reg() : EBX; 1877 Register value = (from() == kDouble) ? locs()->in(0).reg() : EBX;
1878 Register result = locs()->out().reg(); 1878 Register result = locs()->out().reg();
1879 1879
1880 const DeoptReasonId deopt_reason = (from() == kDouble) ? 1880 const DeoptReasonId deopt_reason = (from() == kDouble) ?
1881 kDeoptDoubleToDouble : kDeoptIntegerToDouble; 1881 kDeoptDoubleToDouble : kDeoptIntegerToDouble;
1882 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1882 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
1883 instance_call()->token_index(), 1883 instance_call()->token_pos(),
1884 instance_call()->try_index(), 1884 instance_call()->try_index(),
1885 deopt_reason, 1885 deopt_reason,
1886 value); 1886 value);
1887 1887
1888 if (from() == kDouble) { 1888 if (from() == kDouble) {
1889 Register temp = locs()->temp(0).reg(); 1889 Register temp = locs()->temp(0).reg();
1890 __ testl(value, Immediate(kSmiTagMask)); 1890 __ testl(value, Immediate(kSmiTagMask));
1891 __ j(ZERO, deopt); // Deoptimize if Smi. 1891 __ j(ZERO, deopt); // Deoptimize if Smi.
1892 __ CompareClassId(value, kDouble, temp); 1892 __ CompareClassId(value, kDouble, temp);
1893 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. 1893 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double.
1894 ASSERT(value == result); 1894 ASSERT(value == result);
1895 return; 1895 return;
1896 } 1896 }
1897 1897
1898 ASSERT(from() == kSmi); 1898 ASSERT(from() == kSmi);
1899 1899
1900 const Class& double_class = compiler->double_class(); 1900 const Class& double_class = compiler->double_class();
1901 const Code& stub = 1901 const Code& stub =
1902 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1902 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1903 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1903 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1904 1904
1905 // TODO(vegorov): allocate box in the driver loop to avoid spilling. 1905 // TODO(vegorov): allocate box in the driver loop to avoid spilling.
1906 compiler->GenerateCall(instance_call()->token_index(), 1906 compiler->GenerateCall(instance_call()->token_pos(),
1907 instance_call()->try_index(), 1907 instance_call()->try_index(),
1908 &label, 1908 &label,
1909 PcDescriptors::kOther); 1909 PcDescriptors::kOther);
1910 ASSERT(result == EAX); 1910 ASSERT(result == EAX);
1911 __ popl(value); 1911 __ popl(value);
1912 1912
1913 __ testl(value, Immediate(kSmiTagMask)); 1913 __ testl(value, Immediate(kSmiTagMask));
1914 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. 1914 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi.
1915 __ SmiUntag(value); 1915 __ SmiUntag(value);
1916 __ cvtsi2sd(XMM0, value); 1916 __ cvtsi2sd(XMM0, value);
1917 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 1917 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
1918 } 1918 }
1919 1919
1920 1920
1921 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const { 1921 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const {
1922 return MakeCallSummary(); 1922 return MakeCallSummary();
1923 } 1923 }
1924 1924
1925 1925
1926 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1926 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1927 ASSERT(instance_call()->VerifyComputation()); 1927 ASSERT(instance_call()->VerifyComputation());
1928 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1928 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
1929 instance_call()->token_index(), 1929 instance_call()->token_pos(),
1930 instance_call()->try_index(), 1930 instance_call()->try_index(),
1931 kDeoptPolymorphicInstanceCallTestFail); 1931 kDeoptPolymorphicInstanceCallTestFail);
1932 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) { 1932 if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) {
1933 __ jmp(deopt); 1933 __ jmp(deopt);
1934 return; 1934 return;
1935 } 1935 }
1936 ASSERT(HasICData()); 1936 ASSERT(HasICData());
1937 ASSERT(ic_data()->num_args_tested() == 1); 1937 ASSERT(ic_data()->num_args_tested() == 1);
1938 Label handle_smi; 1938 Label handle_smi;
1939 Label* is_smi_label = 1939 Label* is_smi_label =
1940 ic_data()->GetReceiverClassIdAt(0) == kSmi ? &handle_smi : deopt; 1940 ic_data()->GetReceiverClassIdAt(0) == kSmi ? &handle_smi : deopt;
1941 1941
1942 // Load receiver into EAX. 1942 // Load receiver into EAX.
1943 __ movl(EAX, 1943 __ movl(EAX,
1944 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize)); 1944 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize));
1945 __ testl(EAX, Immediate(kSmiTagMask)); 1945 __ testl(EAX, Immediate(kSmiTagMask));
1946 __ j(ZERO, is_smi_label); 1946 __ j(ZERO, is_smi_label);
1947 Label done; 1947 Label done;
1948 __ LoadClassId(EDI, EAX); 1948 __ LoadClassId(EDI, EAX);
1949 compiler->EmitTestAndCall(*ic_data(), 1949 compiler->EmitTestAndCall(*ic_data(),
1950 EDI, // Class id register. 1950 EDI, // Class id register.
1951 instance_call()->ArgumentCount(), 1951 instance_call()->ArgumentCount(),
1952 instance_call()->argument_names(), 1952 instance_call()->argument_names(),
1953 deopt, &done, // Labels. 1953 deopt, &done, // Labels.
1954 instance_call()->cid(), 1954 instance_call()->cid(),
1955 instance_call()->token_index(), 1955 instance_call()->token_pos(),
1956 instance_call()->try_index()); 1956 instance_call()->try_index());
1957 if (is_smi_label == &handle_smi) { 1957 if (is_smi_label == &handle_smi) {
1958 __ Bind(&handle_smi); 1958 __ Bind(&handle_smi);
1959 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmi); 1959 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmi);
1960 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); 1960 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0));
1961 compiler->GenerateStaticCall(instance_call()->cid(), 1961 compiler->GenerateStaticCall(instance_call()->cid(),
1962 instance_call()->token_index(), 1962 instance_call()->token_pos(),
1963 instance_call()->try_index(), 1963 instance_call()->try_index(),
1964 target, 1964 target,
1965 instance_call()->ArgumentCount(), 1965 instance_call()->ArgumentCount(),
1966 instance_call()->argument_names()); 1966 instance_call()->argument_names());
1967 } 1967 }
1968 __ Bind(&done); 1968 __ Bind(&done);
1969 } 1969 }
1970 1970
1971 } // namespace dart 1971 } // namespace dart
1972 1972
1973 #undef __ 1973 #undef __
1974 1974
1975 #endif // defined TARGET_ARCH_X64 1975 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « vm/intermediate_language.cc ('k') | vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698