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" | 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/assembler_macros.h" | 9 #include "vm/assembler_macros.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 | 175 |
176 // Cache Context pointer into CTX while executing Dart code. | 176 // Cache Context pointer into CTX while executing Dart code. |
177 __ movq(CTX, R8); | 177 __ movq(CTX, R8); |
178 | 178 |
179 __ LeaveFrame(); | 179 __ LeaveFrame(); |
180 __ ret(); | 180 __ ret(); |
181 } | 181 } |
182 | 182 |
183 | 183 |
184 // Input parameters: | 184 // Input parameters: |
185 // RBX: function object. | |
186 // R10: arguments descriptor array (num_args is first Smi element). | 185 // R10: arguments descriptor array (num_args is first Smi element). |
187 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 186 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
188 const Immediate raw_null = | 187 const Immediate raw_null = |
189 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 188 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
190 | |
191 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | |
192 __ cmpq(RAX, raw_null); | |
193 Label function_compiled; | |
194 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); | |
195 | |
196 // Create a stub frame as we are pushing some objects on the stack before | |
197 // calling into the runtime. | |
198 AssemblerMacros::EnterStubFrame(assembler); | 189 AssemblerMacros::EnterStubFrame(assembler); |
199 | |
200 __ pushq(R10); // Preserve arguments descriptor array. | 190 __ pushq(R10); // Preserve arguments descriptor array. |
201 __ pushq(RBX); | 191 __ pushq(raw_null); // Setup space on stack for return value. |
202 __ CallRuntime(kCompileFunctionRuntimeEntry); | 192 __ CallRuntime(kPatchStaticCallRuntimeEntry); |
203 __ popq(RBX); // Restore read-only function object argument in RBX. | 193 __ popq(RAX); // Get Code object result. |
204 __ popq(R10); // Restore arguments descriptor array. | 194 __ popq(R10); // Restore arguments descriptor array. |
205 // Restore RAX. | |
206 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | |
207 | |
208 // Remove the stub frame as we are about to jump to the dart function. | 195 // Remove the stub frame as we are about to jump to the dart function. |
209 __ LeaveFrame(); | 196 __ LeaveFrame(); |
210 | 197 |
211 __ Bind(&function_compiled); | |
212 // Patch caller. | |
213 AssemblerMacros::EnterStubFrame(assembler); | |
214 | |
215 __ pushq(R10); // Preserve arguments descriptor array. | |
216 __ pushq(RBX); // Preserve function object. | |
217 __ CallRuntime(kPatchStaticCallRuntimeEntry); | |
218 __ popq(RBX); // Restore function object argument in RBX. | |
219 __ popq(R10); // Restore arguments descriptor array. | |
220 // Remove the stub frame as we are about to jump to the dart function. | |
221 __ LeaveFrame(); | |
222 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | |
223 | |
224 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); | 198 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); |
225 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 199 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
226 __ jmp(RBX); | 200 __ jmp(RBX); |
227 } | 201 } |
228 | 202 |
229 | 203 |
230 // Called from a static call only when an invalid code has been entered | 204 // Called from a static call only when an invalid code has been entered |
231 // (invalid because its function was optimized or deoptimized). | 205 // (invalid because its function was optimized or deoptimized). |
232 // RBX: function object. | |
233 // R10: arguments descriptor array (num_args is first Smi element). | 206 // R10: arguments descriptor array (num_args is first Smi element). |
234 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 207 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
| 208 const Immediate raw_null = |
| 209 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
235 AssemblerMacros::EnterStubFrame(assembler); | 210 AssemblerMacros::EnterStubFrame(assembler); |
236 __ pushq(R10); // Preserve arguments descriptor array. | 211 __ pushq(R10); // Preserve arguments descriptor array. |
237 __ pushq(RBX); // Preserve target function. | 212 __ pushq(raw_null); // Setup space on stack for return value. |
238 __ pushq(RBX); // Target function. | |
239 __ CallRuntime(kFixCallersTargetRuntimeEntry); | 213 __ CallRuntime(kFixCallersTargetRuntimeEntry); |
240 __ popq(RAX); // discard argument. | 214 __ popq(RAX); // Get Code object. |
241 __ popq(RAX); // Restore function. | |
242 __ popq(R10); // Restore arguments descriptor array. | 215 __ popq(R10); // Restore arguments descriptor array. |
243 __ movq(RAX, FieldAddress(RAX, Function::code_offset())); | |
244 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | 216 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
245 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 217 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
246 __ LeaveFrame(); | 218 __ LeaveFrame(); |
247 __ jmp(RAX); | 219 __ jmp(RAX); |
248 __ int3(); | 220 __ int3(); |
249 } | 221 } |
250 | 222 |
251 | 223 |
252 // Input parameters: | 224 // Input parameters: |
253 // R13: argument count, may be zero. | 225 // R13: argument count, may be zero. |
(...skipping 1526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1780 GenerateNArgsCheckInlineCacheStub(assembler, 1); | 1752 GenerateNArgsCheckInlineCacheStub(assembler, 1); |
1781 } | 1753 } |
1782 | 1754 |
1783 | 1755 |
1784 // Megamorphic call is currently implemented as IC call but through a stub | 1756 // Megamorphic call is currently implemented as IC call but through a stub |
1785 // that does not check/count function invocations. | 1757 // that does not check/count function invocations. |
1786 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { | 1758 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { |
1787 GenerateNArgsCheckInlineCacheStub(assembler, 1); | 1759 GenerateNArgsCheckInlineCacheStub(assembler, 1); |
1788 } | 1760 } |
1789 | 1761 |
1790 // RBX: Function object. | |
1791 // R10: Arguments array. | 1762 // R10: Arguments array. |
1792 // TOS(0): return address (Dart code). | 1763 // TOS(0): return address (Dart code). |
1793 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | 1764 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
| 1765 const Immediate raw_null = |
| 1766 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1794 AssemblerMacros::EnterStubFrame(assembler); | 1767 AssemblerMacros::EnterStubFrame(assembler); |
1795 __ pushq(R10); | 1768 __ pushq(R10); // Preserve arguments descriptor. |
1796 __ pushq(RBX); | 1769 __ pushq(raw_null); // Room for result. |
1797 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); | 1770 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); |
1798 __ popq(RBX); | 1771 __ popq(RAX); // Code object. |
1799 __ popq(R10); | 1772 __ popq(R10); // Restore arguments descriptor. |
1800 __ LeaveFrame(); | 1773 __ LeaveFrame(); |
1801 | 1774 |
1802 // Now call the static function. The breakpoint handler function | 1775 // Now call the static function. The breakpoint handler function |
1803 // ensures that the call target is compiled. | 1776 // ensures that the call target is compiled. |
1804 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | |
1805 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); | 1777 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); |
1806 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1778 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
1807 __ jmp(RBX); | 1779 __ jmp(RBX); |
1808 } | 1780 } |
1809 | 1781 |
1810 | 1782 |
1811 // TOS(0): return address (Dart code). | 1783 // TOS(0): return address (Dart code). |
1812 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { | 1784 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { |
1813 AssemblerMacros::EnterStubFrame(assembler); | 1785 AssemblerMacros::EnterStubFrame(assembler); |
1814 __ pushq(RAX); | 1786 __ pushq(RAX); |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2115 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); | 2087 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); |
2116 __ popq(RDX); | 2088 __ popq(RDX); |
2117 __ popq(RAX); | 2089 __ popq(RAX); |
2118 __ LeaveFrame(); | 2090 __ LeaveFrame(); |
2119 __ ret(); | 2091 __ ret(); |
2120 } | 2092 } |
2121 | 2093 |
2122 } // namespace dart | 2094 } // namespace dart |
2123 | 2095 |
2124 #endif // defined TARGET_ARCH_X64 | 2096 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |