Home | History | Annotate | Download | only in assembler
      1 /*
      2  * Copyright (C) 2009 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef RepatchBuffer_h
     27 #define RepatchBuffer_h
     28 
     29 #if ENABLE(ASSEMBLER)
     30 
     31 #include <MacroAssembler.h>
     32 #include <wtf/Noncopyable.h>
     33 
     34 namespace JSC {
     35 
     36 // RepatchBuffer:
     37 //
     38 // This class is used to modify code after code generation has been completed,
     39 // and after the code has potentially already been executed.  This mechanism is
     40 // used to apply optimizations to the code.
     41 //
     42 class RepatchBuffer {
     43     typedef MacroAssemblerCodePtr CodePtr;
     44 
     45 public:
     46     RepatchBuffer(CodeBlock* codeBlock)
     47     {
     48         JITCode& code = codeBlock->getJITCode();
     49         m_start = code.start();
     50         m_size = code.size();
     51 
     52         ExecutableAllocator::makeWritable(m_start, m_size);
     53     }
     54 
     55     ~RepatchBuffer()
     56     {
     57         ExecutableAllocator::makeExecutable(m_start, m_size);
     58     }
     59 
     60     void relink(CodeLocationJump jump, CodeLocationLabel destination)
     61     {
     62         MacroAssembler::repatchJump(jump, destination);
     63     }
     64 
     65     void relink(CodeLocationCall call, CodeLocationLabel destination)
     66     {
     67         MacroAssembler::repatchCall(call, destination);
     68     }
     69 
     70     void relink(CodeLocationCall call, FunctionPtr destination)
     71     {
     72         MacroAssembler::repatchCall(call, destination);
     73     }
     74 
     75     void relink(CodeLocationNearCall nearCall, CodePtr destination)
     76     {
     77         MacroAssembler::repatchNearCall(nearCall, CodeLocationLabel(destination));
     78     }
     79 
     80     void relink(CodeLocationNearCall nearCall, CodeLocationLabel destination)
     81     {
     82         MacroAssembler::repatchNearCall(nearCall, destination);
     83     }
     84 
     85     void repatch(CodeLocationDataLabel32 dataLabel32, int32_t value)
     86     {
     87         MacroAssembler::repatchInt32(dataLabel32, value);
     88     }
     89 
     90     void repatch(CodeLocationDataLabelPtr dataLabelPtr, void* value)
     91     {
     92         MacroAssembler::repatchPointer(dataLabelPtr, value);
     93     }
     94 
     95     void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label)
     96     {
     97         relink(CodeLocationCall(CodePtr(returnAddress)), label);
     98     }
     99 
    100     void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction)
    101     {
    102         relinkCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction));
    103     }
    104 
    105     void relinkCallerToFunction(ReturnAddressPtr returnAddress, FunctionPtr function)
    106     {
    107         relink(CodeLocationCall(CodePtr(returnAddress)), function);
    108     }
    109 
    110     void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label)
    111     {
    112         relink(CodeLocationNearCall(CodePtr(returnAddress)), label);
    113     }
    114 
    115     void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction)
    116     {
    117         relinkNearCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction));
    118     }
    119 
    120 private:
    121     void* m_start;
    122     size_t m_size;
    123 };
    124 
    125 } // namespace JSC
    126 
    127 #endif // ENABLE(ASSEMBLER)
    128 
    129 #endif // RepatchBuffer_h
    130