X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/b80e619319b1def83d1e8b4f84042b661be1be7f..1df5f87f1309a8daa30dabdee855f48ae40d14ab:/assembler/AbstractMacroAssembler.h diff --git a/assembler/AbstractMacroAssembler.h b/assembler/AbstractMacroAssembler.h index 5db2cb9..7d9d092 100644 --- a/assembler/AbstractMacroAssembler.h +++ b/assembler/AbstractMacroAssembler.h @@ -26,8 +26,8 @@ #ifndef AbstractMacroAssembler_h #define AbstractMacroAssembler_h -#include -#include +#include "CodeLocation.h" +#include "MacroAssemblerCodeRef.h" #include #include @@ -41,6 +41,7 @@ class RepatchBuffer; template class AbstractMacroAssembler { public: + friend class JITWriteBarrierBase; typedef AssemblerType AssemblerType_T; typedef MacroAssemblerCodePtr CodePtr; @@ -49,9 +50,6 @@ public: class Jump; typedef typename AssemblerType::RegisterID RegisterID; - typedef typename AssemblerType::JmpSrc JmpSrc; - typedef typename AssemblerType::JmpDst JmpDst; - // Section 1: MacroAssembler operand types // @@ -145,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(const void* value) + struct TrustedImmPtr { + explicit TrustedImmPtr(const void* value) : m_value(value) { } @@ -172,14 +170,21 @@ public: const void* m_value; }; - // Imm32: + struct ImmPtr : public TrustedImmPtr { + explicit ImmPtr(const void* value) + : TrustedImmPtr(value) + { + } + }; + + // 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 CPU(ARM) || CPU(MIPS) , m_isPointer(false) @@ -188,7 +193,7 @@ public: } #if !CPU(X86_64) - explicit Imm32(ImmPtr ptr) + explicit TrustedImm32(TrustedImmPtr ptr) : m_value(ptr.asIntptr()) #if CPU(ARM) || CPU(MIPS) , m_isPointer(true) @@ -211,6 +216,19 @@ public: }; + 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 @@ -240,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: @@ -264,8 +281,10 @@ public: { } + bool isSet() const { return m_label.isSet(); } + private: - JmpDst m_label; + AssemblerLabel m_label; }; // DataLabel32: @@ -286,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 + friend class AbstractMacroAssembler; + friend class LinkBuffer; + public: + DataLabelCompact() + { + } + + DataLabelCompact(AbstractMacroAssembler* masm) + : m_label(masm->m_assembler.label()) + { + } + + DataLabelCompact(AssemblerLabel label) + : m_label(label) + { + } + private: - JmpDst m_label; + AssemblerLabel m_label; }; // Call: @@ -313,7 +361,7 @@ public: { } - Call(JmpSrc jmp, Flags flags) + Call(AssemblerLabel jmp, Flags flags) : m_jmp(jmp) , m_flags(flags) { @@ -329,7 +377,7 @@ public: return Call(jump.m_jmp, Linkable); } - JmpSrc m_jmp; + AssemblerLabel m_jmp; private: Flags m_flags; }; @@ -350,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* masm) +#else + Jump(AssemblerLabel jmp) + : m_jmp(jmp) + { + } +#endif + + void link(AbstractMacroAssembler* 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* masm) + void linkTo(Label label, AbstractMacroAssembler* 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: @@ -410,6 +482,11 @@ public: return !m_jumps.size(); } + void clear() + { + m_jumps.clear(); + } + const JumpVector& jumps() { return m_jumps; } private: @@ -418,11 +495,6 @@ public: // Section 3: Misc admin methods - size_t size() - { - return m_assembler.size(); - } - Label label() { return Label(this); @@ -458,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) { @@ -473,10 +550,19 @@ 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; @@ -488,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); } @@ -518,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); @@ -527,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()); } };