summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/JavaScriptCore/assembler/AbstractMacroAssembler.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/JavaScriptCore/assembler/AbstractMacroAssembler.h')
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/assembler/AbstractMacroAssembler.h514
1 files changed, 118 insertions, 396 deletions
diff --git a/src/3rdparty/webkit/JavaScriptCore/assembler/AbstractMacroAssembler.h b/src/3rdparty/webkit/JavaScriptCore/assembler/AbstractMacroAssembler.h
index 5def60f..cf94677 100644
--- a/src/3rdparty/webkit/JavaScriptCore/assembler/AbstractMacroAssembler.h
+++ b/src/3rdparty/webkit/JavaScriptCore/assembler/AbstractMacroAssembler.h
@@ -29,6 +29,7 @@
#include <wtf/Platform.h>
#include <MacroAssemblerCodeRef.h>
+#include <CodeLocation.h>
#include <wtf/Noncopyable.h>
#include <wtf/UnusedParam.h>
@@ -48,15 +49,8 @@ public:
typedef MacroAssemblerCodeRef CodeRef;
class Jump;
- class PatchBuffer;
- class CodeLocationInstruction;
- class CodeLocationLabel;
- class CodeLocationJump;
- class CodeLocationCall;
- class CodeLocationNearCall;
- class CodeLocationDataLabel32;
- class CodeLocationDataLabelPtr;
- class ProcessorReturnAddress;
+ class LinkBuffer;
+ class RepatchBuffer;
typedef typename AssemblerType::RegisterID RegisterID;
typedef typename AssemblerType::FPRegisterID FPRegisterID;
@@ -181,17 +175,32 @@ public:
struct Imm32 {
explicit Imm32(int32_t value)
: m_value(value)
+#if PLATFORM_ARM_ARCH(7)
+ , m_isPointer(false)
+#endif
{
}
#if !PLATFORM(X86_64)
explicit Imm32(ImmPtr ptr)
: m_value(ptr.asIntptr())
+#if PLATFORM_ARM_ARCH(7)
+ , m_isPointer(true)
+#endif
{
}
#endif
int32_t m_value;
+#if PLATFORM_ARM_ARCH(7)
+ // 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.
+ bool m_isPointer;
+#endif
};
@@ -212,7 +221,7 @@ public:
friend class AbstractMacroAssembler;
friend class Jump;
friend class MacroAssemblerCodeRef;
- friend class PatchBuffer;
+ friend class LinkBuffer;
public:
Label()
@@ -237,7 +246,7 @@ public:
class DataLabelPtr {
template<class TemplateAssemblerType>
friend class AbstractMacroAssembler;
- friend class PatchBuffer;
+ friend class LinkBuffer;
public:
DataLabelPtr()
{
@@ -259,7 +268,7 @@ public:
class DataLabel32 {
template<class TemplateAssemblerType>
friend class AbstractMacroAssembler;
- friend class PatchBuffer;
+ friend class LinkBuffer;
public:
DataLabel32()
{
@@ -283,7 +292,7 @@ public:
class Call {
template<class TemplateAssemblerType>
friend class AbstractMacroAssembler;
- friend class PatchBuffer;
+ friend class LinkBuffer;
public:
enum Flags {
None = 0x0,
@@ -328,7 +337,7 @@ public:
template<class TemplateAssemblerType>
friend class AbstractMacroAssembler;
friend class Call;
- friend class PatchBuffer;
+ friend class LinkBuffer;
public:
Jump()
{
@@ -358,7 +367,7 @@ public:
// A JumpList is a set of Jump objects.
// All jumps in the set will be linked to the same destination.
class JumpList {
- friend class PatchBuffer;
+ friend class LinkBuffer;
public:
void link(AbstractMacroAssembler<AssemblerType>* masm)
@@ -397,343 +406,14 @@ public:
};
- // Section 3: MacroAssembler JIT instruction stream handles.
- //
- // The MacroAssembler supported facilities to modify a JIT generated
- // instruction stream after it has been generated (relinking calls and
- // jumps, and repatching data values). The following types are used
- // to store handles into the underlying instruction stream, the type
- // providing semantic information as to what it is that is in the
- // instruction stream at this point, and thus what operations may be
- // performed on it.
-
-
- // CodeLocationCommon:
- //
- // Base type for other CodeLocation* types. A postion in the JIT genertaed
- // instruction stream, without any semantic information.
- class CodeLocationCommon {
- public:
- CodeLocationCommon()
- {
- }
-
- // In order to avoid the need to store multiple handles into the
- // instructions stream, where the code generation is deterministic
- // and the labels will always be a fixed distance apart, these
- // methods may be used to recover a handle that has nopw been
- // retained, based on a known fixed relative offset from one that has.
- CodeLocationInstruction instructionAtOffset(int offset);
- CodeLocationLabel labelAtOffset(int offset);
- CodeLocationJump jumpAtOffset(int offset);
- CodeLocationCall callAtOffset(int offset);
- CodeLocationNearCall nearCallAtOffset(int offset);
- CodeLocationDataLabelPtr dataLabelPtrAtOffset(int offset);
- CodeLocationDataLabel32 dataLabel32AtOffset(int offset);
-
- protected:
- explicit CodeLocationCommon(CodePtr location)
- : m_location(location)
- {
- }
-
- void* dataLocation() { return m_location.dataLocation(); }
- void* executableAddress() { return m_location.executableAddress(); }
-
- void reset()
- {
- m_location = CodePtr();
- }
-
- private:
- CodePtr m_location;
- };
-
- // CodeLocationInstruction:
- //
- // An arbitrary instruction in the JIT code.
- class CodeLocationInstruction : public CodeLocationCommon {
- friend class CodeLocationCommon;
- public:
- CodeLocationInstruction()
- {
- }
-
- void repatchLoadPtrToLEA()
- {
- AssemblerType::repatchLoadPtrToLEA(this->dataLocation());
- }
-
- private:
- explicit CodeLocationInstruction(void* location)
- : CodeLocationCommon(CodePtr(location))
- {
- }
- };
-
- // CodeLocationLabel:
- //
- // A point in the JIT code maked with a label.
- class CodeLocationLabel : public CodeLocationCommon {
- friend class CodeLocationCommon;
- friend class CodeLocationJump;
- friend class CodeLocationCall;
- friend class CodeLocationNearCall;
- friend class PatchBuffer;
- friend class ProcessorReturnAddress;
-
- public:
- CodeLocationLabel()
- {
- }
-
- void* addressForSwitch() { return this->executableAddress(); }
- void* addressForExceptionHandler() { return this->executableAddress(); }
- void* addressForJSR() { return this->executableAddress(); }
-
- bool operator!()
- {
- return !this->executableAddress();
- }
-
- void reset()
- {
- CodeLocationCommon::reset();
- }
-
- private:
- explicit CodeLocationLabel(CodePtr location)
- : CodeLocationCommon(location)
- {
- }
-
- explicit CodeLocationLabel(void* location)
- : CodeLocationCommon(CodePtr(location))
- {
- }
-
- void* getJumpDestination() { return this->executableAddress(); }
- };
-
- // CodeLocationJump:
- //
- // A point in the JIT code at which there is a jump instruction.
- class CodeLocationJump : public CodeLocationCommon {
- friend class CodeLocationCommon;
- friend class PatchBuffer;
- public:
- CodeLocationJump()
- {
- }
-
- void relink(CodeLocationLabel destination)
- {
- AssemblerType::relinkJump(this->dataLocation(), destination.executableAddress());
- }
-
- private:
- explicit CodeLocationJump(void* location)
- : CodeLocationCommon(CodePtr(location))
- {
- }
- };
-
- // CodeLocationCall:
- //
- // A point in the JIT code at which there is a call instruction.
- class CodeLocationCall : public CodeLocationCommon {
- friend class CodeLocationCommon;
- friend class PatchBuffer;
- friend class ProcessorReturnAddress;
- public:
- CodeLocationCall()
- {
- }
-
- void relink(CodeLocationLabel destination)
- {
-#if PLATFORM(X86_64)
- CodeLocationCommon::dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11).repatch(destination.executableAddress());
-#else
- AssemblerType::relinkCall(this->dataLocation(), destination.executableAddress());
-#endif
- }
-
- void relink(FunctionPtr destination)
- {
-#if PLATFORM(X86_64)
- CodeLocationCommon::dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11).repatch(destination.executableAddress());
-#else
- AssemblerType::relinkCall(this->dataLocation(), destination.executableAddress());
-#endif
- }
-
- // This methods returns the value that will be set as the return address
- // within a function that has been called from this call instruction.
- void* calleeReturnAddressValue()
- {
- return this->executableAddress();
- }
-
- private:
- explicit CodeLocationCall(CodePtr location)
- : CodeLocationCommon(location)
- {
- }
-
- explicit CodeLocationCall(void* location)
- : CodeLocationCommon(CodePtr(location))
- {
- }
- };
-
- // CodeLocationNearCall:
- //
- // A point in the JIT code at which there is a call instruction with near linkage.
- class CodeLocationNearCall : public CodeLocationCommon {
- friend class CodeLocationCommon;
- friend class PatchBuffer;
- friend class ProcessorReturnAddress;
- public:
- CodeLocationNearCall()
- {
- }
-
- void relink(CodePtr destination)
- {
- AssemblerType::relinkCall(this->dataLocation(), destination.executableAddress());
- }
-
- void relink(CodeLocationLabel destination)
- {
- AssemblerType::relinkCall(this->dataLocation(), destination.executableAddress());
- }
-
- void relink(FunctionPtr destination)
- {
- AssemblerType::relinkCall(this->dataLocation(), destination.executableAddress());
- }
-
- // This methods returns the value that will be set as the return address
- // within a function that has been called from this call instruction.
- void* calleeReturnAddressValue()
- {
- return this->executableAddress();
- }
-
- private:
- explicit CodeLocationNearCall(CodePtr location)
- : CodeLocationCommon(location)
- {
- }
-
- explicit CodeLocationNearCall(void* location)
- : CodeLocationCommon(CodePtr(location))
- {
- }
- };
-
- // CodeLocationDataLabel32:
- //
- // A point in the JIT code at which there is an int32_t immediate that may be repatched.
- class CodeLocationDataLabel32 : public CodeLocationCommon {
- friend class CodeLocationCommon;
- friend class PatchBuffer;
- public:
- CodeLocationDataLabel32()
- {
- }
-
- void repatch(int32_t value)
- {
- AssemblerType::repatchInt32(this->dataLocation(), value);
- }
-
- private:
- explicit CodeLocationDataLabel32(void* location)
- : CodeLocationCommon(CodePtr(location))
- {
- }
- };
-
- // CodeLocationDataLabelPtr:
- //
- // A point in the JIT code at which there is a void* immediate that may be repatched.
- class CodeLocationDataLabelPtr : public CodeLocationCommon {
- friend class CodeLocationCommon;
- friend class PatchBuffer;
- public:
- CodeLocationDataLabelPtr()
- {
- }
-
- void repatch(void* value)
- {
- AssemblerType::repatchPointer(this->dataLocation(), value);
- }
-
- private:
- explicit CodeLocationDataLabelPtr(void* location)
- : CodeLocationCommon(CodePtr(location))
- {
- }
- };
-
- // ProcessorReturnAddress:
- //
- // This class can be used to relink a call identified by its return address.
- class ProcessorReturnAddress {
- friend class CodeLocationCall;
- friend class CodeLocationNearCall;
- public:
- ProcessorReturnAddress(void* location)
- : m_location(location)
- {
- }
-
- void relinkCallerToTrampoline(CodeLocationLabel label)
- {
- CodeLocationCall(CodePtr(m_location)).relink(label);
- }
-
- void relinkCallerToTrampoline(CodePtr newCalleeFunction)
- {
- relinkCallerToTrampoline(CodeLocationLabel(newCalleeFunction));
- }
-
- void relinkCallerToFunction(FunctionPtr function)
- {
- CodeLocationCall(CodePtr(m_location)).relink(function);
- }
-
- void relinkNearCallerToTrampoline(CodeLocationLabel label)
- {
- CodeLocationNearCall(CodePtr(m_location)).relink(label);
- }
-
- void relinkNearCallerToTrampoline(CodePtr newCalleeFunction)
- {
- relinkNearCallerToTrampoline(CodeLocationLabel(newCalleeFunction));
- }
-
- void* addressForLookup()
- {
- return m_location.value();
- }
-
- private:
- ReturnAddressPtr m_location;
- };
-
-
- // Section 4: PatchBuffer - utility to finalize code generation.
+ // Section 3: LinkBuffer - utility to finalize code generation.
static CodePtr trampolineAt(CodeRef ref, Label label)
{
return CodePtr(AssemblerType::getRelocatedAddress(ref.m_code.dataLocation(), label.m_label));
}
- // PatchBuffer:
+ // LinkBuffer:
//
// This class assists in linking code generated by the macro assembler, once code generation
// has been completed, and the code has been copied to is final location in memory. At this
@@ -750,12 +430,12 @@ public:
// FIXME: distinguish between Calls & Jumps (make a specific call to obtain the return
// address of calls, as opposed to a point that can be used to later relink a Jump -
// possibly wrap the later up in an object that can do just that).
- class PatchBuffer : public Noncopyable {
+ class LinkBuffer : public Noncopyable {
public:
// Note: Initialization sequence is significant, since executablePool is a PassRefPtr.
// First, executablePool is copied into m_executablePool, then the initialization of
// m_code uses m_executablePool, *not* executablePool, since this is no longer valid.
- PatchBuffer(AbstractMacroAssembler<AssemblerType>* masm, PassRefPtr<ExecutablePool> executablePool)
+ LinkBuffer(AbstractMacroAssembler<AssemblerType>* masm, PassRefPtr<ExecutablePool> executablePool)
: m_executablePool(executablePool)
, m_code(masm->m_assembler.executableCopy(m_executablePool.get()))
, m_size(masm->m_assembler.size())
@@ -765,7 +445,7 @@ public:
{
}
- ~PatchBuffer()
+ ~LinkBuffer()
{
ASSERT(m_completed);
}
@@ -786,13 +466,13 @@ public:
void link(Jump jump, CodeLocationLabel label)
{
- AssemblerType::linkJump(code(), jump.m_jmp, label.executableAddress());
+ AssemblerType::linkJump(code(), jump.m_jmp, label.dataLocation());
}
void link(JumpList list, CodeLocationLabel label)
{
for (unsigned i = 0; i < list.m_jumps.size(); ++i)
- AssemblerType::linkJump(code(), list.m_jumps[i].m_jmp, label.executableAddress());
+ AssemblerType::linkJump(code(), list.m_jumps[i].m_jmp, label.dataLocation());
}
void patch(DataLabelPtr label, void* value)
@@ -802,7 +482,7 @@ public:
void patch(DataLabelPtr label, CodeLocationLabel value)
{
- AssemblerType::patchPointer(code(), label.m_label, value.getJumpDestination());
+ AssemblerType::patchPointer(code(), label.m_label, value.executableAddress());
}
// These methods are used to obtain handles to allow the code to be relinked / repatched later.
@@ -886,8 +566,93 @@ public:
#endif
};
+ class RepatchBuffer {
+ public:
+ RepatchBuffer()
+ {
+ }
+
+ void relink(CodeLocationJump jump, CodeLocationLabel destination)
+ {
+ AssemblerType::relinkJump(jump.dataLocation(), destination.dataLocation());
+ }
+
+ void relink(CodeLocationCall call, CodeLocationLabel destination)
+ {
+#if PLATFORM(X86_64)
+ repatch(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11), destination.executableAddress());
+#else
+ AssemblerType::relinkCall(call.dataLocation(), destination.executableAddress());
+#endif
+ }
+
+ void relink(CodeLocationCall call, FunctionPtr destination)
+ {
+#if PLATFORM(X86_64)
+ repatch(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11), destination.executableAddress());
+#else
+ AssemblerType::relinkCall(call.dataLocation(), destination.executableAddress());
+#endif
+ }
+
+ void relink(CodeLocationNearCall nearCall, CodePtr destination)
+ {
+ AssemblerType::relinkCall(nearCall.dataLocation(), destination.executableAddress());
+ }
+
+ void relink(CodeLocationNearCall nearCall, CodeLocationLabel destination)
+ {
+ AssemblerType::relinkCall(nearCall.dataLocation(), destination.executableAddress());
+ }
+
+ void relink(CodeLocationNearCall nearCall, FunctionPtr destination)
+ {
+ AssemblerType::relinkCall(nearCall.dataLocation(), destination.executableAddress());
+ }
+
+ void repatch(CodeLocationDataLabel32 dataLabel32, int32_t value)
+ {
+ AssemblerType::repatchInt32(dataLabel32.dataLocation(), value);
+ }
+
+ void repatch(CodeLocationDataLabelPtr dataLabelPtr, void* value)
+ {
+ AssemblerType::repatchPointer(dataLabelPtr.dataLocation(), value);
+ }
+
+ void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label)
+ {
+ relink(CodeLocationCall(CodePtr(returnAddress)), label);
+ }
+
+ void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction)
+ {
+ relinkCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction));
+ }
+
+ void relinkCallerToFunction(ReturnAddressPtr returnAddress, FunctionPtr function)
+ {
+ relink(CodeLocationCall(CodePtr(returnAddress)), function);
+ }
+
+ void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label)
+ {
+ relink(CodeLocationNearCall(CodePtr(returnAddress)), label);
+ }
+
+ void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction)
+ {
+ relinkNearCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction));
+ }
+
+ void repatchLoadPtrToLEA(CodeLocationInstruction instruction)
+ {
+ AssemblerType::repatchLoadPtrToLEA(instruction.dataLocation());
+ }
+ };
+
- // Section 5: Misc admin methods
+ // Section 4: Misc admin methods
size_t size()
{
@@ -949,49 +714,6 @@ protected:
AssemblerType m_assembler;
};
-
-template <class AssemblerType>
-typename AbstractMacroAssembler<AssemblerType>::CodeLocationInstruction AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::instructionAtOffset(int offset)
-{
- return typename AbstractMacroAssembler::CodeLocationInstruction(reinterpret_cast<char*>(dataLocation()) + offset);
-}
-
-template <class AssemblerType>
-typename AbstractMacroAssembler<AssemblerType>::CodeLocationLabel AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::labelAtOffset(int offset)
-{
- return typename AbstractMacroAssembler::CodeLocationLabel(reinterpret_cast<char*>(dataLocation()) + offset);
-}
-
-template <class AssemblerType>
-typename AbstractMacroAssembler<AssemblerType>::CodeLocationJump AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::jumpAtOffset(int offset)
-{
- return typename AbstractMacroAssembler::CodeLocationJump(reinterpret_cast<char*>(dataLocation()) + offset);
-}
-
-template <class AssemblerType>
-typename AbstractMacroAssembler<AssemblerType>::CodeLocationCall AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::callAtOffset(int offset)
-{
- return typename AbstractMacroAssembler::CodeLocationCall(reinterpret_cast<char*>(dataLocation()) + offset);
-}
-
-template <class AssemblerType>
-typename AbstractMacroAssembler<AssemblerType>::CodeLocationNearCall AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::nearCallAtOffset(int offset)
-{
- return typename AbstractMacroAssembler::CodeLocationNearCall(reinterpret_cast<char*>(dataLocation()) + offset);
-}
-
-template <class AssemblerType>
-typename AbstractMacroAssembler<AssemblerType>::CodeLocationDataLabelPtr AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::dataLabelPtrAtOffset(int offset)
-{
- return typename AbstractMacroAssembler::CodeLocationDataLabelPtr(reinterpret_cast<char*>(dataLocation()) + offset);
-}
-
-template <class AssemblerType>
-typename AbstractMacroAssembler<AssemblerType>::CodeLocationDataLabel32 AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::dataLabel32AtOffset(int offset)
-{
- return typename AbstractMacroAssembler::CodeLocationDataLabel32(reinterpret_cast<char*>(dataLocation()) + offset);
-}
-
} // namespace JSC
#endif // ENABLE(ASSEMBLER)