1 /* 2 * Copyright (C) 2008 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 JITStubCall_h 27 #define JITStubCall_h 28 29 #include <wtf/Platform.h> 30 31 #if ENABLE(JIT) 32 33 namespace JSC { 34 35 class JITStubCall { 36 public: JITStubCall(JIT * jit,JSObject * (JIT_STUB * stub)(STUB_ARGS_DECLARATION))37 JITStubCall(JIT* jit, JSObject* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) 38 : m_jit(jit) 39 , m_stub(reinterpret_cast<void*>(stub)) 40 , m_returnType(Cell) 41 , m_stackIndex(stackIndexStart) 42 { 43 } 44 JITStubCall(JIT * jit,JSPropertyNameIterator * (JIT_STUB * stub)(STUB_ARGS_DECLARATION))45 JITStubCall(JIT* jit, JSPropertyNameIterator* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) 46 : m_jit(jit) 47 , m_stub(reinterpret_cast<void*>(stub)) 48 , m_returnType(Cell) 49 , m_stackIndex(stackIndexStart) 50 { 51 } 52 JITStubCall(JIT * jit,void * (JIT_STUB * stub)(STUB_ARGS_DECLARATION))53 JITStubCall(JIT* jit, void* (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) 54 : m_jit(jit) 55 , m_stub(reinterpret_cast<void*>(stub)) 56 , m_returnType(VoidPtr) 57 , m_stackIndex(stackIndexStart) 58 { 59 } 60 JITStubCall(JIT * jit,int (JIT_STUB * stub)(STUB_ARGS_DECLARATION))61 JITStubCall(JIT* jit, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) 62 : m_jit(jit) 63 , m_stub(reinterpret_cast<void*>(stub)) 64 , m_returnType(Int) 65 , m_stackIndex(stackIndexStart) 66 { 67 } 68 JITStubCall(JIT * jit,bool (JIT_STUB * stub)(STUB_ARGS_DECLARATION))69 JITStubCall(JIT* jit, bool (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) 70 : m_jit(jit) 71 , m_stub(reinterpret_cast<void*>(stub)) 72 , m_returnType(Int) 73 , m_stackIndex(stackIndexStart) 74 { 75 } 76 JITStubCall(JIT * jit,void (JIT_STUB * stub)(STUB_ARGS_DECLARATION))77 JITStubCall(JIT* jit, void (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) 78 : m_jit(jit) 79 , m_stub(reinterpret_cast<void*>(stub)) 80 , m_returnType(Void) 81 , m_stackIndex(stackIndexStart) 82 { 83 } 84 85 #if USE(JSVALUE32_64) JITStubCall(JIT * jit,EncodedJSValue (JIT_STUB * stub)(STUB_ARGS_DECLARATION))86 JITStubCall(JIT* jit, EncodedJSValue (JIT_STUB *stub)(STUB_ARGS_DECLARATION)) 87 : m_jit(jit) 88 , m_stub(reinterpret_cast<void*>(stub)) 89 , m_returnType(Value) 90 , m_stackIndex(stackIndexStart) 91 { 92 } 93 #endif 94 95 // Arguments are added first to last. 96 skipArgument()97 void skipArgument() 98 { 99 m_stackIndex += stackIndexStep; 100 } 101 addArgument(JIT::Imm32 argument)102 void addArgument(JIT::Imm32 argument) 103 { 104 m_jit->poke(argument, m_stackIndex); 105 m_stackIndex += stackIndexStep; 106 } 107 addArgument(JIT::ImmPtr argument)108 void addArgument(JIT::ImmPtr argument) 109 { 110 m_jit->poke(argument, m_stackIndex); 111 m_stackIndex += stackIndexStep; 112 } 113 addArgument(JIT::RegisterID argument)114 void addArgument(JIT::RegisterID argument) 115 { 116 m_jit->poke(argument, m_stackIndex); 117 m_stackIndex += stackIndexStep; 118 } 119 addArgument(const JSValue & value)120 void addArgument(const JSValue& value) 121 { 122 m_jit->poke(JIT::Imm32(value.payload()), m_stackIndex); 123 m_jit->poke(JIT::Imm32(value.tag()), m_stackIndex + 1); 124 m_stackIndex += stackIndexStep; 125 } 126 addArgument(JIT::RegisterID tag,JIT::RegisterID payload)127 void addArgument(JIT::RegisterID tag, JIT::RegisterID payload) 128 { 129 m_jit->poke(payload, m_stackIndex); 130 m_jit->poke(tag, m_stackIndex + 1); 131 m_stackIndex += stackIndexStep; 132 } 133 134 #if USE(JSVALUE32_64) addArgument(unsigned srcVirtualRegister)135 void addArgument(unsigned srcVirtualRegister) 136 { 137 if (m_jit->m_codeBlock->isConstantRegisterIndex(srcVirtualRegister)) { 138 addArgument(m_jit->getConstantOperand(srcVirtualRegister)); 139 return; 140 } 141 142 m_jit->emitLoad(srcVirtualRegister, JIT::regT1, JIT::regT0); 143 addArgument(JIT::regT1, JIT::regT0); 144 } 145 getArgument(size_t argumentNumber,JIT::RegisterID tag,JIT::RegisterID payload)146 void getArgument(size_t argumentNumber, JIT::RegisterID tag, JIT::RegisterID payload) 147 { 148 size_t stackIndex = stackIndexStart + (argumentNumber * stackIndexStep); 149 m_jit->peek(payload, stackIndex); 150 m_jit->peek(tag, stackIndex + 1); 151 } 152 #else addArgument(unsigned src,JIT::RegisterID scratchRegister)153 void addArgument(unsigned src, JIT::RegisterID scratchRegister) // src is a virtual register. 154 { 155 if (m_jit->m_codeBlock->isConstantRegisterIndex(src)) 156 addArgument(JIT::ImmPtr(JSValue::encode(m_jit->m_codeBlock->getConstant(src)))); 157 else { 158 m_jit->loadPtr(JIT::Address(JIT::callFrameRegister, src * sizeof(Register)), scratchRegister); 159 addArgument(scratchRegister); 160 } 161 m_jit->killLastResultRegister(); 162 } 163 #endif 164 call()165 JIT::Call call() 166 { 167 #if ENABLE(OPCODE_SAMPLING) 168 if (m_jit->m_bytecodeIndex != (unsigned)-1) 169 m_jit->sampleInstruction(m_jit->m_codeBlock->instructions().begin() + m_jit->m_bytecodeIndex, true); 170 #endif 171 172 m_jit->restoreArgumentReference(); 173 JIT::Call call = m_jit->call(); 174 m_jit->m_calls.append(CallRecord(call, m_jit->m_bytecodeIndex, m_stub)); 175 176 #if ENABLE(OPCODE_SAMPLING) 177 if (m_jit->m_bytecodeIndex != (unsigned)-1) 178 m_jit->sampleInstruction(m_jit->m_codeBlock->instructions().begin() + m_jit->m_bytecodeIndex, false); 179 #endif 180 181 #if USE(JSVALUE32_64) 182 m_jit->unmap(); 183 #else 184 m_jit->killLastResultRegister(); 185 #endif 186 return call; 187 } 188 189 #if USE(JSVALUE32_64) call(unsigned dst)190 JIT::Call call(unsigned dst) // dst is a virtual register. 191 { 192 ASSERT(m_returnType == Value || m_returnType == Cell); 193 JIT::Call call = this->call(); 194 if (m_returnType == Value) 195 m_jit->emitStore(dst, JIT::regT1, JIT::regT0); 196 else 197 m_jit->emitStoreCell(dst, JIT::returnValueRegister); 198 return call; 199 } 200 #else call(unsigned dst)201 JIT::Call call(unsigned dst) // dst is a virtual register. 202 { 203 ASSERT(m_returnType == VoidPtr || m_returnType == Cell); 204 JIT::Call call = this->call(); 205 m_jit->emitPutVirtualRegister(dst); 206 return call; 207 } 208 #endif 209 call(JIT::RegisterID dst)210 JIT::Call call(JIT::RegisterID dst) // dst is a machine register. 211 { 212 #if USE(JSVALUE32_64) 213 ASSERT(m_returnType == Value || m_returnType == VoidPtr || m_returnType == Int || m_returnType == Cell); 214 #else 215 ASSERT(m_returnType == VoidPtr || m_returnType == Int || m_returnType == Cell); 216 #endif 217 JIT::Call call = this->call(); 218 if (dst != JIT::returnValueRegister) 219 m_jit->move(JIT::returnValueRegister, dst); 220 return call; 221 } 222 223 private: 224 static const size_t stackIndexStep = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 2 : 1; 225 static const size_t stackIndexStart = 1; // Index 0 is reserved for restoreArgumentReference(). 226 227 JIT* m_jit; 228 void* m_stub; 229 enum { Void, VoidPtr, Int, Value, Cell } m_returnType; 230 size_t m_stackIndex; 231 }; 232 } 233 234 #endif // ENABLE(JIT) 235 236 #endif // JITStubCall_h 237