diff options
Diffstat (limited to 'Source/JavaScriptCore/assembler/AbstractMacroAssembler.h')
-rw-r--r-- | Source/JavaScriptCore/assembler/AbstractMacroAssembler.h | 341 |
1 files changed, 97 insertions, 244 deletions
diff --git a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h index 1e2d295c9..28537201b 100644 --- a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h +++ b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2012, 2014-2016 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2012 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,23 +26,21 @@ #ifndef AbstractMacroAssembler_h #define AbstractMacroAssembler_h -#include "AbortReason.h" #include "AssemblerBuffer.h" #include "CodeLocation.h" #include "MacroAssemblerCodeRef.h" #include "Options.h" +#include "WeakRandom.h" #include <wtf/CryptographicallyRandomNumber.h> #include <wtf/Noncopyable.h> -#include <wtf/SharedTask.h> -#include <wtf/WeakRandom.h> #if ENABLE(ASSEMBLER) namespace JSC { -inline bool isARMv7IDIVSupported() +inline bool isARMv7s() { -#if HAVE(ARM_IDIV_INSTRUCTIONS) +#if CPU(APPLE_ARMV7S) return true; #else return false; @@ -67,48 +65,32 @@ inline bool isX86() #endif } -inline bool isX86_64() +inline bool optimizeForARMv7s() { -#if CPU(X86_64) - return true; -#else - return false; -#endif -} - -inline bool optimizeForARMv7IDIVSupported() -{ - return isARMv7IDIVSupported() && Options::useArchitectureSpecificOptimizations(); + return isARMv7s() && Options::enableArchitectureSpecificOptimizations(); } inline bool optimizeForARM64() { - return isARM64() && Options::useArchitectureSpecificOptimizations(); + return isARM64() && Options::enableArchitectureSpecificOptimizations(); } inline bool optimizeForX86() { - return isX86() && Options::useArchitectureSpecificOptimizations(); + return isX86() && Options::enableArchitectureSpecificOptimizations(); } -inline bool optimizeForX86_64() -{ - return isX86_64() && Options::useArchitectureSpecificOptimizations(); -} - -class AllowMacroScratchRegisterUsage; -class DisallowMacroScratchRegisterUsage; class LinkBuffer; +class RepatchBuffer; class Watchpoint; namespace DFG { struct OSRExit; } -template <class AssemblerType, class MacroAssemblerType> +template <class AssemblerType> class AbstractMacroAssembler { public: friend class JITWriteBarrierBase; - typedef AbstractMacroAssembler<AssemblerType, MacroAssemblerType> AbstractMacroAssemblerType; typedef AssemblerType AssemblerType_T; typedef MacroAssemblerCodePtr CodePtr; @@ -119,11 +101,11 @@ public: typedef typename AssemblerType::RegisterID RegisterID; typedef typename AssemblerType::FPRegisterID FPRegisterID; - static constexpr RegisterID firstRegister() { return AssemblerType::firstRegister(); } - static constexpr RegisterID lastRegister() { return AssemblerType::lastRegister(); } + static RegisterID firstRegister() { return AssemblerType::firstRegister(); } + static RegisterID lastRegister() { return AssemblerType::lastRegister(); } - static constexpr FPRegisterID firstFPRegister() { return AssemblerType::firstFPRegister(); } - static constexpr FPRegisterID lastFPRegister() { return AssemblerType::lastFPRegister(); } + static FPRegisterID firstFPRegister() { return AssemblerType::firstFPRegister(); } + static FPRegisterID lastFPRegister() { return AssemblerType::lastFPRegister(); } // Section 1: MacroAssembler operand types // @@ -158,7 +140,7 @@ public: { return Address(base, offset + additionalOffset); } - + RegisterID base; int32_t offset; }; @@ -221,11 +203,6 @@ public: RegisterID index; Scale scale; int32_t offset; - - BaseIndex withOffset(int32_t additionalOffset) - { - return BaseIndex(base, index, scale, offset + additionalOffset); - } }; // AbsoluteAddress: @@ -377,7 +354,7 @@ public: // A Label records a point in the generated instruction stream, typically such that // it may be used as a destination for a jump. class Label { - template<class TemplateAssemblerType, class TemplateMacroAssemblerType> + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; friend struct DFG::OSRExit; friend class Jump; @@ -390,14 +367,12 @@ public: { } - Label(AbstractMacroAssemblerType* masm) + Label(AbstractMacroAssembler<AssemblerType>* masm) : m_label(masm->m_assembler.label()) { masm->invalidateAllTempRegisters(); } - bool operator==(const Label& other) const { return m_label == other.m_label; } - bool isSet() const { return m_label.isSet(); } private: AssemblerLabel m_label; @@ -414,7 +389,7 @@ public: // // addPtr(TrustedImmPtr(i), a, b) class ConvertibleLoadLabel { - template<class TemplateAssemblerType, class TemplateMacroAssemblerType> + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; friend class LinkBuffer; @@ -423,7 +398,7 @@ public: { } - ConvertibleLoadLabel(AbstractMacroAssemblerType* masm) + ConvertibleLoadLabel(AbstractMacroAssembler<AssemblerType>* masm) : m_label(masm->m_assembler.labelIgnoringWatchpoints()) { } @@ -438,7 +413,7 @@ public: // A DataLabelPtr is used to refer to a location in the code containing a pointer to be // patched after the code has been generated. class DataLabelPtr { - template<class TemplateAssemblerType, class TemplateMacroAssemblerType> + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; friend class LinkBuffer; public: @@ -446,7 +421,7 @@ public: { } - DataLabelPtr(AbstractMacroAssemblerType* masm) + DataLabelPtr(AbstractMacroAssembler<AssemblerType>* masm) : m_label(masm->m_assembler.label()) { } @@ -459,10 +434,10 @@ public: // DataLabel32: // - // A DataLabel32 is used to refer to a location in the code containing a 32-bit constant to be + // A DataLabelPtr is used to refer to a location in the code containing a pointer to be // patched after the code has been generated. class DataLabel32 { - template<class TemplateAssemblerType, class TemplateMacroAssemblerType> + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; friend class LinkBuffer; public: @@ -470,7 +445,7 @@ public: { } - DataLabel32(AbstractMacroAssemblerType* masm) + DataLabel32(AbstractMacroAssembler<AssemblerType>* masm) : m_label(masm->m_assembler.label()) { } @@ -486,7 +461,7 @@ public: // 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, class TemplateMacroAssemblerType> + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; friend class LinkBuffer; public: @@ -494,7 +469,7 @@ public: { } - DataLabelCompact(AbstractMacroAssemblerType* masm) + DataLabelCompact(AbstractMacroAssembler<AssemblerType>* masm) : m_label(masm->m_assembler.label()) { } @@ -517,7 +492,7 @@ public: // relative offset such that when executed it will call to the desired // destination. class Call { - template<class TemplateAssemblerType, class TemplateMacroAssemblerType> + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; public: @@ -525,9 +500,7 @@ public: None = 0x0, Linkable = 0x1, Near = 0x2, - Tail = 0x4, LinkableNear = 0x3, - LinkableNearTail = 0x7, }; Call() @@ -563,7 +536,7 @@ public: // relative offset such that when executed it will jump to the desired // destination. class Jump { - template<class TemplateAssemblerType, class TemplateMacroAssemblerType> + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; friend class Call; friend struct DFG::OSRExit; @@ -628,7 +601,7 @@ public: return result; } - void link(AbstractMacroAssemblerType* masm) const + void link(AbstractMacroAssembler<AssemblerType>* masm) const { masm->invalidateAllTempRegisters(); @@ -652,7 +625,7 @@ public: #endif } - void linkTo(Label label, AbstractMacroAssemblerType* masm) const + void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) const { #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION) masm->checkRegisterAllocationAgainstBranchRange(label.m_label.m_offset, m_label.m_offset); @@ -720,11 +693,10 @@ public: JumpList(Jump jump) { - if (jump.isSet()) - append(jump); + append(jump); } - void link(AbstractMacroAssemblerType* masm) + void link(AbstractMacroAssembler<AssemblerType>* masm) { size_t size = m_jumps.size(); for (size_t i = 0; i < size; ++i) @@ -732,7 +704,7 @@ public: m_jumps.clear(); } - void linkTo(Label label, AbstractMacroAssemblerType* masm) + void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) { size_t size = m_jumps.size(); for (size_t i = 0; i < size; ++i) @@ -862,187 +834,12 @@ public: AssemblerType::cacheFlush(code, size); } -#if ENABLE(MASM_PROBE) - - struct CPUState { - #define DECLARE_REGISTER(_type, _regName) \ - _type _regName; - FOR_EACH_CPU_REGISTER(DECLARE_REGISTER) - #undef DECLARE_REGISTER - - static const char* gprName(RegisterID regID) - { - switch (regID) { - #define DECLARE_REGISTER(_type, _regName) \ - case RegisterID::_regName: \ - return #_regName; - FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER) - #undef DECLARE_REGISTER - default: - RELEASE_ASSERT_NOT_REACHED(); - } - } - - static const char* fprName(FPRegisterID regID) - { - switch (regID) { - #define DECLARE_REGISTER(_type, _regName) \ - case FPRegisterID::_regName: \ - return #_regName; - FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER) - #undef DECLARE_REGISTER - default: - RELEASE_ASSERT_NOT_REACHED(); - } - } - - void*& gpr(RegisterID regID) - { - switch (regID) { - #define DECLARE_REGISTER(_type, _regName) \ - case RegisterID::_regName: \ - return _regName; - FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER) - #undef DECLARE_REGISTER - default: - RELEASE_ASSERT_NOT_REACHED(); - } - } - - double& fpr(FPRegisterID regID) - { - switch (regID) { - #define DECLARE_REGISTER(_type, _regName) \ - case FPRegisterID::_regName: \ - return _regName; - FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER) - #undef DECLARE_REGISTER - default: - RELEASE_ASSERT_NOT_REACHED(); - } - } - }; - - struct ProbeContext; - typedef void (*ProbeFunction)(struct ProbeContext*); - - struct ProbeContext { - ProbeFunction probeFunction; - void* arg1; - void* arg2; - CPUState cpu; - - // Convenience methods: - void*& gpr(RegisterID regID) { return cpu.gpr(regID); } - double& fpr(FPRegisterID regID) { return cpu.fpr(regID); } - const char* gprName(RegisterID regID) { return cpu.gprName(regID); } - const char* fprName(FPRegisterID regID) { return cpu.fprName(regID); } - }; - - // This function emits code to preserve the CPUState (e.g. registers), - // call a user supplied probe function, and restore the CPUState before - // continuing with other JIT generated code. - // - // The user supplied probe function will be called with a single pointer to - // a ProbeContext struct (defined above) which contains, among other things, - // the preserved CPUState. This allows the user probe function to inspect - // the CPUState at that point in the JIT generated code. - // - // If the user probe function alters the register values in the ProbeContext, - // the altered values will be loaded into the CPU registers when the probe - // returns. - // - // The ProbeContext is stack allocated and is only valid for the duration - // of the call to the user probe function. - // - // Note: probe() should be implemented by the target specific MacroAssembler. - // This prototype is only provided here to document the interface. - - void probe(ProbeFunction, void* arg1, void* arg2); - -#endif // ENABLE(MASM_PROBE) - AssemblerType m_assembler; - static void linkJump(void* code, Jump jump, CodeLocationLabel target) - { - AssemblerType::linkJump(code, jump.m_label, target.dataLocation()); - } - - static void linkPointer(void* code, AssemblerLabel label, void* value) - { - AssemblerType::linkPointer(code, label, value); - } - - static void* getLinkerAddress(void* code, AssemblerLabel label) - { - return AssemblerType::getRelocatedAddress(code, label); - } - - static unsigned getLinkerCallReturnOffset(Call call) - { - return AssemblerType::getCallReturnOffset(call.m_label); - } - - static void repatchJump(CodeLocationJump jump, CodeLocationLabel destination) - { - AssemblerType::relinkJump(jump.dataLocation(), destination.dataLocation()); - } - - static void repatchNearCall(CodeLocationNearCall nearCall, CodeLocationLabel destination) - { - switch (nearCall.callMode()) { - case NearCallMode::Tail: - AssemblerType::relinkJump(nearCall.dataLocation(), destination.dataLocation()); - return; - case NearCallMode::Regular: - AssemblerType::relinkCall(nearCall.dataLocation(), destination.executableAddress()); - return; - } - RELEASE_ASSERT_NOT_REACHED(); - } - - 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); - } - - static void repatchPointer(CodeLocationDataLabelPtr dataLabelPtr, void* value) - { - AssemblerType::repatchPointer(dataLabelPtr.dataLocation(), value); - } - - static void* readPointer(CodeLocationDataLabelPtr dataLabelPtr) - { - return AssemblerType::readPointer(dataLabelPtr.dataLocation()); - } - - static void replaceWithLoad(CodeLocationConvertibleLoad label) - { - AssemblerType::replaceWithLoad(label.dataLocation()); - } - - static void replaceWithAddressComputation(CodeLocationConvertibleLoad label) - { - AssemblerType::replaceWithAddressComputation(label.dataLocation()); - } - - template<typename Functor> - void addLinkTask(const Functor& functor) - { - m_linkTasks.append(createSharedTask<void(LinkBuffer&)>(functor)); - } - protected: AbstractMacroAssembler() : m_randomSource(cryptographicallyRandomNumber()) { - invalidateAllTempRegisters(); } uint32_t random() @@ -1077,7 +874,7 @@ protected: friend class Label; public: - CachedTempRegister(AbstractMacroAssemblerType* masm, RegisterID registerID) + CachedTempRegister(AbstractMacroAssembler<AssemblerType>* masm, RegisterID registerID) : m_masm(masm) , m_registerID(registerID) , m_value(0) @@ -1105,7 +902,7 @@ protected: ALWAYS_INLINE void invalidate() { m_masm->clearTempRegisterValid(m_validBit); } private: - AbstractMacroAssemblerType* m_masm; + AbstractMacroAssembler<AssemblerType>* m_masm; RegisterID m_registerID; intptr_t m_value; unsigned m_validBit; @@ -1131,15 +928,71 @@ protected: m_tempRegistersValidBits |= registerMask; } - friend class AllowMacroScratchRegisterUsage; - friend class DisallowMacroScratchRegisterUsage; unsigned m_tempRegistersValidBits; - bool m_allowScratchRegister { true }; - - Vector<RefPtr<SharedTask<void(LinkBuffer&)>>> m_linkTasks; friend class LinkBuffer; -}; // class AbstractMacroAssembler + friend class RepatchBuffer; + + static void linkJump(void* code, Jump jump, CodeLocationLabel target) + { + AssemblerType::linkJump(code, jump.m_label, target.dataLocation()); + } + + static void linkPointer(void* code, AssemblerLabel label, void* value) + { + AssemblerType::linkPointer(code, label, value); + } + + static void* getLinkerAddress(void* code, AssemblerLabel label) + { + return AssemblerType::getRelocatedAddress(code, label); + } + + static unsigned getLinkerCallReturnOffset(Call call) + { + return AssemblerType::getCallReturnOffset(call.m_label); + } + + static void repatchJump(CodeLocationJump jump, CodeLocationLabel destination) + { + AssemblerType::relinkJump(jump.dataLocation(), destination.dataLocation()); + } + + static void repatchNearCall(CodeLocationNearCall nearCall, CodeLocationLabel destination) + { + 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); + } + + static void repatchPointer(CodeLocationDataLabelPtr dataLabelPtr, void* value) + { + AssemblerType::repatchPointer(dataLabelPtr.dataLocation(), value); + } + + static void* readPointer(CodeLocationDataLabelPtr dataLabelPtr) + { + return AssemblerType::readPointer(dataLabelPtr.dataLocation()); + } + + static void replaceWithLoad(CodeLocationConvertibleLoad label) + { + AssemblerType::replaceWithLoad(label.dataLocation()); + } + + static void replaceWithAddressComputation(CodeLocationConvertibleLoad label) + { + AssemblerType::replaceWithAddressComputation(label.dataLocation()); + } +}; } // namespace JSC |