Changeset 150844 in webkit
- Timestamp:
- May 28, 2013 3:26:24 PM (11 years ago)
- Location:
- branches/dfgFourthTier/Source/JavaScriptCore
- Files:
-
- 1 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/dfgFourthTier/Source/JavaScriptCore/ChangeLog
r150839 r150844 1 2013-05-28 Mark Lam <mark.lam@apple.com> 2 3 Misc JIT probe enhacements. 4 https://bugs.webkit.org/show_bug.cgi?id=116586. 5 6 Reviewed by Michael Saboff. 7 8 1. Added JIT probe support for ARMv7 and traditional ARM. 9 Built and tested on ARMv7. ARM version not tested nor built. 10 2. Fix the following bugs in the X86 and X86_64 probes: 11 a. Cannot assume that the stack pointer is already aligned when 12 we push args for the probe. Instead, we ensure the stack 13 alignment at runtime when we set up the probe call. 14 This is now done in the ctiMasmProbeTrampoline. 15 b. On return, the user probe function may have altered the stack 16 pointer value to be restored. Previously, if the sp restore value 17 points to some of the other register restore values in the 18 ProbeContext record, we will fail to return from the probe having 19 those user specified value as we're expected to do. 20 This is now fixed. 21 3. Rearranged the X86/X86_64 registers order to organize them like gdb 22 expects on X86_64. 23 4. We also now preserve the condition code registers. 24 25 * JavaScriptCore.xcodeproj/project.pbxproj: 26 * assembler/ARMAssembler.h: 27 * assembler/ARMv7Assembler.h: 28 (ARMRegisters): 29 * assembler/MacroAssemblerARM.cpp: 30 (JSC::isVFPPresent): 31 (JSC::MacroAssemblerARM::ProbeContext::dumpCPURegisters): 32 (JSC::MacroAssemblerARM::ProbeContext::dump): 33 (JSC::MacroAssemblerARM::probe): 34 * assembler/MacroAssemblerARM.h: 35 (MacroAssemblerARM): 36 (CPUState): 37 (ProbeContext): 38 (JSC::MacroAssemblerARM::trustedImm32FromPtr): 39 * assembler/MacroAssemblerARMv7.h: 40 (MacroAssemblerARMv7): 41 (CPUState): 42 (ProbeContext): 43 (JSC::MacroAssemblerARMv7::trustedImm32FromPtr): 44 * assembler/MacroAssemblerX86.h: 45 (MacroAssemblerX86): 46 (JSC::MacroAssemblerX86::probe): 47 * assembler/MacroAssemblerX86Common.cpp: 48 (JSC::MacroAssemblerX86Common::ProbeContext::dumpCPURegisters): 49 * assembler/MacroAssemblerX86_64.h: 50 (JSC::MacroAssemblerX86_64::probe): 51 * assembler/X86Assembler.h: 52 * config.h: 53 * jit/JITStubsARM.h: 54 * jit/JITStubsARMv7.h: 55 * jit/JITStubsX86.h: 56 * jit/JITStubsX86Common.h: 57 * jit/JITStubsX86_64.h: 58 1 59 2013-05-28 Filip Pizlo <fpizlo@apple.com> 2 60 … … 1467 1525 1468 1526 Reviewed by Geoffrey Garen. 1527 1528 Edit: For C++ code, you can do debugging by adding printfs to your 1529 code. For JIT generated code, you can now do the equivalent by 1530 inserting a probe and have it emit a call to your probe function. 1469 1531 1470 1532 The probe is in the form of a MacroAssembler pseudo instruction. -
branches/dfgFourthTier/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r150807 r150844 960 960 FECE74571745456500FF9300 /* MacroAssemblerX86Common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECE74561745456500FF9300 /* MacroAssemblerX86Common.cpp */; }; 961 961 FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = FED287B115EC9A5700DA8161 /* LLIntOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; }; 962 FEE3147D174AACAF0013BCAC /* MacroAssemblerARMv7.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEE3147C174AACAF0013BCAC /* MacroAssemblerARMv7.cpp */; }; 962 963 FEF6835E174343CC00A32E25 /* JITStubsARM.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF6835A174343CC00A32E25 /* JITStubsARM.h */; settings = {ATTRIBUTES = (Private, ); }; }; 963 964 FEF6835F174343CC00A32E25 /* JITStubsARMv7.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF6835B174343CC00A32E25 /* JITStubsARMv7.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 1994 1995 FECE74561745456500FF9300 /* MacroAssemblerX86Common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssemblerX86Common.cpp; sourceTree = "<group>"; }; 1995 1996 FED287B115EC9A5700DA8161 /* LLIntOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntOpcode.h; path = llint/LLIntOpcode.h; sourceTree = "<group>"; }; 1997 FEE3147C174AACAF0013BCAC /* MacroAssemblerARMv7.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssemblerARMv7.cpp; sourceTree = "<group>"; }; 1996 1998 FEF6835A174343CC00A32E25 /* JITStubsARM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubsARM.h; sourceTree = "<group>"; }; 1997 1999 FEF6835B174343CC00A32E25 /* JITStubsARMv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubsARMv7.h; sourceTree = "<group>"; }; … … 3123 3125 86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */, 3124 3126 86D3B2C210156BDE002865E7 /* MacroAssemblerARM.h */, 3127 FEE3147C174AACAF0013BCAC /* MacroAssemblerARMv7.cpp */, 3125 3128 86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */, 3126 3129 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */, … … 4432 4435 0FF42745158EBE91004CB9FF /* udis86_syn-att.c in Sources */, 4433 4436 0FF42746158EBE91004CB9FF /* udis86_syn-intel.c in Sources */, 4437 FEE3147D174AACAF0013BCAC /* MacroAssemblerARMv7.cpp in Sources */, 4434 4438 0FF42747158EBE91004CB9FF /* udis86_syn.c in Sources */, 4435 4439 0FF42732158EBD58004CB9FF /* UDis86Disassembler.cpp in Sources */, -
branches/dfgFourthTier/Source/JavaScriptCore/assembler/ARMAssembler.h
r148697 r150844 51 51 r10, 52 52 r11, 53 r12, S1 = r12,53 r12, ip = r12, S1 = r12, 54 54 r13, sp = r13, 55 55 r14, lr = r14, … … 92 92 } FPRegisterID; 93 93 94 #if USE(MASM_PROBE) 95 #define FOR_EACH_CPU_REGISTER(V) \ 96 FOR_EACH_CPU_GPREGISTER(V) \ 97 FOR_EACH_CPU_SPECIAL_REGISTER(V) \ 98 FOR_EACH_CPU_FPREGISTER(V) 99 100 #define FOR_EACH_CPU_GPREGISTER(V) \ 101 V(void*, r0) \ 102 V(void*, r1) \ 103 V(void*, r2) \ 104 V(void*, r3) \ 105 V(void*, r4) \ 106 V(void*, r5) \ 107 V(void*, r6) \ 108 V(void*, r7) \ 109 V(void*, r8) \ 110 V(void*, r9) \ 111 V(void*, r10) \ 112 V(void*, r11) \ 113 V(void*, ip) \ 114 V(void*, sp) \ 115 V(void*, lr) \ 116 V(void*, pc) 117 118 #define FOR_EACH_CPU_SPECIAL_REGISTER(V) \ 119 V(void*, apsr) \ 120 V(void*, fpscr) \ 121 122 #define FOR_EACH_CPU_FPREGISTER(V) \ 123 V(double, d0) \ 124 V(double, d1) \ 125 V(double, d2) \ 126 V(double, d3) \ 127 V(double, d4) \ 128 V(double, d5) \ 129 V(double, d6) \ 130 V(double, d7) \ 131 V(double, d8) \ 132 V(double, d9) \ 133 V(double, d10) \ 134 V(double, d11) \ 135 V(double, d12) \ 136 V(double, d13) \ 137 V(double, d14) \ 138 V(double, d15) 139 #endif // USE(MASM_PROBE) 94 140 } // namespace ARMRegisters 95 141 -
branches/dfgFourthTier/Source/JavaScriptCore/assembler/ARMv7Assembler.h
r149649 r150844 173 173 return (FPDoubleRegisterID)(reg >> 1); 174 174 } 175 176 #if USE(MASM_PROBE) 177 #define FOR_EACH_CPU_REGISTER(V) \ 178 FOR_EACH_CPU_GPREGISTER(V) \ 179 FOR_EACH_CPU_SPECIAL_REGISTER(V) \ 180 FOR_EACH_CPU_FPREGISTER(V) 181 182 #define FOR_EACH_CPU_GPREGISTER(V) \ 183 V(void*, r0) \ 184 V(void*, r1) \ 185 V(void*, r2) \ 186 V(void*, r3) \ 187 V(void*, r4) \ 188 V(void*, r5) \ 189 V(void*, r6) \ 190 V(void*, r7) \ 191 V(void*, r8) \ 192 V(void*, r9) \ 193 V(void*, r10) \ 194 V(void*, r11) \ 195 V(void*, ip) \ 196 V(void*, sp) \ 197 V(void*, lr) \ 198 V(void*, pc) 199 200 #define FOR_EACH_CPU_SPECIAL_REGISTER(V) \ 201 V(void*, apsr) \ 202 V(void*, fpscr) \ 203 204 #define FOR_EACH_CPU_FPREGISTER(V) \ 205 V(double, d0) \ 206 V(double, d1) \ 207 V(double, d2) \ 208 V(double, d3) \ 209 V(double, d4) \ 210 V(double, d5) \ 211 V(double, d6) \ 212 V(double, d7) \ 213 V(double, d8) \ 214 V(double, d9) \ 215 V(double, d10) \ 216 V(double, d11) \ 217 V(double, d12) \ 218 V(double, d13) \ 219 V(double, d14) \ 220 V(double, d15) \ 221 FOR_EACH_CPU_FPREGISTER_EXTENSION(V) 222 223 #if CPU(APPLE_ARMV7S) 224 #define FOR_EACH_CPU_FPREGISTER_EXTENSION(V) \ 225 V(double, d16) \ 226 V(double, d17) \ 227 V(double, d18) \ 228 V(double, d19) \ 229 V(double, d20) \ 230 V(double, d21) \ 231 V(double, d22) \ 232 V(double, d23) \ 233 V(double, d24) \ 234 V(double, d25) \ 235 V(double, d26) \ 236 V(double, d27) \ 237 V(double, d28) \ 238 V(double, d29) \ 239 V(double, d30) \ 240 V(double, d31) 241 #else 242 #define FOR_EACH_CPU_FPREGISTER_EXTENSION(V) // Nothing to add. 243 #endif // CPU(APPLE_ARMV7S) 244 245 #endif // USE(MASM_PROBE) 175 246 } 176 247 -
branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerARM.cpp
r125541 r150844 1 1 /* 2 * Copyright (C) 2013 Apple Inc. 2 3 * Copyright (C) 2009 University of Szeged 3 4 * All rights reserved. … … 31 32 #include "MacroAssemblerARM.h" 32 33 34 #if USE(MASM_PROBE) 35 #include <wtf/StdLibExtras.h> 36 #endif 37 33 38 #if OS(LINUX) 34 39 #include <sys/types.h> … … 56 61 close(fd); 57 62 } 58 #endif 63 #endif // OS(LINUX) 59 64 60 65 #if (COMPILER(RVCT) && defined(__TARGET_FPU_VFP)) || (COMPILER(GCC) && defined(__VFP_FP__)) … … 93 98 m_assembler.orr(dest, dest, m_assembler.lsl(ARMRegisters::S0, 16)); 94 99 } 95 #endif 100 #endif // CPU(ARMV5_OR_LOWER) 101 102 #if USE(MASM_PROBE) 103 104 void MacroAssemblerARM::ProbeContext::dumpCPURegisters(const char* indentation) 105 { 106 #define DUMP_GPREGISTER(_type, _regName) { \ 107 int32_t value = reinterpret_cast<int32_t>(cpu._regName); \ 108 dataLogF("%s %5s: 0x%08x %d\n", indentation, #_regName, value, value) ; \ 109 } 110 FOR_EACH_CPU_GPREGISTER(DUMP_GPREGISTER) 111 FOR_EACH_CPU_SPECIAL_REGISTER(DUMP_GPREGISTER) 112 #undef DUMP_GPREGISTER 113 114 #define DUMP_FPREGISTER(_type, _regName) { \ 115 uint32_t* u = reinterpret_cast<uint32_t*>(&cpu._regName); \ 116 double* d = reinterpret_cast<double*>(&cpu._regName); \ 117 dataLogF("%s %5s: 0x %08x %08x %12g\n", \ 118 indentation, #_regName, u[1], u[0], d[0]); \ 119 } 120 FOR_EACH_CPU_FPREGISTER(DUMP_FPREGISTER) 121 #undef DUMP_FPREGISTER 122 } 123 124 void MacroAssemblerARM::ProbeContext::dump(const char* indentation) 125 { 126 if (!indentation) 127 indentation = ""; 128 129 dataLogF("%sProbeContext %p {\n", indentation, this); 130 dataLogF("%s probeFunction: %p\n", indentation, probeFunction); 131 dataLogF("%s arg1: %p %llu\n", indentation, arg1, reinterpret_cast<int64_t>(arg1)); 132 dataLogF("%s arg2: %p %llu\n", indentation, arg2, reinterpret_cast<int64_t>(arg2)); 133 dataLogF("%s jitStackFrame: %p\n", indentation, jitStackFrame); 134 dataLogF("%s cpu: {\n", indentation); 135 136 dumpCPURegisters(indentation); 137 138 dataLogF("%s }\n", indentation); 139 dataLogF("%s}\n", indentation); 140 } 141 142 143 extern "C" void ctiMasmProbeTrampoline(); 144 145 // For details on "What code is emitted for the probe?" and "What values are in 146 // the saved registers?", see comment for MacroAssemblerX86::probe() in 147 // MacroAssemblerX86_64.h. 148 149 void MacroAssemblerARM::probe(MacroAssemblerARM::ProbeFunction function, void* arg1, void* arg2) 150 { 151 push(RegisterID::sp); 152 push(RegisterID::lr); 153 push(RegisterID::ip); 154 push(RegisterID::S0); 155 // The following uses RegisterID::S0. So, they must come after we push S0 above. 156 push(trustedImm32FromPtr(arg2)); 157 push(trustedImm32FromPtr(arg1)); 158 push(trustedImm32FromPtr(function)); 159 160 move(trustedImm32FromPtr(ctiMasmProbeTrampoline), RegisterID::S0); 161 m_assembler.blx(RegisterID::S0); 96 162 97 163 } 164 #endif // USE(MASM_PROBE) 165 166 } // namespace JSC 98 167 99 168 #endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL) -
branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
r146195 r150844 1 1 /* 2 * Copyright (C) 2008 Apple Inc.2 * Copyright (C) 2008, 2013 Apple Inc. 3 3 * Copyright (C) 2009, 2010 University of Szeged 4 4 * All rights reserved. … … 36 36 namespace JSC { 37 37 38 struct JITStackFrame; 39 38 40 class MacroAssemblerARM : public AbstractMacroAssembler<ARMAssembler> { 39 41 static const int DoubleConditionMask = 0x0f; … … 1326 1328 } 1327 1329 1330 #if USE(MASM_PROBE) 1331 struct CPUState { 1332 #define DECLARE_REGISTER(_type, _regName) \ 1333 _type _regName; 1334 FOR_EACH_CPU_REGISTER(DECLARE_REGISTER) 1335 #undef DECLARE_REGISTER 1336 }; 1337 1338 struct ProbeContext; 1339 typedef void (*ProbeFunction)(struct ProbeContext*); 1340 1341 struct ProbeContext { 1342 ProbeFunction probeFunction; 1343 void* arg1; 1344 void* arg2; 1345 JITStackFrame* jitStackFrame; 1346 CPUState cpu; 1347 1348 void dump(const char* indentation = 0); 1349 private: 1350 void dumpCPURegisters(const char* indentation); 1351 }; 1352 1353 // For details about probe(), see comment in MacroAssemblerX86_64.h. 1354 void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0); 1355 #endif // USE(MASM_PROBE) 1356 1328 1357 protected: 1329 1358 ARMAssembler::Condition ARMCondition(RelationalCondition cond) … … 1381 1410 } 1382 1411 1412 #if USE(MASM_PROBE) 1413 inline TrustedImm32 trustedImm32FromPtr(void* ptr) 1414 { 1415 return TrustedImm32(TrustedImmPtr(ptr)); 1416 } 1417 1418 inline TrustedImm32 trustedImm32FromPtr(ProbeFunction function) 1419 { 1420 return TrustedImm32(TrustedImmPtr(reinterpret_cast<void*>(function))); 1421 } 1422 1423 inline TrustedImm32 trustedImm32FromPtr(void (*function)()) 1424 { 1425 return TrustedImm32(TrustedImmPtr(reinterpret_cast<void*>(function))); 1426 } 1427 #endif 1428 1383 1429 static const bool s_isVFPPresent; 1384 1430 }; -
branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
r149649 r150844 35 35 namespace JSC { 36 36 37 struct JITStackFrame; 38 37 39 class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> { 38 40 // FIXME: switch dataTempRegister & addressTempRegister, or possibly use r7? … … 1790 1792 } 1791 1793 1794 #if USE(MASM_PROBE) 1795 struct CPUState { 1796 #define DECLARE_REGISTER(_type, _regName) \ 1797 _type _regName; 1798 FOR_EACH_CPU_REGISTER(DECLARE_REGISTER) 1799 #undef DECLARE_REGISTER 1800 }; 1801 1802 struct ProbeContext; 1803 typedef void (*ProbeFunction)(struct ProbeContext*); 1804 1805 struct ProbeContext { 1806 ProbeFunction probeFunction; 1807 void* arg1; 1808 void* arg2; 1809 JITStackFrame* jitStackFrame; 1810 CPUState cpu; 1811 1812 void dump(const char* indentation = 0); 1813 private: 1814 void dumpCPURegisters(const char* indentation); 1815 }; 1816 1817 // For details about probe(), see comment in MacroAssemblerX86_64.h. 1818 void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0); 1819 #endif // USE(MASM_PROBE) 1820 1792 1821 protected: 1793 1822 ALWAYS_INLINE Jump jump() … … 1900 1929 } 1901 1930 1931 #if USE(MASM_PROBE) 1932 inline TrustedImm32 trustedImm32FromPtr(void* ptr) 1933 { 1934 return TrustedImm32(TrustedImmPtr(ptr)); 1935 } 1936 1937 inline TrustedImm32 trustedImm32FromPtr(ProbeFunction function) 1938 { 1939 return TrustedImm32(TrustedImmPtr(reinterpret_cast<void*>(function))); 1940 } 1941 1942 inline TrustedImm32 trustedImm32FromPtr(void (*function)()) 1943 { 1944 return TrustedImm32(TrustedImmPtr(reinterpret_cast<void*>(function))); 1945 } 1946 #endif 1947 1902 1948 bool m_makeJumpPatchable; 1903 1949 }; -
branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerX86.h
r150186 r150844 293 293 294 294 #if USE(MASM_PROBE) 295 // This function emits code to preserve the CPUState (e.g. registers), 296 // call a user supplied probe function, and restore the CPUState before 297 // continuing with other JIT generated code. 298 // 299 // The user supplied probe function will be called with a single pointer to 300 // a ProbeContext struct (defined above) which contains, among other things, 301 // the preserved CPUState. This allows the user probe function to inspect 302 // the CPUState at that point in the JIT generated code. 303 // 304 // If the user probe function alters the register values in the ProbeContext, 305 // the altered values will be loaded into the CPU registers when the probe 306 // returns. 307 // 308 // The ProbeContext is stack allocated and is only valid for the duration 309 // of the call to the user probe function. 310 295 // For details about probe(), see comment in MacroAssemblerX86_64.h. 311 296 void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0); 312 297 #endif // USE(MASM_PROBE) … … 353 338 extern "C" void ctiMasmProbeTrampoline(); 354 339 355 // What code is emitted for the probe? 356 // ================================== 357 // We want to keep the size of the emitted probe invocation code as compact as 358 // possible to minimize the perturbation to the JIT generated code. However, 359 // we also need to preserve the CPU registers and set up the ProbeContext to be 360 // passed to the user probe function. 361 // 362 // Hence, we do only the minimum here to preserve the eax (to be used as a 363 // scratch register) and esp registers, and pass the probe arguments. We'll let 364 // the ctiMasmProbeTrampoline handle the rest of the probe invocation work 365 // i.e. saving the CPUState (and setting up the ProbeContext), calling the user 366 // probe function, and restoring the CPUState before returning to JIT generated 367 // code. 368 // 369 // What values are in the saved registers? 370 // ====================================== 371 // Conceptually, the saved registers should contain values as if the probe 372 // is not present in the JIT generated code. Hence, they should contain values 373 // that are expected at the start of the instruction immediately following the 374 // probe. 375 // 376 // Specifcally, the saved esp will point to the stack position before we 377 // push the ProbeContext frame. The saved eip will point to the address of 378 // the instruction immediately following the probe. 340 // For details on "What code is emitted for the probe?" and "What values are in 341 // the saved registers?", see comment for MacroAssemblerX86::probe() in 342 // MacroAssemblerX86_64.h. 379 343 380 344 inline void MacroAssemblerX86::probe(MacroAssemblerX86::ProbeFunction function, void* arg1, void* arg2) 381 345 { 382 RegisterID esp = RegisterID::esp; 383 #define probeContextField(field) Address(esp, offsetof(ProbeContext, field)) 384 385 // The X86_64 ABI specifies that the worse case stack alignment requirement 386 // is 32 bytes. 387 const int probeFrameSize = WTF::roundUpToMultipleOf(32, sizeof(ProbeContext)); 388 sub32(TrustedImm32(probeFrameSize), esp); 389 390 store32(RegisterID::eax, probeContextField(cpu.eax)); 391 392 move(TrustedImm32(probeFrameSize), RegisterID::eax); 393 add32(esp, RegisterID::eax); 394 store32(RegisterID::eax, probeContextField(cpu.esp)); 395 396 store32(trustedImm32FromPtr(function), probeContextField(probeFunction)); 397 store32(trustedImm32FromPtr(arg1), probeContextField(arg1)); 398 store32(trustedImm32FromPtr(arg2), probeContextField(arg2)); 346 push(RegisterID::esp); 347 push(RegisterID::eax); 348 push(trustedImm32FromPtr(arg2)); 349 push(trustedImm32FromPtr(arg1)); 350 push(trustedImm32FromPtr(function)); 399 351 400 352 move(trustedImm32FromPtr(ctiMasmProbeTrampoline), RegisterID::eax); 401 353 call(RegisterID::eax); 402 403 #undef probeContextField404 354 } 405 355 #endif // USE(MASM_PROBE) -
branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp
r150186 r150844 25 25 26 26 #include "config.h" 27 28 #if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64)) 27 29 #include "MacroAssemblerX86Common.h" 28 30 … … 36 38 #define DUMP_GPREGISTER(_type, _regName) { \ 37 39 int32_t value = reinterpret_cast<int32_t>(cpu._regName); \ 38 dataLogF("%s % 4s: 0x%08x %d\n", indentation, #_regName, value, value) ; \40 dataLogF("%s %6s: 0x%08x %d\n", indentation, #_regName, value, value) ; \ 39 41 } 40 42 #elif CPU(X86_64) 41 43 #define DUMP_GPREGISTER(_type, _regName) { \ 42 44 int64_t value = reinterpret_cast<int64_t>(cpu._regName); \ 43 dataLogF("%s % 4s: 0x%016llx %lld\n", indentation, #_regName, value, value) ; \45 dataLogF("%s %6s: 0x%016llx %lld\n", indentation, #_regName, value, value) ; \ 44 46 } 45 47 #endif 46 48 FOR_EACH_CPU_GPREGISTER(DUMP_GPREGISTER) 49 FOR_EACH_CPU_SPECIAL_REGISTER(DUMP_GPREGISTER) 47 50 #undef DUMP_GPREGISTER 48 51 … … 50 53 uint32_t* u = reinterpret_cast<uint32_t*>(&cpu._regName); \ 51 54 double* d = reinterpret_cast<double*>(&cpu._regName); \ 52 dataLogF("%s % s: 0x%08x%08x 0x%08x%08x %12g %12g\n", \55 dataLogF("%s %6s: 0x%08x%08x 0x%08x%08x %12g %12g\n", \ 53 56 indentation, #_regName, u[3], u[2], u[1], u[0], d[1], d[0]); \ 54 57 } … … 78 81 79 82 } // namespace JSC 83 84 #endif // ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64)) -
branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
r150186 r150844 688 688 // passed to the user probe function. 689 689 // 690 // Hence, we do only the minimum here to preserve the rax (to be used as a691 // scratch register) and rsp registers, and pass the probe arguments. We'll let692 // the ctiMasmProbeTrampoline handle the rest of the probe invocation work693 // i.e. saving the CPUState (and setting up the ProbeContext), calling the user694 // probe function, and restoring the CPUState before returning to JIT generated695 // code.690 // Hence, we do only the minimum here to preserve a scratch register (i.e. rax 691 // in this case) and the stack pointer (i.e. rsp), and pass the probe arguments. 692 // We'll let the ctiMasmProbeTrampoline handle the rest of the probe invocation 693 // work i.e. saving the CPUState (and setting up the ProbeContext), calling the 694 // user probe function, and restoring the CPUState before returning to JIT 695 // generated code. 696 696 // 697 697 // What values are in the saved registers? … … 702 702 // probe. 703 703 // 704 // Specifcally, the saved rsp will point to the stack position before we705 // p ush the ProbeContext frame. The saved rip will point to the address of706 // the instruction immediately following the probe.704 // Specifcally, the saved stack pointer register will point to the stack 705 // position before we push the ProbeContext frame. The saved rip will point to 706 // the address of the instruction immediately following the probe. 707 707 708 708 inline void MacroAssemblerX86_64::probe(MacroAssemblerX86_64::ProbeFunction function, void* arg1, void* arg2) 709 709 { 710 RegisterID esp = RegisterID::esp; 711 #define probeContextField(field) Address(esp, offsetof(ProbeContext, field)) 712 713 // The X86_64 ABI specifies that the worse case stack alignment requirement 714 // is 32 bytes. 715 const int probeFrameSize = WTF::roundUpToMultipleOf(32, sizeof(ProbeContext)); 716 sub64(TrustedImm32(probeFrameSize), esp); 717 718 store64(RegisterID::eax, probeContextField(cpu.eax)); 719 720 move(TrustedImm32(probeFrameSize), RegisterID::eax); 721 add64(esp, RegisterID::eax); 722 store64(RegisterID::eax, probeContextField(cpu.esp)); 723 724 store64(trustedImm64FromPtr(function), probeContextField(probeFunction)); 725 store64(trustedImm64FromPtr(arg1), probeContextField(arg1)); 726 store64(trustedImm64FromPtr(arg2), probeContextField(arg2)); 727 710 push(RegisterID::esp); 711 push(RegisterID::eax); 712 move(trustedImm64FromPtr(arg2), RegisterID::eax); 713 push(RegisterID::eax); 714 move(trustedImm64FromPtr(arg1), RegisterID::eax); 715 push(RegisterID::eax); 716 move(trustedImm64FromPtr(function), RegisterID::eax); 717 push(RegisterID::eax); 728 718 move(trustedImm64FromPtr(ctiMasmProbeTrampoline), RegisterID::eax); 729 719 call(RegisterID::eax); 730 731 #undef probeContextField732 720 } 733 721 #endif // USE(MASM_PROBE) -
branches/dfgFourthTier/Source/JavaScriptCore/assembler/X86Assembler.h
r150186 r150844 80 80 #define FOR_EACH_CPU_REGISTER(V) \ 81 81 FOR_EACH_CPU_GPREGISTER(V) \ 82 FOR_EACH_CPU_SPECIAL_REGISTER(V) \ 82 83 FOR_EACH_CPU_FPREGISTER(V) 83 84 84 85 #define FOR_EACH_CPU_GPREGISTER(V) \ 85 86 V(void*, eax) \ 87 V(void*, ebx) \ 86 88 V(void*, ecx) \ 87 89 V(void*, edx) \ 88 V(void*, ebx) \89 V(void*, esp) \90 V(void*, ebp) \91 90 V(void*, esi) \ 92 91 V(void*, edi) \ 93 FOR_EACH_X86_64_CPU_GPREGISTER(V) \ 94 V(void*, eip) 92 V(void*, ebp) \ 93 V(void*, esp) \ 94 FOR_EACH_X86_64_CPU_GPREGISTER(V) 95 96 #define FOR_EACH_CPU_SPECIAL_REGISTER(V) \ 97 V(void*, eip) \ 98 V(void*, eflags) \ 95 99 96 100 #define FOR_EACH_CPU_FPREGISTER(V) \ -
branches/dfgFourthTier/Source/JavaScriptCore/jit/JITStubsARM.h
r150109 r150844 47 47 #define PRESERVEDR4_OFFSET 68 48 48 49 50 49 #if COMPILER(GCC) 50 51 #if USE(MASM_PROBE) 52 // The following are offsets for MacroAssembler::ProbeContext fields accessed 53 // by the ctiMasmProbeTrampoline stub. 54 55 #define PTR_SIZE 4 56 #define PROBE_PROBE_FUNCTION_OFFSET (0 * PTR_SIZE) 57 #define PROBE_ARG1_OFFSET (1 * PTR_SIZE) 58 #define PROBE_ARG2_OFFSET (2 * PTR_SIZE) 59 #define PROBE_JIT_STACK_FRAME_OFFSET (3 * PTR_SIZE) 60 61 #define PROBE_FIRST_GPREG_OFFSET (4 * PTR_SIZE) 62 63 #define GPREG_SIZE 4 64 #define PROBE_CPU_R0_OFFSET (PROBE_FIRST_GPREG_OFFSET + (0 * GPREG_SIZE)) 65 #define PROBE_CPU_R1_OFFSET (PROBE_FIRST_GPREG_OFFSET + (1 * GPREG_SIZE)) 66 #define PROBE_CPU_R2_OFFSET (PROBE_FIRST_GPREG_OFFSET + (2 * GPREG_SIZE)) 67 #define PROBE_CPU_R3_OFFSET (PROBE_FIRST_GPREG_OFFSET + (3 * GPREG_SIZE)) 68 #define PROBE_CPU_R4_OFFSET (PROBE_FIRST_GPREG_OFFSET + (4 * GPREG_SIZE)) 69 #define PROBE_CPU_R5_OFFSET (PROBE_FIRST_GPREG_OFFSET + (5 * GPREG_SIZE)) 70 #define PROBE_CPU_R6_OFFSET (PROBE_FIRST_GPREG_OFFSET + (6 * GPREG_SIZE)) 71 #define PROBE_CPU_R7_OFFSET (PROBE_FIRST_GPREG_OFFSET + (7 * GPREG_SIZE)) 72 #define PROBE_CPU_R8_OFFSET (PROBE_FIRST_GPREG_OFFSET + (8 * GPREG_SIZE)) 73 #define PROBE_CPU_R9_OFFSET (PROBE_FIRST_GPREG_OFFSET + (9 * GPREG_SIZE)) 74 #define PROBE_CPU_R10_OFFSET (PROBE_FIRST_GPREG_OFFSET + (10 * GPREG_SIZE)) 75 #define PROBE_CPU_R11_OFFSET (PROBE_FIRST_GPREG_OFFSET + (11 * GPREG_SIZE)) 76 #define PROBE_CPU_IP_OFFSET (PROBE_FIRST_GPREG_OFFSET + (12 * GPREG_SIZE)) 77 #define PROBE_CPU_SP_OFFSET (PROBE_FIRST_GPREG_OFFSET + (13 * GPREG_SIZE)) 78 #define PROBE_CPU_LR_OFFSET (PROBE_FIRST_GPREG_OFFSET + (14 * GPREG_SIZE)) 79 #define PROBE_CPU_PC_OFFSET (PROBE_FIRST_GPREG_OFFSET + (15 * GPREG_SIZE)) 80 81 #define PROBE_CPU_APSR_OFFSET (PROBE_FIRST_GPREG_OFFSET + (16 * GPREG_SIZE)) 82 #define PROBE_CPU_FPSCR_OFFSET (PROBE_FIRST_GPREG_OFFSET + (17 * GPREG_SIZE)) 83 84 #define PROBE_FIRST_FPREG_OFFSET (PROBE_FIRST_GPREG_OFFSET + (18 * GPREG_SIZE)) 85 86 #define FPREG_SIZE 8 87 #define PROBE_CPU_D0_OFFSET (PROBE_FIRST_FPREG_OFFSET + (0 * FPREG_SIZE)) 88 #define PROBE_CPU_D1_OFFSET (PROBE_FIRST_FPREG_OFFSET + (1 * FPREG_SIZE)) 89 #define PROBE_CPU_D2_OFFSET (PROBE_FIRST_FPREG_OFFSET + (2 * FPREG_SIZE)) 90 #define PROBE_CPU_D3_OFFSET (PROBE_FIRST_FPREG_OFFSET + (3 * FPREG_SIZE)) 91 #define PROBE_CPU_D4_OFFSET (PROBE_FIRST_FPREG_OFFSET + (4 * FPREG_SIZE)) 92 #define PROBE_CPU_D5_OFFSET (PROBE_FIRST_FPREG_OFFSET + (5 * FPREG_SIZE)) 93 #define PROBE_CPU_D6_OFFSET (PROBE_FIRST_FPREG_OFFSET + (6 * FPREG_SIZE)) 94 #define PROBE_CPU_D7_OFFSET (PROBE_FIRST_FPREG_OFFSET + (7 * FPREG_SIZE)) 95 #define PROBE_CPU_D8_OFFSET (PROBE_FIRST_FPREG_OFFSET + (8 * FPREG_SIZE)) 96 #define PROBE_CPU_D9_OFFSET (PROBE_FIRST_FPREG_OFFSET + (9 * FPREG_SIZE)) 97 #define PROBE_CPU_D10_OFFSET (PROBE_FIRST_FPREG_OFFSET + (10 * FPREG_SIZE)) 98 #define PROBE_CPU_D11_OFFSET (PROBE_FIRST_FPREG_OFFSET + (11 * FPREG_SIZE)) 99 #define PROBE_CPU_D12_OFFSET (PROBE_FIRST_FPREG_OFFSET + (12 * FPREG_SIZE)) 100 #define PROBE_CPU_D13_OFFSET (PROBE_FIRST_FPREG_OFFSET + (13 * FPREG_SIZE)) 101 #define PROBE_CPU_D14_OFFSET (PROBE_FIRST_FPREG_OFFSET + (14 * FPREG_SIZE)) 102 #define PROBE_CPU_D15_OFFSET (PROBE_FIRST_FPREG_OFFSET + (15 * FPREG_SIZE)) 103 104 #define PROBE_SIZE (PROBE_FIRST_FPREG_OFFSET + (16 * FPREG_SIZE)) 105 106 // These ASSERTs remind you that if you change the layout of ProbeContext, 107 // you need to change ctiMasmProbeTrampoline offsets above to match. 108 #define PROBE_OFFSETOF(x) offsetof(struct MacroAssembler::ProbeContext, x) 109 COMPILE_ASSERT(PROBE_OFFSETOF(probeFunction) == PROBE_PROBE_FUNCTION_OFFSET, ProbeContext_probeFunction_offset_matches_ctiMasmProbeTrampoline); 110 COMPILE_ASSERT(PROBE_OFFSETOF(arg1) == PROBE_ARG1_OFFSET, ProbeContext_arg1_offset_matches_ctiMasmProbeTrampoline); 111 COMPILE_ASSERT(PROBE_OFFSETOF(arg2) == PROBE_ARG2_OFFSET, ProbeContext_arg2_offset_matches_ctiMasmProbeTrampoline); 112 COMPILE_ASSERT(PROBE_OFFSETOF(jitStackFrame) == PROBE_JIT_STACK_FRAME_OFFSET, ProbeContext_jitStackFrame_offset_matches_ctiMasmProbeTrampoline); 113 114 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r0) == PROBE_CPU_R0_OFFSET, ProbeContext_cpu_r0_offset_matches_ctiMasmProbeTrampoline); 115 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r1) == PROBE_CPU_R1_OFFSET, ProbeContext_cpu_r1_offset_matches_ctiMasmProbeTrampoline); 116 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r2) == PROBE_CPU_R2_OFFSET, ProbeContext_cpu_r2_offset_matches_ctiMasmProbeTrampoline); 117 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r3) == PROBE_CPU_R3_OFFSET, ProbeContext_cpu_r3_offset_matches_ctiMasmProbeTrampoline); 118 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r4) == PROBE_CPU_R4_OFFSET, ProbeContext_cpu_r4_offset_matches_ctiMasmProbeTrampoline); 119 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r5) == PROBE_CPU_R5_OFFSET, ProbeContext_cpu_r5_offset_matches_ctiMasmProbeTrampoline); 120 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r6) == PROBE_CPU_R6_OFFSET, ProbeContext_cpu_r6_offset_matches_ctiMasmProbeTrampoline); 121 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r7) == PROBE_CPU_R7_OFFSET, ProbeContext_cpu_r70_offset_matches_ctiMasmProbeTrampoline); 122 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r8) == PROBE_CPU_R8_OFFSET, ProbeContext_cpu_r8_offset_matches_ctiMasmProbeTrampoline); 123 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r9) == PROBE_CPU_R9_OFFSET, ProbeContext_cpu_r9_offset_matches_ctiMasmProbeTrampoline); 124 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r10) == PROBE_CPU_R10_OFFSET, ProbeContext_cpu_r10_offset_matches_ctiMasmProbeTrampoline); 125 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r11) == PROBE_CPU_R11_OFFSET, ProbeContext_cpu_r11_offset_matches_ctiMasmProbeTrampoline); 126 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.ip) == PROBE_CPU_IP_OFFSET, ProbeContext_cpu_ip_offset_matches_ctiMasmProbeTrampoline); 127 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.sp) == PROBE_CPU_SP_OFFSET, ProbeContext_cpu_sp_offset_matches_ctiMasmProbeTrampoline); 128 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.lr) == PROBE_CPU_LR_OFFSET, ProbeContext_cpu_lr_offset_matches_ctiMasmProbeTrampoline); 129 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.pc) == PROBE_CPU_PC_OFFSET, ProbeContext_cpu_pc_offset_matches_ctiMasmProbeTrampoline); 130 131 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.apsr) == PROBE_CPU_APSR_OFFSET, ProbeContext_cpu_apsr_offset_matches_ctiMasmProbeTrampoline); 132 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.fpscr) == PROBE_CPU_FPSCR_OFFSET, ProbeContext_cpu_fpscr_offset_matches_ctiMasmProbeTrampoline); 133 134 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d0) == PROBE_CPU_D0_OFFSET, ProbeContext_cpu_d0_offset_matches_ctiMasmProbeTrampoline); 135 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d1) == PROBE_CPU_D1_OFFSET, ProbeContext_cpu_d1_offset_matches_ctiMasmProbeTrampoline); 136 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d2) == PROBE_CPU_D2_OFFSET, ProbeContext_cpu_d2_offset_matches_ctiMasmProbeTrampoline); 137 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d3) == PROBE_CPU_D3_OFFSET, ProbeContext_cpu_d3_offset_matches_ctiMasmProbeTrampoline); 138 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d4) == PROBE_CPU_D4_OFFSET, ProbeContext_cpu_d4_offset_matches_ctiMasmProbeTrampoline); 139 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d5) == PROBE_CPU_D5_OFFSET, ProbeContext_cpu_d5_offset_matches_ctiMasmProbeTrampoline); 140 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d6) == PROBE_CPU_D6_OFFSET, ProbeContext_cpu_d6_offset_matches_ctiMasmProbeTrampoline); 141 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d7) == PROBE_CPU_D7_OFFSET, ProbeContext_cpu_d7_offset_matches_ctiMasmProbeTrampoline); 142 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d8) == PROBE_CPU_D8_OFFSET, ProbeContext_cpu_d8_offset_matches_ctiMasmProbeTrampoline); 143 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d9) == PROBE_CPU_D9_OFFSET, ProbeContext_cpu_d9_offset_matches_ctiMasmProbeTrampoline); 144 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d10) == PROBE_CPU_D10_OFFSET, ProbeContext_cpu_d10_offset_matches_ctiMasmProbeTrampoline); 145 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d11) == PROBE_CPU_D11_OFFSET, ProbeContext_cpu_d11_offset_matches_ctiMasmProbeTrampoline); 146 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d12) == PROBE_CPU_D12_OFFSET, ProbeContext_cpu_d12_offset_matches_ctiMasmProbeTrampoline); 147 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d13) == PROBE_CPU_D13_OFFSET, ProbeContext_cpu_d13_offset_matches_ctiMasmProbeTrampoline); 148 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d14) == PROBE_CPU_D14_OFFSET, ProbeContext_cpu_d14_offset_matches_ctiMasmProbeTrampoline); 149 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d15) == PROBE_CPU_D15_OFFSET, ProbeContext_cpu_d15_offset_matches_ctiMasmProbeTrampoline); 150 COMPILE_ASSERT(sizeof(MacroAssembler::ProbeContext) == PROBE_SIZE, ProbeContext_size_matches_ctiMasmProbeTrampoline); 151 #undef PROBE_OFFSETOF 152 153 #endif // USE(MASM_PROBE) 154 51 155 52 156 asm ( … … 92 196 "bx lr" "\n" 93 197 ); 198 199 #if USE(MASM_PROBE) 200 asm ( 201 ".text" "\n" 202 ".globl " SYMBOL_STRING(ctiMasmProbeTrampoline) "\n" 203 HIDE_SYMBOL(ctiMasmProbeTrampoline) "\n" 204 INLINE_ARM_FUNCTION(ctiMasmProbeTrampoline) "\n" 205 SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n" 206 207 // MacroAssembler::probe() has already generated code to store some values. 208 // The top of stack now looks like this: 209 // esp[0 * ptrSize]: probeFunction 210 // esp[1 * ptrSize]: arg1 211 // esp[2 * ptrSize]: arg2 212 // esp[3 * ptrSize]: saved r3 / S0 213 // esp[4 * ptrSize]: saved ip 214 // esp[5 * ptrSize]: saved lr 215 // esp[6 * ptrSize]: saved sp 216 217 "mov ip, sp" "\n" 218 "mov r3, sp" "\n" 219 "sub r3, r3, #" STRINGIZE_VALUE_OF(PROBE_SIZE) "\n" 220 221 // The ARM EABI specifies that the stack needs to be 16 byte aligned. 222 "bic r3, r3, #0xf" "\n" 223 "mov sp, r3" "\n" 224 225 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_PC_OFFSET) "]" "\n" 226 "add lr, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_R0_OFFSET) "\n" 227 "stmia lr, { r0-r11 }" "\n" 228 "mrs lr, APSR" "\n" 229 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_APSR_OFFSET) "]" "\n" 230 "vmrs lr, FPSCR" "\n" 231 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_FPSCR_OFFSET) "]" "\n" 232 233 "ldr lr, [ip, #0 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n" 234 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_PROBE_FUNCTION_OFFSET) "]" "\n" 235 "ldr lr, [ip, #1 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n" 236 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_ARG1_OFFSET) "]" "\n" 237 "ldr lr, [ip, #2 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n" 238 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_ARG2_OFFSET) "]" "\n" 239 "ldr lr, [ip, #3 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n" 240 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_R3_OFFSET) "]" "\n" 241 "ldr lr, [ip, #4 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n" 242 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_IP_OFFSET) "]" "\n" 243 "ldr lr, [ip, #5 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n" 244 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_LR_OFFSET) "]" "\n" 245 "ldr lr, [ip, #6 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n" 246 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n" 247 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_JIT_STACK_FRAME_OFFSET) "]" "\n" 248 249 "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_PC_OFFSET) "]" "\n" 250 251 "add ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_D0_OFFSET) "\n" 252 "vstmia.64 ip, { d0-d15 }" "\n" 253 254 "mov fp, sp" "\n" // Save the ProbeContext*. 255 256 "ldr ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_PROBE_FUNCTION_OFFSET) "]" "\n" 257 "mov r0, sp" "\n" // the ProbeContext* arg. 258 "blx ip" "\n" 259 260 "mov sp, fp" "\n" 261 262 // To enable probes to modify register state, we copy all registers 263 // out of the ProbeContext before returning. 264 265 "add ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_D15_OFFSET + FPREG_SIZE) "\n" 266 "vldmdb.64 ip!, { d0-d15 }" "\n" 267 "add ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_R11_OFFSET + GPREG_SIZE) "\n" 268 "ldmdb ip, { r0-r11 }" "\n" 269 "ldr ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_FPSCR_OFFSET) "]" "\n" 270 "vmsr FPSCR, ip" "\n" 271 272 // There are 5 more registers left to restore: ip, sp, lr, pc, and apsr. 273 // There are 2 issues that complicate the restoration of these last few 274 // registers: 275 // 276 // 1. Normal ARM calling convention relies on moving lr to pc to return to 277 // the caller. In our case, the address to return to is specified by 278 // ProbeContext.cpu.pc. And at that moment, we won't have any available 279 // scratch registers to hold the return address (lr needs to hold 280 // ProbeContext.cpu.lr, not the return address). 281 // 282 // The solution is to store the return address on the stack and load the 283 // pc from there. 284 // 285 // 2. Issue 1 means we will need to write to the stack location at 286 // ProbeContext.cpu.sp - 4. But if the user probe function had modified 287 // the value of ProbeContext.cpu.sp to point in the range between 288 // &ProbeContext.cpu.ip thru &ProbeContext.cpu.aspr, then the action for 289 // Issue 1 may trash the values to be restored before we can restore 290 // them. 291 // 292 // The solution is to check if ProbeContext.cpu.sp contains a value in 293 // the undesirable range. If so, we copy the remaining ProbeContext 294 // register data to a safe range (at memory lower than where 295 // ProbeContext.cpu.sp points) first, and restore the remaining register 296 // from this new range. 297 298 "add ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_APSR_OFFSET) "\n" 299 "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n" 300 "cmp lr, ip" "\n" 301 "bgt " SYMBOL_STRING(ctiMasmProbeTrampolineEnd) "\n" 302 303 // We get here because the new expected stack pointer location is lower 304 // than where it's supposed to be. This means the safe range of stack 305 // memory where we'll be copying the remaining register restore values to 306 // might be in a region of memory below the sp i.e. unallocated stack 307 // memory. This in turn makes it vulnerable to interrupts potentially 308 // trashing the copied values. To prevent that, we must first allocate the 309 // needed stack memory by adjusting the sp before the copying. 310 311 "sub lr, lr, #(6 * " STRINGIZE_VALUE_OF(PTR_SIZE) 312 " + " STRINGIZE_VALUE_OF(PROBE_CPU_IP_OFFSET) ")" "\n" 313 314 "mov ip, sp" "\n" 315 "mov sp, lr" "\n" 316 "mov lr, ip" "\n" 317 318 "ldr ip, [lr, #" STRINGIZE_VALUE_OF(PROBE_CPU_IP_OFFSET) "]" "\n" 319 "str ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_IP_OFFSET) "]" "\n" 320 "ldr ip, [lr, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n" 321 "str ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n" 322 "ldr ip, [lr, #" STRINGIZE_VALUE_OF(PROBE_CPU_LR_OFFSET) "]" "\n" 323 "str ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_LR_OFFSET) "]" "\n" 324 "ldr ip, [lr, #" STRINGIZE_VALUE_OF(PROBE_CPU_PC_OFFSET) "]" "\n" 325 "str ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_PC_OFFSET) "]" "\n" 326 "ldr ip, [lr, #" STRINGIZE_VALUE_OF(PROBE_CPU_APSR_OFFSET) "]" "\n" 327 "str ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_APSR_OFFSET) "]" "\n" 328 329 SYMBOL_STRING(ctiMasmProbeTrampolineEnd) ":" "\n" 330 "ldr ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_PC_OFFSET) "]" "\n" 331 "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n" 332 "sub lr, lr, #" STRINGIZE_VALUE_OF(PTR_SIZE) "\n" 333 "str ip, [lr]" "\n" 334 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n" 335 336 "ldr ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_APSR_OFFSET) "]" "\n" 337 "msr APSR, ip" "\n" 338 "ldr ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_LR_OFFSET) "]" "\n" 339 "mov lr, ip" "\n" 340 "ldr ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_IP_OFFSET) "]" "\n" 341 "ldr sp, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n" 342 343 "pop { pc }" "\n" 344 ); 345 #endif // USE(MASM_PROBE) 346 94 347 95 348 #define DEFINE_STUB_FUNCTION(rtype, op) \ -
branches/dfgFourthTier/Source/JavaScriptCore/jit/JITStubsARMv7.h
r150109 r150844 56 56 57 57 #if COMPILER(GCC) 58 59 #if USE(MASM_PROBE) 60 // The following are offsets for MacroAssembler::ProbeContext fields accessed 61 // by the ctiMasmProbeTrampoline stub. 62 63 #define PTR_SIZE 4 64 #define PROBE_PROBE_FUNCTION_OFFSET (0 * PTR_SIZE) 65 #define PROBE_ARG1_OFFSET (1 * PTR_SIZE) 66 #define PROBE_ARG2_OFFSET (2 * PTR_SIZE) 67 #define PROBE_JIT_STACK_FRAME_OFFSET (3 * PTR_SIZE) 68 69 #define PROBE_FIRST_GPREG_OFFSET (4 * PTR_SIZE) 70 71 #define GPREG_SIZE 4 72 #define PROBE_CPU_R0_OFFSET (PROBE_FIRST_GPREG_OFFSET + (0 * GPREG_SIZE)) 73 #define PROBE_CPU_R1_OFFSET (PROBE_FIRST_GPREG_OFFSET + (1 * GPREG_SIZE)) 74 #define PROBE_CPU_R2_OFFSET (PROBE_FIRST_GPREG_OFFSET + (2 * GPREG_SIZE)) 75 #define PROBE_CPU_R3_OFFSET (PROBE_FIRST_GPREG_OFFSET + (3 * GPREG_SIZE)) 76 #define PROBE_CPU_R4_OFFSET (PROBE_FIRST_GPREG_OFFSET + (4 * GPREG_SIZE)) 77 #define PROBE_CPU_R5_OFFSET (PROBE_FIRST_GPREG_OFFSET + (5 * GPREG_SIZE)) 78 #define PROBE_CPU_R6_OFFSET (PROBE_FIRST_GPREG_OFFSET + (6 * GPREG_SIZE)) 79 #define PROBE_CPU_R7_OFFSET (PROBE_FIRST_GPREG_OFFSET + (7 * GPREG_SIZE)) 80 #define PROBE_CPU_R8_OFFSET (PROBE_FIRST_GPREG_OFFSET + (8 * GPREG_SIZE)) 81 #define PROBE_CPU_R9_OFFSET (PROBE_FIRST_GPREG_OFFSET + (9 * GPREG_SIZE)) 82 #define PROBE_CPU_R10_OFFSET (PROBE_FIRST_GPREG_OFFSET + (10 * GPREG_SIZE)) 83 #define PROBE_CPU_R11_OFFSET (PROBE_FIRST_GPREG_OFFSET + (11 * GPREG_SIZE)) 84 #define PROBE_CPU_IP_OFFSET (PROBE_FIRST_GPREG_OFFSET + (12 * GPREG_SIZE)) 85 #define PROBE_CPU_SP_OFFSET (PROBE_FIRST_GPREG_OFFSET + (13 * GPREG_SIZE)) 86 #define PROBE_CPU_LR_OFFSET (PROBE_FIRST_GPREG_OFFSET + (14 * GPREG_SIZE)) 87 #define PROBE_CPU_PC_OFFSET (PROBE_FIRST_GPREG_OFFSET + (15 * GPREG_SIZE)) 88 89 #define PROBE_CPU_APSR_OFFSET (PROBE_FIRST_GPREG_OFFSET + (16 * GPREG_SIZE)) 90 #define PROBE_CPU_FPSCR_OFFSET (PROBE_FIRST_GPREG_OFFSET + (17 * GPREG_SIZE)) 91 92 #define PROBE_FIRST_FPREG_OFFSET (PROBE_FIRST_GPREG_OFFSET + (18 * GPREG_SIZE)) 93 94 #define FPREG_SIZE 8 95 #define PROBE_CPU_D0_OFFSET (PROBE_FIRST_FPREG_OFFSET + (0 * FPREG_SIZE)) 96 #define PROBE_CPU_D1_OFFSET (PROBE_FIRST_FPREG_OFFSET + (1 * FPREG_SIZE)) 97 #define PROBE_CPU_D2_OFFSET (PROBE_FIRST_FPREG_OFFSET + (2 * FPREG_SIZE)) 98 #define PROBE_CPU_D3_OFFSET (PROBE_FIRST_FPREG_OFFSET + (3 * FPREG_SIZE)) 99 #define PROBE_CPU_D4_OFFSET (PROBE_FIRST_FPREG_OFFSET + (4 * FPREG_SIZE)) 100 #define PROBE_CPU_D5_OFFSET (PROBE_FIRST_FPREG_OFFSET + (5 * FPREG_SIZE)) 101 #define PROBE_CPU_D6_OFFSET (PROBE_FIRST_FPREG_OFFSET + (6 * FPREG_SIZE)) 102 #define PROBE_CPU_D7_OFFSET (PROBE_FIRST_FPREG_OFFSET + (7 * FPREG_SIZE)) 103 #define PROBE_CPU_D8_OFFSET (PROBE_FIRST_FPREG_OFFSET + (8 * FPREG_SIZE)) 104 #define PROBE_CPU_D9_OFFSET (PROBE_FIRST_FPREG_OFFSET + (9 * FPREG_SIZE)) 105 #define PROBE_CPU_D10_OFFSET (PROBE_FIRST_FPREG_OFFSET + (10 * FPREG_SIZE)) 106 #define PROBE_CPU_D11_OFFSET (PROBE_FIRST_FPREG_OFFSET + (11 * FPREG_SIZE)) 107 #define PROBE_CPU_D12_OFFSET (PROBE_FIRST_FPREG_OFFSET + (12 * FPREG_SIZE)) 108 #define PROBE_CPU_D13_OFFSET (PROBE_FIRST_FPREG_OFFSET + (13 * FPREG_SIZE)) 109 #define PROBE_CPU_D14_OFFSET (PROBE_FIRST_FPREG_OFFSET + (14 * FPREG_SIZE)) 110 #define PROBE_CPU_D15_OFFSET (PROBE_FIRST_FPREG_OFFSET + (15 * FPREG_SIZE)) 111 112 #if CPU(APPLE_ARMV7S) 113 #define PROBE_CPU_D16_OFFSET (PROBE_FIRST_FPREG_OFFSET + (16 * FPREG_SIZE)) 114 #define PROBE_CPU_D17_OFFSET (PROBE_FIRST_FPREG_OFFSET + (17 * FPREG_SIZE)) 115 #define PROBE_CPU_D18_OFFSET (PROBE_FIRST_FPREG_OFFSET + (18 * FPREG_SIZE)) 116 #define PROBE_CPU_D19_OFFSET (PROBE_FIRST_FPREG_OFFSET + (19 * FPREG_SIZE)) 117 #define PROBE_CPU_D20_OFFSET (PROBE_FIRST_FPREG_OFFSET + (20 * FPREG_SIZE)) 118 #define PROBE_CPU_D21_OFFSET (PROBE_FIRST_FPREG_OFFSET + (21 * FPREG_SIZE)) 119 #define PROBE_CPU_D22_OFFSET (PROBE_FIRST_FPREG_OFFSET + (22 * FPREG_SIZE)) 120 #define PROBE_CPU_D23_OFFSET (PROBE_FIRST_FPREG_OFFSET + (23 * FPREG_SIZE)) 121 #define PROBE_CPU_D24_OFFSET (PROBE_FIRST_FPREG_OFFSET + (24 * FPREG_SIZE)) 122 #define PROBE_CPU_D25_OFFSET (PROBE_FIRST_FPREG_OFFSET + (25 * FPREG_SIZE)) 123 #define PROBE_CPU_D26_OFFSET (PROBE_FIRST_FPREG_OFFSET + (26 * FPREG_SIZE)) 124 #define PROBE_CPU_D27_OFFSET (PROBE_FIRST_FPREG_OFFSET + (27 * FPREG_SIZE)) 125 #define PROBE_CPU_D28_OFFSET (PROBE_FIRST_FPREG_OFFSET + (28 * FPREG_SIZE)) 126 #define PROBE_CPU_D29_OFFSET (PROBE_FIRST_FPREG_OFFSET + (29 * FPREG_SIZE)) 127 #define PROBE_CPU_D30_OFFSET (PROBE_FIRST_FPREG_OFFSET + (30 * FPREG_SIZE)) 128 #define PROBE_CPU_D31_OFFSET (PROBE_FIRST_FPREG_OFFSET + (31 * FPREG_SIZE)) 129 #define PROBE_SIZE (PROBE_FIRST_FPREG_OFFSET + (32 * FPREG_SIZE)) 130 #else 131 #define PROBE_SIZE (PROBE_FIRST_FPREG_OFFSET + (16 * FPREG_SIZE)) 132 #endif // CPU(APPLE_ARMV7S) 133 134 135 // These ASSERTs remind you that if you change the layout of ProbeContext, 136 // you need to change ctiMasmProbeTrampoline offsets above to match. 137 #define PROBE_OFFSETOF(x) offsetof(struct MacroAssembler::ProbeContext, x) 138 COMPILE_ASSERT(PROBE_OFFSETOF(probeFunction) == PROBE_PROBE_FUNCTION_OFFSET, ProbeContext_probeFunction_offset_matches_ctiMasmProbeTrampoline); 139 COMPILE_ASSERT(PROBE_OFFSETOF(arg1) == PROBE_ARG1_OFFSET, ProbeContext_arg1_offset_matches_ctiMasmProbeTrampoline); 140 COMPILE_ASSERT(PROBE_OFFSETOF(arg2) == PROBE_ARG2_OFFSET, ProbeContext_arg2_offset_matches_ctiMasmProbeTrampoline); 141 COMPILE_ASSERT(PROBE_OFFSETOF(jitStackFrame) == PROBE_JIT_STACK_FRAME_OFFSET, ProbeContext_jitStackFrame_offset_matches_ctiMasmProbeTrampoline); 142 143 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r0) == PROBE_CPU_R0_OFFSET, ProbeContext_cpu_r0_offset_matches_ctiMasmProbeTrampoline); 144 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r1) == PROBE_CPU_R1_OFFSET, ProbeContext_cpu_r1_offset_matches_ctiMasmProbeTrampoline); 145 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r2) == PROBE_CPU_R2_OFFSET, ProbeContext_cpu_r2_offset_matches_ctiMasmProbeTrampoline); 146 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r3) == PROBE_CPU_R3_OFFSET, ProbeContext_cpu_r3_offset_matches_ctiMasmProbeTrampoline); 147 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r4) == PROBE_CPU_R4_OFFSET, ProbeContext_cpu_r4_offset_matches_ctiMasmProbeTrampoline); 148 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r5) == PROBE_CPU_R5_OFFSET, ProbeContext_cpu_r5_offset_matches_ctiMasmProbeTrampoline); 149 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r6) == PROBE_CPU_R6_OFFSET, ProbeContext_cpu_r6_offset_matches_ctiMasmProbeTrampoline); 150 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r7) == PROBE_CPU_R7_OFFSET, ProbeContext_cpu_r70_offset_matches_ctiMasmProbeTrampoline); 151 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r8) == PROBE_CPU_R8_OFFSET, ProbeContext_cpu_r8_offset_matches_ctiMasmProbeTrampoline); 152 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r9) == PROBE_CPU_R9_OFFSET, ProbeContext_cpu_r9_offset_matches_ctiMasmProbeTrampoline); 153 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r10) == PROBE_CPU_R10_OFFSET, ProbeContext_cpu_r10_offset_matches_ctiMasmProbeTrampoline); 154 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r11) == PROBE_CPU_R11_OFFSET, ProbeContext_cpu_r11_offset_matches_ctiMasmProbeTrampoline); 155 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.ip) == PROBE_CPU_IP_OFFSET, ProbeContext_cpu_ip_offset_matches_ctiMasmProbeTrampoline); 156 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.sp) == PROBE_CPU_SP_OFFSET, ProbeContext_cpu_sp_offset_matches_ctiMasmProbeTrampoline); 157 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.lr) == PROBE_CPU_LR_OFFSET, ProbeContext_cpu_lr_offset_matches_ctiMasmProbeTrampoline); 158 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.pc) == PROBE_CPU_PC_OFFSET, ProbeContext_cpu_pc_offset_matches_ctiMasmProbeTrampoline); 159 160 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.apsr) == PROBE_CPU_APSR_OFFSET, ProbeContext_cpu_apsr_offset_matches_ctiMasmProbeTrampoline); 161 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.fpscr) == PROBE_CPU_FPSCR_OFFSET, ProbeContext_cpu_fpscr_offset_matches_ctiMasmProbeTrampoline); 162 163 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d0) == PROBE_CPU_D0_OFFSET, ProbeContext_cpu_d0_offset_matches_ctiMasmProbeTrampoline); 164 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d1) == PROBE_CPU_D1_OFFSET, ProbeContext_cpu_d1_offset_matches_ctiMasmProbeTrampoline); 165 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d2) == PROBE_CPU_D2_OFFSET, ProbeContext_cpu_d2_offset_matches_ctiMasmProbeTrampoline); 166 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d3) == PROBE_CPU_D3_OFFSET, ProbeContext_cpu_d3_offset_matches_ctiMasmProbeTrampoline); 167 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d4) == PROBE_CPU_D4_OFFSET, ProbeContext_cpu_d4_offset_matches_ctiMasmProbeTrampoline); 168 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d5) == PROBE_CPU_D5_OFFSET, ProbeContext_cpu_d5_offset_matches_ctiMasmProbeTrampoline); 169 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d6) == PROBE_CPU_D6_OFFSET, ProbeContext_cpu_d6_offset_matches_ctiMasmProbeTrampoline); 170 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d7) == PROBE_CPU_D7_OFFSET, ProbeContext_cpu_d7_offset_matches_ctiMasmProbeTrampoline); 171 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d8) == PROBE_CPU_D8_OFFSET, ProbeContext_cpu_d8_offset_matches_ctiMasmProbeTrampoline); 172 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d9) == PROBE_CPU_D9_OFFSET, ProbeContext_cpu_d9_offset_matches_ctiMasmProbeTrampoline); 173 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d10) == PROBE_CPU_D10_OFFSET, ProbeContext_cpu_d10_offset_matches_ctiMasmProbeTrampoline); 174 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d11) == PROBE_CPU_D11_OFFSET, ProbeContext_cpu_d11_offset_matches_ctiMasmProbeTrampoline); 175 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d12) == PROBE_CPU_D12_OFFSET, ProbeContext_cpu_d12_offset_matches_ctiMasmProbeTrampoline); 176 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d13) == PROBE_CPU_D13_OFFSET, ProbeContext_cpu_d13_offset_matches_ctiMasmProbeTrampoline); 177 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d14) == PROBE_CPU_D14_OFFSET, ProbeContext_cpu_d14_offset_matches_ctiMasmProbeTrampoline); 178 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d15) == PROBE_CPU_D15_OFFSET, ProbeContext_cpu_d15_offset_matches_ctiMasmProbeTrampoline); 179 180 #if CPU(APPLE_ARMV7S) 181 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d16) == PROBE_CPU_D16_OFFSET, ProbeContext_cpu_d16_offset_matches_ctiMasmProbeTrampoline); 182 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d17) == PROBE_CPU_D17_OFFSET, ProbeContext_cpu_d17_offset_matches_ctiMasmProbeTrampoline); 183 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d18) == PROBE_CPU_D18_OFFSET, ProbeContext_cpu_d18_offset_matches_ctiMasmProbeTrampoline); 184 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d19) == PROBE_CPU_D19_OFFSET, ProbeContext_cpu_d19_offset_matches_ctiMasmProbeTrampoline); 185 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d20) == PROBE_CPU_D20_OFFSET, ProbeContext_cpu_d20_offset_matches_ctiMasmProbeTrampoline); 186 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d21) == PROBE_CPU_D21_OFFSET, ProbeContext_cpu_d21_offset_matches_ctiMasmProbeTrampoline); 187 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d22) == PROBE_CPU_D22_OFFSET, ProbeContext_cpu_d22_offset_matches_ctiMasmProbeTrampoline); 188 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d23) == PROBE_CPU_D23_OFFSET, ProbeContext_cpu_d23_offset_matches_ctiMasmProbeTrampoline); 189 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d24) == PROBE_CPU_D24_OFFSET, ProbeContext_cpu_d24_offset_matches_ctiMasmProbeTrampoline); 190 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d25) == PROBE_CPU_D25_OFFSET, ProbeContext_cpu_d25_offset_matches_ctiMasmProbeTrampoline); 191 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d26) == PROBE_CPU_D26_OFFSET, ProbeContext_cpu_d26_offset_matches_ctiMasmProbeTrampoline); 192 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d27) == PROBE_CPU_D27_OFFSET, ProbeContext_cpu_d27_offset_matches_ctiMasmProbeTrampoline); 193 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d28) == PROBE_CPU_D28_OFFSET, ProbeContext_cpu_d28_offset_matches_ctiMasmProbeTrampoline); 194 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d29) == PROBE_CPU_D29_OFFSET, ProbeContext_cpu_d29_offset_matches_ctiMasmProbeTrampoline); 195 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d30) == PROBE_CPU_D30_OFFSET, ProbeContext_cpu_d30_offset_matches_ctiMasmProbeTrampoline); 196 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d31) == PROBE_CPU_D31_OFFSET, ProbeContext_cpu_d31_offset_matches_ctiMasmProbeTrampoline); 197 #endif // CPU(APPLE_ARMV7S) 198 199 COMPILE_ASSERT(sizeof(MacroAssembler::ProbeContext) == PROBE_SIZE, ProbeContext_size_matches_ctiMasmProbeTrampoline); 200 201 #undef PROBE_OFFSETOF 202 203 #endif // USE(MASM_PROBE) 204 58 205 59 206 asm ( … … 142 289 ); 143 290 291 #if USE(MASM_PROBE) 292 asm ( 293 ".text" "\n" 294 ".align 2" "\n" 295 ".globl " SYMBOL_STRING(ctiMasmProbeTrampoline) "\n" 296 HIDE_SYMBOL(ctiMasmProbeTrampoline) "\n" 297 ".thumb" "\n" 298 ".thumb_func " THUMB_FUNC_PARAM(ctiMasmProbeTrampoline) "\n" 299 SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n" 300 301 // MacroAssembler::probe() has already generated code to store some values. 302 // The top of stack now looks like this: 303 // esp[0 * ptrSize]: probeFunction 304 // esp[1 * ptrSize]: arg1 305 // esp[2 * ptrSize]: arg2 306 // esp[3 * ptrSize]: saved r0 307 // esp[4 * ptrSize]: saved ip 308 // esp[5 * ptrSize]: saved lr 309 // esp[6 * ptrSize]: saved sp 310 311 "mov ip, sp" "\n" 312 "mov r0, sp" "\n" 313 "sub r0, r0, #" STRINGIZE_VALUE_OF(PROBE_SIZE) "\n" 314 315 // The ARM EABI specifies that the stack needs to be 16 byte aligned. 316 "bic r0, r0, #0xf" "\n" 317 "mov sp, r0" "\n" 318 319 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_PC_OFFSET) "]" "\n" 320 "add lr, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_R1_OFFSET) "\n" 321 "stmia lr, { r1-r11 }" "\n" 322 "mrs lr, APSR" "\n" 323 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_APSR_OFFSET) "]" "\n" 324 "vmrs lr, FPSCR" "\n" 325 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_FPSCR_OFFSET) "]" "\n" 326 327 "ldr lr, [ip, #0 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n" 328 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_PROBE_FUNCTION_OFFSET) "]" "\n" 329 "ldr lr, [ip, #1 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n" 330 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_ARG1_OFFSET) "]" "\n" 331 "ldr lr, [ip, #2 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n" 332 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_ARG2_OFFSET) "]" "\n" 333 "ldr lr, [ip, #3 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n" 334 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_R0_OFFSET) "]" "\n" 335 "ldr lr, [ip, #4 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n" 336 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_IP_OFFSET) "]" "\n" 337 "ldr lr, [ip, #5 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n" 338 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_LR_OFFSET) "]" "\n" 339 "ldr lr, [ip, #6 * " STRINGIZE_VALUE_OF(PTR_SIZE) "]" "\n" 340 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n" 341 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_JIT_STACK_FRAME_OFFSET) "]" "\n" 342 343 "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_PC_OFFSET) "]" "\n" 344 345 "add ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_D0_OFFSET) "\n" 346 #if CPU(APPLE_ARMV7S) 347 "vstmia.64 ip, { d0-d31 }" "\n" 348 #else 349 "vstmia.64 ip, { d0-d15 }" "\n" 350 #endif 351 352 "mov fp, sp" "\n" // Save the ProbeContext*. 353 354 "ldr ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_PROBE_FUNCTION_OFFSET) "]" "\n" 355 "mov r0, sp" "\n" // the ProbeContext* arg. 356 "blx ip" "\n" 357 358 "mov sp, fp" "\n" 359 360 // To enable probes to modify register state, we copy all registers 361 // out of the ProbeContext before returning. 362 363 #if CPU(APPLE_ARMV7S) 364 "add ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_D31_OFFSET + FPREG_SIZE) "\n" 365 "vldmdb.64 ip!, { d0-d31 }" "\n" 366 #else 367 "add ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_D15_OFFSET + FPREG_SIZE) "\n" 368 "vldmdb.64 ip!, { d0-d15 }" "\n" 369 #endif 370 "add ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_R11_OFFSET + GPREG_SIZE) "\n" 371 "ldmdb ip, { r0-r11 }" "\n" 372 "ldr ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_FPSCR_OFFSET) "]" "\n" 373 "vmsr FPSCR, ip" "\n" 374 375 // There are 5 more registers left to restore: ip, sp, lr, pc, and apsr. 376 // There are 2 issues that complicate the restoration of these last few 377 // registers: 378 // 379 // 1. Normal ARM calling convention relies on moving lr to pc to return to 380 // the caller. In our case, the address to return to is specified by 381 // ProbeContext.cpu.pc. And at that moment, we won't have any available 382 // scratch registers to hold the return address (lr needs to hold 383 // ProbeContext.cpu.lr, not the return address). 384 // 385 // The solution is to store the return address on the stack and load the 386 // pc from there. 387 // 388 // 2. Issue 1 means we will need to write to the stack location at 389 // ProbeContext.cpu.sp - 4. But if the user probe function had modified 390 // the value of ProbeContext.cpu.sp to point in the range between 391 // &ProbeContext.cpu.ip thru &ProbeContext.cpu.aspr, then the action for 392 // Issue 1 may trash the values to be restored before we can restore 393 // them. 394 // 395 // The solution is to check if ProbeContext.cpu.sp contains a value in 396 // the undesirable range. If so, we copy the remaining ProbeContext 397 // register data to a safe range (at memory lower than where 398 // ProbeContext.cpu.sp points) first, and restore the remaining register 399 // from this new range. 400 401 "add ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_APSR_OFFSET) "\n" 402 "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n" 403 "cmp lr, ip" "\n" 404 "it gt" "\n" 405 "bgt " SYMBOL_STRING(ctiMasmProbeTrampolineEnd) "\n" 406 407 // We get here because the new expected stack pointer location is lower 408 // than where it's supposed to be. This means the safe range of stack 409 // memory where we'll be copying the remaining register restore values to 410 // might be in a region of memory below the sp i.e. unallocated stack 411 // memory. This, in turn, makes it vulnerable to interrupts potentially 412 // trashing the copied values. To prevent that, we must first allocate the 413 // needed stack memory by adjusting the sp before the copying. 414 415 "sub lr, lr, #(6 * " STRINGIZE_VALUE_OF(PTR_SIZE) 416 " + " STRINGIZE_VALUE_OF(PROBE_CPU_IP_OFFSET) ")" "\n" 417 418 "mov ip, sp" "\n" 419 "mov sp, lr" "\n" 420 "mov lr, ip" "\n" 421 422 "ldr ip, [lr, #" STRINGIZE_VALUE_OF(PROBE_CPU_IP_OFFSET) "]" "\n" 423 "str ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_IP_OFFSET) "]" "\n" 424 "ldr ip, [lr, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n" 425 "str ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n" 426 "ldr ip, [lr, #" STRINGIZE_VALUE_OF(PROBE_CPU_LR_OFFSET) "]" "\n" 427 "str ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_LR_OFFSET) "]" "\n" 428 "ldr ip, [lr, #" STRINGIZE_VALUE_OF(PROBE_CPU_PC_OFFSET) "]" "\n" 429 "str ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_PC_OFFSET) "]" "\n" 430 "ldr ip, [lr, #" STRINGIZE_VALUE_OF(PROBE_CPU_APSR_OFFSET) "]" "\n" 431 "str ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_APSR_OFFSET) "]" "\n" 432 433 ".thumb_func " THUMB_FUNC_PARAM(ctiMasmProbeTrampolineEnd) "\n" 434 SYMBOL_STRING(ctiMasmProbeTrampolineEnd) ":" "\n" 435 "ldr ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_PC_OFFSET) "]" "\n" 436 "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n" 437 "sub lr, lr, #" STRINGIZE_VALUE_OF(PTR_SIZE) "\n" 438 "str ip, [lr]" "\n" 439 "str lr, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n" 440 441 "ldr ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_APSR_OFFSET) "]" "\n" 442 "msr APSR, ip" "\n" 443 "ldr ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_LR_OFFSET) "]" "\n" 444 "mov lr, ip" "\n" 445 "ldr ip, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_IP_OFFSET) "]" "\n" 446 "ldr sp, [sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_SP_OFFSET) "]" "\n" 447 448 "pop { pc }" "\n" 449 ); 450 #endif // USE(MASM_PROBE) 451 452 144 453 #define DEFINE_STUB_FUNCTION(rtype, op) \ 145 454 extern "C" { \ -
branches/dfgFourthTier/Source/JavaScriptCore/jit/JITStubsX86.h
r150186 r150844 104 104 SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n" 105 105 106 // MacroAssembler::probe() has already generated code to save/store the 107 // values for eax and esp in the ProbeContext. Save/store the remaining 108 // registers here. 109 110 "popl %eax" "\n" 111 "movl %eax, " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%esp)" "\n" 106 "pushfd" "\n" 107 108 // MacroAssembler::probe() has already generated code to store some values. 109 // Together with the eflags pushed above, the top of stack now looks like 110 // this: 111 // esp[0 * ptrSize]: eflags 112 // esp[1 * ptrSize]: return address / saved eip 113 // esp[2 * ptrSize]: probeFunction 114 // esp[3 * ptrSize]: arg1 115 // esp[4 * ptrSize]: arg2 116 // esp[5 * ptrSize]: saved eax 117 // esp[6 * ptrSize]: saved esp 118 119 "movl %esp, %eax" "\n" 120 "subl $" STRINGIZE_VALUE_OF(PROBE_SIZE) ", %esp" "\n" 121 122 // The X86_64 ABI specifies that the worse case stack alignment requirement 123 // is 32 bytes. 124 "andl $~0x1f, %esp" "\n" 112 125 113 126 "movl %ebp, " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%esp)" "\n" … … 119 132 "movl %esi, " STRINGIZE_VALUE_OF(PROBE_CPU_ESI_OFFSET) "(%ebp)" "\n" 120 133 "movl %edi, " STRINGIZE_VALUE_OF(PROBE_CPU_EDI_OFFSET) "(%ebp)" "\n" 134 135 "movl 0 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%eax), %ecx" "\n" 136 "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_CPU_EFLAGS_OFFSET) "(%ebp)" "\n" 137 "movl 1 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%eax), %ecx" "\n" 138 "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%ebp)" "\n" 139 "movl 2 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%eax), %ecx" "\n" 140 "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_PROBE_FUNCTION_OFFSET) "(%ebp)" "\n" 141 "movl 3 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%eax), %ecx" "\n" 142 "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_ARG1_OFFSET) "(%ebp)" "\n" 143 "movl 4 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%eax), %ecx" "\n" 144 "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_ARG2_OFFSET) "(%ebp)" "\n" 145 "movl 5 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%eax), %ecx" "\n" 146 "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) "(%ebp)" "\n" 147 "movl 6 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%eax), %ecx" "\n" 148 "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%ebp)" "\n" 149 "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_JIT_STACK_FRAME_OFFSET) "(%ebp)" "\n" 121 150 122 151 "movdqa %xmm0, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM0_OFFSET) "(%ebp)" "\n" … … 129 158 "movdqa %xmm7, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%ebp)" "\n" 130 159 131 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%ebp), %eax" "\n"132 "movl %eax, " STRINGIZE_VALUE_OF(PROBE_JIT_STACK_FRAME_OFFSET) "(%ebp)" "\n"133 134 160 // Reserve stack space for the arg while maintaining the required stack 135 161 // pointer 32 byte alignment: … … 139 165 "call *" STRINGIZE_VALUE_OF(PROBE_PROBE_FUNCTION_OFFSET) "(%ebp)" "\n" 140 166 141 // To enable probes to modify register state, we copy all regi esters167 // To enable probes to modify register state, we copy all registers 142 168 // out of the ProbeContext before returning. 143 169 144 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) "(%ebp), %eax" "\n"145 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ECX_OFFSET) "(%ebp), %ecx" "\n"146 170 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EDX_OFFSET) "(%ebp), %edx" "\n" 147 171 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EBX_OFFSET) "(%ebp), %ebx" "\n" 148 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%ebp), %esp" "\n"149 172 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ESI_OFFSET) "(%ebp), %esi" "\n" 150 173 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EDI_OFFSET) "(%ebp), %edi" "\n" … … 159 182 "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%ebp), %xmm7" "\n" 160 183 161 "pushl " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%ebp)" "\n" 162 163 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%ebp), %ebp" "\n" 184 // There are 6 more registers left to restore: 185 // eax, ecx, ebp, esp, eip, and eflags. 186 // We need to handle these last few restores carefully because: 187 // 188 // 1. We need to push the return address on the stack for ret to use. 189 // That means we need to write to the stack. 190 // 2. The user probe function may have altered the restore value of esp to 191 // point to the vicinity of one of the restore values for the remaining 192 // registers left to be restored. 193 // That means, for requirement 1, we may end up writing over some of the 194 // restore values. We can check for this, and first copy the restore 195 // values to a "safe area" on the stack before commencing with the action 196 // for requirement 1. 197 // 3. For requirement 2, we need to ensure that the "safe area" is 198 // protected from interrupt handlers overwriting it. Hence, the esp needs 199 // to be adjusted to include the "safe area" before we start copying the 200 // the restore values. 201 202 "movl %ebp, %eax" "\n" 203 "addl $" STRINGIZE_VALUE_OF(PROBE_CPU_EFLAGS_OFFSET) ", %eax" "\n" 204 "cmpl %eax, " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%ebp)" "\n" 205 "jg " SYMBOL_STRING(ctiMasmProbeTrampolineEnd) "\n" 206 207 // Locate the "safe area" at 2x sizeof(ProbeContext) below where the new 208 // rsp will be. This time we don't have to 32-byte align it because we're 209 // not using to store any xmm regs. 210 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%ebp), %eax" "\n" 211 "subl $2 * " STRINGIZE_VALUE_OF(PROBE_SIZE) ", %eax" "\n" 212 "movl %eax, %esp" "\n" 213 214 "subl $" STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) ", %eax" "\n" 215 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) "(%ebp), %ecx" "\n" 216 "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) "(%eax)" "\n" 217 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ECX_OFFSET) "(%ebp), %ecx" "\n" 218 "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_CPU_ECX_OFFSET) "(%eax)" "\n" 219 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%ebp), %ecx" "\n" 220 "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%eax)" "\n" 221 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%ebp), %ecx" "\n" 222 "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%eax)" "\n" 223 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%ebp), %ecx" "\n" 224 "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%eax)" "\n" 225 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EFLAGS_OFFSET) "(%ebp), %ecx" "\n" 226 "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_CPU_EFLAGS_OFFSET) "(%eax)" "\n" 227 "movl %eax, %ebp" "\n" 228 229 SYMBOL_STRING(ctiMasmProbeTrampolineEnd) ":" "\n" 230 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%ebp), %eax" "\n" 231 "subl $5 * " STRINGIZE_VALUE_OF(PTR_SIZE) ", %eax" "\n" 232 // At this point, %esp should be < %eax. 233 234 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EFLAGS_OFFSET) "(%ebp), %ecx" "\n" 235 "movl %ecx, 0 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%eax)" "\n" 236 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) "(%ebp), %ecx" "\n" 237 "movl %ecx, 1 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%eax)" "\n" 238 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ECX_OFFSET) "(%ebp), %ecx" "\n" 239 "movl %ecx, 2 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%eax)" "\n" 240 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%ebp), %ecx" "\n" 241 "movl %ecx, 3 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%eax)" "\n" 242 "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%ebp), %ecx" "\n" 243 "movl %ecx, 4 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%eax)" "\n" 244 "movl %eax, %esp" "\n" 245 246 "popfd" "\n" 247 "popl %eax" "\n" 248 "popl %ecx" "\n" 249 "popl %ebp" "\n" 164 250 "ret" "\n" 165 251 ); -
branches/dfgFourthTier/Source/JavaScriptCore/jit/JITStubsX86Common.h
r150186 r150844 53 53 54 54 #define PROBE_CPU_EAX_OFFSET (4 * PTR_SIZE) 55 #define PROBE_CPU_E CX_OFFSET (5 * PTR_SIZE)56 #define PROBE_CPU_E DX_OFFSET (6 * PTR_SIZE)57 #define PROBE_CPU_E BX_OFFSET (7 * PTR_SIZE)58 #define PROBE_CPU_ES P_OFFSET (8 * PTR_SIZE)59 #define PROBE_CPU_E BP_OFFSET (9 * PTR_SIZE)60 #define PROBE_CPU_E SI_OFFSET (10 * PTR_SIZE)61 #define PROBE_CPU_E DI_OFFSET (11 * PTR_SIZE)55 #define PROBE_CPU_EBX_OFFSET (5 * PTR_SIZE) 56 #define PROBE_CPU_ECX_OFFSET (6 * PTR_SIZE) 57 #define PROBE_CPU_EDX_OFFSET (7 * PTR_SIZE) 58 #define PROBE_CPU_ESI_OFFSET (8 * PTR_SIZE) 59 #define PROBE_CPU_EDI_OFFSET (9 * PTR_SIZE) 60 #define PROBE_CPU_EBP_OFFSET (10 * PTR_SIZE) 61 #define PROBE_CPU_ESP_OFFSET (11 * PTR_SIZE) 62 62 63 63 #if CPU(X86) 64 #define PROBE_CPU_EIP_OFFSET (12 * PTR_SIZE) 65 #define PROBE_FIRST_XMM_OFFSET (16 * PTR_SIZE) // After padding. 64 #define PROBE_FIRST_SPECIAL_OFFSET (12 * PTR_SIZE) 66 65 #else // CPU(X86_64) 67 66 #define PROBE_CPU_R8_OFFSET (12 * PTR_SIZE) … … 73 72 #define PROBE_CPU_R14_OFFSET (18 * PTR_SIZE) 74 73 #define PROBE_CPU_R15_OFFSET (19 * PTR_SIZE) 75 #define PROBE_CPU_EIP_OFFSET (20 * PTR_SIZE) 76 #define PROBE_FIRST_XMM_OFFSET (22 * PTR_SIZE) // After padding. 74 #define PROBE_FIRST_SPECIAL_OFFSET (20 * PTR_SIZE) 75 #endif // CPU(X86_64) 76 77 #define PROBE_CPU_EIP_OFFSET (PROBE_FIRST_SPECIAL_OFFSET + (0 * PTR_SIZE)) 78 #define PROBE_CPU_EFLAGS_OFFSET (PROBE_FIRST_SPECIAL_OFFSET + (1 * PTR_SIZE)) 79 80 #if CPU(X86) 81 #define PROBE_FIRST_XMM_OFFSET (PROBE_FIRST_SPECIAL_OFFSET + (4 * PTR_SIZE)) // After padding. 82 #else // CPU(X86_64) 83 #define PROBE_FIRST_XMM_OFFSET (PROBE_FIRST_SPECIAL_OFFSET + (2 * PTR_SIZE)) // After padding. 77 84 #endif // CPU(X86_64) 78 85 … … 87 94 #define PROBE_CPU_XMM7_OFFSET (PROBE_FIRST_XMM_OFFSET + (7 * XMM_SIZE)) 88 95 96 #define PROBE_SIZE (PROBE_CPU_XMM7_OFFSET + XMM_SIZE) 89 97 90 98 // These ASSERTs remind you that if you change the layout of ProbeContext, … … 104 112 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.esi) == PROBE_CPU_ESI_OFFSET, ProbeContext_cpu_esi_offset_matches_ctiMasmProbeTrampoline); 105 113 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.edi) == PROBE_CPU_EDI_OFFSET, ProbeContext_cpu_edi_offset_matches_ctiMasmProbeTrampoline); 114 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.eip) == PROBE_CPU_EIP_OFFSET, ProbeContext_cpu_eip_offset_matches_ctiMasmProbeTrampoline); 115 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.eflags) == PROBE_CPU_EFLAGS_OFFSET, ProbeContext_cpu_eflags_offset_matches_ctiMasmProbeTrampoline); 106 116 107 117 #if CPU(X86_64) … … 116 126 #endif // CPU(X86_64) 117 127 118 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.eip) == PROBE_CPU_EIP_OFFSET, ProbeContext_cpu_eip_offset_matches_ctiMasmProbeTrampoline);119 120 128 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm0) == PROBE_CPU_XMM0_OFFSET, ProbeContext_cpu_xmm0_offset_matches_ctiMasmProbeTrampoline); 121 129 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm1) == PROBE_CPU_XMM1_OFFSET, ProbeContext_cpu_xmm1_offset_matches_ctiMasmProbeTrampoline); … … 126 134 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm6) == PROBE_CPU_XMM6_OFFSET, ProbeContext_cpu_xmm6_offset_matches_ctiMasmProbeTrampoline); 127 135 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm7) == PROBE_CPU_XMM7_OFFSET, ProbeContext_cpu_xmm7_offset_matches_ctiMasmProbeTrampoline); 136 137 COMPILE_ASSERT(sizeof(MacroAssembler::ProbeContext) == PROBE_SIZE, ProbeContext_size_matches_ctiMasmProbeTrampoline); 128 138 129 139 // Also double check that the xmm registers are 16 byte (128-bit) aligned as -
branches/dfgFourthTier/Source/JavaScriptCore/jit/JITStubsX86_64.h
r150186 r150844 119 119 SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n" 120 120 121 // MacroAssembler::probe() has already generated code to save/store the 122 // values for rax and rsp in the ProbeContext. Save/store the remaining 123 // registers here. 124 125 "popq %rax" "\n" 126 "movq %rax, " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%rsp)" "\n" 121 "pushfq" "\n" 122 123 // MacroAssembler::probe() has already generated code to store some values. 124 // Together with the rflags pushed above, the top of stack now looks like 125 // this: 126 // esp[0 * ptrSize]: rflags 127 // esp[1 * ptrSize]: return address / saved rip 128 // esp[2 * ptrSize]: probeFunction 129 // esp[3 * ptrSize]: arg1 130 // esp[4 * ptrSize]: arg2 131 // esp[5 * ptrSize]: saved rax 132 // esp[6 * ptrSize]: saved rsp 133 134 "movq %rsp, %rax" "\n" 135 "subq $" STRINGIZE_VALUE_OF(PROBE_SIZE) ", %rsp" "\n" 136 137 // The X86_64 ABI specifies that the worse case stack alignment requirement 138 // is 32 bytes. 139 "andq $~0x1f, %rsp" "\n" 127 140 128 141 "movq %rbp, " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%rsp)" "\n" … … 134 147 "movq %rsi, " STRINGIZE_VALUE_OF(PROBE_CPU_ESI_OFFSET) "(%rbp)" "\n" 135 148 "movq %rdi, " STRINGIZE_VALUE_OF(PROBE_CPU_EDI_OFFSET) "(%rbp)" "\n" 149 150 "movq 0 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%rax), %rcx" "\n" 151 "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_CPU_EFLAGS_OFFSET) "(%rbp)" "\n" 152 "movq 1 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%rax), %rcx" "\n" 153 "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%rbp)" "\n" 154 "movq 2 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%rax), %rcx" "\n" 155 "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_PROBE_FUNCTION_OFFSET) "(%rbp)" "\n" 156 "movq 3 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%rax), %rcx" "\n" 157 "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_ARG1_OFFSET) "(%rbp)" "\n" 158 "movq 4 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%rax), %rcx" "\n" 159 "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_ARG2_OFFSET) "(%rbp)" "\n" 160 "movq 5 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%rax), %rcx" "\n" 161 "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) "(%rbp)" "\n" 162 "movq 6 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%rax), %rcx" "\n" 163 "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%rbp)" "\n" 164 "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_JIT_STACK_FRAME_OFFSET) "(%rbp)" "\n" 136 165 137 166 "movq %r8, " STRINGIZE_VALUE_OF(PROBE_CPU_R8_OFFSET) "(%rbp)" "\n" … … 153 182 "movdqa %xmm7, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%rbp)" "\n" 154 183 155 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%rbp), %rax" "\n"156 "movq %rax, " STRINGIZE_VALUE_OF(PROBE_JIT_STACK_FRAME_OFFSET) "(%rbp)" "\n"157 158 184 "movq %rbp, %rdi" "\n" // the ProbeContext* arg. 159 185 "call *" STRINGIZE_VALUE_OF(PROBE_PROBE_FUNCTION_OFFSET) "(%rbp)" "\n" 160 186 161 // To enable probes to modify register state, we copy all regi esters187 // To enable probes to modify register state, we copy all registers 162 188 // out of the ProbeContext before returning. 163 189 164 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) "(%rbp), %rax" "\n"165 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ECX_OFFSET) "(%rbp), %rcx" "\n"166 190 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EDX_OFFSET) "(%rbp), %rdx" "\n" 167 191 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EBX_OFFSET) "(%rbp), %rbx" "\n" 168 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%rbp), %rsp" "\n"169 192 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ESI_OFFSET) "(%rbp), %rsi" "\n" 170 193 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EDI_OFFSET) "(%rbp), %rdi" "\n" … … 188 211 "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%rbp), %xmm7" "\n" 189 212 190 "pushq " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%rbp)" "\n" 191 192 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%rbp), %rbp" "\n" 213 // There are 6 more registers left to restore: 214 // rax, rcx, rbp, rsp, rip, and rflags. 215 // We need to handle these last few restores carefully because: 216 // 217 // 1. We need to push the return address on the stack for ret to use 218 // That means we need to write to the stack. 219 // 2. The user probe function may have altered the restore value of esp to 220 // point to the vicinity of one of the restore values for the remaining 221 // registers left to be restored. 222 // That means, for requirement 1, we may end up writing over some of the 223 // restore values. We can check for this, and first copy the restore 224 // values to a "safe area" on the stack before commencing with the action 225 // for requirement 1. 226 // 3. For both requirement 2, we need to ensure that the "safe area" is 227 // protected from interrupt handlers overwriting it. Hence, the esp needs 228 // to be adjusted to include the "safe area" before we start copying the 229 // the restore values. 230 231 "movq %rbp, %rax" "\n" 232 "addq $" STRINGIZE_VALUE_OF(PROBE_CPU_EFLAGS_OFFSET) ", %rax" "\n" 233 "cmpq %rax, " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%rbp)" "\n" 234 "jg " SYMBOL_STRING(ctiMasmProbeTrampolineEnd) "\n" 235 236 // Locate the "safe area" at 2x sizeof(ProbeContext) below where the new 237 // rsp will be. This time we don't have to 32-byte align it because we're 238 // not using to store any xmm regs. 239 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%rbp), %rax" "\n" 240 "subq $2 * " STRINGIZE_VALUE_OF(PROBE_SIZE) ", %rax" "\n" 241 "movq %rax, %rsp" "\n" 242 243 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) "(%rbp), %rcx" "\n" 244 "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) "(%rax)" "\n" 245 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ECX_OFFSET) "(%rbp), %rcx" "\n" 246 "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_CPU_ECX_OFFSET) "(%rax)" "\n" 247 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%rbp), %rcx" "\n" 248 "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%rax)" "\n" 249 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%rbp), %rcx" "\n" 250 "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%rax)" "\n" 251 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%rbp), %rcx" "\n" 252 "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%rax)" "\n" 253 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EFLAGS_OFFSET) "(%rbp), %rcx" "\n" 254 "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_CPU_EFLAGS_OFFSET) "(%rax)" "\n" 255 "movq %rax, %rbp" "\n" 256 257 SYMBOL_STRING(ctiMasmProbeTrampolineEnd) ":" "\n" 258 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%rbp), %rax" "\n" 259 "subq $5 * " STRINGIZE_VALUE_OF(PTR_SIZE) ", %rax" "\n" 260 // At this point, %rsp should be < %rax. 261 262 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EFLAGS_OFFSET) "(%rbp), %rcx" "\n" 263 "movq %rcx, 0 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%rax)" "\n" 264 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) "(%rbp), %rcx" "\n" 265 "movq %rcx, 1 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%rax)" "\n" 266 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ECX_OFFSET) "(%rbp), %rcx" "\n" 267 "movq %rcx, 2 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%rax)" "\n" 268 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%rbp), %rcx" "\n" 269 "movq %rcx, 3 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%rax)" "\n" 270 "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%rbp), %rcx" "\n" 271 "movq %rcx, 4 * " STRINGIZE_VALUE_OF(PTR_SIZE) "(%rax)" "\n" 272 "movq %rax, %rsp" "\n" 273 274 "popfq" "\n" 275 "popq %rax" "\n" 276 "popq %rcx" "\n" 277 "popq %rbp" "\n" 193 278 "ret" "\n" 194 279 );
Note: See TracChangeset
for help on using the changeset viewer.