| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 // 'temp' contains class-id of the left argument. | 455 // 'temp' contains class-id of the left argument. |
| 456 ObjectStore* object_store = Isolate::Current()->object_store(); | 456 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 457 Condition cond = TokenKindToSmiCondition(kind); | 457 Condition cond = TokenKindToSmiCondition(kind); |
| 458 Label done; | 458 Label done; |
| 459 const intptr_t len = ic_data.NumberOfChecks(); | 459 const intptr_t len = ic_data.NumberOfChecks(); |
| 460 for (intptr_t i = 0; i < len; i++) { | 460 for (intptr_t i = 0; i < len; i++) { |
| 461 // Assert that the Smi is at position 0, if at all. | 461 // Assert that the Smi is at position 0, if at all. |
| 462 ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmiCid) || (i == 0)); | 462 ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmiCid) || (i == 0)); |
| 463 Label next_test; | 463 Label next_test; |
| 464 __ cmpl(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); | 464 __ cmpl(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); |
| 465 __ j(NOT_EQUAL, &next_test); | 465 if (i < len - 1) { |
| 466 __ j(NOT_EQUAL, &next_test); |
| 467 } else { |
| 468 __ j(NOT_EQUAL, deopt); |
| 469 } |
| 466 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); | 470 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); |
| 467 if (target.Owner() == object_store->object_class()) { | 471 if (target.Owner() == object_store->object_class()) { |
| 468 // Object.== is same as ===. | 472 // Object.== is same as ===. |
| 469 __ Drop(2); | 473 __ Drop(2); |
| 470 __ cmpl(left, right); | 474 __ cmpl(left, right); |
| 471 if (branch != NULL) { | 475 if (branch != NULL) { |
| 472 branch->EmitBranchOnCondition(compiler, cond); | 476 branch->EmitBranchOnCondition(compiler, cond); |
| 473 } else { | 477 } else { |
| 474 Register result = locs->out().reg(); | 478 Register result = locs->out().reg(); |
| 475 Label load_true; | 479 Label load_true; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 490 locs); | 494 locs); |
| 491 if (branch == NULL) { | 495 if (branch == NULL) { |
| 492 if (kind == Token::kNE) { | 496 if (kind == Token::kNE) { |
| 493 Label false_label; | 497 Label false_label; |
| 494 __ CompareObject(EAX, Bool::True()); | 498 __ CompareObject(EAX, Bool::True()); |
| 495 __ j(EQUAL, &false_label, Assembler::kNearJump); | 499 __ j(EQUAL, &false_label, Assembler::kNearJump); |
| 496 __ LoadObject(EAX, Bool::True()); | 500 __ LoadObject(EAX, Bool::True()); |
| 497 __ jmp(&done); | 501 __ jmp(&done); |
| 498 __ Bind(&false_label); | 502 __ Bind(&false_label); |
| 499 __ LoadObject(EAX, Bool::False()); | 503 __ LoadObject(EAX, Bool::False()); |
| 500 __ jmp(&done); | |
| 501 } | 504 } |
| 502 } else { | 505 } else { |
| 503 if (branch->is_checked()) { | 506 if (branch->is_checked()) { |
| 504 EmitAssertBoolean(EAX, token_pos, deopt_id, locs, compiler); | 507 EmitAssertBoolean(EAX, token_pos, deopt_id, locs, compiler); |
| 505 } | 508 } |
| 506 __ CompareObject(EAX, Bool::True()); | 509 __ CompareObject(EAX, Bool::True()); |
| 507 branch->EmitBranchOnCondition(compiler, cond); | 510 branch->EmitBranchOnCondition(compiler, cond); |
| 508 } | 511 } |
| 509 } | 512 } |
| 510 __ jmp(&done); | 513 if (i < len - 1) { |
| 511 __ Bind(&next_test); | 514 __ jmp(&done); |
| 515 __ Bind(&next_test); |
| 516 } |
| 512 } | 517 } |
| 513 // Fall through leads to deoptimization | |
| 514 __ jmp(deopt); | |
| 515 __ Bind(&done); | 518 __ Bind(&done); |
| 516 } | 519 } |
| 517 | 520 |
| 518 | 521 |
| 519 // Emit code when ICData's targets are all Object == (which is ===). | 522 // Emit code when ICData's targets are all Object == (which is ===). |
| 520 static void EmitCheckedStrictEqual(FlowGraphCompiler* compiler, | 523 static void EmitCheckedStrictEqual(FlowGraphCompiler* compiler, |
| 521 const ICData& ic_data, | 524 const ICData& ic_data, |
| 522 const LocationSummary& locs, | 525 const LocationSummary& locs, |
| 523 Token::Kind kind, | 526 Token::Kind kind, |
| 524 BranchInstr* branch, | 527 BranchInstr* branch, |
| (...skipping 2889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3414 PcDescriptors::kOther, | 3417 PcDescriptors::kOther, |
| 3415 locs()); | 3418 locs()); |
| 3416 __ Drop(2); // Discard type arguments and receiver. | 3419 __ Drop(2); // Discard type arguments and receiver. |
| 3417 } | 3420 } |
| 3418 | 3421 |
| 3419 } // namespace dart | 3422 } // namespace dart |
| 3420 | 3423 |
| 3421 #undef __ | 3424 #undef __ |
| 3422 | 3425 |
| 3423 #endif // defined TARGET_ARCH_IA32 | 3426 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |