📄 abstractmacroassembler.h
字号:
} void* m_location; }; // CodeLocationLabel: // // A point in the JIT code maked with a label. class CodeLocationLabel : public CodeLocationCommon { friend class CodeLocationCommon; friend class CodeLocationJump; friend class PatchBuffer; public: CodeLocationLabel() { } void* addressForSwitch() { return this->m_location; } void* addressForExceptionHandler() { return this->m_location; } void* addressForJSR() { return this->m_location; } private: explicit CodeLocationLabel(void* location) : CodeLocationCommon(location) { } void* getJumpDestination() { return this->m_location; } }; // 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::patchJump(reinterpret_cast<intptr_t>(this->m_location), destination.m_location); } private: explicit CodeLocationJump(void* location) : CodeLocationCommon(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; public: CodeLocationCall() { } template<typename FunctionSig> void relink(FunctionSig* function) { AssemblerType::patchMacroAssemblerCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(function)); } // 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->m_location; } private: explicit CodeLocationCall(void* location) : CodeLocationCommon(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; public: CodeLocationNearCall() { } template<typename FunctionSig> void relink(FunctionSig* function) { AssemblerType::patchCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(function)); } // 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->m_location; } private: explicit CodeLocationNearCall(void* location) : CodeLocationCommon(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::patchImmediate(reinterpret_cast<intptr_t>(this->m_location), value); } private: explicit CodeLocationDataLabel32(void* location) : CodeLocationCommon(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::patchPointer(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<intptr_t>(value)); } private: explicit CodeLocationDataLabelPtr(void* location) : CodeLocationCommon(location) { } }; // ProcessorReturnAddress: // // This class can be used to relink a call identified by its return address. class ProcessorReturnAddress { public: ProcessorReturnAddress(void* location) : m_location(location) { } template<typename FunctionSig> void relinkCallerToFunction(FunctionSig* newCalleeFunction) { AssemblerType::patchMacroAssemblerCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(newCalleeFunction)); } template<typename FunctionSig> void relinkNearCallerToFunction(FunctionSig* newCalleeFunction) { AssemblerType::patchCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(newCalleeFunction)); } operator void*() { return m_location; } private: void* m_location; }; // Section 4: The patch buffer - utility to finalize code generation. // PatchBuffer: // // 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 // time pointers to labels within the code may be resolved, and relative offsets to external // addresses may be fixed. // // Specifically: // * Jump objects may be linked to external targets, // * The address of Jump objects may taken, such that it can later be relinked. // * The return address of a Jump object representing a call may be acquired. // * The address of a Label pointing into the code may be resolved. // * The value referenced by a DataLabel may be fixed. // // 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: PatchBuffer(void* code) : m_code(code) { } CodeLocationLabel entry() { return CodeLocationLabel(m_code); } void* trampolineAt(Label label) { return AssemblerType::getRelocatedAddress(m_code, label.m_label); } // These methods are used to link or set values at code generation time. template<typename FunctionSig> void link(Call call, FunctionSig* function) { ASSERT(call.isFlagSet(Call::Linkable));#if PLATFORM(X86_64) if (call.isFlagSet(Call::Near)) { AssemblerType::linkCall(m_code, call.m_jmp, reinterpret_cast<void*>(function)); } else { intptr_t callLocation = reinterpret_cast<intptr_t>(AssemblerType::getRelocatedAddress(m_code, call.m_jmp)); AssemblerType::patchMacroAssemblerCall(callLocation, reinterpret_cast<void*>(function)); }#else AssemblerType::linkCall(m_code, call.m_jmp, reinterpret_cast<void*>(function));#endif } template<typename FunctionSig> void linkTailRecursive(Jump jump, FunctionSig* function) { AssemblerType::linkJump(m_code, jump.m_jmp, reinterpret_cast<void*>(function)); } template<typename FunctionSig> void linkTailRecursive(JumpList list, FunctionSig* function) { for (unsigned i = 0; i < list.m_jumps.size(); ++i) { AssemblerType::linkJump(m_code, list.m_jumps[i].m_jmp, reinterpret_cast<void*>(function)); } } void link(Jump jump, CodeLocationLabel label) { AssemblerType::linkJump(m_code, jump.m_jmp, label.m_location); } void link(JumpList list, CodeLocationLabel label) { for (unsigned i = 0; i < list.m_jumps.size(); ++i) AssemblerType::linkJump(m_code, list.m_jumps[i].m_jmp, label.m_location); } void patch(DataLabelPtr label, void* value) { AssemblerType::patchAddress(m_code, label.m_label, value); } // These methods are used to obtain handles to allow the code to be relinked / repatched later. CodeLocationCall locationOf(Call call) { ASSERT(call.isFlagSet(Call::Linkable)); ASSERT(!call.isFlagSet(Call::Near)); return CodeLocationCall(AssemblerType::getRelocatedAddress(m_code, call.m_jmp)); } CodeLocationNearCall locationOfNearCall(Call call) { ASSERT(call.isFlagSet(Call::Linkable)); ASSERT(call.isFlagSet(Call::Near)); return CodeLocationNearCall(AssemblerType::getRelocatedAddress(m_code, call.m_jmp)); } CodeLocationLabel locationOf(Label label) { return CodeLocationLabel(AssemblerType::getRelocatedAddress(m_code, label.m_label)); } CodeLocationDataLabelPtr locationOf(DataLabelPtr label) { return CodeLocationDataLabelPtr(AssemblerType::getRelocatedAddress(m_code, label.m_label)); } CodeLocationDataLabel32 locationOf(DataLabel32 label) { return CodeLocationDataLabel32(AssemblerType::getRelocatedAddress(m_code, label.m_label)); } // This method obtains the return address of the call, given as an offset from // the start of the code. unsigned returnAddressOffset(Call call) { return AssemblerType::getCallReturnOffset(call.m_jmp); } private: void* m_code; }; // Section 5: Misc admin methods size_t size() { return m_assembler.size(); } void* copyCode(ExecutablePool* allocator) { return m_assembler.executableCopy(allocator); } Label label() { return Label(this); } Label align() { m_assembler.align(16); return Label(this); } ptrdiff_t differenceBetween(Label from, Jump to) { return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp); } ptrdiff_t differenceBetween(Label from, Call to) { return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp); } ptrdiff_t differenceBetween(Label from, Label to) { return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label); } ptrdiff_t differenceBetween(Label from, DataLabelPtr to) { return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label); } ptrdiff_t differenceBetween(Label from, DataLabel32 to) { return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label); } ptrdiff_t differenceBetween(DataLabelPtr from, Jump to) { return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp); } ptrdiff_t differenceBetween(DataLabelPtr from, Call to) { return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp); }protected: AssemblerType m_assembler;};template <class AssemblerType>typename AbstractMacroAssembler<AssemblerType>::CodeLocationLabel AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::labelAtOffset(int offset){ return typename AbstractMacroAssembler::CodeLocationLabel(reinterpret_cast<char*>(m_location) + offset);}template <class AssemblerType>typename AbstractMacroAssembler<AssemblerType>::CodeLocationJump AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::jumpAtOffset(int offset){ return typename AbstractMacroAssembler::CodeLocationJump(reinterpret_cast<char*>(m_location) + offset);}template <class AssemblerType>typename AbstractMacroAssembler<AssemblerType>::CodeLocationCall AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::callAtOffset(int offset){ return typename AbstractMacroAssembler::CodeLocationCall(reinterpret_cast<char*>(m_location) + offset);}template <class AssemblerType>typename AbstractMacroAssembler<AssemblerType>::CodeLocationDataLabelPtr AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::dataLabelPtrAtOffset(int offset){ return typename AbstractMacroAssembler::CodeLocationDataLabelPtr(reinterpret_cast<char*>(m_location) + offset);}template <class AssemblerType>typename AbstractMacroAssembler<AssemblerType>::CodeLocationDataLabel32 AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::dataLabel32AtOffset(int offset){ return typename AbstractMacroAssembler::CodeLocationDataLabel32(reinterpret_cast<char*>(m_location) + offset);}} // namespace JSC#endif // ENABLE(ASSEMBLER)#endif // AbstractMacroAssembler_h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -