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

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

Issue 10873027: Use the location summary to represent safepoint information. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
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, 89 CatchClauseNode::kInvalidTryIndex,
90 kTraceFunctionExitRuntimeEntry, 90 kTraceFunctionExitRuntimeEntry,
91 locs()->stack_bitmap()); 91 locs());
92 __ popl(temp); // Remove argument. 92 __ popl(temp); // Remove argument.
93 __ popl(result); // Restore result. 93 __ popl(result); // Restore result.
94 } 94 }
95 #if defined(DEBUG) 95 #if defined(DEBUG)
96 // TODO(srdjan): Fix for functions with finally clause. 96 // TODO(srdjan): Fix for functions with finally clause.
97 // A finally clause may leave a previously pushed return value if it 97 // A finally clause may leave a previously pushed return value if it
98 // has its own return instruction. Method that have finally are currently 98 // has its own return instruction. Method that have finally are currently
99 // not optimized. 99 // not optimized.
100 if (!compiler->HasFinally()) { 100 if (!compiler->HasFinally()) {
101 Label done; 101 Label done;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 __ CompareObject(obj, compiler->bool_true()); 208 __ CompareObject(obj, compiler->bool_true());
209 __ j(EQUAL, &done, Assembler::kNearJump); 209 __ j(EQUAL, &done, Assembler::kNearJump);
210 __ CompareObject(obj, compiler->bool_false()); 210 __ CompareObject(obj, compiler->bool_false());
211 __ j(EQUAL, &done, Assembler::kNearJump); 211 __ j(EQUAL, &done, Assembler::kNearJump);
212 212
213 __ pushl(obj); // Push the source object. 213 __ pushl(obj); // Push the source object.
214 compiler->GenerateCallRuntime(deopt_id(), 214 compiler->GenerateCallRuntime(deopt_id(),
215 token_pos(), 215 token_pos(),
216 try_index(), 216 try_index(),
217 kConditionTypeErrorRuntimeEntry, 217 kConditionTypeErrorRuntimeEntry,
218 locs()->stack_bitmap()); 218 locs());
219 // We should never return here. 219 // We should never return here.
220 __ int3(); 220 __ int3();
221 __ Bind(&done); 221 __ Bind(&done);
222 } 222 }
223 ASSERT(obj == result); 223 ASSERT(obj == result);
224 } 224 }
225 225
226 226
227 static Condition TokenKindToSmiCondition(Token::Kind kind) { 227 static Condition TokenKindToSmiCondition(Token::Kind kind) {
228 switch (kind) { 228 switch (kind) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 locs->set_out(Location::RegisterLocation(EAX)); 273 locs->set_out(Location::RegisterLocation(EAX));
274 return locs; 274 return locs;
275 } 275 }
276 276
277 277
278 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, 278 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
279 intptr_t deopt_id, 279 intptr_t deopt_id,
280 intptr_t token_pos, 280 intptr_t token_pos,
281 intptr_t try_index, 281 intptr_t try_index,
282 Token::Kind kind, 282 Token::Kind kind,
283 const LocationSummary& locs) { 283 LocationSummary* locs) {
284 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 284 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
285 deopt_id, 285 deopt_id,
286 token_pos, 286 token_pos,
287 try_index); 287 try_index);
288 const String& operator_name = String::ZoneHandle(Symbols::New("==")); 288 const String& operator_name = String::ZoneHandle(Symbols::New("=="));
289 const int kNumberOfArguments = 2; 289 const int kNumberOfArguments = 2;
290 const Array& kNoArgumentNames = Array::Handle(); 290 const Array& kNoArgumentNames = Array::Handle();
291 const int kNumArgumentsChecked = 2; 291 const int kNumArgumentsChecked = 2;
292 292
293 Label done, false_label, true_label; 293 Label done, false_label, true_label;
294 Register left = locs.in(0).reg(); 294 Register left = locs->in(0).reg();
295 Register right = locs.in(1).reg(); 295 Register right = locs->in(1).reg();
296 __ popl(right); 296 __ popl(right);
297 __ popl(left); 297 __ popl(left);
298 const Immediate raw_null = 298 const Immediate raw_null =
299 Immediate(reinterpret_cast<intptr_t>(Object::null())); 299 Immediate(reinterpret_cast<intptr_t>(Object::null()));
300 Label check_identity, instance_call; 300 Label check_identity, instance_call;
301 __ cmpl(right, raw_null); 301 __ cmpl(right, raw_null);
302 __ j(EQUAL, &check_identity, Assembler::kNearJump); 302 __ j(EQUAL, &check_identity, Assembler::kNearJump);
303 __ cmpl(left, raw_null); 303 __ cmpl(left, raw_null);
304 __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump); 304 __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump);
305 305
(...skipping 14 matching lines...) Expand all
320 __ Bind(&instance_call); 320 __ Bind(&instance_call);
321 __ pushl(left); 321 __ pushl(left);
322 __ pushl(right); 322 __ pushl(right);
323 compiler->GenerateInstanceCall(deopt_id, 323 compiler->GenerateInstanceCall(deopt_id,
324 token_pos, 324 token_pos,
325 try_index, 325 try_index,
326 operator_name, 326 operator_name,
327 kNumberOfArguments, 327 kNumberOfArguments,
328 kNoArgumentNames, 328 kNoArgumentNames,
329 kNumArgumentsChecked, 329 kNumArgumentsChecked,
330 locs.stack_bitmap()); 330 locs);
331 if (kind == Token::kNE) { 331 if (kind == Token::kNE) {
332 // Negate the condition: true label returns false and vice versa. 332 // Negate the condition: true label returns false and vice versa.
333 __ CompareObject(EAX, compiler->bool_true()); 333 __ CompareObject(EAX, compiler->bool_true());
334 __ j(EQUAL, &true_label, Assembler::kNearJump); 334 __ j(EQUAL, &true_label, Assembler::kNearJump);
335 __ Bind(&false_label); 335 __ Bind(&false_label);
336 __ LoadObject(EAX, compiler->bool_true()); 336 __ LoadObject(EAX, compiler->bool_true());
337 __ jmp(&done, Assembler::kNearJump); 337 __ jmp(&done, Assembler::kNearJump);
338 __ Bind(&true_label); 338 __ Bind(&true_label);
339 __ LoadObject(EAX, compiler->bool_false()); 339 __ LoadObject(EAX, compiler->bool_false());
340 } 340 }
341 __ Bind(&done); 341 __ Bind(&done);
342 } 342 }
343 343
344 344
345 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, 345 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
346 const ICData& orig_ic_data, 346 const ICData& orig_ic_data,
347 const LocationSummary& locs, 347 LocationSummary* locs,
348 BranchInstr* branch, 348 BranchInstr* branch,
349 Token::Kind kind, 349 Token::Kind kind,
350 intptr_t deopt_id, 350 intptr_t deopt_id,
351 intptr_t token_pos, 351 intptr_t token_pos,
352 intptr_t try_index, 352 intptr_t try_index) {
353 BitmapBuilder* stack_bitmap) {
354 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 353 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
355 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); 354 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks());
356 ASSERT(ic_data.NumberOfChecks() > 0); 355 ASSERT(ic_data.NumberOfChecks() > 0);
357 ASSERT(ic_data.num_args_tested() == 1); 356 ASSERT(ic_data.num_args_tested() == 1);
358 Label* deopt = compiler->AddDeoptStub(deopt_id, try_index, kDeoptEquality); 357 Label* deopt = compiler->AddDeoptStub(deopt_id, try_index, kDeoptEquality);
359 Register left = locs.in(0).reg(); 358 Register left = locs->in(0).reg();
360 Register right = locs.in(1).reg(); 359 Register right = locs->in(1).reg();
361 __ testl(left, Immediate(kSmiTagMask)); 360 __ testl(left, Immediate(kSmiTagMask));
362 Register temp = locs.temp(0).reg(); 361 Register temp = locs->temp(0).reg();
363 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) { 362 if (ic_data.GetReceiverClassIdAt(0) == kSmiCid) {
364 Label done, load_class_id; 363 Label done, load_class_id;
365 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump); 364 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump);
366 __ movl(temp, Immediate(kSmiCid)); 365 __ movl(temp, Immediate(kSmiCid));
367 __ jmp(&done, Assembler::kNearJump); 366 __ jmp(&done, Assembler::kNearJump);
368 __ Bind(&load_class_id); 367 __ Bind(&load_class_id);
369 __ LoadClassId(temp, left); 368 __ LoadClassId(temp, left);
370 __ Bind(&done); 369 __ Bind(&done);
371 } else { 370 } else {
372 __ j(ZERO, deopt); // Smi deopts. 371 __ j(ZERO, deopt); // Smi deopts.
(...skipping 10 matching lines...) Expand all
383 __ cmpl(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); 382 __ cmpl(temp, Immediate(ic_data.GetReceiverClassIdAt(i)));
384 __ j(NOT_EQUAL, &next_test); 383 __ j(NOT_EQUAL, &next_test);
385 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); 384 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i));
386 if (target.Owner() == object_store->object_class()) { 385 if (target.Owner() == object_store->object_class()) {
387 // Object.== is same as ===. 386 // Object.== is same as ===.
388 __ Drop(2); 387 __ Drop(2);
389 __ cmpl(left, right); 388 __ cmpl(left, right);
390 if (branch != NULL) { 389 if (branch != NULL) {
391 branch->EmitBranchOnCondition(compiler, cond); 390 branch->EmitBranchOnCondition(compiler, cond);
392 } else { 391 } else {
393 Register result = locs.out().reg(); 392 Register result = locs->out().reg();
394 Label load_true; 393 Label load_true;
395 __ j(cond, &load_true, Assembler::kNearJump); 394 __ j(cond, &load_true, Assembler::kNearJump);
396 __ LoadObject(result, compiler->bool_false()); 395 __ LoadObject(result, compiler->bool_false());
397 __ jmp(&done); 396 __ jmp(&done);
398 __ Bind(&load_true); 397 __ Bind(&load_true);
399 __ LoadObject(result, compiler->bool_true()); 398 __ LoadObject(result, compiler->bool_true());
400 } 399 }
401 } else { 400 } else {
402 const int kNumberOfArguments = 2; 401 const int kNumberOfArguments = 2;
403 const Array& kNoArgumentNames = Array::Handle(); 402 const Array& kNoArgumentNames = Array::Handle();
404 compiler->GenerateStaticCall(deopt_id, 403 compiler->GenerateStaticCall(deopt_id,
405 token_pos, 404 token_pos,
406 try_index, 405 try_index,
407 target, 406 target,
408 kNumberOfArguments, 407 kNumberOfArguments,
409 kNoArgumentNames, 408 kNoArgumentNames,
410 stack_bitmap); 409 locs);
411 if (branch == NULL) { 410 if (branch == NULL) {
412 if (kind == Token::kNE) { 411 if (kind == Token::kNE) {
413 Label false_label; 412 Label false_label;
414 __ CompareObject(EAX, compiler->bool_true()); 413 __ CompareObject(EAX, compiler->bool_true());
415 __ j(EQUAL, &false_label, Assembler::kNearJump); 414 __ j(EQUAL, &false_label, Assembler::kNearJump);
416 __ LoadObject(EAX, compiler->bool_true()); 415 __ LoadObject(EAX, compiler->bool_true());
417 __ jmp(&done); 416 __ jmp(&done);
418 __ Bind(&false_label); 417 __ Bind(&false_label);
419 __ LoadObject(EAX, compiler->bool_false()); 418 __ LoadObject(EAX, compiler->bool_false());
420 __ jmp(&done); 419 __ jmp(&done);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 Condition cond = TokenKindToSmiCondition(kind); 486 Condition cond = TokenKindToSmiCondition(kind);
488 branch->EmitBranchOnCondition(compiler, cond); 487 branch->EmitBranchOnCondition(compiler, cond);
489 } 488 }
490 } 489 }
491 490
492 491
493 // First test if receiver is NULL, in which case === is applied. 492 // First test if receiver is NULL, in which case === is applied.
494 // If type feedback was provided (lists of <class-id, target>), do a 493 // If type feedback was provided (lists of <class-id, target>), do a
495 // type by type check (either === or static call to the operator. 494 // type by type check (either === or static call to the operator.
496 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler, 495 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler,
497 const LocationSummary& locs, 496 LocationSummary* locs,
498 Token::Kind kind, 497 Token::Kind kind,
499 BranchInstr* branch, 498 BranchInstr* branch,
500 const ICData& ic_data, 499 const ICData& ic_data,
501 intptr_t deopt_id, 500 intptr_t deopt_id,
502 intptr_t token_pos, 501 intptr_t token_pos,
503 intptr_t try_index) { 502 intptr_t try_index) {
504 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 503 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
505 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); 504 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
506 Register left = locs.in(0).reg(); 505 Register left = locs->in(0).reg();
507 Register right = locs.in(1).reg(); 506 Register right = locs->in(1).reg();
508 const Immediate raw_null = 507 const Immediate raw_null =
509 Immediate(reinterpret_cast<intptr_t>(Object::null())); 508 Immediate(reinterpret_cast<intptr_t>(Object::null()));
510 Label done, identity_compare, non_null_compare; 509 Label done, identity_compare, non_null_compare;
511 __ cmpl(right, raw_null); 510 __ cmpl(right, raw_null);
512 __ j(EQUAL, &identity_compare, Assembler::kNearJump); 511 __ j(EQUAL, &identity_compare, Assembler::kNearJump);
513 __ cmpl(left, raw_null); 512 __ cmpl(left, raw_null);
514 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); 513 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump);
515 // Comparison with NULL is "===". 514 // Comparison with NULL is "===".
516 __ Bind(&identity_compare); 515 __ Bind(&identity_compare);
517 __ cmpl(left, right); 516 __ cmpl(left, right);
518 Condition cond = TokenKindToSmiCondition(kind); 517 Condition cond = TokenKindToSmiCondition(kind);
519 if (branch != NULL) { 518 if (branch != NULL) {
520 branch->EmitBranchOnCondition(compiler, cond); 519 branch->EmitBranchOnCondition(compiler, cond);
521 } else { 520 } else {
522 Register result = locs.out().reg(); 521 Register result = locs->out().reg();
523 Label load_true; 522 Label load_true;
524 __ j(cond, &load_true, Assembler::kNearJump); 523 __ j(cond, &load_true, Assembler::kNearJump);
525 __ LoadObject(result, compiler->bool_false()); 524 __ LoadObject(result, compiler->bool_false());
526 __ jmp(&done); 525 __ jmp(&done);
527 __ Bind(&load_true); 526 __ Bind(&load_true);
528 __ LoadObject(result, compiler->bool_true()); 527 __ LoadObject(result, compiler->bool_true());
529 } 528 }
530 __ jmp(&done); 529 __ jmp(&done);
531 __ Bind(&non_null_compare); // Receiver is not null. 530 __ Bind(&non_null_compare); // Receiver is not null.
532 __ pushl(left); 531 __ pushl(left);
533 __ pushl(right); 532 __ pushl(right);
534 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 533 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
535 deopt_id, token_pos, try_index, 534 deopt_id, token_pos, try_index);
536 locs.stack_bitmap());
537 __ Bind(&done); 535 __ Bind(&done);
538 } 536 }
539 537
540 538
541 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 539 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
542 const LocationSummary& locs, 540 const LocationSummary& locs,
543 Token::Kind kind, 541 Token::Kind kind,
544 BranchInstr* branch, 542 BranchInstr* branch,
545 intptr_t deopt_id, 543 intptr_t deopt_id,
546 intptr_t token_pos, 544 intptr_t token_pos,
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 return; 635 return;
638 } 636 }
639 const bool is_checked_strict_equal = 637 const bool is_checked_strict_equal =
640 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 638 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
641 if (is_checked_strict_equal) { 639 if (is_checked_strict_equal) {
642 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), NULL, 640 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), NULL,
643 deopt_id(), token_pos(), try_index()); 641 deopt_id(), token_pos(), try_index());
644 return; 642 return;
645 } 643 }
646 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 644 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
647 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(), 645 EmitGenericEqualityCompare(compiler, locs(), kind(), NULL, *ic_data(),
648 deopt_id(), token_pos(), try_index()); 646 deopt_id(), token_pos(), try_index());
649 } else { 647 } else {
650 Register left = locs()->in(0).reg(); 648 Register left = locs()->in(0).reg();
651 Register right = locs()->in(1).reg(); 649 Register right = locs()->in(1).reg();
652 __ pushl(left); 650 __ pushl(left);
653 __ pushl(right); 651 __ pushl(right);
654 EmitEqualityAsInstanceCall(compiler, 652 EmitEqualityAsInstanceCall(compiler,
655 deopt_id(), 653 deopt_id(),
656 token_pos(), 654 token_pos(),
657 try_index(), 655 try_index(),
658 kind(), 656 kind(),
659 *locs()); 657 locs());
660 ASSERT(locs()->out().reg() == EAX); 658 ASSERT(locs()->out().reg() == EAX);
661 } 659 }
662 } 660 }
663 661
664 662
665 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 663 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
666 const intptr_t kNumInputs = 2; 664 const intptr_t kNumInputs = 2;
667 if ((operands_class_id() == kSmiCid) || (operands_class_id() == kDoubleCid)) { 665 if ((operands_class_id() == kSmiCid) || (operands_class_id() == kDoubleCid)) {
668 const intptr_t kNumTemps = 1; 666 const intptr_t kNumTemps = 1;
669 LocationSummary* summary = 667 LocationSummary* summary =
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 __ Bind(&done); 718 __ Bind(&done);
721 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()), 719 compiler->EmitTestAndCall(ICData::Handle(ic_data()->AsUnaryClassChecks()),
722 EDI, // Class id register. 720 EDI, // Class id register.
723 kNumArguments, 721 kNumArguments,
724 Array::Handle(), // No named arguments. 722 Array::Handle(), // No named arguments.
725 deopt, // Deoptimize target. 723 deopt, // Deoptimize target.
726 NULL, // Fallthrough when done. 724 NULL, // Fallthrough when done.
727 deopt_id(), 725 deopt_id(),
728 token_pos(), 726 token_pos(),
729 try_index(), 727 try_index(),
730 locs()->stack_bitmap()); 728 locs());
731 ASSERT(locs()->out().reg() == EAX); 729 ASSERT(locs()->out().reg() == EAX);
732 return; 730 return;
733 } 731 }
734 const String& function_name = 732 const String& function_name =
735 String::ZoneHandle(Symbols::New(Token::Str(kind()))); 733 String::ZoneHandle(Symbols::New(Token::Str(kind())));
736 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 734 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
737 deopt_id(), 735 deopt_id(),
738 token_pos(), 736 token_pos(),
739 try_index()); 737 try_index());
740 const intptr_t kNumArguments = 2; 738 const intptr_t kNumArguments = 2;
741 const intptr_t kNumArgsChecked = 2; // Type-feedback. 739 const intptr_t kNumArgsChecked = 2; // Type-feedback.
742 compiler->GenerateInstanceCall(deopt_id(), 740 compiler->GenerateInstanceCall(deopt_id(),
743 token_pos(), 741 token_pos(),
744 try_index(), 742 try_index(),
745 function_name, 743 function_name,
746 kNumArguments, 744 kNumArguments,
747 Array::ZoneHandle(), // No optional arguments. 745 Array::ZoneHandle(), // No optional arguments.
748 kNumArgsChecked, 746 kNumArgsChecked,
749 locs()->stack_bitmap()); 747 locs());
750 ASSERT(locs()->out().reg() == EAX); 748 ASSERT(locs()->out().reg() == EAX);
751 } 749 }
752 750
753 751
754 LocationSummary* NativeCallComp::MakeLocationSummary() const { 752 LocationSummary* NativeCallComp::MakeLocationSummary() const {
755 const intptr_t kNumInputs = 0; 753 const intptr_t kNumInputs = 0;
756 const intptr_t kNumTemps = 3; 754 const intptr_t kNumTemps = 3;
757 LocationSummary* locs = 755 LocationSummary* locs =
758 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 756 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
759 locs->set_temp(0, Location::RegisterLocation(EAX)); 757 locs->set_temp(0, Location::RegisterLocation(EAX));
(...skipping 22 matching lines...) Expand all
782 } else { 780 } else {
783 __ leal(EAX, 781 __ leal(EAX,
784 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize)); 782 Address(EBP, ParsedFunction::kFirstLocalSlotIndex * kWordSize));
785 } 783 }
786 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function()))); 784 __ movl(ECX, Immediate(reinterpret_cast<uword>(native_c_function())));
787 __ movl(EDX, Immediate(arg_count)); 785 __ movl(EDX, Immediate(arg_count));
788 compiler->GenerateCall(token_pos(), 786 compiler->GenerateCall(token_pos(),
789 try_index(), 787 try_index(),
790 &StubCode::CallNativeCFunctionLabel(), 788 &StubCode::CallNativeCFunctionLabel(),
791 PcDescriptors::kOther, 789 PcDescriptors::kOther,
792 locs()->stack_bitmap()); 790 locs());
793 __ popl(result); 791 __ popl(result);
794 } 792 }
795 793
796 794
797 LocationSummary* LoadIndexedComp::MakeLocationSummary() const { 795 LocationSummary* LoadIndexedComp::MakeLocationSummary() const {
798 ASSERT((receiver_type() == kGrowableObjectArrayCid) || 796 ASSERT((receiver_type() == kGrowableObjectArrayCid) ||
799 (receiver_type() == kArrayCid) || 797 (receiver_type() == kArrayCid) ||
800 (receiver_type() == kImmutableArrayCid)); 798 (receiver_type() == kImmutableArrayCid));
801 const intptr_t kNumInputs = 2; 799 const intptr_t kNumInputs = 2;
802 const intptr_t kNumTemps = 1; 800 const intptr_t kNumTemps = 1;
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { 986 void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) {
989 ASSERT(locs()->in(0).reg() == EAX); // Value. 987 ASSERT(locs()->in(0).reg() == EAX); // Value.
990 ASSERT(locs()->in(1).reg() == ECX); // Instantiator. 988 ASSERT(locs()->in(1).reg() == ECX); // Instantiator.
991 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. 989 ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments.
992 990
993 compiler->GenerateInstanceOf(deopt_id(), 991 compiler->GenerateInstanceOf(deopt_id(),
994 token_pos(), 992 token_pos(),
995 try_index(), 993 try_index(),
996 type(), 994 type(),
997 negate_result(), 995 negate_result(),
998 locs()->stack_bitmap()); 996 locs());
999 ASSERT(locs()->out().reg() == EAX); 997 ASSERT(locs()->out().reg() == EAX);
1000 } 998 }
1001 999
1002 1000
1003 LocationSummary* CreateArrayComp::MakeLocationSummary() const { 1001 LocationSummary* CreateArrayComp::MakeLocationSummary() const {
1004 const intptr_t kNumInputs = 1; 1002 const intptr_t kNumInputs = 1;
1005 const intptr_t kNumTemps = 0; 1003 const intptr_t kNumTemps = 0;
1006 LocationSummary* locs = 1004 LocationSummary* locs =
1007 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1005 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1008 locs->set_in(0, Location::RegisterLocation(ECX)); 1006 locs->set_in(0, Location::RegisterLocation(ECX));
1009 locs->set_out(Location::RegisterLocation(EAX)); 1007 locs->set_out(Location::RegisterLocation(EAX));
1010 return locs; 1008 return locs;
1011 } 1009 }
1012 1010
1013 1011
1014 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1012 void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1015 // Allocate the array. EDX = length, ECX = element type. 1013 // Allocate the array. EDX = length, ECX = element type.
1016 ASSERT(locs()->in(0).reg() == ECX); 1014 ASSERT(locs()->in(0).reg() == ECX);
1017 __ movl(EDX, Immediate(Smi::RawValue(ArgumentCount()))); 1015 __ movl(EDX, Immediate(Smi::RawValue(ArgumentCount())));
1018 compiler->GenerateCall(token_pos(), 1016 compiler->GenerateCall(token_pos(),
1019 try_index(), 1017 try_index(),
1020 &StubCode::AllocateArrayLabel(), 1018 &StubCode::AllocateArrayLabel(),
1021 PcDescriptors::kOther, 1019 PcDescriptors::kOther,
1022 locs()->stack_bitmap()); 1020 locs());
1023 ASSERT(locs()->out().reg() == EAX); 1021 ASSERT(locs()->out().reg() == EAX);
1024 1022
1025 // Pop the element values from the stack into the array. 1023 // Pop the element values from the stack into the array.
1026 __ leal(EDX, FieldAddress(EAX, Array::data_offset())); 1024 __ leal(EDX, FieldAddress(EAX, Array::data_offset()));
1027 for (int i = ArgumentCount() - 1; i >= 0; --i) { 1025 for (int i = ArgumentCount() - 1; i >= 0; --i) {
1028 ASSERT(ArgumentAt(i)->value()->IsUse()); 1026 ASSERT(ArgumentAt(i)->value()->IsUse());
1029 __ popl(Address(EDX, i * kWordSize)); 1027 __ popl(Address(EDX, i * kWordSize));
1030 } 1028 }
1031 } 1029 }
1032 1030
(...skipping 20 matching lines...) Expand all
1053 1051
1054 // Push the result place holder initialized to NULL. 1052 // Push the result place holder initialized to NULL.
1055 __ PushObject(Object::ZoneHandle()); 1053 __ PushObject(Object::ZoneHandle());
1056 __ PushObject(cls); 1054 __ PushObject(cls);
1057 __ pushl(type_arguments); 1055 __ pushl(type_arguments);
1058 __ pushl(instantiator_type_arguments); 1056 __ pushl(instantiator_type_arguments);
1059 compiler->GenerateCallRuntime(deopt_id(), 1057 compiler->GenerateCallRuntime(deopt_id(),
1060 token_pos(), 1058 token_pos(),
1061 try_index(), 1059 try_index(),
1062 kAllocateObjectWithBoundsCheckRuntimeEntry, 1060 kAllocateObjectWithBoundsCheckRuntimeEntry,
1063 locs()->stack_bitmap()); 1061 locs());
1064 // Pop instantiator type arguments, type arguments, and class. 1062 // Pop instantiator type arguments, type arguments, and class.
1065 // source location. 1063 // source location.
1066 __ Drop(3); 1064 __ Drop(3);
1067 __ popl(result); // Pop new instance. 1065 __ popl(result); // Pop new instance.
1068 } 1066 }
1069 1067
1070 1068
1071 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { 1069 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const {
1072 return LocationSummary::Make(1, 1070 return LocationSummary::Make(1,
1073 Location::RequiresRegister(), 1071 Location::RequiresRegister(),
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 __ Bind(&type_arguments_uninstantiated); 1139 __ Bind(&type_arguments_uninstantiated);
1142 } 1140 }
1143 // A runtime call to instantiate the type arguments is required. 1141 // A runtime call to instantiate the type arguments is required.
1144 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1142 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1145 __ PushObject(type_arguments()); 1143 __ PushObject(type_arguments());
1146 __ pushl(instantiator_reg); // Push instantiator type arguments. 1144 __ pushl(instantiator_reg); // Push instantiator type arguments.
1147 compiler->GenerateCallRuntime(deopt_id(), 1145 compiler->GenerateCallRuntime(deopt_id(),
1148 token_pos(), 1146 token_pos(),
1149 try_index(), 1147 try_index(),
1150 kInstantiateTypeArgumentsRuntimeEntry, 1148 kInstantiateTypeArgumentsRuntimeEntry,
1151 locs()->stack_bitmap()); 1149 locs());
1152 __ Drop(2); // Drop instantiator and uninstantiated type arguments. 1150 __ Drop(2); // Drop instantiator and uninstantiated type arguments.
1153 __ popl(result_reg); // Pop instantiated type arguments. 1151 __ popl(result_reg); // Pop instantiated type arguments.
1154 __ Bind(&type_arguments_instantiated); 1152 __ Bind(&type_arguments_instantiated);
1155 ASSERT(instantiator_reg == result_reg); 1153 ASSERT(instantiator_reg == result_reg);
1156 // 'result_reg': Instantiated type arguments. 1154 // 'result_reg': Instantiated type arguments.
1157 } 1155 }
1158 1156
1159 1157
1160 LocationSummary* 1158 LocationSummary*
1161 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const { 1159 ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const {
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 ASSERT(locs()->temp(0).reg() == EDX); 1296 ASSERT(locs()->temp(0).reg() == EDX);
1299 ASSERT(locs()->out().reg() == EAX); 1297 ASSERT(locs()->out().reg() == EAX);
1300 1298
1301 __ movl(EDX, Immediate(num_context_variables())); 1299 __ movl(EDX, Immediate(num_context_variables()));
1302 const ExternalLabel label("alloc_context", 1300 const ExternalLabel label("alloc_context",
1303 StubCode::AllocateContextEntryPoint()); 1301 StubCode::AllocateContextEntryPoint());
1304 compiler->GenerateCall(token_pos(), 1302 compiler->GenerateCall(token_pos(),
1305 try_index(), 1303 try_index(),
1306 &label, 1304 &label,
1307 PcDescriptors::kOther, 1305 PcDescriptors::kOther,
1308 locs()->stack_bitmap()); 1306 locs());
1309 } 1307 }
1310 1308
1311 1309
1312 LocationSummary* CloneContextComp::MakeLocationSummary() const { 1310 LocationSummary* CloneContextComp::MakeLocationSummary() const {
1313 const intptr_t kNumInputs = 1; 1311 const intptr_t kNumInputs = 1;
1314 const intptr_t kNumTemps = 0; 1312 const intptr_t kNumTemps = 0;
1315 LocationSummary* locs = 1313 LocationSummary* locs =
1316 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1314 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1317 locs->set_in(0, Location::RegisterLocation(EAX)); 1315 locs->set_in(0, Location::RegisterLocation(EAX));
1318 locs->set_out(Location::RegisterLocation(EAX)); 1316 locs->set_out(Location::RegisterLocation(EAX));
1319 return locs; 1317 return locs;
1320 } 1318 }
1321 1319
1322 1320
1323 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1321 void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1324 Register context_value = locs()->in(0).reg(); 1322 Register context_value = locs()->in(0).reg();
1325 Register result = locs()->out().reg(); 1323 Register result = locs()->out().reg();
1326 1324
1327 __ PushObject(Object::ZoneHandle()); // Make room for the result. 1325 __ PushObject(Object::ZoneHandle()); // Make room for the result.
1328 __ pushl(context_value); 1326 __ pushl(context_value);
1329 compiler->GenerateCallRuntime(deopt_id(), 1327 compiler->GenerateCallRuntime(deopt_id(),
1330 token_pos(), 1328 token_pos(),
1331 try_index(), 1329 try_index(),
1332 kCloneContextRuntimeEntry, 1330 kCloneContextRuntimeEntry,
1333 locs()->stack_bitmap()); 1331 locs());
1334 __ popl(result); // Remove argument. 1332 __ popl(result); // Remove argument.
1335 __ popl(result); // Get result (cloned context). 1333 __ popl(result); // Get result (cloned context).
1336 } 1334 }
1337 1335
1338 1336
1339 LocationSummary* CatchEntryComp::MakeLocationSummary() const { 1337 LocationSummary* CatchEntryComp::MakeLocationSummary() const {
1340 return LocationSummary::Make(0, 1338 return LocationSummary::Make(0,
1341 Location::NoLocation(), 1339 Location::NoLocation(),
1342 LocationSummary::kNoCall); 1340 LocationSummary::kNoCall);
1343 } 1341 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 explicit CheckStackOverflowSlowPath(CheckStackOverflowComp* computation) 1377 explicit CheckStackOverflowSlowPath(CheckStackOverflowComp* computation)
1380 : computation_(computation) { } 1378 : computation_(computation) { }
1381 1379
1382 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { 1380 virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
1383 __ Bind(entry_label()); 1381 __ Bind(entry_label());
1384 compiler->SaveLiveRegisters(computation_->locs()); 1382 compiler->SaveLiveRegisters(computation_->locs());
1385 compiler->GenerateCallRuntime(computation_->deopt_id(), 1383 compiler->GenerateCallRuntime(computation_->deopt_id(),
1386 computation_->token_pos(), 1384 computation_->token_pos(),
1387 computation_->try_index(), 1385 computation_->try_index(),
1388 kStackOverflowRuntimeEntry, 1386 kStackOverflowRuntimeEntry,
1389 computation_->locs()->stack_bitmap()); 1387 computation_->locs());
1390 compiler->RestoreLiveRegisters(computation_->locs()); 1388 compiler->RestoreLiveRegisters(computation_->locs());
1391 __ jmp(exit_label()); 1389 __ jmp(exit_label());
1392 } 1390 }
1393 1391
1394 private: 1392 private:
1395 CheckStackOverflowComp* computation_; 1393 CheckStackOverflowComp* computation_;
1396 }; 1394 };
1397 1395
1398 1396
1399 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1397 void CheckStackOverflowComp::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1571 const intptr_t kArgumentCount = 2; 1569 const intptr_t kArgumentCount = 2;
1572 __ pushl(temp); 1570 __ pushl(temp);
1573 __ pushl(right); 1571 __ pushl(right);
1574 compiler->GenerateStaticCall( 1572 compiler->GenerateStaticCall(
1575 instance_call()->deopt_id(), 1573 instance_call()->deopt_id(),
1576 instance_call()->token_pos(), 1574 instance_call()->token_pos(),
1577 instance_call()->try_index(), 1575 instance_call()->try_index(),
1578 target, 1576 target,
1579 kArgumentCount, 1577 kArgumentCount,
1580 Array::Handle(), // No argument names. 1578 Array::Handle(), // No argument names.
1581 locs()->stack_bitmap()); 1579 locs());
1582 ASSERT(result == EAX); 1580 ASSERT(result == EAX);
1583 } 1581 }
1584 __ Bind(&done); 1582 __ Bind(&done);
1585 break; 1583 break;
1586 } 1584 }
1587 case Token::kDIV: { 1585 case Token::kDIV: {
1588 // Dispatches to 'Double./'. 1586 // Dispatches to 'Double./'.
1589 // TODO(srdjan): Implement as conversion to double and double division. 1587 // TODO(srdjan): Implement as conversion to double and double division.
1590 UNREACHABLE(); 1588 UNREACHABLE();
1591 break; 1589 break;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 } else { 1677 } else {
1680 __ pushl(left); 1678 __ pushl(left);
1681 __ pushl(right); 1679 __ pushl(right);
1682 compiler->GenerateStaticCall( 1680 compiler->GenerateStaticCall(
1683 instance_call()->deopt_id(), 1681 instance_call()->deopt_id(),
1684 instance_call()->token_pos(), 1682 instance_call()->token_pos(),
1685 instance_call()->try_index(), 1683 instance_call()->try_index(),
1686 target, 1684 target,
1687 instance_call()->ArgumentCount(), 1685 instance_call()->ArgumentCount(),
1688 instance_call()->argument_names(), 1686 instance_call()->argument_names(),
1689 locs()->stack_bitmap()); 1687 locs());
1690 ASSERT(result == EAX); 1688 ASSERT(result == EAX);
1691 __ jmp(&done); 1689 __ jmp(&done);
1692 } 1690 }
1693 } 1691 }
1694 1692
1695 __ Bind(&mint_static_call); 1693 __ Bind(&mint_static_call);
1696 { 1694 {
1697 Function& target = Function::ZoneHandle( 1695 Function& target = Function::ZoneHandle(
1698 ic_data()->GetTargetForReceiverClassId(kMintCid)); 1696 ic_data()->GetTargetForReceiverClassId(kMintCid));
1699 if (target.IsNull()) { 1697 if (target.IsNull()) {
1700 __ jmp(deopt); 1698 __ jmp(deopt);
1701 } else { 1699 } else {
1702 __ pushl(left); 1700 __ pushl(left);
1703 __ pushl(right); 1701 __ pushl(right);
1704 compiler->GenerateStaticCall( 1702 compiler->GenerateStaticCall(
1705 instance_call()->deopt_id(), 1703 instance_call()->deopt_id(),
1706 instance_call()->token_pos(), 1704 instance_call()->token_pos(),
1707 instance_call()->try_index(), 1705 instance_call()->try_index(),
1708 target, 1706 target,
1709 instance_call()->ArgumentCount(), 1707 instance_call()->ArgumentCount(),
1710 instance_call()->argument_names(), 1708 instance_call()->argument_names(),
1711 locs()->stack_bitmap()); 1709 locs());
1712 ASSERT(result == EAX); 1710 ASSERT(result == EAX);
1713 } 1711 }
1714 } 1712 }
1715 __ Bind(&done); 1713 __ Bind(&done);
1716 } 1714 }
1717 1715
1718 1716
1719 LocationSummary* BinaryDoubleOpComp::MakeLocationSummary() const { 1717 LocationSummary* BinaryDoubleOpComp::MakeLocationSummary() const {
1720 return MakeCallSummary(); // Calls into a stub for allocation. 1718 return MakeCallSummary(); // Calls into a stub for allocation.
1721 } 1719 }
1722 1720
1723 1721
1724 void BinaryDoubleOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1722 void BinaryDoubleOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1725 Register left = EBX; 1723 Register left = EBX;
1726 Register right = ECX; 1724 Register right = ECX;
1727 Register temp = EDX; 1725 Register temp = EDX;
1728 Register result = locs()->out().reg(); 1726 Register result = locs()->out().reg();
1729 1727
1730 const Class& double_class = compiler->double_class(); 1728 const Class& double_class = compiler->double_class();
1731 const Code& stub = 1729 const Code& stub =
1732 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1730 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1733 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1731 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1734 compiler->GenerateCall(instance_call()->token_pos(), 1732 compiler->GenerateCall(instance_call()->token_pos(),
1735 instance_call()->try_index(), 1733 instance_call()->try_index(),
1736 &label, 1734 &label,
1737 PcDescriptors::kOther, 1735 PcDescriptors::kOther,
1738 locs()->stack_bitmap()); 1736 locs());
1739 // Newly allocated object is now in the result register (RAX). 1737 // Newly allocated object is now in the result register (RAX).
1740 ASSERT(result == EAX); 1738 ASSERT(result == EAX);
1741 __ movl(right, Address(ESP, 0)); 1739 __ movl(right, Address(ESP, 0));
1742 __ movl(left, Address(ESP, kWordSize)); 1740 __ movl(left, Address(ESP, kWordSize));
1743 1741
1744 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1742 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1745 instance_call()->try_index(), 1743 instance_call()->try_index(),
1746 kDeoptBinaryDoubleOp); 1744 kDeoptBinaryDoubleOp);
1747 1745
1748 // Binary operation of two Smi's produces a Smi not a double. 1746 // Binary operation of two Smi's produces a Smi not a double.
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1854 // Allocate result object. 1852 // Allocate result object.
1855 const Class& double_class = compiler->double_class(); 1853 const Class& double_class = compiler->double_class();
1856 const Code& stub = 1854 const Code& stub =
1857 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1855 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1858 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1856 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1859 __ pushl(value); 1857 __ pushl(value);
1860 compiler->GenerateCall(instance_call()->token_pos(), 1858 compiler->GenerateCall(instance_call()->token_pos(),
1861 instance_call()->try_index(), 1859 instance_call()->try_index(),
1862 &label, 1860 &label,
1863 PcDescriptors::kOther, 1861 PcDescriptors::kOther,
1864 locs()->stack_bitmap()); 1862 locs());
1865 // Result is in EAX. 1863 // Result is in EAX.
1866 ASSERT(result != temp); 1864 ASSERT(result != temp);
1867 __ movl(result, EAX); 1865 __ movl(result, EAX);
1868 __ popl(temp); 1866 __ popl(temp);
1869 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); 1867 __ movsd(XMM0, FieldAddress(temp, Double::value_offset()));
1870 __ DoubleNegate(XMM0); 1868 __ DoubleNegate(XMM0);
1871 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 1869 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
1872 } else { 1870 } else {
1873 UNREACHABLE(); 1871 UNREACHABLE();
1874 } 1872 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1919 const Class& double_class = compiler->double_class(); 1917 const Class& double_class = compiler->double_class();
1920 const Code& stub = 1918 const Code& stub =
1921 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1919 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1922 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1920 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1923 1921
1924 // TODO(vegorov): allocate box in the driver loop to avoid spilling. 1922 // TODO(vegorov): allocate box in the driver loop to avoid spilling.
1925 compiler->GenerateCall(instance_call()->token_pos(), 1923 compiler->GenerateCall(instance_call()->token_pos(),
1926 instance_call()->try_index(), 1924 instance_call()->try_index(),
1927 &label, 1925 &label,
1928 PcDescriptors::kOther, 1926 PcDescriptors::kOther,
1929 locs()->stack_bitmap()); 1927 locs());
1930 ASSERT(result == EAX); 1928 ASSERT(result == EAX);
1931 Register value = EBX; 1929 Register value = EBX;
1932 // Preserve argument on the stack until after the deoptimization point. 1930 // Preserve argument on the stack until after the deoptimization point.
1933 __ movl(value, Address(ESP, 0)); 1931 __ movl(value, Address(ESP, 0));
1934 1932
1935 __ testl(value, Immediate(kSmiTagMask)); 1933 __ testl(value, Immediate(kSmiTagMask));
1936 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. 1934 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi.
1937 __ SmiUntag(value); 1935 __ SmiUntag(value);
1938 __ cvtsi2sd(XMM0, value); 1936 __ cvtsi2sd(XMM0, value);
1939 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); 1937 __ movsd(FieldAddress(result, Double::value_offset()), XMM0);
(...skipping 29 matching lines...) Expand all
1969 __ LoadClassId(EDI, EAX); 1967 __ LoadClassId(EDI, EAX);
1970 compiler->EmitTestAndCall(*ic_data(), 1968 compiler->EmitTestAndCall(*ic_data(),
1971 EDI, // Class id register. 1969 EDI, // Class id register.
1972 instance_call()->ArgumentCount(), 1970 instance_call()->ArgumentCount(),
1973 instance_call()->argument_names(), 1971 instance_call()->argument_names(),
1974 deopt, 1972 deopt,
1975 (is_smi_label == &handle_smi) ? &done : NULL, 1973 (is_smi_label == &handle_smi) ? &done : NULL,
1976 instance_call()->deopt_id(), 1974 instance_call()->deopt_id(),
1977 instance_call()->token_pos(), 1975 instance_call()->token_pos(),
1978 instance_call()->try_index(), 1976 instance_call()->try_index(),
1979 locs()->stack_bitmap()); 1977 locs());
1980 if (is_smi_label == &handle_smi) { 1978 if (is_smi_label == &handle_smi) {
1981 __ Bind(&handle_smi); 1979 __ Bind(&handle_smi);
1982 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmiCid); 1980 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmiCid);
1983 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0)); 1981 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0));
1984 compiler->GenerateStaticCall(instance_call()->deopt_id(), 1982 compiler->GenerateStaticCall(instance_call()->deopt_id(),
1985 instance_call()->token_pos(), 1983 instance_call()->token_pos(),
1986 instance_call()->try_index(), 1984 instance_call()->try_index(),
1987 target, 1985 target,
1988 instance_call()->ArgumentCount(), 1986 instance_call()->ArgumentCount(),
1989 instance_call()->argument_names(), 1987 instance_call()->argument_names(),
1990 locs()->stack_bitmap()); 1988 locs());
1991 } 1989 }
1992 __ Bind(&done); 1990 __ Bind(&done);
1993 } 1991 }
1994 1992
1995 1993
1996 // TODO(srdjan): Move to shared. 1994 // TODO(srdjan): Move to shared.
1997 static bool ICDataWithBothClassIds(const ICData& ic_data, intptr_t class_id) { 1995 static bool ICDataWithBothClassIds(const ICData& ic_data, intptr_t class_id) {
1998 if (ic_data.num_args_tested() != 2) return false; 1996 if (ic_data.num_args_tested() != 2) return false;
1999 if (ic_data.NumberOfChecks() != 1) return false; 1997 if (ic_data.NumberOfChecks() != 1) return false;
2000 Function& target = Function::Handle(); 1998 Function& target = Function::Handle();
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2080 return; 2078 return;
2081 } 2079 }
2082 if (IsCheckedStrictEquals(*ic_data(), kind())) { 2080 if (IsCheckedStrictEquals(*ic_data(), kind())) {
2083 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), this, 2081 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), this,
2084 deopt_id(), token_pos(), try_index()); 2082 deopt_id(), token_pos(), try_index());
2085 return; 2083 return;
2086 } 2084 }
2087 2085
2088 // TODO(srdjan): Add Smi/Double, Double/Smi comparisons. 2086 // TODO(srdjan): Add Smi/Double, Double/Smi comparisons.
2089 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) { 2087 if ((kind() == Token::kEQ) || (kind() == Token::kNE)) {
2090 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(), 2088 EmitGenericEqualityCompare(compiler, locs(), kind(), this, *ic_data(),
2091 deopt_id(), token_pos(), try_index()); 2089 deopt_id(), token_pos(), try_index());
2092 return; 2090 return;
2093 } 2091 }
2094 // Otherwise polymorphic dispatch? 2092 // Otherwise polymorphic dispatch?
2095 } 2093 }
2096 Register left = locs()->in(0).reg(); 2094 Register left = locs()->in(0).reg();
2097 Register right = locs()->in(1).reg(); 2095 Register right = locs()->in(1).reg();
2098 __ pushl(left); 2096 __ pushl(left);
2099 __ pushl(right); 2097 __ pushl(right);
2100 if ((kind() == Token::kNE) || (kind() == Token::kEQ)) { 2098 if ((kind() == Token::kNE) || (kind() == Token::kEQ)) {
2101 EmitEqualityAsInstanceCall(compiler, 2099 EmitEqualityAsInstanceCall(compiler,
2102 deopt_id(), 2100 deopt_id(),
2103 token_pos(), 2101 token_pos(),
2104 try_index(), 2102 try_index(),
2105 Token::kEQ, // kNE reverse occurs at branch. 2103 Token::kEQ, // kNE reverse occurs at branch.
2106 *locs()); 2104 locs());
2107 } else { 2105 } else {
2108 const String& function_name = 2106 const String& function_name =
2109 String::ZoneHandle(Symbols::New(Token::Str(kind()))); 2107 String::ZoneHandle(Symbols::New(Token::Str(kind())));
2110 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 2108 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
2111 deopt_id(), 2109 deopt_id(),
2112 token_pos(), 2110 token_pos(),
2113 try_index()); 2111 try_index());
2114 const intptr_t kNumArguments = 2; 2112 const intptr_t kNumArguments = 2;
2115 const intptr_t kNumArgsChecked = 2; // Type-feedback. 2113 const intptr_t kNumArgsChecked = 2; // Type-feedback.
2116 compiler->GenerateInstanceCall(deopt_id(), 2114 compiler->GenerateInstanceCall(deopt_id(),
2117 token_pos(), 2115 token_pos(),
2118 try_index(), 2116 try_index(),
2119 function_name, 2117 function_name,
2120 kNumArguments, 2118 kNumArguments,
2121 Array::ZoneHandle(), // No optional args. 2119 Array::ZoneHandle(), // No optional args.
2122 kNumArgsChecked, 2120 kNumArgsChecked,
2123 locs()->stack_bitmap()); 2121 locs());
2124 } 2122 }
2125 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 2123 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
2126 __ CompareObject(EAX, compiler->bool_true()); 2124 __ CompareObject(EAX, compiler->bool_true());
2127 EmitBranchOnCondition(compiler, branch_condition); 2125 EmitBranchOnCondition(compiler, branch_condition);
2128 } 2126 }
2129 2127
2130 2128
2131 LocationSummary* CheckClassComp::MakeLocationSummary() const { 2129 LocationSummary* CheckClassComp::MakeLocationSummary() const {
2132 const intptr_t kNumInputs = 1; 2130 const intptr_t kNumInputs = 1;
2133 const intptr_t kNumTemps = 1; 2131 const intptr_t kNumTemps = 1;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2193 __ testl(value, Immediate(kSmiTagMask)); 2191 __ testl(value, Immediate(kSmiTagMask));
2194 __ j(NOT_ZERO, deopt); 2192 __ j(NOT_ZERO, deopt);
2195 } 2193 }
2196 2194
2197 2195
2198 } // namespace dart 2196 } // namespace dart
2199 2197
2200 #undef __ 2198 #undef __
2201 2199
2202 #endif // defined TARGET_ARCH_X64 2200 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698