Changeset 176134 in webkit


Ignore:
Timestamp:
Nov 14, 2014 12:24:55 PM (9 years ago)
Author:
mark.lam@apple.com
Message:

Reduce amount of cut-and-paste needed for probe mechanism implementations.
<https://webkit.org/b/138671>

Reviewed by Geoffrey Garen.

The existing code requires that each MacroAssembler implementation provide
their own copy of all of the probe implementations even when most of it is
identical. This patch hoists the common parts into AbstractMacroAssembler
(with some minor renaming). Each target specific MacroAssembler now only
need to implement a few target specific methods that are expected by and
documented in AbstractMacroAssembler.h in the ENABLE(MASM_PROBE) section.

In this patch, I also simplified the X86 and X86_64 ports to use the same
port implementation. The ARMv7 probe implementation should not conditionally
exclude the higher FP registers (since the JIT doesn't). Fixed the ARMv7
probe code to include the higher FP registers always.

This is all done in preparation to add printing functionality in JITted code
for debugging.

  • assembler/AbstractMacroAssembler.h:

(JSC::AbstractMacroAssembler::Label::Label):
(JSC::AbstractMacroAssembler::ConvertibleLoadLabel::ConvertibleLoadLabel):
(JSC::AbstractMacroAssembler::DataLabelPtr::DataLabelPtr):
(JSC::AbstractMacroAssembler::DataLabel32::DataLabel32):
(JSC::AbstractMacroAssembler::DataLabelCompact::DataLabelCompact):
(JSC::AbstractMacroAssembler::Jump::link):
(JSC::AbstractMacroAssembler::Jump::linkTo):
(JSC::AbstractMacroAssembler::JumpList::link):
(JSC::AbstractMacroAssembler::JumpList::linkTo):
(JSC::AbstractMacroAssembler::ProbeContext::print):
(JSC::AbstractMacroAssembler::printIndent):
(JSC::AbstractMacroAssembler::printCPU):
(JSC::AbstractMacroAssembler::CachedTempRegister::CachedTempRegister):

  • Except for the 3 printing methods (which are for the probe), the rest are touched simply because we need to add the MacroAssemblerType to the template args. The MacroAssemblerType is used by the abstract probe code to call the few probe methods that need to have CPU specific implementations.
  • assembler/MacroAssemblerARM.cpp:

(JSC::MacroAssemblerARM::printCPURegisters):

  • This was refactored from ProbeContext::dumpCPURegisters() which no longer exists.

(JSC::MacroAssemblerARM::ProbeContext::dumpCPURegisters): Deleted.
(JSC::MacroAssemblerARM::ProbeContext::dump): Deleted.

  • assembler/MacroAssemblerARM.h:
  • assembler/MacroAssemblerARM64.h:
  • assembler/MacroAssemblerARMv7.cpp:

(JSC::MacroAssemblerARMv7::printCPURegisters):

  • This was refactored from ProbeContext::dumpCPURegisters() which no longer exists.

(JSC::MacroAssemblerARMv7::ProbeContext::dumpCPURegisters): Deleted.
(JSC::MacroAssemblerARMv7::ProbeContext::dump): Deleted.

  • assembler/MacroAssemblerARMv7.h:
  • assembler/MacroAssemblerMIPS.h:
  • assembler/MacroAssemblerSH4.h:
  • assembler/MacroAssemblerX86.h:

(JSC::MacroAssemblerX86::trustedImm32FromPtr): Deleted.
(JSC::MacroAssemblerX86::probe): Deleted.

  • assembler/MacroAssemblerX86Common.cpp:

(JSC::MacroAssemblerX86Common::printCPURegisters):

  • This was refactored from ProbeContext::dumpCPURegisters() which no longer exists.

(JSC::MacroAssemblerX86Common::probe):

  • This implementation of probe() is based on the one originally in MacroAssemblerX86_64.h. It is generic and should work for both 32-bit and 64-bit.

(JSC::MacroAssemblerX86Common::ProbeContext::dumpCPURegisters): Deleted.
(JSC::MacroAssemblerX86Common::ProbeContext::dump): Deleted.

  • assembler/MacroAssemblerX86Common.h:
  • assembler/MacroAssemblerX86_64.h:

(JSC::MacroAssemblerX86_64::trustedImm64FromPtr): Deleted.
(JSC::MacroAssemblerX86_64::probe): Deleted.

  • jit/JITStubsARMv7.h:
Location:
trunk/Source/JavaScriptCore
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r176109 r176134  
     12014-11-13  Mark Lam  <mark.lam@apple.com>
     2
     3        Reduce amount of cut-and-paste needed for probe mechanism implementations.
     4        <https://webkit.org/b/138671>
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        The existing code requires that each MacroAssembler implementation provide
     9        their own copy of all of the probe implementations even when most of it is
     10        identical.  This patch hoists the common parts into AbstractMacroAssembler
     11        (with some minor renaming).  Each target specific MacroAssembler now only
     12        need to implement a few target specific methods that are expected by and
     13        documented in AbstractMacroAssembler.h in the ENABLE(MASM_PROBE) section.
     14
     15        In this patch, I also simplified the X86 and X86_64 ports to use the same
     16        port implementation.  The ARMv7 probe implementation should not conditionally
     17        exclude the higher FP registers (since the JIT doesn't).  Fixed the ARMv7
     18        probe code to include the higher FP registers always.
     19
     20        This is all done in preparation to add printing functionality in JITted code
     21        for debugging.
     22
     23        * assembler/AbstractMacroAssembler.h:
     24        (JSC::AbstractMacroAssembler::Label::Label):
     25        (JSC::AbstractMacroAssembler::ConvertibleLoadLabel::ConvertibleLoadLabel):
     26        (JSC::AbstractMacroAssembler::DataLabelPtr::DataLabelPtr):
     27        (JSC::AbstractMacroAssembler::DataLabel32::DataLabel32):
     28        (JSC::AbstractMacroAssembler::DataLabelCompact::DataLabelCompact):
     29        (JSC::AbstractMacroAssembler::Jump::link):
     30        (JSC::AbstractMacroAssembler::Jump::linkTo):
     31        (JSC::AbstractMacroAssembler::JumpList::link):
     32        (JSC::AbstractMacroAssembler::JumpList::linkTo):
     33        (JSC::AbstractMacroAssembler::ProbeContext::print):
     34        (JSC::AbstractMacroAssembler::printIndent):
     35        (JSC::AbstractMacroAssembler::printCPU):
     36        (JSC::AbstractMacroAssembler::CachedTempRegister::CachedTempRegister):
     37        - Except for the 3 printing methods (which are for the probe), the rest
     38          are touched simply because we need to add the MacroAssemblerType to the
     39          template args.
     40          The MacroAssemblerType is used by the abstract probe code to call the
     41          few probe methods that need to have CPU specific implementations.
     42
     43        * assembler/MacroAssemblerARM.cpp:
     44        (JSC::MacroAssemblerARM::printCPURegisters):
     45        - This was refactored from ProbeContext::dumpCPURegisters() which no
     46          longer exists.
     47        (JSC::MacroAssemblerARM::ProbeContext::dumpCPURegisters): Deleted.
     48        (JSC::MacroAssemblerARM::ProbeContext::dump): Deleted.
     49
     50        * assembler/MacroAssemblerARM.h:
     51        * assembler/MacroAssemblerARM64.h:
     52
     53        * assembler/MacroAssemblerARMv7.cpp:
     54        (JSC::MacroAssemblerARMv7::printCPURegisters):
     55        - This was refactored from ProbeContext::dumpCPURegisters() which no
     56          longer exists.
     57        (JSC::MacroAssemblerARMv7::ProbeContext::dumpCPURegisters): Deleted.
     58        (JSC::MacroAssemblerARMv7::ProbeContext::dump): Deleted.
     59
     60        * assembler/MacroAssemblerARMv7.h:
     61        * assembler/MacroAssemblerMIPS.h:
     62        * assembler/MacroAssemblerSH4.h:
     63        * assembler/MacroAssemblerX86.h:
     64        (JSC::MacroAssemblerX86::trustedImm32FromPtr): Deleted.
     65        (JSC::MacroAssemblerX86::probe): Deleted.
     66
     67        * assembler/MacroAssemblerX86Common.cpp:
     68        (JSC::MacroAssemblerX86Common::printCPURegisters):
     69        - This was refactored from ProbeContext::dumpCPURegisters() which no
     70          longer exists.
     71        (JSC::MacroAssemblerX86Common::probe):
     72        - This implementation of probe() is based on the one originally in
     73          MacroAssemblerX86_64.h.  It is generic and should work for both
     74          32-bit and 64-bit.
     75        (JSC::MacroAssemblerX86Common::ProbeContext::dumpCPURegisters): Deleted.
     76        (JSC::MacroAssemblerX86Common::ProbeContext::dump): Deleted.
     77
     78        * assembler/MacroAssemblerX86Common.h:
     79        * assembler/MacroAssemblerX86_64.h:
     80        (JSC::MacroAssemblerX86_64::trustedImm64FromPtr): Deleted.
     81        (JSC::MacroAssemblerX86_64::probe): Deleted.
     82        * jit/JITStubsARMv7.h:
     83
    1842014-11-13  Michael Saboff  <msaboff@apple.com>
    285
  • trunk/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h

    r168776 r176134  
    8989}
    9090
    91 template <class AssemblerType>
     91template <class AssemblerType, class MacroAssemblerType>
    9292class AbstractMacroAssembler {
    9393public:
    9494    friend class JITWriteBarrierBase;
     95    typedef AbstractMacroAssembler<AssemblerType, MacroAssemblerType> AbstractMacroAssemblerType;
    9596    typedef AssemblerType AssemblerType_T;
    9697
     
    356357    // it may be used as a destination for a jump.
    357358    class Label {
    358         template<class TemplateAssemblerType>
     359        template<class TemplateAssemblerType, class TemplateMacroAssemblerType>
    359360        friend class AbstractMacroAssembler;
    360361        friend struct DFG::OSRExit;
     
    369370        }
    370371
    371         Label(AbstractMacroAssembler<AssemblerType>* masm)
     372        Label(AbstractMacroAssemblerType* masm)
    372373            : m_label(masm->m_assembler.label())
    373374        {
     
    391392    // addPtr(TrustedImmPtr(i), a, b)
    392393    class ConvertibleLoadLabel {
    393         template<class TemplateAssemblerType>
     394        template<class TemplateAssemblerType, class TemplateMacroAssemblerType>
    394395        friend class AbstractMacroAssembler;
    395396        friend class LinkBuffer;
     
    400401        }
    401402       
    402         ConvertibleLoadLabel(AbstractMacroAssembler<AssemblerType>* masm)
     403        ConvertibleLoadLabel(AbstractMacroAssemblerType* masm)
    403404            : m_label(masm->m_assembler.labelIgnoringWatchpoints())
    404405        {
     
    415416    // patched after the code has been generated.
    416417    class DataLabelPtr {
    417         template<class TemplateAssemblerType>
     418        template<class TemplateAssemblerType, class TemplateMacroAssemblerType>
    418419        friend class AbstractMacroAssembler;
    419420        friend class LinkBuffer;
     
    423424        }
    424425
    425         DataLabelPtr(AbstractMacroAssembler<AssemblerType>* masm)
     426        DataLabelPtr(AbstractMacroAssemblerType* masm)
    426427            : m_label(masm->m_assembler.label())
    427428        {
     
    439440    // patched after the code has been generated.
    440441    class DataLabel32 {
    441         template<class TemplateAssemblerType>
     442        template<class TemplateAssemblerType, class TemplateMacroAssemblerType>
    442443        friend class AbstractMacroAssembler;
    443444        friend class LinkBuffer;
     
    447448        }
    448449
    449         DataLabel32(AbstractMacroAssembler<AssemblerType>* masm)
     450        DataLabel32(AbstractMacroAssemblerType* masm)
    450451            : m_label(masm->m_assembler.label())
    451452        {
     
    463464    // compact immediate to be patched after the code has been generated.
    464465    class DataLabelCompact {
    465         template<class TemplateAssemblerType>
     466        template<class TemplateAssemblerType, class TemplateMacroAssemblerType>
    466467        friend class AbstractMacroAssembler;
    467468        friend class LinkBuffer;
     
    471472        }
    472473       
    473         DataLabelCompact(AbstractMacroAssembler<AssemblerType>* masm)
     474        DataLabelCompact(AbstractMacroAssemblerType* masm)
    474475            : m_label(masm->m_assembler.label())
    475476        {
     
    494495    // destination.
    495496    class Call {
    496         template<class TemplateAssemblerType>
     497        template<class TemplateAssemblerType, class TemplateMacroAssemblerType>
    497498        friend class AbstractMacroAssembler;
    498499
     
    538539    // destination.
    539540    class Jump {
    540         template<class TemplateAssemblerType>
     541        template<class TemplateAssemblerType, class TemplateMacroAssemblerType>
    541542        friend class AbstractMacroAssembler;
    542543        friend class Call;
     
    603604        }
    604605
    605         void link(AbstractMacroAssembler<AssemblerType>* masm) const
     606        void link(AbstractMacroAssemblerType* masm) const
    606607        {
    607608            masm->invalidateAllTempRegisters();
     
    627628        }
    628629       
    629         void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) const
     630        void linkTo(Label label, AbstractMacroAssemblerType* masm) const
    630631        {
    631632#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
     
    699700        }
    700701
    701         void link(AbstractMacroAssembler<AssemblerType>* masm)
     702        void link(AbstractMacroAssemblerType* masm)
    702703        {
    703704            size_t size = m_jumps.size();
     
    707708        }
    708709       
    709         void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm)
     710        void linkTo(Label label, AbstractMacroAssemblerType* masm)
    710711        {
    711712            size_t size = m_jumps.size();
     
    836837        AssemblerType::cacheFlush(code, size);
    837838    }
     839
     840#if ENABLE(MASM_PROBE)
     841
     842    struct CPUState {
     843        #define DECLARE_REGISTER(_type, _regName) \
     844            _type _regName;
     845        FOR_EACH_CPU_REGISTER(DECLARE_REGISTER)
     846        #undef DECLARE_REGISTER
     847    };
     848
     849    struct ProbeContext;
     850    typedef void (*ProbeFunction)(struct ProbeContext*);
     851
     852    struct ProbeContext {
     853        ProbeFunction probeFunction;
     854        void* arg1;
     855        void* arg2;
     856        CPUState cpu;
     857
     858        void print(int indentation = 0)
     859        {
     860            #define INDENT MacroAssemblerType::printIndent(indentation)
     861
     862            INDENT, dataLogF("ProbeContext %p {\n", this);
     863            indentation++;
     864            {
     865                INDENT, dataLogF("probeFunction: %p\n", probeFunction);
     866                INDENT, dataLogF("arg1: %p %llu\n", arg1, reinterpret_cast<int64_t>(arg1));
     867                INDENT, dataLogF("arg2: %p %llu\n", arg2, reinterpret_cast<int64_t>(arg2));
     868                MacroAssemblerType::printCPU(cpu, indentation);
     869            }
     870            indentation--;
     871            INDENT, dataLog("}\n");
     872
     873            #undef INDENT
     874        }
     875    };
     876
     877    static void printIndent(int indentation)
     878    {
     879        for (; indentation > 0; indentation--)
     880            dataLog("    ");
     881    }
     882
     883    static void printCPU(CPUState& cpu, int indentation = 0)
     884    {
     885        #define INDENT printIndent(indentation)
     886
     887        INDENT, dataLog("cpu: {\n");
     888        MacroAssemblerType::printCPURegisters(cpu, indentation + 1);
     889        INDENT, dataLog("}\n");
     890
     891        #undef INDENT
     892    }
     893
     894
     895    // This function will be called by printCPU() to print the contents of the
     896    // target specific registers which are saved away in the CPUInfo struct.
     897    // printCPURegisters() should make use of printIndentation() to print the
     898    // registers with the appropriate amount of indentation.
     899    //
     900    // Note: printCPURegisters() should be implemented by the target specific
     901    // MacroAssembler. This prototype is only provided here to document the
     902    // interface.
     903
     904    static void printCPURegisters(CPUState&, int indentation = 0);
     905
     906    // This function emits code to preserve the CPUInfo (e.g. registers),
     907    // call a user supplied probe function, and restore the CPUInfo before
     908    // continuing with other JIT generated code.
     909    //
     910    // The user supplied probe function will be called with a single pointer to
     911    // a ProbeContext struct (defined above) which contains, among other things,
     912    // the preserved CPUInfo. This allows the user probe function to inspect
     913    // the CPUInfo at that point in the JIT generated code.
     914    //
     915    // If the user probe function alters the register values in the ProbeContext,
     916    // the altered values will be loaded into the CPU registers when the probe
     917    // returns.
     918    //
     919    // The ProbeContext is stack allocated and is only valid for the duration
     920    // of the call to the user probe function.
     921    //
     922    // Note: probe() should be implemented by the target specific MacroAssembler.
     923    // This prototype is only provided here to document the interface.
     924
     925    void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
     926
     927#endif // ENABLE(MASM_PROBE)
    838928
    839929    AssemblerType m_assembler;
     
    878968
    879969    public:
    880         CachedTempRegister(AbstractMacroAssembler<AssemblerType>* masm, RegisterID registerID)
     970        CachedTempRegister(AbstractMacroAssemblerType* masm, RegisterID registerID)
    881971            : m_masm(masm)
    882972            , m_registerID(registerID)
     
    906996
    907997    private:
    908         AbstractMacroAssembler<AssemblerType>* m_masm;
     998        AbstractMacroAssemblerType* m_masm;
    909999        RegisterID m_registerID;
    9101000        intptr_t m_value;
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM.cpp

    r176031 r176134  
    11/*
    2  * Copyright (C) 2013 Apple Inc.
     2 * Copyright (C) 2013, 2014 Apple Inc.
    33 * Copyright (C) 2009 University of Szeged
    44 * All rights reserved.
     
    3131
    3232#include "MacroAssemblerARM.h"
    33 
    34 #if ENABLE(MASM_PROBE)
    35 #include <wtf/StdLibExtras.h>
    36 #endif
    3733
    3834#if OS(LINUX)
     
    10298#if ENABLE(MASM_PROBE)
    10399
    104 void MacroAssemblerARM::ProbeContext::dumpCPURegisters(const char* indentation)
     100#define INDENT printIndent(indentation)
     101
     102void MacroAssemblerARM::printCPURegisters(CPUState& cpu, int indentation)
    105103{
    106104    #define DUMP_GPREGISTER(_type, _regName) { \
    107105        int32_t value = reinterpret_cast<int32_t>(cpu._regName); \
    108         dataLogF("%s    %5s: 0x%08x   %d\n", indentation, #_regName, value, value) ; \
     106        INDENT, dataLogF("%5s: 0x%08x  %d\n", #_regName, value, value) ; \
    109107    }
    110108    FOR_EACH_CPU_GPREGISTER(DUMP_GPREGISTER)
     
    113111
    114112    #define DUMP_FPREGISTER(_type, _regName) { \
    115         uint32_t* u = reinterpret_cast<uint32_t*>(&cpu._regName); \
     113        uint64_t* u = reinterpret_cast<uint64_t*>(&cpu._regName); \
    116114        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]); \
     115        INDENT, dataLogF("%5s: 0x%016llx  %.13g\n", #_regName, *u, *d); \
    119116    }
    120117    FOR_EACH_CPU_FPREGISTER(DUMP_FPREGISTER)
     
    122119}
    123120
    124 void MacroAssemblerARM::ProbeContext::dump(const char* indentation)
    125 {
    126     if (!indentation)
    127         indentation = "";
    128 
    129     dataLogF("%sProbeContext %p {\n", indentation, this);
    130     dataLogF("%s  probeFunction: %p\n", indentation, probeFunction);
    131     dataLogF("%s  arg1: %p %llu\n", indentation, arg1, reinterpret_cast<int64_t>(arg1));
    132     dataLogF("%s  arg2: %p %llu\n", indentation, arg2, reinterpret_cast<int64_t>(arg2));
    133     dataLogF("%s  cpu: {\n", indentation);
    134 
    135     dumpCPURegisters(indentation);
    136 
    137     dataLogF("%s  }\n", indentation);
    138     dataLogF("%s}\n", indentation);
    139 }
    140 
     121#undef INDENT
    141122
    142123extern "C" void ctiMasmProbeTrampoline();
    143124
    144125// For details on "What code is emitted for the probe?" and "What values are in
    145 // the saved registers?", see comment for MacroAssemblerX86::probe() in
    146 // MacroAssemblerX86_64.h.
     126// the saved registers?", see comment for MacroAssemblerX86Common::probe() in
     127// MacroAssemblerX86Common.cpp.
    147128
    148129void MacroAssemblerARM::probe(MacroAssemblerARM::ProbeFunction function, void* arg1, void* arg2)
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM.h

    r176031 r176134  
    11/*
    2  * Copyright (C) 2008, 2013 Apple Inc.
     2 * Copyright (C) 2008, 2013, 2014 Apple Inc.
    33 * Copyright (C) 2009, 2010 University of Szeged
    44 * All rights reserved.
     
    3636namespace JSC {
    3737
    38 class MacroAssemblerARM : public AbstractMacroAssembler<ARMAssembler> {
     38class MacroAssemblerARM : public AbstractMacroAssembler<ARMAssembler, MacroAssemblerARM> {
    3939    static const int DoubleConditionMask = 0x0f;
    4040    static const int DoubleConditionBitSpecial = 0x10;
     
    14341434
    14351435#if ENABLE(MASM_PROBE)
    1436     struct CPUState {
    1437         #define DECLARE_REGISTER(_type, _regName) \
    1438             _type _regName;
    1439         FOR_EACH_CPU_REGISTER(DECLARE_REGISTER)
    1440         #undef DECLARE_REGISTER
    1441     };
    1442 
    1443     struct ProbeContext;
    1444     typedef void (*ProbeFunction)(struct ProbeContext*);
    1445 
    1446     struct ProbeContext {
    1447         ProbeFunction probeFunction;
    1448         void* arg1;
    1449         void* arg2;
    1450         CPUState cpu;
    1451 
    1452         void dump(const char* indentation = 0);
    1453     private:
    1454         void dumpCPURegisters(const char* indentation);
    1455     };
    1456 
    1457     // For details about probe(), see comment in MacroAssemblerX86_64.h.
     1436    // Methods required by the MASM_PROBE mechanism as defined in
     1437    // AbstractMacroAssembler.h.
     1438    static void printCPURegisters(CPUState&, int indentation = 0);
    14581439    void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
    14591440#endif // ENABLE(MASM_PROBE)
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h

    r171705 r176134  
    3535namespace JSC {
    3636
    37 class MacroAssemblerARM64 : public AbstractMacroAssembler<ARM64Assembler> {
     37class MacroAssemblerARM64 : public AbstractMacroAssembler<ARM64Assembler, MacroAssemblerARM64> {
    3838    static const RegisterID dataTempRegister = ARM64Registers::ip0;
    3939    static const RegisterID memoryTempRegister = ARM64Registers::ip1;
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.cpp

    r176031 r176134  
    2929#include "MacroAssemblerARMv7.h"
    3030
    31 #if ENABLE(MASM_PROBE)
    32 #include <wtf/StdLibExtras.h>
    33 #endif
    34 
    3531namespace JSC {
    3632
    3733#if ENABLE(MASM_PROBE)
    3834
    39 void MacroAssemblerARMv7::ProbeContext::dumpCPURegisters(const char* indentation)
     35#define INDENT printIndent(indentation)
     36
     37void MacroAssemblerARMv7::printCPURegisters(CPUState& cpu, int indentation)
    4038{
    4139    #define DUMP_GPREGISTER(_type, _regName) { \
    4240        int32_t value = reinterpret_cast<int32_t>(cpu._regName); \
    43         dataLogF("%s    %5s: 0x%08x   %d\n", indentation, #_regName, value, value) ; \
     41        INDENT, dataLogF("%5s: 0x%08x  %d\n", #_regName, value, value) ; \
    4442    }
    4543    FOR_EACH_CPU_GPREGISTER(DUMP_GPREGISTER)
     
    4846
    4947    #define DUMP_FPREGISTER(_type, _regName) { \
    50         uint32_t* u = reinterpret_cast<uint32_t*>(&cpu._regName); \
     48        uint64_t* u = reinterpret_cast<uint64_t*>(&cpu._regName); \
    5149        double* d = reinterpret_cast<double*>(&cpu._regName); \
    52         dataLogF("%s    %5s: 0x %08x %08x   %12g\n", \
    53             indentation, #_regName, u[1], u[0], d[0]); \
     50        INDENT, dataLogF("%5s: 0x%016llx  %.13g\n", #_regName, *u, *d); \
    5451    }
    5552    FOR_EACH_CPU_FPREGISTER(DUMP_FPREGISTER)
     
    5754}
    5855
    59 void MacroAssemblerARMv7::ProbeContext::dump(const char* indentation)
    60 {
    61     if (!indentation)
    62         indentation = "";
    63 
    64     dataLogF("%sProbeContext %p {\n", indentation, this);
    65     dataLogF("%s  probeFunction: %p\n", indentation, probeFunction);
    66     dataLogF("%s  arg1: %p %llu\n", indentation, arg1, reinterpret_cast<int64_t>(arg1));
    67     dataLogF("%s  arg2: %p %llu\n", indentation, arg2, reinterpret_cast<int64_t>(arg2));
    68     dataLogF("%s  cpu: {\n", indentation);
    69 
    70     dumpCPURegisters(indentation);
    71 
    72     dataLogF("%s  }\n", indentation);
    73     dataLogF("%s}\n", indentation);
    74 }
    75 
     56#undef INDENT
    7657
    7758extern "C" void ctiMasmProbeTrampoline();
    7859
    7960// For details on "What code is emitted for the probe?" and "What values are in
    80 // the saved registers?", see comment for MacroAssemblerX86::probe() in
    81 // MacroAssemblerX86_64.h.
     61// the saved registers?", see comment for MacroAssemblerX86Common::probe() in
     62// MacroAssemblerX86Common.cpp.
    8263
    8364void MacroAssemblerARMv7::probe(MacroAssemblerARMv7::ProbeFunction function, void* arg1, void* arg2)
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h

    r176031 r176134  
    3535namespace JSC {
    3636
    37 class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> {
     37class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler, MacroAssemblerARMv7> {
    3838    static const RegisterID dataTempRegister = ARMRegisters::ip;
    3939    static const RegisterID addressTempRegister = ARMRegisters::r6;
     
    19031903
    19041904#if ENABLE(MASM_PROBE)
    1905     struct CPUState {
    1906         #define DECLARE_REGISTER(_type, _regName) \
    1907             _type _regName;
    1908         FOR_EACH_CPU_REGISTER(DECLARE_REGISTER)
    1909         #undef DECLARE_REGISTER
    1910     };
    1911 
    1912     struct ProbeContext;
    1913     typedef void (*ProbeFunction)(struct ProbeContext*);
    1914 
    1915     struct ProbeContext {
    1916         ProbeFunction probeFunction;
    1917         void* arg1;
    1918         void* arg2;
    1919         CPUState cpu;
    1920 
    1921         void dump(const char* indentation = 0);
    1922     private:
    1923         void dumpCPURegisters(const char* indentation);
    1924     };
    1925 
    1926     // For details about probe(), see comment in MacroAssemblerX86_64.h.
     1905    // Methods required by the MASM_PROBE mechanism as defined in
     1906    // AbstractMacroAssembler.h.
     1907    static void printCPURegisters(CPUState&, int indentation = 0);
    19271908    void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
    19281909#endif // ENABLE(MASM_PROBE)
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h

    r173461 r176134  
    11/*
    2  * Copyright (C) 2008 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2014 Apple Inc. All rights reserved.
    33 * Copyright (C) 2010 MIPS Technologies, Inc. All rights reserved.
    44 *
     
    3535namespace JSC {
    3636
    37 class MacroAssemblerMIPS : public AbstractMacroAssembler<MIPSAssembler> {
     37class MacroAssemblerMIPS : public AbstractMacroAssembler<MIPSAssembler, MacroAssemblerMIPS> {
    3838public:
    3939    typedef MIPSRegisters::FPRegisterID FPRegisterID;
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h

    r173222 r176134  
    22 * Copyright (C) 2013 Cisco Systems, Inc. All rights reserved.
    33 * Copyright (C) 2009-2011 STMicroelectronics. All rights reserved.
    4  * Copyright (C) 2008 Apple Inc. All rights reserved.
     4 * Copyright (C) 2008, 2014 Apple Inc. All rights reserved.
    55 *
    66 * Redistribution and use in source and binary forms, with or without
     
    3737namespace JSC {
    3838
    39 class MacroAssemblerSH4 : public AbstractMacroAssembler<SH4Assembler> {
     39class MacroAssemblerSH4 : public AbstractMacroAssembler<SH4Assembler, MacroAssemblerSH4> {
    4040public:
    4141    typedef SH4Assembler::FPRegisterID FPRegisterID;
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86.h

    r176031 r176134  
    3131#include "MacroAssemblerX86Common.h"
    3232
    33 #if ENABLE(MASM_PROBE)
    34 #include <wtf/StdLibExtras.h>
    35 #endif
    36 
    3733namespace JSC {
    3834
     
    350346    }
    351347
    352 #if ENABLE(MASM_PROBE)
    353     // For details about probe(), see comment in MacroAssemblerX86_64.h.
    354     void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
    355 #endif // ENABLE(MASM_PROBE)
    356 
    357348private:
    358349    friend class LinkBuffer;
     
    373364        X86Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
    374365    }
    375 
    376 #if ENABLE(MASM_PROBE)
    377     inline TrustedImm32 trustedImm32FromPtr(void* ptr)
    378     {
    379         return TrustedImm32(TrustedImmPtr(ptr));
    380     }
    381 
    382     inline TrustedImm32 trustedImm32FromPtr(ProbeFunction function)
    383     {
    384         return TrustedImm32(TrustedImmPtr(reinterpret_cast<void*>(function)));
    385     }
    386 
    387     inline TrustedImm32 trustedImm32FromPtr(void (*function)())
    388     {
    389         return TrustedImm32(TrustedImmPtr(reinterpret_cast<void*>(function)));
    390     }
    391 #endif
    392366};
    393367
    394 #if ENABLE(MASM_PROBE)
    395 
    396 extern "C" void ctiMasmProbeTrampoline();
    397 
    398 // For details on "What code is emitted for the probe?" and "What values are in
    399 // the saved registers?", see comment for MacroAssemblerX86::probe() in
    400 // MacroAssemblerX86_64.h.
    401 
    402 inline void MacroAssemblerX86::probe(MacroAssemblerX86::ProbeFunction function, void* arg1, void* arg2)
    403 {
    404     push(RegisterID::esp);
    405     push(RegisterID::eax);
    406     push(trustedImm32FromPtr(arg2));
    407     push(trustedImm32FromPtr(arg1));
    408     push(trustedImm32FromPtr(function));
    409 
    410     move(trustedImm32FromPtr(ctiMasmProbeTrampoline), RegisterID::eax);
    411     call(RegisterID::eax);
    412 }
    413 #endif // ENABLE(MASM_PROBE)
    414 
    415368} // namespace JSC
    416369
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp

    r176095 r176134  
    3333#if ENABLE(MASM_PROBE)
    3434
    35 void MacroAssemblerX86Common::ProbeContext::dumpCPURegisters(const char* indentation)
     35#define INDENT printIndent(indentation)
     36
     37void MacroAssemblerX86Common::printCPURegisters(MacroAssemblerX86Common::CPUState& cpu, int indentation)
    3638{
    3739#if CPU(X86)
    38     #define DUMP_GPREGISTER(_type, _regName) { \
     40    #define PRINT_GPREGISTER(_type, _regName) { \
    3941        int32_t value = reinterpret_cast<int32_t>(cpu._regName); \
    40         dataLogF("%s    %6s: 0x%08x  %d\n", indentation, #_regName, value, value) ; \
     42        INDENT, dataLogF("%6s: 0x%08x  %d\n", #_regName, value, value) ; \
    4143    }
    4244#elif CPU(X86_64)
    43     #define DUMP_GPREGISTER(_type, _regName) { \
     45    #define PRINT_GPREGISTER(_type, _regName) { \
    4446        int64_t value = reinterpret_cast<int64_t>(cpu._regName); \
    45         dataLogF("%s    %6s: 0x%016llx  %lld\n", indentation, #_regName, value, value) ; \
     47        INDENT, dataLogF("%6s: 0x%016llx  %lld\n", #_regName, value, value) ; \
    4648    }
    4749#endif
    48     FOR_EACH_CPU_GPREGISTER(DUMP_GPREGISTER)
    49     FOR_EACH_CPU_SPECIAL_REGISTER(DUMP_GPREGISTER)
    50     #undef DUMP_GPREGISTER
     50    FOR_EACH_CPU_GPREGISTER(PRINT_GPREGISTER)
     51    FOR_EACH_CPU_SPECIAL_REGISTER(PRINT_GPREGISTER)
     52    #undef PRINT_GPREGISTER
    5153
    52     #define DUMP_FPREGISTER(_type, _regName) { \
     54    #define PRINT_FPREGISTER(_type, _regName) { \
    5355        uint64_t* u = reinterpret_cast<uint64_t*>(&cpu._regName); \
    5456        double* d = reinterpret_cast<double*>(&cpu._regName); \
    55         dataLogF("%s    %6s: 0x%016llx  %.13g\n", indentation, #_regName, *u, *d); \
     57        INDENT, dataLogF("%6s: 0x%016llx  %.13g\n", #_regName, *u, *d); \
    5658    }
    57     FOR_EACH_CPU_FPREGISTER(DUMP_FPREGISTER)
    58     #undef DUMP_FPREGISTER
     59    FOR_EACH_CPU_FPREGISTER(PRINT_FPREGISTER)
     60    #undef PRINT_FPREGISTER
    5961}
    6062
    61 void MacroAssemblerX86Common::ProbeContext::dump(const char* indentation)
     63#undef INDENT
     64
     65extern "C" void ctiMasmProbeTrampoline();
     66
     67// What code is emitted for the probe?
     68// ==================================
     69// We want to keep the size of the emitted probe invocation code as compact as
     70// possible to minimize the perturbation to the JIT generated code. However,
     71// we also need to preserve the CPU registers and set up the ProbeContext to be
     72// passed to the user probe function.
     73//
     74// Hence, we do only the minimum here to preserve a scratch register (i.e. rax
     75// in this case) and the stack pointer (i.e. rsp), and pass the probe arguments.
     76// We'll let the ctiMasmProbeTrampoline handle the rest of the probe invocation
     77// work i.e. saving the CPUState (and setting up the ProbeContext), calling the
     78// user probe function, and restoring the CPUState before returning to JIT
     79// generated code.
     80//
     81// What registers need to be saved?
     82// ===============================
     83// The registers are saved for 2 reasons:
     84// 1. To preserve their state in the JITted code. This means that all registers
     85//    that are not callee saved needs to be saved. We also need to save the
     86//    condition code registers because the probe can be inserted between a test
     87//    and a branch.
     88// 2. To allow the probe to inspect the values of the registers for debugging
     89//    purposes. This means all registers need to be saved.
     90//
     91// In summary, save everything. But for reasons stated above, we should do the
     92// minimum here and let ctiMasmProbeTrampoline do the heavy lifting to save the
     93// full set.
     94//
     95// What values are in the saved registers?
     96// ======================================
     97// Conceptually, the saved registers should contain values as if the probe
     98// is not present in the JIT generated code. Hence, they should contain values
     99// that are expected at the start of the instruction immediately following the
     100// probe.
     101//
     102// Specifically, the saved stack pointer register will point to the stack
     103// position before we push the ProbeContext frame. The saved rip will point to
     104// the address of the instruction immediately following the probe.
     105
     106void MacroAssemblerX86Common::probe(MacroAssemblerX86Common::ProbeFunction function, void* arg1, void* arg2)
    62107{
    63     if (!indentation)
    64         indentation = "";
    65 
    66     dataLogF("%sProbeContext %p {\n", indentation, this);
    67     dataLogF("%s  probeFunction: %p\n", indentation, probeFunction);
    68     dataLogF("%s  arg1: %p %llu\n", indentation, arg1, reinterpret_cast<int64_t>(arg1));
    69     dataLogF("%s  arg2: %p %llu\n", indentation, arg2, reinterpret_cast<int64_t>(arg2));
    70     dataLogF("%s  cpu: {\n", indentation);
    71 
    72     dumpCPURegisters(indentation);
    73 
    74     dataLogF("%s  }\n", indentation);
    75     dataLogF("%s}\n", indentation);
     108    push(RegisterID::esp);
     109    push(RegisterID::eax);
     110    move(TrustedImmPtr(arg2), RegisterID::eax);
     111    push(RegisterID::eax);
     112    move(TrustedImmPtr(arg1), RegisterID::eax);
     113    push(RegisterID::eax);
     114    move(TrustedImmPtr(reinterpret_cast<void*>(function)), RegisterID::eax);
     115    push(RegisterID::eax);
     116    move(TrustedImmPtr(reinterpret_cast<void*>(ctiMasmProbeTrampoline)), RegisterID::eax);
     117    call(RegisterID::eax);
    76118}
    77119
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h

    r176031 r176134  
    3434namespace JSC {
    3535
    36 class MacroAssemblerX86Common : public AbstractMacroAssembler<X86Assembler> {
     36class MacroAssemblerX86Common : public AbstractMacroAssembler<X86Assembler, MacroAssemblerX86Common> {
    3737public:
    3838#if CPU(X86_64)
     
    14711471
    14721472#if ENABLE(MASM_PROBE)
    1473     struct CPUState {
    1474         #define DECLARE_REGISTER(_type, _regName) \
    1475             _type _regName;
    1476         FOR_EACH_CPU_REGISTER(DECLARE_REGISTER)
    1477         #undef DECLARE_REGISTER
    1478     };
    1479 
    1480     struct ProbeContext;
    1481     typedef void (*ProbeFunction)(struct ProbeContext*);
    1482 
    1483     struct ProbeContext {
    1484         ProbeFunction probeFunction;
    1485         void* arg1;
    1486         void* arg2;
    1487         CPUState cpu;
    1488 
    1489         void dump(const char* indentation = 0);
    1490     private:
    1491         void dumpCPURegisters(const char* indentation);
    1492     };
     1473    // Methods required by the MASM_PROBE mechanism as defined in
     1474    // AbstractMacroAssembler.h.
     1475    static void printCPURegisters(CPUState&, int indentation = 0);
     1476    void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
    14931477#endif // ENABLE(MASM_PROBE)
    14941478
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h

    r176031 r176134  
    3131#include "MacroAssemblerX86Common.h"
    3232
    33 #if ENABLE(MASM_PROBE)
    34 #include <wtf/StdLibExtras.h>
    35 #endif
    36 
    3733#define REPTACH_OFFSET_CALL_R11 3
    3834
     
    841837    }
    842838
    843 #if ENABLE(MASM_PROBE)
    844     // This function emits code to preserve the CPUState (e.g. registers),
    845     // call a user supplied probe function, and restore the CPUState before
    846     // continuing with other JIT generated code.
    847     //
    848     // The user supplied probe function will be called with a single pointer to
    849     // a ProbeContext struct (defined above) which contains, among other things,
    850     // the preserved CPUState. This allows the user probe function to inspect
    851     // the CPUState at that point in the JIT generated code.
    852     //
    853     // If the user probe function alters the register values in the ProbeContext,
    854     // the altered values will be loaded into the CPU registers when the probe
    855     // returns.
    856     //
    857     // The ProbeContext is stack allocated and is only valid for the duration
    858     // of the call to the user probe function.
    859 
    860     void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0);
    861 #endif // ENABLE(MASM_PROBE)
    862 
    863839private:
    864840    friend class LinkBuffer;
     
    882858        X86Assembler::repatchPointer(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11).dataLocation(), destination.executableAddress());
    883859    }
    884 
    885 #if ENABLE(MASM_PROBE)
    886     inline TrustedImm64 trustedImm64FromPtr(void* ptr)
    887     {
    888         return TrustedImm64(TrustedImmPtr(ptr));
    889     }
    890 
    891     inline TrustedImm64 trustedImm64FromPtr(ProbeFunction function)
    892     {
    893         return TrustedImm64(TrustedImmPtr(reinterpret_cast<void*>(function)));
    894     }
    895 
    896     inline TrustedImm64 trustedImm64FromPtr(void (*function)())
    897     {
    898         return TrustedImm64(TrustedImmPtr(reinterpret_cast<void*>(function)));
    899     }
    900 #endif
    901860};
    902861
    903 #if ENABLE(MASM_PROBE)
    904 
    905 extern "C" void ctiMasmProbeTrampoline();
    906 
    907 // What code is emitted for the probe?
    908 // ==================================
    909 // We want to keep the size of the emitted probe invocation code as compact as
    910 // possible to minimize the perturbation to the JIT generated code. However,
    911 // we also need to preserve the CPU registers and set up the ProbeContext to be
    912 // passed to the user probe function.
    913 //
    914 // Hence, we do only the minimum here to preserve a scratch register (i.e. rax
    915 // in this case) and the stack pointer (i.e. rsp), and pass the probe arguments.
    916 // We'll let the ctiMasmProbeTrampoline handle the rest of the probe invocation
    917 // work i.e. saving the CPUState (and setting up the ProbeContext), calling the
    918 // user probe function, and restoring the CPUState before returning to JIT
    919 // generated code.
    920 //
    921 // What values are in the saved registers?
    922 // ======================================
    923 // Conceptually, the saved registers should contain values as if the probe
    924 // is not present in the JIT generated code. Hence, they should contain values
    925 // that are expected at the start of the instruction immediately following the
    926 // probe.
    927 //
    928 // Specifcally, the saved stack pointer register will point to the stack
    929 // position before we push the ProbeContext frame. The saved rip will point to
    930 // the address of the instruction immediately following the probe.
    931 
    932 inline void MacroAssemblerX86_64::probe(MacroAssemblerX86_64::ProbeFunction function, void* arg1, void* arg2)
    933 {
    934     push(RegisterID::esp);
    935     push(RegisterID::eax);
    936     move(trustedImm64FromPtr(arg2), RegisterID::eax);
    937     push(RegisterID::eax);
    938     move(trustedImm64FromPtr(arg1), RegisterID::eax);
    939     push(RegisterID::eax);
    940     move(trustedImm64FromPtr(function), RegisterID::eax);
    941     push(RegisterID::eax);
    942     move(trustedImm64FromPtr(ctiMasmProbeTrampoline), RegisterID::eax);
    943     call(RegisterID::eax);
    944 }
    945 #endif // ENABLE(MASM_PROBE)
    946 
    947862} // namespace JSC
    948863
  • trunk/Source/JavaScriptCore/jit/JITStubsARMv7.h

    r176031 r176134  
    9595#define PROBE_CPU_D14_OFFSET (PROBE_FIRST_FPREG_OFFSET + (14 * FPREG_SIZE))
    9696#define PROBE_CPU_D15_OFFSET (PROBE_FIRST_FPREG_OFFSET + (15 * FPREG_SIZE))
    97 
    98 #if CPU(APPLE_ARMV7S)
    9997#define PROBE_CPU_D16_OFFSET (PROBE_FIRST_FPREG_OFFSET + (16 * FPREG_SIZE))
    10098#define PROBE_CPU_D17_OFFSET (PROBE_FIRST_FPREG_OFFSET + (17 * FPREG_SIZE))
     
    114112#define PROBE_CPU_D31_OFFSET (PROBE_FIRST_FPREG_OFFSET + (31 * FPREG_SIZE))
    115113#define PROBE_SIZE (PROBE_FIRST_FPREG_OFFSET + (32 * FPREG_SIZE))
    116 #else
    117 #define PROBE_SIZE (PROBE_FIRST_FPREG_OFFSET + (16 * FPREG_SIZE))
    118 #endif // CPU(APPLE_ARMV7S)
    119 
    120114
    121115// These ASSERTs remind you that if you change the layout of ProbeContext,
     
    163157COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d15) == PROBE_CPU_D15_OFFSET, ProbeContext_cpu_d15_offset_matches_ctiMasmProbeTrampoline);
    164158
    165 #if CPU(APPLE_ARMV7S)
    166159COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d16) == PROBE_CPU_D16_OFFSET, ProbeContext_cpu_d16_offset_matches_ctiMasmProbeTrampoline);
    167160COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d17) == PROBE_CPU_D17_OFFSET, ProbeContext_cpu_d17_offset_matches_ctiMasmProbeTrampoline);
     
    180173COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d30) == PROBE_CPU_D30_OFFSET, ProbeContext_cpu_d30_offset_matches_ctiMasmProbeTrampoline);
    181174COMPILE_ASSERT(PROBE_OFFSETOF(cpu.d31) == PROBE_CPU_D31_OFFSET, ProbeContext_cpu_d31_offset_matches_ctiMasmProbeTrampoline);
    182 #endif // CPU(APPLE_ARMV7S)
    183175
    184176COMPILE_ASSERT(sizeof(MacroAssembler::ProbeContext) == PROBE_SIZE, ProbeContext_size_matches_ctiMasmProbeTrampoline);
     
    239231
    240232    "add       ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_D0_OFFSET) "\n"
    241 #if CPU(APPLE_ARMV7S)
    242233    "vstmia.64 ip, { d0-d31 }" "\n"
    243 #else
    244     "vstmia.64 ip, { d0-d15 }" "\n"
    245 #endif
    246234
    247235    "mov       fp, sp" "\n" // Save the ProbeContext*.
     
    256244    // out of the ProbeContext before returning.
    257245
    258 #if CPU(APPLE_ARMV7S)
    259246    "add       ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_D31_OFFSET + FPREG_SIZE) "\n"
    260247    "vldmdb.64 ip!, { d0-d31 }" "\n"
    261 #else
    262     "add       ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_D15_OFFSET + FPREG_SIZE) "\n"
    263     "vldmdb.64 ip!, { d0-d15 }" "\n"
    264 #endif
    265248    "add       ip, sp, #" STRINGIZE_VALUE_OF(PROBE_CPU_R11_OFFSET + GPREG_SIZE) "\n"
    266249    "ldmdb     ip, { r0-r11 }" "\n"
Note: See TracChangeset for help on using the changeset viewer.