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: RepatchBuffer(CodeBlock * codeBlock)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 ~RepatchBuffer()55 ~RepatchBuffer() 56 { 57 ExecutableAllocator::makeExecutable(m_start, m_size); 58 } 59 relink(CodeLocationJump jump,CodeLocationLabel destination)60 void relink(CodeLocationJump jump, CodeLocationLabel destination) 61 { 62 MacroAssembler::repatchJump(jump, destination); 63 } 64 relink(CodeLocationCall call,CodeLocationLabel destination)65 void relink(CodeLocationCall call, CodeLocationLabel destination) 66 { 67 MacroAssembler::repatchCall(call, destination); 68 } 69 relink(CodeLocationCall call,FunctionPtr destination)70 void relink(CodeLocationCall call, FunctionPtr destination) 71 { 72 MacroAssembler::repatchCall(call, destination); 73 } 74 relink(CodeLocationNearCall nearCall,CodePtr destination)75 void relink(CodeLocationNearCall nearCall, CodePtr destination) 76 { 77 MacroAssembler::repatchNearCall(nearCall, CodeLocationLabel(destination)); 78 } 79 relink(CodeLocationNearCall nearCall,CodeLocationLabel destination)80 void relink(CodeLocationNearCall nearCall, CodeLocationLabel destination) 81 { 82 MacroAssembler::repatchNearCall(nearCall, destination); 83 } 84 repatch(CodeLocationDataLabel32 dataLabel32,int32_t value)85 void repatch(CodeLocationDataLabel32 dataLabel32, int32_t value) 86 { 87 MacroAssembler::repatchInt32(dataLabel32, value); 88 } 89 repatch(CodeLocationDataLabelPtr dataLabelPtr,void * value)90 void repatch(CodeLocationDataLabelPtr dataLabelPtr, void* value) 91 { 92 MacroAssembler::repatchPointer(dataLabelPtr, value); 93 } 94 relinkCallerToTrampoline(ReturnAddressPtr returnAddress,CodeLocationLabel label)95 void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label) 96 { 97 relink(CodeLocationCall(CodePtr(returnAddress)), label); 98 } 99 relinkCallerToTrampoline(ReturnAddressPtr returnAddress,CodePtr newCalleeFunction)100 void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction) 101 { 102 relinkCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction)); 103 } 104 relinkCallerToFunction(ReturnAddressPtr returnAddress,FunctionPtr function)105 void relinkCallerToFunction(ReturnAddressPtr returnAddress, FunctionPtr function) 106 { 107 relink(CodeLocationCall(CodePtr(returnAddress)), function); 108 } 109 relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress,CodeLocationLabel label)110 void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label) 111 { 112 relink(CodeLocationNearCall(CodePtr(returnAddress)), label); 113 } 114 relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress,CodePtr newCalleeFunction)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