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

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

Issue 10855208: Implement new equality spec. (Closed) Base URL: http://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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 EqualityCompareComp* comp) { 292 EqualityCompareComp* comp) {
293 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 293 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
294 comp->deopt_id(), 294 comp->deopt_id(),
295 comp->token_pos(), 295 comp->token_pos(),
296 comp->try_index()); 296 comp->try_index());
297 const String& operator_name = String::ZoneHandle(Symbols::New("==")); 297 const String& operator_name = String::ZoneHandle(Symbols::New("=="));
298 const int kNumberOfArguments = 2; 298 const int kNumberOfArguments = 2;
299 const Array& kNoArgumentNames = Array::Handle(); 299 const Array& kNoArgumentNames = Array::Handle();
300 const int kNumArgumentsChecked = 2; 300 const int kNumArgumentsChecked = 2;
301 301
302 Label done, false_label, true_label;
303 Register left = comp->locs()->in(0).reg();
304 Register right = comp->locs()->in(1).reg();
305 __ popq(right);
306 __ popq(left);
307 const Immediate raw_null =
308 Immediate(reinterpret_cast<intptr_t>(Object::null()));
309 Label check_identity, instance_call;
310 __ cmpq(right, raw_null);
311 __ j(EQUAL, &check_identity, Assembler::kNearJump);
312 __ cmpq(left, raw_null);
313 __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump);
314
315 __ Bind(&check_identity);
316 __ cmpq(left, right);
317 __ j(EQUAL, &true_label);
318 if (comp->kind() == Token::kEQ) {
319 __ LoadObject(RAX, compiler->bool_false());
320 __ jmp(&done);
321 __ Bind(&true_label);
322 __ LoadObject(RAX, compiler->bool_true());
323 __ jmp(&done);
324 } else {
regis 2012/08/17 01:53:45 ditto
srdjan 2012/08/17 17:26:41 Done.
325 __ jmp(&false_label);
326 }
327
328 __ Bind(&instance_call);
329 __ pushq(left);
330 __ pushq(right);
302 compiler->GenerateInstanceCall(comp->deopt_id(), 331 compiler->GenerateInstanceCall(comp->deopt_id(),
303 comp->token_pos(), 332 comp->token_pos(),
304 comp->try_index(), 333 comp->try_index(),
305 operator_name, 334 operator_name,
306 kNumberOfArguments, 335 kNumberOfArguments,
307 kNoArgumentNames, 336 kNoArgumentNames,
308 kNumArgumentsChecked, 337 kNumArgumentsChecked,
309 comp->locs()->stack_bitmap()); 338 comp->locs()->stack_bitmap());
310 ASSERT(comp->locs()->out().reg() == RAX); 339 ASSERT(comp->locs()->out().reg() == RAX);
311 if (comp->kind() == Token::kNE) { 340 if (comp->kind() == Token::kNE) {
312 Label done, false_label; 341 // Negate the condition: true label returns false and vice versa.
313 __ CompareObject(RAX, compiler->bool_true()); 342 __ CompareObject(RAX, compiler->bool_true());
314 __ j(EQUAL, &false_label, Assembler::kNearJump); 343 __ j(EQUAL, &true_label, Assembler::kNearJump);
344 __ Bind(&false_label);
315 __ LoadObject(RAX, compiler->bool_true()); 345 __ LoadObject(RAX, compiler->bool_true());
316 __ jmp(&done, Assembler::kNearJump); 346 __ jmp(&done, Assembler::kNearJump);
317 __ Bind(&false_label); 347 __ Bind(&true_label);
318 __ LoadObject(RAX, compiler->bool_false()); 348 __ LoadObject(RAX, compiler->bool_false());
319 __ Bind(&done);
320 } 349 }
350 __ Bind(&done);
321 } 351 }
322 352
323 353
324 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, 354 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
325 const ICData& orig_ic_data, 355 const ICData& orig_ic_data,
326 const LocationSummary& locs, 356 const LocationSummary& locs,
327 BranchInstr* branch, 357 BranchInstr* branch,
328 Token::Kind kind, 358 Token::Kind kind,
329 intptr_t deopt_id, 359 intptr_t deopt_id,
330 intptr_t token_pos, 360 intptr_t token_pos,
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 Register left = locs.in(0).reg(); 456 Register left = locs.in(0).reg();
427 Register right = locs.in(1).reg(); 457 Register right = locs.in(1).reg();
428 Register temp = locs.temp(0).reg(); 458 Register temp = locs.temp(0).reg();
429 Label* deopt = compiler->AddDeoptStub(deopt_id, 459 Label* deopt = compiler->AddDeoptStub(deopt_id,
430 try_index, 460 try_index,
431 kDeoptEquality, 461 kDeoptEquality,
432 left, 462 left,
433 right); 463 right);
434 __ testq(left, Immediate(kSmiTagMask)); 464 __ testq(left, Immediate(kSmiTagMask));
435 __ j(ZERO, deopt); 465 __ j(ZERO, deopt);
466 // 'left' is not Smi.
467 const Immediate raw_null =
468 Immediate(reinterpret_cast<intptr_t>(Object::null()));
469 Label identity_compare;
470 __ cmpq(right, raw_null);
471 __ j(EQUAL, &identity_compare);
472 __ cmpq(left, raw_null);
473 __ j(EQUAL, &identity_compare);
474
436 __ LoadClassId(temp, left); 475 __ LoadClassId(temp, left);
437 Label done;
438 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { 476 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
439 __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); 477 __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i)));
440 if (i == (ic_data.NumberOfChecks() - 1)) { 478 if (i == (ic_data.NumberOfChecks() - 1)) {
441 __ j(NOT_EQUAL, deopt); 479 __ j(NOT_EQUAL, deopt);
442 } else { 480 } else {
443 __ j(EQUAL, &done); 481 __ j(EQUAL, &identity_compare);
444 } 482 }
445 } 483 }
446 __ Bind(&done); 484 __ Bind(&identity_compare);
447 __ cmpq(left, right); 485 __ cmpq(left, right);
448 if (branch == NULL) { 486 if (branch == NULL) {
449 Label done, is_equal; 487 Label done, is_equal;
450 Register result = locs.out().reg(); 488 Register result = locs.out().reg();
451 __ j(EQUAL, &is_equal, Assembler::kNearJump); 489 __ j(EQUAL, &is_equal, Assembler::kNearJump);
452 // Not equal. 490 // Not equal.
453 __ LoadObject(result, (kind == Token::kEQ) ? compiler->bool_false() 491 __ LoadObject(result, (kind == Token::kEQ) ? compiler->bool_false()
454 : compiler->bool_true()); 492 : compiler->bool_true());
455 __ jmp(&done, Assembler::kNearJump); 493 __ jmp(&done, Assembler::kNearJump);
456 __ Bind(&is_equal); 494 __ Bind(&is_equal);
(...skipping 17 matching lines...) Expand all
474 const ICData& ic_data, 512 const ICData& ic_data,
475 intptr_t deopt_id, 513 intptr_t deopt_id,
476 intptr_t token_pos, 514 intptr_t token_pos,
477 intptr_t try_index) { 515 intptr_t try_index) {
478 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 516 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
479 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); 517 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
480 Register left = locs.in(0).reg(); 518 Register left = locs.in(0).reg();
481 Register right = locs.in(1).reg(); 519 Register right = locs.in(1).reg();
482 const Immediate raw_null = 520 const Immediate raw_null =
483 Immediate(reinterpret_cast<intptr_t>(Object::null())); 521 Immediate(reinterpret_cast<intptr_t>(Object::null()));
484 Label done, non_null_compare; 522 Label done, identity_compare, non_null_compare;
523 __ cmpq(right, raw_null);
524 __ j(EQUAL, &identity_compare, Assembler::kNearJump);
485 __ cmpq(left, raw_null); 525 __ cmpq(left, raw_null);
486 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); 526 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump);
487 // Comparison with NULL is "===". 527 // Comparison with NULL is "===".
528 __ Bind(&identity_compare);
488 __ cmpq(left, right); 529 __ cmpq(left, right);
489 Condition cond = TokenKindToSmiCondition(kind); 530 Condition cond = TokenKindToSmiCondition(kind);
490 if (branch != NULL) { 531 if (branch != NULL) {
491 branch->EmitBranchOnCondition(compiler, cond); 532 branch->EmitBranchOnCondition(compiler, cond);
492 } else { 533 } else {
493 Register result = locs.out().reg(); 534 Register result = locs.out().reg();
494 Label load_true; 535 Label load_true;
495 __ j(cond, &load_true, Assembler::kNearJump); 536 __ j(cond, &load_true, Assembler::kNearJump);
496 __ LoadObject(result, compiler->bool_false()); 537 __ LoadObject(result, compiler->bool_false());
497 __ jmp(&done); 538 __ jmp(&done);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 true_condition, XMM0, XMM1, branch); 634 true_condition, XMM0, XMM1, branch);
594 } else { 635 } else {
595 compiler->EmitDoubleCompareBool( 636 compiler->EmitDoubleCompareBool(
596 true_condition, XMM0, XMM1, locs.out().reg()); 637 true_condition, XMM0, XMM1, locs.out().reg());
597 } 638 }
598 } 639 }
599 640
600 641
601 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 642 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
602 if (receiver_class_id() == kSmiCid) { 643 if (receiver_class_id() == kSmiCid) {
644 // Deoptimizes if both arguments not Smi.
603 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch. 645 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
604 deopt_id(), token_pos(), try_index()); 646 deopt_id(), token_pos(), try_index());
605 return; 647 return;
606 } 648 }
607 if (receiver_class_id() == kDoubleCid) { 649 if (receiver_class_id() == kDoubleCid) {
650 // Deoptimizes if both arguments are Smi, or if none is Double or Smi.
608 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, // No branch. 651 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, // No branch.
609 deopt_id(), token_pos(), try_index()); 652 deopt_id(), token_pos(), try_index());
610 return; 653 return;
611 } 654 }
612 const bool is_checked_strict_equal = 655 const bool is_checked_strict_equal =
613 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); 656 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid);
614 if (is_checked_strict_equal) { 657 if (is_checked_strict_equal) {
615 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), NULL, 658 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), NULL,
616 deopt_id(), token_pos(), try_index()); 659 deopt_id(), token_pos(), try_index());
617 return; 660 return;
(...skipping 1523 matching lines...) Expand 10 before | Expand all | Expand 10 after
2141 locs()->stack_bitmap()); 2184 locs()->stack_bitmap());
2142 __ CompareObject(RAX, compiler->bool_true()); 2185 __ CompareObject(RAX, compiler->bool_true());
2143 EmitBranchOnCondition(compiler, branch_condition); 2186 EmitBranchOnCondition(compiler, branch_condition);
2144 } 2187 }
2145 2188
2146 } // namespace dart 2189 } // namespace dart
2147 2190
2148 #undef __ 2191 #undef __
2149 2192
2150 #endif // defined TARGET_ARCH_X64 2193 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698