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 20 matching lines...) Expand all Loading... |
31 | 31 |
32 // Input parameters: | 32 // Input parameters: |
33 // RSP : points to return address. | 33 // RSP : points to return address. |
34 // RSP + 8 : address of last argument in argument array. | 34 // RSP + 8 : address of last argument in argument array. |
35 // RSP + 8*R10 : address of first argument in argument array. | 35 // RSP + 8*R10 : address of first argument in argument array. |
36 // RSP + 8*R10 + 8 : address of return value. | 36 // RSP + 8*R10 + 8 : address of return value. |
37 // RBX : address of the runtime function to call. | 37 // RBX : address of the runtime function to call. |
38 // R10 : number of arguments to the call. | 38 // R10 : number of arguments to the call. |
39 // Must preserve callee saved registers R12 and R13. | 39 // Must preserve callee saved registers R12 and R13. |
40 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 40 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
41 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 41 const intptr_t thread_offset = NativeArguments::thread_offset(); |
42 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 42 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
43 const intptr_t argv_offset = NativeArguments::argv_offset(); | 43 const intptr_t argv_offset = NativeArguments::argv_offset(); |
44 const intptr_t retval_offset = NativeArguments::retval_offset(); | 44 const intptr_t retval_offset = NativeArguments::retval_offset(); |
45 | 45 |
46 __ EnterFrame(0); | 46 __ EnterFrame(0); |
47 | 47 |
48 COMPILE_ASSERT( | 48 COMPILE_ASSERT( |
49 (CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0); | 49 (CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0); |
50 __ LoadIsolate(R12); | 50 __ LoadIsolate(R12); |
51 | 51 |
(...skipping 15 matching lines...) Expand all Loading... |
67 // Mark that the isolate is executing VM code. | 67 // Mark that the isolate is executing VM code. |
68 __ movq(Address(R12, Isolate::vm_tag_offset()), RBX); | 68 __ movq(Address(R12, Isolate::vm_tag_offset()), RBX); |
69 | 69 |
70 // Reserve space for arguments and align frame before entering C++ world. | 70 // Reserve space for arguments and align frame before entering C++ world. |
71 __ subq(RSP, Immediate(sizeof(NativeArguments))); | 71 __ subq(RSP, Immediate(sizeof(NativeArguments))); |
72 if (OS::ActivationFrameAlignment() > 1) { | 72 if (OS::ActivationFrameAlignment() > 1) { |
73 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 73 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
74 } | 74 } |
75 | 75 |
76 // Pass NativeArguments structure by value and call runtime. | 76 // Pass NativeArguments structure by value and call runtime. |
77 __ movq(Address(RSP, isolate_offset), R12); // Set isolate in NativeArgs. | 77 __ movq(Address(RSP, thread_offset), THR); // Set thread in NativeArgs. |
78 // There are no runtime calls to closures, so we do not need to set the tag | 78 // There are no runtime calls to closures, so we do not need to set the tag |
79 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 79 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
80 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. | 80 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. |
81 __ leaq(RAX, Address(RBP, R10, TIMES_8, 1 * kWordSize)); // Compute argv. | 81 __ leaq(RAX, Address(RBP, R10, TIMES_8, 1 * kWordSize)); // Compute argv. |
82 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. | 82 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. |
83 __ addq(RAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument. | 83 __ addq(RAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument. |
84 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. | 84 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. |
85 #if defined(_WIN64) | 85 #if defined(_WIN64) |
86 ASSERT(sizeof(NativeArguments) > CallingConventions::kRegisterTransferLimit); | 86 ASSERT(sizeof(NativeArguments) > CallingConventions::kRegisterTransferLimit); |
87 __ movq(CallingConventions::kArg1Reg, RSP); | 87 __ movq(CallingConventions::kArg1Reg, RSP); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 | 124 |
125 | 125 |
126 // Input parameters: | 126 // Input parameters: |
127 // RSP : points to return address. | 127 // RSP : points to return address. |
128 // RSP + 8 : address of return value. | 128 // RSP + 8 : address of return value. |
129 // RAX : address of first argument in argument array. | 129 // RAX : address of first argument in argument array. |
130 // RBX : address of the native function to call. | 130 // RBX : address of the native function to call. |
131 // R10 : argc_tag including number of arguments and function kind. | 131 // R10 : argc_tag including number of arguments and function kind. |
132 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 132 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
133 const intptr_t native_args_struct_offset = 0; | 133 const intptr_t native_args_struct_offset = 0; |
134 const intptr_t isolate_offset = | 134 const intptr_t thread_offset = |
135 NativeArguments::isolate_offset() + native_args_struct_offset; | 135 NativeArguments::thread_offset() + native_args_struct_offset; |
136 const intptr_t argc_tag_offset = | 136 const intptr_t argc_tag_offset = |
137 NativeArguments::argc_tag_offset() + native_args_struct_offset; | 137 NativeArguments::argc_tag_offset() + native_args_struct_offset; |
138 const intptr_t argv_offset = | 138 const intptr_t argv_offset = |
139 NativeArguments::argv_offset() + native_args_struct_offset; | 139 NativeArguments::argv_offset() + native_args_struct_offset; |
140 const intptr_t retval_offset = | 140 const intptr_t retval_offset = |
141 NativeArguments::retval_offset() + native_args_struct_offset; | 141 NativeArguments::retval_offset() + native_args_struct_offset; |
142 | 142 |
143 __ EnterFrame(0); | 143 __ EnterFrame(0); |
144 | 144 |
145 COMPILE_ASSERT( | 145 COMPILE_ASSERT( |
(...skipping 20 matching lines...) Expand all Loading... |
166 | 166 |
167 // Reserve space for the native arguments structure passed on the stack (the | 167 // Reserve space for the native arguments structure passed on the stack (the |
168 // outgoing pointer parameter to the native arguments structure is passed in | 168 // outgoing pointer parameter to the native arguments structure is passed in |
169 // RDI) and align frame before entering the C++ world. | 169 // RDI) and align frame before entering the C++ world. |
170 __ subq(RSP, Immediate(sizeof(NativeArguments))); | 170 __ subq(RSP, Immediate(sizeof(NativeArguments))); |
171 if (OS::ActivationFrameAlignment() > 1) { | 171 if (OS::ActivationFrameAlignment() > 1) { |
172 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 172 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
173 } | 173 } |
174 | 174 |
175 // Pass NativeArguments structure by value and call native function. | 175 // Pass NativeArguments structure by value and call native function. |
176 __ movq(Address(RSP, isolate_offset), R12); // Set isolate in NativeArgs. | 176 __ movq(Address(RSP, thread_offset), THR); // Set thread in NativeArgs. |
177 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. | 177 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. |
178 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. | 178 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. |
179 __ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr. | 179 __ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr. |
180 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. | 180 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. |
181 | 181 |
182 // Pass the pointer to the NativeArguments. | 182 // Pass the pointer to the NativeArguments. |
183 __ movq(CallingConventions::kArg1Reg, RSP); | 183 __ movq(CallingConventions::kArg1Reg, RSP); |
184 // Pass pointer to function entrypoint. | 184 // Pass pointer to function entrypoint. |
185 __ movq(CallingConventions::kArg2Reg, RBX); | 185 __ movq(CallingConventions::kArg2Reg, RBX); |
186 __ CallCFunction(&NativeEntry::NativeCallWrapperLabel()); | 186 __ CallCFunction(&NativeEntry::NativeCallWrapperLabel()); |
(...skipping 11 matching lines...) Expand all Loading... |
198 | 198 |
199 | 199 |
200 // Input parameters: | 200 // Input parameters: |
201 // RSP : points to return address. | 201 // RSP : points to return address. |
202 // RSP + 8 : address of return value. | 202 // RSP + 8 : address of return value. |
203 // RAX : address of first argument in argument array. | 203 // RAX : address of first argument in argument array. |
204 // RBX : address of the native function to call. | 204 // RBX : address of the native function to call. |
205 // R10 : argc_tag including number of arguments and function kind. | 205 // R10 : argc_tag including number of arguments and function kind. |
206 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 206 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
207 const intptr_t native_args_struct_offset = 0; | 207 const intptr_t native_args_struct_offset = 0; |
208 const intptr_t isolate_offset = | 208 const intptr_t thread_offset = |
209 NativeArguments::isolate_offset() + native_args_struct_offset; | 209 NativeArguments::thread_offset() + native_args_struct_offset; |
210 const intptr_t argc_tag_offset = | 210 const intptr_t argc_tag_offset = |
211 NativeArguments::argc_tag_offset() + native_args_struct_offset; | 211 NativeArguments::argc_tag_offset() + native_args_struct_offset; |
212 const intptr_t argv_offset = | 212 const intptr_t argv_offset = |
213 NativeArguments::argv_offset() + native_args_struct_offset; | 213 NativeArguments::argv_offset() + native_args_struct_offset; |
214 const intptr_t retval_offset = | 214 const intptr_t retval_offset = |
215 NativeArguments::retval_offset() + native_args_struct_offset; | 215 NativeArguments::retval_offset() + native_args_struct_offset; |
216 | 216 |
217 __ EnterFrame(0); | 217 __ EnterFrame(0); |
218 | 218 |
219 COMPILE_ASSERT( | 219 COMPILE_ASSERT( |
(...skipping 20 matching lines...) Expand all Loading... |
240 | 240 |
241 // Reserve space for the native arguments structure passed on the stack (the | 241 // Reserve space for the native arguments structure passed on the stack (the |
242 // outgoing pointer parameter to the native arguments structure is passed in | 242 // outgoing pointer parameter to the native arguments structure is passed in |
243 // RDI) and align frame before entering the C++ world. | 243 // RDI) and align frame before entering the C++ world. |
244 __ subq(RSP, Immediate(sizeof(NativeArguments))); | 244 __ subq(RSP, Immediate(sizeof(NativeArguments))); |
245 if (OS::ActivationFrameAlignment() > 1) { | 245 if (OS::ActivationFrameAlignment() > 1) { |
246 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 246 __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
247 } | 247 } |
248 | 248 |
249 // Pass NativeArguments structure by value and call native function. | 249 // Pass NativeArguments structure by value and call native function. |
250 __ movq(Address(RSP, isolate_offset), R12); // Set isolate in NativeArgs. | 250 __ movq(Address(RSP, thread_offset), THR); // Set thread in NativeArgs. |
251 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. | 251 __ movq(Address(RSP, argc_tag_offset), R10); // Set argc in NativeArguments. |
252 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. | 252 __ movq(Address(RSP, argv_offset), RAX); // Set argv in NativeArguments. |
253 __ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr. | 253 __ leaq(RAX, Address(RBP, 2 * kWordSize)); // Compute return value addr. |
254 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. | 254 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. |
255 | 255 |
256 // Pass the pointer to the NativeArguments. | 256 // Pass the pointer to the NativeArguments. |
257 __ movq(CallingConventions::kArg1Reg, RSP); | 257 __ movq(CallingConventions::kArg1Reg, RSP); |
258 __ CallCFunction(RBX); | 258 __ CallCFunction(RBX); |
259 | 259 |
260 // Mark that the isolate is executing Dart code. | 260 // Mark that the isolate is executing Dart code. |
(...skipping 1693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1954 } | 1954 } |
1955 | 1955 |
1956 | 1956 |
1957 // Jump to the exception or error handler. | 1957 // Jump to the exception or error handler. |
1958 // TOS + 0: return address | 1958 // TOS + 0: return address |
1959 // Arg1: program counter | 1959 // Arg1: program counter |
1960 // Arg2: stack pointer | 1960 // Arg2: stack pointer |
1961 // Arg3: frame_pointer | 1961 // Arg3: frame_pointer |
1962 // Arg4: exception object | 1962 // Arg4: exception object |
1963 // Arg5: stacktrace object | 1963 // Arg5: stacktrace object |
1964 // Arg6: isolate | 1964 // Arg6: thread |
1965 // No Result. | 1965 // No Result. |
1966 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { | 1966 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { |
1967 ASSERT(kExceptionObjectReg == RAX); | 1967 ASSERT(kExceptionObjectReg == RAX); |
1968 ASSERT(kStackTraceObjectReg == RDX); | 1968 ASSERT(kStackTraceObjectReg == RDX); |
1969 ASSERT(CallingConventions::kArg4Reg != kStackTraceObjectReg); | 1969 ASSERT(CallingConventions::kArg4Reg != kStackTraceObjectReg); |
1970 ASSERT(CallingConventions::kArg1Reg != kStackTraceObjectReg); | 1970 ASSERT(CallingConventions::kArg1Reg != kStackTraceObjectReg); |
1971 | 1971 |
1972 #if defined(_WIN64) | 1972 #if defined(_WIN64) |
1973 Register stacktrace_reg = RBX; | 1973 Register stacktrace_reg = RBX; |
1974 __ movq(stacktrace_reg, Address(RSP, 5 * kWordSize)); | 1974 __ movq(stacktrace_reg, Address(RSP, 5 * kWordSize)); |
| 1975 __ movq(THR, Address(RSP, 6 * kWordSize)); |
1975 Register isolate_reg = RDI; | 1976 Register isolate_reg = RDI; |
1976 __ movq(isolate_reg, Address(RSP, 6 * kWordSize)); | |
1977 #else | 1977 #else |
1978 Register stacktrace_reg = CallingConventions::kArg5Reg; | 1978 Register stacktrace_reg = CallingConventions::kArg5Reg; |
| 1979 __ movq(THR, CallingConventions::kArg6Reg); |
1979 Register isolate_reg = CallingConventions::kArg6Reg; | 1980 Register isolate_reg = CallingConventions::kArg6Reg; |
1980 #endif | 1981 #endif |
1981 // TODO(koda): Pass thread instead of isolate. | 1982 __ LoadIsolate(isolate_reg); |
1982 __ movq(THR, Address(isolate_reg, Isolate::mutator_thread_offset())); | |
1983 __ movq(RBP, CallingConventions::kArg3Reg); | 1983 __ movq(RBP, CallingConventions::kArg3Reg); |
1984 __ movq(RSP, CallingConventions::kArg2Reg); | 1984 __ movq(RSP, CallingConventions::kArg2Reg); |
1985 __ movq(kStackTraceObjectReg, stacktrace_reg); | 1985 __ movq(kStackTraceObjectReg, stacktrace_reg); |
1986 __ movq(kExceptionObjectReg, CallingConventions::kArg4Reg); | 1986 __ movq(kExceptionObjectReg, CallingConventions::kArg4Reg); |
1987 // Set the tag. | 1987 // Set the tag. |
1988 __ movq(Address(isolate_reg, Isolate::vm_tag_offset()), | 1988 __ movq(Address(isolate_reg, Isolate::vm_tag_offset()), |
1989 Immediate(VMTag::kDartTagId)); | 1989 Immediate(VMTag::kDartTagId)); |
1990 // Clear top exit frame. | 1990 // Clear top exit frame. |
1991 __ movq(Address(isolate_reg, Isolate::top_exit_frame_info_offset()), | 1991 __ movq(Address(isolate_reg, Isolate::top_exit_frame_info_offset()), |
1992 Immediate(0)); | 1992 Immediate(0)); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2180 // Result: | 2180 // Result: |
2181 // RCX: entry point. | 2181 // RCX: entry point. |
2182 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2182 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
2183 EmitMegamorphicLookup(assembler, RDI, RBX, RCX); | 2183 EmitMegamorphicLookup(assembler, RDI, RBX, RCX); |
2184 __ ret(); | 2184 __ ret(); |
2185 } | 2185 } |
2186 | 2186 |
2187 } // namespace dart | 2187 } // namespace dart |
2188 | 2188 |
2189 #endif // defined TARGET_ARCH_X64 | 2189 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |