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 CodeLocation_h 27 #define CodeLocation_h 28 29 #include <wtf/Platform.h> 30 31 #include <MacroAssemblerCodeRef.h> 32 33 #if ENABLE(ASSEMBLER) 34 35 namespace JSC { 36 37 class CodeLocationInstruction; 38 class CodeLocationLabel; 39 class CodeLocationJump; 40 class CodeLocationCall; 41 class CodeLocationNearCall; 42 class CodeLocationDataLabel32; 43 class CodeLocationDataLabelPtr; 44 45 // The CodeLocation* types are all pretty much do-nothing wrappers around 46 // CodePtr (or MacroAssemblerCodePtr, to give it its full name). These 47 // classes only exist to provide type-safety when linking and patching code. 48 // 49 // The one new piece of functionallity introduced by these classes is the 50 // ability to create (or put another way, to re-discover) another CodeLocation 51 // at an offset from one you already know. When patching code to optimize it 52 // we often want to patch a number of instructions that are short, fixed 53 // offsets apart. To reduce memory overhead we will only retain a pointer to 54 // one of the instructions, and we will use the *AtOffset methods provided by 55 // CodeLocationCommon to find the other points in the code to modify. 56 class CodeLocationCommon : public MacroAssemblerCodePtr { 57 public: 58 CodeLocationInstruction instructionAtOffset(int offset); 59 CodeLocationLabel labelAtOffset(int offset); 60 CodeLocationJump jumpAtOffset(int offset); 61 CodeLocationCall callAtOffset(int offset); 62 CodeLocationNearCall nearCallAtOffset(int offset); 63 CodeLocationDataLabelPtr dataLabelPtrAtOffset(int offset); 64 CodeLocationDataLabel32 dataLabel32AtOffset(int offset); 65 66 protected: 67 CodeLocationCommon() 68 { 69 } 70 71 CodeLocationCommon(MacroAssemblerCodePtr location) 72 : MacroAssemblerCodePtr(location) 73 { 74 } 75 }; 76 77 class CodeLocationInstruction : public CodeLocationCommon { 78 public: 79 CodeLocationInstruction() {} 80 explicit CodeLocationInstruction(MacroAssemblerCodePtr location) 81 : CodeLocationCommon(location) {} 82 explicit CodeLocationInstruction(void* location) 83 : CodeLocationCommon(MacroAssemblerCodePtr(location)) {} 84 }; 85 86 class CodeLocationLabel : public CodeLocationCommon { 87 public: 88 CodeLocationLabel() {} 89 explicit CodeLocationLabel(MacroAssemblerCodePtr location) 90 : CodeLocationCommon(location) {} 91 explicit CodeLocationLabel(void* location) 92 : CodeLocationCommon(MacroAssemblerCodePtr(location)) {} 93 }; 94 95 class CodeLocationJump : public CodeLocationCommon { 96 public: 97 CodeLocationJump() {} 98 explicit CodeLocationJump(MacroAssemblerCodePtr location) 99 : CodeLocationCommon(location) {} 100 explicit CodeLocationJump(void* location) 101 : CodeLocationCommon(MacroAssemblerCodePtr(location)) {} 102 }; 103 104 class CodeLocationCall : public CodeLocationCommon { 105 public: 106 CodeLocationCall() {} 107 explicit CodeLocationCall(MacroAssemblerCodePtr location) 108 : CodeLocationCommon(location) {} 109 explicit CodeLocationCall(void* location) 110 : CodeLocationCommon(MacroAssemblerCodePtr(location)) {} 111 }; 112 113 class CodeLocationNearCall : public CodeLocationCommon { 114 public: 115 CodeLocationNearCall() {} 116 explicit CodeLocationNearCall(MacroAssemblerCodePtr location) 117 : CodeLocationCommon(location) {} 118 explicit CodeLocationNearCall(void* location) 119 : CodeLocationCommon(MacroAssemblerCodePtr(location)) {} 120 }; 121 122 class CodeLocationDataLabel32 : public CodeLocationCommon { 123 public: 124 CodeLocationDataLabel32() {} 125 explicit CodeLocationDataLabel32(MacroAssemblerCodePtr location) 126 : CodeLocationCommon(location) {} 127 explicit CodeLocationDataLabel32(void* location) 128 : CodeLocationCommon(MacroAssemblerCodePtr(location)) {} 129 }; 130 131 class CodeLocationDataLabelPtr : public CodeLocationCommon { 132 public: 133 CodeLocationDataLabelPtr() {} 134 explicit CodeLocationDataLabelPtr(MacroAssemblerCodePtr location) 135 : CodeLocationCommon(location) {} 136 explicit CodeLocationDataLabelPtr(void* location) 137 : CodeLocationCommon(MacroAssemblerCodePtr(location)) {} 138 }; 139 140 inline CodeLocationInstruction CodeLocationCommon::instructionAtOffset(int offset) 141 { 142 ASSERT_VALID_CODE_OFFSET(offset); 143 return CodeLocationInstruction(reinterpret_cast<char*>(dataLocation()) + offset); 144 } 145 146 inline CodeLocationLabel CodeLocationCommon::labelAtOffset(int offset) 147 { 148 ASSERT_VALID_CODE_OFFSET(offset); 149 return CodeLocationLabel(reinterpret_cast<char*>(dataLocation()) + offset); 150 } 151 152 inline CodeLocationJump CodeLocationCommon::jumpAtOffset(int offset) 153 { 154 ASSERT_VALID_CODE_OFFSET(offset); 155 return CodeLocationJump(reinterpret_cast<char*>(dataLocation()) + offset); 156 } 157 158 inline CodeLocationCall CodeLocationCommon::callAtOffset(int offset) 159 { 160 ASSERT_VALID_CODE_OFFSET(offset); 161 return CodeLocationCall(reinterpret_cast<char*>(dataLocation()) + offset); 162 } 163 164 inline CodeLocationNearCall CodeLocationCommon::nearCallAtOffset(int offset) 165 { 166 ASSERT_VALID_CODE_OFFSET(offset); 167 return CodeLocationNearCall(reinterpret_cast<char*>(dataLocation()) + offset); 168 } 169 170 inline CodeLocationDataLabelPtr CodeLocationCommon::dataLabelPtrAtOffset(int offset) 171 { 172 ASSERT_VALID_CODE_OFFSET(offset); 173 return CodeLocationDataLabelPtr(reinterpret_cast<char*>(dataLocation()) + offset); 174 } 175 176 inline CodeLocationDataLabel32 CodeLocationCommon::dataLabel32AtOffset(int offset) 177 { 178 ASSERT_VALID_CODE_OFFSET(offset); 179 return CodeLocationDataLabel32(reinterpret_cast<char*>(dataLocation()) + offset); 180 } 181 182 } // namespace JSC 183 184 #endif // ENABLE(ASSEMBLER) 185 186 #endif // CodeLocation_h 187