Changeset 150844 in webkit


Ignore:
Timestamp:
May 28, 2013 3:26:24 PM (11 years ago)
Author:
mark.lam@apple.com
Message:

Misc JIT probe enhacements.
https://bugs.webkit.org/show_bug.cgi?id=116586.

Reviewed by Michael Saboff.

  1. Added JIT probe support for ARMv7 and traditional ARM. Built and tested on ARMv7. ARM version not tested nor built.
  2. Fix the following bugs in the X86 and X86_64 probes:
    1. Cannot assume that the stack pointer is already aligned when we push args for the probe. Instead, we ensure the stack alignment at runtime when we set up the probe call. This is now done in the ctiMasmProbeTrampoline.
    2. On return, the user probe function may have altered the stack pointer value to be restored. Previously, if the sp restore value points to some of the other register restore values in the ProbeContext record, we will fail to return from the probe having those user specified value as we're expected to do. This is now fixed.
  3. Rearranged the X86/X86_64 registers order to organize them like gdb expects on X86_64.
  4. We also now preserve the condition code registers.
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • assembler/ARMAssembler.h:
  • assembler/ARMv7Assembler.h:

(ARMRegisters):

  • assembler/MacroAssemblerARM.cpp:

(JSC::isVFPPresent):
(JSC::MacroAssemblerARM::ProbeContext::dumpCPURegisters):
(JSC::MacroAssemblerARM::ProbeContext::dump):
(JSC::MacroAssemblerARM::probe):

  • assembler/MacroAssemblerARM.h:

(MacroAssemblerARM):
(CPUState):
(ProbeContext):
(JSC::MacroAssemblerARM::trustedImm32FromPtr):

  • assembler/MacroAssemblerARMv7.h:

(MacroAssemblerARMv7):
(CPUState):
(ProbeContext):
(JSC::MacroAssemblerARMv7::trustedImm32FromPtr):

  • assembler/MacroAssemblerX86.h:

(MacroAssemblerX86):
(JSC::MacroAssemblerX86::probe):

  • assembler/MacroAssemblerX86Common.cpp:

(JSC::MacroAssemblerX86Common::ProbeContext::dumpCPURegisters):

  • assembler/MacroAssemblerX86_64.h:

(JSC::MacroAssemblerX86_64::probe):

  • assembler/X86Assembler.h:
  • config.h:
  • jit/JITStubsARM.h:
  • jit/JITStubsARMv7.h:
  • jit/JITStubsX86.h:
  • jit/JITStubsX86Common.h:
  • jit/JITStubsX86_64.h:
Location:
branches/dfgFourthTier/Source/JavaScriptCore
Files:
1 added
16 edited

Legend:

Unmodified
Added
Removed
  • branches/dfgFourthTier/Source/JavaScriptCore/ChangeLog

    r150839 r150844  
     12013-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
    1592013-05-28  Filip Pizlo  <fpizlo@apple.com>
    260
     
    14671525
    14681526        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.
    14691531
    14701532        The probe is in the form of a MacroAssembler pseudo instruction.
  • branches/dfgFourthTier/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r150807 r150844  
    960960                FECE74571745456500FF9300 /* MacroAssemblerX86Common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECE74561745456500FF9300 /* MacroAssemblerX86Common.cpp */; };
    961961                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 */; };
    962963                FEF6835E174343CC00A32E25 /* JITStubsARM.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF6835A174343CC00A32E25 /* JITStubsARM.h */; settings = {ATTRIBUTES = (Private, ); }; };
    963964                FEF6835F174343CC00A32E25 /* JITStubsARMv7.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF6835B174343CC00A32E25 /* JITStubsARMv7.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    19941995                FECE74561745456500FF9300 /* MacroAssemblerX86Common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssemblerX86Common.cpp; sourceTree = "<group>"; };
    19951996                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>"; };
    19961998                FEF6835A174343CC00A32E25 /* JITStubsARM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubsARM.h; sourceTree = "<group>"; };
    19971999                FEF6835B174343CC00A32E25 /* JITStubsARMv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubsARMv7.h; sourceTree = "<group>"; };
     
    31233125                                86C568DD11A213EE0007F7F0 /* MacroAssemblerARM.cpp */,
    31243126                                86D3B2C210156BDE002865E7 /* MacroAssemblerARM.h */,
     3127                                FEE3147C174AACAF0013BCAC /* MacroAssemblerARMv7.cpp */,
    31253128                                86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */,
    31263129                                863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */,
     
    44324435                                0FF42745158EBE91004CB9FF /* udis86_syn-att.c in Sources */,
    44334436                                0FF42746158EBE91004CB9FF /* udis86_syn-intel.c in Sources */,
     4437                                FEE3147D174AACAF0013BCAC /* MacroAssemblerARMv7.cpp in Sources */,
    44344438                                0FF42747158EBE91004CB9FF /* udis86_syn.c in Sources */,
    44354439                                0FF42732158EBD58004CB9FF /* UDis86Disassembler.cpp in Sources */,
  • branches/dfgFourthTier/Source/JavaScriptCore/assembler/ARMAssembler.h

    r148697 r150844  
    5151            r10,
    5252            r11,
    53             r12, S1 = r12,
     53            r12, ip = r12, S1 = r12,
    5454            r13, sp = r13,
    5555            r14, lr = r14,
     
    9292        } FPRegisterID;
    9393
     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)
    94140    } // namespace ARMRegisters
    95141
  • branches/dfgFourthTier/Source/JavaScriptCore/assembler/ARMv7Assembler.h

    r149649 r150844  
    173173        return (FPDoubleRegisterID)(reg >> 1);
    174174    }
     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)
    175246}
    176247
  • branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerARM.cpp

    r125541 r150844  
    11/*
     2 * Copyright (C) 2013 Apple Inc.
    23 * Copyright (C) 2009 University of Szeged
    34 * All rights reserved.
     
    3132#include "MacroAssemblerARM.h"
    3233
     34#if USE(MASM_PROBE)
     35#include <wtf/StdLibExtras.h>
     36#endif
     37
    3338#if OS(LINUX)
    3439#include <sys/types.h>
     
    5661        close(fd);
    5762    }
    58 #endif
     63#endif // OS(LINUX)
    5964
    6065#if (COMPILER(RVCT) && defined(__TARGET_FPU_VFP)) || (COMPILER(GCC) && defined(__VFP_FP__))
     
    9398    m_assembler.orr(dest, dest, m_assembler.lsl(ARMRegisters::S0, 16));
    9499}
    95 #endif
     100#endif // CPU(ARMV5_OR_LOWER)
     101
     102#if USE(MASM_PROBE)
     103
     104void 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
     124void 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
     143extern "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
     149void 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);
    96162
    97163}
     164#endif // USE(MASM_PROBE)
     165
     166} // namespace JSC
    98167
    99168#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
  • branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerARM.h

    r146195 r150844  
    11/*
    2  * Copyright (C) 2008 Apple Inc.
     2 * Copyright (C) 2008, 2013 Apple Inc.
    33 * Copyright (C) 2009, 2010 University of Szeged
    44 * All rights reserved.
     
    3636namespace JSC {
    3737
     38struct JITStackFrame;
     39
    3840class MacroAssemblerARM : public AbstractMacroAssembler<ARMAssembler> {
    3941    static const int DoubleConditionMask = 0x0f;
     
    13261328    }
    13271329
     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
    13281357protected:
    13291358    ARMAssembler::Condition ARMCondition(RelationalCondition cond)
     
    13811410    }
    13821411
     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
    13831429    static const bool s_isVFPPresent;
    13841430};
  • branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h

    r149649 r150844  
    3535namespace JSC {
    3636
     37struct JITStackFrame;
     38
    3739class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> {
    3840    // FIXME: switch dataTempRegister & addressTempRegister, or possibly use r7?
     
    17901792    }
    17911793
     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
    17921821protected:
    17931822    ALWAYS_INLINE Jump jump()
     
    19001929    }
    19011930
     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
    19021948    bool m_makeJumpPatchable;
    19031949};
  • branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerX86.h

    r150186 r150844  
    293293
    294294#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.
    311296    void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
    312297#endif // USE(MASM_PROBE)
     
    353338extern "C" void ctiMasmProbeTrampoline();
    354339
    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.
    379343
    380344inline void MacroAssemblerX86::probe(MacroAssemblerX86::ProbeFunction function, void* arg1, void* arg2)
    381345{
    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));
    399351
    400352    move(trustedImm32FromPtr(ctiMasmProbeTrampoline), RegisterID::eax);
    401353    call(RegisterID::eax);
    402 
    403     #undef probeContextField
    404354}
    405355#endif // USE(MASM_PROBE)
  • branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp

    r150186 r150844  
    2525
    2626#include "config.h"
     27
     28#if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64))
    2729#include "MacroAssemblerX86Common.h"
    2830
     
    3638    #define DUMP_GPREGISTER(_type, _regName) { \
    3739        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) ; \
    3941    }
    4042#elif CPU(X86_64)
    4143    #define DUMP_GPREGISTER(_type, _regName) { \
    4244        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) ; \
    4446    }
    4547#endif
    4648    FOR_EACH_CPU_GPREGISTER(DUMP_GPREGISTER)
     49    FOR_EACH_CPU_SPECIAL_REGISTER(DUMP_GPREGISTER)
    4750    #undef DUMP_GPREGISTER
    4851
     
    5053        uint32_t* u = reinterpret_cast<uint32_t*>(&cpu._regName); \
    5154        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", \
    5356            indentation, #_regName, u[3], u[2], u[1], u[0], d[1], d[0]); \
    5457    }
     
    7881
    7982} // namespace JSC
     83
     84#endif // ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64))
  • branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h

    r150186 r150844  
    688688// passed to the user probe function.
    689689//
    690 // Hence, we do only the minimum here to preserve the rax (to be used as a
    691 // scratch register) and rsp registers, and pass the probe arguments. We'll let
    692 // the ctiMasmProbeTrampoline handle the rest of the probe invocation work
    693 // i.e. saving the CPUState (and setting up the ProbeContext), calling the user
    694 // probe function, and restoring the CPUState before returning to JIT generated
    695 // 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.
    696696//
    697697// What values are in the saved registers?
     
    702702// probe.
    703703//
    704 // Specifcally, the saved rsp will point to the stack position before we
    705 // push the ProbeContext frame. The saved rip will point to the address of
    706 // 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.
    707707
    708708inline void MacroAssemblerX86_64::probe(MacroAssemblerX86_64::ProbeFunction function, void* arg1, void* arg2)
    709709{
    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);
    728718    move(trustedImm64FromPtr(ctiMasmProbeTrampoline), RegisterID::eax);
    729719    call(RegisterID::eax);
    730 
    731     #undef probeContextField
    732720}
    733721#endif // USE(MASM_PROBE)
  • branches/dfgFourthTier/Source/JavaScriptCore/assembler/X86Assembler.h

    r150186 r150844  
    8080    #define FOR_EACH_CPU_REGISTER(V) \
    8181        FOR_EACH_CPU_GPREGISTER(V) \
     82        FOR_EACH_CPU_SPECIAL_REGISTER(V) \
    8283        FOR_EACH_CPU_FPREGISTER(V)
    8384
    8485    #define FOR_EACH_CPU_GPREGISTER(V) \
    8586        V(void*, eax) \
     87        V(void*, ebx) \
    8688        V(void*, ecx) \
    8789        V(void*, edx) \
    88         V(void*, ebx) \
    89         V(void*, esp) \
    90         V(void*, ebp) \
    9190        V(void*, esi) \
    9291        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) \
    9599
    96100    #define FOR_EACH_CPU_FPREGISTER(V) \
  • branches/dfgFourthTier/Source/JavaScriptCore/jit/JITStubsARM.h

    r150109 r150844  
    4747#define PRESERVEDR4_OFFSET          68
    4848
    49 
    5049#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)
     109COMPILE_ASSERT(PROBE_OFFSETOF(probeFunction) == PROBE_PROBE_FUNCTION_OFFSET, ProbeContext_probeFunction_offset_matches_ctiMasmProbeTrampoline);
     110COMPILE_ASSERT(PROBE_OFFSETOF(arg1) == PROBE_ARG1_OFFSET, ProbeContext_arg1_offset_matches_ctiMasmProbeTrampoline);
     111COMPILE_ASSERT(PROBE_OFFSETOF(arg2) == PROBE_ARG2_OFFSET, ProbeContext_arg2_offset_matches_ctiMasmProbeTrampoline);
     112COMPILE_ASSERT(PROBE_OFFSETOF(jitStackFrame) == PROBE_JIT_STACK_FRAME_OFFSET, ProbeContext_jitStackFrame_offset_matches_ctiMasmProbeTrampoline);
     113
     114COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r0) == PROBE_CPU_R0_OFFSET, ProbeContext_cpu_r0_offset_matches_ctiMasmProbeTrampoline);
     115COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r1) == PROBE_CPU_R1_OFFSET, ProbeContext_cpu_r1_offset_matches_ctiMasmProbeTrampoline);
     116COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r2) == PROBE_CPU_R2_OFFSET, ProbeContext_cpu_r2_offset_matches_ctiMasmProbeTrampoline);
     117COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r3) == PROBE_CPU_R3_OFFSET, ProbeContext_cpu_r3_offset_matches_ctiMasmProbeTrampoline);
     118COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r4) == PROBE_CPU_R4_OFFSET, ProbeContext_cpu_r4_offset_matches_ctiMasmProbeTrampoline);
     119COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r5) == PROBE_CPU_R5_OFFSET, ProbeContext_cpu_r5_offset_matches_ctiMasmProbeTrampoline);
     120COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r6) == PROBE_CPU_R6_OFFSET, ProbeContext_cpu_r6_offset_matches_ctiMasmProbeTrampoline);
     121COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r7) == PROBE_CPU_R7_OFFSET, ProbeContext_cpu_r70_offset_matches_ctiMasmProbeTrampoline);
     122COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r8) == PROBE_CPU_R8_OFFSET, ProbeContext_cpu_r8_offset_matches_ctiMasmProbeTrampoline);
     123COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r9) == PROBE_CPU_R9_OFFSET, ProbeContext_cpu_r9_offset_matches_ctiMasmProbeTrampoline);
     124COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r10) == PROBE_CPU_R10_OFFSET, ProbeContext_cpu_r10_offset_matches_ctiMasmProbeTrampoline);
     125COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r11) == PROBE_CPU_R11_OFFSET, ProbeContext_cpu_r11_offset_matches_ctiMasmProbeTrampoline);
     126COMPILE_ASSERT(PROBE_OFFSETOF(cpu.ip) == PROBE_CPU_IP_OFFSET, ProbeContext_cpu_ip_offset_matches_ctiMasmProbeTrampoline);
     127COMPILE_ASSERT(PROBE_OFFSETOF(cpu.sp) == PROBE_CPU_SP_OFFSET, ProbeContext_cpu_sp_offset_matches_ctiMasmProbeTrampoline);
     128COMPILE_ASSERT(PROBE_OFFSETOF(cpu.lr) == PROBE_CPU_LR_OFFSET, ProbeContext_cpu_lr_offset_matches_ctiMasmProbeTrampoline);
     129COMPILE_ASSERT(PROBE_OFFSETOF(cpu.pc) == PROBE_CPU_PC_OFFSET, ProbeContext_cpu_pc_offset_matches_ctiMasmProbeTrampoline);
     130
     131COMPILE_ASSERT(PROBE_OFFSETOF(cpu.apsr) == PROBE_CPU_APSR_OFFSET, ProbeContext_cpu_apsr_offset_matches_ctiMasmProbeTrampoline);
     132COMPILE_ASSERT(PROBE_OFFSETOF(cpu.fpscr) == PROBE_CPU_FPSCR_OFFSET, ProbeContext_cpu_fpscr_offset_matches_ctiMasmProbeTrampoline);
     133
     134COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d0) == PROBE_CPU_D0_OFFSET, ProbeContext_cpu_d0_offset_matches_ctiMasmProbeTrampoline);
     135COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d1) == PROBE_CPU_D1_OFFSET, ProbeContext_cpu_d1_offset_matches_ctiMasmProbeTrampoline);
     136COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d2) == PROBE_CPU_D2_OFFSET, ProbeContext_cpu_d2_offset_matches_ctiMasmProbeTrampoline);
     137COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d3) == PROBE_CPU_D3_OFFSET, ProbeContext_cpu_d3_offset_matches_ctiMasmProbeTrampoline);
     138COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d4) == PROBE_CPU_D4_OFFSET, ProbeContext_cpu_d4_offset_matches_ctiMasmProbeTrampoline);
     139COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d5) == PROBE_CPU_D5_OFFSET, ProbeContext_cpu_d5_offset_matches_ctiMasmProbeTrampoline);
     140COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d6) == PROBE_CPU_D6_OFFSET, ProbeContext_cpu_d6_offset_matches_ctiMasmProbeTrampoline);
     141COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d7) == PROBE_CPU_D7_OFFSET, ProbeContext_cpu_d7_offset_matches_ctiMasmProbeTrampoline);
     142COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d8) == PROBE_CPU_D8_OFFSET, ProbeContext_cpu_d8_offset_matches_ctiMasmProbeTrampoline);
     143COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d9) == PROBE_CPU_D9_OFFSET, ProbeContext_cpu_d9_offset_matches_ctiMasmProbeTrampoline);
     144COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d10) == PROBE_CPU_D10_OFFSET, ProbeContext_cpu_d10_offset_matches_ctiMasmProbeTrampoline);
     145COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d11) == PROBE_CPU_D11_OFFSET, ProbeContext_cpu_d11_offset_matches_ctiMasmProbeTrampoline);
     146COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d12) == PROBE_CPU_D12_OFFSET, ProbeContext_cpu_d12_offset_matches_ctiMasmProbeTrampoline);
     147COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d13) == PROBE_CPU_D13_OFFSET, ProbeContext_cpu_d13_offset_matches_ctiMasmProbeTrampoline);
     148COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d14) == PROBE_CPU_D14_OFFSET, ProbeContext_cpu_d14_offset_matches_ctiMasmProbeTrampoline);
     149COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d15) == PROBE_CPU_D15_OFFSET, ProbeContext_cpu_d15_offset_matches_ctiMasmProbeTrampoline);
     150COMPILE_ASSERT(sizeof(MacroAssembler::ProbeContext) == PROBE_SIZE, ProbeContext_size_matches_ctiMasmProbeTrampoline);
     151#undef PROBE_OFFSETOF
     152
     153#endif // USE(MASM_PROBE)
     154
    51155
    52156asm (
     
    92196    "bx lr" "\n"
    93197);
     198
     199#if USE(MASM_PROBE)
     200asm (
     201".text" "\n"
     202".globl " SYMBOL_STRING(ctiMasmProbeTrampoline) "\n"
     203HIDE_SYMBOL(ctiMasmProbeTrampoline) "\n"
     204INLINE_ARM_FUNCTION(ctiMasmProbeTrampoline) "\n"
     205SYMBOL_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
     329SYMBOL_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
    94347
    95348#define DEFINE_STUB_FUNCTION(rtype, op) \
  • branches/dfgFourthTier/Source/JavaScriptCore/jit/JITStubsARMv7.h

    r150109 r150844  
    5656
    5757#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)
     138COMPILE_ASSERT(PROBE_OFFSETOF(probeFunction) == PROBE_PROBE_FUNCTION_OFFSET, ProbeContext_probeFunction_offset_matches_ctiMasmProbeTrampoline);
     139COMPILE_ASSERT(PROBE_OFFSETOF(arg1) == PROBE_ARG1_OFFSET, ProbeContext_arg1_offset_matches_ctiMasmProbeTrampoline);
     140COMPILE_ASSERT(PROBE_OFFSETOF(arg2) == PROBE_ARG2_OFFSET, ProbeContext_arg2_offset_matches_ctiMasmProbeTrampoline);
     141COMPILE_ASSERT(PROBE_OFFSETOF(jitStackFrame) == PROBE_JIT_STACK_FRAME_OFFSET, ProbeContext_jitStackFrame_offset_matches_ctiMasmProbeTrampoline);
     142
     143COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r0) == PROBE_CPU_R0_OFFSET, ProbeContext_cpu_r0_offset_matches_ctiMasmProbeTrampoline);
     144COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r1) == PROBE_CPU_R1_OFFSET, ProbeContext_cpu_r1_offset_matches_ctiMasmProbeTrampoline);
     145COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r2) == PROBE_CPU_R2_OFFSET, ProbeContext_cpu_r2_offset_matches_ctiMasmProbeTrampoline);
     146COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r3) == PROBE_CPU_R3_OFFSET, ProbeContext_cpu_r3_offset_matches_ctiMasmProbeTrampoline);
     147COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r4) == PROBE_CPU_R4_OFFSET, ProbeContext_cpu_r4_offset_matches_ctiMasmProbeTrampoline);
     148COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r5) == PROBE_CPU_R5_OFFSET, ProbeContext_cpu_r5_offset_matches_ctiMasmProbeTrampoline);
     149COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r6) == PROBE_CPU_R6_OFFSET, ProbeContext_cpu_r6_offset_matches_ctiMasmProbeTrampoline);
     150COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r7) == PROBE_CPU_R7_OFFSET, ProbeContext_cpu_r70_offset_matches_ctiMasmProbeTrampoline);
     151COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r8) == PROBE_CPU_R8_OFFSET, ProbeContext_cpu_r8_offset_matches_ctiMasmProbeTrampoline);
     152COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r9) == PROBE_CPU_R9_OFFSET, ProbeContext_cpu_r9_offset_matches_ctiMasmProbeTrampoline);
     153COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r10) == PROBE_CPU_R10_OFFSET, ProbeContext_cpu_r10_offset_matches_ctiMasmProbeTrampoline);
     154COMPILE_ASSERT(PROBE_OFFSETOF(cpu.r11) == PROBE_CPU_R11_OFFSET, ProbeContext_cpu_r11_offset_matches_ctiMasmProbeTrampoline);
     155COMPILE_ASSERT(PROBE_OFFSETOF(cpu.ip) == PROBE_CPU_IP_OFFSET, ProbeContext_cpu_ip_offset_matches_ctiMasmProbeTrampoline);
     156COMPILE_ASSERT(PROBE_OFFSETOF(cpu.sp) == PROBE_CPU_SP_OFFSET, ProbeContext_cpu_sp_offset_matches_ctiMasmProbeTrampoline);
     157COMPILE_ASSERT(PROBE_OFFSETOF(cpu.lr) == PROBE_CPU_LR_OFFSET, ProbeContext_cpu_lr_offset_matches_ctiMasmProbeTrampoline);
     158COMPILE_ASSERT(PROBE_OFFSETOF(cpu.pc) == PROBE_CPU_PC_OFFSET, ProbeContext_cpu_pc_offset_matches_ctiMasmProbeTrampoline);
     159
     160COMPILE_ASSERT(PROBE_OFFSETOF(cpu.apsr) == PROBE_CPU_APSR_OFFSET, ProbeContext_cpu_apsr_offset_matches_ctiMasmProbeTrampoline);
     161COMPILE_ASSERT(PROBE_OFFSETOF(cpu.fpscr) == PROBE_CPU_FPSCR_OFFSET, ProbeContext_cpu_fpscr_offset_matches_ctiMasmProbeTrampoline);
     162
     163COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d0) == PROBE_CPU_D0_OFFSET, ProbeContext_cpu_d0_offset_matches_ctiMasmProbeTrampoline);
     164COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d1) == PROBE_CPU_D1_OFFSET, ProbeContext_cpu_d1_offset_matches_ctiMasmProbeTrampoline);
     165COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d2) == PROBE_CPU_D2_OFFSET, ProbeContext_cpu_d2_offset_matches_ctiMasmProbeTrampoline);
     166COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d3) == PROBE_CPU_D3_OFFSET, ProbeContext_cpu_d3_offset_matches_ctiMasmProbeTrampoline);
     167COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d4) == PROBE_CPU_D4_OFFSET, ProbeContext_cpu_d4_offset_matches_ctiMasmProbeTrampoline);
     168COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d5) == PROBE_CPU_D5_OFFSET, ProbeContext_cpu_d5_offset_matches_ctiMasmProbeTrampoline);
     169COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d6) == PROBE_CPU_D6_OFFSET, ProbeContext_cpu_d6_offset_matches_ctiMasmProbeTrampoline);
     170COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d7) == PROBE_CPU_D7_OFFSET, ProbeContext_cpu_d7_offset_matches_ctiMasmProbeTrampoline);
     171COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d8) == PROBE_CPU_D8_OFFSET, ProbeContext_cpu_d8_offset_matches_ctiMasmProbeTrampoline);
     172COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d9) == PROBE_CPU_D9_OFFSET, ProbeContext_cpu_d9_offset_matches_ctiMasmProbeTrampoline);
     173COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d10) == PROBE_CPU_D10_OFFSET, ProbeContext_cpu_d10_offset_matches_ctiMasmProbeTrampoline);
     174COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d11) == PROBE_CPU_D11_OFFSET, ProbeContext_cpu_d11_offset_matches_ctiMasmProbeTrampoline);
     175COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d12) == PROBE_CPU_D12_OFFSET, ProbeContext_cpu_d12_offset_matches_ctiMasmProbeTrampoline);
     176COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d13) == PROBE_CPU_D13_OFFSET, ProbeContext_cpu_d13_offset_matches_ctiMasmProbeTrampoline);
     177COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d14) == PROBE_CPU_D14_OFFSET, ProbeContext_cpu_d14_offset_matches_ctiMasmProbeTrampoline);
     178COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d15) == PROBE_CPU_D15_OFFSET, ProbeContext_cpu_d15_offset_matches_ctiMasmProbeTrampoline);
     179
     180#if CPU(APPLE_ARMV7S)
     181COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d16) == PROBE_CPU_D16_OFFSET, ProbeContext_cpu_d16_offset_matches_ctiMasmProbeTrampoline);
     182COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d17) == PROBE_CPU_D17_OFFSET, ProbeContext_cpu_d17_offset_matches_ctiMasmProbeTrampoline);
     183COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d18) == PROBE_CPU_D18_OFFSET, ProbeContext_cpu_d18_offset_matches_ctiMasmProbeTrampoline);
     184COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d19) == PROBE_CPU_D19_OFFSET, ProbeContext_cpu_d19_offset_matches_ctiMasmProbeTrampoline);
     185COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d20) == PROBE_CPU_D20_OFFSET, ProbeContext_cpu_d20_offset_matches_ctiMasmProbeTrampoline);
     186COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d21) == PROBE_CPU_D21_OFFSET, ProbeContext_cpu_d21_offset_matches_ctiMasmProbeTrampoline);
     187COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d22) == PROBE_CPU_D22_OFFSET, ProbeContext_cpu_d22_offset_matches_ctiMasmProbeTrampoline);
     188COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d23) == PROBE_CPU_D23_OFFSET, ProbeContext_cpu_d23_offset_matches_ctiMasmProbeTrampoline);
     189COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d24) == PROBE_CPU_D24_OFFSET, ProbeContext_cpu_d24_offset_matches_ctiMasmProbeTrampoline);
     190COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d25) == PROBE_CPU_D25_OFFSET, ProbeContext_cpu_d25_offset_matches_ctiMasmProbeTrampoline);
     191COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d26) == PROBE_CPU_D26_OFFSET, ProbeContext_cpu_d26_offset_matches_ctiMasmProbeTrampoline);
     192COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d27) == PROBE_CPU_D27_OFFSET, ProbeContext_cpu_d27_offset_matches_ctiMasmProbeTrampoline);
     193COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d28) == PROBE_CPU_D28_OFFSET, ProbeContext_cpu_d28_offset_matches_ctiMasmProbeTrampoline);
     194COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d29) == PROBE_CPU_D29_OFFSET, ProbeContext_cpu_d29_offset_matches_ctiMasmProbeTrampoline);
     195COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d30) == PROBE_CPU_D30_OFFSET, ProbeContext_cpu_d30_offset_matches_ctiMasmProbeTrampoline);
     196COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d31) == PROBE_CPU_D31_OFFSET, ProbeContext_cpu_d31_offset_matches_ctiMasmProbeTrampoline);
     197#endif // CPU(APPLE_ARMV7S)
     198
     199COMPILE_ASSERT(sizeof(MacroAssembler::ProbeContext) == PROBE_SIZE, ProbeContext_size_matches_ctiMasmProbeTrampoline);
     200
     201#undef PROBE_OFFSETOF
     202
     203#endif // USE(MASM_PROBE)
     204
    58205
    59206asm (
     
    142289);
    143290
     291#if USE(MASM_PROBE)
     292asm (
     293".text" "\n"
     294".align 2" "\n"
     295".globl " SYMBOL_STRING(ctiMasmProbeTrampoline) "\n"
     296HIDE_SYMBOL(ctiMasmProbeTrampoline) "\n"
     297".thumb" "\n"
     298".thumb_func " THUMB_FUNC_PARAM(ctiMasmProbeTrampoline) "\n"
     299SYMBOL_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"
     434SYMBOL_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
    144453#define DEFINE_STUB_FUNCTION(rtype, op) \
    145454    extern "C" { \
  • branches/dfgFourthTier/Source/JavaScriptCore/jit/JITStubsX86.h

    r150186 r150844  
    104104SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n"
    105105
    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"
    112125
    113126    "movl %ebp, " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%esp)" "\n"
     
    119132    "movl %esi, " STRINGIZE_VALUE_OF(PROBE_CPU_ESI_OFFSET) "(%ebp)" "\n"
    120133    "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"
    121150
    122151    "movdqa %xmm0, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM0_OFFSET) "(%ebp)" "\n"
     
    129158    "movdqa %xmm7, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%ebp)" "\n"
    130159
    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 
    134160    // Reserve stack space for the arg while maintaining the required stack
    135161    // pointer 32 byte alignment:
     
    139165    "call *" STRINGIZE_VALUE_OF(PROBE_PROBE_FUNCTION_OFFSET) "(%ebp)" "\n"
    140166
    141     // To enable probes to modify register state, we copy all regiesters
     167    // To enable probes to modify register state, we copy all registers
    142168    // out of the ProbeContext before returning.
    143169
    144     "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) "(%ebp), %eax" "\n"
    145     "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ECX_OFFSET) "(%ebp), %ecx" "\n"
    146170    "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EDX_OFFSET) "(%ebp), %edx" "\n"
    147171    "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EBX_OFFSET) "(%ebp), %ebx" "\n"
    148     "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%ebp), %esp" "\n"
    149172    "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ESI_OFFSET) "(%ebp), %esi" "\n"
    150173    "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EDI_OFFSET) "(%ebp), %edi" "\n"
     
    159182    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%ebp), %xmm7" "\n"
    160183
    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
     229SYMBOL_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"
    164250    "ret" "\n"
    165251);
  • branches/dfgFourthTier/Source/JavaScriptCore/jit/JITStubsX86Common.h

    r150186 r150844  
    5353
    5454#define PROBE_CPU_EAX_OFFSET (4 * PTR_SIZE)
    55 #define PROBE_CPU_ECX_OFFSET (5 * PTR_SIZE)
    56 #define PROBE_CPU_EDX_OFFSET (6 * PTR_SIZE)
    57 #define PROBE_CPU_EBX_OFFSET (7 * PTR_SIZE)
    58 #define PROBE_CPU_ESP_OFFSET (8 * PTR_SIZE)
    59 #define PROBE_CPU_EBP_OFFSET (9 * PTR_SIZE)
    60 #define PROBE_CPU_ESI_OFFSET (10 * PTR_SIZE)
    61 #define PROBE_CPU_EDI_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)
    6262
    6363#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)
    6665#else // CPU(X86_64)
    6766#define PROBE_CPU_R8_OFFSET (12 * PTR_SIZE)
     
    7372#define PROBE_CPU_R14_OFFSET (18 * PTR_SIZE)
    7473#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.
    7784#endif // CPU(X86_64)
    7885
     
    8794#define PROBE_CPU_XMM7_OFFSET (PROBE_FIRST_XMM_OFFSET + (7 * XMM_SIZE))
    8895
     96#define PROBE_SIZE (PROBE_CPU_XMM7_OFFSET + XMM_SIZE)
    8997
    9098// These ASSERTs remind you that if you change the layout of ProbeContext,
     
    104112COMPILE_ASSERT(PROBE_OFFSETOF(cpu.esi) == PROBE_CPU_ESI_OFFSET, ProbeContext_cpu_esi_offset_matches_ctiMasmProbeTrampoline);
    105113COMPILE_ASSERT(PROBE_OFFSETOF(cpu.edi) == PROBE_CPU_EDI_OFFSET, ProbeContext_cpu_edi_offset_matches_ctiMasmProbeTrampoline);
     114COMPILE_ASSERT(PROBE_OFFSETOF(cpu.eip) == PROBE_CPU_EIP_OFFSET, ProbeContext_cpu_eip_offset_matches_ctiMasmProbeTrampoline);
     115COMPILE_ASSERT(PROBE_OFFSETOF(cpu.eflags) == PROBE_CPU_EFLAGS_OFFSET, ProbeContext_cpu_eflags_offset_matches_ctiMasmProbeTrampoline);
    106116
    107117#if CPU(X86_64)
     
    116126#endif // CPU(X86_64)
    117127
    118 COMPILE_ASSERT(PROBE_OFFSETOF(cpu.eip) == PROBE_CPU_EIP_OFFSET, ProbeContext_cpu_eip_offset_matches_ctiMasmProbeTrampoline);
    119 
    120128COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm0) == PROBE_CPU_XMM0_OFFSET, ProbeContext_cpu_xmm0_offset_matches_ctiMasmProbeTrampoline);
    121129COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm1) == PROBE_CPU_XMM1_OFFSET, ProbeContext_cpu_xmm1_offset_matches_ctiMasmProbeTrampoline);
     
    126134COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm6) == PROBE_CPU_XMM6_OFFSET, ProbeContext_cpu_xmm6_offset_matches_ctiMasmProbeTrampoline);
    127135COMPILE_ASSERT(PROBE_OFFSETOF(cpu.xmm7) == PROBE_CPU_XMM7_OFFSET, ProbeContext_cpu_xmm7_offset_matches_ctiMasmProbeTrampoline);
     136
     137COMPILE_ASSERT(sizeof(MacroAssembler::ProbeContext) == PROBE_SIZE, ProbeContext_size_matches_ctiMasmProbeTrampoline);
    128138
    129139// Also double check that the xmm registers are 16 byte (128-bit) aligned as
  • branches/dfgFourthTier/Source/JavaScriptCore/jit/JITStubsX86_64.h

    r150186 r150844  
    119119SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n"
    120120
    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"
    127140
    128141    "movq %rbp, " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%rsp)" "\n"
     
    134147    "movq %rsi, " STRINGIZE_VALUE_OF(PROBE_CPU_ESI_OFFSET) "(%rbp)" "\n"
    135148    "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"
    136165
    137166    "movq %r8, " STRINGIZE_VALUE_OF(PROBE_CPU_R8_OFFSET) "(%rbp)" "\n"
     
    153182    "movdqa %xmm7, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%rbp)" "\n"
    154183
    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 
    158184    "movq %rbp, %rdi" "\n" // the ProbeContext* arg.
    159185    "call *" STRINGIZE_VALUE_OF(PROBE_PROBE_FUNCTION_OFFSET) "(%rbp)" "\n"
    160186
    161     // To enable probes to modify register state, we copy all regiesters
     187    // To enable probes to modify register state, we copy all registers
    162188    // out of the ProbeContext before returning.
    163189
    164     "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) "(%rbp), %rax" "\n"
    165     "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ECX_OFFSET) "(%rbp), %rcx" "\n"
    166190    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EDX_OFFSET) "(%rbp), %rdx" "\n"
    167191    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EBX_OFFSET) "(%rbp), %rbx" "\n"
    168     "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%rbp), %rsp" "\n"
    169192    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ESI_OFFSET) "(%rbp), %rsi" "\n"
    170193    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EDI_OFFSET) "(%rbp), %rdi" "\n"
     
    188211    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%rbp), %xmm7" "\n"
    189212
    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
     257SYMBOL_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"
    193278    "ret" "\n"
    194279);
Note: See TracChangeset for help on using the changeset viewer.