| 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_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 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 // 'temp' contains class-id of the left argument. | 452 // 'temp' contains class-id of the left argument. |
| 453 ObjectStore* object_store = Isolate::Current()->object_store(); | 453 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 454 Condition cond = TokenKindToSmiCondition(kind); | 454 Condition cond = TokenKindToSmiCondition(kind); |
| 455 Label done; | 455 Label done; |
| 456 const intptr_t len = ic_data.NumberOfChecks(); | 456 const intptr_t len = ic_data.NumberOfChecks(); |
| 457 for (intptr_t i = 0; i < len; i++) { | 457 for (intptr_t i = 0; i < len; i++) { |
| 458 // Assert that the Smi is at position 0, if at all. | 458 // Assert that the Smi is at position 0, if at all. |
| 459 ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmiCid) || (i == 0)); | 459 ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmiCid) || (i == 0)); |
| 460 Label next_test; | 460 Label next_test; |
| 461 __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); | 461 __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); |
| 462 __ j(NOT_EQUAL, &next_test); | 462 if (i < len - 1) { |
| 463 __ j(NOT_EQUAL, &next_test); |
| 464 } else { |
| 465 __ j(NOT_EQUAL, deopt); |
| 466 } |
| 463 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); | 467 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); |
| 464 if (target.Owner() == object_store->object_class()) { | 468 if (target.Owner() == object_store->object_class()) { |
| 465 // Object.== is same as ===. | 469 // Object.== is same as ===. |
| 466 __ Drop(2); | 470 __ Drop(2); |
| 467 __ cmpq(left, right); | 471 __ cmpq(left, right); |
| 468 if (branch != NULL) { | 472 if (branch != NULL) { |
| 469 branch->EmitBranchOnCondition(compiler, cond); | 473 branch->EmitBranchOnCondition(compiler, cond); |
| 470 } else { | 474 } else { |
| 471 // This case should be rare. | 475 // This case should be rare. |
| 472 Register result = locs->out().reg(); | 476 Register result = locs->out().reg(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 488 locs); | 492 locs); |
| 489 if (branch == NULL) { | 493 if (branch == NULL) { |
| 490 if (kind == Token::kNE) { | 494 if (kind == Token::kNE) { |
| 491 Label false_label; | 495 Label false_label; |
| 492 __ CompareObject(RAX, Bool::True()); | 496 __ CompareObject(RAX, Bool::True()); |
| 493 __ j(EQUAL, &false_label, Assembler::kNearJump); | 497 __ j(EQUAL, &false_label, Assembler::kNearJump); |
| 494 __ LoadObject(RAX, Bool::True()); | 498 __ LoadObject(RAX, Bool::True()); |
| 495 __ jmp(&done); | 499 __ jmp(&done); |
| 496 __ Bind(&false_label); | 500 __ Bind(&false_label); |
| 497 __ LoadObject(RAX, Bool::False()); | 501 __ LoadObject(RAX, Bool::False()); |
| 498 __ jmp(&done); | |
| 499 } | 502 } |
| 500 } else { | 503 } else { |
| 501 if (branch->is_checked()) { | 504 if (branch->is_checked()) { |
| 502 EmitAssertBoolean(RAX, token_pos, deopt_id, locs, compiler); | 505 EmitAssertBoolean(RAX, token_pos, deopt_id, locs, compiler); |
| 503 } | 506 } |
| 504 __ CompareObject(RAX, Bool::True()); | 507 __ CompareObject(RAX, Bool::True()); |
| 505 branch->EmitBranchOnCondition(compiler, cond); | 508 branch->EmitBranchOnCondition(compiler, cond); |
| 506 } | 509 } |
| 507 } | 510 } |
| 508 __ jmp(&done); | 511 if (i < len - 1) { |
| 512 __ jmp(&done); |
| 513 } |
| 509 __ Bind(&next_test); | 514 __ Bind(&next_test); |
| 510 } | 515 } |
| 511 // Fall through leads to deoptimization | |
| 512 __ jmp(deopt); | |
| 513 __ Bind(&done); | 516 __ Bind(&done); |
| 514 } | 517 } |
| 515 | 518 |
| 516 | 519 |
| 517 // Emit code when ICData's targets are all Object == (which is ===). | 520 // Emit code when ICData's targets are all Object == (which is ===). |
| 518 static void EmitCheckedStrictEqual(FlowGraphCompiler* compiler, | 521 static void EmitCheckedStrictEqual(FlowGraphCompiler* compiler, |
| 519 const ICData& ic_data, | 522 const ICData& ic_data, |
| 520 const LocationSummary& locs, | 523 const LocationSummary& locs, |
| 521 Token::Kind kind, | 524 Token::Kind kind, |
| 522 BranchInstr* branch, | 525 BranchInstr* branch, |
| (...skipping 2520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3043 PcDescriptors::kOther, | 3046 PcDescriptors::kOther, |
| 3044 locs()); | 3047 locs()); |
| 3045 __ Drop(2); // Discard type arguments and receiver. | 3048 __ Drop(2); // Discard type arguments and receiver. |
| 3046 } | 3049 } |
| 3047 | 3050 |
| 3048 } // namespace dart | 3051 } // namespace dart |
| 3049 | 3052 |
| 3050 #undef __ | 3053 #undef __ |
| 3051 | 3054 |
| 3052 #endif // defined TARGET_ARCH_X64 | 3055 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |