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 #include <wtf/Platform.h> 30 31 #if ENABLE(ASSEMBLER) 32 33 #include <MacroAssembler.h> 34 #include <wtf/Noncopyable.h> 35 36 namespace JSC { 37 38 // RepatchBuffer: 39 // 40 // This class is used to modify code after code generation has been completed, 41 // and after the code has potentially already been executed. This mechanism is 42 // used to apply optimizations to the code. 43 // 44 class RepatchBuffer { 45 typedef MacroAssemblerCodePtr CodePtr; 46 47 public: 48 RepatchBuffer(CodeBlock* codeBlock) 49 { 50 JITCode& code = codeBlock->getJITCode(); 51 m_start = code.start(); 52 m_size = code.size(); 53 54 ExecutableAllocator::makeWritable(m_start, m_size); 55 } 56 57 ~RepatchBuffer() 58 { 59 ExecutableAllocator::makeExecutable(m_start, m_size); 60 } 61 62 void relink(CodeLocationJump jump, CodeLocationLabel destination) 63 { 64 MacroAssembler::repatchJump(jump, destination); 65 } 66 67 void relink(CodeLocationCall call, CodeLocationLabel destination) 68 { 69 MacroAssembler::repatchCall(call, destination); 70 } 71 72 void relink(CodeLocationCall call, FunctionPtr destination) 73 { 74 MacroAssembler::repatchCall(call, destination); 75 } 76 77 void relink(CodeLocationNearCall nearCall, CodePtr destination) 78 { 79 MacroAssembler::repatchNearCall(nearCall, CodeLocationLabel(destination)); 80 } 81 82 void relink(CodeLocationNearCall nearCall, CodeLocationLabel destination) 83 { 84 MacroAssembler::repatchNearCall(nearCall, destination); 85 } 86 87 void repatch(CodeLocationDataLabel32 dataLabel32, int32_t value) 88 { 89 MacroAssembler::repatchInt32(dataLabel32, value); 90 } 91 92 void repatch(CodeLocationDataLabelPtr dataLabelPtr, void* value) 93 { 94 MacroAssembler::repatchPointer(dataLabelPtr, value); 95 } 96 97 void repatchLoadPtrToLEA(CodeLocationInstruction instruction) 98 { 99 MacroAssembler::repatchLoadPtrToLEA(instruction); 100 } 101 102 void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label) 103 { 104 relink(CodeLocationCall(CodePtr(returnAddress)), label); 105 } 106 107 void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction) 108 { 109 relinkCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction)); 110 } 111 112 void relinkCallerToFunction(ReturnAddressPtr returnAddress, FunctionPtr function) 113 { 114 relink(CodeLocationCall(CodePtr(returnAddress)), function); 115 } 116 117 void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label) 118 { 119 relink(CodeLocationNearCall(CodePtr(returnAddress)), label); 120 } 121 122 void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction) 123 { 124 relinkNearCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction)); 125 } 126 127 private: 128 void* m_start; 129 size_t m_size; 130 }; 131 132 } // namespace JSC 133 134 #endif // ENABLE(ASSEMBLER) 135 136 #endif // RepatchBuffer_h 137