]> git.saurik.com Git - apple/javascriptcore.git/blob - jit/JSInterfaceJIT.h
JavaScriptCore-1218.34.tar.gz
[apple/javascriptcore.git] / jit / JSInterfaceJIT.h
1 /*
2 * Copyright (C) 2010 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. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #ifndef JSInterfaceJIT_h
27 #define JSInterfaceJIT_h
28
29 #include "BytecodeConventions.h"
30 #include "JITCode.h"
31 #include "JITStubs.h"
32 #include "JSCJSValue.h"
33 #include "JSStack.h"
34 #include "JSString.h"
35 #include "MacroAssembler.h"
36 #include <wtf/Vector.h>
37
38 #if ENABLE(JIT)
39
40 namespace JSC {
41 class JSInterfaceJIT : public MacroAssembler {
42 public:
43 // NOTES:
44 //
45 // regT0 has two special meanings. The return value from a stub
46 // call will always be in regT0, and by default (unless
47 // a register is specified) emitPutVirtualRegister() will store
48 // the value from regT0.
49 //
50 // regT3 is required to be callee-preserved.
51 //
52 // tempRegister2 is has no such dependencies. It is important that
53 // on x86/x86-64 it is ecx for performance reasons, since the
54 // MacroAssembler will need to plant register swaps if it is not -
55 // however the code will still function correctly.
56 #if CPU(X86_64)
57 static const RegisterID returnValueRegister = X86Registers::eax;
58 static const RegisterID cachedResultRegister = X86Registers::eax;
59 #if !OS(WINDOWS)
60 static const RegisterID firstArgumentRegister = X86Registers::edi;
61 #else
62 static const RegisterID firstArgumentRegister = X86Registers::ecx;
63 #endif
64
65 #if ENABLE(VALUE_PROFILER)
66 static const RegisterID bucketCounterRegister = X86Registers::r10;
67 #endif
68
69 static const RegisterID callFrameRegister = X86Registers::r13;
70 static const RegisterID tagTypeNumberRegister = X86Registers::r14;
71 static const RegisterID tagMaskRegister = X86Registers::r15;
72
73 static const RegisterID regT0 = X86Registers::eax;
74 static const RegisterID regT1 = X86Registers::edx;
75 static const RegisterID regT2 = X86Registers::ecx;
76 static const RegisterID regT3 = X86Registers::ebx;
77
78 static const FPRegisterID fpRegT0 = X86Registers::xmm0;
79 static const FPRegisterID fpRegT1 = X86Registers::xmm1;
80 static const FPRegisterID fpRegT2 = X86Registers::xmm2;
81 static const FPRegisterID fpRegT3 = X86Registers::xmm3;
82
83 static const RegisterID nonArgGPR1 = X86Registers::eax; // regT0
84 #elif CPU(X86)
85 static const RegisterID returnValueRegister = X86Registers::eax;
86 static const RegisterID cachedResultRegister = X86Registers::eax;
87 // On x86 we always use fastcall conventions = but on
88 // OS X if might make more sense to just use regparm.
89 static const RegisterID firstArgumentRegister = X86Registers::ecx;
90
91 static const RegisterID bucketCounterRegister = X86Registers::esi;
92 static const RegisterID callFrameRegister = X86Registers::edi;
93
94 static const RegisterID regT0 = X86Registers::eax;
95 static const RegisterID regT1 = X86Registers::edx;
96 static const RegisterID regT2 = X86Registers::ecx;
97 static const RegisterID regT3 = X86Registers::ebx;
98
99 static const FPRegisterID fpRegT0 = X86Registers::xmm0;
100 static const FPRegisterID fpRegT1 = X86Registers::xmm1;
101 static const FPRegisterID fpRegT2 = X86Registers::xmm2;
102 static const FPRegisterID fpRegT3 = X86Registers::xmm3;
103 #elif CPU(ARM)
104 static const RegisterID returnValueRegister = ARMRegisters::r0;
105 static const RegisterID cachedResultRegister = ARMRegisters::r0;
106 static const RegisterID firstArgumentRegister = ARMRegisters::r0;
107
108 #if ENABLE(VALUE_PROFILER)
109 static const RegisterID bucketCounterRegister = ARMRegisters::r7;
110 #endif
111
112 static const RegisterID regT0 = ARMRegisters::r0;
113 static const RegisterID regT1 = ARMRegisters::r1;
114 static const RegisterID regT2 = ARMRegisters::r2;
115 static const RegisterID regT3 = ARMRegisters::r4;
116
117 // Update ctiTrampoline in JITStubs.cpp if these values are changed!
118 static const RegisterID callFrameRegister = ARMRegisters::r5;
119
120 static const FPRegisterID fpRegT0 = ARMRegisters::d0;
121 static const FPRegisterID fpRegT1 = ARMRegisters::d1;
122 static const FPRegisterID fpRegT2 = ARMRegisters::d2;
123 static const FPRegisterID fpRegT3 = ARMRegisters::d3;
124 #elif CPU(ARM64)
125 static const RegisterID returnValueRegister = ARM64Registers::x0;
126 static const RegisterID cachedResultRegister = ARM64Registers::x0;
127 static const RegisterID firstArgumentRegister = ARM64Registers::x0;
128
129 #if ENABLE(VALUE_PROFILER)
130 static const RegisterID bucketCounterRegister = ARM64Registers::x7;
131 #endif
132
133 static const RegisterID regT0 = ARM64Registers::x0;
134 static const RegisterID regT1 = ARM64Registers::x1;
135 static const RegisterID regT2 = ARM64Registers::x2;
136 static const RegisterID regT3 = ARM64Registers::x23;
137
138 static const RegisterID callFrameRegister = ARM64Registers::x25;
139 static const RegisterID timeoutCheckRegister = ARM64Registers::x26;
140 static const RegisterID tagTypeNumberRegister = ARM64Registers::x27;
141 static const RegisterID tagMaskRegister = ARM64Registers::x28;
142
143 static const FPRegisterID fpRegT0 = ARM64Registers::q0;
144 static const FPRegisterID fpRegT1 = ARM64Registers::q1;
145 static const FPRegisterID fpRegT2 = ARM64Registers::q2;
146 static const FPRegisterID fpRegT3 = ARM64Registers::q3;
147
148 static const RegisterID nonArgGPR1 = ARM64Registers::x9;
149 #elif CPU(MIPS)
150 static const RegisterID returnValueRegister = MIPSRegisters::v0;
151 static const RegisterID cachedResultRegister = MIPSRegisters::v0;
152 static const RegisterID firstArgumentRegister = MIPSRegisters::a0;
153
154 #if ENABLE(VALUE_PROFILER)
155 static const RegisterID bucketCounterRegister = MIPSRegisters::s3;
156 #endif
157
158 // regT0 must be v0 for returning a 32-bit value.
159 static const RegisterID regT0 = MIPSRegisters::v0;
160
161 // regT1 must be v1 for returning a pair of 32-bit value.
162 static const RegisterID regT1 = MIPSRegisters::v1;
163
164 static const RegisterID regT2 = MIPSRegisters::t4;
165
166 // regT3 must be saved in the callee, so use an S register.
167 static const RegisterID regT3 = MIPSRegisters::s2;
168
169 static const RegisterID callFrameRegister = MIPSRegisters::s0;
170
171 static const FPRegisterID fpRegT0 = MIPSRegisters::f4;
172 static const FPRegisterID fpRegT1 = MIPSRegisters::f6;
173 static const FPRegisterID fpRegT2 = MIPSRegisters::f8;
174 static const FPRegisterID fpRegT3 = MIPSRegisters::f10;
175 #elif CPU(SH4)
176 static const RegisterID callFrameRegister = SH4Registers::fp;
177
178 static const RegisterID regT0 = SH4Registers::r0;
179 static const RegisterID regT1 = SH4Registers::r1;
180 static const RegisterID regT2 = SH4Registers::r2;
181 static const RegisterID regT3 = SH4Registers::r10;
182 static const RegisterID regT4 = SH4Registers::r4;
183 static const RegisterID regT5 = SH4Registers::r5;
184 static const RegisterID regT6 = SH4Registers::r6;
185 static const RegisterID regT7 = SH4Registers::r7;
186 static const RegisterID firstArgumentRegister =regT4;
187
188 static const RegisterID returnValueRegister = SH4Registers::r0;
189 static const RegisterID cachedResultRegister = SH4Registers::r0;
190
191 static const FPRegisterID fpRegT0 = SH4Registers::fr0;
192 static const FPRegisterID fpRegT1 = SH4Registers::fr2;
193 static const FPRegisterID fpRegT2 = SH4Registers::fr4;
194 static const FPRegisterID fpRegT3 = SH4Registers::fr6;
195 static const FPRegisterID fpRegT4 = SH4Registers::fr8;
196 static const FPRegisterID fpRegT5 = SH4Registers::fr10;
197 static const FPRegisterID fpRegT6 = SH4Registers::fr12;
198 static const FPRegisterID fpRegT7 = SH4Registers::fr14;
199 #else
200 #error "JIT not supported on this platform."
201 #endif
202
203 #if USE(JSVALUE32_64)
204 // Can't just propogate JSValue::Int32Tag as visual studio doesn't like it
205 static const unsigned Int32Tag = 0xffffffff;
206 COMPILE_ASSERT(Int32Tag == JSValue::Int32Tag, Int32Tag_out_of_sync);
207 #else
208 static const unsigned Int32Tag = TagTypeNumber >> 32;
209 #endif
210 inline Jump emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID payload);
211 inline Jump emitLoadInt32(unsigned virtualRegisterIndex, RegisterID dst);
212 inline Jump emitLoadDouble(unsigned virtualRegisterIndex, FPRegisterID dst, RegisterID scratch);
213
214 #if USE(JSVALUE32_64)
215 inline Jump emitJumpIfNotJSCell(unsigned virtualRegisterIndex);
216 inline Address tagFor(int index, RegisterID base = callFrameRegister);
217 #endif
218
219 #if USE(JSVALUE64)
220 Jump emitJumpIfNotJSCell(RegisterID);
221 Jump emitJumpIfImmediateNumber(RegisterID reg);
222 Jump emitJumpIfNotImmediateNumber(RegisterID reg);
223 void emitFastArithImmToInt(RegisterID reg);
224 void emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest);
225 #endif
226
227 Jump emitJumpIfNotType(RegisterID baseReg, RegisterID scratchReg, JSType);
228
229 void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry, RegisterID to, RegisterID from = callFrameRegister);
230 void emitPutToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry);
231 void emitPutImmediateToCallFrameHeader(void* value, JSStack::CallFrameHeaderEntry);
232 void emitPutCellToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry);
233
234 void preserveReturnAddressAfterCall(RegisterID);
235 void restoreReturnAddressBeforeReturn(RegisterID);
236 void restoreReturnAddressBeforeReturn(Address);
237 void restoreArgumentReference();
238
239 inline Address payloadFor(int index, RegisterID base = callFrameRegister);
240 inline Address intPayloadFor(int index, RegisterID base = callFrameRegister);
241 inline Address intTagFor(int index, RegisterID base = callFrameRegister);
242 inline Address addressFor(int index, RegisterID base = callFrameRegister);
243 };
244
245 struct ThunkHelpers {
246 static unsigned jsStringLengthOffset() { return OBJECT_OFFSETOF(JSString, m_length); }
247 static unsigned jsStringValueOffset() { return OBJECT_OFFSETOF(JSString, m_value); }
248 };
249
250 #if USE(JSVALUE32_64)
251 inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID payload)
252 {
253 loadPtr(payloadFor(virtualRegisterIndex), payload);
254 return emitJumpIfNotJSCell(virtualRegisterIndex);
255 }
256
257 inline JSInterfaceJIT::Jump JSInterfaceJIT::emitJumpIfNotJSCell(unsigned virtualRegisterIndex)
258 {
259 ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
260 return branch32(NotEqual, tagFor(virtualRegisterIndex), TrustedImm32(JSValue::CellTag));
261 }
262
263 inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadInt32(unsigned virtualRegisterIndex, RegisterID dst)
264 {
265 ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
266 loadPtr(payloadFor(virtualRegisterIndex), dst);
267 return branch32(NotEqual, tagFor(static_cast<int>(virtualRegisterIndex)), TrustedImm32(JSValue::Int32Tag));
268 }
269
270 inline JSInterfaceJIT::Address JSInterfaceJIT::tagFor(int virtualRegisterIndex, RegisterID base)
271 {
272 ASSERT(virtualRegisterIndex < FirstConstantRegisterIndex);
273 return Address(base, (static_cast<unsigned>(virtualRegisterIndex) * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.tag));
274 }
275
276 inline JSInterfaceJIT::Address JSInterfaceJIT::payloadFor(int virtualRegisterIndex, RegisterID base)
277 {
278 ASSERT(virtualRegisterIndex < FirstConstantRegisterIndex);
279 return Address(base, (static_cast<unsigned>(virtualRegisterIndex) * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.payload));
280 }
281
282 inline JSInterfaceJIT::Address JSInterfaceJIT::intPayloadFor(int virtualRegisterIndex, RegisterID base)
283 {
284 return payloadFor(virtualRegisterIndex, base);
285 }
286
287 inline JSInterfaceJIT::Address JSInterfaceJIT::intTagFor(int virtualRegisterIndex, RegisterID base)
288 {
289 return tagFor(virtualRegisterIndex, base);
290 }
291
292 inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadDouble(unsigned virtualRegisterIndex, FPRegisterID dst, RegisterID scratch)
293 {
294 ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
295 loadPtr(tagFor(virtualRegisterIndex), scratch);
296 Jump isDouble = branch32(Below, scratch, TrustedImm32(JSValue::LowestTag));
297 Jump notInt = branch32(NotEqual, scratch, TrustedImm32(JSValue::Int32Tag));
298 loadPtr(payloadFor(virtualRegisterIndex), scratch);
299 convertInt32ToDouble(scratch, dst);
300 Jump done = jump();
301 isDouble.link(this);
302 loadDouble(addressFor(virtualRegisterIndex), dst);
303 done.link(this);
304 return notInt;
305 }
306
307 #endif
308
309 #if USE(JSVALUE64)
310 ALWAYS_INLINE JSInterfaceJIT::Jump JSInterfaceJIT::emitJumpIfNotJSCell(RegisterID reg)
311 {
312 return branchTest64(NonZero, reg, tagMaskRegister);
313 }
314
315 ALWAYS_INLINE JSInterfaceJIT::Jump JSInterfaceJIT::emitJumpIfImmediateNumber(RegisterID reg)
316 {
317 return branchTest64(NonZero, reg, tagTypeNumberRegister);
318 }
319 ALWAYS_INLINE JSInterfaceJIT::Jump JSInterfaceJIT::emitJumpIfNotImmediateNumber(RegisterID reg)
320 {
321 return branchTest64(Zero, reg, tagTypeNumberRegister);
322 }
323 inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID dst)
324 {
325 load64(addressFor(virtualRegisterIndex), dst);
326 return branchTest64(NonZero, dst, tagMaskRegister);
327 }
328
329 inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadInt32(unsigned virtualRegisterIndex, RegisterID dst)
330 {
331 load64(addressFor(virtualRegisterIndex), dst);
332 Jump result = branch64(Below, dst, tagTypeNumberRegister);
333 zeroExtend32ToPtr(dst, dst);
334 return result;
335 }
336
337 inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadDouble(unsigned virtualRegisterIndex, FPRegisterID dst, RegisterID scratch)
338 {
339 load64(addressFor(virtualRegisterIndex), scratch);
340 Jump notNumber = emitJumpIfNotImmediateNumber(scratch);
341 Jump notInt = branch64(Below, scratch, tagTypeNumberRegister);
342 convertInt32ToDouble(scratch, dst);
343 Jump done = jump();
344 notInt.link(this);
345 add64(tagTypeNumberRegister, scratch);
346 move64ToDouble(scratch, dst);
347 done.link(this);
348 return notNumber;
349 }
350
351 ALWAYS_INLINE void JSInterfaceJIT::emitFastArithImmToInt(RegisterID)
352 {
353 }
354
355 // operand is int32_t, must have been zero-extended if register is 64-bit.
356 ALWAYS_INLINE void JSInterfaceJIT::emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest)
357 {
358 if (src != dest)
359 move(src, dest);
360 or64(tagTypeNumberRegister, dest);
361 }
362 #endif
363
364 #if USE(JSVALUE64)
365 inline JSInterfaceJIT::Address JSInterfaceJIT::payloadFor(int virtualRegisterIndex, RegisterID base)
366 {
367 ASSERT(virtualRegisterIndex < FirstConstantRegisterIndex);
368 return addressFor(virtualRegisterIndex, base);
369 }
370
371 inline JSInterfaceJIT::Address JSInterfaceJIT::intPayloadFor(int virtualRegisterIndex, RegisterID base)
372 {
373 ASSERT(virtualRegisterIndex < FirstConstantRegisterIndex);
374 return Address(base, (static_cast<unsigned>(virtualRegisterIndex) * sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
375 }
376 inline JSInterfaceJIT::Address JSInterfaceJIT::intTagFor(int virtualRegisterIndex, RegisterID base)
377 {
378 ASSERT(virtualRegisterIndex < FirstConstantRegisterIndex);
379 return Address(base, (static_cast<unsigned>(virtualRegisterIndex) * sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
380 }
381 #endif
382
383 ALWAYS_INLINE JSInterfaceJIT::Jump JSInterfaceJIT::emitJumpIfNotType(RegisterID baseReg, RegisterID scratchReg, JSType type)
384 {
385 loadPtr(Address(baseReg, JSCell::structureOffset()), scratchReg);
386 return branch8(NotEqual, Address(scratchReg, Structure::typeInfoTypeOffset()), TrustedImm32(type));
387 }
388
389 ALWAYS_INLINE void JSInterfaceJIT::emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
390 {
391 loadPtr(Address(from, entry * sizeof(Register)), to);
392 }
393
394 ALWAYS_INLINE void JSInterfaceJIT::emitPutToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry entry)
395 {
396 #if USE(JSVALUE32_64)
397 storePtr(from, payloadFor(entry, callFrameRegister));
398 #else
399 store64(from, addressFor(entry, callFrameRegister));
400 #endif
401 }
402
403 ALWAYS_INLINE void JSInterfaceJIT::emitPutImmediateToCallFrameHeader(void* value, JSStack::CallFrameHeaderEntry entry)
404 {
405 storePtr(TrustedImmPtr(value), Address(callFrameRegister, entry * sizeof(Register)));
406 }
407
408 ALWAYS_INLINE void JSInterfaceJIT::emitPutCellToCallFrameHeader(RegisterID from, JSStack::CallFrameHeaderEntry entry)
409 {
410 #if USE(JSVALUE32_64)
411 store32(TrustedImm32(JSValue::CellTag), tagFor(entry, callFrameRegister));
412 store32(from, payloadFor(entry, callFrameRegister));
413 #else
414 store64(from, addressFor(entry, callFrameRegister));
415 #endif
416 }
417
418 inline JSInterfaceJIT::Address JSInterfaceJIT::addressFor(int virtualRegisterIndex, RegisterID base)
419 {
420 ASSERT(virtualRegisterIndex < FirstConstantRegisterIndex);
421 return Address(base, (static_cast<unsigned>(virtualRegisterIndex) * sizeof(Register)));
422 }
423
424 #if CPU(ARM) || CPU(ARM64)
425
426 ALWAYS_INLINE void JSInterfaceJIT::preserveReturnAddressAfterCall(RegisterID reg)
427 {
428 move(linkRegister, reg);
429 }
430
431 ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(RegisterID reg)
432 {
433 move(reg, linkRegister);
434 }
435
436 ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(Address address)
437 {
438 loadPtr(address, linkRegister);
439 }
440 #elif CPU(SH4)
441
442 ALWAYS_INLINE void JSInterfaceJIT::preserveReturnAddressAfterCall(RegisterID reg)
443 {
444 m_assembler.stspr(reg);
445 }
446
447 ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(RegisterID reg)
448 {
449 m_assembler.ldspr(reg);
450 }
451
452 ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(Address address)
453 {
454 loadPtrLinkReg(address);
455 }
456
457 #elif CPU(MIPS)
458
459 ALWAYS_INLINE void JSInterfaceJIT::preserveReturnAddressAfterCall(RegisterID reg)
460 {
461 move(returnAddressRegister, reg);
462 }
463
464 ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(RegisterID reg)
465 {
466 move(reg, returnAddressRegister);
467 }
468
469 ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(Address address)
470 {
471 loadPtr(address, returnAddressRegister);
472 }
473
474 #else // CPU(X86) || CPU(X86_64)
475
476 ALWAYS_INLINE void JSInterfaceJIT::preserveReturnAddressAfterCall(RegisterID reg)
477 {
478 pop(reg);
479 }
480
481 ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(RegisterID reg)
482 {
483 push(reg);
484 }
485
486 ALWAYS_INLINE void JSInterfaceJIT::restoreReturnAddressBeforeReturn(Address address)
487 {
488 push(address);
489 }
490
491 #endif
492
493 ALWAYS_INLINE void JSInterfaceJIT::restoreArgumentReference()
494 {
495 move(stackPointerRegister, firstArgumentRegister);
496 poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof(void*));
497 }
498
499 } // namespace JSC
500
501 #endif // ENABLE(JIT)
502
503 #endif // JSInterfaceJIT_h