Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 283 EqualityCompareComp* comp) { | 283 EqualityCompareComp* comp) { |
| 284 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 284 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 285 comp->deopt_id(), | 285 comp->deopt_id(), |
| 286 comp->token_pos(), | 286 comp->token_pos(), |
| 287 comp->try_index()); | 287 comp->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; | |
| 294 Register left = comp->locs()->in(0).reg(); | |
| 295 Register right = comp->locs()->in(1).reg(); | |
| 296 __ popl(right); | |
| 297 __ popl(left); | |
| 298 const Immediate raw_null = | |
| 299 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 300 Label check_identity, instance_call; | |
| 301 __ cmpl(right, raw_null); | |
| 302 __ j(EQUAL, &check_identity, Assembler::kNearJump); | |
| 303 __ cmpl(left, raw_null); | |
| 304 __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump); | |
| 305 | |
| 306 __ Bind(&check_identity); | |
| 307 __ cmpl(left, right); | |
| 308 __ j(EQUAL, &true_label); | |
| 309 if (comp->kind() == Token::kEQ) { | |
| 310 __ LoadObject(EAX, compiler->bool_false()); | |
| 311 __ jmp(&done); | |
| 312 __ Bind(&true_label); | |
| 313 __ LoadObject(EAX, compiler->bool_true()); | |
| 314 __ jmp(&done); | |
| 315 } else { | |
|
regis
2012/08/17 01:53:45
Code is easier to read if you document this branch
srdjan
2012/08/17 17:26:41
Done.
| |
| 316 __ jmp(&false_label); | |
| 317 } | |
| 318 | |
| 319 __ Bind(&instance_call); | |
| 320 __ pushl(left); | |
| 321 __ pushl(right); | |
| 293 compiler->GenerateInstanceCall(comp->deopt_id(), | 322 compiler->GenerateInstanceCall(comp->deopt_id(), |
| 294 comp->token_pos(), | 323 comp->token_pos(), |
| 295 comp->try_index(), | 324 comp->try_index(), |
| 296 operator_name, | 325 operator_name, |
| 297 kNumberOfArguments, | 326 kNumberOfArguments, |
| 298 kNoArgumentNames, | 327 kNoArgumentNames, |
| 299 kNumArgumentsChecked, | 328 kNumArgumentsChecked, |
| 300 comp->locs()->stack_bitmap()); | 329 comp->locs()->stack_bitmap()); |
| 301 ASSERT(comp->locs()->out().reg() == EAX); | 330 ASSERT(comp->locs()->out().reg() == EAX); |
| 302 if (comp->kind() == Token::kNE) { | 331 if (comp->kind() == Token::kNE) { |
| 303 Label done, false_label; | 332 // Negate the condition: true label returns false and vice versa. |
| 304 __ CompareObject(EAX, compiler->bool_true()); | 333 __ CompareObject(EAX, compiler->bool_true()); |
| 305 __ j(EQUAL, &false_label, Assembler::kNearJump); | 334 __ j(EQUAL, &true_label, Assembler::kNearJump); |
| 335 __ Bind(&false_label); | |
| 306 __ LoadObject(EAX, compiler->bool_true()); | 336 __ LoadObject(EAX, compiler->bool_true()); |
| 307 __ jmp(&done, Assembler::kNearJump); | 337 __ jmp(&done, Assembler::kNearJump); |
| 308 __ Bind(&false_label); | 338 __ Bind(&true_label); |
| 309 __ LoadObject(EAX, compiler->bool_false()); | 339 __ LoadObject(EAX, compiler->bool_false()); |
| 310 __ Bind(&done); | |
| 311 } | 340 } |
| 341 __ Bind(&done); | |
| 312 } | 342 } |
| 313 | 343 |
| 314 | 344 |
| 315 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, | 345 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, |
| 316 const ICData& orig_ic_data, | 346 const ICData& orig_ic_data, |
| 317 const LocationSummary& locs, | 347 const LocationSummary& locs, |
| 318 BranchInstr* branch, | 348 BranchInstr* branch, |
| 319 Token::Kind kind, | 349 Token::Kind kind, |
| 320 intptr_t deopt_id, | 350 intptr_t deopt_id, |
| 321 intptr_t token_pos, | 351 intptr_t token_pos, |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 416 Register left = locs.in(0).reg(); | 446 Register left = locs.in(0).reg(); |
| 417 Register right = locs.in(1).reg(); | 447 Register right = locs.in(1).reg(); |
| 418 Register temp = locs.temp(0).reg(); | 448 Register temp = locs.temp(0).reg(); |
| 419 Label* deopt = compiler->AddDeoptStub(deopt_id, | 449 Label* deopt = compiler->AddDeoptStub(deopt_id, |
| 420 try_index, | 450 try_index, |
| 421 kDeoptEquality, | 451 kDeoptEquality, |
| 422 left, | 452 left, |
| 423 right); | 453 right); |
| 424 __ testl(left, Immediate(kSmiTagMask)); | 454 __ testl(left, Immediate(kSmiTagMask)); |
| 425 __ j(ZERO, deopt); | 455 __ j(ZERO, deopt); |
| 456 // 'left' is not Smi. | |
| 457 const Immediate raw_null = | |
| 458 Immediate(reinterpret_cast<intptr_t>(Object::null())); | |
| 459 Label identity_compare; | |
| 460 __ cmpl(right, raw_null); | |
| 461 __ j(EQUAL, &identity_compare); | |
| 462 __ cmpl(left, raw_null); | |
| 463 __ j(EQUAL, &identity_compare); | |
| 464 | |
| 426 __ LoadClassId(temp, left); | 465 __ LoadClassId(temp, left); |
| 427 Label done; | |
| 428 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { | 466 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { |
| 429 __ cmpl(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); | 467 __ cmpl(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); |
| 430 if (i == (ic_data.NumberOfChecks() - 1)) { | 468 if (i == (ic_data.NumberOfChecks() - 1)) { |
| 431 __ j(NOT_EQUAL, deopt); | 469 __ j(NOT_EQUAL, deopt); |
| 432 } else { | 470 } else { |
| 433 __ j(EQUAL, &done); | 471 __ j(EQUAL, &identity_compare); |
| 434 } | 472 } |
| 435 } | 473 } |
| 436 __ Bind(&done); | 474 __ Bind(&identity_compare); |
| 437 __ cmpl(left, right); | 475 __ cmpl(left, right); |
| 438 if (branch == NULL) { | 476 if (branch == NULL) { |
| 439 Label done, is_equal; | 477 Label done, is_equal; |
| 440 Register result = locs.out().reg(); | 478 Register result = locs.out().reg(); |
| 441 __ j(EQUAL, &is_equal, Assembler::kNearJump); | 479 __ j(EQUAL, &is_equal, Assembler::kNearJump); |
| 442 // Not equal. | 480 // Not equal. |
| 443 __ LoadObject(result, (kind == Token::kEQ) ? compiler->bool_false() | 481 __ LoadObject(result, (kind == Token::kEQ) ? compiler->bool_false() |
| 444 : compiler->bool_true()); | 482 : compiler->bool_true()); |
| 445 __ jmp(&done, Assembler::kNearJump); | 483 __ jmp(&done, Assembler::kNearJump); |
| 446 __ Bind(&is_equal); | 484 __ Bind(&is_equal); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 464 const ICData& ic_data, | 502 const ICData& ic_data, |
| 465 intptr_t deopt_id, | 503 intptr_t deopt_id, |
| 466 intptr_t token_pos, | 504 intptr_t token_pos, |
| 467 intptr_t try_index) { | 505 intptr_t try_index) { |
| 468 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); | 506 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); |
| 469 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); | 507 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); |
| 470 Register left = locs.in(0).reg(); | 508 Register left = locs.in(0).reg(); |
| 471 Register right = locs.in(1).reg(); | 509 Register right = locs.in(1).reg(); |
| 472 const Immediate raw_null = | 510 const Immediate raw_null = |
| 473 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 511 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 474 Label done, non_null_compare; | 512 Label done, identity_compare, non_null_compare; |
| 513 __ cmpl(right, raw_null); | |
| 514 __ j(EQUAL, &identity_compare, Assembler::kNearJump); | |
| 475 __ cmpl(left, raw_null); | 515 __ cmpl(left, raw_null); |
| 476 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); | 516 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); |
| 477 // Comparison with NULL is "===". | 517 // Comparison with NULL is "===". |
| 518 __ Bind(&identity_compare); | |
| 478 __ cmpl(left, right); | 519 __ cmpl(left, right); |
| 479 Condition cond = TokenKindToSmiCondition(kind); | 520 Condition cond = TokenKindToSmiCondition(kind); |
| 480 if (branch != NULL) { | 521 if (branch != NULL) { |
| 481 branch->EmitBranchOnCondition(compiler, cond); | 522 branch->EmitBranchOnCondition(compiler, cond); |
| 482 } else { | 523 } else { |
| 483 Register result = locs.out().reg(); | 524 Register result = locs.out().reg(); |
| 484 Label load_true; | 525 Label load_true; |
| 485 __ j(cond, &load_true, Assembler::kNearJump); | 526 __ j(cond, &load_true, Assembler::kNearJump); |
| 486 __ LoadObject(result, compiler->bool_false()); | 527 __ LoadObject(result, compiler->bool_false()); |
| 487 __ jmp(&done); | 528 __ jmp(&done); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 583 true_condition, XMM0, XMM1, branch); | 624 true_condition, XMM0, XMM1, branch); |
| 584 } else { | 625 } else { |
| 585 compiler->EmitDoubleCompareBool( | 626 compiler->EmitDoubleCompareBool( |
| 586 true_condition, XMM0, XMM1, locs.out().reg()); | 627 true_condition, XMM0, XMM1, locs.out().reg()); |
| 587 } | 628 } |
| 588 } | 629 } |
| 589 | 630 |
| 590 | 631 |
| 591 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 632 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 592 if (receiver_class_id() == kSmiCid) { | 633 if (receiver_class_id() == kSmiCid) { |
| 634 // Deoptimizes if both arguments not Smi. | |
| 593 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch. | 635 EmitSmiComparisonOp(compiler, *locs(), kind(), NULL, // No branch. |
| 594 deopt_id(), token_pos(), try_index()); | 636 deopt_id(), token_pos(), try_index()); |
| 595 return; | 637 return; |
| 596 } | 638 } |
| 597 if (receiver_class_id() == kDoubleCid) { | 639 if (receiver_class_id() == kDoubleCid) { |
| 640 // Deoptimizes if both arguments are Smi, or if none is Double or Smi. | |
| 598 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, // No branch. | 641 EmitDoubleComparisonOp(compiler, *locs(), kind(), NULL, // No branch. |
| 599 deopt_id(), token_pos(), try_index()); | 642 deopt_id(), token_pos(), try_index()); |
| 600 return; | 643 return; |
| 601 } | 644 } |
| 602 const bool is_checked_strict_equal = | 645 const bool is_checked_strict_equal = |
| 603 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); | 646 HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid); |
| 604 if (is_checked_strict_equal) { | 647 if (is_checked_strict_equal) { |
| 605 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), NULL, | 648 EmitCheckedStrictEqual(compiler, *ic_data(), *locs(), kind(), NULL, |
| 606 deopt_id(), token_pos(), try_index()); | 649 deopt_id(), token_pos(), try_index()); |
| 607 return; | 650 return; |
| (...skipping 1520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2128 locs()->stack_bitmap()); | 2171 locs()->stack_bitmap()); |
| 2129 __ CompareObject(EAX, compiler->bool_true()); | 2172 __ CompareObject(EAX, compiler->bool_true()); |
| 2130 EmitBranchOnCondition(compiler, branch_condition); | 2173 EmitBranchOnCondition(compiler, branch_condition); |
| 2131 } | 2174 } |
| 2132 | 2175 |
| 2133 } // namespace dart | 2176 } // namespace dart |
| 2134 | 2177 |
| 2135 #undef __ | 2178 #undef __ |
| 2136 | 2179 |
| 2137 #endif // defined TARGET_ARCH_X64 | 2180 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |