Ignore:
Timestamp:
Jun 1, 2009, 6:20:35 PM (16 years ago)
Author:
[email protected]
Message:

2009-06-01 Gavin Barraclough <[email protected]>

Reviewed by Sam "WX" Weinig.

Allow the JIT to operate without relying on use of RWX memory, on platforms where this is supported.

This patch adds a switch to Platform.h (ENABLE_ASSEMBLER_WX_EXCLUSIVE) which enables this mode of operation.
When this flag is set, all executable memory will be allocated RX, and switched to RW only whilst being
modified. Upon completion of code generation the protection is switched back to RX to allow execution.

Further optimization will be required before it is desirable to enable this mode of operation by default;
enabling this presently incurs a 5%-10% regression.

(Submitting disabled - no performance impact).

  • assembler/AbstractMacroAssembler.h: (JSC::AbstractMacroAssembler::CodeLocationInstruction::repatchLoadToLEA): (JSC::AbstractMacroAssembler::CodeLocationLabel::fromFunctionPointer): (JSC::AbstractMacroAssembler::CodeLocationJump::relink): (JSC::AbstractMacroAssembler::CodeLocationCall::relink): (JSC::AbstractMacroAssembler::CodeLocationNearCall::relink): (JSC::AbstractMacroAssembler::CodeLocationDataLabel32::repatch): (JSC::AbstractMacroAssembler::CodeLocationDataLabelPtr::repatch): (JSC::AbstractMacroAssembler::ProcessorReturnAddress::relinkCallerToTrampoline): (JSC::AbstractMacroAssembler::ProcessorReturnAddress::relinkCallerToFunction): (JSC::AbstractMacroAssembler::ProcessorReturnAddress::relinkNearCallerToTrampoline): (JSC::AbstractMacroAssembler::ProcessorReturnAddress::relinkNearCallerToFunction): (JSC::AbstractMacroAssembler::PatchBuffer::PatchBuffer): (JSC::AbstractMacroAssembler::PatchBuffer::~PatchBuffer): (JSC::AbstractMacroAssembler::PatchBuffer::link): (JSC::AbstractMacroAssembler::PatchBuffer::patch): (JSC::AbstractMacroAssembler::PatchBuffer::performFinalization): (JSC::::CodeLocationCommon::nearCallAtOffset): (JSC::::CodeLocationCall::CodeLocationCall): (JSC::::CodeLocationNearCall::CodeLocationNearCall):
  • assembler/AssemblerBuffer.h: (JSC::AssemblerBuffer::executableCopy):
  • assembler/X86Assembler.h: (JSC::CAN_SIGN_EXTEND_U32_64): (JSC::X86Assembler::linkJump): (JSC::X86Assembler::linkCall): (JSC::X86Assembler::patchPointer): (JSC::X86Assembler::relinkJump): (JSC::X86Assembler::relinkCall): (JSC::X86Assembler::repatchInt32): (JSC::X86Assembler::repatchPointer): (JSC::X86Assembler::repatchLoadToLEA): (JSC::X86Assembler::patchInt32): (JSC::X86Assembler::patchRel32):
  • jit/ExecutableAllocator.h: (JSC::ExecutableAllocator::): (JSC::ExecutableAllocator::makeWritable): (JSC::ExecutableAllocator::makeExecutable):
  • jit/ExecutableAllocatorFixedVMPool.cpp: (JSC::FixedVMPoolAllocator::FixedVMPoolAllocator):
  • jit/ExecutableAllocatorPosix.cpp: (JSC::ExecutablePool::systemAlloc): (JSC::ExecutablePool::systemRelease): (JSC::ExecutableAllocator::reprotectRegion):
  • jit/ExecutableAllocatorWin.cpp:
  • jit/JITPropertyAccess.cpp: (JSC::JIT::patchGetByIdSelf): (JSC::JIT::patchPutByIdReplace):
  • wtf/Platform.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/assembler/AbstractMacroAssembler.h

    r44076 r44341  
    3535#if ENABLE(ASSEMBLER)
    3636
     37// FIXME: keep transitioning this out into MacroAssemblerX86_64.
     38#if PLATFORM(X86_64)
     39#define REPTACH_OFFSET_CALL_R11 3
     40#endif
     41
    3742namespace JSC {
    3843
     
    4853    class CodeLocationJump;
    4954    class CodeLocationCall;
     55    class CodeLocationNearCall;
    5056    class CodeLocationDataLabel32;
    5157    class CodeLocationDataLabelPtr;
     
    422428        CodeLocationJump jumpAtOffset(int offset);
    423429        CodeLocationCall callAtOffset(int offset);
     430        CodeLocationNearCall nearCallAtOffset(int offset);
    424431        CodeLocationDataLabelPtr dataLabelPtrAtOffset(int offset);
    425432        CodeLocationDataLabel32 dataLabel32AtOffset(int offset);
     
    447454        }
    448455
    449         void patchLoadToLEA() {
    450             AssemblerType::patchLoadToLEA(reinterpret_cast<intptr_t>(this->m_location));
     456        void repatchLoadToLEA()
     457        {
     458            AssemblerType::repatchLoadToLEA(this->m_location);
    451459        }
    452460
     
    464472        friend class CodeLocationCommon;
    465473        friend class CodeLocationJump;
     474        friend class CodeLocationCall;
     475        friend class CodeLocationNearCall;
    466476        friend class PatchBuffer;
    467477        friend class ProcessorReturnAddress;
     
    476486        void* addressForJSR() { return this->m_location; }
    477487
     488        template<typename FunctionSig>
     489        static CodeLocationLabel fromFunctionPointer(FunctionSig* function)
     490        {
     491            return CodeLocationLabel(reinterpret_cast<void*>(function));
     492        }
     493
    478494    private:
    479495        explicit CodeLocationLabel(void* location)
     
    498514        void relink(CodeLocationLabel destination)
    499515        {
    500             AssemblerType::patchJump(reinterpret_cast<intptr_t>(this->m_location), destination.m_location);
     516            AssemblerType::relinkJump(this->m_location, destination.m_location);
    501517        }
    502518
     
    519535        }
    520536
     537        CodeLocationCall(ProcessorReturnAddress*);
     538
     539        void relink(CodeLocationLabel destination)
     540        {
     541#if PLATFORM(X86_64)
     542            CodeLocationCommon::dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11).repatch(destination.m_location);
     543#else
     544            AssemblerType::relinkCall(this->m_location, destination.m_location);
     545#endif
     546        }
     547
    521548        template<typename FunctionSig>
    522549        void relink(FunctionSig* function)
    523550        {
    524             AssemblerType::patchMacroAssemblerCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(function));
     551            relink(CodeLocationLabel::fromFunctionPointer(function));
    525552        }
    526553
     
    550577        }
    551578
     579        CodeLocationNearCall(ProcessorReturnAddress*);
     580
     581        void relink(CodeLocationLabel destination)
     582        {
     583            AssemblerType::relinkCall(this->m_location, destination.m_location);
     584        }
     585
    552586        template<typename FunctionSig>
    553587        void relink(FunctionSig* function)
    554588        {
    555             AssemblerType::patchCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(function));
     589            relink(CodeLocationLabel::fromFunctionPointer(function));
    556590        }
    557591
     
    583617        void repatch(int32_t value)
    584618        {
    585             AssemblerType::patchImmediate(reinterpret_cast<intptr_t>(this->m_location), value);
     619            AssemblerType::repatchInt32(this->m_location, value);
    586620        }
    587621
     
    606640        void repatch(void* value)
    607641        {
    608             AssemblerType::patchPointer(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<intptr_t>(value));
     642            AssemblerType::repatchPointer(this->m_location, value);
    609643        }
    610644
     
    620654    // This class can be used to relink a call identified by its return address.
    621655    class ProcessorReturnAddress {
     656        friend class CodeLocationCall;
     657        friend class CodeLocationNearCall;
    622658    public:
    623659        ProcessorReturnAddress(void* location)
     
    628664        void relinkCallerToTrampoline(CodeLocationLabel label)
    629665        {
    630             AssemblerType::patchMacroAssemblerCall(reinterpret_cast<intptr_t>(this->m_location), label.getJumpDestination());
     666            CodeLocationCall(this).relink(label);
    631667        }
    632668       
     
    634670        void relinkCallerToFunction(FunctionSig* newCalleeFunction)
    635671        {
    636             AssemblerType::patchMacroAssemblerCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(newCalleeFunction));
     672            relinkCallerToTrampoline(CodeLocationLabel::fromFunctionPointer(newCalleeFunction));
     673        }
     674       
     675        void relinkNearCallerToTrampoline(CodeLocationLabel label)
     676        {
     677            CodeLocationNearCall(this).relink(label);
    637678        }
    638679       
     
    640681        void relinkNearCallerToFunction(FunctionSig* newCalleeFunction)
    641682        {
    642             AssemblerType::patchCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(newCalleeFunction));
     683            relinkNearCallerToTrampoline(CodeLocationLabel::fromFunctionPointer(newCalleeFunction));
    643684        }
    644685       
     
    681722        PatchBuffer(AbstractMacroAssembler<AssemblerType>* masm, PassRefPtr<ExecutablePool> executablePool)
    682723            : m_ref(0, executablePool, masm->m_assembler.size())
     724            , m_size(masm->m_assembler.size())
    683725#ifndef NDEBUG
    684726            , m_completed(false)
     
    688730        }
    689731
    690 #ifndef NDEBUG
    691732        ~PatchBuffer()
    692733        {
    693734            ASSERT(m_completed);
    694735        }
    695 #endif
    696736
    697737        // These methods are used to link or set values at code generation time.
     
    702742            ASSERT(call.isFlagSet(Call::Linkable));
    703743#if PLATFORM(X86_64)
    704             if (call.isFlagSet(Call::Near))
    705                 AssemblerType::linkCall(code(), call.m_jmp, reinterpret_cast<void*>(function));
    706             else {
    707                 intptr_t callLocation = reinterpret_cast<intptr_t>(AssemblerType::getRelocatedAddress(code(), call.m_jmp));
    708                 AssemblerType::patchMacroAssemblerCall(callLocation, reinterpret_cast<void*>(function));
    709             }
    710 #else
     744            if (!call.isFlagSet(Call::Near)) {
     745                intptr_t callLocation = reinterpret_cast<intptr_t>(AssemblerType::getRelocatedAddress(code(), call.m_jmp)) - REPTACH_OFFSET_CALL_R11;
     746                AssemblerType::patchPointer(reinterpret_cast<void*>(callLocation), reinterpret_cast<void*>(function));
     747            } else
     748#endif
    711749            AssemblerType::linkCall(code(), call.m_jmp, reinterpret_cast<void*>(function));
    712 #endif
    713750        }
    714751       
     
    739776        void patch(DataLabelPtr label, void* value)
    740777        {
    741             AssemblerType::patchAddress(code(), label.m_label, value);
     778            AssemblerType::patchPointer(code(), label.m_label, value);
    742779        }
    743780
    744781        void patch(DataLabelPtr label, CodeLocationLabel value)
    745782        {
    746             AssemblerType::patchAddress(code(), label.m_label, value.getJumpDestination());
     783            AssemblerType::patchPointer(code(), label.m_label, value.getJumpDestination());
    747784        }
    748785
     
    816853            m_completed = true;
    817854#endif
     855
     856            ExecutableAllocator::makeExecutable(m_ref.m_code, m_size);
    818857        }
    819858
    820859        CodeRef m_ref;
     860        size_t m_size;
    821861#ifndef NDEBUG
    822862        bool m_completed;
     
    913953
    914954template <class AssemblerType>
     955typename AbstractMacroAssembler<AssemblerType>::CodeLocationNearCall AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::nearCallAtOffset(int offset)
     956{
     957    return typename AbstractMacroAssembler::CodeLocationNearCall(reinterpret_cast<char*>(m_location) + offset);
     958}
     959
     960template <class AssemblerType>
    915961typename AbstractMacroAssembler<AssemblerType>::CodeLocationDataLabelPtr AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::dataLabelPtrAtOffset(int offset)
    916962{
     
    924970}
    925971
     972template <class AssemblerType>
     973AbstractMacroAssembler<AssemblerType>::CodeLocationCall::CodeLocationCall(AbstractMacroAssembler<AssemblerType>::ProcessorReturnAddress* ra)
     974    : CodeLocationCommon(ra->m_location)
     975{
     976}
     977
     978template <class AssemblerType>
     979AbstractMacroAssembler<AssemblerType>::CodeLocationNearCall::CodeLocationNearCall(AbstractMacroAssembler<AssemblerType>::ProcessorReturnAddress* ra)
     980    : CodeLocationCommon(ra->m_location)
     981{
     982}
    926983
    927984} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.