| 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_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 23 matching lines...) Expand all Loading... |
| 34 | 34 |
| 35 // Input parameters: | 35 // Input parameters: |
| 36 // ESP : points to return address. | 36 // ESP : points to return address. |
| 37 // ESP + 4 : address of last argument in argument array. | 37 // ESP + 4 : address of last argument in argument array. |
| 38 // ESP + 4*EDX : address of first argument in argument array. | 38 // ESP + 4*EDX : address of first argument in argument array. |
| 39 // ESP + 4*EDX + 4 : address of return value. | 39 // ESP + 4*EDX + 4 : address of return value. |
| 40 // ECX : address of the runtime function to call. | 40 // ECX : address of the runtime function to call. |
| 41 // EDX : number of arguments to the call. | 41 // EDX : number of arguments to the call. |
| 42 // Must preserve callee saved registers EDI and EBX. | 42 // Must preserve callee saved registers EDI and EBX. |
| 43 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { | 43 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { |
| 44 const intptr_t isolate_offset = NativeArguments::isolate_offset(); | 44 const intptr_t thread_offset = NativeArguments::thread_offset(); |
| 45 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); | 45 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
| 46 const intptr_t argv_offset = NativeArguments::argv_offset(); | 46 const intptr_t argv_offset = NativeArguments::argv_offset(); |
| 47 const intptr_t retval_offset = NativeArguments::retval_offset(); | 47 const intptr_t retval_offset = NativeArguments::retval_offset(); |
| 48 | 48 |
| 49 __ EnterFrame(0); | 49 __ EnterFrame(0); |
| 50 | 50 |
| 51 __ LoadIsolate(EDI); | 51 __ LoadIsolate(EDI); |
| 52 | 52 |
| 53 // Save exit frame information to enable stack walking as we are about | 53 // Save exit frame information to enable stack walking as we are about |
| 54 // to transition to Dart VM C++ code. | 54 // to transition to Dart VM C++ code. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 68 // Mark that the isolate is executing VM code. | 68 // Mark that the isolate is executing VM code. |
| 69 __ movl(Address(EDI, Isolate::vm_tag_offset()), ECX); | 69 __ movl(Address(EDI, Isolate::vm_tag_offset()), ECX); |
| 70 | 70 |
| 71 // Reserve space for arguments and align frame before entering C++ world. | 71 // Reserve space for arguments and align frame before entering C++ world. |
| 72 __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments))); | 72 __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments))); |
| 73 if (OS::ActivationFrameAlignment() > 1) { | 73 if (OS::ActivationFrameAlignment() > 1) { |
| 74 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 74 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
| 75 } | 75 } |
| 76 | 76 |
| 77 // Pass NativeArguments structure by value and call runtime. | 77 // Pass NativeArguments structure by value and call runtime. |
| 78 __ movl(Address(ESP, isolate_offset), EDI); // Set isolate in NativeArgs. | 78 __ movl(Address(ESP, thread_offset), THR); // Set thread in NativeArgs. |
| 79 // There are no runtime calls to closures, so we do not need to set the tag | 79 // There are no runtime calls to closures, so we do not need to set the tag |
| 80 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. | 80 // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
| 81 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. | 81 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. |
| 82 __ leal(EAX, Address(EBP, EDX, TIMES_4, 1 * kWordSize)); // Compute argv. | 82 __ leal(EAX, Address(EBP, EDX, TIMES_4, 1 * kWordSize)); // Compute argv. |
| 83 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. | 83 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. |
| 84 __ addl(EAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument. | 84 __ addl(EAX, Immediate(1 * kWordSize)); // Retval is next to 1st argument. |
| 85 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. | 85 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. |
| 86 __ call(ECX); | 86 __ call(ECX); |
| 87 | 87 |
| 88 // Mark that the isolate is executing Dart code. EDI is callee saved. | 88 // Mark that the isolate is executing Dart code. EDI is callee saved. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 // Input parameters: | 120 // Input parameters: |
| 121 // ESP : points to return address. | 121 // ESP : points to return address. |
| 122 // ESP + 4 : address of return value. | 122 // ESP + 4 : address of return value. |
| 123 // EAX : address of first argument in argument array. | 123 // EAX : address of first argument in argument array. |
| 124 // ECX : address of the native function to call. | 124 // ECX : address of the native function to call. |
| 125 // EDX : argc_tag including number of arguments and function kind. | 125 // EDX : argc_tag including number of arguments and function kind. |
| 126 // Uses EDI. | 126 // Uses EDI. |
| 127 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { | 127 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { |
| 128 const intptr_t native_args_struct_offset = | 128 const intptr_t native_args_struct_offset = |
| 129 NativeEntry::kNumCallWrapperArguments * kWordSize; | 129 NativeEntry::kNumCallWrapperArguments * kWordSize; |
| 130 const intptr_t isolate_offset = | 130 const intptr_t thread_offset = |
| 131 NativeArguments::isolate_offset() + native_args_struct_offset; | 131 NativeArguments::thread_offset() + native_args_struct_offset; |
| 132 const intptr_t argc_tag_offset = | 132 const intptr_t argc_tag_offset = |
| 133 NativeArguments::argc_tag_offset() + native_args_struct_offset; | 133 NativeArguments::argc_tag_offset() + native_args_struct_offset; |
| 134 const intptr_t argv_offset = | 134 const intptr_t argv_offset = |
| 135 NativeArguments::argv_offset() + native_args_struct_offset; | 135 NativeArguments::argv_offset() + native_args_struct_offset; |
| 136 const intptr_t retval_offset = | 136 const intptr_t retval_offset = |
| 137 NativeArguments::retval_offset() + native_args_struct_offset; | 137 NativeArguments::retval_offset() + native_args_struct_offset; |
| 138 | 138 |
| 139 __ EnterFrame(0); | 139 __ EnterFrame(0); |
| 140 | 140 |
| 141 __ LoadIsolate(EDI); | 141 __ LoadIsolate(EDI); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 161 // Reserve space for the native arguments structure, the outgoing parameters | 161 // Reserve space for the native arguments structure, the outgoing parameters |
| 162 // (pointer to the native arguments structure, the C function entry point) | 162 // (pointer to the native arguments structure, the C function entry point) |
| 163 // and align frame before entering the C++ world. | 163 // and align frame before entering the C++ world. |
| 164 __ AddImmediate(ESP, | 164 __ AddImmediate(ESP, |
| 165 Immediate(-INT32_SIZEOF(NativeArguments) - (2 * kWordSize))); | 165 Immediate(-INT32_SIZEOF(NativeArguments) - (2 * kWordSize))); |
| 166 if (OS::ActivationFrameAlignment() > 1) { | 166 if (OS::ActivationFrameAlignment() > 1) { |
| 167 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 167 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
| 168 } | 168 } |
| 169 | 169 |
| 170 // Pass NativeArguments structure by value and call native function. | 170 // Pass NativeArguments structure by value and call native function. |
| 171 __ movl(Address(ESP, isolate_offset), EDI); // Set isolate in NativeArgs. | 171 __ movl(Address(ESP, thread_offset), THR); // Set thread in NativeArgs. |
| 172 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. | 172 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. |
| 173 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. | 173 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. |
| 174 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr. | 174 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr. |
| 175 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. | 175 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. |
| 176 __ leal(EAX, Address(ESP, 2 * kWordSize)); // Pointer to the NativeArguments. | 176 __ leal(EAX, Address(ESP, 2 * kWordSize)); // Pointer to the NativeArguments. |
| 177 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. | 177 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. |
| 178 | 178 |
| 179 __ movl(Address(ESP, kWordSize), ECX); // Function to call. | 179 __ movl(Address(ESP, kWordSize), ECX); // Function to call. |
| 180 __ call(&NativeEntry::NativeCallWrapperLabel()); | 180 __ call(&NativeEntry::NativeCallWrapperLabel()); |
| 181 | 181 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 193 | 193 |
| 194 // Input parameters: | 194 // Input parameters: |
| 195 // ESP : points to return address. | 195 // ESP : points to return address. |
| 196 // ESP + 4 : address of return value. | 196 // ESP + 4 : address of return value. |
| 197 // EAX : address of first argument in argument array. | 197 // EAX : address of first argument in argument array. |
| 198 // ECX : address of the native function to call. | 198 // ECX : address of the native function to call. |
| 199 // EDX : argc_tag including number of arguments and function kind. | 199 // EDX : argc_tag including number of arguments and function kind. |
| 200 // Uses EDI. | 200 // Uses EDI. |
| 201 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { | 201 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
| 202 const intptr_t native_args_struct_offset = kWordSize; | 202 const intptr_t native_args_struct_offset = kWordSize; |
| 203 const intptr_t isolate_offset = | 203 const intptr_t thread_offset = |
| 204 NativeArguments::isolate_offset() + native_args_struct_offset; | 204 NativeArguments::thread_offset() + native_args_struct_offset; |
| 205 const intptr_t argc_tag_offset = | 205 const intptr_t argc_tag_offset = |
| 206 NativeArguments::argc_tag_offset() + native_args_struct_offset; | 206 NativeArguments::argc_tag_offset() + native_args_struct_offset; |
| 207 const intptr_t argv_offset = | 207 const intptr_t argv_offset = |
| 208 NativeArguments::argv_offset() + native_args_struct_offset; | 208 NativeArguments::argv_offset() + native_args_struct_offset; |
| 209 const intptr_t retval_offset = | 209 const intptr_t retval_offset = |
| 210 NativeArguments::retval_offset() + native_args_struct_offset; | 210 NativeArguments::retval_offset() + native_args_struct_offset; |
| 211 | 211 |
| 212 __ EnterFrame(0); | 212 __ EnterFrame(0); |
| 213 | 213 |
| 214 __ LoadIsolate(EDI); | 214 __ LoadIsolate(EDI); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 233 | 233 |
| 234 // Reserve space for the native arguments structure, the outgoing parameter | 234 // Reserve space for the native arguments structure, the outgoing parameter |
| 235 // (pointer to the native arguments structure) and align frame before | 235 // (pointer to the native arguments structure) and align frame before |
| 236 // entering the C++ world. | 236 // entering the C++ world. |
| 237 __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments) - kWordSize)); | 237 __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments) - kWordSize)); |
| 238 if (OS::ActivationFrameAlignment() > 1) { | 238 if (OS::ActivationFrameAlignment() > 1) { |
| 239 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); | 239 __ andl(ESP, Immediate(~(OS::ActivationFrameAlignment() - 1))); |
| 240 } | 240 } |
| 241 | 241 |
| 242 // Pass NativeArguments structure by value and call native function. | 242 // Pass NativeArguments structure by value and call native function. |
| 243 __ movl(Address(ESP, isolate_offset), EDI); // Set isolate in NativeArgs. | 243 __ movl(Address(ESP, thread_offset), THR); // Set thread in NativeArgs. |
| 244 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. | 244 __ movl(Address(ESP, argc_tag_offset), EDX); // Set argc in NativeArguments. |
| 245 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. | 245 __ movl(Address(ESP, argv_offset), EAX); // Set argv in NativeArguments. |
| 246 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr. | 246 __ leal(EAX, Address(EBP, 2 * kWordSize)); // Compute return value addr. |
| 247 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. | 247 __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. |
| 248 __ leal(EAX, Address(ESP, kWordSize)); // Pointer to the NativeArguments. | 248 __ leal(EAX, Address(ESP, kWordSize)); // Pointer to the NativeArguments. |
| 249 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. | 249 __ movl(Address(ESP, 0), EAX); // Pass the pointer to the NativeArguments. |
| 250 __ call(ECX); | 250 __ call(ECX); |
| 251 | 251 |
| 252 // Mark that the isolate is executing Dart code. EDI is callee saved. | 252 // Mark that the isolate is executing Dart code. EDI is callee saved. |
| 253 __ movl(Address(EDI, Isolate::vm_tag_offset()), | 253 __ movl(Address(EDI, Isolate::vm_tag_offset()), |
| (...skipping 1651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1905 } | 1905 } |
| 1906 | 1906 |
| 1907 | 1907 |
| 1908 // Jump to the exception or error handler. | 1908 // Jump to the exception or error handler. |
| 1909 // TOS + 0: return address | 1909 // TOS + 0: return address |
| 1910 // TOS + 1: program_counter | 1910 // TOS + 1: program_counter |
| 1911 // TOS + 2: stack_pointer | 1911 // TOS + 2: stack_pointer |
| 1912 // TOS + 3: frame_pointer | 1912 // TOS + 3: frame_pointer |
| 1913 // TOS + 4: exception object | 1913 // TOS + 4: exception object |
| 1914 // TOS + 5: stacktrace object | 1914 // TOS + 5: stacktrace object |
| 1915 // TOS + 6: isolate | 1915 // TOS + 6: thread |
| 1916 // No Result. | 1916 // No Result. |
| 1917 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { | 1917 void StubCode::GenerateJumpToExceptionHandlerStub(Assembler* assembler) { |
| 1918 ASSERT(kExceptionObjectReg == EAX); | 1918 ASSERT(kExceptionObjectReg == EAX); |
| 1919 ASSERT(kStackTraceObjectReg == EDX); | 1919 ASSERT(kStackTraceObjectReg == EDX); |
| 1920 __ movl(EDI, Address(ESP, 6 * kWordSize)); // Load target isolate. | 1920 __ movl(THR, Address(ESP, 6 * kWordSize)); // Load target thread. |
| 1921 __ movl(kStackTraceObjectReg, Address(ESP, 5 * kWordSize)); | 1921 __ movl(kStackTraceObjectReg, Address(ESP, 5 * kWordSize)); |
| 1922 __ movl(kExceptionObjectReg, Address(ESP, 4 * kWordSize)); | 1922 __ movl(kExceptionObjectReg, Address(ESP, 4 * kWordSize)); |
| 1923 __ movl(EBP, Address(ESP, 3 * kWordSize)); // Load target frame_pointer. | 1923 __ movl(EBP, Address(ESP, 3 * kWordSize)); // Load target frame_pointer. |
| 1924 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Load target PC into EBX. | 1924 __ movl(EBX, Address(ESP, 1 * kWordSize)); // Load target PC into EBX. |
| 1925 __ movl(ESP, Address(ESP, 2 * kWordSize)); // Load target stack_pointer. | 1925 __ movl(ESP, Address(ESP, 2 * kWordSize)); // Load target stack_pointer. |
| 1926 // TODO(koda): Pass thread instead of isolate. | 1926 // TODO(koda): Pass thread instead of isolate. |
| 1927 __ movl(THR, Address(EDI, Isolate::mutator_thread_offset())); | 1927 __ LoadIsolate(EDI); |
| 1928 // Set tag. | 1928 // Set tag. |
| 1929 __ movl(Address(EDI, Isolate::vm_tag_offset()), | 1929 __ movl(Address(EDI, Isolate::vm_tag_offset()), |
| 1930 Immediate(VMTag::kDartTagId)); | 1930 Immediate(VMTag::kDartTagId)); |
| 1931 // Clear top exit frame. | 1931 // Clear top exit frame. |
| 1932 __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), Immediate(0)); | 1932 __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), Immediate(0)); |
| 1933 __ jmp(EBX); // Jump to the exception handler code. | 1933 __ jmp(EBX); // Jump to the exception handler code. |
| 1934 } | 1934 } |
| 1935 | 1935 |
| 1936 | 1936 |
| 1937 // Calls to the runtime to optimize the given function. | 1937 // Calls to the runtime to optimize the given function. |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2127 // EBX: entry point. | 2127 // EBX: entry point. |
| 2128 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2128 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
| 2129 EmitMegamorphicLookup(assembler, EDI, EBX, EBX); | 2129 EmitMegamorphicLookup(assembler, EDI, EBX, EBX); |
| 2130 __ ret(); | 2130 __ ret(); |
| 2131 } | 2131 } |
| 2132 | 2132 |
| 2133 | 2133 |
| 2134 } // namespace dart | 2134 } // namespace dart |
| 2135 | 2135 |
| 2136 #endif // defined TARGET_ARCH_IA32 | 2136 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |