]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - assembler/AbstractMacroAssembler.h
JavaScriptCore-903.5.tar.gz
[apple/javascriptcore.git] / assembler / AbstractMacroAssembler.h
index 0b23d02e8ba582ca5806347133a0c0d8de702baa..7d9d0925c5ee42931c3f7568eec49d7dda05049f 100644 (file)
 #ifndef AbstractMacroAssembler_h
 #define AbstractMacroAssembler_h
 
-#include <wtf/Platform.h>
-
-#include <MacroAssemblerCodeRef.h>
-#include <CodeLocation.h>
+#include "CodeLocation.h"
+#include "MacroAssemblerCodeRef.h"
 #include <wtf/Noncopyable.h>
 #include <wtf/UnusedParam.h>
 
@@ -43,6 +41,7 @@ class RepatchBuffer;
 template <class AssemblerType>
 class AbstractMacroAssembler {
 public:
+    friend class JITWriteBarrierBase;
     typedef AssemblerType AssemblerType_T;
 
     typedef MacroAssemblerCodePtr CodePtr;
@@ -51,10 +50,6 @@ public:
     class Jump;
 
     typedef typename AssemblerType::RegisterID RegisterID;
-    typedef typename AssemblerType::FPRegisterID FPRegisterID;
-    typedef typename AssemblerType::JmpSrc JmpSrc;
-    typedef typename AssemblerType::JmpDst JmpDst;
-
 
     // Section 1: MacroAssembler operand types
     //
@@ -83,6 +78,17 @@ public:
         int32_t offset;
     };
 
+    struct ExtendedAddress {
+        explicit ExtendedAddress(RegisterID base, intptr_t offset = 0)
+            : base(base)
+            , offset(offset)
+        {
+        }
+        
+        RegisterID base;
+        intptr_t offset;
+    };
+
     // ImplicitAddress:
     //
     // This class is used for explicit 'load' and 'store' operations
@@ -137,21 +143,21 @@ public:
     // Describes an memory operand given by a pointer.  For regular load & store
     // operations an unwrapped void* will be used, rather than using this.
     struct AbsoluteAddress {
-        explicit AbsoluteAddress(void* ptr)
+        explicit AbsoluteAddress(const void* ptr)
             : m_ptr(ptr)
         {
         }
 
-        void* m_ptr;
+        const void* m_ptr;
     };
 
-    // ImmPtr:
+    // TrustedImmPtr:
     //
     // A pointer sized immediate operand to an instruction - this is wrapped
     // in a class requiring explicit construction in order to differentiate
     // from pointers used as absolute addresses to memory operations
-    struct ImmPtr {
-        explicit ImmPtr(void* value)
+    struct TrustedImmPtr {
+        explicit TrustedImmPtr(const void* value)
             : m_value(value)
         {
         }
@@ -161,28 +167,35 @@ public:
             return reinterpret_cast<intptr_t>(m_value);
         }
 
-        void* m_value;
+        const void* m_value;
+    };
+
+    struct ImmPtr : public TrustedImmPtr {
+        explicit ImmPtr(const void* value)
+            : TrustedImmPtr(value)
+        {
+        }
     };
 
-    // Imm32:
+    // TrustedImm32:
     //
     // A 32bit immediate operand to an instruction - this is wrapped in a
     // class requiring explicit construction in order to prevent RegisterIDs
     // (which are implemented as an enum) from accidentally being passed as
     // immediate values.
-    struct Imm32 {
-        explicit Imm32(int32_t value)
+    struct TrustedImm32 {
+        explicit TrustedImm32(int32_t value)
             : m_value(value)
-#if PLATFORM_ARM_ARCH(7)
+#if CPU(ARM) || CPU(MIPS)
             , m_isPointer(false)
 #endif
         {
         }
 
-#if !PLATFORM(X86_64)
-        explicit Imm32(ImmPtr ptr)
+#if !CPU(X86_64)
+        explicit TrustedImm32(TrustedImmPtr ptr)
             : m_value(ptr.asIntptr())
-#if PLATFORM_ARM_ARCH(7)
+#if CPU(ARM) || CPU(MIPS)
             , m_isPointer(true)
 #endif
         {
@@ -190,18 +203,32 @@ public:
 #endif
 
         int32_t m_value;
-#if PLATFORM_ARM_ARCH(7)
+#if CPU(ARM) || CPU(MIPS)
         // We rely on being able to regenerate code to recover exception handling
         // information.  Since ARMv7 supports 16-bit immediates there is a danger
         // that if pointer values change the layout of the generated code will change.
         // To avoid this problem, always generate pointers (and thus Imm32s constructed
         // from ImmPtrs) with a code sequence that is able  to represent  any pointer
         // value - don't use a more compact form in these cases.
+        // Same for MIPS.
         bool m_isPointer;
 #endif
     };
 
 
+    struct Imm32 : public TrustedImm32 {
+        explicit Imm32(int32_t value)
+            : TrustedImm32(value)
+        {
+        }
+#if !CPU(X86_64)
+        explicit Imm32(TrustedImmPtr ptr)
+            : TrustedImm32(ptr)
+        {
+        }
+#endif
+    };
+    
     // Section 2: MacroAssembler code buffer handles
     //
     // The following types are used to reference items in the code buffer
@@ -231,10 +258,9 @@ public:
         {
         }
         
-        bool isUsed() const { return m_label.isUsed(); }
-        void used() { m_label.used(); }
+        bool isSet() const { return m_label.isSet(); }
     private:
-        JmpDst m_label;
+        AssemblerLabel m_label;
     };
 
     // DataLabelPtr:
@@ -255,8 +281,10 @@ public:
         {
         }
         
+        bool isSet() const { return m_label.isSet(); }
+        
     private:
-        JmpDst m_label;
+        AssemblerLabel m_label;
     };
 
     // DataLabel32:
@@ -277,8 +305,37 @@ public:
         {
         }
 
+        AssemblerLabel label() const { return m_label; }
+
+    private:
+        AssemblerLabel m_label;
+    };
+
+    // DataLabelCompact:
+    //
+    // A DataLabelCompact is used to refer to a location in the code containing a
+    // compact immediate to be patched after the code has been generated.
+    class DataLabelCompact {
+        template<class TemplateAssemblerType>
+        friend class AbstractMacroAssembler;
+        friend class LinkBuffer;
+    public:
+        DataLabelCompact()
+        {
+        }
+        
+        DataLabelCompact(AbstractMacroAssembler<AssemblerType>* masm)
+            : m_label(masm->m_assembler.label())
+        {
+        }
+    
+        DataLabelCompact(AssemblerLabel label)
+            : m_label(label)
+        {
+        }
+
     private:
-        JmpDst m_label;
+        AssemblerLabel m_label;
     };
 
     // Call:
@@ -304,7 +361,7 @@ public:
         {
         }
         
-        Call(JmpSrc jmp, Flags flags)
+        Call(AssemblerLabel jmp, Flags flags)
             : m_jmp(jmp)
             , m_flags(flags)
         {
@@ -320,8 +377,7 @@ public:
             return Call(jump.m_jmp, Linkable);
         }
 
-        JmpSrc m_jmp;
-
+        AssemblerLabel m_jmp;
     private:
         Flags m_flags;
     };
@@ -342,23 +398,47 @@ public:
         {
         }
         
-        Jump(JmpSrc jmp)    
+#if CPU(ARM_THUMB2)
+        // Fixme: this information should be stored in the instruction stream, not in the Jump object.
+        Jump(AssemblerLabel jmp, ARMv7Assembler::JumpType type, ARMv7Assembler::Condition condition = ARMv7Assembler::ConditionInvalid)
             : m_jmp(jmp)
+            , m_type(type)
+            , m_condition(condition)
         {
         }
-        
-        void link(AbstractMacroAssembler<AssemblerType>* masm)
+#else
+        Jump(AssemblerLabel jmp)    
+            : m_jmp(jmp)
         {
+        }
+#endif
+
+        void link(AbstractMacroAssembler<AssemblerType>* masm) const
+        {
+#if CPU(ARM_THUMB2)
+            masm->m_assembler.linkJump(m_jmp, masm->m_assembler.label(), m_type, m_condition);
+#else
             masm->m_assembler.linkJump(m_jmp, masm->m_assembler.label());
+#endif
         }
         
-        void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm)
+        void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) const
         {
+#if CPU(ARM_THUMB2)
+            masm->m_assembler.linkJump(m_jmp, label.m_label, m_type, m_condition);
+#else
             masm->m_assembler.linkJump(m_jmp, label.m_label);
+#endif
         }
 
+        bool isSet() const { return m_jmp.isSet(); }
+
     private:
-        JmpSrc m_jmp;
+        AssemblerLabel m_jmp;
+#if CPU(ARM_THUMB2)
+        ARMv7Assembler::JumpType m_type;
+        ARMv7Assembler::Condition m_condition;
+#endif
     };
 
     // JumpList:
@@ -402,6 +482,11 @@ public:
             return !m_jumps.size();
         }
         
+        void clear()
+        {
+            m_jumps.clear();
+        }
+        
         const JumpVector& jumps() { return m_jumps; }
 
     private:
@@ -410,17 +495,6 @@ public:
 
 
     // Section 3: Misc admin methods
-
-    static CodePtr trampolineAt(CodeRef ref, Label label)
-    {
-        return CodePtr(AssemblerType::getRelocatedAddress(ref.m_code.dataLocation(), label.m_label));
-    }
-
-    size_t size()
-    {
-        return m_assembler.size();
-    }
-
     Label label()
     {
         return Label(this);
@@ -456,6 +530,11 @@ public:
     {
         return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
     }
+    
+    ptrdiff_t differenceBetween(Label from, DataLabelCompact to)
+    {
+        return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
+    }
 
     ptrdiff_t differenceBetween(DataLabelPtr from, Jump to)
     {
@@ -472,6 +551,18 @@ public:
         return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
     }
 
+    // Temporary interface; likely to be removed, since may be hard to port to all architectures.
+#if CPU(X86) || CPU(X86_64)
+    void rewindToLabel(Label rewindTo) { m_assembler.rewindToLabel(rewindTo.m_label); }
+#endif
+
+    void beginUninterruptedSequence() { }
+    void endUninterruptedSequence() { }
+
+#ifndef NDEBUG
+    unsigned debugOffset() { return m_assembler.debugOffset(); }
+#endif
+
 protected:
     AssemblerType m_assembler;
 
@@ -483,17 +574,12 @@ protected:
         AssemblerType::linkJump(code, jump.m_jmp, target.dataLocation());
     }
 
-    static void linkPointer(void* code, typename AssemblerType::JmpDst label, void* value)
+    static void linkPointer(void* code, AssemblerLabel label, void* value)
     {
         AssemblerType::linkPointer(code, label, value);
     }
 
-    static void* getLinkerAddress(void* code, typename AssemblerType::JmpSrc label)
-    {
-        return AssemblerType::getRelocatedAddress(code, label);
-    }
-
-    static void* getLinkerAddress(void* code, typename AssemblerType::JmpDst label)
+    static void* getLinkerAddress(void* code, AssemblerLabel label)
     {
         return AssemblerType::getRelocatedAddress(code, label);
     }
@@ -513,6 +599,11 @@ protected:
         AssemblerType::relinkCall(nearCall.dataLocation(), destination.executableAddress());
     }
 
+    static void repatchCompact(CodeLocationDataLabelCompact dataLabelCompact, int32_t value)
+    {
+        AssemblerType::repatchCompact(dataLabelCompact.dataLocation(), value);
+    }
+    
     static void repatchInt32(CodeLocationDataLabel32 dataLabel32, int32_t value)
     {
         AssemblerType::repatchInt32(dataLabel32.dataLocation(), value);
@@ -522,10 +613,10 @@ protected:
     {
         AssemblerType::repatchPointer(dataLabelPtr.dataLocation(), value);
     }
-
-    static void repatchLoadPtrToLEA(CodeLocationInstruction instruction)
+    
+    static void* readPointer(CodeLocationDataLabelPtr dataLabelPtr)
     {
-        AssemblerType::repatchLoadPtrToLEA(instruction.dataLocation());
+        return AssemblerType::readPointer(dataLabelPtr.dataLocation());
     }
 };