| 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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 __ EnterStubFrame(); | 276 __ EnterStubFrame(); |
| 277 __ pushq(R10); // Preserve arguments descriptor array. | 277 __ pushq(R10); // Preserve arguments descriptor array. |
| 278 // Setup space on stack for return value. | 278 // Setup space on stack for return value. |
| 279 __ PushObject(Object::null_object()); | 279 __ PushObject(Object::null_object()); |
| 280 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); | 280 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); |
| 281 __ popq(RAX); // Get Code object result. | 281 __ popq(RAX); // Get Code object result. |
| 282 __ popq(R10); // Restore arguments descriptor array. | 282 __ popq(R10); // Restore arguments descriptor array. |
| 283 // Remove the stub frame as we are about to jump to the dart function. | 283 // Remove the stub frame as we are about to jump to the dart function. |
| 284 __ LeaveStubFrame(); | 284 __ LeaveStubFrame(); |
| 285 | 285 |
| 286 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); | 286 __ movq(RBX, FieldAddress(RAX, Code::entry_point_offset())); |
| 287 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 288 __ jmp(RBX); | 287 __ jmp(RBX); |
| 289 } | 288 } |
| 290 | 289 |
| 291 | 290 |
| 292 // Called from a static call only when an invalid code has been entered | 291 // Called from a static call only when an invalid code has been entered |
| 293 // (invalid because its function was optimized or deoptimized). | 292 // (invalid because its function was optimized or deoptimized). |
| 294 // R10: arguments descriptor array. | 293 // R10: arguments descriptor array. |
| 295 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 294 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
| 296 __ EnterStubFrame(); | 295 __ EnterStubFrame(); |
| 297 __ pushq(R10); // Preserve arguments descriptor array. | 296 __ pushq(R10); // Preserve arguments descriptor array. |
| 298 // Setup space on stack for return value. | 297 // Setup space on stack for return value. |
| 299 __ PushObject(Object::null_object()); | 298 __ PushObject(Object::null_object()); |
| 300 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); | 299 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); |
| 301 __ popq(RAX); // Get Code object. | 300 __ popq(RAX); // Get Code object. |
| 302 __ popq(R10); // Restore arguments descriptor array. | 301 __ popq(R10); // Restore arguments descriptor array. |
| 303 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | 302 __ movq(RAX, FieldAddress(RAX, Code::entry_point_offset())); |
| 304 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 305 __ LeaveStubFrame(); | 303 __ LeaveStubFrame(); |
| 306 __ jmp(RAX); | 304 __ jmp(RAX); |
| 307 __ int3(); | 305 __ int3(); |
| 308 } | 306 } |
| 309 | 307 |
| 310 | 308 |
| 311 // Called from object allocate instruction when the allocation stub has been | 309 // Called from object allocate instruction when the allocation stub has been |
| 312 // disabled. | 310 // disabled. |
| 313 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { | 311 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { |
| 314 __ EnterStubFrame(); | 312 __ EnterStubFrame(); |
| 315 // Setup space on stack for return value. | 313 // Setup space on stack for return value. |
| 316 __ PushObject(Object::null_object()); | 314 __ PushObject(Object::null_object()); |
| 317 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); | 315 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); |
| 318 __ popq(RAX); // Get Code object. | 316 __ popq(RAX); // Get Code object. |
| 319 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | 317 __ movq(RAX, FieldAddress(RAX, Code::entry_point_offset())); |
| 320 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 321 __ LeaveStubFrame(); | 318 __ LeaveStubFrame(); |
| 322 __ jmp(RAX); | 319 __ jmp(RAX); |
| 323 __ int3(); | 320 __ int3(); |
| 324 } | 321 } |
| 325 | 322 |
| 326 | 323 |
| 327 // Input parameters: | 324 // Input parameters: |
| 328 // R10: smi-tagged argument count, may be zero. | 325 // R10: smi-tagged argument count, may be zero. |
| 329 // RBP[kParamEndSlotFromFp + 1]: last argument. | 326 // RBP[kParamEndSlotFromFp + 1]: last argument. |
| 330 static void PushArgumentsArray(Assembler* assembler) { | 327 static void PushArgumentsArray(Assembler* assembler) { |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 __ popq(R10); // Restore arguments descriptor. | 547 __ popq(R10); // Restore arguments descriptor. |
| 551 __ popq(RBX); // Restore IC data. | 548 __ popq(RBX); // Restore IC data. |
| 552 __ LeaveStubFrame(); | 549 __ LeaveStubFrame(); |
| 553 | 550 |
| 554 if (!FLAG_lazy_dispatchers) { | 551 if (!FLAG_lazy_dispatchers) { |
| 555 Label call_target_function; | 552 Label call_target_function; |
| 556 GenerateDispatcherCode(assembler, &call_target_function); | 553 GenerateDispatcherCode(assembler, &call_target_function); |
| 557 __ Bind(&call_target_function); | 554 __ Bind(&call_target_function); |
| 558 } | 555 } |
| 559 | 556 |
| 560 __ movq(RCX, FieldAddress(RAX, Function::instructions_offset())); | 557 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); |
| 561 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 562 __ jmp(RCX); | 558 __ jmp(RCX); |
| 563 } | 559 } |
| 564 | 560 |
| 565 | 561 |
| 566 // Called for inline allocation of arrays. | 562 // Called for inline allocation of arrays. |
| 567 // Input parameters: | 563 // Input parameters: |
| 568 // R10 : Array length as Smi. | 564 // R10 : Array length as Smi. |
| 569 // RBX : array element type (either NULL or an instantiated type). | 565 // RBX : array element type (either NULL or an instantiated type). |
| 570 // NOTE: R10 cannot be clobbered here as the caller relies on it being saved. | 566 // NOTE: R10 cannot be clobbered here as the caller relies on it being saved. |
| 571 // The newly allocated object is returned in RAX. | 567 // The newly allocated object is returned in RAX. |
| (...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1485 __ addq(R8, Immediate(Smi::RawValue(1))); | 1481 __ addq(R8, Immediate(Smi::RawValue(1))); |
| 1486 __ movq(R13, Immediate(Smi::RawValue(Smi::kMaxValue))); | 1482 __ movq(R13, Immediate(Smi::RawValue(Smi::kMaxValue))); |
| 1487 __ cmovnoq(R13, R8); | 1483 __ cmovnoq(R13, R8); |
| 1488 __ StoreIntoSmiField(Address(R12, count_offset), R13); | 1484 __ StoreIntoSmiField(Address(R12, count_offset), R13); |
| 1489 } | 1485 } |
| 1490 | 1486 |
| 1491 __ Comment("Call target"); | 1487 __ Comment("Call target"); |
| 1492 __ Bind(&call_target_function); | 1488 __ Bind(&call_target_function); |
| 1493 // RAX: Target function. | 1489 // RAX: Target function. |
| 1494 Label is_compiled; | 1490 Label is_compiled; |
| 1495 __ movq(RCX, FieldAddress(RAX, Function::instructions_offset())); | 1491 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); |
| 1496 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 1497 if (range_collection_mode == kCollectRanges) { | 1492 if (range_collection_mode == kCollectRanges) { |
| 1498 __ movq(R8, Address(RSP, + 1 * kWordSize)); | 1493 __ movq(R8, Address(RSP, + 1 * kWordSize)); |
| 1499 if (num_args == 2) { | 1494 if (num_args == 2) { |
| 1500 __ movq(R13, Address(RSP, + 2 * kWordSize)); | 1495 __ movq(R13, Address(RSP, + 2 * kWordSize)); |
| 1501 } | 1496 } |
| 1502 __ EnterStubFrame(); | 1497 __ EnterStubFrame(); |
| 1503 __ pushq(RBX); | 1498 __ pushq(RBX); |
| 1504 if (num_args == 2) { | 1499 if (num_args == 2) { |
| 1505 __ pushq(R13); | 1500 __ pushq(R13); |
| 1506 } | 1501 } |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1685 __ movq(R13, Immediate(Smi::RawValue(Smi::kMaxValue))); | 1680 __ movq(R13, Immediate(Smi::RawValue(Smi::kMaxValue))); |
| 1686 __ cmovnoq(R13, R8); | 1681 __ cmovnoq(R13, R8); |
| 1687 __ StoreIntoSmiField(Address(R12, count_offset), R13); | 1682 __ StoreIntoSmiField(Address(R12, count_offset), R13); |
| 1688 } | 1683 } |
| 1689 | 1684 |
| 1690 // Load arguments descriptor into R10. | 1685 // Load arguments descriptor into R10. |
| 1691 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); | 1686 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); |
| 1692 | 1687 |
| 1693 // Get function and call it, if possible. | 1688 // Get function and call it, if possible. |
| 1694 __ movq(RAX, Address(R12, target_offset)); | 1689 __ movq(RAX, Address(R12, target_offset)); |
| 1695 __ movq(RCX, FieldAddress(RAX, Function::instructions_offset())); | 1690 __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset())); |
| 1696 // RCX: Target instructions. | |
| 1697 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 1698 __ jmp(RCX); | 1691 __ jmp(RCX); |
| 1699 | 1692 |
| 1700 if (FLAG_support_debugger) { | 1693 if (FLAG_support_debugger) { |
| 1701 __ Bind(&stepping); | 1694 __ Bind(&stepping); |
| 1702 __ EnterStubFrame(); | 1695 __ EnterStubFrame(); |
| 1703 __ pushq(RBX); // Preserve IC data object. | 1696 __ pushq(RBX); // Preserve IC data object. |
| 1704 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); | 1697 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); |
| 1705 __ popq(RBX); | 1698 __ popq(RBX); |
| 1706 __ LeaveStubFrame(); | 1699 __ LeaveStubFrame(); |
| 1707 __ jmp(&done_stepping, Assembler::kNearJump); | 1700 __ jmp(&done_stepping, Assembler::kNearJump); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1738 __ EnterStubFrame(); | 1731 __ EnterStubFrame(); |
| 1739 __ pushq(R10); // Preserve arguments descriptor array. | 1732 __ pushq(R10); // Preserve arguments descriptor array. |
| 1740 __ pushq(RBX); // Preserve IC data object. | 1733 __ pushq(RBX); // Preserve IC data object. |
| 1741 __ pushq(RAX); // Pass function. | 1734 __ pushq(RAX); // Pass function. |
| 1742 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); | 1735 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); |
| 1743 __ popq(RAX); // Restore function. | 1736 __ popq(RAX); // Restore function. |
| 1744 __ popq(RBX); // Restore IC data array. | 1737 __ popq(RBX); // Restore IC data array. |
| 1745 __ popq(R10); // Restore arguments descriptor array. | 1738 __ popq(R10); // Restore arguments descriptor array. |
| 1746 __ LeaveStubFrame(); | 1739 __ LeaveStubFrame(); |
| 1747 | 1740 |
| 1748 __ movq(RAX, FieldAddress(RAX, Function::instructions_offset())); | 1741 __ movq(RAX, FieldAddress(RAX, Function::entry_point_offset())); |
| 1749 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 1750 __ jmp(RAX); | 1742 __ jmp(RAX); |
| 1751 } | 1743 } |
| 1752 | 1744 |
| 1753 | 1745 |
| 1754 // RBX: Contains an ICData. | 1746 // RBX: Contains an ICData. |
| 1755 // TOS(0): return address (Dart code). | 1747 // TOS(0): return address (Dart code). |
| 1756 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { | 1748 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { |
| 1757 __ EnterStubFrame(); | 1749 __ EnterStubFrame(); |
| 1758 // Preserve IC data. | 1750 // Preserve IC data. |
| 1759 __ pushq(RBX); | 1751 __ pushq(RBX); |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1966 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 1958 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
| 1967 __ EnterStubFrame(); | 1959 __ EnterStubFrame(); |
| 1968 __ LoadObject(R12, Object::null_object()); | 1960 __ LoadObject(R12, Object::null_object()); |
| 1969 __ pushq(R10); | 1961 __ pushq(R10); |
| 1970 __ pushq(R12); // Setup space on stack for return value. | 1962 __ pushq(R12); // Setup space on stack for return value. |
| 1971 __ pushq(RDI); | 1963 __ pushq(RDI); |
| 1972 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); | 1964 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
| 1973 __ popq(RAX); // Disard argument. | 1965 __ popq(RAX); // Disard argument. |
| 1974 __ popq(RAX); // Get Code object. | 1966 __ popq(RAX); // Get Code object. |
| 1975 __ popq(R10); // Restore argument descriptor. | 1967 __ popq(R10); // Restore argument descriptor. |
| 1976 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | 1968 __ movq(RAX, FieldAddress(RAX, Code::entry_point_offset())); |
| 1977 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 1978 __ LeaveStubFrame(); | 1969 __ LeaveStubFrame(); |
| 1979 __ jmp(RAX); | 1970 __ jmp(RAX); |
| 1980 __ int3(); | 1971 __ int3(); |
| 1981 } | 1972 } |
| 1982 | 1973 |
| 1983 | 1974 |
| 1984 // Does identical check (object references are equal or not equal) with special | 1975 // Does identical check (object references are equal or not equal) with special |
| 1985 // checks for boxed numbers. | 1976 // checks for boxed numbers. |
| 1986 // Left and right are pushed on stack. | 1977 // Left and right are pushed on stack. |
| 1987 // Return ZF set. | 1978 // Return ZF set. |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2117 __ j(ZERO, &call_target_function, Assembler::kNearJump); | 2108 __ j(ZERO, &call_target_function, Assembler::kNearJump); |
| 2118 __ cmpq(RDX, RAX); | 2109 __ cmpq(RDX, RAX); |
| 2119 __ j(NOT_EQUAL, &update, Assembler::kNearJump); | 2110 __ j(NOT_EQUAL, &update, Assembler::kNearJump); |
| 2120 | 2111 |
| 2121 __ Bind(&call_target_function); | 2112 __ Bind(&call_target_function); |
| 2122 // Call the target found in the cache. For a class id match, this is a | 2113 // Call the target found in the cache. For a class id match, this is a |
| 2123 // proper target for the given name and arguments descriptor. If the | 2114 // proper target for the given name and arguments descriptor. If the |
| 2124 // illegal class id was found, the target is a cache miss handler that can | 2115 // illegal class id was found, the target is a cache miss handler that can |
| 2125 // be invoked as a normal Dart function. | 2116 // be invoked as a normal Dart function. |
| 2126 __ movq(RAX, FieldAddress(RDI, RCX, TIMES_8, base + kWordSize)); | 2117 __ movq(RAX, FieldAddress(RDI, RCX, TIMES_8, base + kWordSize)); |
| 2127 __ movq(target, FieldAddress(RAX, Function::instructions_offset())); | 2118 __ movq(target, FieldAddress(RAX, Function::entry_point_offset())); |
| 2128 // TODO(srdjan): Evaluate performance impact of moving the instruction below | |
| 2129 // to the call site, instead of having it here. | |
| 2130 __ AddImmediate( | |
| 2131 target, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 2132 } | 2119 } |
| 2133 | 2120 |
| 2134 | 2121 |
| 2135 // Called from megamorphic calls. | 2122 // Called from megamorphic calls. |
| 2136 // RDI: receiver. | 2123 // RDI: receiver. |
| 2137 // RBX: lookup cache. | 2124 // RBX: lookup cache. |
| 2138 // Result: | 2125 // Result: |
| 2139 // RCX: entry point. | 2126 // RCX: entry point. |
| 2140 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2127 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2141 EmitMegamorphicLookup(assembler, RDI, RBX, RCX); | 2128 EmitMegamorphicLookup(assembler, RDI, RBX, RCX); |
| 2142 __ ret(); | 2129 __ ret(); |
| 2143 } | 2130 } |
| 2144 | 2131 |
| 2145 } // namespace dart | 2132 } // namespace dart |
| 2146 | 2133 |
| 2147 #endif // defined TARGET_ARCH_X64 | 2134 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |