| 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" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 1316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1327 // - If receiver is Smi -> load Smi class. | 1327 // - If receiver is Smi -> load Smi class. |
| 1328 // - If receiver is not-Smi -> load receiver's class. | 1328 // - If receiver is not-Smi -> load receiver's class. |
| 1329 // - Check if 'num_args' (including receiver) match any IC data group. | 1329 // - Check if 'num_args' (including receiver) match any IC data group. |
| 1330 // - Match found -> jump to target. | 1330 // - Match found -> jump to target. |
| 1331 // - Match not found -> jump to IC miss. | 1331 // - Match not found -> jump to IC miss. |
| 1332 void StubCode::GenerateNArgsCheckInlineCacheStub( | 1332 void StubCode::GenerateNArgsCheckInlineCacheStub( |
| 1333 Assembler* assembler, | 1333 Assembler* assembler, |
| 1334 intptr_t num_args, | 1334 intptr_t num_args, |
| 1335 const RuntimeEntry& handle_ic_miss, | 1335 const RuntimeEntry& handle_ic_miss, |
| 1336 Token::Kind kind, | 1336 Token::Kind kind, |
| 1337 RangeCollectionMode range_collection_mode) { | 1337 RangeCollectionMode range_collection_mode, |
| 1338 bool optimized) { |
| 1338 ASSERT(num_args > 0); | 1339 ASSERT(num_args > 0); |
| 1339 #if defined(DEBUG) | 1340 #if defined(DEBUG) |
| 1340 { Label ok; | 1341 { Label ok; |
| 1341 // Check that the IC data array has NumArgsTested() == num_args. | 1342 // Check that the IC data array has NumArgsTested() == num_args. |
| 1342 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. | 1343 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
| 1343 __ movl(RCX, FieldAddress(RBX, ICData::state_bits_offset())); | 1344 __ movl(RCX, FieldAddress(RBX, ICData::state_bits_offset())); |
| 1344 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. | 1345 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1345 __ andq(RCX, Immediate(ICData::NumArgsTestedMask())); | 1346 __ andq(RCX, Immediate(ICData::NumArgsTestedMask())); |
| 1346 __ cmpq(RCX, Immediate(num_args)); | 1347 __ cmpq(RCX, Immediate(num_args)); |
| 1347 __ j(EQUAL, &ok, Assembler::kNearJump); | 1348 __ j(EQUAL, &ok, Assembler::kNearJump); |
| 1348 __ Stop("Incorrect stub for IC data"); | 1349 __ Stop("Incorrect stub for IC data"); |
| 1349 __ Bind(&ok); | 1350 __ Bind(&ok); |
| 1350 } | 1351 } |
| 1351 #endif // DEBUG | 1352 #endif // DEBUG |
| 1352 | 1353 |
| 1353 Label stepping, done_stepping; | 1354 Label stepping, done_stepping; |
| 1354 if (FLAG_support_debugger) { | 1355 if (FLAG_support_debugger && !optimized) { |
| 1355 __ Comment("Check single stepping"); | 1356 __ Comment("Check single stepping"); |
| 1356 __ LoadIsolate(RAX); | 1357 __ LoadIsolate(RAX); |
| 1357 __ cmpb(Address(RAX, Isolate::single_step_offset()), Immediate(0)); | 1358 __ cmpb(Address(RAX, Isolate::single_step_offset()), Immediate(0)); |
| 1358 __ j(NOT_EQUAL, &stepping); | 1359 __ j(NOT_EQUAL, &stepping); |
| 1359 __ Bind(&done_stepping); | 1360 __ Bind(&done_stepping); |
| 1360 } | 1361 } |
| 1361 | 1362 |
| 1362 __ Comment("Range feedback collection"); | 1363 __ Comment("Range feedback collection"); |
| 1363 Label not_smi_or_overflow; | 1364 Label not_smi_or_overflow; |
| 1364 if (range_collection_mode == kCollectRanges) { | 1365 if (range_collection_mode == kCollectRanges) { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 __ movq(RDX, RAX); | 1505 __ movq(RDX, RAX); |
| 1505 __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize)); | 1506 __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize)); |
| 1506 __ UpdateRangeFeedback(RDX, 2, RBX, RCX, &done); | 1507 __ UpdateRangeFeedback(RDX, 2, RBX, RCX, &done); |
| 1507 __ Bind(&done); | 1508 __ Bind(&done); |
| 1508 __ LeaveStubFrame(); | 1509 __ LeaveStubFrame(); |
| 1509 __ ret(); | 1510 __ ret(); |
| 1510 } else { | 1511 } else { |
| 1511 __ jmp(RCX); | 1512 __ jmp(RCX); |
| 1512 } | 1513 } |
| 1513 | 1514 |
| 1514 if (FLAG_support_debugger) { | 1515 if (FLAG_support_debugger && !optimized) { |
| 1515 __ Bind(&stepping); | 1516 __ Bind(&stepping); |
| 1516 __ EnterStubFrame(); | 1517 __ EnterStubFrame(); |
| 1517 __ pushq(RBX); | 1518 __ pushq(RBX); |
| 1518 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1519 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1519 __ popq(RBX); | 1520 __ popq(RBX); |
| 1520 __ LeaveStubFrame(); | 1521 __ LeaveStubFrame(); |
| 1521 __ jmp(&done_stepping); | 1522 __ jmp(&done_stepping); |
| 1522 } | 1523 } |
| 1523 } | 1524 } |
| 1524 | 1525 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1608 // 1: N, number of arguments checked. | 1609 // 1: N, number of arguments checked. |
| 1609 // 2 .. (length - 1): group of checks, each check containing: | 1610 // 2 .. (length - 1): group of checks, each check containing: |
| 1610 // - N classes. | 1611 // - N classes. |
| 1611 // - 1 target function. | 1612 // - 1 target function. |
| 1612 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( | 1613 void StubCode::GenerateOneArgOptimizedCheckInlineCacheStub( |
| 1613 Assembler* assembler) { | 1614 Assembler* assembler) { |
| 1614 GenerateOptimizedUsageCounterIncrement(assembler); | 1615 GenerateOptimizedUsageCounterIncrement(assembler); |
| 1615 GenerateNArgsCheckInlineCacheStub(assembler, 1, | 1616 GenerateNArgsCheckInlineCacheStub(assembler, 1, |
| 1616 kInlineCacheMissHandlerOneArgRuntimeEntry, | 1617 kInlineCacheMissHandlerOneArgRuntimeEntry, |
| 1617 Token::kILLEGAL, | 1618 Token::kILLEGAL, |
| 1618 kIgnoreRanges); | 1619 kIgnoreRanges, true); |
| 1619 } | 1620 } |
| 1620 | 1621 |
| 1621 | 1622 |
| 1622 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( | 1623 void StubCode::GenerateTwoArgsOptimizedCheckInlineCacheStub( |
| 1623 Assembler* assembler) { | 1624 Assembler* assembler) { |
| 1624 GenerateOptimizedUsageCounterIncrement(assembler); | 1625 GenerateOptimizedUsageCounterIncrement(assembler); |
| 1625 GenerateNArgsCheckInlineCacheStub(assembler, 2, | 1626 GenerateNArgsCheckInlineCacheStub(assembler, 2, |
| 1626 kInlineCacheMissHandlerTwoArgsRuntimeEntry, | 1627 kInlineCacheMissHandlerTwoArgsRuntimeEntry, |
| 1627 Token::kILLEGAL, | 1628 Token::kILLEGAL, |
| 1628 kIgnoreRanges); | 1629 kIgnoreRanges, true); |
| 1629 } | 1630 } |
| 1630 | 1631 |
| 1631 | 1632 |
| 1632 // Intermediary stub between a static call and its target. ICData contains | 1633 // Intermediary stub between a static call and its target. ICData contains |
| 1633 // the target function and the call count. | 1634 // the target function and the call count. |
| 1634 // RBX: ICData | 1635 // RBX: ICData |
| 1635 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1636 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
| 1636 GenerateUsageCounterIncrement(assembler, RCX); | 1637 GenerateUsageCounterIncrement(assembler, RCX); |
| 1637 #if defined(DEBUG) | 1638 #if defined(DEBUG) |
| 1638 { Label ok; | 1639 { Label ok; |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2161 // Result: | 2162 // Result: |
| 2162 // RCX: entry point. | 2163 // RCX: entry point. |
| 2163 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2164 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2164 EmitMegamorphicLookup(assembler, RDI, RBX, RCX); | 2165 EmitMegamorphicLookup(assembler, RDI, RBX, RCX); |
| 2165 __ ret(); | 2166 __ ret(); |
| 2166 } | 2167 } |
| 2167 | 2168 |
| 2168 } // namespace dart | 2169 } // namespace dart |
| 2169 | 2170 |
| 2170 #endif // defined TARGET_ARCH_X64 | 2171 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |