7cb71066b0faeb45d54895c599df530ff132f4d0
[WebKit.git] / JavaScriptCore / VM / CTI.cpp
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 #include "config.h"
27 #include "CTI.h"
28
29 #if ENABLE(CTI)
30
31 #include "CodeBlock.h"
32 #include "JSArray.h"
33 #include "Machine.h"
34 #include "wrec/WREC.h"
35 #include "ResultType.h"
36 #if PLATFORM(MAC)
37 #include <sys/sysctl.h>
38 #endif
39
40 using namespace std;
41
42 namespace JSC {
43
44 #if PLATFORM(MAC)
45 bool isSSE2Present()
46 {
47     return true; // All X86 Macs are guaranteed to support at least SSE2
48 }
49 #else COMPILER(MSVC)
50 bool isSSE2Present()
51 {
52     static const int SSE2FeatureBit = 1 << 26;
53     struct SSE2Check {
54         SSE2Check()
55         {
56             int flags;
57 #if COMPILER(MSVC)
58             _asm {
59                 mov eax, 1 // cpuid function 1 gives us the standard feature set
60                 cpuid;
61                 mov flags, edx;
62             }
63 #else
64             flags = 0;
65             // FIXME: Add GCC code to do above asm
66 #endif
67             present = (flags & SSE2FeatureBit) != 0;
68         }
69         bool present;
70     };
71     static SSE2Check check;
72     return check.present;
73 }
74 #endif
75
76 #if COMPILER(GCC) && PLATFORM(X86)
77 asm(
78 ".globl _ctiTrampoline" "\n"
79 "_ctiTrampoline:" "\n"
80     "pushl %esi" "\n"
81     "pushl %edi" "\n"
82     "subl $0x24, %esp" "\n"
83     "movl $512, %esi" "\n"
84     "call *0x30(%esp)" "\n" //Ox30 = 0x0C * 4, 0x0C = CTI_ARGS_code
85     "addl $0x24, %esp" "\n"
86     "popl %edi" "\n"
87     "popl %esi" "\n"
88     "ret" "\n"
89 );
90
91 asm(
92 ".globl _ctiVMThrowTrampoline" "\n"
93 "_ctiVMThrowTrampoline:" "\n"
94 #ifndef NDEBUG
95     "movl 0x34(%esp), %ecx" "\n" //Ox34 = 0x0D * 4, 0x0D = CTI_ARGS_exec
96     "cmpl $0, 8(%ecx)" "\n"
97     "jne 1f" "\n"
98     "int3" "\n"
99     "1:" "\n"
100 #endif
101     "call __ZN3JSC7Machine12cti_vm_throwEPv" "\n"
102     "addl $0x24, %esp" "\n"
103     "popl %edi" "\n"
104     "popl %esi" "\n"
105     "ret" "\n"
106 );
107     
108 #elif COMPILER(MSVC)
109 extern "C"
110 {
111     
112     __declspec(naked) JSValue* ctiTrampoline(void* code, ExecState* exec, RegisterFile* registerFile, Register* r, JSValue** exception, Profiler**, JSGlobalData*)
113     {
114         __asm {
115             push esi;
116             push edi;
117             sub esp, 0x24;
118             mov esi, 512;
119             mov [esp], esp;
120             call [esp + 0x30];
121             add esp, 0x24;
122             pop edi;
123             pop esi;
124             ret;
125         }
126     }
127     
128     __declspec(naked) void ctiVMThrowTrampoline()
129     {
130         __asm {
131            mov [esp], esp;
132             call JSC::Machine::cti_vm_throw;
133             add esp, 0x24;
134             pop edi;
135             pop esi;
136             ret;
137         }
138     }
139     
140 }
141
142 #endif
143
144
145 ALWAYS_INLINE bool CTI::isConstant(int src)
146 {
147     return src >= m_codeBlock->numVars && src < m_codeBlock->numVars + m_codeBlock->numConstants;
148 }
149
150 ALWAYS_INLINE JSValue* CTI::getConstant(ExecState* exec, int src)
151 {
152     return m_codeBlock->constantRegisters[src - m_codeBlock->numVars].jsValue(exec);
153 }
154
155 // get arg puts an arg from the SF register array into a h/w register
156 ALWAYS_INLINE void CTI::emitGetArg(int src, X86Assembler::RegisterID dst)
157 {
158     // TODO: we want to reuse values that are already in registers if we can - add a register allocator!
159     if (isConstant(src)) {
160         JSValue* js = getConstant(m_exec, src);
161         m_jit.movl_i32r(reinterpret_cast<unsigned>(js), dst);
162     } else
163         m_jit.movl_mr(src * sizeof(Register), X86::edi, dst);
164 }
165
166 // get arg puts an arg from the SF register array onto the stack, as an arg to a context threaded function.
167 ALWAYS_INLINE void CTI::emitGetPutArg(unsigned src, unsigned offset, X86Assembler::RegisterID scratch)
168 {
169     if (isConstant(src)) {
170         JSValue* js = getConstant(m_exec, src);
171         m_jit.movl_i32m(reinterpret_cast<unsigned>(js), offset + sizeof(void*), X86::esp);
172     } else {
173         m_jit.movl_mr(src * sizeof(Register), X86::edi, scratch);
174         m_jit.movl_rm(scratch, offset + sizeof(void*), X86::esp);
175     }
176 }
177
178 // puts an arg onto the stack, as an arg to a context threaded function.
179 ALWAYS_INLINE void CTI::emitPutArg(X86Assembler::RegisterID src, unsigned offset)
180 {
181     m_jit.movl_rm(src, offset + sizeof(void*), X86::esp);
182 }
183
184 ALWAYS_INLINE void CTI::emitPutArgConstant(unsigned value, unsigned offset)
185 {
186     m_jit.movl_i32m(value, offset + sizeof(void*), X86::esp);
187 }
188
189 ALWAYS_INLINE JSValue* CTI::getConstantImmediateNumericArg(unsigned src)
190 {
191     if (isConstant(src)) {
192         JSValue* js = getConstant(m_exec, src);
193         return JSImmediate::isNumber(js) ? js : 0;
194     }
195     return 0;
196 }
197
198 ALWAYS_INLINE void CTI::emitPutCTIParam(void* value, unsigned name)
199 {
200     m_jit.movl_i32m(reinterpret_cast<intptr_t>(value), name * sizeof(void*), X86::esp);
201 }
202
203 ALWAYS_INLINE void CTI::emitPutCTIParam(X86Assembler::RegisterID from, unsigned name)
204 {
205     m_jit.movl_rm(from, name * sizeof(void*), X86::esp);
206 }
207
208 ALWAYS_INLINE void CTI::emitGetCTIParam(unsigned name, X86Assembler::RegisterID to)
209 {
210     m_jit.movl_mr(name * sizeof(void*), X86::esp, to);
211 }
212
213 ALWAYS_INLINE void CTI::emitPutToCallFrameHeader(X86Assembler::RegisterID from, RegisterFile::CallFrameHeaderEntry entry)
214 {
215     m_jit.movl_rm(from, entry * sizeof(Register), X86::edi);
216 }
217
218 ALWAYS_INLINE void CTI::emitGetFromCallFrameHeader(RegisterFile::CallFrameHeaderEntry entry, X86Assembler::RegisterID to)
219 {
220     m_jit.movl_mr(entry * sizeof(Register), X86::edi, to);
221 }
222
223 ALWAYS_INLINE void CTI::emitPutResult(unsigned dst, X86Assembler::RegisterID from)
224 {
225     m_jit.movl_rm(from, dst * sizeof(Register), X86::edi);
226     // FIXME: #ifndef NDEBUG, Write the correct m_type to the register.
227 }
228
229 ALWAYS_INLINE void CTI::emitInitRegister(unsigned dst)
230 {
231     m_jit.movl_i32m(reinterpret_cast<unsigned>(jsUndefined()), dst * sizeof(Register), X86::edi);
232     // FIXME: #ifndef NDEBUG, Write the correct m_type to the register.
233 }
234
235 #if ENABLE(SAMPLING_TOOL)
236 unsigned inCalledCode = 0;
237 #endif
238
239 void ctiSetReturnAddress(void** where, void* what)
240 {
241     *where = what;
242 }
243
244 void ctiRepatchCallByReturnAddress(void* where, void* what)
245 {
246     (static_cast<void**>(where))[-1] = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(what) - reinterpret_cast<uintptr_t>(where));
247 }
248
249 #ifdef NDEBUG
250
251 ALWAYS_INLINE void CTI::emitDebugExceptionCheck()
252 {
253 }
254
255 #else
256
257 ALWAYS_INLINE void CTI::emitDebugExceptionCheck()
258 {
259     emitGetCTIParam(CTI_ARGS_exec, X86::ecx);
260     m_jit.cmpl_i32m(0, OBJECT_OFFSET(ExecState, m_exception), X86::ecx);
261     X86Assembler::JmpSrc noException = m_jit.emitUnlinkedJe();
262     m_jit.emitInt3();
263     m_jit.link(noException, m_jit.label());
264 }
265
266 void CTI::printOpcodeOperandTypes(unsigned src1, unsigned src2)
267 {
268     char which1 = '*';
269     if (isConstant(src1)) {
270         JSValue* js = getConstant(m_exec, src1);
271         which1 = 
272             JSImmediate::isImmediate(js) ?
273                 (JSImmediate::isNumber(js) ? 'i' :
274                 JSImmediate::isBoolean(js) ? 'b' :
275                 js->isUndefined() ? 'u' :
276                 js->isNull() ? 'n' : '?')
277                 :
278             (js->isString() ? 's' :
279             js->isObject() ? 'o' :
280             'k');
281     }
282     char which2 = '*';
283     if (isConstant(src2)) {
284         JSValue* js = getConstant(m_exec, src2);
285         which2 = 
286             JSImmediate::isImmediate(js) ?
287                 (JSImmediate::isNumber(js) ? 'i' :
288                 JSImmediate::isBoolean(js) ? 'b' :
289                 js->isUndefined() ? 'u' :
290                 js->isNull() ? 'n' : '?')
291                 :
292             (js->isString() ? 's' :
293             js->isObject() ? 'o' :
294             'k');
295     }
296     if ((which1 != '*') | (which2 != '*'))
297         fprintf(stderr, "Types %c %c\n", which1, which2);
298 }
299
300 #endif
301
302 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCall(unsigned opcodeIndex, X86::RegisterID r)
303 {
304     m_jit.emitRestoreArgumentReference();
305     X86Assembler::JmpSrc call = m_jit.emitCall(r);
306     m_calls.append(CallRecord(call, opcodeIndex));
307     emitDebugExceptionCheck();
308
309     return call;
310 }
311
312 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCall(unsigned opcodeIndex, CTIHelper_j helper)
313 {
314 #if ENABLE(SAMPLING_TOOL)
315     m_jit.movl_i32m(1, &inCalledCode);
316 #endif
317     m_jit.emitRestoreArgumentReference();
318     X86Assembler::JmpSrc call = m_jit.emitCall();
319     m_calls.append(CallRecord(call, helper, opcodeIndex));
320     emitDebugExceptionCheck();
321 #if ENABLE(SAMPLING_TOOL)
322     m_jit.movl_i32m(0, &inCalledCode);
323 #endif
324
325     return call;
326 }
327
328 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCall(unsigned opcodeIndex, CTIHelper_p helper)
329 {
330 #if ENABLE(SAMPLING_TOOL)
331     m_jit.movl_i32m(1, &inCalledCode);
332 #endif
333     m_jit.emitRestoreArgumentReference();
334     X86Assembler::JmpSrc call = m_jit.emitCall();
335     m_calls.append(CallRecord(call, helper, opcodeIndex));
336     emitDebugExceptionCheck();
337 #if ENABLE(SAMPLING_TOOL)
338     m_jit.movl_i32m(0, &inCalledCode);
339 #endif
340
341     return call;
342 }
343
344 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCall(unsigned opcodeIndex, CTIHelper_b helper)
345 {
346 #if ENABLE(SAMPLING_TOOL)
347     m_jit.movl_i32m(1, &inCalledCode);
348 #endif
349     m_jit.emitRestoreArgumentReference();
350     X86Assembler::JmpSrc call = m_jit.emitCall();
351     m_calls.append(CallRecord(call, helper, opcodeIndex));
352     emitDebugExceptionCheck();
353 #if ENABLE(SAMPLING_TOOL)
354     m_jit.movl_i32m(0, &inCalledCode);
355 #endif
356
357     return call;
358 }
359
360 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCall(unsigned opcodeIndex, CTIHelper_v helper)
361 {
362 #if ENABLE(SAMPLING_TOOL)
363     m_jit.movl_i32m(1, &inCalledCode);
364 #endif
365     m_jit.emitRestoreArgumentReference();
366     X86Assembler::JmpSrc call = m_jit.emitCall();
367     m_calls.append(CallRecord(call, helper, opcodeIndex));
368     emitDebugExceptionCheck();
369 #if ENABLE(SAMPLING_TOOL)
370     m_jit.movl_i32m(0, &inCalledCode);
371 #endif
372
373     return call;
374 }
375
376 ALWAYS_INLINE X86Assembler::JmpSrc CTI::emitCall(unsigned opcodeIndex, CTIHelper_s helper)
377 {
378 #if ENABLE(SAMPLING_TOOL)
379     m_jit.movl_i32m(1, &inCalledCode);
380 #endif
381     m_jit.emitRestoreArgumentReference();
382     X86Assembler::JmpSrc call = m_jit.emitCall();
383     m_calls.append(CallRecord(call, helper, opcodeIndex));
384     emitDebugExceptionCheck();
385 #if ENABLE(SAMPLING_TOOL)
386     m_jit.movl_i32m(0, &inCalledCode);
387 #endif
388
389     return call;
390 }
391
392 ALWAYS_INLINE void CTI::emitJumpSlowCaseIfNotJSCell(X86Assembler::RegisterID reg, unsigned opcodeIndex)
393 {
394     m_jit.testl_i32r(JSImmediate::TagMask, reg);
395     m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), opcodeIndex));
396 }
397
398 ALWAYS_INLINE void CTI::emitJumpSlowCaseIfNotImmNum(X86Assembler::RegisterID reg, unsigned opcodeIndex)
399 {
400     m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, reg);
401     m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJe(), opcodeIndex));
402 }
403
404 ALWAYS_INLINE void CTI::emitJumpSlowCaseIfNotImmNums(X86Assembler::RegisterID reg1, X86Assembler::RegisterID reg2, unsigned opcodeIndex)
405 {
406     m_jit.movl_rr(reg1, X86::ecx);
407     m_jit.andl_rr(reg2, X86::ecx);
408     emitJumpSlowCaseIfNotImmNum(X86::ecx, opcodeIndex);
409 }
410
411 ALWAYS_INLINE unsigned CTI::getDeTaggedConstantImmediate(JSValue* imm)
412 {
413     ASSERT(JSImmediate::isNumber(imm));
414     return reinterpret_cast<unsigned>(imm) & ~JSImmediate::TagBitTypeInteger;
415 }
416
417 ALWAYS_INLINE void CTI::emitFastArithDeTagImmediate(X86Assembler::RegisterID reg)
418 {
419     // op_mod relies on this being a sub - setting zf if result is 0.
420     m_jit.subl_i8r(JSImmediate::TagBitTypeInteger, reg);
421 }
422
423 ALWAYS_INLINE void CTI::emitFastArithReTagImmediate(X86Assembler::RegisterID reg)
424 {
425     m_jit.addl_i8r(JSImmediate::TagBitTypeInteger, reg);
426 }
427
428 ALWAYS_INLINE void CTI::emitFastArithPotentiallyReTagImmediate(X86Assembler::RegisterID reg)
429 {
430     m_jit.orl_i32r(JSImmediate::TagBitTypeInteger, reg);
431 }
432
433 ALWAYS_INLINE void CTI::emitFastArithImmToInt(X86Assembler::RegisterID reg)
434 {
435     m_jit.sarl_i8r(1, reg);
436 }
437
438 ALWAYS_INLINE void CTI::emitFastArithIntToImmOrSlowCase(X86Assembler::RegisterID reg, unsigned opcodeIndex)
439 {
440     m_jit.addl_rr(reg, reg);
441     m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), opcodeIndex));
442     emitFastArithReTagImmediate(reg);
443 }
444
445 ALWAYS_INLINE void CTI::emitFastArithIntToImmNoCheck(X86Assembler::RegisterID reg)
446 {
447     m_jit.addl_rr(reg, reg);
448     emitFastArithReTagImmediate(reg);
449 }
450
451 ALWAYS_INLINE void CTI::emitTagAsBoolImmediate(X86Assembler::RegisterID reg)
452 {
453     m_jit.shl_i8r(JSImmediate::ExtendedPayloadShift, reg);
454     m_jit.orl_i32r(JSImmediate::FullTagTypeBool, reg);
455 }
456
457 CTI::CTI(Machine* machine, ExecState* exec, CodeBlock* codeBlock)
458     : m_jit(machine->jitCodeBuffer())
459     , m_machine(machine)
460     , m_exec(exec)
461     , m_codeBlock(codeBlock)
462     , m_labels(codeBlock ? codeBlock->instructions.size() : 0)
463     , m_structureStubCompilationInfo(codeBlock ? codeBlock->structureIDInstructions.size() : 0)
464 {
465 }
466
467 #define CTI_COMPILE_BINARY_OP(name) \
468     case name: { \
469         emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); \
470         emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); \
471         emitCall(i, Machine::cti_##name); \
472         emitPutResult(instruction[i + 1].u.operand); \
473         i += 4; \
474         break; \
475     }
476
477 #define CTI_COMPILE_UNARY_OP(name) \
478     case name: { \
479         emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); \
480         emitCall(i, Machine::cti_##name); \
481         emitPutResult(instruction[i + 1].u.operand); \
482         i += 3; \
483         break; \
484     }
485
486 #if ENABLE(SAMPLING_TOOL)
487 OpcodeID currentOpcodeID = static_cast<OpcodeID>(-1);
488 #endif
489
490 void CTI::compileOpCall(Instruction* instruction, unsigned i, CompileOpCallType type)
491 {
492     int dst = instruction[i + 1].u.operand;
493     int firstArg = instruction[i + 4].u.operand;
494     int argCount = instruction[i + 5].u.operand;
495     int registerOffset = instruction[i + 6].u.operand;
496
497     if (type == OpCallEval)
498         emitGetPutArg(instruction[i + 3].u.operand, 16, X86::ecx);
499
500     if (type == OpConstruct) {
501         emitPutArgConstant(reinterpret_cast<unsigned>(instruction + i), 20);
502         emitPutArgConstant(argCount, 16);
503         emitPutArgConstant(registerOffset, 12);
504         emitPutArgConstant(firstArg, 8);
505         emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
506     } else {
507         emitPutArgConstant(reinterpret_cast<unsigned>(instruction + i), 12);
508         emitPutArgConstant(argCount, 8);
509         emitPutArgConstant(registerOffset, 4);
510
511         int thisVal = instruction[i + 3].u.operand;
512         if (thisVal == missingThisObjectMarker()) {
513             // FIXME: should this be loaded dynamically off m_exec?
514             m_jit.movl_i32m(reinterpret_cast<unsigned>(m_exec->globalThisValue()), firstArg * sizeof(Register), X86::edi);
515         } else {
516             emitGetArg(thisVal, X86::ecx);
517             emitPutResult(firstArg, X86::ecx);
518         }
519     }
520
521     X86Assembler::JmpSrc wasEval;
522     if (type == OpCallEval) {
523         emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
524         emitCall(i, Machine::cti_op_call_eval);
525
526         emitGetCTIParam(CTI_ARGS_r, X86::edi); // edi := r
527
528         m_jit.cmpl_i32r(reinterpret_cast<unsigned>(JSImmediate::impossibleValue()), X86::eax);
529         wasEval = m_jit.emitUnlinkedJne();
530
531         // this sets up the first arg to op_cti_call (func), and explicitly leaves the value in ecx (checked just below).
532         emitGetArg(instruction[i + 2].u.operand, X86::ecx);
533     } else {
534         // this sets up the first arg to op_cti_call (func), and explicitly leaves the value in ecx (checked just below).
535         emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
536     }
537
538     // Fast check for JS function.
539     m_jit.testl_i32r(JSImmediate::TagMask, X86::ecx);
540     X86Assembler::JmpSrc isNotObject = m_jit.emitUnlinkedJne();
541     m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsFunctionVptr), X86::ecx);
542     X86Assembler::JmpSrc isJSFunction = m_jit.emitUnlinkedJe();
543     m_jit.link(isNotObject, m_jit.label());
544
545     // This handles host functions
546     emitCall(i, ((type == OpConstruct) ? Machine::cti_op_construct_NotJSConstruct : Machine::cti_op_call_NotJSFunction));
547
548     X86Assembler::JmpSrc wasNotJSFunction = m_jit.emitUnlinkedJmp();
549     m_jit.link(isJSFunction, m_jit.label());
550
551     // This handles JSFunctions
552     emitCall(i, ((type == OpConstruct) ? Machine::cti_op_construct_JSConstruct : Machine::cti_op_call_JSFunction));
553
554     // Check the ctiCode has been generated - if not, this is handled in a slow case.
555     m_jit.testl_rr(X86::eax, X86::eax);
556     m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJe(), i));
557     emitCall(i, X86::eax);
558     
559     X86Assembler::JmpDst end = m_jit.label();
560     m_jit.link(wasNotJSFunction, end);
561     if (type == OpCallEval)
562         m_jit.link(wasEval, end);
563
564     // Put the return value in dst. In the interpreter, op_ret does this.
565     emitPutResult(dst);
566 }
567
568 void CTI::compileOpStrictEq(Instruction* instruction, unsigned i, CompileOpStrictEqType type)
569 {
570     bool negated = (type == OpNStrictEq);
571
572     unsigned dst = instruction[i + 1].u.operand;
573     unsigned src1 = instruction[i + 2].u.operand;
574     unsigned src2 = instruction[i + 3].u.operand;
575
576     emitGetArg(src1, X86::eax);
577     emitGetArg(src2, X86::edx);
578
579     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
580     X86Assembler::JmpSrc firstNotImmediate = m_jit.emitUnlinkedJe();
581     m_jit.testl_i32r(JSImmediate::TagMask, X86::edx);
582     X86Assembler::JmpSrc secondNotImmediate = m_jit.emitUnlinkedJe();
583
584     m_jit.cmpl_rr(X86::edx, X86::eax);
585     if (negated)
586         m_jit.setne_r(X86::eax);
587     else
588         m_jit.sete_r(X86::eax);
589     m_jit.movzbl_rr(X86::eax, X86::eax);
590     emitTagAsBoolImmediate(X86::eax);
591             
592     X86Assembler::JmpSrc bothWereImmediates = m_jit.emitUnlinkedJmp();
593
594     m_jit.link(firstNotImmediate, m_jit.label());
595
596     // check that edx is immediate but not the zero immediate
597     m_jit.testl_i32r(JSImmediate::TagMask, X86::edx);
598     m_jit.setz_r(X86::ecx);
599     m_jit.movzbl_rr(X86::ecx, X86::ecx); // ecx is now 1 if edx was nonimmediate
600     m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::edx);
601     m_jit.sete_r(X86::edx);
602     m_jit.movzbl_rr(X86::edx, X86::edx); // edx is now 1 if edx was the 0 immediate
603     m_jit.orl_rr(X86::ecx, X86::edx);
604
605     m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJnz(), i));
606
607     m_jit.movl_i32r(reinterpret_cast<uint32_t>(jsBoolean(negated)), X86::eax);
608
609     X86Assembler::JmpSrc firstWasNotImmediate = m_jit.emitUnlinkedJmp();
610
611     m_jit.link(secondNotImmediate, m_jit.label());
612     // check that eax is not the zero immediate (we know it must be immediate)
613     m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::eax);
614     m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJe(), i));
615
616     m_jit.movl_i32r(reinterpret_cast<uint32_t>(jsBoolean(negated)), X86::eax);
617
618     m_jit.link(bothWereImmediates, m_jit.label());
619     m_jit.link(firstWasNotImmediate, m_jit.label());
620
621     emitPutResult(dst);
622 }
623
624 void CTI::emitSlowScriptCheck(unsigned opcodeIndex)
625 {
626     m_jit.subl_i8r(1, X86::esi);
627     X86Assembler::JmpSrc skipTimeout = m_jit.emitUnlinkedJne();
628     emitCall(opcodeIndex, Machine::cti_timeout_check);
629
630     emitGetCTIParam(CTI_ARGS_globalData, X86::ecx);
631     m_jit.movl_mr(OBJECT_OFFSET(JSGlobalData, machine), X86::ecx, X86::ecx);
632     m_jit.movl_mr(OBJECT_OFFSET(Machine, m_ticksUntilNextTimeoutCheck), X86::ecx, X86::esi);
633     m_jit.link(skipTimeout, m_jit.label());
634 }
635
636 /*
637   This is required since number representation is canonical - values representable as a JSImmediate should not be stored in a JSNumberCell.
638   
639   In the common case, the double value from 'xmmSource' is written to the reusable JSNumberCell pointed to by 'jsNumberCell', then 'jsNumberCell'
640   is written to the output SF Register 'dst', and then a jump is planted (stored into *wroteJSNumberCell).
641   
642   However if the value from xmmSource is representable as a JSImmediate, then the JSImmediate value will be written to the output, and flow
643   control will fall through from the code planted.
644 */
645 void CTI::putDoubleResultToJSNumberCellOrJSImmediate(X86::XMMRegisterID xmmSource, X86::RegisterID jsNumberCell, unsigned dst, X86Assembler::JmpSrc* wroteJSNumberCell,  X86::XMMRegisterID tempXmm, X86::RegisterID tempReg1, X86::RegisterID tempReg2)
646 {
647     // convert (double -> JSImmediate -> double), and check if the value is unchanged - in which case the value is representable as a JSImmediate.
648     m_jit.cvttsd2si_rr(xmmSource, tempReg1);
649     m_jit.addl_rr(tempReg1, tempReg1);
650     m_jit.sarl_i8r(1, tempReg1);
651     m_jit.cvtsi2sd_rr(tempReg1, tempXmm);
652     // Compare & branch if immediate. 
653     m_jit.ucomis_rr(tempXmm, xmmSource);
654     X86Assembler::JmpSrc resultIsImm = m_jit.emitUnlinkedJe();
655     X86Assembler::JmpDst resultLookedLikeImmButActuallyIsnt = m_jit.label();
656     
657     // Store the result to the JSNumberCell and jump.
658     m_jit.movsd_rm(xmmSource, OBJECT_OFFSET(JSNumberCell, m_value), jsNumberCell);
659     emitPutResult(dst, jsNumberCell);
660     *wroteJSNumberCell = m_jit.emitUnlinkedJmp();
661
662     m_jit.link(resultIsImm, m_jit.label());
663     // value == (double)(JSImmediate)value... or at least, it looks that way...
664     // ucomi will report that (0 == -0), and will report true if either input in NaN (result is unordered).
665     m_jit.link(m_jit.emitUnlinkedJp(), resultLookedLikeImmButActuallyIsnt); // Actually was a NaN
666     m_jit.pextrw_irr(3, xmmSource, tempReg2);
667     m_jit.cmpl_i32r(0x8000, tempReg2);
668     m_jit.link(m_jit.emitUnlinkedJe(), resultLookedLikeImmButActuallyIsnt); // Actually was -0
669     // Yes it really really really is representable as a JSImmediate.
670     emitFastArithIntToImmNoCheck(tempReg1);
671     emitPutResult(dst, X86::ecx);
672 }
673
674 void CTI::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes types, unsigned i)
675 {
676     StructureID* numberStructureID = m_exec->globalData().numberStructureID.get();
677     X86Assembler::JmpSrc wasJSNumberCell1, wasJSNumberCell1b, wasJSNumberCell2, wasJSNumberCell2b;
678
679     emitGetArg(src1, X86::eax);
680     emitGetArg(src2, X86::edx);
681
682     if (types.second().isReusable() && isSSE2Present()) {
683         ASSERT(types.second().mightBeNumber());
684
685         // Check op2 is a number
686         m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::edx);
687         X86Assembler::JmpSrc op2imm = m_jit.emitUnlinkedJne();
688         if (!types.second().definitelyIsNumber()) {
689             emitJumpSlowCaseIfNotJSCell(X86::edx, i);
690             m_jit.cmpl_i32m(reinterpret_cast<unsigned>(numberStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::edx);
691             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
692         }
693
694         // (1) In this case src2 is a reusable number cell.
695         //     Slow case if src1 is not a number type.
696         m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
697         X86Assembler::JmpSrc op1imm = m_jit.emitUnlinkedJne();
698         if (!types.first().definitelyIsNumber()) {
699             emitJumpSlowCaseIfNotJSCell(X86::eax, i);
700             m_jit.cmpl_i32m(reinterpret_cast<unsigned>(numberStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
701             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
702         }
703
704         // (1a) if we get here, src1 is also a number cell
705         m_jit.movsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0);
706         X86Assembler::JmpSrc loadedDouble = m_jit.emitUnlinkedJmp();
707         // (1b) if we get here, src1 is an immediate
708         m_jit.link(op1imm, m_jit.label());
709         emitFastArithImmToInt(X86::eax);
710         m_jit.cvtsi2sd_rr(X86::eax, X86::xmm0);
711         // (1c) 
712         m_jit.link(loadedDouble, m_jit.label());
713         if (opcodeID == op_add)
714             m_jit.addsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0);
715         else if (opcodeID == op_sub)
716             m_jit.subsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0);
717         else {
718             ASSERT(opcodeID == op_mul);
719             m_jit.mulsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0);
720         }
721
722         putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::edx, dst, &wasJSNumberCell2, X86::xmm1, X86::ecx, X86::eax);
723         wasJSNumberCell2b = m_jit.emitUnlinkedJmp();
724
725         // (2) This handles cases where src2 is an immediate number.
726         //     Two slow cases - either src1 isn't an immediate, or the subtract overflows.
727         m_jit.link(op2imm, m_jit.label());
728         emitJumpSlowCaseIfNotImmNum(X86::eax, i);
729     } else if (types.first().isReusable() && isSSE2Present()) {
730         ASSERT(types.first().mightBeNumber());
731
732         // Check op1 is a number
733         m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
734         X86Assembler::JmpSrc op1imm = m_jit.emitUnlinkedJne();
735         if (!types.first().definitelyIsNumber()) {
736             emitJumpSlowCaseIfNotJSCell(X86::eax, i);
737             m_jit.cmpl_i32m(reinterpret_cast<unsigned>(numberStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
738             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
739         }
740
741         // (1) In this case src1 is a reusable number cell.
742         //     Slow case if src2 is not a number type.
743         m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::edx);
744         X86Assembler::JmpSrc op2imm = m_jit.emitUnlinkedJne();
745         if (!types.second().definitelyIsNumber()) {
746             emitJumpSlowCaseIfNotJSCell(X86::edx, i);
747             m_jit.cmpl_i32m(reinterpret_cast<unsigned>(numberStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::edx);
748             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
749         }
750
751         // (1a) if we get here, src2 is also a number cell
752         m_jit.movsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm1);
753         X86Assembler::JmpSrc loadedDouble = m_jit.emitUnlinkedJmp();
754         // (1b) if we get here, src2 is an immediate
755         m_jit.link(op2imm, m_jit.label());
756         emitFastArithImmToInt(X86::edx);
757         m_jit.cvtsi2sd_rr(X86::edx, X86::xmm1);
758         // (1c) 
759         m_jit.link(loadedDouble, m_jit.label());
760         m_jit.movsd_mr(OBJECT_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0);
761         if (opcodeID == op_add)
762             m_jit.addsd_rr(X86::xmm1, X86::xmm0);
763         else if (opcodeID == op_sub)
764             m_jit.subsd_rr(X86::xmm1, X86::xmm0);
765         else {
766             ASSERT(opcodeID == op_mul);
767             m_jit.mulsd_rr(X86::xmm1, X86::xmm0);
768         }
769         m_jit.movsd_rm(X86::xmm0, OBJECT_OFFSET(JSNumberCell, m_value), X86::eax);
770         emitPutResult(dst);
771
772         putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::eax, dst, &wasJSNumberCell1, X86::xmm1, X86::ecx, X86::edx);
773         wasJSNumberCell1b = m_jit.emitUnlinkedJmp();
774
775         // (2) This handles cases where src1 is an immediate number.
776         //     Two slow cases - either src2 isn't an immediate, or the subtract overflows.
777         m_jit.link(op1imm, m_jit.label());
778         emitJumpSlowCaseIfNotImmNum(X86::edx, i);
779     } else
780         emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i);
781
782     if (opcodeID == op_add) {
783         emitFastArithDeTagImmediate(X86::eax);
784         m_jit.addl_rr(X86::edx, X86::eax);
785         m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
786     } else  if (opcodeID == op_sub) {
787         m_jit.subl_rr(X86::edx, X86::eax);
788         m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
789         emitFastArithReTagImmediate(X86::eax);
790     } else {
791         ASSERT(opcodeID == op_mul);
792         emitFastArithDeTagImmediate(X86::eax);
793         emitFastArithImmToInt(X86::edx);
794         m_jit.imull_rr(X86::edx, X86::eax);
795         m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
796         emitFastArithReTagImmediate(X86::eax);
797     }
798     emitPutResult(dst);
799
800     if (types.second().isReusable() && isSSE2Present()) {
801         m_jit.link(wasJSNumberCell2, m_jit.label());
802         m_jit.link(wasJSNumberCell2b, m_jit.label());
803     }
804     else if (types.first().isReusable() && isSSE2Present()) {
805         m_jit.link(wasJSNumberCell1, m_jit.label());
806         m_jit.link(wasJSNumberCell1b, m_jit.label());
807     }
808 }
809
810 void CTI::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned dst, unsigned src1, unsigned src2, OperandTypes types, unsigned i)
811 {
812     X86Assembler::JmpDst here = m_jit.label();
813     m_jit.link(iter->from, here);
814     if (types.second().isReusable() && isSSE2Present()) {
815         if (!types.first().definitelyIsNumber()) {
816             m_jit.link((++iter)->from, here);
817             m_jit.link((++iter)->from, here);
818         }
819         if (!types.second().definitelyIsNumber()) {
820             m_jit.link((++iter)->from, here);
821             m_jit.link((++iter)->from, here);
822         }
823         m_jit.link((++iter)->from, here);
824     } else if (types.first().isReusable() && isSSE2Present()) {
825         if (!types.first().definitelyIsNumber()) {
826             m_jit.link((++iter)->from, here);
827             m_jit.link((++iter)->from, here);
828         }
829         if (!types.second().definitelyIsNumber()) {
830             m_jit.link((++iter)->from, here);
831             m_jit.link((++iter)->from, here);
832         }
833         m_jit.link((++iter)->from, here);
834     } else
835         m_jit.link((++iter)->from, here);
836
837     emitGetPutArg(src1, 0, X86::ecx);
838     emitGetPutArg(src2, 4, X86::ecx);
839     if (opcodeID == op_add)
840         emitCall(i, Machine::cti_op_add);
841     else if (opcodeID == op_sub)
842         emitCall(i, Machine::cti_op_sub);
843     else {
844         ASSERT(opcodeID == op_mul);
845         emitCall(i, Machine::cti_op_mul);
846     }
847     emitPutResult(dst);
848 }
849
850 void CTI::privateCompileMainPass()
851 {
852     Instruction* instruction = m_codeBlock->instructions.begin();
853     unsigned instructionCount = m_codeBlock->instructions.size();
854
855     unsigned structureIDInstructionIndex = 0;
856
857     for (unsigned i = 0; i < instructionCount; ) {
858         m_labels[i] = m_jit.label();
859
860 #if ENABLE(SAMPLING_TOOL)
861         m_jit.movl_i32m(m_machine->getOpcodeID(instruction[i].u.opcode), &currentOpcodeID);
862 #endif
863
864         ASSERT_WITH_MESSAGE(m_machine->isOpcode(instruction[i].u.opcode), "privateCompileMainPass gone bad @ %d", i);
865         switch (m_machine->getOpcodeID(instruction[i].u.opcode)) {
866         case op_mov: {
867             unsigned src = instruction[i + 2].u.operand;
868             if (isConstant(src))
869                 m_jit.movl_i32r(reinterpret_cast<unsigned>(getConstant(m_exec, src)), X86::edx);
870             else
871                 emitGetArg(src, X86::edx);
872             emitPutResult(instruction[i + 1].u.operand, X86::edx);
873             i += 3;
874             break;
875         }
876         case op_add: {
877             unsigned dst = instruction[i + 1].u.operand;
878             unsigned src1 = instruction[i + 2].u.operand;
879             unsigned src2 = instruction[i + 3].u.operand;
880
881             if (JSValue* value = getConstantImmediateNumericArg(src1)) {
882                 emitGetArg(src2, X86::edx);
883                 emitJumpSlowCaseIfNotImmNum(X86::edx, i);
884                 m_jit.addl_i32r(getDeTaggedConstantImmediate(value), X86::edx);
885                 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
886                 emitPutResult(dst, X86::edx);
887             } else if (JSValue* value = getConstantImmediateNumericArg(src2)) {
888                 emitGetArg(src1, X86::eax);
889                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
890                 m_jit.addl_i32r(getDeTaggedConstantImmediate(value), X86::eax);
891                 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
892                 emitPutResult(dst);
893             } else {
894                 OperandTypes types = OperandTypes::fromInt(instruction[i + 4].u.operand);
895                 if (types.first().mightBeNumber() && types.second().mightBeNumber())
896                     compileBinaryArithOp(op_add, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
897                 else {
898                     emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
899                     emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
900                     emitCall(i, Machine::cti_op_add);
901                     emitPutResult(instruction[i + 1].u.operand);
902                 }
903             }
904
905             i += 5;
906             break;
907         }
908         case op_end: {
909             if (m_codeBlock->needsFullScopeChain)
910                 emitCall(i, Machine::cti_op_end);
911             emitGetArg(instruction[i + 1].u.operand, X86::eax);
912 #if ENABLE(SAMPLING_TOOL)
913             m_jit.movl_i32m(-1, &currentOpcodeID);
914 #endif
915             m_jit.pushl_m(RegisterFile::ReturnPC * static_cast<int>(sizeof(Register)), X86::edi);
916             m_jit.ret();
917             i += 2;
918             break;
919         }
920         case op_jmp: {
921             unsigned target = instruction[i + 1].u.operand;
922             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 1 + target));
923             i += 2;
924             break;
925         }
926         case op_pre_inc: {
927             int srcDst = instruction[i + 1].u.operand;
928             emitGetArg(srcDst, X86::eax);
929             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
930             m_jit.addl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);
931             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
932             emitPutResult(srcDst, X86::eax);
933             i += 2;
934             break;
935         }
936         case op_loop: {
937             emitSlowScriptCheck(i);
938
939             unsigned target = instruction[i + 1].u.operand;
940             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 1 + target));
941             i += 2;
942             break;
943         }
944         case op_loop_if_less: {
945             emitSlowScriptCheck(i);
946
947             unsigned target = instruction[i + 3].u.operand;
948             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
949             if (src2imm) {
950                 emitGetArg(instruction[i + 1].u.operand, X86::edx);
951                 emitJumpSlowCaseIfNotImmNum(X86::edx, i);
952                 m_jit.cmpl_i32r(reinterpret_cast<unsigned>(src2imm), X86::edx);
953                 m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJl(), i + 3 + target));
954             } else {
955                 emitGetArg(instruction[i + 1].u.operand, X86::eax);
956                 emitGetArg(instruction[i + 2].u.operand, X86::edx);
957                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
958                 emitJumpSlowCaseIfNotImmNum(X86::edx, i);
959                 m_jit.cmpl_rr(X86::edx, X86::eax);
960                 m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJl(), i + 3 + target));
961             }
962             i += 4;
963             break;
964         }
965         case op_loop_if_lesseq: {
966             emitSlowScriptCheck(i);
967
968             unsigned target = instruction[i + 3].u.operand;
969             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
970             if (src2imm) {
971                 emitGetArg(instruction[i + 1].u.operand, X86::edx);
972                 emitJumpSlowCaseIfNotImmNum(X86::edx, i);
973                 m_jit.cmpl_i32r(reinterpret_cast<unsigned>(src2imm), X86::edx);
974                 m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJle(), i + 3 + target));
975             } else {
976                 emitGetArg(instruction[i + 1].u.operand, X86::eax);
977                 emitGetArg(instruction[i + 2].u.operand, X86::edx);
978                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
979                 emitJumpSlowCaseIfNotImmNum(X86::edx, i);
980                 m_jit.cmpl_rr(X86::edx, X86::eax);
981                 m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJle(), i + 3 + target));
982             }
983             i += 4;
984             break;
985         }
986         case op_new_object: {
987             emitCall(i, Machine::cti_op_new_object);
988             emitPutResult(instruction[i + 1].u.operand);
989             i += 2;
990             break;
991         }
992         case op_put_by_id: {
993             // In order to be able to repatch both the StructureID, and the object offset, we store one pointer,
994             // to just after the arguments have been loaded into registers 'hotPathBegin', and we generate code
995             // such that the StructureID & offset are always at the same distance from this.
996
997             emitGetArg(instruction[i + 1].u.operand, X86::eax);
998             emitGetArg(instruction[i + 3].u.operand, X86::edx);
999
1000             ASSERT(m_codeBlock->structureIDInstructions[structureIDInstructionIndex].opcodeIndex == i);
1001             X86Assembler::JmpDst hotPathBegin = m_jit.label();
1002             m_structureStubCompilationInfo[structureIDInstructionIndex].hotPathBegin = hotPathBegin;
1003             ++structureIDInstructionIndex;
1004
1005             // Jump to a slow case if either the base object is an immediate, or if the StructureID does not match.
1006             emitJumpSlowCaseIfNotJSCell(X86::eax, i);
1007             // It is important that the following instruction plants a 32bit immediate, in order that it can be patched over.
1008             m_jit.cmpl_i32m(repatchGetByIdDefaultStructureID, OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
1009             ASSERT(X86Assembler::getDifferenceBetweenLabels(hotPathBegin, m_jit.label()) == repatchOffsetPutByIdStructureID);
1010             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
1011
1012             // Plant a load from a bogus ofset in the object's property map; we will patch this later, if it is to be used.
1013             m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax);
1014             m_jit.movl_rm(X86::edx, repatchGetByIdDefaultOffset, X86::eax);
1015             ASSERT(X86Assembler::getDifferenceBetweenLabels(hotPathBegin, m_jit.label()) == repatchOffsetPutByIdPropertyMapOffset);
1016
1017             i += 8;
1018             break;
1019         }
1020         case op_get_by_id: {
1021             // As for put_by_id, get_by_id requires the offset of the StructureID and the offset of the access to be repatched.
1022             // Additionally, for get_by_id we need repatch the offset of the branch to the slow case (we repatch this to jump
1023             // to array-length / prototype access tranpolines, and finally we also the the property-map access offset as a label
1024             // to jump back to if one of these trampolies finds a match.
1025
1026             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1027
1028             ASSERT(m_codeBlock->structureIDInstructions[structureIDInstructionIndex].opcodeIndex == i);
1029
1030             X86Assembler::JmpDst hotPathBegin = m_jit.label();
1031             m_structureStubCompilationInfo[structureIDInstructionIndex].hotPathBegin = hotPathBegin;
1032             ++structureIDInstructionIndex;
1033
1034             emitJumpSlowCaseIfNotJSCell(X86::eax, i);
1035             m_jit.cmpl_i32m(repatchGetByIdDefaultStructureID, OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
1036             ASSERT(X86Assembler::getDifferenceBetweenLabels(hotPathBegin, m_jit.label()) == repatchOffsetGetByIdStructureID);
1037             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
1038             ASSERT(X86Assembler::getDifferenceBetweenLabels(hotPathBegin, m_jit.label()) == repatchOffsetGetByIdBranchToSlowCase);
1039
1040             m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax);
1041             m_jit.movl_mr(repatchGetByIdDefaultOffset, X86::eax, X86::ecx);
1042             ASSERT(X86Assembler::getDifferenceBetweenLabels(hotPathBegin, m_jit.label()) == repatchOffsetGetByIdPropertyMapOffset);
1043             emitPutResult(instruction[i + 1].u.operand, X86::ecx);
1044
1045             i += 8;
1046             break;
1047         }
1048         case op_instanceof: {
1049             emitGetArg(instruction[i + 2].u.operand, X86::eax); // value
1050             emitGetArg(instruction[i + 3].u.operand, X86::ecx); // baseVal
1051             emitGetArg(instruction[i + 4].u.operand, X86::edx); // proto
1052
1053             // check if any are immediates
1054             m_jit.orl_rr(X86::eax, X86::ecx);
1055             m_jit.orl_rr(X86::edx, X86::ecx);
1056             m_jit.testl_i32r(JSImmediate::TagMask, X86::ecx);
1057
1058             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJnz(), i));
1059
1060             // check that all are object type - this is a bit of a bithack to avoid excess branching;
1061             // we check that the sum of the three type codes from StructureIDs is exactly 3 * ObjectType,
1062             // this works because NumberType and StringType are smaller
1063             m_jit.movl_i32r(3 * ObjectType, X86::ecx);
1064             m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::eax);
1065             m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::edx, X86::edx);
1066             m_jit.subl_mr(OBJECT_OFFSET(StructureID, m_typeInfo.m_type), X86::eax, X86::ecx);
1067             m_jit.subl_mr(OBJECT_OFFSET(StructureID, m_typeInfo.m_type), X86::edx, X86::ecx);
1068             emitGetArg(instruction[i + 3].u.operand, X86::edx); // reload baseVal
1069             m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::edx, X86::edx);
1070             m_jit.cmpl_rm(X86::ecx, OBJECT_OFFSET(StructureID, m_typeInfo.m_type), X86::edx);
1071
1072             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
1073
1074             // check that baseVal's flags include ImplementsHasInstance but not OverridesHasInstance
1075             m_jit.movl_mr(OBJECT_OFFSET(StructureID, m_typeInfo.m_flags), X86::edx, X86::ecx);
1076             m_jit.andl_i32r(ImplementsHasInstance | OverridesHasInstance, X86::ecx);
1077             m_jit.cmpl_i32r(ImplementsHasInstance, X86::ecx);
1078
1079             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
1080
1081             emitGetArg(instruction[i + 2].u.operand, X86::ecx); // reload value
1082             emitGetArg(instruction[i + 4].u.operand, X86::edx); // reload proto
1083
1084             // optimistically load true result
1085             m_jit.movl_i32r(reinterpret_cast<int32_t>(jsBoolean(true)), X86::eax);
1086
1087             X86Assembler::JmpDst loop = m_jit.label();
1088
1089             // load value's prototype
1090             m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::ecx, X86::ecx);
1091             m_jit.movl_mr(OBJECT_OFFSET(StructureID, m_prototype), X86::ecx, X86::ecx);
1092             
1093             m_jit.cmpl_rr(X86::ecx, X86::edx);
1094             X86Assembler::JmpSrc exit = m_jit.emitUnlinkedJe();
1095
1096             m_jit.cmpl_i32r(reinterpret_cast<int32_t>(jsNull()), X86::ecx);
1097             X86Assembler::JmpSrc goToLoop = m_jit.emitUnlinkedJne();
1098             m_jit.link(goToLoop, loop);
1099
1100             m_jit.movl_i32r(reinterpret_cast<int32_t>(jsBoolean(false)), X86::eax);
1101
1102             m_jit.link(exit, m_jit.label());
1103
1104             emitPutResult(instruction[i + 1].u.operand);
1105
1106             i += 5;
1107             break;
1108         }
1109         case op_del_by_id: {
1110             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1111             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
1112             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
1113             emitCall(i, Machine::cti_op_del_by_id);
1114             emitPutResult(instruction[i + 1].u.operand);
1115             i += 4;
1116             break;
1117         }
1118         case op_mul: {
1119             unsigned dst = instruction[i + 1].u.operand;
1120             unsigned src1 = instruction[i + 2].u.operand;
1121             unsigned src2 = instruction[i + 3].u.operand;
1122
1123             if (JSValue* src1Value = getConstantImmediateNumericArg(src1)) {
1124                 emitGetArg(src2, X86::eax);
1125                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
1126                 emitFastArithImmToInt(X86::eax);
1127                 m_jit.imull_i32r(X86::eax, getDeTaggedConstantImmediate(src1Value), X86::eax);
1128                 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
1129                 emitFastArithReTagImmediate(X86::eax);
1130                 emitPutResult(dst);
1131             } else if (JSValue* src2Value = getConstantImmediateNumericArg(src2)) {
1132                 emitGetArg(src1, X86::eax);
1133                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
1134                 emitFastArithImmToInt(X86::eax);
1135                 m_jit.imull_i32r(X86::eax, getDeTaggedConstantImmediate(src2Value), X86::eax);
1136                 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
1137                 emitFastArithReTagImmediate(X86::eax);
1138                 emitPutResult(dst);
1139             } else
1140                 compileBinaryArithOp(op_mul, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
1141
1142             i += 5;
1143             break;
1144         }
1145         case op_new_func: {
1146             FuncDeclNode* func = (m_codeBlock->functions[instruction[i + 2].u.operand]).get();
1147             emitPutArgConstant(reinterpret_cast<unsigned>(func), 0);
1148             emitCall(i, Machine::cti_op_new_func);
1149             emitPutResult(instruction[i + 1].u.operand);
1150             i += 3;
1151             break;
1152         }
1153         case op_call: {
1154             compileOpCall(instruction, i);
1155             i += 7;
1156             break;
1157         }
1158         case op_get_global_var: {
1159             JSVariableObject* globalObject = static_cast<JSVariableObject*>(instruction[i + 2].u.jsCell);
1160             m_jit.movl_i32r(reinterpret_cast<unsigned>(globalObject), X86::eax);
1161             emitGetVariableObjectRegister(X86::eax, instruction[i + 3].u.operand, X86::eax);
1162             emitPutResult(instruction[i + 1].u.operand, X86::eax);
1163             i += 4;
1164             break;
1165         }
1166         case op_put_global_var: {
1167             JSVariableObject* globalObject = static_cast<JSVariableObject*>(instruction[i + 1].u.jsCell);
1168             m_jit.movl_i32r(reinterpret_cast<unsigned>(globalObject), X86::eax);
1169             emitGetArg(instruction[i + 3].u.operand, X86::edx);
1170             emitPutVariableObjectRegister(X86::edx, X86::eax, instruction[i + 2].u.operand);
1171             i += 4;
1172             break;
1173         }
1174         case op_get_scoped_var: {
1175             int skip = instruction[i + 3].u.operand + m_codeBlock->needsFullScopeChain;
1176
1177             emitGetArg(RegisterFile::ScopeChain, X86::eax);
1178             while (skip--)
1179                 m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, next), X86::eax, X86::eax);
1180
1181             m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, object), X86::eax, X86::eax);
1182             emitGetVariableObjectRegister(X86::eax, instruction[i + 2].u.operand, X86::eax);
1183             emitPutResult(instruction[i + 1].u.operand);
1184             i += 4;
1185             break;
1186         }
1187         case op_put_scoped_var: {
1188             int skip = instruction[i + 2].u.operand + m_codeBlock->needsFullScopeChain;
1189
1190             emitGetArg(RegisterFile::ScopeChain, X86::edx);
1191             emitGetArg(instruction[i + 3].u.operand, X86::eax);
1192             while (skip--)
1193                 m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, next), X86::edx, X86::edx);
1194
1195             m_jit.movl_mr(OBJECT_OFFSET(ScopeChainNode, object), X86::edx, X86::edx);
1196             emitPutVariableObjectRegister(X86::eax, X86::edx, instruction[i + 1].u.operand);
1197             i += 4;
1198             break;
1199         }
1200         case op_ret: {
1201             // If there is an activation or an 'arguments' object, we tear it
1202             // off by jumping to the hook below.
1203             m_jit.movl_mr(RegisterFile::OptionalCalleeActivation * static_cast<int>(sizeof(Register)), X86::edi, X86::eax);
1204             m_jit.orl_mr(RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register)), X86::edi, X86::eax);
1205             m_jit.cmpl_i32r(0, X86::eax);
1206             X86Assembler::JmpSrc activation = m_jit.emitUnlinkedJne();
1207             X86Assembler::JmpDst activated = m_jit.label();
1208
1209             // Check for a profiler - if there is one, jump to the hook below.
1210             emitGetCTIParam(CTI_ARGS_profilerReference, X86::eax);
1211             m_jit.cmpl_i32m(0, X86::eax);
1212             X86Assembler::JmpSrc profile = m_jit.emitUnlinkedJne();
1213             X86Assembler::JmpDst profiled = m_jit.label();
1214
1215             // We could JIT generate the deref, only calling out to C when the refcount hits zero.
1216             if (m_codeBlock->needsFullScopeChain)
1217                 emitCall(i, Machine::cti_op_ret_scopeChain);
1218
1219             // Return the result in %eax.
1220             emitGetArg(instruction[i + 1].u.operand, X86::eax);
1221
1222             // Grab the return address.
1223             emitGetArg(RegisterFile::ReturnPC, X86::edx);
1224
1225             // Restore our caller's "r".
1226             emitGetCTIParam(CTI_ARGS_exec, X86::ecx);
1227             emitGetArg(RegisterFile::CallerRegisters, X86::edi);
1228             emitPutCTIParam(X86::edi, CTI_ARGS_r);
1229             m_jit.movl_rm(X86::edi, OBJECT_OFFSET(ExecState, m_callFrame), X86::ecx);
1230
1231             // Return.
1232             m_jit.pushl_r(X86::edx);
1233             m_jit.ret();
1234
1235             // Activation and 'arguments' hook
1236             m_jit.link(activation, m_jit.label());
1237             emitCall(i, Machine::cti_op_ret_activation_arguments);
1238             m_jit.link(m_jit.emitUnlinkedJmp(), activated);
1239
1240             // Profiling hook
1241             m_jit.link(profile, m_jit.label());
1242             emitCall(i, Machine::cti_op_ret_profiler);
1243             m_jit.link(m_jit.emitUnlinkedJmp(), profiled);
1244
1245             i += 2;
1246             break;
1247         }
1248         case op_new_array: {
1249             m_jit.leal_mr(sizeof(Register) * instruction[i + 2].u.operand, X86::edi, X86::edx);
1250             emitPutArg(X86::edx, 0);
1251             emitPutArgConstant(instruction[i + 3].u.operand, 4);
1252             emitCall(i, Machine::cti_op_new_array);
1253             emitPutResult(instruction[i + 1].u.operand);
1254             i += 4;
1255             break;
1256         }
1257         case op_resolve: {
1258             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
1259             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
1260             emitCall(i, Machine::cti_op_resolve);
1261             emitPutResult(instruction[i + 1].u.operand);
1262             i += 3;
1263             break;
1264         }
1265         case op_construct: {
1266             compileOpCall(instruction, i, OpConstruct);
1267             i += 7;
1268             break;
1269         }
1270         case op_construct_verify: {
1271             emitGetArg(instruction[i + 1].u.operand, X86::eax);
1272             
1273             m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
1274             X86Assembler::JmpSrc isImmediate = m_jit.emitUnlinkedJne();
1275             m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::ecx);
1276             m_jit.cmpl_i32m(ObjectType, OBJECT_OFFSET(StructureID, m_typeInfo) + OBJECT_OFFSET(TypeInfo, m_type), X86::ecx);
1277             X86Assembler::JmpSrc isObject = m_jit.emitUnlinkedJe();
1278
1279             m_jit.link(isImmediate, m_jit.label());
1280             emitGetArg(instruction[i + 2].u.operand, X86::ecx);
1281             emitPutResult(instruction[i + 1].u.operand, X86::ecx);
1282             m_jit.link(isObject, m_jit.label());
1283
1284             i += 3;
1285             break;
1286         }
1287         case op_get_by_val: {
1288             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1289             emitGetArg(instruction[i + 3].u.operand, X86::edx);
1290             emitJumpSlowCaseIfNotImmNum(X86::edx, i);
1291             emitFastArithImmToInt(X86::edx);
1292             m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
1293             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
1294             m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsArrayVptr), X86::eax);
1295             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
1296
1297             // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
1298             m_jit.movl_mr(OBJECT_OFFSET(JSArray, m_storage), X86::eax, X86::ecx);
1299             m_jit.cmpl_rm(X86::edx, OBJECT_OFFSET(JSArray, m_fastAccessCutoff), X86::eax);
1300             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJbe(), i));
1301
1302             // Get the value from the vector
1303             m_jit.movl_mr(OBJECT_OFFSET(ArrayStorage, m_vector[0]), X86::ecx, X86::edx, sizeof(JSValue*), X86::eax);
1304             emitPutResult(instruction[i + 1].u.operand);
1305             i += 4;
1306             break;
1307         }
1308         case op_resolve_func: {
1309             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
1310             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
1311             emitCall(i, Machine::cti_op_resolve_func);
1312             emitPutResult(instruction[i + 1].u.operand);
1313             emitGetCTIParam(CTI_ARGS_2ndResult, X86::eax);
1314             emitPutResult(instruction[i + 2].u.operand);
1315             i += 4;
1316             break;
1317         }
1318         case op_sub: {
1319             compileBinaryArithOp(op_sub, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
1320             i += 5;
1321             break;
1322         }
1323         case op_put_by_val: {
1324             emitGetArg(instruction[i + 1].u.operand, X86::eax);
1325             emitGetArg(instruction[i + 2].u.operand, X86::edx);
1326             emitJumpSlowCaseIfNotImmNum(X86::edx, i);
1327             emitFastArithImmToInt(X86::edx);
1328             m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
1329             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
1330             m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsArrayVptr), X86::eax);
1331             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
1332
1333             // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
1334             m_jit.movl_mr(OBJECT_OFFSET(JSArray, m_storage), X86::eax, X86::ecx);
1335             m_jit.cmpl_rm(X86::edx, OBJECT_OFFSET(JSArray, m_fastAccessCutoff), X86::eax);
1336             X86Assembler::JmpSrc inFastVector = m_jit.emitUnlinkedJa();
1337             // No; oh well, check if the access if within the vector - if so, we may still be okay.
1338             m_jit.cmpl_rm(X86::edx, OBJECT_OFFSET(ArrayStorage, m_vectorLength), X86::ecx);
1339             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJbe(), i));
1340
1341             // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location.
1342             // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff. 
1343             m_jit.cmpl_i8m(0, OBJECT_OFFSET(ArrayStorage, m_vector[0]), X86::ecx, X86::edx, sizeof(JSValue*));
1344             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJe(), i));
1345
1346             // All good - put the value into the array.
1347             m_jit.link(inFastVector, m_jit.label());
1348             emitGetArg(instruction[i + 3].u.operand, X86::eax);
1349             m_jit.movl_rm(X86::eax, OBJECT_OFFSET(ArrayStorage, m_vector[0]), X86::ecx, X86::edx, sizeof(JSValue*));
1350             i += 4;
1351             break;
1352         }
1353         CTI_COMPILE_BINARY_OP(op_lesseq)
1354         case op_loop_if_true: {
1355             emitSlowScriptCheck(i);
1356
1357             unsigned target = instruction[i + 2].u.operand;
1358             emitGetArg(instruction[i + 1].u.operand, X86::eax);
1359
1360             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::eax);
1361             X86Assembler::JmpSrc isZero = m_jit.emitUnlinkedJe();
1362             m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
1363             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJne(), i + 2 + target));
1364
1365             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::trueImmediate()), X86::eax);
1366             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
1367             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::falseImmediate()), X86::eax);
1368             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
1369
1370             m_jit.link(isZero, m_jit.label());
1371             i += 3;
1372             break;
1373         };
1374         case op_resolve_base: {
1375             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
1376             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
1377             emitCall(i, Machine::cti_op_resolve_base);
1378             emitPutResult(instruction[i + 1].u.operand);
1379             i += 3;
1380             break;
1381         }
1382         case op_negate: {
1383             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1384             emitCall(i, Machine::cti_op_negate);
1385             emitPutResult(instruction[i + 1].u.operand);
1386             i += 3;
1387             break;
1388         }
1389         case op_resolve_skip: {
1390             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
1391             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
1392             emitPutArgConstant(instruction[i + 3].u.operand + m_codeBlock->needsFullScopeChain, 4);
1393             emitCall(i, Machine::cti_op_resolve_skip);
1394             emitPutResult(instruction[i + 1].u.operand);
1395             i += 4;
1396             break;
1397         }
1398         case op_resolve_global: {
1399             // Fast case
1400             unsigned globalObject = reinterpret_cast<unsigned>(instruction[i + 2].u.jsCell);
1401             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
1402             void* structureIDAddr = reinterpret_cast<void*>(instruction + i + 4);
1403             void* offsetAddr = reinterpret_cast<void*>(instruction + i + 5);
1404
1405             // Check StructureID of global object
1406             m_jit.movl_i32r(globalObject, X86::eax);
1407             m_jit.movl_mr(structureIDAddr, X86::edx);
1408             m_jit.cmpl_rm(X86::edx, OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
1409             X86Assembler::JmpSrc slowCase = m_jit.emitUnlinkedJne(); // StructureIDs don't match
1410             m_slowCases.append(SlowCaseEntry(slowCase, i));
1411
1412             // Load cached property
1413             m_jit.movl_mr(OBJECT_OFFSET(JSGlobalObject, m_propertyStorage), X86::eax, X86::eax);
1414             m_jit.movl_mr(offsetAddr, X86::edx);
1415             m_jit.movl_mr(0, X86::eax, X86::edx, sizeof(JSValue*), X86::eax);
1416             emitPutResult(instruction[i + 1].u.operand);
1417             X86Assembler::JmpSrc end = m_jit.emitUnlinkedJmp();
1418
1419             // Slow case
1420             m_jit.link(slowCase, m_jit.label());
1421             emitPutArgConstant(globalObject, 0);
1422             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
1423             emitPutArgConstant(reinterpret_cast<unsigned>(instruction + i), 8);
1424             emitCall(i, Machine::cti_op_resolve_global);
1425             emitPutResult(instruction[i + 1].u.operand);
1426             m_jit.link(end, m_jit.label());
1427             i += 6;
1428             ++structureIDInstructionIndex;
1429             break;
1430         }
1431         CTI_COMPILE_BINARY_OP(op_div)
1432         case op_pre_dec: {
1433             int srcDst = instruction[i + 1].u.operand;
1434             emitGetArg(srcDst, X86::eax);
1435             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
1436             m_jit.subl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);
1437             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
1438             emitPutResult(srcDst, X86::eax);
1439             i += 2;
1440             break;
1441         }
1442         case op_jnless: {
1443             unsigned target = instruction[i + 3].u.operand;
1444             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
1445             if (src2imm) {
1446                 emitGetArg(instruction[i + 1].u.operand, X86::edx);
1447                 emitJumpSlowCaseIfNotImmNum(X86::edx, i);
1448                 m_jit.cmpl_i32r(reinterpret_cast<unsigned>(src2imm), X86::edx);
1449                 m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJge(), i + 3 + target));
1450             } else {
1451                 emitGetArg(instruction[i + 1].u.operand, X86::eax);
1452                 emitGetArg(instruction[i + 2].u.operand, X86::edx);
1453                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
1454                 emitJumpSlowCaseIfNotImmNum(X86::edx, i);
1455                 m_jit.cmpl_rr(X86::edx, X86::eax);
1456                 m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJge(), i + 3 + target));
1457             }
1458             i += 4;
1459             break;
1460         }
1461         case op_not: {
1462             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1463             m_jit.xorl_i8r(JSImmediate::FullTagTypeBool, X86::eax);
1464             m_jit.testl_i32r(JSImmediate::FullTagTypeMask, X86::eax); // i8?
1465             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
1466             m_jit.xorl_i8r((JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue), X86::eax);
1467             emitPutResult(instruction[i + 1].u.operand);
1468             i += 3;
1469             break;
1470         }
1471         case op_jfalse: {
1472             unsigned target = instruction[i + 2].u.operand;
1473             emitGetArg(instruction[i + 1].u.operand, X86::eax);
1474
1475             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::eax);
1476             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
1477             m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
1478             X86Assembler::JmpSrc isNonZero = m_jit.emitUnlinkedJne();
1479
1480             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::falseImmediate()), X86::eax);
1481             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
1482             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::trueImmediate()), X86::eax);
1483             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
1484
1485             m_jit.link(isNonZero, m_jit.label());
1486             i += 3;
1487             break;
1488         };
1489         case op_post_inc: {
1490             int srcDst = instruction[i + 2].u.operand;
1491             emitGetArg(srcDst, X86::eax);
1492             m_jit.movl_rr(X86::eax, X86::edx);
1493             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
1494             m_jit.addl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::edx);
1495             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
1496             emitPutResult(srcDst, X86::edx);
1497             emitPutResult(instruction[i + 1].u.operand);
1498             i += 3;
1499             break;
1500         }
1501         case op_unexpected_load: {
1502             JSValue* v = m_codeBlock->unexpectedConstants[instruction[i + 2].u.operand];
1503             m_jit.movl_i32r(reinterpret_cast<unsigned>(v), X86::eax);
1504             emitPutResult(instruction[i + 1].u.operand);
1505             i += 3;
1506             break;
1507         }
1508         case op_jsr: {
1509             int retAddrDst = instruction[i + 1].u.operand;
1510             int target = instruction[i + 2].u.operand;
1511             m_jit.movl_i32m(0, sizeof(Register) * retAddrDst, X86::edi);
1512             X86Assembler::JmpDst addrPosition = m_jit.label();
1513             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 2 + target));
1514             X86Assembler::JmpDst sretTarget = m_jit.label();
1515             m_jsrSites.append(JSRInfo(addrPosition, sretTarget));
1516             i += 3;
1517             break;
1518         }
1519         case op_sret: {
1520             m_jit.jmp_m(sizeof(Register) * instruction[i + 1].u.operand, X86::edi);
1521             i += 2;
1522             break;
1523         }
1524         case op_eq: {
1525             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1526             emitGetArg(instruction[i + 3].u.operand, X86::edx);
1527             emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i);
1528             m_jit.cmpl_rr(X86::edx, X86::eax);
1529             m_jit.sete_r(X86::eax);
1530             m_jit.movzbl_rr(X86::eax, X86::eax);
1531             emitTagAsBoolImmediate(X86::eax);
1532             emitPutResult(instruction[i + 1].u.operand);
1533             i += 4;
1534             break;
1535         }
1536         case op_lshift: {
1537             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1538             emitGetArg(instruction[i + 3].u.operand, X86::ecx);
1539             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
1540             emitJumpSlowCaseIfNotImmNum(X86::ecx, i);
1541             emitFastArithImmToInt(X86::eax);
1542             emitFastArithImmToInt(X86::ecx);
1543             m_jit.shll_CLr(X86::eax);
1544             emitFastArithIntToImmOrSlowCase(X86::eax, i);
1545             emitPutResult(instruction[i + 1].u.operand);
1546             i += 4;
1547             break;
1548         }
1549         case op_bitand: {
1550             unsigned src1 = instruction[i + 2].u.operand;
1551             unsigned src2 = instruction[i + 3].u.operand;
1552             unsigned dst = instruction[i + 1].u.operand;
1553             if (JSValue* value = getConstantImmediateNumericArg(src1)) {
1554                 emitGetArg(src2, X86::eax);
1555                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
1556                 m_jit.andl_i32r(reinterpret_cast<unsigned>(value), X86::eax); // FIXME: make it more obvious this is relying on the format of JSImmediate
1557                 emitPutResult(dst);
1558             } else if (JSValue* value = getConstantImmediateNumericArg(src2)) {
1559                 emitGetArg(src1, X86::eax);
1560                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
1561                 m_jit.andl_i32r(reinterpret_cast<unsigned>(value), X86::eax);
1562                 emitPutResult(dst);
1563             } else {
1564                 emitGetArg(src1, X86::eax);
1565                 emitGetArg(src2, X86::edx);
1566                 m_jit.andl_rr(X86::edx, X86::eax);
1567                 emitJumpSlowCaseIfNotImmNum(X86::eax, i);
1568                 emitPutResult(dst);
1569             }
1570             i += 5;
1571             break;
1572         }
1573         case op_rshift: {
1574             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1575             emitGetArg(instruction[i + 3].u.operand, X86::ecx);
1576             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
1577             emitJumpSlowCaseIfNotImmNum(X86::ecx, i);
1578             emitFastArithImmToInt(X86::ecx);
1579             m_jit.sarl_CLr(X86::eax);
1580             emitFastArithPotentiallyReTagImmediate(X86::eax);
1581             emitPutResult(instruction[i + 1].u.operand);
1582             i += 4;
1583             break;
1584         }
1585         case op_bitnot: {
1586             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1587             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
1588             m_jit.xorl_i8r(~JSImmediate::TagBitTypeInteger, X86::eax);
1589             emitPutResult(instruction[i + 1].u.operand);
1590             i += 3;
1591             break;
1592         }
1593         case op_resolve_with_base: {
1594             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
1595             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
1596             emitCall(i, Machine::cti_op_resolve_with_base);
1597             emitPutResult(instruction[i + 1].u.operand);
1598             emitGetCTIParam(CTI_ARGS_2ndResult, X86::eax);
1599             emitPutResult(instruction[i + 2].u.operand);
1600             i += 4;
1601             break;
1602         }
1603         case op_new_func_exp: {
1604             FuncExprNode* func = (m_codeBlock->functionExpressions[instruction[i + 2].u.operand]).get();
1605             emitPutArgConstant(reinterpret_cast<unsigned>(func), 0);
1606             emitCall(i, Machine::cti_op_new_func_exp);
1607             emitPutResult(instruction[i + 1].u.operand);
1608             i += 3;
1609             break;
1610         }
1611         case op_mod: {
1612             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1613             emitGetArg(instruction[i + 3].u.operand, X86::ecx);
1614             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
1615             emitJumpSlowCaseIfNotImmNum(X86::ecx, i);
1616             emitFastArithDeTagImmediate(X86::eax);
1617             emitFastArithDeTagImmediate(X86::ecx);
1618             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJe(), i)); // This is checking if the last detag resulted in a value 0.
1619             m_jit.cdq();
1620             m_jit.idivl_r(X86::ecx);
1621             emitFastArithReTagImmediate(X86::edx);
1622             m_jit.movl_rr(X86::edx, X86::eax);
1623             emitPutResult(instruction[i + 1].u.operand);
1624             i += 4;
1625             break;
1626         }
1627         case op_jtrue: {
1628             unsigned target = instruction[i + 2].u.operand;
1629             emitGetArg(instruction[i + 1].u.operand, X86::eax);
1630
1631             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::eax);
1632             X86Assembler::JmpSrc isZero = m_jit.emitUnlinkedJe();
1633             m_jit.testl_i32r(JSImmediate::TagBitTypeInteger, X86::eax);
1634             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJne(), i + 2 + target));
1635
1636             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::trueImmediate()), X86::eax);
1637             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJe(), i + 2 + target));
1638             m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::falseImmediate()), X86::eax);
1639             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
1640
1641             m_jit.link(isZero, m_jit.label());
1642             i += 3;
1643             break;
1644         }
1645         CTI_COMPILE_BINARY_OP(op_less)
1646         case op_neq: {
1647             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1648             emitGetArg(instruction[i + 3].u.operand, X86::edx);
1649             emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i);
1650             m_jit.cmpl_rr(X86::eax, X86::edx);
1651
1652             m_jit.setne_r(X86::eax);
1653             m_jit.movzbl_rr(X86::eax, X86::eax);
1654             emitTagAsBoolImmediate(X86::eax);
1655
1656             emitPutResult(instruction[i + 1].u.operand);
1657
1658             i += 4;
1659             break;
1660         }
1661         case op_post_dec: {
1662             int srcDst = instruction[i + 2].u.operand;
1663             emitGetArg(srcDst, X86::eax);
1664             m_jit.movl_rr(X86::eax, X86::edx);
1665             emitJumpSlowCaseIfNotImmNum(X86::eax, i);
1666             m_jit.subl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::edx);
1667             m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJo(), i));
1668             emitPutResult(srcDst, X86::edx);
1669             emitPutResult(instruction[i + 1].u.operand);
1670             i += 3;
1671             break;
1672         }
1673         CTI_COMPILE_BINARY_OP(op_urshift)
1674         case op_bitxor: {
1675             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1676             emitGetArg(instruction[i + 3].u.operand, X86::edx);
1677             emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i);
1678             m_jit.xorl_rr(X86::edx, X86::eax);
1679             emitFastArithReTagImmediate(X86::eax);
1680             emitPutResult(instruction[i + 1].u.operand);
1681             i += 5;
1682             break;
1683         }
1684         case op_new_regexp: {
1685             RegExp* regExp = m_codeBlock->regexps[instruction[i + 2].u.operand].get();
1686             emitPutArgConstant(reinterpret_cast<unsigned>(regExp), 0);
1687             emitCall(i, Machine::cti_op_new_regexp);
1688             emitPutResult(instruction[i + 1].u.operand);
1689             i += 3;
1690             break;
1691         }
1692         case op_bitor: {
1693             emitGetArg(instruction[i + 2].u.operand, X86::eax);
1694             emitGetArg(instruction[i + 3].u.operand, X86::edx);
1695             emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i);
1696             m_jit.orl_rr(X86::edx, X86::eax);
1697             emitPutResult(instruction[i + 1].u.operand);
1698             i += 5;
1699             break;
1700         }
1701         case op_call_eval: {
1702             compileOpCall(instruction, i, OpCallEval);
1703             i += 7;
1704             break;
1705         }
1706         case op_throw: {
1707             emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
1708             emitCall(i, Machine::cti_op_throw);
1709             m_jit.addl_i8r(0x24, X86::esp);
1710             m_jit.popl_r(X86::edi);
1711             m_jit.popl_r(X86::esi);
1712             m_jit.ret();
1713             i += 2;
1714             break;
1715         }
1716         case op_get_pnames: {
1717             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1718             emitCall(i, Machine::cti_op_get_pnames);
1719             emitPutResult(instruction[i + 1].u.operand);
1720             i += 3;
1721             break;
1722         }
1723         case op_next_pname: {
1724             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1725             unsigned target = instruction[i + 3].u.operand;
1726             emitCall(i, Machine::cti_op_next_pname);
1727             m_jit.testl_rr(X86::eax, X86::eax);
1728             X86Assembler::JmpSrc endOfIter = m_jit.emitUnlinkedJe();
1729             emitPutResult(instruction[i + 1].u.operand);
1730             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 3 + target));
1731             m_jit.link(endOfIter, m_jit.label());
1732             i += 4;
1733             break;
1734         }
1735         case op_push_scope: {
1736             emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
1737             emitCall(i, Machine::cti_op_push_scope);
1738             i += 2;
1739             break;
1740         }
1741         case op_pop_scope: {
1742             emitCall(i, Machine::cti_op_pop_scope);
1743             i += 1;
1744             break;
1745         }
1746         CTI_COMPILE_UNARY_OP(op_typeof)
1747         CTI_COMPILE_UNARY_OP(op_is_undefined)
1748         CTI_COMPILE_UNARY_OP(op_is_boolean)
1749         CTI_COMPILE_UNARY_OP(op_is_number)
1750         CTI_COMPILE_UNARY_OP(op_is_string)
1751         CTI_COMPILE_UNARY_OP(op_is_object)
1752         CTI_COMPILE_UNARY_OP(op_is_function)
1753         case op_stricteq: {
1754             compileOpStrictEq(instruction, i, OpStrictEq);
1755             i += 4;
1756             break;
1757         }
1758         case op_nstricteq: {
1759             compileOpStrictEq(instruction, i, OpNStrictEq);
1760             i += 4;
1761             break;
1762         }
1763         case op_to_jsnumber: {
1764             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1765             emitCall(i, Machine::cti_op_to_jsnumber);
1766             emitPutResult(instruction[i + 1].u.operand);
1767             i += 3;
1768             break;
1769         }
1770         case op_in: {
1771             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1772             emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
1773             emitCall(i, Machine::cti_op_in);
1774             emitPutResult(instruction[i + 1].u.operand);
1775             i += 4;
1776             break;
1777         }
1778         case op_push_new_scope: {
1779             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
1780             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
1781             emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
1782             emitCall(i, Machine::cti_op_push_new_scope);
1783             emitPutResult(instruction[i + 1].u.operand);
1784             i += 4;
1785             break;
1786         }
1787         case op_catch: {
1788             emitGetCTIParam(CTI_ARGS_r, X86::edi); // edi := r
1789             emitGetCTIParam(CTI_ARGS_exec, X86::ecx);
1790             m_jit.movl_mr(OBJECT_OFFSET(ExecState, m_exception), X86::ecx, X86::eax);
1791             m_jit.movl_i32m(0, OBJECT_OFFSET(ExecState, m_exception), X86::ecx);
1792             emitPutResult(instruction[i + 1].u.operand);
1793             i += 2;
1794             break;
1795         }
1796         case op_jmp_scopes: {
1797             unsigned count = instruction[i + 1].u.operand;
1798             emitPutArgConstant(count, 0);
1799             emitCall(i, Machine::cti_op_jmp_scopes);
1800             unsigned target = instruction[i + 2].u.operand;
1801             m_jmpTable.append(JmpTable(m_jit.emitUnlinkedJmp(), i + 2 + target));
1802             i += 3;
1803             break;
1804         }
1805         case op_put_by_index: {
1806             emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
1807             emitPutArgConstant(instruction[i + 2].u.operand, 4);
1808             emitGetPutArg(instruction[i + 3].u.operand, 8, X86::ecx);
1809             emitCall(i, Machine::cti_op_put_by_index);
1810             i += 4;
1811             break;
1812         }
1813         case op_switch_imm: {
1814             unsigned tableIndex = instruction[i + 1].u.operand;
1815             unsigned defaultOffset = instruction[i + 2].u.operand;
1816             unsigned scrutinee = instruction[i + 3].u.operand;
1817
1818             // create jump table for switch destinations, track this switch statement.
1819             SimpleJumpTable* jumpTable = &m_codeBlock->immediateSwitchJumpTables[tableIndex];
1820             m_switches.append(SwitchRecord(jumpTable, i, defaultOffset, SwitchRecord::Immediate));
1821             jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
1822
1823             emitGetPutArg(scrutinee, 0, X86::ecx);
1824             emitPutArgConstant(tableIndex, 4);
1825             emitCall(i, Machine::cti_op_switch_imm);
1826             m_jit.jmp_r(X86::eax);
1827             i += 4;
1828             break;
1829         }
1830         case op_switch_char: {
1831             unsigned tableIndex = instruction[i + 1].u.operand;
1832             unsigned defaultOffset = instruction[i + 2].u.operand;
1833             unsigned scrutinee = instruction[i + 3].u.operand;
1834
1835             // create jump table for switch destinations, track this switch statement.
1836             SimpleJumpTable* jumpTable = &m_codeBlock->characterSwitchJumpTables[tableIndex];
1837             m_switches.append(SwitchRecord(jumpTable, i, defaultOffset, SwitchRecord::Character));
1838             jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
1839
1840             emitGetPutArg(scrutinee, 0, X86::ecx);
1841             emitPutArgConstant(tableIndex, 4);
1842             emitCall(i, Machine::cti_op_switch_char);
1843             m_jit.jmp_r(X86::eax);
1844             i += 4;
1845             break;
1846         }
1847         case op_switch_string: {
1848             unsigned tableIndex = instruction[i + 1].u.operand;
1849             unsigned defaultOffset = instruction[i + 2].u.operand;
1850             unsigned scrutinee = instruction[i + 3].u.operand;
1851
1852             // create jump table for switch destinations, track this switch statement.
1853             StringJumpTable* jumpTable = &m_codeBlock->stringSwitchJumpTables[tableIndex];
1854             m_switches.append(SwitchRecord(jumpTable, i, defaultOffset));
1855
1856             emitGetPutArg(scrutinee, 0, X86::ecx);
1857             emitPutArgConstant(tableIndex, 4);
1858             emitCall(i, Machine::cti_op_switch_string);
1859             m_jit.jmp_r(X86::eax);
1860             i += 4;
1861             break;
1862         }
1863         case op_del_by_val: {
1864             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
1865             emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
1866             emitCall(i, Machine::cti_op_del_by_val);
1867             emitPutResult(instruction[i + 1].u.operand);
1868             i += 4;
1869             break;
1870         }
1871         case op_put_getter: {
1872             emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
1873             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
1874             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
1875             emitGetPutArg(instruction[i + 3].u.operand, 8, X86::ecx);
1876             emitCall(i, Machine::cti_op_put_getter);
1877             i += 4;
1878             break;
1879         }
1880         case op_put_setter: {
1881             emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
1882             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
1883             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
1884             emitGetPutArg(instruction[i + 3].u.operand, 8, X86::ecx);
1885             emitCall(i, Machine::cti_op_put_setter);
1886             i += 4;
1887             break;
1888         }
1889         case op_new_error: {
1890             JSValue* message = m_codeBlock->unexpectedConstants[instruction[i + 3].u.operand];
1891             emitPutArgConstant(instruction[i + 2].u.operand, 0);
1892             emitPutArgConstant(reinterpret_cast<unsigned>(message), 4);
1893             emitPutArgConstant(m_codeBlock->lineNumberForVPC(&instruction[i]), 8);
1894             emitCall(i, Machine::cti_op_new_error);
1895             emitPutResult(instruction[i + 1].u.operand);
1896             i += 4;
1897             break;
1898         }
1899         case op_debug: {
1900             emitPutArgConstant(instruction[i + 1].u.operand, 0);
1901             emitPutArgConstant(instruction[i + 2].u.operand, 4);
1902             emitPutArgConstant(instruction[i + 3].u.operand, 8);
1903             emitCall(i, Machine::cti_op_debug);
1904             i += 4;
1905             break;
1906         }
1907         case op_eq_null: {
1908             unsigned dst = instruction[i + 1].u.operand;
1909             unsigned src1 = instruction[i + 2].u.operand;
1910
1911             emitGetArg(src1, X86::eax);
1912             m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
1913             X86Assembler::JmpSrc isImmediate = m_jit.emitUnlinkedJnz();
1914
1915             m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::ecx);
1916             m_jit.testl_i32m(MasqueradesAsUndefined, OBJECT_OFFSET(StructureID, m_typeInfo.m_flags), X86::ecx);
1917             m_jit.setnz_r(X86::eax);
1918
1919             X86Assembler::JmpSrc wasNotImmediate = m_jit.emitUnlinkedJmp();
1920
1921             m_jit.link(isImmediate, m_jit.label());
1922
1923             m_jit.movl_i32r(~JSImmediate::ExtendedTagBitUndefined, X86::ecx);
1924             m_jit.andl_rr(X86::eax, X86::ecx);
1925             m_jit.cmpl_i32r(JSImmediate::FullTagTypeNull, X86::ecx);
1926             m_jit.sete_r(X86::eax);
1927
1928             m_jit.link(wasNotImmediate, m_jit.label());
1929
1930             m_jit.movzbl_rr(X86::eax, X86::eax);
1931             emitTagAsBoolImmediate(X86::eax);
1932             emitPutResult(dst);
1933
1934             i += 3;
1935             break;
1936         }
1937         case op_neq_null: {
1938             unsigned dst = instruction[i + 1].u.operand;
1939             unsigned src1 = instruction[i + 2].u.operand;
1940
1941             emitGetArg(src1, X86::eax);
1942             m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
1943             X86Assembler::JmpSrc isImmediate = m_jit.emitUnlinkedJnz();
1944
1945             m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::ecx);
1946             m_jit.testl_i32m(MasqueradesAsUndefined, OBJECT_OFFSET(StructureID, m_typeInfo.m_flags), X86::ecx);
1947             m_jit.setz_r(X86::eax);
1948
1949             X86Assembler::JmpSrc wasNotImmediate = m_jit.emitUnlinkedJmp();
1950
1951             m_jit.link(isImmediate, m_jit.label());
1952
1953             m_jit.movl_i32r(~JSImmediate::ExtendedTagBitUndefined, X86::ecx);
1954             m_jit.andl_rr(X86::eax, X86::ecx);
1955             m_jit.cmpl_i32r(JSImmediate::FullTagTypeNull, X86::ecx);
1956             m_jit.setne_r(X86::eax);
1957
1958             m_jit.link(wasNotImmediate, m_jit.label());
1959
1960             m_jit.movzbl_rr(X86::eax, X86::eax);
1961             emitTagAsBoolImmediate(X86::eax);
1962             emitPutResult(dst);
1963
1964             i += 3;
1965             break;
1966         }
1967         case op_init: {
1968             // Even though CTI doesn't use them, we initialize our constant
1969             // registers to zap stale pointers, to avoid unnecessarily prolonging
1970             // object lifetime and increasing GC pressure.
1971             size_t count = m_codeBlock->numVars + m_codeBlock->constantRegisters.size();
1972             for (size_t j = 0; j < count; ++j)
1973                 emitInitRegister(j);
1974
1975             i+= 1;
1976             break;
1977         }
1978         case op_init_activation: {
1979             emitCall(i, Machine::cti_op_push_activation);
1980
1981             // Even though CTI doesn't use them, we initialize our constant
1982             // registers to zap stale pointers, to avoid unnecessarily prolonging
1983             // object lifetime and increasing GC pressure.
1984             size_t count = m_codeBlock->numVars + m_codeBlock->constantRegisters.size();
1985             for (size_t j = 0; j < count; ++j)
1986                 emitInitRegister(j);
1987
1988             i+= 1;
1989             break;
1990         }
1991         case op_init_arguments: {
1992             emitCall(i, Machine::cti_op_init_arguments);
1993             i += 1;
1994             break;
1995         }
1996         case op_get_array_length:
1997         case op_get_by_id_chain:
1998         case op_get_by_id_generic:
1999         case op_get_by_id_proto:
2000         case op_get_by_id_self:
2001         case op_get_string_length:
2002         case op_put_by_id_generic:
2003         case op_put_by_id_replace:
2004         case op_put_by_id_transition:
2005             ASSERT_NOT_REACHED();
2006         }
2007     }
2008
2009     ASSERT(structureIDInstructionIndex == m_codeBlock->structureIDInstructions.size());
2010 }
2011
2012
2013 void CTI::privateCompileLinkPass()
2014 {
2015     unsigned jmpTableCount = m_jmpTable.size();
2016     for (unsigned i = 0; i < jmpTableCount; ++i)
2017         m_jit.link(m_jmpTable[i].from, m_labels[m_jmpTable[i].to]);
2018     m_jmpTable.clear();
2019 }
2020
2021 #define CTI_COMPILE_BINARY_OP_SLOW_CASE(name) \
2022     case name: { \
2023         m_jit.link(iter->from, m_jit.label()); \
2024         emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx); \
2025         emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx); \
2026         emitCall(i, Machine::cti_##name); \
2027         emitPutResult(instruction[i + 1].u.operand); \
2028         i += 4; \
2029         break; \
2030     }
2031     
2032 void CTI::privateCompileSlowCases()
2033 {
2034     unsigned structureIDInstructionIndex = 0;
2035
2036     Instruction* instruction = m_codeBlock->instructions.begin();
2037     for (Vector<SlowCaseEntry>::iterator iter = m_slowCases.begin(); iter != m_slowCases.end(); ++iter) {
2038         unsigned i = iter->to;
2039         switch (m_machine->getOpcodeID(instruction[i].u.opcode)) {
2040         case op_add: {
2041             unsigned dst = instruction[i + 1].u.operand;
2042             unsigned src1 = instruction[i + 2].u.operand;
2043             unsigned src2 = instruction[i + 3].u.operand;
2044             if (JSValue* value = getConstantImmediateNumericArg(src1)) {
2045                 X86Assembler::JmpSrc notImm = iter->from;
2046                 m_jit.link((++iter)->from, m_jit.label());
2047                 m_jit.subl_i32r(getDeTaggedConstantImmediate(value), X86::edx);
2048                 m_jit.link(notImm, m_jit.label());
2049                 emitGetPutArg(src1, 0, X86::ecx);
2050                 emitPutArg(X86::edx, 4);
2051                 emitCall(i, Machine::cti_op_add);
2052                 emitPutResult(dst);
2053             } else if (JSValue* value = getConstantImmediateNumericArg(src2)) {
2054                 X86Assembler::JmpSrc notImm = iter->from;
2055                 m_jit.link((++iter)->from, m_jit.label());
2056                 m_jit.subl_i32r(getDeTaggedConstantImmediate(value), X86::eax);
2057                 m_jit.link(notImm, m_jit.label());
2058                 emitPutArg(X86::eax, 0);
2059                 emitGetPutArg(src2, 4, X86::ecx);
2060                 emitCall(i, Machine::cti_op_add);
2061                 emitPutResult(dst);
2062             } else {
2063                 OperandTypes types = OperandTypes::fromInt(instruction[i + 4].u.operand);
2064                 if (types.first().mightBeNumber() && types.second().mightBeNumber())
2065                     compileBinaryArithOpSlowCase(op_add, iter, dst, src1, src2, types, i);
2066                 else
2067                     ASSERT_NOT_REACHED();
2068             }
2069
2070             i += 5;
2071             break;
2072         }
2073         case op_get_by_val: {
2074             // The slow case that handles accesses to arrays (below) may jump back up to here. 
2075             X86Assembler::JmpDst beginGetByValSlow = m_jit.label();
2076
2077             X86Assembler::JmpSrc notImm = iter->from;
2078             m_jit.link((++iter)->from, m_jit.label());
2079             m_jit.link((++iter)->from, m_jit.label());
2080             emitFastArithIntToImmNoCheck(X86::edx);
2081             m_jit.link(notImm, m_jit.label());
2082             emitPutArg(X86::eax, 0);
2083             emitPutArg(X86::edx, 4);
2084             emitCall(i, Machine::cti_op_get_by_val);
2085             emitPutResult(instruction[i + 1].u.operand);
2086             m_jit.link(m_jit.emitUnlinkedJmp(), m_labels[i + 4]);
2087
2088             // This is slow case that handles accesses to arrays above the fast cut-off.
2089             // First, check if this is an access to the vector
2090             m_jit.link((++iter)->from, m_jit.label());
2091             m_jit.cmpl_rm(X86::edx, OBJECT_OFFSET(ArrayStorage, m_vectorLength), X86::ecx);
2092             m_jit.link(m_jit.emitUnlinkedJbe(), beginGetByValSlow);
2093
2094             // okay, missed the fast region, but it is still in the vector.  Get the value.
2095             m_jit.movl_mr(OBJECT_OFFSET(ArrayStorage, m_vector[0]), X86::ecx, X86::edx, sizeof(JSValue*), X86::ecx);
2096             // Check whether the value loaded is zero; if so we need to return undefined.
2097             m_jit.testl_rr(X86::ecx, X86::ecx);
2098             m_jit.link(m_jit.emitUnlinkedJe(), beginGetByValSlow);
2099             emitPutResult(instruction[i + 1].u.operand, X86::ecx);
2100             
2101             i += 4;
2102             break;
2103         }
2104         case op_sub: {
2105             compileBinaryArithOpSlowCase(op_sub, iter, instruction[i + 1].u.operand, instruction[i + 2].u.operand, instruction[i + 3].u.operand, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
2106             i += 5;
2107             break;
2108         }
2109         case op_rshift: {
2110             m_jit.link(iter->from, m_jit.label());
2111             m_jit.link((++iter)->from, m_jit.label());
2112             emitPutArg(X86::eax, 0);
2113             emitPutArg(X86::ecx, 4);
2114             emitCall(i, Machine::cti_op_rshift);
2115             emitPutResult(instruction[i + 1].u.operand);
2116             i += 4;
2117             break;
2118         }
2119         case op_lshift: {
2120             X86Assembler::JmpSrc notImm1 = iter->from;
2121             X86Assembler::JmpSrc notImm2 = (++iter)->from;
2122             m_jit.link((++iter)->from, m_jit.label());
2123             emitGetArg(instruction[i + 2].u.operand, X86::eax);
2124             emitGetArg(instruction[i + 3].u.operand, X86::ecx);
2125             m_jit.link(notImm1, m_jit.label());
2126             m_jit.link(notImm2, m_jit.label());
2127             emitPutArg(X86::eax, 0);
2128             emitPutArg(X86::ecx, 4);
2129             emitCall(i, Machine::cti_op_lshift);
2130             emitPutResult(instruction[i + 1].u.operand);
2131             i += 4;
2132             break;
2133         }
2134         case op_loop_if_less: {
2135             emitSlowScriptCheck(i);
2136
2137             unsigned target = instruction[i + 3].u.operand;
2138             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
2139             if (src2imm) {
2140                 m_jit.link(iter->from, m_jit.label());
2141                 emitPutArg(X86::edx, 0);
2142                 emitGetPutArg(instruction[i + 2].u.operand, 4, X86::ecx);
2143                 emitCall(i, Machine::cti_op_loop_if_less);
2144                 m_jit.testl_rr(X86::eax, X86::eax);
2145                 m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 3 + target]);
2146             } else {
2147                 m_jit.link(iter->from, m_jit.label());
2148                 m_jit.link((++iter)->from, m_jit.label());
2149                 emitPutArg(X86::eax, 0);
2150                 emitPutArg(X86::edx, 4);
2151                 emitCall(i, Machine::cti_op_loop_if_less);
2152                 m_jit.testl_rr(X86::eax, X86::eax);
2153                 m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 3 + target]);
2154             }
2155             i += 4;
2156             break;
2157         }
2158         case op_put_by_id: {
2159             m_jit.link(iter->from, m_jit.label());
2160             m_jit.link((++iter)->from, m_jit.label());
2161
2162             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u.operand]);
2163             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
2164             emitPutArg(X86::eax, 0);
2165             emitPutArg(X86::edx, 8);
2166             X86Assembler::JmpSrc call = emitCall(i, Machine::cti_op_put_by_id);
2167
2168             // Track the location of the call; this will be used to recover repatch information.
2169             ASSERT(m_codeBlock->structureIDInstructions[structureIDInstructionIndex].opcodeIndex == i);
2170             m_structureStubCompilationInfo[structureIDInstructionIndex].callReturnLocation = call;
2171             ++structureIDInstructionIndex;
2172
2173             i += 8;
2174             break;
2175         }
2176         case op_get_by_id: {
2177             // As for the hot path of get_by_id, above, we ensure that we can use an architecture specific offset
2178             // so that we only need track one pointer into the slow case code - we track a pointer to the location
2179             // of the call (which we can use to look up the repatch information), but should a array-length or
2180             // prototype access trampoline fail we want to bail out back to here.  To do so we can subtract back
2181             // the distance from the call to the head of the slow case.
2182
2183             m_jit.link(iter->from, m_jit.label());
2184             m_jit.link((++iter)->from, m_jit.label());
2185
2186 #ifndef NDEBUG
2187             X86Assembler::JmpDst coldPathBegin = m_jit.label();
2188 #endif        
2189             emitPutArg(X86::eax, 0);
2190             Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 3].u.operand]);
2191             emitPutArgConstant(reinterpret_cast<unsigned>(ident), 4);
2192             X86Assembler::JmpSrc call = emitCall(i, Machine::cti_op_get_by_id);
2193             ASSERT(X86Assembler::getDifferenceBetweenLabels(coldPathBegin, call) == repatchOffsetGetByIdSlowCaseCall);
2194             emitPutResult(instruction[i + 1].u.operand);
2195
2196             // Track the location of the call; this will be used to recover repatch information.
2197             ASSERT(m_codeBlock->structureIDInstructions[structureIDInstructionIndex].opcodeIndex == i);
2198             m_structureStubCompilationInfo[structureIDInstructionIndex].callReturnLocation = call;
2199             ++structureIDInstructionIndex;
2200
2201             i += 8;
2202             break;
2203         }
2204         case op_resolve_global: {
2205             ++structureIDInstructionIndex;
2206             i += 6;
2207             break;
2208         }
2209         case op_loop_if_lesseq: {
2210             emitSlowScriptCheck(i);
2211
2212             unsigned target = instruction[i + 3].u.operand;
2213             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
2214             if (src2imm) {
2215                 m_jit.link(iter->from, m_jit.label());
2216                 emitPutArg(X86::edx, 0);
2217                 emitGetPutArg(instruction[i + 2].u.operand, 4, X86::ecx);
2218                 emitCall(i, Machine::cti_op_loop_if_lesseq);
2219                 m_jit.testl_rr(X86::eax, X86::eax);
2220                 m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 3 + target]);
2221             } else {
2222                 m_jit.link(iter->from, m_jit.label());
2223                 m_jit.link((++iter)->from, m_jit.label());
2224                 emitPutArg(X86::eax, 0);
2225                 emitPutArg(X86::edx, 4);
2226                 emitCall(i, Machine::cti_op_loop_if_lesseq);
2227                 m_jit.testl_rr(X86::eax, X86::eax);
2228                 m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 3 + target]);
2229             }
2230             i += 4;
2231             break;
2232         }
2233         case op_pre_inc: {
2234             unsigned srcDst = instruction[i + 1].u.operand;
2235             X86Assembler::JmpSrc notImm = iter->from;
2236             m_jit.link((++iter)->from, m_jit.label());
2237             m_jit.subl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);
2238             m_jit.link(notImm, m_jit.label());
2239             emitPutArg(X86::eax, 0);
2240             emitCall(i, Machine::cti_op_pre_inc);
2241             emitPutResult(srcDst);
2242             i += 2;
2243             break;
2244         }
2245         case op_put_by_val: {
2246             // Normal slow cases - either is not an immediate imm, or is an array.
2247             X86Assembler::JmpSrc notImm = iter->from;
2248             m_jit.link((++iter)->from, m_jit.label());
2249             m_jit.link((++iter)->from, m_jit.label());
2250             emitFastArithIntToImmNoCheck(X86::edx);
2251             m_jit.link(notImm, m_jit.label());
2252             emitGetArg(instruction[i + 3].u.operand, X86::ecx);
2253             emitPutArg(X86::eax, 0);
2254             emitPutArg(X86::edx, 4);
2255             emitPutArg(X86::ecx, 8);
2256             emitCall(i, Machine::cti_op_put_by_val);
2257             m_jit.link(m_jit.emitUnlinkedJmp(), m_labels[i + 4]);
2258
2259             // slow cases for immediate int accesses to arrays
2260             m_jit.link((++iter)->from, m_jit.label());
2261             m_jit.link((++iter)->from, m_jit.label());
2262             emitGetArg(instruction[i + 3].u.operand, X86::ecx);
2263             emitPutArg(X86::eax, 0);
2264             emitPutArg(X86::edx, 4);
2265             emitPutArg(X86::ecx, 8);
2266             emitCall(i, Machine::cti_op_put_by_val_array);
2267
2268             i += 4;
2269             break;
2270         }
2271         case op_loop_if_true: {
2272             emitSlowScriptCheck(i);
2273
2274             m_jit.link(iter->from, m_jit.label());
2275             emitPutArg(X86::eax, 0);
2276             emitCall(i, Machine::cti_op_jtrue);
2277             m_jit.testl_rr(X86::eax, X86::eax);
2278             unsigned target = instruction[i + 2].u.operand;
2279             m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 2 + target]);
2280             i += 3;
2281             break;
2282         }
2283         case op_pre_dec: {
2284             unsigned srcDst = instruction[i + 1].u.operand;
2285             X86Assembler::JmpSrc notImm = iter->from;
2286             m_jit.link((++iter)->from, m_jit.label());
2287             m_jit.addl_i8r(getDeTaggedConstantImmediate(JSImmediate::oneImmediate()), X86::eax);
2288             m_jit.link(notImm, m_jit.label());
2289             emitPutArg(X86::eax, 0);
2290             emitCall(i, Machine::cti_op_pre_dec);
2291             emitPutResult(srcDst);
2292             i += 2;
2293             break;
2294         }
2295         case op_jnless: {
2296             unsigned target = instruction[i + 3].u.operand;
2297             JSValue* src2imm = getConstantImmediateNumericArg(instruction[i + 2].u.operand);
2298             if (src2imm) {
2299                 m_jit.link(iter->from, m_jit.label());
2300                 emitPutArg(X86::edx, 0);
2301                 emitGetPutArg(instruction[i + 2].u.operand, 4, X86::ecx);
2302                 emitCall(i, Machine::cti_op_jless);
2303                 m_jit.testl_rr(X86::eax, X86::eax);
2304                 m_jit.link(m_jit.emitUnlinkedJe(), m_labels[i + 3 + target]);
2305             } else {
2306                 m_jit.link(iter->from, m_jit.label());
2307                 m_jit.link((++iter)->from, m_jit.label());
2308                 emitPutArg(X86::eax, 0);
2309                 emitPutArg(X86::edx, 4);
2310                 emitCall(i, Machine::cti_op_jless);
2311                 m_jit.testl_rr(X86::eax, X86::eax);
2312                 m_jit.link(m_jit.emitUnlinkedJe(), m_labels[i + 3 + target]);
2313             }
2314             i += 4;
2315             break;
2316         }
2317         case op_not: {
2318             m_jit.link(iter->from, m_jit.label());
2319             m_jit.xorl_i8r(JSImmediate::FullTagTypeBool, X86::eax);
2320             emitPutArg(X86::eax, 0);
2321             emitCall(i, Machine::cti_op_not);
2322             emitPutResult(instruction[i + 1].u.operand);
2323             i += 3;
2324             break;
2325         }
2326         case op_jfalse: {
2327             m_jit.link(iter->from, m_jit.label());
2328             emitPutArg(X86::eax, 0);
2329             emitCall(i, Machine::cti_op_jtrue);
2330             m_jit.testl_rr(X86::eax, X86::eax);
2331             unsigned target = instruction[i + 2].u.operand;
2332             m_jit.link(m_jit.emitUnlinkedJe(), m_labels[i + 2 + target]); // inverted!
2333             i += 3;
2334             break;
2335         }
2336         case op_post_inc: {
2337             unsigned srcDst = instruction[i + 2].u.operand;
2338             m_jit.link(iter->from, m_jit.label());
2339             m_jit.link((++iter)->from, m_jit.label());
2340             emitPutArg(X86::eax, 0);
2341             emitCall(i, Machine::cti_op_post_inc);
2342             emitPutResult(instruction[i + 1].u.operand);
2343             emitGetCTIParam(CTI_ARGS_2ndResult, X86::eax);
2344             emitPutResult(srcDst);
2345             i += 3;
2346             break;
2347         }
2348         case op_bitnot: {
2349             m_jit.link(iter->from, m_jit.label());
2350             emitPutArg(X86::eax, 0);
2351             emitCall(i, Machine::cti_op_bitnot);
2352             emitPutResult(instruction[i + 1].u.operand);
2353             i += 3;
2354             break;
2355         }
2356         case op_bitand: {
2357             unsigned src1 = instruction[i + 2].u.operand;
2358             unsigned src2 = instruction[i + 3].u.operand;
2359             unsigned dst = instruction[i + 1].u.operand;
2360             if (getConstantImmediateNumericArg(src1)) {
2361                 m_jit.link(iter->from, m_jit.label());
2362                 emitGetPutArg(src1, 0, X86::ecx);
2363                 emitPutArg(X86::eax, 4);
2364                 emitCall(i, Machine::cti_op_bitand);
2365                 emitPutResult(dst);
2366             } else if (getConstantImmediateNumericArg(src2)) {
2367                 m_jit.link(iter->from, m_jit.label());
2368                 emitPutArg(X86::eax, 0);
2369                 emitGetPutArg(src2, 4, X86::ecx);
2370                 emitCall(i, Machine::cti_op_bitand);
2371                 emitPutResult(dst);
2372             } else {
2373                 m_jit.link(iter->from, m_jit.label());
2374                 emitGetPutArg(src1, 0, X86::ecx);
2375                 emitPutArg(X86::edx, 4);
2376                 emitCall(i, Machine::cti_op_bitand);
2377                 emitPutResult(dst);
2378             }
2379             i += 5;
2380             break;
2381         }
2382         case op_jtrue: {
2383             m_jit.link(iter->from, m_jit.label());
2384             emitPutArg(X86::eax, 0);
2385             emitCall(i, Machine::cti_op_jtrue);
2386             m_jit.testl_rr(X86::eax, X86::eax);
2387             unsigned target = instruction[i + 2].u.operand;
2388             m_jit.link(m_jit.emitUnlinkedJne(), m_labels[i + 2 + target]);
2389             i += 3;
2390             break;
2391         }
2392         case op_post_dec: {
2393             unsigned srcDst = instruction[i + 2].u.operand;
2394             m_jit.link(iter->from, m_jit.label());
2395             m_jit.link((++iter)->from, m_jit.label());
2396             emitPutArg(X86::eax, 0);
2397             emitCall(i, Machine::cti_op_post_dec);
2398             emitPutResult(instruction[i + 1].u.operand);
2399             emitGetCTIParam(CTI_ARGS_2ndResult, X86::eax);
2400             emitPutResult(srcDst);
2401             i += 3;
2402             break;
2403         }
2404         case op_bitxor: {
2405             m_jit.link(iter->from, m_jit.label());
2406             emitPutArg(X86::eax, 0);
2407             emitPutArg(X86::edx, 4);
2408             emitCall(i, Machine::cti_op_bitxor);
2409             emitPutResult(instruction[i + 1].u.operand);
2410             i += 5;
2411             break;
2412         }
2413         case op_bitor: {
2414             m_jit.link(iter->from, m_jit.label());
2415             emitPutArg(X86::eax, 0);
2416             emitPutArg(X86::edx, 4);
2417             emitCall(i, Machine::cti_op_bitor);
2418             emitPutResult(instruction[i + 1].u.operand);
2419             i += 5;
2420             break;
2421         }
2422         case op_eq: {
2423             m_jit.link(iter->from, m_jit.label());
2424             emitPutArg(X86::eax, 0);
2425             emitPutArg(X86::edx, 4);
2426             emitCall(i, Machine::cti_op_eq);
2427             emitPutResult(instruction[i + 1].u.operand);
2428             i += 4;
2429             break;
2430         }
2431         case op_neq: {
2432             m_jit.link(iter->from, m_jit.label());
2433             emitPutArg(X86::eax, 0);
2434             emitPutArg(X86::edx, 4);
2435             emitCall(i, Machine::cti_op_neq);
2436             emitPutResult(instruction[i + 1].u.operand);
2437             i += 4;
2438             break;
2439         }
2440         CTI_COMPILE_BINARY_OP_SLOW_CASE(op_stricteq);
2441         CTI_COMPILE_BINARY_OP_SLOW_CASE(op_nstricteq);
2442         case op_instanceof: {
2443             m_jit.link(iter->from, m_jit.label());
2444             emitGetPutArg(instruction[i + 2].u.operand, 0, X86::ecx);
2445             emitGetPutArg(instruction[i + 3].u.operand, 4, X86::ecx);
2446             emitGetPutArg(instruction[i + 4].u.operand, 8, X86::ecx);
2447             emitCall(i, Machine::cti_op_instanceof);
2448             emitPutResult(instruction[i + 1].u.operand);
2449             i += 5;
2450             break;
2451         }
2452         case op_mod: {
2453             X86Assembler::JmpSrc notImm1 = iter->from;
2454             X86Assembler::JmpSrc notImm2 = (++iter)->from;
2455             m_jit.link((++iter)->from, m_jit.label());
2456             emitFastArithReTagImmediate(X86::eax);
2457             emitFastArithReTagImmediate(X86::ecx);
2458             m_jit.link(notImm1, m_jit.label());
2459             m_jit.link(notImm2, m_jit.label());
2460             emitPutArg(X86::eax, 0);
2461             emitPutArg(X86::ecx, 4);
2462             emitCall(i, Machine::cti_op_mod);
2463             emitPutResult(instruction[i + 1].u.operand);
2464             i += 4;
2465             break;
2466         }
2467         case op_mul: {
2468             int dst = instruction[i + 1].u.operand;
2469             int src1 = instruction[i + 2].u.operand;
2470             int src2 = instruction[i + 3].u.operand;
2471             if (getConstantImmediateNumericArg(src1) || getConstantImmediateNumericArg(src2)) {
2472                 m_jit.link(iter->from, m_jit.label());
2473                 emitGetPutArg(src1, 0, X86::ecx);
2474                 emitGetPutArg(src2, 4, X86::ecx);
2475                 emitCall(i, Machine::cti_op_mul);
2476                 emitPutResult(dst);
2477             } else
2478                 compileBinaryArithOpSlowCase(op_mul, iter, dst, src1, src2, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
2479             i += 5;
2480             break;
2481         }
2482
2483         case op_call:
2484         case op_call_eval:
2485         case op_construct: {
2486             m_jit.link(iter->from, m_jit.label());
2487
2488             // We jump to this slow case if the ctiCode for the codeBlock has not yet been generated; compile it now.
2489             emitCall(i, Machine::cti_vm_compile);
2490             emitCall(i, X86::eax);
2491
2492             // Instead of checking for 0 we could initialize the CodeBlock::ctiCode to point to a trampoline that would trigger the translation.
2493
2494             // Put the return value in dst. In the interpreter, op_ret does this.
2495             emitPutResult(instruction[i + 1].u.operand);
2496             i += 7;
2497             break;
2498         }
2499
2500         default:
2501             ASSERT_NOT_REACHED();
2502             break;
2503         }
2504
2505         m_jit.link(m_jit.emitUnlinkedJmp(), m_labels[i]);
2506     }
2507
2508     ASSERT(structureIDInstructionIndex == m_codeBlock->structureIDInstructions.size());
2509 }
2510
2511 void CTI::privateCompile()
2512 {
2513     // Could use a popl_m, but would need to offset the following instruction if so.
2514     m_jit.popl_r(X86::ecx);
2515     emitGetCTIParam(CTI_ARGS_r, X86::edi); // edi := r
2516     emitPutToCallFrameHeader(X86::ecx, RegisterFile::ReturnPC);
2517
2518     privateCompileMainPass();
2519     privateCompileLinkPass();
2520     privateCompileSlowCases();
2521
2522     ASSERT(m_jmpTable.isEmpty());
2523
2524     void* code = m_jit.copy();
2525     ASSERT(code);
2526
2527     // Translate vPC offsets into addresses in JIT generated code, for switch tables.
2528     for (unsigned i = 0; i < m_switches.size(); ++i) {
2529         SwitchRecord record = m_switches[i];
2530         unsigned opcodeIndex = record.m_opcodeIndex;
2531
2532         if (record.m_type != SwitchRecord::String) {
2533             ASSERT(record.m_type == SwitchRecord::Immediate || record.m_type == SwitchRecord::Character); 
2534             ASSERT(record.m_jumpTable.m_simpleJumpTable->branchOffsets.size() == record.m_jumpTable.m_simpleJumpTable->ctiOffsets.size());
2535
2536             record.m_jumpTable.m_simpleJumpTable->ctiDefault = m_jit.getRelocatedAddress(code, m_labels[opcodeIndex + 3 + record.m_defaultOffset]);
2537
2538             for (unsigned j = 0; j < record.m_jumpTable.m_simpleJumpTable->branchOffsets.size(); ++j) {
2539                 unsigned offset = record.m_jumpTable.m_simpleJumpTable->branchOffsets[j];
2540                 record.m_jumpTable.m_simpleJumpTable->ctiOffsets[j] = offset ? m_jit.getRelocatedAddress(code, m_labels[opcodeIndex + 3 + offset]) : record.m_jumpTable.m_simpleJumpTable->ctiDefault;
2541             }
2542         } else {
2543             ASSERT(record.m_type == SwitchRecord::String);
2544
2545             record.m_jumpTable.m_stringJumpTable->ctiDefault = m_jit.getRelocatedAddress(code, m_labels[opcodeIndex + 3 + record.m_defaultOffset]);
2546
2547             StringJumpTable::StringOffsetTable::iterator end = record.m_jumpTable.m_stringJumpTable->offsetTable.end();            
2548             for (StringJumpTable::StringOffsetTable::iterator it = record.m_jumpTable.m_stringJumpTable->offsetTable.begin(); it != end; ++it) {
2549                 unsigned offset = it->second.branchOffset;
2550                 it->second.ctiOffset = offset ? m_jit.getRelocatedAddress(code, m_labels[opcodeIndex + 3 + offset]) : record.m_jumpTable.m_stringJumpTable->ctiDefault;
2551             }
2552         }
2553     }
2554
2555     for (Vector<HandlerInfo>::iterator iter = m_codeBlock->exceptionHandlers.begin(); iter != m_codeBlock->exceptionHandlers.end(); ++iter)
2556          iter->nativeCode = m_jit.getRelocatedAddress(code, m_labels[iter->target]);
2557
2558     for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
2559         if (iter->to)
2560             X86Assembler::link(code, iter->from, iter->to);
2561         m_codeBlock->ctiReturnAddressVPCMap.add(m_jit.getRelocatedAddress(code, iter->from), iter->opcodeIndex);
2562     }
2563
2564     // Link absolute addresses for jsr
2565     for (Vector<JSRInfo>::iterator iter = m_jsrSites.begin(); iter != m_jsrSites.end(); ++iter)
2566         X86Assembler::linkAbsoluteAddress(code, iter->addrPosition, iter->target);
2567
2568     for (unsigned i = 0; i < m_codeBlock->structureIDInstructions.size(); ++i) {
2569         StructureStubInfo& info = m_codeBlock->structureIDInstructions[i];
2570         info.callReturnLocation = X86Assembler::getRelocatedAddress(code, m_structureStubCompilationInfo[i].callReturnLocation);
2571         info.hotPathBegin = X86Assembler::getRelocatedAddress(code, m_structureStubCompilationInfo[i].hotPathBegin);
2572     }
2573
2574     m_codeBlock->ctiCode = code;
2575 }
2576
2577 void CTI::privateCompileGetByIdSelf(StructureID* structureID, size_t cachedOffset, void* returnAddress)
2578 {
2579     // Check eax is an object of the right StructureID.
2580     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
2581     X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
2582     m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(structureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
2583     X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
2584
2585     // Checks out okay! - getDirectOffset
2586     m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax);
2587     m_jit.movl_mr(cachedOffset * sizeof(JSValue*), X86::eax, X86::eax);
2588     m_jit.ret();
2589
2590     void* code = m_jit.copy();
2591     ASSERT(code);
2592
2593     X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
2594     X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
2595     
2596     m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
2597     
2598     ctiRepatchCallByReturnAddress(returnAddress, code);
2599 }
2600
2601 void CTI::privateCompileGetByIdProto(StructureID* structureID, StructureID* prototypeStructureID, size_t cachedOffset, void* returnAddress)
2602 {
2603 #if USE(CTI_REPATCH_PIC)
2604     StructureStubInfo& info = m_codeBlock->getStubInfo(returnAddress);
2605
2606     // We don't want to repatch more than once - in future go to cti_op_put_by_id_generic.
2607     ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
2608
2609     // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a StructureID that is
2610     // referencing the prototype object - let's speculatively load it's table nice and early!)
2611     JSObject* protoObject = static_cast<JSObject*>(structureID->prototypeForLookup(m_exec));
2612     PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
2613     m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx);
2614
2615     // check eax is an object of the right StructureID.
2616     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
2617     X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
2618     m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(structureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
2619     X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
2620
2621     // Check the prototype object's StructureID had not changed.
2622     StructureID** protoStructureIDAddress = &(protoObject->m_structureID);
2623     m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(prototypeStructureID), static_cast<void*>(protoStructureIDAddress));
2624     X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJne();
2625
2626     // Checks out okay! - getDirectOffset
2627     m_jit.movl_mr(cachedOffset * sizeof(JSValue*), X86::edx, X86::ecx);
2628
2629     X86Assembler::JmpSrc success = m_jit.emitUnlinkedJmp();
2630
2631     void* code = m_jit.copy();
2632     ASSERT(code);
2633
2634     // Use the repatch information to link the failure cases back to the original slow case routine.
2635     void* slowCaseBegin = reinterpret_cast<char*>(info.callReturnLocation) - repatchOffsetGetByIdSlowCaseCall;
2636     X86Assembler::link(code, failureCases1, slowCaseBegin);
2637     X86Assembler::link(code, failureCases2, slowCaseBegin);
2638     X86Assembler::link(code, failureCases3, slowCaseBegin);
2639
2640     // On success return back to the hot patch code, at a point it will perform the store to dest for us.
2641     intptr_t successDest = (intptr_t)(info.hotPathBegin) + repatchOffsetGetByIdPropertyMapOffset;
2642     X86Assembler::link(code, success, reinterpret_cast<void*>(successDest));
2643
2644     // Track the stub we have created so that it will be deleted later.
2645     m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
2646
2647     // Finally repatch the jump to sow case back in the hot path to jump here instead.
2648     // FIXME: should revert this repatching, on failure.
2649     intptr_t jmpLocation = reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetGetByIdBranchToSlowCase;
2650     X86Assembler::repatchBranchOffset(jmpLocation, code);
2651 #else
2652     // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a StructureID that is
2653     // referencing the prototype object - let's speculatively load it's table nice and early!)
2654     JSObject* protoObject = static_cast<JSObject*>(structureID->prototypeForLookup(m_exec));
2655     PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
2656     m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx);
2657
2658     // check eax is an object of the right StructureID.
2659     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
2660     X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
2661     m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(structureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
2662     X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
2663
2664     // Check the prototype object's StructureID had not changed.
2665     StructureID** protoStructureIDAddress = &(protoObject->m_structureID);
2666     m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(prototypeStructureID), static_cast<void*>(protoStructureIDAddress));
2667     X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJne();
2668
2669     // Checks out okay! - getDirectOffset
2670     m_jit.movl_mr(cachedOffset * sizeof(JSValue*), X86::edx, X86::eax);
2671
2672     m_jit.ret();
2673
2674     void* code = m_jit.copy();
2675     ASSERT(code);
2676
2677     X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
2678     X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
2679     X86Assembler::link(code, failureCases3, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
2680
2681     m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
2682
2683     ctiRepatchCallByReturnAddress(returnAddress, code);
2684 #endif
2685 }
2686
2687 void CTI::privateCompileGetByIdChain(StructureID* structureID, StructureIDChain* chain, size_t count, size_t cachedOffset, void* returnAddress)
2688 {
2689     ASSERT(count);
2690     
2691     Vector<X86Assembler::JmpSrc> bucketsOfFail;
2692
2693     // Check eax is an object of the right StructureID.
2694     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
2695     bucketsOfFail.append(m_jit.emitUnlinkedJne());
2696     m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(structureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
2697     bucketsOfFail.append(m_jit.emitUnlinkedJne());
2698
2699     StructureID* currStructureID = structureID;
2700     RefPtr<StructureID>* chainEntries = chain->head();
2701     JSObject* protoObject = 0;
2702     for (unsigned i = 0; i<count; ++i) {
2703         protoObject = static_cast<JSObject*>(currStructureID->prototypeForLookup(m_exec));
2704         currStructureID = chainEntries[i].get();
2705
2706         // Check the prototype object's StructureID had not changed.
2707         StructureID** protoStructureIDAddress = &(protoObject->m_structureID);
2708         m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(currStructureID), static_cast<void*>(protoStructureIDAddress));
2709         bucketsOfFail.append(m_jit.emitUnlinkedJne());
2710     }
2711     ASSERT(protoObject);
2712
2713     PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
2714     m_jit.movl_mr(static_cast<void*>(protoPropertyStorage), X86::edx);
2715     m_jit.movl_mr(cachedOffset * sizeof(JSValue*), X86::edx, X86::eax);
2716     m_jit.ret();
2717
2718     bucketsOfFail.append(m_jit.emitUnlinkedJmp());
2719
2720     void* code = m_jit.copy();
2721     ASSERT(code);
2722
2723     for (unsigned i = 0; i < bucketsOfFail.size(); ++i)
2724         X86Assembler::link(code, bucketsOfFail[i], reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
2725
2726     m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
2727
2728     ctiRepatchCallByReturnAddress(returnAddress, code);
2729 }
2730
2731 void CTI::privateCompilePutByIdReplace(StructureID* structureID, size_t cachedOffset, void* returnAddress)
2732 {
2733     // check eax is an object of the right StructureID.
2734     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
2735     X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
2736     m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(structureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
2737     X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
2738
2739     // checks out okay! - putDirectOffset
2740     m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax);
2741     m_jit.movl_rm(X86::edx, cachedOffset * sizeof(JSValue*), X86::eax);
2742     m_jit.ret();
2743
2744     void* code = m_jit.copy();
2745     ASSERT(code);
2746     
2747     X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_put_by_id_fail));
2748     X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_put_by_id_fail));
2749
2750     m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
2751     
2752     ctiRepatchCallByReturnAddress(returnAddress, code);
2753 }
2754
2755 extern "C" {
2756
2757 static JSValue* SFX_CALL transitionObject(StructureID* newStructureID, size_t cachedOffset, JSObject* baseObject, JSValue* value)
2758 {
2759     StructureID* oldStructureID = newStructureID->previousID();
2760
2761     baseObject->transitionTo(newStructureID);
2762
2763     if (oldStructureID->propertyMap().storageSize() == JSObject::inlineStorageCapacity)
2764         baseObject->allocatePropertyStorage(oldStructureID->propertyMap().storageSize(), oldStructureID->propertyMap().size());
2765
2766     baseObject->putDirectOffset(cachedOffset, value);
2767     return baseObject;
2768 }
2769
2770 }
2771
2772 static inline bool transitionWillNeedStorageRealloc(StructureID* oldStructureID, StructureID* newStructureID)
2773 {
2774     if (oldStructureID->propertyMap().storageSize() == JSObject::inlineStorageCapacity)
2775         return true;
2776
2777     if (oldStructureID->propertyMap().storageSize() < JSObject::inlineStorageCapacity)
2778         return false;
2779
2780     if (oldStructureID->propertyMap().size() != newStructureID->propertyMap().size())
2781         return true;
2782
2783     return false;
2784 }
2785
2786 void CTI::privateCompilePutByIdTransition(StructureID* oldStructureID, StructureID* newStructureID, size_t cachedOffset, StructureIDChain* sIDC, void* returnAddress)
2787 {
2788     Vector<X86Assembler::JmpSrc, 16> failureCases;
2789     // check eax is an object of the right StructureID.
2790     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
2791     failureCases.append(m_jit.emitUnlinkedJne());
2792     m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(oldStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
2793     failureCases.append(m_jit.emitUnlinkedJne());
2794     Vector<X86Assembler::JmpSrc> successCases;
2795
2796     //  ecx = baseObject
2797     m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::ecx);
2798     // proto(ecx) = baseObject->structureID()->prototype()
2799     m_jit.cmpl_i32m(ObjectType, OBJECT_OFFSET(StructureID, m_typeInfo) + OBJECT_OFFSET(TypeInfo, m_type), X86::ecx);
2800     failureCases.append(m_jit.emitUnlinkedJne());
2801     m_jit.movl_mr(OBJECT_OFFSET(StructureID, m_prototype), X86::ecx, X86::ecx);
2802     
2803     // ecx = baseObject->m_structureID
2804     for (RefPtr<StructureID>* it = sIDC->head(); *it; ++it) {
2805         // null check the prototype
2806         m_jit.cmpl_i32r(reinterpret_cast<intptr_t> (jsNull()), X86::ecx);
2807         successCases.append(m_jit.emitUnlinkedJe());
2808
2809         // Check the structure id
2810         m_jit.cmpl_i32m(reinterpret_cast<uint32_t>(it->get()), OBJECT_OFFSET(JSCell, m_structureID), X86::ecx);
2811         failureCases.append(m_jit.emitUnlinkedJne());
2812         
2813         m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::ecx, X86::ecx);
2814         m_jit.cmpl_i32m(ObjectType, OBJECT_OFFSET(StructureID, m_typeInfo) + OBJECT_OFFSET(TypeInfo, m_type), X86::ecx);
2815         failureCases.append(m_jit.emitUnlinkedJne());
2816         m_jit.movl_mr(OBJECT_OFFSET(StructureID, m_prototype), X86::ecx, X86::ecx);
2817     }
2818
2819     failureCases.append(m_jit.emitUnlinkedJne());
2820     for (unsigned i = 0; i < successCases.size(); ++i)
2821         m_jit.link(successCases[i], m_jit.label());
2822
2823     X86Assembler::JmpSrc callTarget;
2824     // Fast case, don't need to do any heavy lifting, so don't bother making a call.
2825     if (!transitionWillNeedStorageRealloc(oldStructureID, newStructureID)) {
2826         // Assumes m_refCount can be decremented easily, refcount decrement is safe as 
2827         // codeblock should ensure oldStructureID->m_refCount > 0
2828         m_jit.subl_i8m(1, reinterpret_cast<void*>(oldStructureID));
2829         m_jit.addl_i8m(1, reinterpret_cast<void*>(newStructureID));
2830         m_jit.movl_i32m(reinterpret_cast<uint32_t>(newStructureID), OBJECT_OFFSET(JSCell, m_structureID), X86::eax);
2831
2832         // write the value
2833         m_jit.movl_mr(OBJECT_OFFSET(JSObject, m_propertyStorage), X86::eax, X86::eax);
2834         m_jit.movl_rm(X86::edx, cachedOffset * sizeof(JSValue*), X86::eax);
2835     } else {
2836         // Slow case transition -- we're going to need to quite a bit of work,
2837         // so just make a call
2838         m_jit.pushl_r(X86::edx);
2839         m_jit.pushl_r(X86::eax);
2840         m_jit.movl_i32r(cachedOffset, X86::eax);
2841         m_jit.pushl_r(X86::eax);
2842         m_jit.movl_i32r(reinterpret_cast<uint32_t>(newStructureID), X86::eax);
2843         m_jit.pushl_r(X86::eax);
2844         callTarget = m_jit.emitCall();
2845         m_jit.addl_i32r(4 * sizeof(void*), X86::esp);
2846     }
2847     m_jit.ret();
2848     void* code = m_jit.copy();
2849     ASSERT(code);
2850     
2851     for (unsigned i = 0; i < failureCases.size(); ++i)
2852         X86Assembler::link(code, failureCases[i], reinterpret_cast<void*>(Machine::cti_op_put_by_id_fail));
2853
2854     if (transitionWillNeedStorageRealloc(oldStructureID, newStructureID))
2855         X86Assembler::link(code, callTarget, reinterpret_cast<void*>(transitionObject));
2856     
2857     m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
2858     
2859     ctiRepatchCallByReturnAddress(returnAddress, code);
2860 }
2861
2862 void* CTI::privateCompileArrayLengthTrampoline()
2863 {
2864     // Check eax is an array
2865     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
2866     X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
2867     m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsArrayVptr), X86::eax);
2868     X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
2869
2870     // Checks out okay! - get the length from the storage
2871     m_jit.movl_mr(OBJECT_OFFSET(JSArray, m_storage), X86::eax, X86::eax);
2872     m_jit.movl_mr(OBJECT_OFFSET(ArrayStorage, m_length), X86::eax, X86::eax);
2873
2874     m_jit.addl_rr(X86::eax, X86::eax);
2875     X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJo();
2876     m_jit.addl_i8r(1, X86::eax);
2877     
2878     m_jit.ret();
2879
2880     void* code = m_jit.copy();
2881     ASSERT(code);
2882
2883     X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
2884     X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
2885     X86Assembler::link(code, failureCases3, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
2886     
2887     return code;
2888 }
2889
2890 void* CTI::privateCompileStringLengthTrampoline()
2891 {
2892     // Check eax is a string
2893     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
2894     X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
2895     m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsStringVptr), X86::eax);
2896     X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
2897
2898     // Checks out okay! - get the length from the Ustring.
2899     m_jit.movl_mr(OBJECT_OFFSET(JSString, m_value) + OBJECT_OFFSET(UString, m_rep), X86::eax, X86::eax);
2900     m_jit.movl_mr(OBJECT_OFFSET(UString::Rep, len), X86::eax, X86::eax);
2901
2902     m_jit.addl_rr(X86::eax, X86::eax);
2903     X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJo();
2904     m_jit.addl_i8r(1, X86::eax);
2905     
2906     m_jit.ret();
2907
2908     void* code = m_jit.copy();
2909     ASSERT(code);
2910
2911     X86Assembler::link(code, failureCases1, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
2912     X86Assembler::link(code, failureCases2, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
2913     X86Assembler::link(code, failureCases3, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
2914
2915     return code;
2916 }
2917
2918 void CTI::patchGetByIdSelf(CodeBlock* codeBlock, StructureID* structureID, size_t cachedOffset, void* returnAddress)
2919 {
2920     StructureStubInfo& info = codeBlock->getStubInfo(returnAddress);
2921
2922     // We don't want to repatch more than once - in future go to cti_op_get_by_id_generic.
2923     // Should probably go to Machine::cti_op_get_by_id_fail, but that doesn't do anything interesting right now.
2924     ctiRepatchCallByReturnAddress(returnAddress, (void*)(Machine::cti_op_get_by_id_generic));
2925
2926     // Repatch the offset into the propoerty map to load from, then repatch the StructureID to look for.
2927     X86Assembler::repatchDisplacement(reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetGetByIdPropertyMapOffset, cachedOffset * sizeof(JSValue*));
2928     X86Assembler::repatchImmediate(reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetGetByIdStructureID, reinterpret_cast<uint32_t>(structureID));
2929 }
2930
2931 void CTI::patchPutByIdReplace(CodeBlock* codeBlock, StructureID* structureID, size_t cachedOffset, void* returnAddress)
2932 {
2933     StructureStubInfo& info = codeBlock->getStubInfo(returnAddress);
2934     
2935     // We don't want to repatch more than once - in future go to cti_op_put_by_id_generic.
2936     // Should probably go to Machine::cti_op_put_by_id_fail, but that doesn't do anything interesting right now.
2937     ctiRepatchCallByReturnAddress(returnAddress, (void*)(Machine::cti_op_put_by_id_generic));
2938
2939     // Repatch the offset into the propoerty map to load from, then repatch the StructureID to look for.
2940     X86Assembler::repatchDisplacement(reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetPutByIdPropertyMapOffset, cachedOffset * sizeof(JSValue*));
2941     X86Assembler::repatchImmediate(reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetPutByIdStructureID, reinterpret_cast<uint32_t>(structureID));
2942 }
2943
2944 void CTI::privateCompilePatchGetArrayLength(void* returnAddress)
2945 {
2946     StructureStubInfo& info = m_codeBlock->getStubInfo(returnAddress);
2947
2948     // We don't want to repatch more than once - in future go to cti_op_put_by_id_generic.
2949     ctiRepatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(Machine::cti_op_get_by_id_fail));
2950
2951     // Check eax is an array
2952     m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
2953     X86Assembler::JmpSrc failureCases1 = m_jit.emitUnlinkedJne();
2954     m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsArrayVptr), X86::eax);
2955     X86Assembler::JmpSrc failureCases2 = m_jit.emitUnlinkedJne();
2956
2957     // Checks out okay! - get the length from the storage
2958     m_jit.movl_mr(OBJECT_OFFSET(JSArray, m_storage), X86::eax, X86::ecx);
2959     m_jit.movl_mr(OBJECT_OFFSET(ArrayStorage, m_length), X86::ecx, X86::ecx);
2960
2961     m_jit.addl_rr(X86::ecx, X86::ecx);
2962     X86Assembler::JmpSrc failureCases3 = m_jit.emitUnlinkedJo();
2963     m_jit.addl_i8r(1, X86::ecx);
2964
2965     X86Assembler::JmpSrc success = m_jit.emitUnlinkedJmp();
2966
2967     void* code = m_jit.copy();
2968     ASSERT(code);
2969
2970     // Use the repatch information to link the failure cases back to the original slow case routine.
2971     void* slowCaseBegin = reinterpret_cast<char*>(info.callReturnLocation) - repatchOffsetGetByIdSlowCaseCall;
2972     X86Assembler::link(code, failureCases1, slowCaseBegin);
2973     X86Assembler::link(code, failureCases2, slowCaseBegin);
2974     X86Assembler::link(code, failureCases3, slowCaseBegin);
2975
2976     // On success return back to the hot patch code, at a point it will perform the store to dest for us.
2977     intptr_t successDest = (intptr_t)(info.hotPathBegin) + repatchOffsetGetByIdPropertyMapOffset;
2978     X86Assembler::link(code, success, reinterpret_cast<void*>(successDest));
2979
2980     // Track the stub we have created so that it will be deleted later.
2981     m_codeBlock->getStubInfo(returnAddress).stubRoutine = code;
2982
2983     // Finally repatch the jump to sow case back in the hot path to jump here instead.
2984     // FIXME: should revert this repatching, on failure.
2985     intptr_t jmpLocation = reinterpret_cast<intptr_t>(info.hotPathBegin) + repatchOffsetGetByIdBranchToSlowCase;
2986     X86Assembler::repatchBranchOffset(jmpLocation, code);
2987 }
2988
2989 void CTI::emitGetVariableObjectRegister(X86Assembler::RegisterID variableObject, int index, X86Assembler::RegisterID dst)
2990 {
2991     m_jit.movl_mr(JSVariableObject::offsetOf_d(), variableObject, dst);
2992     m_jit.movl_mr(JSVariableObject::offsetOf_Data_registers(), dst, dst);
2993     m_jit.movl_mr(index * sizeof(Register), dst, dst);
2994 }
2995
2996 void CTI::emitPutVariableObjectRegister(X86Assembler::RegisterID src, X86Assembler::RegisterID variableObject, int index)
2997 {
2998     m_jit.movl_mr(JSVariableObject::offsetOf_d(), variableObject, variableObject);
2999     m_jit.movl_mr(JSVariableObject::offsetOf_Data_registers(), variableObject, variableObject);
3000     m_jit.movl_rm(src, index * sizeof(Register), variableObject);
3001 }
3002
3003 #if ENABLE(WREC)
3004
3005 void* CTI::compileRegExp(ExecState* exec, const UString& pattern, unsigned* numSubpatterns_ptr, const char** error_ptr, bool ignoreCase, bool multiline)
3006 {
3007     // TODO: better error messages
3008     if (pattern.size() > MaxPatternSize) {
3009         *error_ptr = "regular expression too large";
3010         return 0;
3011     }
3012
3013     X86Assembler jit(exec->machine()->jitCodeBuffer());
3014     WRECParser parser(pattern, ignoreCase, multiline, jit);
3015     
3016     jit.emitConvertToFastCall();
3017     // (0) Setup:
3018     //     Preserve regs & initialize outputRegister.
3019     jit.pushl_r(WRECGenerator::outputRegister);
3020     jit.pushl_r(WRECGenerator::currentValueRegister);
3021     // push pos onto the stack, both to preserve and as a parameter available to parseDisjunction
3022     jit.pushl_r(WRECGenerator::currentPositionRegister);
3023     // load output pointer
3024     jit.movl_mr(16
3025 #if COMPILER(MSVC)
3026                     + 3 * sizeof(void*)
3027 #endif
3028                     , X86::esp, WRECGenerator::outputRegister);
3029     
3030     // restart point on match fail.
3031     WRECGenerator::JmpDst nextLabel = jit.label();
3032
3033     // (1) Parse Disjunction:
3034     
3035     //     Parsing the disjunction should fully consume the pattern.
3036     JmpSrcVector failures;
3037     parser.parseDisjunction(failures);
3038     if (parser.isEndOfPattern()) {
3039         parser.m_err = WRECParser::Error_malformedPattern;
3040     }
3041     if (parser.m_err) {
3042         // TODO: better error messages
3043         *error_ptr = "TODO: better error messages";
3044         return 0;
3045     }
3046
3047     // (2) Success:
3048     //     Set return value & pop registers from the stack.
3049
3050     jit.testl_rr(WRECGenerator::outputRegister, WRECGenerator::outputRegister);
3051     WRECGenerator::JmpSrc noOutput = jit.emitUnlinkedJe();
3052
3053     jit.movl_rm(WRECGenerator::currentPositionRegister, 4, WRECGenerator::outputRegister);
3054     jit.popl_r(X86::eax);
3055     jit.movl_rm(X86::eax, WRECGenerator::outputRegister);
3056     jit.popl_r(WRECGenerator::currentValueRegister);
3057     jit.popl_r(WRECGenerator::outputRegister);
3058     jit.ret();
3059     
3060     jit.link(noOutput, jit.label());
3061     
3062     jit.popl_r(X86::eax);
3063     jit.movl_rm(X86::eax, WRECGenerator::outputRegister);
3064     jit.popl_r(WRECGenerator::currentValueRegister);
3065     jit.popl_r(WRECGenerator::outputRegister);
3066     jit.ret();
3067
3068     // (3) Failure:
3069     //     All fails link to here.  Progress the start point & if it is within scope, loop.
3070     //     Otherwise, return fail value.
3071     WRECGenerator::JmpDst here = jit.label();
3072     for (unsigned i = 0; i < failures.size(); ++i)
3073         jit.link(failures[i], here);
3074     failures.clear();
3075
3076     jit.movl_mr(X86::esp, WRECGenerator::currentPositionRegister);
3077     jit.addl_i8r(1, WRECGenerator::currentPositionRegister);
3078     jit.movl_rm(WRECGenerator::currentPositionRegister, X86::esp);
3079     jit.cmpl_rr(WRECGenerator::lengthRegister, WRECGenerator::currentPositionRegister);
3080     jit.link(jit.emitUnlinkedJle(), nextLabel);
3081
3082     jit.addl_i8r(4, X86::esp);
3083
3084     jit.movl_i32r(-1, X86::eax);
3085     jit.popl_r(WRECGenerator::currentValueRegister);
3086     jit.popl_r(WRECGenerator::outputRegister);
3087     jit.ret();
3088
3089     *numSubpatterns_ptr = parser.m_numSubpatterns;
3090
3091     void* code = jit.copy();
3092     ASSERT(code);
3093     return code;
3094 }
3095
3096 #endif // ENABLE(WREC)
3097
3098 } // namespace JSC
3099
3100 #endif // ENABLE(CTI)