Remove branch compaction #ifdef
Since the #ifdef for ARMv7 and ARM64 makes it impossible to cross compile, we need to replace it with a template specialization of LinkBuffer. The "old" LinkBuffer becomes LinkBufferBase, then there's a generic LinkBuffer that's a sub-class of LinkBufferBase. Then there's a BranchCompactingLinkBuffer template that implements the compaction and two ARMv7 and ARM64 specializations of LinkBuffer<T> end up being sub-classes of BranchCompactingLinkBuffer instead of LinkBufferBase. Change-Id: Ib62fe24aa6c3570dfa311edc39fde6fb5975f3cc Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
64f21fc782
commit
4eca12e9f5
|
@ -47,8 +47,10 @@
|
|||
namespace JSC {
|
||||
|
||||
class JumpReplacementWatchpoint;
|
||||
template <typename, template <typename> class>
|
||||
class LinkBufferBase;
|
||||
template <typename>
|
||||
class LinkBuffer;
|
||||
class BranchCompactingLinkBuffer;
|
||||
class RepatchBuffer;
|
||||
class Watchpoint;
|
||||
namespace DFG {
|
||||
|
@ -326,7 +328,7 @@ public:
|
|||
friend class Jump;
|
||||
friend class JumpReplacementWatchpoint;
|
||||
friend class MacroAssemblerCodeRef;
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
friend class Watchpoint;
|
||||
|
||||
public:
|
||||
|
@ -357,7 +359,7 @@ public:
|
|||
class ConvertibleLoadLabel {
|
||||
template<class TemplateAssemblerType>
|
||||
friend class AbstractMacroAssembler;
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
|
||||
public:
|
||||
ConvertibleLoadLabel()
|
||||
|
@ -381,7 +383,7 @@ public:
|
|||
class DataLabelPtr {
|
||||
template<class TemplateAssemblerType>
|
||||
friend class AbstractMacroAssembler;
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
public:
|
||||
DataLabelPtr()
|
||||
{
|
||||
|
@ -405,7 +407,7 @@ public:
|
|||
class DataLabel32 {
|
||||
template<class TemplateAssemblerType>
|
||||
friend class AbstractMacroAssembler;
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
public:
|
||||
DataLabel32()
|
||||
{
|
||||
|
@ -429,7 +431,7 @@ public:
|
|||
class DataLabelCompact {
|
||||
template<class TemplateAssemblerType>
|
||||
friend class AbstractMacroAssembler;
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
public:
|
||||
DataLabelCompact()
|
||||
{
|
||||
|
@ -504,7 +506,7 @@ public:
|
|||
friend class AbstractMacroAssembler;
|
||||
friend class Call;
|
||||
friend struct DFG::OSRExit;
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
public:
|
||||
Jump()
|
||||
{
|
||||
|
@ -646,7 +648,7 @@ public:
|
|||
// A JumpList is a set of Jump objects.
|
||||
// All jumps in the set will be linked to the same destination.
|
||||
class JumpList {
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
|
||||
public:
|
||||
typedef Vector<Jump, 2> JumpVector;
|
||||
|
@ -820,7 +822,8 @@ protected:
|
|||
static bool shouldBlindForSpecificArch(uint64_t) { return true; }
|
||||
#endif
|
||||
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
template <typename> friend class BranchCompactingLinkBuffer;
|
||||
friend class RepatchBuffer;
|
||||
|
||||
static void linkJump(void* code, Jump jump, CodeLocationLabel target)
|
||||
|
|
|
@ -44,6 +44,12 @@ namespace JSC {
|
|||
|
||||
class JSGlobalData;
|
||||
|
||||
template <typename T>
|
||||
struct DefaultExecutableOffsetCalculator {
|
||||
template <typename Assembler>
|
||||
static T applyOffset(Assembler *, T src) { return src; }
|
||||
};
|
||||
|
||||
// LinkBuffer:
|
||||
//
|
||||
// This class assists in linking code generated by the macro assembler, once code generation
|
||||
|
@ -58,9 +64,9 @@ class JSGlobalData;
|
|||
// * The address of a Label pointing into the code may be resolved.
|
||||
// * The value referenced by a DataLabel may be set.
|
||||
//
|
||||
template <typename MacroAssembler>
|
||||
class LinkBuffer {
|
||||
WTF_MAKE_NONCOPYABLE(LinkBuffer);
|
||||
template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>
|
||||
class LinkBufferBase {
|
||||
WTF_MAKE_NONCOPYABLE(LinkBufferBase);
|
||||
typedef MacroAssemblerCodeRef CodeRef;
|
||||
typedef MacroAssemblerCodePtr CodePtr;
|
||||
typedef typename MacroAssembler::Label Label;
|
||||
|
@ -72,17 +78,10 @@ class LinkBuffer {
|
|||
typedef typename MacroAssembler::DataLabel32 DataLabel32;
|
||||
typedef typename MacroAssembler::DataLabelPtr DataLabelPtr;
|
||||
typedef typename MacroAssembler::ConvertibleLoadLabel ConvertibleLoadLabel;
|
||||
#if ENABLE(BRANCH_COMPACTION)
|
||||
typedef typename MacroAssembler::LinkRecord LinkRecord;
|
||||
typedef typename MacroAssembler::JumpLinkType JumpLinkType;
|
||||
#endif
|
||||
|
||||
public:
|
||||
LinkBuffer(JSGlobalData& globalData, MacroAssembler* masm, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed)
|
||||
LinkBufferBase(JSGlobalData& globalData, MacroAssembler* masm, JITCompilationEffort effort = JITCompilationMustSucceed)
|
||||
: m_size(0)
|
||||
#if ENABLE(BRANCH_COMPACTION)
|
||||
, m_initialSize(0)
|
||||
#endif
|
||||
, m_code(0)
|
||||
, m_assembler(masm)
|
||||
, m_globalData(&globalData)
|
||||
|
@ -91,10 +90,13 @@ public:
|
|||
, m_effort(effort)
|
||||
#endif
|
||||
{
|
||||
linkCode(ownerUID, effort);
|
||||
#ifdef NDEBUG
|
||||
UNUSED_PARAM(effort)
|
||||
#endif
|
||||
// Simon: Moved this to the sub-classes linkCode(ownerUID, effort);
|
||||
}
|
||||
|
||||
~LinkBuffer()
|
||||
~LinkBufferBase()
|
||||
{
|
||||
ASSERT(m_completed || (!m_executableMemory && m_effort == JITCompilationCanFail));
|
||||
}
|
||||
|
@ -227,12 +229,10 @@ public:
|
|||
private:
|
||||
template <typename T> T applyOffset(T src)
|
||||
{
|
||||
#if ENABLE(BRANCH_COMPACTION)
|
||||
src.m_offset -= m_assembler->executableOffsetFor(src.m_offset);
|
||||
#endif
|
||||
return src;
|
||||
return ExecutableOffsetCalculator<T>::applyOffset(m_assembler, src);
|
||||
}
|
||||
|
||||
protected:
|
||||
// Keep this private! - the underlying code should only be obtained externally via finalizeCode().
|
||||
void* code()
|
||||
{
|
||||
|
@ -253,12 +253,10 @@ private:
|
|||
|
||||
RefPtr<ExecutableMemoryHandle> m_executableMemory;
|
||||
size_t m_size;
|
||||
#if ENABLE(BRANCH_COMPACTION)
|
||||
size_t m_initialSize;
|
||||
#endif
|
||||
void* m_code;
|
||||
MacroAssembler* m_assembler;
|
||||
JSGlobalData* m_globalData;
|
||||
protected:
|
||||
#ifndef NDEBUG
|
||||
bool m_completed;
|
||||
JITCompilationEffort m_effort;
|
||||
|
@ -293,16 +291,16 @@ private:
|
|||
FINALIZE_CODE_IF((Options::showDisassembly() || Options::showDFGDisassembly()), linkBufferReference, dataLogFArgumentsForHeading)
|
||||
|
||||
|
||||
template <typename MacroAssembler>
|
||||
inline typename LinkBuffer<MacroAssembler>::CodeRef LinkBuffer<MacroAssembler>::finalizeCodeWithoutDisassembly()
|
||||
template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>
|
||||
inline typename LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::CodeRef LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::finalizeCodeWithoutDisassembly()
|
||||
{
|
||||
performFinalization();
|
||||
|
||||
return CodeRef(m_executableMemory);
|
||||
}
|
||||
|
||||
template <typename MacroAssembler>
|
||||
inline typename LinkBuffer<MacroAssembler>::CodeRef LinkBuffer<MacroAssembler>::finalizeCodeWithDisassembly(const char* format, ...)
|
||||
template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>
|
||||
inline typename LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::CodeRef LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::finalizeCodeWithDisassembly(const char* format, ...)
|
||||
{
|
||||
ASSERT(Options::showDisassembly() || Options::showDFGDisassembly());
|
||||
|
||||
|
@ -327,18 +325,109 @@ inline typename LinkBuffer<MacroAssembler>::CodeRef LinkBuffer<MacroAssembler>::
|
|||
return result;
|
||||
}
|
||||
|
||||
template <typename MacroAssembler>
|
||||
inline void LinkBuffer<MacroAssembler>::linkCode(void* ownerUID, JITCompilationEffort effort)
|
||||
template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>
|
||||
inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::linkCode(void* ownerUID, JITCompilationEffort effort)
|
||||
{
|
||||
UNUSED_PARAM(ownerUID)
|
||||
UNUSED_PARAM(effort)
|
||||
ASSERT(!m_code);
|
||||
#if !ENABLE(BRANCH_COMPACTION)
|
||||
m_executableMemory = m_assembler->m_assembler.executableCopy(*m_globalData, ownerUID, effort);
|
||||
if (!m_executableMemory)
|
||||
return;
|
||||
m_code = m_executableMemory->start();
|
||||
m_size = m_assembler->m_assembler.codeSize();
|
||||
ASSERT(m_code);
|
||||
#else
|
||||
}
|
||||
|
||||
template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>
|
||||
inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::performFinalization()
|
||||
{
|
||||
// NOTE: This function is specialized in LinkBuffer<MacroAssemblerARMv7>
|
||||
#ifndef NDEBUG
|
||||
ASSERT(!m_completed);
|
||||
ASSERT(isValid());
|
||||
m_completed = true;
|
||||
#endif
|
||||
|
||||
ASSERT(m_size <= INT_MAX);
|
||||
ExecutableAllocator::makeExecutable(code(), static_cast<int>(m_size));
|
||||
MacroAssembler::cacheFlush(code(), m_size);
|
||||
}
|
||||
|
||||
template <typename MacroAssembler>
|
||||
class LinkBuffer : public LinkBufferBase<MacroAssembler, DefaultExecutableOffsetCalculator>
|
||||
{
|
||||
public:
|
||||
LinkBuffer(JSGlobalData& globalData, MacroAssembler* masm, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed)
|
||||
: LinkBufferBase<MacroAssembler, DefaultExecutableOffsetCalculator>(globalData, masm, effort)
|
||||
{
|
||||
this->linkCode(ownerUID, effort);
|
||||
}
|
||||
};
|
||||
|
||||
#if CPU(ARM_THUMB2) || CPU(ARM64)
|
||||
|
||||
template <typename T>
|
||||
struct BranchCompactingExecutableOffsetCalculator {
|
||||
template <typename Assembler>
|
||||
static T applyOffset(Assembler *as, T src) {
|
||||
src.m_offset -= as->executableOffsetFor(src.m_offset);
|
||||
return src;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename MacroAssembler>
|
||||
class BranchCompactingLinkBuffer : public LinkBufferBase<MacroAssembler, BranchCompactingExecutableOffsetCalculator>
|
||||
{
|
||||
public:
|
||||
BranchCompactingLinkBuffer(JSGlobalData& globalData, MacroAssembler* masm, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed)
|
||||
: LinkBufferBase<MacroAssembler, BranchCompactingExecutableOffsetCalculator>(globalData, masm, effort)
|
||||
{
|
||||
linkCode(ownerUID, effort);
|
||||
}
|
||||
|
||||
inline void performFinalization();
|
||||
|
||||
inline void linkCode(void* ownerUID, JITCompilationEffort);
|
||||
|
||||
private:
|
||||
using Base = LinkBufferBase<MacroAssembler, BranchCompactingExecutableOffsetCalculator>;
|
||||
#ifndef NDEBUG
|
||||
using Base::m_completed;
|
||||
#endif
|
||||
using Base::isValid;
|
||||
using Base::code;
|
||||
using Base::m_code;
|
||||
using Base::m_size;
|
||||
using Base::m_assembler;
|
||||
using Base::m_executableMemory;
|
||||
using Base::m_globalData;
|
||||
|
||||
using LinkRecord = typename MacroAssembler::LinkRecord;
|
||||
using JumpLinkType = typename MacroAssembler::JumpLinkType;
|
||||
|
||||
size_t m_initialSize = 0;
|
||||
};
|
||||
|
||||
template <typename MacroAssembler>
|
||||
inline void BranchCompactingLinkBuffer<MacroAssembler>::performFinalization()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
ASSERT(!m_completed);
|
||||
ASSERT(isValid());
|
||||
this->m_completed = true;
|
||||
#endif
|
||||
|
||||
ExecutableAllocator::makeExecutable(code(), m_initialSize);
|
||||
MacroAssembler::cacheFlush(code(), m_size);
|
||||
}
|
||||
|
||||
template <typename MacroAssembler>
|
||||
inline void BranchCompactingLinkBuffer<MacroAssembler>::linkCode(void* ownerUID, JITCompilationEffort effort)
|
||||
{
|
||||
UNUSED_PARAM(ownerUID)
|
||||
UNUSED_PARAM(effort)
|
||||
ASSERT(!m_code);
|
||||
m_initialSize = m_assembler->m_assembler.codeSize();
|
||||
m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, m_initialSize, ownerUID, effort);
|
||||
if (!m_executableMemory)
|
||||
|
@ -403,33 +492,32 @@ inline void LinkBuffer<MacroAssembler>::linkCode(void* ownerUID, JITCompilationE
|
|||
jumpsToLink.clear();
|
||||
m_size = writePtr + m_initialSize - readPtr;
|
||||
m_executableMemory->shrink(m_size);
|
||||
|
||||
#if DUMP_LINK_STATISTICS
|
||||
dumpLinkStatistics(m_code, m_initialSize, m_size);
|
||||
#endif
|
||||
#if DUMP_CODE
|
||||
dumpCode(m_code, m_size);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename MacroAssembler>
|
||||
inline void LinkBuffer<MacroAssembler>::performFinalization()
|
||||
#if CPU(ARM_THUMB2)
|
||||
template <>
|
||||
class LinkBuffer<JSC::MacroAssembler<MacroAssemblerARMv7>> : public BranchCompactingLinkBuffer<JSC::MacroAssembler<MacroAssemblerARMv7>>
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
ASSERT(!m_completed);
|
||||
ASSERT(isValid());
|
||||
m_completed = true;
|
||||
public:
|
||||
LinkBuffer(JSGlobalData& globalData, JSC::MacroAssembler<MacroAssemblerARMv7>* masm, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed)
|
||||
: BranchCompactingLinkBuffer<JSC::MacroAssembler<MacroAssemblerARMv7>>(globalData, masm, ownerUID, effort)
|
||||
{}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if ENABLE(BRANCH_COMPACTION)
|
||||
ExecutableAllocator::makeExecutable(code(), m_initialSize);
|
||||
#else
|
||||
ASSERT(m_size <= INT_MAX);
|
||||
ExecutableAllocator::makeExecutable(code(), static_cast<int>(m_size));
|
||||
#if CPU(ARM64)
|
||||
template <>
|
||||
class LinkBuffer<JSC::MacroAssembler<MacroAssemblerARM64>> : public BranchCompactingLinkBuffer<JSC::MacroAssembler<MacroAssemblerARM64>>
|
||||
{
|
||||
public:
|
||||
LinkBuffer(JSGlobalData& globalData, JSC::MacroAssembler<MacroAssemblerARM64>* masm, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed)
|
||||
: BranchCompactingLinkBuffer<JSC::MacroAssembler<JSC::MacroAssemblerARM64>>(globalData, masm, ownerUID, effort)
|
||||
{}
|
||||
};
|
||||
#endif
|
||||
MacroAssembler::cacheFlush(code(), m_size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace JSC
|
||||
|
||||
#endif // ENABLE(ASSEMBLER)
|
||||
|
|
|
@ -1349,7 +1349,7 @@ protected:
|
|||
}
|
||||
|
||||
private:
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
friend class RepatchBuffer;
|
||||
|
||||
void internalCompare32(RegisterID left, TrustedImm32 right)
|
||||
|
|
|
@ -3353,7 +3353,7 @@ private:
|
|||
return makeBranch(cond);
|
||||
}
|
||||
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
void recordLinkOffsets(int32_t regionStart, int32_t regionEnd, int32_t offset) {return m_assembler.recordLinkOffsets(regionStart, regionEnd, offset); }
|
||||
int executableOffsetFor(int location) { return m_assembler.executableOffsetFor(location); }
|
||||
|
||||
|
|
|
@ -1930,7 +1930,7 @@ protected:
|
|||
}
|
||||
|
||||
private:
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
friend class RepatchBuffer;
|
||||
|
||||
static void linkCall(void* code, Call call, FunctionPtr function)
|
||||
|
|
|
@ -2802,7 +2802,7 @@ private:
|
|||
// Otherwise, we can emit any number of instructions.
|
||||
bool m_fixedWidth;
|
||||
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
friend class RepatchBuffer;
|
||||
|
||||
static void linkCall(void* code, Call call, FunctionPtr function)
|
||||
|
|
|
@ -2278,7 +2278,7 @@ protected:
|
|||
return static_cast<SH4Assembler::Condition>(cond);
|
||||
}
|
||||
private:
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
friend class RepatchBuffer;
|
||||
|
||||
static void linkCall(void*, Call, FunctionPtr);
|
||||
|
|
|
@ -306,7 +306,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
friend class RepatchBuffer;
|
||||
|
||||
static void linkCall(void* code, Call call, FunctionPtr function)
|
||||
|
|
|
@ -634,7 +634,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
template <typename> friend class LinkBuffer;
|
||||
template <typename, template <typename> class> friend class LinkBufferBase;
|
||||
friend class RepatchBuffer;
|
||||
|
||||
static void linkCall(void* code, Call call, FunctionPtr function)
|
||||
|
|
|
@ -949,10 +949,6 @@
|
|||
#define WTF_USE_ACCESSIBILITY_CONTEXT_MENUS 1
|
||||
#endif
|
||||
|
||||
#if CPU(ARM_THUMB2) || CPU(ARM64)
|
||||
#define ENABLE_BRANCH_COMPACTION 1
|
||||
#endif
|
||||
|
||||
#if !defined(ENABLE_THREADING_LIBDISPATCH) && HAVE(DISPATCH_H)
|
||||
#define ENABLE_THREADING_LIBDISPATCH 1
|
||||
#elif !defined(ENABLE_THREADING_OPENMP) && defined(_OPENMP)
|
||||
|
|
Loading…
Reference in New Issue