Changeset 150186 in webkit


Ignore:
Timestamp:
May 16, 2013 10:54:38 AM (11 years ago)
Author:
mark.lam@apple.com
Message:

Implement a probe mechanism for JIT generated code.
https://bugs.webkit.org/show_bug.cgi?id=115705.

Reviewed by Geoffrey Garen.

The probe is in the form of a MacroAssembler pseudo instruction.
It takes 3 arguments: a ProbeFunction, and 2 void* args.

When inserted into the JIT at some code generation site, the probe
pseudo "instruction" will emit a minimal amount of code to save the
stack pointer, 1 (or more) scratch register(s), and the probe
arguments into a ProbeContext record on the stack. The emitted code
will then call a probe trampoline to do the rest of the work, which
consists of:

  1. saving the remaining registers into the ProbeContext.
  2. calling the ProbeFunction, and passing it the ProbeContext pointer.
  3. restoring the registers from the ProbeContext after the ProbeFunction returns, and then returning to the JIT generated code.

The ProbeContext is stack allocated and is only valid for the duration
that the ProbeFunction is executing.

If the user supplied ProbeFunction alters the register values in the
ProbeContext, the new values will be installed into the registers upon
returning from the probe. This can be useful for some debugging or
testing purposes.

The probe mechanism is built conditional on USE(MASM_PROBE) which is
defined in config.h. USE(MASM_PROBE) will off by default.

This changeset only implements the probe mechanism for X86 and X86_64.

  • CMakeLists.txt:
  • GNUmakefile.list.am:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
  • JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • Target.pri:
  • assembler/MacroAssembler.h:

(MacroAssembler):
(JSC::MacroAssembler::shouldBlind):
(JSC::MacroAssembler::store32):

  • assembler/MacroAssemblerX86.h:

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

  • assembler/MacroAssemblerX86Common.cpp: Added.

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

  • CPU specific register dumper called by ProbeContext::dump().

(JSC::MacroAssemblerX86Common::ProbeContext::dump):

  • Prints the ProbeContext to the DataLog.
  • assembler/MacroAssemblerX86Common.h:

(MacroAssemblerX86Common):
(CPUState): Added.
(ProbeContext): Added.

  • assembler/MacroAssemblerX86_64.h:

(MacroAssemblerX86_64):
(JSC::MacroAssemblerX86_64::trustedImm64FromPtr):
(JSC::MacroAssemblerX86_64::probe):

  • assembler/X86Assembler.h:
  • config.h: Added WTF_USE_MASM_PROBE flag.
  • jit/JITStubs.cpp:
  • jit/JITStubs.h:
  • jit/JITStubsX86.h:
  • jit/JITStubsX86Common.h: Added.
  • jit/JITStubsX86_64.h:
Location:
branches/dfgFourthTier/Source/JavaScriptCore
Files:
2 added
18 edited

Legend:

Unmodified
Added
Removed
  • branches/dfgFourthTier/Source/JavaScriptCore/CMakeLists.txt

    r149946 r150186  
    506506elseif (WTF_CPU_MIPS)
    507507elseif (WTF_CPU_X86)
     508    list(APPEND JavaScriptCore_SOURCES
     509        assembler/MacroAssemblerX86Common.cpp
     510    )
    508511elseif (WTF_CPU_X86_64)
     512    list(APPEND JavaScriptCore_SOURCES
     513        assembler/MacroAssemblerX86Common.cpp
     514    )
    509515else ()
    510516    message(FATAL_ERROR "Unknown CPU")
  • branches/dfgFourthTier/Source/JavaScriptCore/ChangeLog

    r150144 r150186  
     12013-05-16  Mark Lam  <mark.lam@apple.com>
     2
     3        Implement a probe mechanism for JIT generated code.
     4        https://bugs.webkit.org/show_bug.cgi?id=115705.
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        The probe is in the form of a MacroAssembler pseudo instruction.
     9        It takes 3 arguments: a ProbeFunction, and 2 void* args.
     10
     11        When inserted into the JIT at some code generation site, the probe
     12        pseudo "instruction" will emit a minimal amount of code to save the
     13        stack pointer, 1 (or more) scratch register(s), and the probe
     14        arguments into a ProbeContext record on the stack. The emitted code
     15        will then call a probe trampoline to do the rest of the work, which
     16        consists of:
     17        1. saving the remaining registers into the ProbeContext.
     18        2. calling the ProbeFunction, and passing it the ProbeContext pointer.
     19        3. restoring the registers from the ProbeContext after the ProbeFunction
     20           returns, and then returning to the JIT generated code.
     21
     22        The ProbeContext is stack allocated and is only valid for the duration
     23        that the ProbeFunction is executing.
     24
     25        If the user supplied ProbeFunction alters the register values in the
     26        ProbeContext, the new values will be installed into the registers upon
     27        returning from the probe. This can be useful for some debugging or
     28        testing purposes.
     29
     30        The probe mechanism is built conditional on USE(MASM_PROBE) which is
     31        defined in config.h. USE(MASM_PROBE) will off by default.
     32
     33        This changeset only implements the probe mechanism for X86 and X86_64.
     34
     35        * CMakeLists.txt:
     36        * GNUmakefile.list.am:
     37        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
     38        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
     39        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
     40        * JavaScriptCore.xcodeproj/project.pbxproj:
     41        * Target.pri:
     42        * assembler/MacroAssembler.h:
     43        (MacroAssembler):
     44        (JSC::MacroAssembler::shouldBlind):
     45        (JSC::MacroAssembler::store32):
     46        * assembler/MacroAssemblerX86.h:
     47        (MacroAssemblerX86):
     48        (JSC::MacroAssemblerX86::trustedImm32FromPtr):
     49        (JSC::MacroAssemblerX86::probe):
     50        * assembler/MacroAssemblerX86Common.cpp: Added.
     51        (JSC::MacroAssemblerX86Common::ProbeContext::dumpCPURegisters):
     52        - CPU specific register dumper called by ProbeContext::dump().
     53        (JSC::MacroAssemblerX86Common::ProbeContext::dump):
     54        - Prints the ProbeContext to the DataLog.
     55        * assembler/MacroAssemblerX86Common.h:
     56        (MacroAssemblerX86Common):
     57        (CPUState): Added.
     58        (ProbeContext): Added.
     59        * assembler/MacroAssemblerX86_64.h:
     60        (MacroAssemblerX86_64):
     61        (JSC::MacroAssemblerX86_64::trustedImm64FromPtr):
     62        (JSC::MacroAssemblerX86_64::probe):
     63        * assembler/X86Assembler.h:
     64        * config.h: Added WTF_USE_MASM_PROBE flag.
     65        * jit/JITStubs.cpp:
     66        * jit/JITStubs.h:
     67        * jit/JITStubsX86.h:
     68        * jit/JITStubsX86Common.h: Added.
     69        * jit/JITStubsX86_64.h:
     70
    1712013-05-15  Mark Lam  <mark.lam@apple.com>
    272
  • branches/dfgFourthTier/Source/JavaScriptCore/GNUmakefile.list.am

    r150109 r150186  
    8181        Source/JavaScriptCore/assembler/MacroAssemblerSH4.h \
    8282        Source/JavaScriptCore/assembler/MacroAssemblerX86.h \
     83        Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp \
    8384        Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h \
    8485        Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h \
  • branches/dfgFourthTier/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj

    r150109 r150186  
    20432043                        </File>
    20442044                        <File
     2045                                RelativePath="..\..\assembler\MacroAssemblerX86Common.cpp"
     2046                                >
     2047                        </File>
     2048                        <File
    20452049                                RelativePath="..\..\assembler\MacroAssemblerX86Common.h"
    20462050                                >
     
    22442248                        <File
    22452249                                RelativePath="..\..\jit\JITStubsX86.h"
     2250                                >
     2251                        </File>
     2252                        <File
     2253                                RelativePath="..\..\jit\JITStubsX86Common.h"
    22462254                                >
    22472255                        </File>
  • branches/dfgFourthTier/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r150109 r150186  
    162162    <ClCompile Include="..\assembler\LinkBuffer.cpp" />
    163163    <ClCompile Include="..\assembler\MacroAssembler.cpp" />
     164    <ClInclude Include="..\assembler\MacroAssemblerX86Common.cpp" />
    164165    <ClCompile Include="..\bytecode\ArrayAllocationProfile.cpp" />
    165166    <ClCompile Include="..\bytecode\ArrayProfile.cpp" />
     
    570571    <ClInclude Include="..\jit\JITStubs.h" />
    571572    <ClInclude Include="..\jit\JITStubsX86.h" />
     573    <ClInclude Include="..\jit\JITStubsX86Common.h" />
    572574    <ClInclude Include="..\jit\JITStubsX86_64.h" />
    573575    <ClInclude Include="..\jit\JITThunks.h" />
  • branches/dfgFourthTier/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters

    r148697 r150186  
    103103      <Filter>assembler</Filter>
    104104    </ClCompile>
     105    <ClCompile Include="..\assembler\MacroAssemblerX86Common.cpp">
     106      <Filter>assembler</Filter>
     107    </ClCompile>
    105108    <ClCompile Include="..\bytecode\ArrayAllocationProfile.cpp">
    106109      <Filter>bytecode</Filter>
     
    12521255    </ClInclude>
    12531256    <ClInclude Include="..\jit\JITStubs.h">
     1257      <Filter>jit</Filter>
     1258    </ClInclude>
     1259    <ClInclude Include="..\jit\JITStubsX86.h">
     1260      <Filter>jit</Filter>
     1261    </ClInclude>
     1262    <ClInclude Include="..\jit\JITStubsX86Common.h">
     1263      <Filter>jit</Filter>
     1264    </ClInclude>
     1265    <ClInclude Include="..\jit\JITStubsX86_64.h">
    12541266      <Filter>jit</Filter>
    12551267    </ClInclude>
  • branches/dfgFourthTier/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r150139 r150186  
    949949                FE4A331F15BD2E07006F54F3 /* VMInspector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */; };
    950950                FE4A332015BD2E07006F54F3 /* VMInspector.h in Headers */ = {isa = PBXBuildFile; fileRef = FE4A331E15BD2E07006F54F3 /* VMInspector.h */; settings = {ATTRIBUTES = (Private, ); }; };
     951                FE940322174442590047CF6E /* JITStubsX86Common.h in Headers */ = {isa = PBXBuildFile; fileRef = FE940321174442590047CF6E /* JITStubsX86Common.h */; settings = {ATTRIBUTES = (Private, ); }; };
     952                FECE74571745456500FF9300 /* MacroAssemblerX86Common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FECE74561745456500FF9300 /* MacroAssemblerX86Common.cpp */; };
    951953                FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = FED287B115EC9A5700DA8161 /* LLIntOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
    952954                FEF6835E174343CC00A32E25 /* JITStubsARM.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF6835A174343CC00A32E25 /* JITStubsARM.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    19731975                FE4A331D15BD2E07006F54F3 /* VMInspector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VMInspector.cpp; sourceTree = "<group>"; };
    19741976                FE4A331E15BD2E07006F54F3 /* VMInspector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMInspector.h; sourceTree = "<group>"; };
     1977                FE940321174442590047CF6E /* JITStubsX86Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubsX86Common.h; sourceTree = "<group>"; };
     1978                FECE74561745456500FF9300 /* MacroAssemblerX86Common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MacroAssemblerX86Common.cpp; sourceTree = "<group>"; };
    19751979                FED287B115EC9A5700DA8161 /* LLIntOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntOpcode.h; path = llint/LLIntOpcode.h; sourceTree = "<group>"; };
    19761980                FEF6835A174343CC00A32E25 /* JITStubsARM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubsARM.h; sourceTree = "<group>"; };
     
    23042308                                FEF6835C174343CC00A32E25 /* JITStubsX86_64.h */,
    23052309                                FEF6835D174343CC00A32E25 /* JITStubsX86.h */,
     2310                                FE940321174442590047CF6E /* JITStubsX86Common.h */,
    23062311                                0F5EF91B16878F78003E5C25 /* JITThunks.cpp */,
    23072312                                0F5EF91C16878F78003E5C25 /* JITThunks.h */,
     
    31003105                                860161E00F3A83C100F84710 /* MacroAssemblerX86.h */,
    31013106                                860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */,
     3107                                FECE74561745456500FF9300 /* MacroAssemblerX86Common.cpp */,
    31023108                                860161E20F3A83C100F84710 /* MacroAssemblerX86Common.h */,
    31033109                                86C568DF11A213EE0007F7F0 /* MIPSAssembler.h */,
     
    32303236                                FEF68360174343CC00A32E25 /* JITStubsX86_64.h in Headers */,
    32313237                                FEF6835E174343CC00A32E25 /* JITStubsARM.h in Headers */,
     3238                                FE940322174442590047CF6E /* JITStubsX86Common.h in Headers */,
    32323239                                FEF68361174343CC00A32E25 /* JITStubsX86.h in Headers */,
    32333240                                86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */,
     
    41644171                                86EC9DD21328DF82002B2AD7 /* DFGSpeculativeJIT.cpp in Sources */,
    41654172                                86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */,
     4173                                FECE74571745456500FF9300 /* MacroAssemblerX86Common.cpp in Sources */,
    41664174                                86880F4D14353B2100B08D42 /* DFGSpeculativeJIT64.cpp in Sources */,
    41674175                                0F63944015C75F1D006A597C /* DFGTypeCheckHoistingPhase.cpp in Sources */,
  • branches/dfgFourthTier/Source/JavaScriptCore/Target.pri

    r149946 r150186  
    5454    assembler/MacroAssemblerARM.cpp \
    5555    assembler/MacroAssemblerSH4.cpp \
     56    assembler/MacroAssemblerX86Common.cpp \
    5657    bytecode/ArrayAllocationProfile.cpp \
    5758    bytecode/ArrayProfile.cpp \
  • branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssembler.h

    r143408 r150186  
    11/*
    2  * Copyright (C) 2008, 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    572572        return MacroAssemblerBase::branchTest8(cond, Address(address.base, address.offset), mask);
    573573    }
    574 #else
     574
     575#else // !CPU(X86_64)
     576
    575577    void addPtr(RegisterID src, RegisterID dest)
    576578    {
     
    10681070    }
    10691071
    1070 #endif
     1072#endif // ENABLE(JIT_CONSTANT_BLINDING)
    10711073
    10721074#endif // !CPU(X86_64)
     
    10801082        // if we've broken blinding during patch development.
    10811083        return true;
    1082 #else
     1084#else // ENABLE(FORCED_JIT_BLINDING)
    10831085
    10841086        // First off we'll special case common, "safe" values to avoid hurting
     
    11011103
    11021104        return shouldBlindForSpecificArch(value);
    1103 #endif
     1105#endif // ENABLE(FORCED_JIT_BLINDING)
    11041106    }
    11051107
     
    12721274        store64(value, addressForPoke(index));
    12731275    }
    1274 #endif
     1276#endif // CPU(X86_64)
    12751277   
    12761278    void store32(Imm32 imm, Address dest)
     
    12811283            store32(blind.value1, dest);
    12821284            xor32(blind.value2, dest);
    1283 #else
     1285#else // CPU(X86) || CPU(X86_64)
    12841286            if (RegisterID scratchRegister = (RegisterID)scratchRegisterForBlinding()) {
    12851287                loadXorBlindedConstant(xorBlindConstant(imm), scratchRegister);
     
    12931295                store32(imm.asTrustedImm32(), dest);
    12941296            }
    1295 #endif
     1297#endif // CPU(X86) || CPU(X86_64)
    12961298        } else
    12971299            store32(imm.asTrustedImm32(), dest);
     
    14411443        urshift32(src, trustedImm32ForShift(amount), dest);
    14421444    }
    1443 #endif
     1445#endif // ENABLE(JIT_CONSTANT_BLINDING)
    14441446};
    14451447
  • branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerX86.h

    r135330 r150186  
    3131#include "MacroAssemblerX86Common.h"
    3232
     33#if USE(MASM_PROBE)
     34#include <wtf/StdLibExtras.h>
     35#endif
     36
    3337namespace JSC {
    3438
     
    288292    }
    289293
     294#if USE(MASM_PROBE)
     295    // This function emits code to preserve the CPUState (e.g. registers),
     296    // call a user supplied probe function, and restore the CPUState before
     297    // continuing with other JIT generated code.
     298    //
     299    // The user supplied probe function will be called with a single pointer to
     300    // a ProbeContext struct (defined above) which contains, among other things,
     301    // the preserved CPUState. This allows the user probe function to inspect
     302    // the CPUState at that point in the JIT generated code.
     303    //
     304    // If the user probe function alters the register values in the ProbeContext,
     305    // the altered values will be loaded into the CPU registers when the probe
     306    // returns.
     307    //
     308    // The ProbeContext is stack allocated and is only valid for the duration
     309    // of the call to the user probe function.
     310
     311    void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
     312#endif // USE(MASM_PROBE)
     313
    290314private:
    291315    friend class LinkBuffer;
     
    306330        X86Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
    307331    }
     332
     333#if USE(MASM_PROBE)
     334    inline TrustedImm32 trustedImm32FromPtr(void* ptr)
     335    {
     336        return TrustedImm32(TrustedImmPtr(ptr));
     337    }
     338
     339    inline TrustedImm32 trustedImm32FromPtr(ProbeFunction function)
     340    {
     341        return TrustedImm32(TrustedImmPtr(reinterpret_cast<void*>(function)));
     342    }
     343
     344    inline TrustedImm32 trustedImm32FromPtr(void (*function)())
     345    {
     346        return TrustedImm32(TrustedImmPtr(reinterpret_cast<void*>(function)));
     347    }
     348#endif
    308349};
    309350
     351#if USE(MASM_PROBE)
     352
     353extern "C" void ctiMasmProbeTrampoline();
     354
     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.
     379
     380inline void MacroAssemblerX86::probe(MacroAssemblerX86::ProbeFunction function, void* arg1, void* arg2)
     381{
     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));
     399
     400    move(trustedImm32FromPtr(ctiMasmProbeTrampoline), RegisterID::eax);
     401    call(RegisterID::eax);
     402
     403    #undef probeContextField
     404}
     405#endif // USE(MASM_PROBE)
     406
    310407} // namespace JSC
    311408
  • branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h

    r148347 r150186  
    3434namespace JSC {
    3535
     36struct JITStackFrame;
     37
    3638class MacroAssemblerX86Common : public AbstractMacroAssembler<X86Assembler> {
    3739protected:
     
    14371439        return X86Assembler::maxJumpReplacementSize();
    14381440    }
     1441
     1442#if USE(MASM_PROBE)
     1443    struct CPUState {
     1444        #define DECLARE_REGISTER(_type, _regName) \
     1445            _type _regName;
     1446        FOR_EACH_CPU_REGISTER(DECLARE_REGISTER)
     1447        #undef DECLARE_REGISTER
     1448    };
     1449
     1450    struct ProbeContext;
     1451    typedef void (*ProbeFunction)(struct ProbeContext*);
     1452
     1453    struct ProbeContext {
     1454        ProbeFunction probeFunction;
     1455        void* arg1;
     1456        void* arg2;
     1457        JITStackFrame* jitStackFrame;
     1458        CPUState cpu;
     1459
     1460        void dump(const char* indentation = 0);
     1461    private:
     1462        void dumpCPURegisters(const char* indentation);
     1463    };
     1464#endif // USE(MASM_PROBE)
    14391465
    14401466protected:
  • branches/dfgFourthTier/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h

    r135330 r150186  
    3131#include "MacroAssemblerX86Common.h"
    3232
     33#if USE(MASM_PROBE)
     34#include <wtf/StdLibExtras.h>
     35#endif
     36
    3337#define REPTACH_OFFSET_CALL_R11 3
    3438
     
    613617    }
    614618
     619#if USE(MASM_PROBE)
     620    // This function emits code to preserve the CPUState (e.g. registers),
     621    // call a user supplied probe function, and restore the CPUState before
     622    // continuing with other JIT generated code.
     623    //
     624    // The user supplied probe function will be called with a single pointer to
     625    // a ProbeContext struct (defined above) which contains, among other things,
     626    // the preserved CPUState. This allows the user probe function to inspect
     627    // the CPUState at that point in the JIT generated code.
     628    //
     629    // If the user probe function alters the register values in the ProbeContext,
     630    // the altered values will be loaded into the CPU registers when the probe
     631    // returns.
     632    //
     633    // The ProbeContext is stack allocated and is only valid for the duration
     634    // of the call to the user probe function.
     635
     636    void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
     637#endif // USE(MASM_PROBE)
     638
    615639private:
    616640    friend class LinkBuffer;
     
    635659    }
    636660
     661#if USE(MASM_PROBE)
     662    inline TrustedImm64 trustedImm64FromPtr(void* ptr)
     663    {
     664        return TrustedImm64(TrustedImmPtr(ptr));
     665    }
     666
     667    inline TrustedImm64 trustedImm64FromPtr(ProbeFunction function)
     668    {
     669        return TrustedImm64(TrustedImmPtr(reinterpret_cast<void*>(function)));
     670    }
     671
     672    inline TrustedImm64 trustedImm64FromPtr(void (*function)())
     673    {
     674        return TrustedImm64(TrustedImmPtr(reinterpret_cast<void*>(function)));
     675    }
     676#endif
    637677};
    638678
     679#if USE(MASM_PROBE)
     680
     681extern "C" void ctiMasmProbeTrampoline();
     682
     683// What code is emitted for the probe?
     684// ==================================
     685// We want to keep the size of the emitted probe invocation code as compact as
     686// possible to minimize the perturbation to the JIT generated code. However,
     687// we also need to preserve the CPU registers and set up the ProbeContext to be
     688// passed to the user probe function.
     689//
     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.
     696//
     697// What values are in the saved registers?
     698// ======================================
     699// Conceptually, the saved registers should contain values as if the probe
     700// is not present in the JIT generated code. Hence, they should contain values
     701// that are expected at the start of the instruction immediately following the
     702// probe.
     703//
     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.
     707
     708inline void MacroAssemblerX86_64::probe(MacroAssemblerX86_64::ProbeFunction function, void* arg1, void* arg2)
     709{
     710    RegisterID esp = RegisterID::esp;
     711    #define probeContextField(field) Address(esp, offsetof(ProbeContext, field))
     712
     713    // The X86_64 ABI specifies that the worse case stack alignment requirement
     714    // is 32 bytes.
     715    const int probeFrameSize = WTF::roundUpToMultipleOf(32, sizeof(ProbeContext));
     716    sub64(TrustedImm32(probeFrameSize), esp);
     717
     718    store64(RegisterID::eax, probeContextField(cpu.eax));
     719
     720    move(TrustedImm32(probeFrameSize), RegisterID::eax);
     721    add64(esp, RegisterID::eax);
     722    store64(RegisterID::eax, probeContextField(cpu.esp));
     723
     724    store64(trustedImm64FromPtr(function), probeContextField(probeFunction));
     725    store64(trustedImm64FromPtr(arg1), probeContextField(arg1));
     726    store64(trustedImm64FromPtr(arg2), probeContextField(arg2));
     727
     728    move(trustedImm64FromPtr(ctiMasmProbeTrampoline), RegisterID::eax);
     729    call(RegisterID::eax);
     730
     731    #undef probeContextField
     732}
     733#endif // USE(MASM_PROBE)
     734
    639735} // namespace JSC
    640736
  • branches/dfgFourthTier/Source/JavaScriptCore/assembler/X86Assembler.h

    r148697 r150186  
    11/*
    2  * Copyright (C) 2008, 2012 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3535#include <wtf/Vector.h>
    3636
     37#if USE(MASM_PROBE)
     38#include <xmmintrin.h>
     39#endif
     40
    3741namespace JSC {
    3842
     
    7276        xmm7,
    7377    } XMMRegisterID;
     78
     79#if USE(MASM_PROBE)
     80    #define FOR_EACH_CPU_REGISTER(V) \
     81        FOR_EACH_CPU_GPREGISTER(V) \
     82        FOR_EACH_CPU_FPREGISTER(V)
     83
     84    #define FOR_EACH_CPU_GPREGISTER(V) \
     85        V(void*, eax) \
     86        V(void*, ecx) \
     87        V(void*, edx) \
     88        V(void*, ebx) \
     89        V(void*, esp) \
     90        V(void*, ebp) \
     91        V(void*, esi) \
     92        V(void*, edi) \
     93        FOR_EACH_X86_64_CPU_GPREGISTER(V) \
     94        V(void*, eip)
     95
     96    #define FOR_EACH_CPU_FPREGISTER(V) \
     97        V(__m128, xmm0) \
     98        V(__m128, xmm1) \
     99        V(__m128, xmm2) \
     100        V(__m128, xmm3) \
     101        V(__m128, xmm4) \
     102        V(__m128, xmm5) \
     103        V(__m128, xmm6) \
     104        V(__m128, xmm7)
     105
     106#if CPU(X86)
     107    #define FOR_EACH_X86_64_CPU_GPREGISTER(V) // Nothing to add.
     108#elif CPU(X86_64)
     109    #define FOR_EACH_X86_64_CPU_GPREGISTER(V) \
     110        V(void*, r8) \
     111        V(void*, r9) \
     112        V(void*, r10) \
     113        V(void*, r11) \
     114        V(void*, r12) \
     115        V(void*, r13) \
     116        V(void*, r14) \
     117        V(void*, r15)
     118#endif // CPU(X86_64)
     119#endif // USE(MASM_PROBE)
    74120}
    75121
  • branches/dfgFourthTier/Source/JavaScriptCore/config.h

    r140930 r150186  
    11/*
    2  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
    33 * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
    44 *
     
    7777#define SKIP_STATIC_CONSTRUCTORS_ON_GCC 1
    7878#endif
     79
     80// Enable the following if you want to use the MacroAssembler::probe() facility
     81// to do JIT debugging.
     82#define WTF_USE_MASM_PROBE 0
     83
  • branches/dfgFourthTier/Source/JavaScriptCore/jit/JITStubs.cpp

    r150109 r150186  
    3434#include "JITStubs.h"
    3535
    36 #include "CommonSlowPaths.h"
    3736#include "Arguments.h"
    3837#include "ArrayConstructor.h"
     
    4039#include "CodeBlock.h"
    4140#include "CodeProfiling.h"
     41#include "CommonSlowPaths.h"
    4242#include "DFGOSREntry.h"
    4343#include "Debugger.h"
  • branches/dfgFourthTier/Source/JavaScriptCore/jit/JITStubs.h

    r149649 r150186  
    317317        && returnAddress.value() < bitwise_cast<void*>(&ctiTrampolineEnd);
    318318}
     319#endif
     320
     321#if USE(MASM_PROBE)
     322extern "C" void ctiMasmProbeTrampoline();
    319323#endif
    320324
  • branches/dfgFourthTier/Source/JavaScriptCore/jit/JITStubsX86.h

    r150109 r150186  
    3232#define JITStubsX86_h
    3333
     34#include "JITStubsX86Common.h"
     35
    3436#if !CPU(X86)
    3537#error "JITStubsX86.h should only be #included if CPU(X86)"
     
    9698);
    9799
     100#if USE(MASM_PROBE)
     101asm (
     102".globl " SYMBOL_STRING(ctiMasmProbeTrampoline) "\n"
     103HIDE_SYMBOL(ctiMasmProbeTrampoline) "\n"
     104SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n"
     105
     106    // MacroAssembler::probe() has already generated code to save/store the
     107    // values for eax and esp in the ProbeContext. Save/store the remaining
     108    // registers here.
     109
     110    "popl %eax" "\n"
     111    "movl %eax, " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%esp)" "\n"
     112
     113    "movl %ebp, " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%esp)" "\n"
     114    "movl %esp, %ebp" "\n" // Save the ProbeContext*.
     115
     116    "movl %ecx, " STRINGIZE_VALUE_OF(PROBE_CPU_ECX_OFFSET) "(%ebp)" "\n"
     117    "movl %edx, " STRINGIZE_VALUE_OF(PROBE_CPU_EDX_OFFSET) "(%ebp)" "\n"
     118    "movl %ebx, " STRINGIZE_VALUE_OF(PROBE_CPU_EBX_OFFSET) "(%ebp)" "\n"
     119    "movl %esi, " STRINGIZE_VALUE_OF(PROBE_CPU_ESI_OFFSET) "(%ebp)" "\n"
     120    "movl %edi, " STRINGIZE_VALUE_OF(PROBE_CPU_EDI_OFFSET) "(%ebp)" "\n"
     121
     122    "movdqa %xmm0, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM0_OFFSET) "(%ebp)" "\n"
     123    "movdqa %xmm1, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM1_OFFSET) "(%ebp)" "\n"
     124    "movdqa %xmm2, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM2_OFFSET) "(%ebp)" "\n"
     125    "movdqa %xmm3, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM3_OFFSET) "(%ebp)" "\n"
     126    "movdqa %xmm4, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM4_OFFSET) "(%ebp)" "\n"
     127    "movdqa %xmm5, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM5_OFFSET) "(%ebp)" "\n"
     128    "movdqa %xmm6, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM6_OFFSET) "(%ebp)" "\n"
     129    "movdqa %xmm7, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%ebp)" "\n"
     130
     131    "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%ebp), %eax" "\n"
     132    "movl %eax, " STRINGIZE_VALUE_OF(PROBE_JIT_STACK_FRAME_OFFSET) "(%ebp)" "\n"
     133
     134    // Reserve stack space for the arg while maintaining the required stack
     135    // pointer 32 byte alignment:
     136    "subl $0x20, %esp" "\n"
     137    "movl %ebp, 0(%esp)" "\n" // the ProbeContext* arg.
     138
     139    "call *" STRINGIZE_VALUE_OF(PROBE_PROBE_FUNCTION_OFFSET) "(%ebp)" "\n"
     140
     141    // To enable probes to modify register state, we copy all regiesters
     142    // out of the ProbeContext before returning.
     143
     144    "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) "(%ebp), %eax" "\n"
     145    "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ECX_OFFSET) "(%ebp), %ecx" "\n"
     146    "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EDX_OFFSET) "(%ebp), %edx" "\n"
     147    "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EBX_OFFSET) "(%ebp), %ebx" "\n"
     148    "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%ebp), %esp" "\n"
     149    "movl " STRINGIZE_VALUE_OF(PROBE_CPU_ESI_OFFSET) "(%ebp), %esi" "\n"
     150    "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EDI_OFFSET) "(%ebp), %edi" "\n"
     151
     152    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM0_OFFSET) "(%ebp), %xmm0" "\n"
     153    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM1_OFFSET) "(%ebp), %xmm1" "\n"
     154    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM2_OFFSET) "(%ebp), %xmm2" "\n"
     155    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM3_OFFSET) "(%ebp), %xmm3" "\n"
     156    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM4_OFFSET) "(%ebp), %xmm4" "\n"
     157    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM5_OFFSET) "(%ebp), %xmm5" "\n"
     158    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM6_OFFSET) "(%ebp), %xmm6" "\n"
     159    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%ebp), %xmm7" "\n"
     160
     161    "pushl " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%ebp)" "\n"
     162
     163    "movl " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%ebp), %ebp" "\n"
     164    "ret" "\n"
     165);
     166#endif // USE(MASM_PROBE)
     167
    98168#endif // COMPILER(GCC)
    99169
  • branches/dfgFourthTier/Source/JavaScriptCore/jit/JITStubsX86_64.h

    r150109 r150186  
    3131#ifndef JITStubsX86_64_h
    3232#define JITStubsX86_64_h
     33
     34#include "JITStubsX86Common.h"
    3335
    3436#if !CPU(X86_64)
     
    111113);
    112114
     115#if USE(MASM_PROBE)
     116asm (
     117".globl " SYMBOL_STRING(ctiMasmProbeTrampoline) "\n"
     118HIDE_SYMBOL(ctiMasmProbeTrampoline) "\n"
     119SYMBOL_STRING(ctiMasmProbeTrampoline) ":" "\n"
     120
     121    // MacroAssembler::probe() has already generated code to save/store the
     122    // values for rax and rsp in the ProbeContext. Save/store the remaining
     123    // registers here.
     124
     125    "popq %rax" "\n"
     126    "movq %rax, " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%rsp)" "\n"
     127
     128    "movq %rbp, " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%rsp)" "\n"
     129    "movq %rsp, %rbp" "\n" // Save the ProbeContext*.
     130
     131    "movq %rcx, " STRINGIZE_VALUE_OF(PROBE_CPU_ECX_OFFSET) "(%rbp)" "\n"
     132    "movq %rdx, " STRINGIZE_VALUE_OF(PROBE_CPU_EDX_OFFSET) "(%rbp)" "\n"
     133    "movq %rbx, " STRINGIZE_VALUE_OF(PROBE_CPU_EBX_OFFSET) "(%rbp)" "\n"
     134    "movq %rsi, " STRINGIZE_VALUE_OF(PROBE_CPU_ESI_OFFSET) "(%rbp)" "\n"
     135    "movq %rdi, " STRINGIZE_VALUE_OF(PROBE_CPU_EDI_OFFSET) "(%rbp)" "\n"
     136
     137    "movq %r8, " STRINGIZE_VALUE_OF(PROBE_CPU_R8_OFFSET) "(%rbp)" "\n"
     138    "movq %r9, " STRINGIZE_VALUE_OF(PROBE_CPU_R9_OFFSET) "(%rbp)" "\n"
     139    "movq %r10, " STRINGIZE_VALUE_OF(PROBE_CPU_R10_OFFSET) "(%rbp)" "\n"
     140    "movq %r11, " STRINGIZE_VALUE_OF(PROBE_CPU_R11_OFFSET) "(%rbp)" "\n"
     141    "movq %r12, " STRINGIZE_VALUE_OF(PROBE_CPU_R12_OFFSET) "(%rbp)" "\n"
     142    "movq %r13, " STRINGIZE_VALUE_OF(PROBE_CPU_R13_OFFSET) "(%rbp)" "\n"
     143    "movq %r14, " STRINGIZE_VALUE_OF(PROBE_CPU_R14_OFFSET) "(%rbp)" "\n"
     144    "movq %r15, " STRINGIZE_VALUE_OF(PROBE_CPU_R15_OFFSET) "(%rbp)" "\n"
     145
     146    "movdqa %xmm0, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM0_OFFSET) "(%rbp)" "\n"
     147    "movdqa %xmm1, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM1_OFFSET) "(%rbp)" "\n"
     148    "movdqa %xmm2, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM2_OFFSET) "(%rbp)" "\n"
     149    "movdqa %xmm3, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM3_OFFSET) "(%rbp)" "\n"
     150    "movdqa %xmm4, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM4_OFFSET) "(%rbp)" "\n"
     151    "movdqa %xmm5, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM5_OFFSET) "(%rbp)" "\n"
     152    "movdqa %xmm6, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM6_OFFSET) "(%rbp)" "\n"
     153    "movdqa %xmm7, " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%rbp)" "\n"
     154
     155    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%rbp), %rax" "\n"
     156    "movq %rax, " STRINGIZE_VALUE_OF(PROBE_JIT_STACK_FRAME_OFFSET) "(%rbp)" "\n"
     157
     158    "movq %rbp, %rdi" "\n" // the ProbeContext* arg.
     159    "call *" STRINGIZE_VALUE_OF(PROBE_PROBE_FUNCTION_OFFSET) "(%rbp)" "\n"
     160
     161    // To enable probes to modify register state, we copy all regiesters
     162    // out of the ProbeContext before returning.
     163
     164    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EAX_OFFSET) "(%rbp), %rax" "\n"
     165    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ECX_OFFSET) "(%rbp), %rcx" "\n"
     166    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EDX_OFFSET) "(%rbp), %rdx" "\n"
     167    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EBX_OFFSET) "(%rbp), %rbx" "\n"
     168    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ESP_OFFSET) "(%rbp), %rsp" "\n"
     169    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_ESI_OFFSET) "(%rbp), %rsi" "\n"
     170    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EDI_OFFSET) "(%rbp), %rdi" "\n"
     171
     172    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_R8_OFFSET) "(%rbp), %r8" "\n"
     173    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_R9_OFFSET) "(%rbp), %r9" "\n"
     174    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_R10_OFFSET) "(%rbp), %r10" "\n"
     175    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_R11_OFFSET) "(%rbp), %r11" "\n"
     176    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_R12_OFFSET) "(%rbp), %r12" "\n"
     177    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_R13_OFFSET) "(%rbp), %r13" "\n"
     178    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_R14_OFFSET) "(%rbp), %r14" "\n"
     179    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_R15_OFFSET) "(%rbp), %r15" "\n"
     180
     181    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM0_OFFSET) "(%rbp), %xmm0" "\n"
     182    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM1_OFFSET) "(%rbp), %xmm1" "\n"
     183    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM2_OFFSET) "(%rbp), %xmm2" "\n"
     184    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM3_OFFSET) "(%rbp), %xmm3" "\n"
     185    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM4_OFFSET) "(%rbp), %xmm4" "\n"
     186    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM5_OFFSET) "(%rbp), %xmm5" "\n"
     187    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM6_OFFSET) "(%rbp), %xmm6" "\n"
     188    "movdqa " STRINGIZE_VALUE_OF(PROBE_CPU_XMM7_OFFSET) "(%rbp), %xmm7" "\n"
     189
     190    "pushq " STRINGIZE_VALUE_OF(PROBE_CPU_EIP_OFFSET) "(%rbp)" "\n"
     191
     192    "movq " STRINGIZE_VALUE_OF(PROBE_CPU_EBP_OFFSET) "(%rbp), %rbp" "\n"
     193    "ret" "\n"
     194);
     195#endif // USE(MASM_PROBE)
     196
    113197#endif // COMPILER(GCC)
    114198
Note: See TracChangeset for help on using the changeset viewer.