blob: 9330e773e74514354220efa667863a6e9d7e7326 [file] [log] [blame]
barraclough@apple.come367b002008-12-04 05:43:14 +00001/*
oliver@apple.comc14eb7d2013-07-25 03:58:47 +00002 * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved.
barraclough@apple.come367b002008-12-04 05:43:14 +00003 *
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
mark.lam@apple.coma4fe7ab2012-11-09 03:03:44 +000026#ifndef JITInlines_h
27#define JITInlines_h
barraclough@apple.come367b002008-12-04 05:43:14 +000028
barraclough@apple.come367b002008-12-04 05:43:14 +000029
30#if ENABLE(JIT)
31
oliver@apple.comc4c9b8a2013-07-25 04:02:09 +000032#include "CallFrameInlines.h"
33
barraclough@apple.come367b002008-12-04 05:43:14 +000034namespace JSC {
35
msaboff@apple.com7535bbd2013-09-10 06:01:03 +000036ALWAYS_INLINE bool JIT::isOperandConstantImmediateDouble(int src)
oliver@apple.com8d181632009-09-25 02:40:59 +000037{
38 return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isDouble();
39}
40
msaboff@apple.com7535bbd2013-09-10 06:01:03 +000041ALWAYS_INLINE JSValue JIT::getConstantOperand(int src)
barraclough@apple.combe1ce032009-01-02 03:06:10 +000042{
43 ASSERT(m_codeBlock->isConstantRegisterIndex(src));
44 return m_codeBlock->getConstant(src);
45}
46
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000047ALWAYS_INLINE void JIT::emitPutIntToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry entry)
oliver@apple.com9d4f0ec2011-03-14 18:16:36 +000048{
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +000049#if USE(JSVALUE32_64)
oliver@apple.combe4e0672011-03-28 17:14:57 +000050 store32(TrustedImm32(Int32Tag), intTagFor(entry, callFrameRegister));
oliver@apple.com9d4f0ec2011-03-14 18:16:36 +000051 store32(from, intPayloadFor(entry, callFrameRegister));
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +000052#else
53 store64(from, addressFor(entry, callFrameRegister));
54#endif
55}
56
mark.lam@apple.com4fbb9c32012-10-09 07:12:56 +000057ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
barraclough@apple.come367b002008-12-04 05:43:14 +000058{
oliver@apple.come79807b2009-05-05 11:34:23 +000059 loadPtr(Address(from, entry * sizeof(Register)), to);
oliver@apple.come79807b2009-05-05 11:34:23 +000060}
61
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +000062ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
63{
64 load32(Address(from, entry * sizeof(Register)), to);
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +000065}
66
67#if USE(JSVALUE64)
68ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader64(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
69{
70 load64(Address(from, entry * sizeof(Register)), to);
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +000071}
72#endif
73
oliver@apple.com5230bd32010-05-06 19:39:54 +000074ALWAYS_INLINE void JIT::emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures)
75{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000076 failures.append(branchPtr(NotEqual, Address(src, JSCell::structureOffset()), TrustedImmPtr(m_vm->stringStructure.get())));
oliver@apple.combe4e0672011-03-28 17:14:57 +000077 failures.append(branch32(NotEqual, MacroAssembler::Address(src, ThunkHelpers::jsStringLengthOffset()), TrustedImm32(1)));
oliver@apple.com5230bd32010-05-06 19:39:54 +000078 loadPtr(MacroAssembler::Address(src, ThunkHelpers::jsStringValueOffset()), dst);
ggaren@apple.comffbe44d2011-10-19 19:45:35 +000079 failures.append(branchTest32(Zero, dst));
benjamin@webkit.orgde409f72013-04-30 01:22:32 +000080 loadPtr(MacroAssembler::Address(dst, StringImpl::flagsOffset()), regT1);
81 loadPtr(MacroAssembler::Address(dst, StringImpl::dataOffset()), dst);
msaboff@apple.coma64c5812011-10-28 01:09:53 +000082
83 JumpList is16Bit;
84 JumpList cont8Bit;
benjamin@webkit.orgde409f72013-04-30 01:22:32 +000085 is16Bit.append(branchTest32(Zero, regT1, TrustedImm32(StringImpl::flagIs8Bit())));
msaboff@apple.coma64c5812011-10-28 01:09:53 +000086 load8(MacroAssembler::Address(dst, 0), dst);
87 cont8Bit.append(jump());
88 is16Bit.link(this);
oliver@apple.com5230bd32010-05-06 19:39:54 +000089 load16(MacroAssembler::Address(dst, 0), dst);
msaboff@apple.coma64c5812011-10-28 01:09:53 +000090 cont8Bit.link(this);
oliver@apple.com5230bd32010-05-06 19:39:54 +000091}
92
barraclough@apple.com97bacef2009-06-05 07:55:38 +000093ALWAYS_INLINE JIT::Call JIT::emitNakedCall(CodePtr function)
barraclough@apple.come367b002008-12-04 05:43:14 +000094{
ggaren@apple.com1ba49812010-05-19 18:28:54 +000095 ASSERT(m_bytecodeOffset != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
barraclough@apple.com249befb2008-12-13 03:18:10 +000096
barraclough@apple.comd7e13382009-02-19 22:51:40 +000097 Call nakedCall = nearCall();
ggaren@apple.com1ba49812010-05-19 18:28:54 +000098 m_calls.append(CallRecord(nakedCall, m_bytecodeOffset, function.executableAddress()));
barraclough@apple.com80924152008-12-05 06:58:40 +000099 return nakedCall;
barraclough@apple.come367b002008-12-04 05:43:14 +0000100}
101
commit-queue@webkit.org84814622011-08-25 01:25:38 +0000102ALWAYS_INLINE void JIT::updateTopCallFrame()
103{
oliver@apple.com8b234c92012-02-08 21:22:49 +0000104 ASSERT(static_cast<int>(m_bytecodeOffset) >= 0);
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +0000105#if USE(JSVALUE32_64)
oliver@apple.comc4c9b8a2013-07-25 04:02:09 +0000106 Instruction* instruction = m_codeBlock->instructions().begin() + m_bytecodeOffset + 1;
107 uint32_t locationBits = CallFrame::Location::encodeAsBytecodeInstruction(instruction);
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +0000108#else
oliver@apple.comc4c9b8a2013-07-25 04:02:09 +0000109 uint32_t locationBits = CallFrame::Location::encodeAsBytecodeOffset(m_bytecodeOffset + 1);
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +0000110#endif
oliver@apple.comc4c9b8a2013-07-25 04:02:09 +0000111 store32(TrustedImm32(locationBits), intTagFor(JSStack::ArgumentCount));
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000112 storePtr(callFrameRegister, &m_vm->topCallFrame);
commit-queue@webkit.org84814622011-08-25 01:25:38 +0000113}
114
msaboff@apple.coma482c542013-10-04 18:20:40 +0000115ALWAYS_INLINE MacroAssembler::Call JIT::appendCallWithExceptionCheck(const FunctionPtr& function)
116{
117 updateTopCallFrame();
118 MacroAssembler::Call call = appendCall(function);
119 exceptionCheck();
120 return call;
121}
122
msaboff@apple.com5ca16c42013-10-07 18:20:27 +0000123ALWAYS_INLINE MacroAssembler::Call JIT::appendCallWithCallFrameRollbackOnException(const FunctionPtr& function)
124{
125 updateTopCallFrame(); // The callee is responsible for setting topCallFrame to their caller
126 MacroAssembler::Call call = appendCall(function);
127 exceptionCheckWithCallFrameRollback();
128 return call;
129}
130
msaboff@apple.coma482c542013-10-04 18:20:40 +0000131ALWAYS_INLINE MacroAssembler::Call JIT::appendCallWithExceptionCheckSetJSValueResult(const FunctionPtr& function, int dst)
132{
133 MacroAssembler::Call call = appendCallWithExceptionCheck(function);
134#if USE(JSVALUE64)
mark.lam@apple.comab6b5eb2013-11-08 04:05:27 +0000135 emitPutVirtualRegister(dst, returnValueGPR);
msaboff@apple.coma482c542013-10-04 18:20:40 +0000136#else
mark.lam@apple.comab6b5eb2013-11-08 04:05:27 +0000137 emitStore(dst, returnValueGPR2, returnValueGPR);
msaboff@apple.coma482c542013-10-04 18:20:40 +0000138#endif
139 return call;
140}
141
fpizlo@apple.com1cfa0a92013-10-16 02:19:20 +0000142ALWAYS_INLINE MacroAssembler::Call JIT::appendCallWithExceptionCheckSetJSValueResultWithProfile(const FunctionPtr& function, int dst)
143{
144 MacroAssembler::Call call = appendCallWithExceptionCheck(function);
fpizlo@apple.comba833642014-01-06 20:41:32 +0000145 emitValueProfilingSite();
fpizlo@apple.com1cfa0a92013-10-16 02:19:20 +0000146#if USE(JSVALUE64)
mark.lam@apple.comab6b5eb2013-11-08 04:05:27 +0000147 emitPutVirtualRegister(dst, returnValueGPR);
fpizlo@apple.com1cfa0a92013-10-16 02:19:20 +0000148#else
mark.lam@apple.comab6b5eb2013-11-08 04:05:27 +0000149 emitStore(dst, returnValueGPR2, returnValueGPR);
fpizlo@apple.com1cfa0a92013-10-16 02:19:20 +0000150#endif
151 return call;
152}
153
mark.lam@apple.com03944a02013-10-14 16:42:22 +0000154ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_E operation)
155{
156 setupArgumentsExecState();
157 return appendCallWithExceptionCheck(operation);
158}
159
160ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EO operation, GPRReg arg)
161{
162 setupArgumentsWithExecState(arg);
163 return appendCallWithExceptionCheck(operation);
164}
165
mark.lam@apple.com5d7e7082013-10-11 19:03:39 +0000166ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_ESt operation, Structure* structure)
167{
168 setupArgumentsWithExecState(TrustedImmPtr(structure));
169 return appendCallWithExceptionCheck(operation);
170}
171
mark.lam@apple.com03944a02013-10-14 16:42:22 +0000172ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(C_JITOperation_EZ operation, int32_t arg)
173{
174 setupArgumentsWithExecState(TrustedImm32(arg));
175 return appendCallWithExceptionCheck(operation);
176}
177
msaboff@apple.coma482c542013-10-04 18:20:40 +0000178ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_E operation, int dst)
179{
180 setupArgumentsExecState();
181 return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
182}
183
mark.lam@apple.com5d7e7082013-10-11 19:03:39 +0000184ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EAapJcpZ operation, int dst, ArrayAllocationProfile* arg1, GPRReg arg2, int32_t arg3)
185{
186 setupArgumentsWithExecState(TrustedImmPtr(arg1), arg2, TrustedImm32(arg3));
187 return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
188}
189
190ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EAapJcpZ operation, int dst, ArrayAllocationProfile* arg1, const JSValue* arg2, int32_t arg3)
191{
192 setupArgumentsWithExecState(TrustedImmPtr(arg1), TrustedImmPtr(arg2), TrustedImm32(arg3));
193 return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
194}
195
196ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EC operation, int dst, JSCell* cell)
197{
198 setupArgumentsWithExecState(TrustedImmPtr(cell));
199 return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
200}
201
mhahnenberg@apple.com2ceb9d72013-12-20 00:49:58 +0000202ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EC operation, JSCell* cell)
203{
204 setupArgumentsWithExecState(TrustedImmPtr(cell));
205 return appendCallWithExceptionCheck(operation);
206}
207
msaboff@apple.coma482c542013-10-04 18:20:40 +0000208ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EP operation, int dst, void* pointer)
209{
210 setupArgumentsWithExecState(TrustedImmPtr(pointer));
211 return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
212}
213
fpizlo@apple.com1cfa0a92013-10-16 02:19:20 +0000214ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(WithProfileTag, J_JITOperation_EPc operation, int dst, Instruction* bytecodePC)
mark.lam@apple.com2a90d902013-10-15 03:03:45 +0000215{
216 setupArgumentsWithExecState(TrustedImmPtr(bytecodePC));
fpizlo@apple.com1cfa0a92013-10-16 02:19:20 +0000217 return appendCallWithExceptionCheckSetJSValueResultWithProfile(operation, dst);
mark.lam@apple.com2a90d902013-10-15 03:03:45 +0000218}
219
220ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EZ operation, int dst, int32_t arg)
221{
222 setupArgumentsWithExecState(TrustedImm32(arg));
223 return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
224}
225
msaboff@apple.com4b6250f2013-10-15 18:33:04 +0000226ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(P_JITOperation_EZ operation, int32_t op)
227{
228 setupArgumentsWithExecState(TrustedImm32(op));
229 return appendCallWithExceptionCheck(operation);
230}
231
msaboff@apple.comc8dd3f72013-10-10 23:10:40 +0000232ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(S_JITOperation_ECC operation, RegisterID regOp1, RegisterID regOp2)
233{
234 setupArgumentsWithExecState(regOp1, regOp2);
235 return appendCallWithExceptionCheck(operation);
236}
237
msaboff@apple.comc8dd3f72013-10-10 23:10:40 +0000238ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(S_JITOperation_EOJss operation, RegisterID regOp1, RegisterID regOp2)
239{
240 setupArgumentsWithExecState(regOp1, regOp2);
241 return appendCallWithExceptionCheck(operation);
242}
243
msaboff@apple.com4b6250f2013-10-15 18:33:04 +0000244ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_E operation)
245{
246 setupArgumentsExecState();
247 return appendCallWithExceptionCheck(operation);
248}
249
msaboff@apple.com4b6250f2013-10-15 18:33:04 +0000250ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EC operation, RegisterID regOp)
251{
252 setupArgumentsWithExecState(regOp);
253 return appendCallWithExceptionCheck(operation);
254}
255
256ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_ECC operation, RegisterID regOp1, RegisterID regOp2)
257{
258 setupArgumentsWithExecState(regOp1, regOp2);
259 return appendCallWithExceptionCheck(operation);
260}
261
mark.lam@apple.com2a90d902013-10-15 03:03:45 +0000262ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EPc operation, Instruction* bytecodePC)
263{
264 setupArgumentsWithExecState(TrustedImmPtr(bytecodePC));
265 return appendCallWithExceptionCheck(operation);
266}
267
msaboff@apple.com4b6250f2013-10-15 18:33:04 +0000268ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EZ operation, int32_t op)
269{
270 setupArgumentsWithExecState(TrustedImm32(op));
271 return appendCallWithExceptionCheck(operation);
272}
273
msaboff@apple.com2b95ada2013-10-09 13:29:00 +0000274ALWAYS_INLINE MacroAssembler::Call JIT::callOperationWithCallFrameRollbackOnException(J_JITOperation_E operation)
275{
276 setupArgumentsExecState();
277 return appendCallWithCallFrameRollbackOnException(operation);
278}
279
msaboff@apple.com5ca16c42013-10-07 18:20:27 +0000280ALWAYS_INLINE MacroAssembler::Call JIT::callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb operation, CodeBlock* pointer)
msaboff@apple.coma482c542013-10-04 18:20:40 +0000281{
282 setupArgumentsWithExecState(TrustedImmPtr(pointer));
msaboff@apple.com5ca16c42013-10-07 18:20:27 +0000283 return appendCallWithCallFrameRollbackOnException(operation);
msaboff@apple.coma482c542013-10-04 18:20:40 +0000284}
msaboff@apple.com5ca16c42013-10-07 18:20:27 +0000285
286ALWAYS_INLINE MacroAssembler::Call JIT::callOperationWithCallFrameRollbackOnException(Z_JITOperation_E operation)
287{
288 setupArgumentsExecState();
289 return appendCallWithCallFrameRollbackOnException(operation);
290}
291
commit-queue@webkit.org54f3f2c2013-10-18 17:03:48 +0000292
293#if USE(JSVALUE64)
msaboff@apple.com75cc9322013-12-06 21:38:26 +0000294ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EJZ operation, GPRReg arg1, int32_t arg3)
commit-queue@webkit.org54f3f2c2013-10-18 17:03:48 +0000295{
msaboff@apple.com75cc9322013-12-06 21:38:26 +0000296 setupArgumentsWithExecState(arg1, TrustedImm32(arg3));
297 return appendCallWithExceptionCheck(operation);
298}
299
300ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
301{
302 setupArgumentsWithExecState(arg1, arg2, arg3);
commit-queue@webkit.org54f3f2c2013-10-18 17:03:48 +0000303 return appendCallWithExceptionCheck(operation);
304}
305
fpizlo@apple.comd49bfe82013-10-19 02:20:14 +0000306ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, RegisterID regOp1, RegisterID regOp2, StringImpl* uid)
commit-queue@webkit.org54f3f2c2013-10-18 17:03:48 +0000307{
fpizlo@apple.comd49bfe82013-10-19 02:20:14 +0000308 setupArgumentsWithExecState(TrustedImmPtr(stubInfo), regOp1, regOp2, TrustedImmPtr(uid));
commit-queue@webkit.org54f3f2c2013-10-18 17:03:48 +0000309 return appendCallWithExceptionCheck(operation);
310}
311
312ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJJJ operation, RegisterID regOp1, RegisterID regOp2, RegisterID regOp3)
313{
314 setupArgumentsWithExecState(regOp1, regOp2, regOp3);
315 return appendCallWithExceptionCheck(operation);
316}
317
fpizlo@apple.comd49bfe82013-10-19 02:20:14 +0000318ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(JIT::WithProfileTag, J_JITOperation_ESsiJI operation, int dst, StructureStubInfo* stubInfo, GPRReg arg1, StringImpl* uid)
commit-queue@webkit.org54f3f2c2013-10-18 17:03:48 +0000319{
fpizlo@apple.comd49bfe82013-10-19 02:20:14 +0000320 setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
commit-queue@webkit.org54f3f2c2013-10-18 17:03:48 +0000321 return appendCallWithExceptionCheckSetJSValueResultWithProfile(operation, dst);
322}
323
324ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(JIT::WithProfileTag, J_JITOperation_EJJ operation, int dst, GPRReg arg1, GPRReg arg2)
325{
326 setupArgumentsWithExecState(arg1, arg2);
327 return appendCallWithExceptionCheckSetJSValueResultWithProfile(operation, dst);
328}
329
330ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EAapJ operation, int dst, ArrayAllocationProfile* arg1, GPRReg arg2)
331{
332 setupArgumentsWithExecState(TrustedImmPtr(arg1), arg2);
333 return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
334}
335
336ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJ operation, int dst, GPRReg arg1)
337{
338 setupArgumentsWithExecState(arg1);
339 return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
340}
341
342ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJIdc operation, int dst, GPRReg arg1, const Identifier* arg2)
343{
344 setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
345 return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
346}
347
348ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJJ operation, int dst, GPRReg arg1, GPRReg arg2)
349{
350 setupArgumentsWithExecState(arg1, arg2);
351 return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
352}
353
354ALWAYS_INLINE MacroAssembler::Call JIT::callOperationNoExceptionCheck(V_JITOperation_EJ operation, GPRReg arg1)
355{
356 setupArgumentsWithExecState(arg1);
357 updateTopCallFrame();
358 return appendCall(operation);
359}
360
361ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(P_JITOperation_EJS operation, GPRReg arg1, size_t arg2)
362{
363 setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
364 return appendCallWithExceptionCheck(operation);
365}
366
367ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(S_JITOperation_EJ operation, RegisterID regOp)
368{
369 setupArgumentsWithExecState(regOp);
370 return appendCallWithExceptionCheck(operation);
371}
372
373ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(S_JITOperation_EJJ operation, RegisterID regOp1, RegisterID regOp2)
374{
375 setupArgumentsWithExecState(regOp1, regOp2);
376 return appendCallWithExceptionCheck(operation);
377}
378
379ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EIdJZ operation, const Identifier* identOp1, RegisterID regOp2, int32_t op3)
380{
381 setupArgumentsWithExecState(TrustedImmPtr(identOp1), regOp2, TrustedImm32(op3));
382 return appendCallWithExceptionCheck(operation);
383}
384
385ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJ operation, RegisterID regOp)
386{
387 setupArgumentsWithExecState(regOp);
388 return appendCallWithExceptionCheck(operation);
389}
390
391ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJIdJJ operation, RegisterID regOp1, const Identifier* identOp2, RegisterID regOp3, RegisterID regOp4)
392{
393 setupArgumentsWithExecState(regOp1, TrustedImmPtr(identOp2), regOp3, regOp4);
394 return appendCallWithExceptionCheck(operation);
395}
396
397ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJZ operation, RegisterID regOp1, int32_t op2)
398{
399 setupArgumentsWithExecState(regOp1, TrustedImm32(op2));
400 return appendCallWithExceptionCheck(operation);
401}
402
403ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJZJ operation, RegisterID regOp1, int32_t op2, RegisterID regOp3)
404{
405 setupArgumentsWithExecState(regOp1, TrustedImm32(op2), regOp3);
406 return appendCallWithExceptionCheck(operation);
407}
408
409#else // USE(JSVALUE32_64)
msaboff@apple.comc8dd3f72013-10-10 23:10:40 +0000410
411// EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]).
412// To avoid assemblies from using wrong registers, let's occupy r1 or r3 with a dummy argument when necessary.
413#if (COMPILER_SUPPORTS(EABI) && CPU(ARM)) || CPU(MIPS)
414#define EABI_32BIT_DUMMY_ARG TrustedImm32(0),
415#else
416#define EABI_32BIT_DUMMY_ARG
417#endif
418
419// JSVALUE32_64 is a 64-bit integer that cannot be put half in an argument register and half on stack when using SH4 architecture.
commit-queue@webkit.org0d080f42013-10-15 22:23:49 +0000420// To avoid this, let's occupy the 4th argument register (r7) with a dummy argument when necessary. This must only be done when there
421// is no other 32-bit value argument behind this 64-bit JSValue.
msaboff@apple.comc8dd3f72013-10-10 23:10:40 +0000422#if CPU(SH4)
423#define SH4_32BIT_DUMMY_ARG TrustedImm32(0),
424#else
425#define SH4_32BIT_DUMMY_ARG
426#endif
427
commit-queue@webkit.org54f3f2c2013-10-18 17:03:48 +0000428ALWAYS_INLINE MacroAssembler::Call JIT::callOperationNoExceptionCheck(V_JITOperation_EJ operation, GPRReg arg1Tag, GPRReg arg1Payload)
429{
commit-queue@webkit.orgda99c7f2013-10-22 17:04:59 +0000430 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
commit-queue@webkit.org54f3f2c2013-10-18 17:03:48 +0000431 updateTopCallFrame();
432 return appendCall(operation);
433}
434
msaboff@apple.com75cc9322013-12-06 21:38:26 +0000435ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EJZ operation, GPRReg arg1Tag, GPRReg arg1Payload, int32_t arg2)
mark.lam@apple.com03944a02013-10-14 16:42:22 +0000436{
commit-queue@webkit.org0d080f42013-10-15 22:23:49 +0000437#if CPU(SH4)
438 // We have to put arg3 in the 4th argument register (r7) as 64-bit value arg2 will be put on stack for sh4 architecure.
msaboff@apple.com75cc9322013-12-06 21:38:26 +0000439 setupArgumentsWithExecState(arg1Payload, arg1Tag, TrustedImm32(arg2));
commit-queue@webkit.org0d080f42013-10-15 22:23:49 +0000440#else
msaboff@apple.com75cc9322013-12-06 21:38:26 +0000441 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImm32(arg2));
commit-queue@webkit.org0d080f42013-10-15 22:23:49 +0000442#endif
mark.lam@apple.com03944a02013-10-14 16:42:22 +0000443 return appendCallWithExceptionCheck(operation);
444}
445
msaboff@apple.com75cc9322013-12-06 21:38:26 +0000446ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(F_JITOperation_EFJJ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
447{
448 setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, arg3Payload, arg3Tag);
449 return appendCallWithExceptionCheck(operation);
450}
451
mark.lam@apple.com5d7e7082013-10-11 19:03:39 +0000452ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EAapJ operation, int dst, ArrayAllocationProfile* arg1, GPRReg arg2Tag, GPRReg arg2Payload)
453{
commit-queue@webkit.orgf857f1f2013-10-18 15:23:51 +0000454 setupArgumentsWithExecState(TrustedImmPtr(arg1), arg2Payload, arg2Tag);
mark.lam@apple.com5d7e7082013-10-11 19:03:39 +0000455 return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
456}
457
mark.lam@apple.com03944a02013-10-14 16:42:22 +0000458ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJ operation, int dst, GPRReg arg1Tag, GPRReg arg1Payload)
459{
460 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
461 return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
462}
463
fpizlo@apple.comd49bfe82013-10-19 02:20:14 +0000464ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(JIT::WithProfileTag, J_JITOperation_ESsiJI operation, int dst, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, StringImpl* uid)
fpizlo@apple.com1cfa0a92013-10-16 02:19:20 +0000465{
fpizlo@apple.comd49bfe82013-10-19 02:20:14 +0000466 setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, TrustedImmPtr(uid));
fpizlo@apple.com1cfa0a92013-10-16 02:19:20 +0000467 return appendCallWithExceptionCheckSetJSValueResultWithProfile(operation, dst);
468}
469
mark.lam@apple.com03944a02013-10-14 16:42:22 +0000470ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJIdc operation, int dst, GPRReg arg1Tag, GPRReg arg1Payload, const Identifier* arg2)
471{
472 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(arg2));
473 return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
474}
475
476ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(J_JITOperation_EJJ operation, int dst, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
477{
478 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
479 return appendCallWithExceptionCheckSetJSValueResult(operation, dst);
480}
481
mark.lam@apple.com65293072013-10-17 07:20:20 +0000482ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(JIT::WithProfileTag, J_JITOperation_EJJ operation, int dst, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
483{
484 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
485 return appendCallWithExceptionCheckSetJSValueResultWithProfile(operation, dst);
486}
487
mark.lam@apple.com2a90d902013-10-15 03:03:45 +0000488ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(P_JITOperation_EJS operation, GPRReg arg1Tag, GPRReg arg1Payload, size_t arg2)
489{
490 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(arg2));
491 return appendCallWithExceptionCheck(operation);
492}
493
msaboff@apple.comc8dd3f72013-10-10 23:10:40 +0000494ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(S_JITOperation_EJ operation, RegisterID argTag, RegisterID argPayload)
495{
496 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG argPayload, argTag);
497 return appendCallWithExceptionCheck(operation);
498}
499
500ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(S_JITOperation_EJJ operation, RegisterID arg1Tag, RegisterID arg1Payload, RegisterID arg2Tag, RegisterID arg2Payload)
501{
502 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
503 return appendCallWithExceptionCheck(operation);
504}
505
msaboff@apple.com4b6250f2013-10-15 18:33:04 +0000506ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_ECICC operation, RegisterID regOp1, const Identifier* identOp2, RegisterID regOp3, RegisterID regOp4)
507{
508 setupArgumentsWithExecState(regOp1, TrustedImmPtr(identOp2), regOp3, regOp4);
509 return appendCallWithExceptionCheck(operation);
510}
511
512ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJ operation, RegisterID regOp1Tag, RegisterID regOp1Payload)
513{
commit-queue@webkit.orgda99c7f2013-10-22 17:04:59 +0000514 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG regOp1Payload, regOp1Tag);
msaboff@apple.com4b6250f2013-10-15 18:33:04 +0000515 return appendCallWithExceptionCheck(operation);
516}
517
518ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EIdJZ operation, const Identifier* identOp1, RegisterID regOp2Tag, RegisterID regOp2Payload, int32_t op3)
519{
commit-queue@webkit.org0d080f42013-10-15 22:23:49 +0000520 setupArgumentsWithExecState(TrustedImmPtr(identOp1), regOp2Payload, regOp2Tag, TrustedImm32(op3));
msaboff@apple.com4b6250f2013-10-15 18:33:04 +0000521 return appendCallWithExceptionCheck(operation);
522}
523
fpizlo@apple.comd49bfe82013-10-19 02:20:14 +0000524ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, RegisterID regOp1Tag, RegisterID regOp1Payload, RegisterID regOp2Tag, RegisterID regOp2Payload, StringImpl* uid)
fpizlo@apple.comd97d7572013-10-14 18:39:45 +0000525{
fpizlo@apple.comd49bfe82013-10-19 02:20:14 +0000526 setupArgumentsWithExecState(TrustedImmPtr(stubInfo), regOp1Payload, regOp1Tag, regOp2Payload, regOp2Tag, TrustedImmPtr(uid));
fpizlo@apple.comd97d7572013-10-14 18:39:45 +0000527 return appendCallWithExceptionCheck(operation);
528}
529
commit-queue@webkit.orgda99c7f2013-10-22 17:04:59 +0000530ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJJJ operation, RegisterID regOp1Tag, RegisterID regOp1Payload, RegisterID regOp2Tag, RegisterID regOp2Payload, RegisterID regOp3Tag, RegisterID regOp3Payload)
msaboff@apple.com853b04f2013-10-17 01:23:56 +0000531{
532 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG regOp1Payload, regOp1Tag, SH4_32BIT_DUMMY_ARG regOp2Payload, regOp2Tag, regOp3Payload, regOp3Tag);
533 return appendCallWithExceptionCheck(operation);
534}
535
msaboff@apple.com4b6250f2013-10-15 18:33:04 +0000536ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJZ operation, RegisterID regOp1Tag, RegisterID regOp1Payload, int32_t op2)
537{
538 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG regOp1Payload, regOp1Tag, TrustedImm32(op2));
539 return appendCallWithExceptionCheck(operation);
540}
541
542ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJZJ operation, RegisterID regOp1Tag, RegisterID regOp1Payload, int32_t op2, RegisterID regOp3Tag, RegisterID regOp3Payload)
543{
commit-queue@webkit.orge890e762013-11-25 15:28:45 +0000544 setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG regOp1Payload, regOp1Tag, TrustedImm32(op2), EABI_32BIT_DUMMY_ARG regOp3Payload, regOp3Tag);
msaboff@apple.com4b6250f2013-10-15 18:33:04 +0000545 return appendCallWithExceptionCheck(operation);
546}
commit-queue@webkit.org54f3f2c2013-10-18 17:03:48 +0000547
msaboff@apple.comc8dd3f72013-10-10 23:10:40 +0000548#undef EABI_32BIT_DUMMY_ARG
549#undef SH4_32BIT_DUMMY_ARG
550
551#endif // USE(JSVALUE32_64)
552
barraclough@apple.coma2a2e132008-12-13 23:58:58 +0000553ALWAYS_INLINE JIT::Jump JIT::checkStructure(RegisterID reg, Structure* structure)
barraclough@apple.come367b002008-12-04 05:43:14 +0000554{
oliver@apple.combe4e0672011-03-28 17:14:57 +0000555 return branchPtr(NotEqual, Address(reg, JSCell::structureOffset()), TrustedImmPtr(structure));
barraclough@apple.come367b002008-12-04 05:43:14 +0000556}
557
barraclough@apple.com4f46a502008-12-13 01:39:38 +0000558ALWAYS_INLINE void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator& iter, int vReg)
barraclough@apple.come367b002008-12-04 05:43:14 +0000559{
barraclough@apple.com4f46a502008-12-13 01:39:38 +0000560 if (!m_codeBlock->isKnownNotImmediate(vReg))
561 linkSlowCase(iter);
barraclough@apple.come367b002008-12-04 05:43:14 +0000562}
563
barraclough@apple.coma2a2e132008-12-13 23:58:58 +0000564ALWAYS_INLINE void JIT::addSlowCase(Jump jump)
barraclough@apple.com249befb2008-12-13 03:18:10 +0000565{
ggaren@apple.com1ba49812010-05-19 18:28:54 +0000566 ASSERT(m_bytecodeOffset != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
barraclough@apple.com249befb2008-12-13 03:18:10 +0000567
ggaren@apple.com1ba49812010-05-19 18:28:54 +0000568 m_slowCases.append(SlowCaseEntry(jump, m_bytecodeOffset));
barraclough@apple.com249befb2008-12-13 03:18:10 +0000569}
570
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000571ALWAYS_INLINE void JIT::addSlowCase(JumpList jumpList)
572{
ggaren@apple.com1ba49812010-05-19 18:28:54 +0000573 ASSERT(m_bytecodeOffset != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000574
575 const JumpList::JumpVector& jumpVector = jumpList.jumps();
576 size_t size = jumpVector.size();
577 for (size_t i = 0; i < size; ++i)
ggaren@apple.com1ba49812010-05-19 18:28:54 +0000578 m_slowCases.append(SlowCaseEntry(jumpVector[i], m_bytecodeOffset));
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000579}
580
fpizlo@apple.com9b0b31e2011-09-19 22:27:38 +0000581ALWAYS_INLINE void JIT::addSlowCase()
582{
583 ASSERT(m_bytecodeOffset != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
584
585 Jump emptyJump; // Doing it this way to make Windows happy.
586 m_slowCases.append(SlowCaseEntry(emptyJump, m_bytecodeOffset));
587}
588
barraclough@apple.coma2a2e132008-12-13 23:58:58 +0000589ALWAYS_INLINE void JIT::addJump(Jump jump, int relativeOffset)
barraclough@apple.com249befb2008-12-13 03:18:10 +0000590{
ggaren@apple.com1ba49812010-05-19 18:28:54 +0000591 ASSERT(m_bytecodeOffset != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
barraclough@apple.com249befb2008-12-13 03:18:10 +0000592
ggaren@apple.com1ba49812010-05-19 18:28:54 +0000593 m_jmpTable.append(JumpTable(jump, m_bytecodeOffset + relativeOffset));
barraclough@apple.com249befb2008-12-13 03:18:10 +0000594}
595
barraclough@apple.coma2a2e132008-12-13 23:58:58 +0000596ALWAYS_INLINE void JIT::emitJumpSlowToHot(Jump jump, int relativeOffset)
barraclough@apple.com249befb2008-12-13 03:18:10 +0000597{
ggaren@apple.com1ba49812010-05-19 18:28:54 +0000598 ASSERT(m_bytecodeOffset != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
barraclough@apple.com249befb2008-12-13 03:18:10 +0000599
ggaren@apple.com1ba49812010-05-19 18:28:54 +0000600 jump.linkTo(m_labels[m_bytecodeOffset + relativeOffset], this);
barraclough@apple.com249befb2008-12-13 03:18:10 +0000601}
602
barraclough@apple.comb8bcc942011-09-07 17:55:50 +0000603ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotObject(RegisterID structureReg)
604{
weinig@apple.com58576b22011-09-16 21:34:20 +0000605 return branch8(Below, Address(structureReg, Structure::typeInfoTypeOffset()), TrustedImm32(ObjectType));
barraclough@apple.comb8bcc942011-09-07 17:55:50 +0000606}
607
barraclough@apple.com536c0db2009-05-12 06:21:56 +0000608#if ENABLE(SAMPLING_FLAGS)
barraclough@apple.comc32f32e2009-05-13 09:10:02 +0000609ALWAYS_INLINE void JIT::setSamplingFlag(int32_t flag)
barraclough@apple.com536c0db2009-05-12 06:21:56 +0000610{
611 ASSERT(flag >= 1);
612 ASSERT(flag <= 32);
barraclough@apple.com02dee5d2011-04-21 01:03:44 +0000613 or32(TrustedImm32(1u << (flag - 1)), AbsoluteAddress(SamplingFlags::addressOfFlags()));
barraclough@apple.com536c0db2009-05-12 06:21:56 +0000614}
615
barraclough@apple.comc32f32e2009-05-13 09:10:02 +0000616ALWAYS_INLINE void JIT::clearSamplingFlag(int32_t flag)
barraclough@apple.com536c0db2009-05-12 06:21:56 +0000617{
618 ASSERT(flag >= 1);
619 ASSERT(flag <= 32);
barraclough@apple.com02dee5d2011-04-21 01:03:44 +0000620 and32(TrustedImm32(~(1u << (flag - 1))), AbsoluteAddress(SamplingFlags::addressOfFlags()));
barraclough@apple.comc32f32e2009-05-13 09:10:02 +0000621}
622#endif
623
624#if ENABLE(SAMPLING_COUNTERS)
barraclough@apple.com6d410b02011-11-10 20:24:06 +0000625ALWAYS_INLINE void JIT::emitCount(AbstractSamplingCounter& counter, int32_t count)
barraclough@apple.comc32f32e2009-05-13 09:10:02 +0000626{
barraclough@apple.com6d410b02011-11-10 20:24:06 +0000627 add64(TrustedImm32(count), AbsoluteAddress(counter.addressOfCounter()));
barraclough@apple.com536c0db2009-05-12 06:21:56 +0000628}
629#endif
630
631#if ENABLE(OPCODE_SAMPLING)
mjs@apple.comcc668212010-01-04 11:38:56 +0000632#if CPU(X86_64)
barraclough@apple.com536c0db2009-05-12 06:21:56 +0000633ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostFunction)
634{
oliver@apple.combe4e0672011-03-28 17:14:57 +0000635 move(TrustedImmPtr(m_interpreter->sampler()->sampleSlot()), X86Registers::ecx);
636 storePtr(TrustedImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), X86Registers::ecx);
barraclough@apple.com536c0db2009-05-12 06:21:56 +0000637}
638#else
639ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostFunction)
640{
oliver@apple.combe4e0672011-03-28 17:14:57 +0000641 storePtr(TrustedImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), m_interpreter->sampler()->sampleSlot());
barraclough@apple.com536c0db2009-05-12 06:21:56 +0000642}
643#endif
644#endif
645
646#if ENABLE(CODEBLOCK_SAMPLING)
mjs@apple.comcc668212010-01-04 11:38:56 +0000647#if CPU(X86_64)
barraclough@apple.com536c0db2009-05-12 06:21:56 +0000648ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock)
649{
oliver@apple.combe4e0672011-03-28 17:14:57 +0000650 move(TrustedImmPtr(m_interpreter->sampler()->codeBlockSlot()), X86Registers::ecx);
651 storePtr(TrustedImmPtr(codeBlock), X86Registers::ecx);
barraclough@apple.com536c0db2009-05-12 06:21:56 +0000652}
653#else
654ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock)
655{
oliver@apple.combe4e0672011-03-28 17:14:57 +0000656 storePtr(TrustedImmPtr(codeBlock), m_interpreter->sampler()->codeBlockSlot());
barraclough@apple.com536c0db2009-05-12 06:21:56 +0000657}
658#endif
659#endif
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000660
msaboff@apple.com7535bbd2013-09-10 06:01:03 +0000661ALWAYS_INLINE bool JIT::isOperandConstantImmediateChar(int src)
oliver@apple.com5230bd32010-05-06 19:39:54 +0000662{
663 return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isString() && asString(getConstantOperand(src).asCell())->length() == 1;
664}
665
ggaren@apple.comc862eac2013-01-29 05:48:01 +0000666template<typename StructureType>
667inline void JIT::emitAllocateJSObject(RegisterID allocator, StructureType structure, RegisterID result, RegisterID scratch)
commit-queue@webkit.orgc9b19ab2011-07-18 18:55:48 +0000668{
ggaren@apple.comc862eac2013-01-29 05:48:01 +0000669 loadPtr(Address(allocator, MarkedAllocator::offsetOfFreeListHead()), result);
commit-queue@webkit.orgc9b19ab2011-07-18 18:55:48 +0000670 addSlowCase(branchTestPtr(Zero, result));
oliver@apple.come843bc02011-08-05 20:03:19 +0000671
commit-queue@webkit.orgc9b19ab2011-07-18 18:55:48 +0000672 // remove the object from the free list
ggaren@apple.comc862eac2013-01-29 05:48:01 +0000673 loadPtr(Address(result), scratch);
674 storePtr(scratch, Address(allocator, MarkedAllocator::offsetOfFreeListHead()));
oliver@apple.come843bc02011-08-05 20:03:19 +0000675
commit-queue@webkit.orgc9b19ab2011-07-18 18:55:48 +0000676 // initialize the object's structure
677 storePtr(structure, Address(result, JSCell::structureOffset()));
oliver@apple.come843bc02011-08-05 20:03:19 +0000678
commit-queue@webkit.orgc9b19ab2011-07-18 18:55:48 +0000679 // initialize the object's property storage pointer
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +0000680 storePtr(TrustedImmPtr(0), Address(result, JSObject::butterflyOffset()));
oliver@apple.come843bc02011-08-05 20:03:19 +0000681}
682
fpizlo@apple.comba833642014-01-06 20:41:32 +0000683inline void JIT::emitValueProfilingSite(ValueProfile* valueProfile)
fpizlo@apple.com95a9f0d2011-08-20 02:17:49 +0000684{
fpizlo@apple.com086d2af2011-12-21 02:29:15 +0000685 ASSERT(shouldEmitProfiling());
686 ASSERT(valueProfile);
687
fpizlo@apple.com95a9f0d2011-08-20 02:17:49 +0000688 const RegisterID value = regT0;
fpizlo@apple.com4043e812011-11-06 11:54:59 +0000689#if USE(JSVALUE32_64)
690 const RegisterID valueTag = regT1;
691#endif
fpizlo@apple.com95a9f0d2011-08-20 02:17:49 +0000692
fpizlo@apple.comba833642014-01-06 20:41:32 +0000693 // We're in a simple configuration: only one bucket, so we can just do a direct
694 // store.
fpizlo@apple.com4043e812011-11-06 11:54:59 +0000695#if USE(JSVALUE64)
fpizlo@apple.comba833642014-01-06 20:41:32 +0000696 store64(value, valueProfile->m_buckets);
fpizlo@apple.com4043e812011-11-06 11:54:59 +0000697#else
fpizlo@apple.comba833642014-01-06 20:41:32 +0000698 EncodedValueDescriptor* descriptor = bitwise_cast<EncodedValueDescriptor*>(valueProfile->m_buckets);
699 store32(value, &descriptor->asBits.payload);
700 store32(valueTag, &descriptor->asBits.tag);
commit-queue@webkit.org387d2ec2011-10-09 10:19:23 +0000701#endif
fpizlo@apple.com95a9f0d2011-08-20 02:17:49 +0000702}
fpizlo@apple.com086d2af2011-12-21 02:29:15 +0000703
fpizlo@apple.comba833642014-01-06 20:41:32 +0000704inline void JIT::emitValueProfilingSite(unsigned bytecodeOffset)
fpizlo@apple.com086d2af2011-12-21 02:29:15 +0000705{
706 if (!shouldEmitProfiling())
707 return;
fpizlo@apple.comba833642014-01-06 20:41:32 +0000708 emitValueProfilingSite(m_codeBlock->valueProfileForBytecodeOffset(bytecodeOffset));
fpizlo@apple.comafcf9042012-01-20 20:22:18 +0000709}
710
fpizlo@apple.comba833642014-01-06 20:41:32 +0000711inline void JIT::emitValueProfilingSite()
fpizlo@apple.comafcf9042012-01-20 20:22:18 +0000712{
fpizlo@apple.comba833642014-01-06 20:41:32 +0000713 emitValueProfilingSite(m_bytecodeOffset);
fpizlo@apple.com086d2af2011-12-21 02:29:15 +0000714}
fpizlo@apple.comc7be5be02012-09-17 19:07:32 +0000715
716inline void JIT::emitArrayProfilingSite(RegisterID structureAndIndexingType, RegisterID scratch, ArrayProfile* arrayProfile)
717{
fpizlo@apple.com44e9ef42012-10-19 07:24:32 +0000718 UNUSED_PARAM(scratch); // We had found this scratch register useful here before, so I will keep it for now.
719
fpizlo@apple.comc7be5be02012-09-17 19:07:32 +0000720 RegisterID structure = structureAndIndexingType;
721 RegisterID indexingType = structureAndIndexingType;
722
fpizlo@apple.com4d95ce62013-02-27 03:52:58 +0000723 if (shouldEmitProfiling())
fpizlo@apple.comc7be5be02012-09-17 19:07:32 +0000724 storePtr(structure, arrayProfile->addressOfLastSeenStructure());
fpizlo@apple.com44e9ef42012-10-19 07:24:32 +0000725
726 load8(Address(structure, Structure::indexingTypeOffset()), indexingType);
fpizlo@apple.comc7be5be02012-09-17 19:07:32 +0000727}
728
729inline void JIT::emitArrayProfilingSiteForBytecodeIndex(RegisterID structureAndIndexingType, RegisterID scratch, unsigned bytecodeIndex)
730{
fpizlo@apple.comc7be5be02012-09-17 19:07:32 +0000731 emitArrayProfilingSite(structureAndIndexingType, scratch, m_codeBlock->getOrAddArrayProfile(bytecodeIndex));
fpizlo@apple.comc7be5be02012-09-17 19:07:32 +0000732}
fpizlo@apple.com95a9f0d2011-08-20 02:17:49 +0000733
fpizlo@apple.com69e27842012-09-19 21:43:10 +0000734inline void JIT::emitArrayProfileStoreToHoleSpecialCase(ArrayProfile* arrayProfile)
735{
fpizlo@apple.com69e27842012-09-19 21:43:10 +0000736 store8(TrustedImm32(1), arrayProfile->addressOfMayStoreToHole());
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000737}
738
fpizlo@apple.com304fbca2012-12-17 21:38:51 +0000739inline void JIT::emitArrayProfileOutOfBoundsSpecialCase(ArrayProfile* arrayProfile)
740{
fpizlo@apple.com304fbca2012-12-17 21:38:51 +0000741 store8(TrustedImm32(1), arrayProfile->addressOfOutOfBounds());
fpizlo@apple.com304fbca2012-12-17 21:38:51 +0000742}
743
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000744static inline bool arrayProfileSaw(ArrayModes arrayModes, IndexingType capability)
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000745{
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000746 return arrayModesInclude(arrayModes, capability);
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000747}
748
749inline JITArrayMode JIT::chooseArrayMode(ArrayProfile* profile)
750{
oliver@apple.comd2056662013-07-25 04:00:37 +0000751 ConcurrentJITLocker locker(m_codeBlock->m_lock);
oliver@apple.comc14eb7d2013-07-25 03:58:47 +0000752 profile->computeUpdatedPrediction(locker, m_codeBlock);
753 ArrayModes arrayModes = profile->observedArrayModes(locker);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000754 if (arrayProfileSaw(arrayModes, DoubleShape))
755 return JITDouble;
756 if (arrayProfileSaw(arrayModes, Int32Shape))
757 return JITInt32;
758 if (arrayProfileSaw(arrayModes, ArrayStorageShape))
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000759 return JITArrayStorage;
760 return JITContiguous;
fpizlo@apple.com69e27842012-09-19 21:43:10 +0000761}
762
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000763#if USE(JSVALUE32_64)
764
ggaren@apple.come1e45912011-11-14 19:44:32 +0000765inline void JIT::emitLoadTag(int index, RegisterID tag)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000766{
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000767 if (m_codeBlock->isConstantRegisterIndex(index)) {
768 move(Imm32(getConstantOperand(index).tag()), tag);
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000769 return;
770 }
771
772 load32(tagFor(index), tag);
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000773}
774
ggaren@apple.come1e45912011-11-14 19:44:32 +0000775inline void JIT::emitLoadPayload(int index, RegisterID payload)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000776{
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000777 if (m_codeBlock->isConstantRegisterIndex(index)) {
778 move(Imm32(getConstantOperand(index).payload()), payload);
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000779 return;
780 }
781
782 load32(payloadFor(index), payload);
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000783}
784
785inline void JIT::emitLoad(const JSValue& v, RegisterID tag, RegisterID payload)
786{
787 move(Imm32(v.payload()), payload);
788 move(Imm32(v.tag()), tag);
789}
790
ggaren@apple.come1e45912011-11-14 19:44:32 +0000791inline void JIT::emitLoad(int index, RegisterID tag, RegisterID payload, RegisterID base)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000792{
oliver@apple.com903b0c02013-01-24 01:40:37 +0000793 RELEASE_ASSERT(tag != payload);
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000794
795 if (base == callFrameRegister) {
oliver@apple.com903b0c02013-01-24 01:40:37 +0000796 RELEASE_ASSERT(payload != base);
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000797 emitLoadPayload(index, payload);
798 emitLoadTag(index, tag);
799 return;
800 }
801
802 if (payload == base) { // avoid stomping base
803 load32(tagFor(index, base), tag);
804 load32(payloadFor(index, base), payload);
805 return;
806 }
807
808 load32(payloadFor(index, base), payload);
809 load32(tagFor(index, base), tag);
810}
811
ggaren@apple.come1e45912011-11-14 19:44:32 +0000812inline void JIT::emitLoad2(int index1, RegisterID tag1, RegisterID payload1, int index2, RegisterID tag2, RegisterID payload2)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000813{
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000814 emitLoad(index2, tag2, payload2);
815 emitLoad(index1, tag1, payload1);
816}
817
ggaren@apple.come1e45912011-11-14 19:44:32 +0000818inline void JIT::emitLoadDouble(int index, FPRegisterID value)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000819{
820 if (m_codeBlock->isConstantRegisterIndex(index)) {
oliver@apple.comba10bec2011-03-08 23:17:32 +0000821 WriteBarrier<Unknown>& inConstantPool = m_codeBlock->constantRegister(index);
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000822 loadDouble(&inConstantPool, value);
823 } else
824 loadDouble(addressFor(index), value);
825}
826
ggaren@apple.come1e45912011-11-14 19:44:32 +0000827inline void JIT::emitLoadInt32ToDouble(int index, FPRegisterID value)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000828{
829 if (m_codeBlock->isConstantRegisterIndex(index)) {
oliver@apple.comba10bec2011-03-08 23:17:32 +0000830 WriteBarrier<Unknown>& inConstantPool = m_codeBlock->constantRegister(index);
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000831 char* bytePointer = reinterpret_cast<char*>(&inConstantPool);
832 convertInt32ToDouble(AbsoluteAddress(bytePointer + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), value);
833 } else
834 convertInt32ToDouble(payloadFor(index), value);
835}
836
ggaren@apple.come1e45912011-11-14 19:44:32 +0000837inline void JIT::emitStore(int index, RegisterID tag, RegisterID payload, RegisterID base)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000838{
839 store32(payload, payloadFor(index, base));
840 store32(tag, tagFor(index, base));
841}
842
ggaren@apple.come1e45912011-11-14 19:44:32 +0000843inline void JIT::emitStoreInt32(int index, RegisterID payload, bool indexIsInt32)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000844{
845 store32(payload, payloadFor(index, callFrameRegister));
846 if (!indexIsInt32)
oliver@apple.combe4e0672011-03-28 17:14:57 +0000847 store32(TrustedImm32(JSValue::Int32Tag), tagFor(index, callFrameRegister));
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000848}
849
ggaren@apple.come1e45912011-11-14 19:44:32 +0000850inline void JIT::emitStoreInt32(int index, TrustedImm32 payload, bool indexIsInt32)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000851{
852 store32(payload, payloadFor(index, callFrameRegister));
853 if (!indexIsInt32)
oliver@apple.combe4e0672011-03-28 17:14:57 +0000854 store32(TrustedImm32(JSValue::Int32Tag), tagFor(index, callFrameRegister));
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000855}
856
ggaren@apple.come1e45912011-11-14 19:44:32 +0000857inline void JIT::emitStoreCell(int index, RegisterID payload, bool indexIsCell)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000858{
859 store32(payload, payloadFor(index, callFrameRegister));
860 if (!indexIsCell)
oliver@apple.combe4e0672011-03-28 17:14:57 +0000861 store32(TrustedImm32(JSValue::CellTag), tagFor(index, callFrameRegister));
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000862}
863
ggaren@apple.come1e45912011-11-14 19:44:32 +0000864inline void JIT::emitStoreBool(int index, RegisterID payload, bool indexIsBool)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000865{
barraclough@apple.com5139edc2011-04-07 23:47:06 +0000866 store32(payload, payloadFor(index, callFrameRegister));
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000867 if (!indexIsBool)
barraclough@apple.com5139edc2011-04-07 23:47:06 +0000868 store32(TrustedImm32(JSValue::BooleanTag), tagFor(index, callFrameRegister));
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000869}
870
ggaren@apple.come1e45912011-11-14 19:44:32 +0000871inline void JIT::emitStoreDouble(int index, FPRegisterID value)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000872{
873 storeDouble(value, addressFor(index));
874}
875
ggaren@apple.come1e45912011-11-14 19:44:32 +0000876inline void JIT::emitStore(int index, const JSValue constant, RegisterID base)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000877{
878 store32(Imm32(constant.payload()), payloadFor(index, base));
879 store32(Imm32(constant.tag()), tagFor(index, base));
880}
881
msaboff@apple.com7535bbd2013-09-10 06:01:03 +0000882ALWAYS_INLINE void JIT::emitInitRegister(int dst)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000883{
884 emitStore(dst, jsUndefined());
885}
886
ggaren@apple.come1e45912011-11-14 19:44:32 +0000887inline void JIT::emitJumpSlowCaseIfNotJSCell(int virtualRegisterIndex)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000888{
oliver@apple.comfc502ee2010-05-20 00:30:35 +0000889 if (!m_codeBlock->isKnownNotImmediate(virtualRegisterIndex)) {
890 if (m_codeBlock->isConstantRegisterIndex(virtualRegisterIndex))
891 addSlowCase(jump());
892 else
893 addSlowCase(emitJumpIfNotJSCell(virtualRegisterIndex));
894 }
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000895}
896
ggaren@apple.come1e45912011-11-14 19:44:32 +0000897inline void JIT::emitJumpSlowCaseIfNotJSCell(int virtualRegisterIndex, RegisterID tag)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000898{
oliver@apple.comfc502ee2010-05-20 00:30:35 +0000899 if (!m_codeBlock->isKnownNotImmediate(virtualRegisterIndex)) {
900 if (m_codeBlock->isConstantRegisterIndex(virtualRegisterIndex))
901 addSlowCase(jump());
902 else
oliver@apple.combe4e0672011-03-28 17:14:57 +0000903 addSlowCase(branch32(NotEqual, tag, TrustedImm32(JSValue::CellTag)));
oliver@apple.comfc502ee2010-05-20 00:30:35 +0000904 }
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000905}
906
msaboff@apple.com7535bbd2013-09-10 06:01:03 +0000907ALWAYS_INLINE bool JIT::isOperandConstantImmediateInt(int src)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000908{
909 return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isInt32();
910}
911
msaboff@apple.com7535bbd2013-09-10 06:01:03 +0000912ALWAYS_INLINE bool JIT::getOperandConstantImmediateInt(int op1, int op2, int& op, int32_t& constant)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000913{
914 if (isOperandConstantImmediateInt(op1)) {
915 constant = getConstantOperand(op1).asInt32();
916 op = op2;
917 return true;
918 }
919
920 if (isOperandConstantImmediateInt(op2)) {
921 constant = getConstantOperand(op2).asInt32();
922 op = op1;
923 return true;
924 }
925
926 return false;
927}
928
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000929#else // USE(JSVALUE32_64)
930
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000931// get arg puts an arg from the SF register array into a h/w register
932ALWAYS_INLINE void JIT::emitGetVirtualRegister(int src, RegisterID dst)
933{
ggaren@apple.com1ba49812010-05-19 18:28:54 +0000934 ASSERT(m_bytecodeOffset != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeOffset is set.
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000935
936 // TODO: we want to reuse values that are already in registers if we can - add a register allocator!
937 if (m_codeBlock->isConstantRegisterIndex(src)) {
938 JSValue value = m_codeBlock->getConstant(src);
oliver@apple.comb2a14ec2012-03-08 01:07:34 +0000939 if (!value.isNumber())
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +0000940 move(TrustedImm64(JSValue::encode(value)), dst);
oliver@apple.comb2a14ec2012-03-08 01:07:34 +0000941 else
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +0000942 move(Imm64(JSValue::encode(value)), dst);
barraclough@apple.com4836c7a2011-05-01 22:20:59 +0000943 return;
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000944 }
945
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +0000946 load64(Address(callFrameRegister, src * sizeof(Register)), dst);
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000947}
948
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000949ALWAYS_INLINE void JIT::emitGetVirtualRegister(VirtualRegister src, RegisterID dst)
950{
951 emitGetVirtualRegister(src.offset(), dst);
952}
953
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000954ALWAYS_INLINE void JIT::emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2)
955{
fpizlo@apple.com9a5ab802013-11-12 03:28:41 +0000956 emitGetVirtualRegister(src1, dst1);
957 emitGetVirtualRegister(src2, dst2);
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000958}
959
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000960ALWAYS_INLINE void JIT::emitGetVirtualRegisters(VirtualRegister src1, RegisterID dst1, VirtualRegister src2, RegisterID dst2)
961{
962 emitGetVirtualRegisters(src1.offset(), dst1, src2.offset(), dst2);
963}
964
msaboff@apple.com7535bbd2013-09-10 06:01:03 +0000965ALWAYS_INLINE int32_t JIT::getConstantOperandImmediateInt(int src)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000966{
967 return getConstantOperand(src).asInt32();
968}
969
msaboff@apple.com7535bbd2013-09-10 06:01:03 +0000970ALWAYS_INLINE bool JIT::isOperandConstantImmediateInt(int src)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000971{
972 return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isInt32();
973}
974
msaboff@apple.com7535bbd2013-09-10 06:01:03 +0000975ALWAYS_INLINE void JIT::emitPutVirtualRegister(int dst, RegisterID from)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000976{
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +0000977 store64(from, Address(callFrameRegister, dst * sizeof(Register)));
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000978}
979
msaboff@apple.com62aa8b72013-09-26 22:53:54 +0000980ALWAYS_INLINE void JIT::emitPutVirtualRegister(VirtualRegister dst, RegisterID from)
981{
982 emitPutVirtualRegister(dst.offset(), from);
983}
984
msaboff@apple.com7535bbd2013-09-10 06:01:03 +0000985ALWAYS_INLINE void JIT::emitInitRegister(int dst)
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000986{
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +0000987 store64(TrustedImm64(JSValue::encode(jsUndefined())), Address(callFrameRegister, dst * sizeof(Register)));
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000988}
989
990ALWAYS_INLINE JIT::Jump JIT::emitJumpIfJSCell(RegisterID reg)
991{
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +0000992 return branchTest64(Zero, reg, tagMaskRegister);
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000993}
994
995ALWAYS_INLINE JIT::Jump JIT::emitJumpIfBothJSCells(RegisterID reg1, RegisterID reg2, RegisterID scratch)
996{
997 move(reg1, scratch);
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +0000998 or64(reg2, scratch);
ggaren@apple.com540d71a62009-07-30 20:57:44 +0000999 return emitJumpIfJSCell(scratch);
1000}
1001
1002ALWAYS_INLINE void JIT::emitJumpSlowCaseIfJSCell(RegisterID reg)
1003{
1004 addSlowCase(emitJumpIfJSCell(reg));
1005}
1006
ggaren@apple.com540d71a62009-07-30 20:57:44 +00001007ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotJSCell(RegisterID reg)
1008{
1009 addSlowCase(emitJumpIfNotJSCell(reg));
1010}
1011
1012ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotJSCell(RegisterID reg, int vReg)
1013{
1014 if (!m_codeBlock->isKnownNotImmediate(vReg))
1015 emitJumpSlowCaseIfNotJSCell(reg);
1016}
1017
ggaren@apple.come1e45912011-11-14 19:44:32 +00001018inline void JIT::emitLoadDouble(int index, FPRegisterID value)
oliver@apple.com8d181632009-09-25 02:40:59 +00001019{
1020 if (m_codeBlock->isConstantRegisterIndex(index)) {
oliver@apple.comba10bec2011-03-08 23:17:32 +00001021 WriteBarrier<Unknown>& inConstantPool = m_codeBlock->constantRegister(index);
oliver@apple.com8d181632009-09-25 02:40:59 +00001022 loadDouble(&inConstantPool, value);
1023 } else
1024 loadDouble(addressFor(index), value);
1025}
1026
ggaren@apple.come1e45912011-11-14 19:44:32 +00001027inline void JIT::emitLoadInt32ToDouble(int index, FPRegisterID value)
oliver@apple.com8d181632009-09-25 02:40:59 +00001028{
1029 if (m_codeBlock->isConstantRegisterIndex(index)) {
barraclough@apple.com8af7a532011-03-13 22:11:13 +00001030 ASSERT(isOperandConstantImmediateInt(index));
1031 convertInt32ToDouble(Imm32(getConstantOperand(index).asInt32()), value);
oliver@apple.com8d181632009-09-25 02:40:59 +00001032 } else
1033 convertInt32ToDouble(addressFor(index), value);
1034}
ggaren@apple.com540d71a62009-07-30 20:57:44 +00001035
1036ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateInteger(RegisterID reg)
1037{
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +00001038 return branch64(AboveOrEqual, reg, tagTypeNumberRegister);
ggaren@apple.com540d71a62009-07-30 20:57:44 +00001039}
1040
1041ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateInteger(RegisterID reg)
1042{
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +00001043 return branch64(Below, reg, tagTypeNumberRegister);
ggaren@apple.com540d71a62009-07-30 20:57:44 +00001044}
1045
1046ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateIntegers(RegisterID reg1, RegisterID reg2, RegisterID scratch)
1047{
1048 move(reg1, scratch);
yuqiang.xian@intel.com5b1cb732012-10-19 05:46:10 +00001049 and64(reg2, scratch);
ggaren@apple.com540d71a62009-07-30 20:57:44 +00001050 return emitJumpIfNotImmediateInteger(scratch);
1051}
1052
1053ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateInteger(RegisterID reg)
1054{
1055 addSlowCase(emitJumpIfNotImmediateInteger(reg));
1056}
1057
1058ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateIntegers(RegisterID reg1, RegisterID reg2, RegisterID scratch)
1059{
1060 addSlowCase(emitJumpIfNotImmediateIntegers(reg1, reg2, scratch));
1061}
1062
oliver@apple.com8d181632009-09-25 02:40:59 +00001063ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateNumber(RegisterID reg)
1064{
1065 addSlowCase(emitJumpIfNotImmediateNumber(reg));
1066}
1067
ggaren@apple.com540d71a62009-07-30 20:57:44 +00001068ALWAYS_INLINE void JIT::emitFastArithReTagImmediate(RegisterID src, RegisterID dest)
1069{
ggaren@apple.com540d71a62009-07-30 20:57:44 +00001070 emitFastArithIntToImmNoCheck(src, dest);
ggaren@apple.com540d71a62009-07-30 20:57:44 +00001071}
1072
ggaren@apple.com540d71a62009-07-30 20:57:44 +00001073ALWAYS_INLINE void JIT::emitTagAsBoolImmediate(RegisterID reg)
1074{
barraclough@apple.com560dde72011-04-11 22:18:30 +00001075 or32(TrustedImm32(static_cast<int32_t>(ValueFalse)), reg);
ggaren@apple.com540d71a62009-07-30 20:57:44 +00001076}
1077
ggaren@apple.com540d71a62009-07-30 20:57:44 +00001078#endif // USE(JSVALUE32_64)
1079
1080} // namespace JSC
1081
barraclough@apple.come367b002008-12-04 05:43:14 +00001082#endif // ENABLE(JIT)
1083
mark.lam@apple.coma4fe7ab2012-11-09 03:03:44 +00001084#endif // JITInlines_h
1085