883b211efa29c8dabbef75fd1598f60d65d04b88
[WebKit-https.git] / Source / JavaScriptCore / jit / JITStubs.cpp
1 /*
2  * Copyright (C) 2008, 2009, 2013 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4  * Copyright (C) Research In Motion Limited 2010, 2011. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1.  Redistributions of source code must retain the above copyright
11  *     notice, this list of conditions and the following disclaimer.
12  * 2.  Redistributions in binary form must reproduce the above copyright
13  *     notice, this list of conditions and the following disclaimer in the
14  *     documentation and/or other materials provided with the distribution.
15  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16  *     its contributors may be used to endorse or promote products derived
17  *     from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32
33 #if ENABLE(JIT)
34 #include "JITStubs.h"
35
36 #include "Arguments.h"
37 #include "ArrayConstructor.h"
38 #include "CallFrame.h"
39 #include "CallFrameInlines.h"
40 #include "CodeBlock.h"
41 #include "CodeProfiling.h"
42 #include "CommonSlowPaths.h"
43 #include "DFGOSREntry.h"
44 #include "DFGWorklist.h"
45 #include "Debugger.h"
46 #include "DeferGC.h"
47 #include "ErrorInstance.h"
48 #include "ExceptionHelpers.h"
49 #include "GetterSetter.h"
50 #include "Heap.h"
51 #include <wtf/InlineASM.h>
52 #include "JIT.h"
53 #include "JITExceptions.h"
54 #include "JITToDFGDeferredCompilationCallback.h"
55 #include "JSActivation.h"
56 #include "JSArray.h"
57 #include "JSFunction.h"
58 #include "JSGlobalObjectFunctions.h"
59 #include "JSNameScope.h"
60 #include "JSNotAnObject.h"
61 #include "JSPropertyNameIterator.h"
62 #include "JSString.h"
63 #include "JSWithScope.h"
64 #include "LegacyProfiler.h"
65 #include "NameInstance.h"
66 #include "ObjectConstructor.h"
67 #include "ObjectPrototype.h"
68 #include "Operations.h"
69 #include "Parser.h"
70 #include "RegExpObject.h"
71 #include "RegExpPrototype.h"
72 #include "Register.h"
73 #include "RepatchBuffer.h"
74 #include "SamplingTool.h"
75 #include "SlowPathCall.h"
76 #include "Strong.h"
77 #include "StructureRareDataInlines.h"
78 #include <wtf/StdLibExtras.h>
79 #include <stdarg.h>
80 #include <stdio.h>
81
82 using namespace std;
83
84 #if CPU(ARM_TRADITIONAL)
85 #include "JITStubsARM.h"
86 #elif CPU(ARM_THUMB2)
87 #include "JITStubsARMv7.h"
88 #elif CPU(MIPS)
89 #include "JITStubsMIPS.h"
90 #elif CPU(SH4)
91 #include "JITStubsSH4.h"
92 #elif CPU(X86)
93 #include "JITStubsX86.h"
94 #elif CPU(X86_64)
95 #include "JITStubsX86_64.h"
96 #else
97 #error "JIT not supported on this platform."
98 #endif
99
100 namespace JSC {
101
102 #if ENABLE(OPCODE_SAMPLING)
103     #define CTI_SAMPLER stackFrame.vm->interpreter->sampler()
104 #else
105     #define CTI_SAMPLER 0
106 #endif
107
108 void performPlatformSpecificJITAssertions(VM* vm)
109 {
110     if (!vm->canUseJIT())
111         return;
112
113 #if CPU(ARM_THUMB2)
114     performARMv7JITAssertions();
115 #elif CPU(ARM_TRADITIONAL)
116     performARMJITAssertions();
117 #elif CPU(MIPS)
118     performMIPSJITAssertions();
119 #elif CPU(SH4)
120     performSH4JITAssertions();
121 #endif
122 }
123
124 NEVER_INLINE static void tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot, StructureStubInfo* stubInfo, bool direct)
125 {
126     ConcurrentJITLocker locker(codeBlock->m_lock);
127     
128     // The interpreter checks for recursion here; I do not believe this can occur in CTI.
129
130     if (!baseValue.isCell())
131         return;
132
133     // Uncacheable: give up.
134     if (!slot.isCacheable()) {
135         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
136         return;
137     }
138     
139     JSCell* baseCell = baseValue.asCell();
140     Structure* structure = baseCell->structure();
141
142     if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching()) {
143         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
144         return;
145     }
146
147     // If baseCell != base, then baseCell must be a proxy for another object.
148     if (baseCell != slot.base()) {
149         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
150         return;
151     }
152
153     // Cache hit: Specialize instruction and ref Structures.
154
155     // Structure transition, cache transition info
156     if (slot.type() == PutPropertySlot::NewProperty) {
157         if (structure->isDictionary()) {
158             ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
159             return;
160         }
161
162         // put_by_id_transition checks the prototype chain for setters.
163         if (normalizePrototypeChain(callFrame, baseCell) == InvalidPrototypeChain) {
164             ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
165             return;
166         }
167
168         StructureChain* prototypeChain = structure->prototypeChain(callFrame);
169         ASSERT(structure->previousID()->transitionWatchpointSetHasBeenInvalidated());
170         stubInfo->initPutByIdTransition(callFrame->vm(), codeBlock->ownerExecutable(), structure->previousID(), structure, prototypeChain, direct);
171         JIT::compilePutByIdTransition(callFrame->scope()->vm(), codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress, direct);
172         return;
173     }
174     
175     stubInfo->initPutByIdReplace(callFrame->vm(), codeBlock->ownerExecutable(), structure);
176
177     JIT::patchPutByIdReplace(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress, direct);
178 }
179
180 NEVER_INLINE static void tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo* stubInfo)
181 {
182     ConcurrentJITLocker locker(codeBlock->m_lock);
183     
184     // FIXME: Write a test that proves we need to check for recursion here just
185     // like the interpreter does, then add a check for recursion.
186
187     // FIXME: Cache property access for immediates.
188     if (!baseValue.isCell()) {
189         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
190         return;
191     }
192     
193     VM* vm = &callFrame->vm();
194
195     if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().length) {
196         JIT::compilePatchGetArrayLength(callFrame->scope()->vm(), codeBlock, returnAddress);
197         return;
198     }
199     
200     if (isJSString(baseValue) && propertyName == callFrame->propertyNames().length) {
201         // The tradeoff of compiling an patched inline string length access routine does not seem
202         // to pay off, so we currently only do this for arrays.
203         ctiPatchCallByReturnAddress(codeBlock, returnAddress, vm->getCTIStub(stringLengthTrampolineGenerator).code());
204         return;
205     }
206
207     // Uncacheable: give up.
208     if (!slot.isCacheable()) {
209         stubInfo->accessType = access_get_by_id_generic;
210         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
211         return;
212     }
213
214     JSCell* baseCell = baseValue.asCell();
215     Structure* structure = baseCell->structure();
216
217     if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching()) {
218         stubInfo->accessType = access_get_by_id_generic;
219         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
220         return;
221     }
222
223     // Cache hit: Specialize instruction and ref Structures.
224
225     if (slot.slotBase() == baseValue) {
226         RELEASE_ASSERT(stubInfo->accessType == access_unset);
227         if (!slot.isCacheableValue() || !MacroAssembler::isCompactPtrAlignedAddressOffset(maxOffsetRelativeToPatchedStorage(slot.cachedOffset())))
228             ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_self_fail));
229         else {
230             JIT::patchGetByIdSelf(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
231             stubInfo->initGetByIdSelf(callFrame->vm(), codeBlock->ownerExecutable(), structure);
232         }
233         return;
234     }
235
236     if (structure->isDictionary()) {
237         stubInfo->accessType = access_get_by_id_generic;
238         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
239         return;
240     }
241
242     if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
243         JSObject* slotBaseObject = asObject(slot.slotBase());
244         size_t offset = slot.cachedOffset();
245
246         if (structure->typeInfo().hasImpureGetOwnPropertySlot()) {
247             stubInfo->accessType = access_get_by_id_generic;
248             ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
249             return;
250         }
251         
252         // Since we're accessing a prototype in a loop, it's a good bet that it
253         // should not be treated as a dictionary.
254         if (slotBaseObject->structure()->isDictionary()) {
255             slotBaseObject->flattenDictionaryObject(callFrame->vm());
256             offset = slotBaseObject->structure()->get(callFrame->vm(), propertyName);
257         }
258         
259         stubInfo->initGetByIdProto(callFrame->vm(), codeBlock->ownerExecutable(), structure, slotBaseObject->structure(), slot.isCacheableValue());
260
261         ASSERT(!structure->isDictionary());
262         ASSERT(!slotBaseObject->structure()->isDictionary());
263         JIT::compileGetByIdProto(callFrame->scope()->vm(), callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), propertyName, slot, offset, returnAddress);
264         return;
265     }
266
267     PropertyOffset offset = slot.cachedOffset();
268     size_t count = normalizePrototypeChainForChainAccess(callFrame, baseValue, slot.slotBase(), propertyName, offset);
269     if (count == InvalidPrototypeChain) {
270         stubInfo->accessType = access_get_by_id_generic;
271         ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
272         return;
273     }
274
275     StructureChain* prototypeChain = structure->prototypeChain(callFrame);
276     stubInfo->initGetByIdChain(callFrame->vm(), codeBlock->ownerExecutable(), structure, prototypeChain, count, slot.isCacheableValue());
277     JIT::compileGetByIdChain(callFrame->scope()->vm(), callFrame, codeBlock, stubInfo, structure, prototypeChain, count, propertyName, slot, offset, returnAddress);
278 }
279
280 #if !defined(NDEBUG)
281
282 extern "C" {
283
284 static void jscGeneratedNativeCode() 
285 {
286     // When executing a JIT stub function (which might do an allocation), we hack the return address
287     // to pretend to be executing this function, to keep stack logging tools from blowing out
288     // memory.
289 }
290
291 }
292
293 struct StackHack {
294     ALWAYS_INLINE StackHack(JITStackFrame& stackFrame) 
295         : stackFrame(stackFrame)
296         , savedReturnAddress(*stackFrame.returnAddressSlot())
297     {
298         if (!CodeProfiling::enabled())
299             *stackFrame.returnAddressSlot() = ReturnAddressPtr(FunctionPtr(jscGeneratedNativeCode));
300     }
301
302     ALWAYS_INLINE ~StackHack() 
303     { 
304         *stackFrame.returnAddressSlot() = savedReturnAddress;
305     }
306
307     JITStackFrame& stackFrame;
308     ReturnAddressPtr savedReturnAddress;
309 };
310
311 #define STUB_INIT_STACK_FRAME(stackFrame) JITStackFrame& stackFrame = *reinterpret_cast_ptr<JITStackFrame*>(STUB_ARGS); StackHack stackHack(stackFrame)
312 #define STUB_SET_RETURN_ADDRESS(returnAddress) stackHack.savedReturnAddress = ReturnAddressPtr(returnAddress)
313 #define STUB_RETURN_ADDRESS stackHack.savedReturnAddress
314
315 #else
316
317 #define STUB_INIT_STACK_FRAME(stackFrame) JITStackFrame& stackFrame = *reinterpret_cast_ptr<JITStackFrame*>(STUB_ARGS)
318 #define STUB_SET_RETURN_ADDRESS(returnAddress) *stackFrame.returnAddressSlot() = ReturnAddressPtr(returnAddress)
319 #define STUB_RETURN_ADDRESS *stackFrame.returnAddressSlot()
320
321 #endif
322
323 // The reason this is not inlined is to avoid having to do a PIC branch
324 // to get the address of the ctiVMThrowTrampoline function. It's also
325 // good to keep the code size down by leaving as much of the exception
326 // handling code out of line as possible.
327 static NEVER_INLINE void returnToThrowTrampoline(VM* vm, ReturnAddressPtr exceptionLocation, ReturnAddressPtr& returnAddressSlot)
328 {
329     RELEASE_ASSERT(vm->exception());
330     vm->exceptionLocation = exceptionLocation;
331     returnAddressSlot = ReturnAddressPtr(FunctionPtr(ctiVMThrowTrampoline));
332 }
333
334 #define VM_THROW_EXCEPTION() \
335     do { \
336         VM_THROW_EXCEPTION_AT_END(); \
337         return 0; \
338     } while (0)
339 #define VM_THROW_EXCEPTION_AT_END() \
340     do {\
341         returnToThrowTrampoline(stackFrame.vm, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS);\
342     } while (0)
343
344 #define CHECK_FOR_EXCEPTION() \
345     do { \
346         if (UNLIKELY(stackFrame.vm->exception())) \
347             VM_THROW_EXCEPTION(); \
348     } while (0)
349 #define CHECK_FOR_EXCEPTION_AT_END() \
350     do { \
351         if (UNLIKELY(stackFrame.vm->exception())) \
352             VM_THROW_EXCEPTION_AT_END(); \
353     } while (0)
354 #define CHECK_FOR_EXCEPTION_VOID() \
355     do { \
356         if (UNLIKELY(stackFrame.vm->exception())) { \
357             VM_THROW_EXCEPTION_AT_END(); \
358             return; \
359         } \
360     } while (0)
361
362 class ErrorFunctor {
363 public:
364     virtual ~ErrorFunctor() { }
365     virtual JSValue operator()(ExecState*) = 0;
366 };
367
368 class ErrorWithExecFunctor : public ErrorFunctor {
369 public:
370     typedef JSObject* (*Factory)(ExecState* exec);
371     
372     ErrorWithExecFunctor(Factory factory)
373         : m_factory(factory)
374     {
375     }
376     JSValue operator()(ExecState* exec)
377     {
378         return m_factory(exec);
379     }
380
381 private:
382     Factory m_factory;
383 };
384
385 class ErrorWithExecAndCalleeFunctor : public ErrorFunctor {
386 public:
387     typedef JSObject* (*Factory)(ExecState* exec, JSValue callee);
388
389     ErrorWithExecAndCalleeFunctor(Factory factory, JSValue callee)
390         : m_factory(factory), m_callee(callee)
391     {
392     }
393     JSValue operator()(ExecState* exec)
394     {
395         return m_factory(exec, m_callee);
396     }
397 private:
398     Factory m_factory;
399     JSValue m_callee;
400 };
401
402 // Helper function for JIT stubs that may throw an exception in the middle of
403 // processing a function call. This function rolls back the stack to
404 // our caller, so exception processing can proceed from a valid state.
405 template<typename T> static T throwExceptionFromOpCall(JITStackFrame& jitStackFrame, CallFrame* newCallFrame, ReturnAddressPtr& returnAddressSlot, ErrorFunctor* createError = 0)
406 {
407     CallFrame* callFrame = newCallFrame->callerFrame()->removeHostCallFrameFlag();
408     jitStackFrame.callFrame = callFrame;
409     callFrame->vm().topCallFrame = callFrame;
410     if (createError)
411         callFrame->vm().throwException(callFrame, (*createError)(callFrame));
412     ASSERT(callFrame->vm().exception());
413     returnToThrowTrampoline(&callFrame->vm(), ReturnAddressPtr(newCallFrame->returnPC()), returnAddressSlot);
414     return T();
415 }
416
417 // If the CPU specific header does not provide an implementation, use the default one here.
418 #ifndef DEFINE_STUB_FUNCTION
419 #define DEFINE_STUB_FUNCTION(rtype, op) rtype JIT_STUB cti_##op(STUB_ARGS_DECLARATION)
420 #endif
421
422 DEFINE_STUB_FUNCTION(void, handle_watchdog_timer)
423 {
424     STUB_INIT_STACK_FRAME(stackFrame);
425     CallFrame* callFrame = stackFrame.callFrame;
426     VM* vm = stackFrame.vm;
427     if (UNLIKELY(vm->watchdog.didFire(callFrame))) {
428         vm->throwException(callFrame, createTerminatedExecutionException(vm));
429         VM_THROW_EXCEPTION_AT_END();
430         return;
431     }
432 }
433
434 DEFINE_STUB_FUNCTION(void*, stack_check)
435 {
436     STUB_INIT_STACK_FRAME(stackFrame);
437     CallFrame* callFrame = stackFrame.callFrame;
438
439     if (UNLIKELY(!stackFrame.stack->grow(&callFrame->registers()[callFrame->codeBlock()->m_numCalleeRegisters]))) {
440         ErrorWithExecFunctor functor = ErrorWithExecFunctor(createStackOverflowError);
441         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, &functor);
442     }
443
444     return callFrame;
445 }
446
447 DEFINE_STUB_FUNCTION(JSObject*, op_new_object)
448 {
449     STUB_INIT_STACK_FRAME(stackFrame);
450
451     return constructEmptyObject(stackFrame.callFrame, stackFrame.args[0].structure());
452 }
453
454 DEFINE_STUB_FUNCTION(void, op_put_by_id_generic)
455 {
456     STUB_INIT_STACK_FRAME(stackFrame);
457
458     PutPropertySlot slot(
459         stackFrame.callFrame->codeBlock()->isStrictMode(),
460         stackFrame.callFrame->codeBlock()->putByIdContext());
461     stackFrame.args[0].jsValue().put(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
462     CHECK_FOR_EXCEPTION_AT_END();
463 }
464
465 DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_generic)
466 {
467     STUB_INIT_STACK_FRAME(stackFrame);
468     
469     PutPropertySlot slot(
470         stackFrame.callFrame->codeBlock()->isStrictMode(),
471         stackFrame.callFrame->codeBlock()->putByIdContext());
472     JSValue baseValue = stackFrame.args[0].jsValue();
473     ASSERT(baseValue.isObject());
474     asObject(baseValue)->putDirect(stackFrame.callFrame->vm(), stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
475     CHECK_FOR_EXCEPTION_AT_END();
476 }
477
478 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_generic)
479 {
480     STUB_INIT_STACK_FRAME(stackFrame);
481
482     CallFrame* callFrame = stackFrame.callFrame;
483     Identifier& ident = stackFrame.args[1].identifier();
484
485     JSValue baseValue = stackFrame.args[0].jsValue();
486     PropertySlot slot(baseValue);
487     JSValue result = baseValue.get(callFrame, ident, slot);
488
489     CHECK_FOR_EXCEPTION_AT_END();
490     return JSValue::encode(result);
491 }
492
493 DEFINE_STUB_FUNCTION(void, op_put_by_id)
494 {
495     STUB_INIT_STACK_FRAME(stackFrame);
496     CallFrame* callFrame = stackFrame.callFrame;
497     Identifier& ident = stackFrame.args[1].identifier();
498     
499     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
500     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
501     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
502
503     PutPropertySlot slot(
504         callFrame->codeBlock()->isStrictMode(),
505         callFrame->codeBlock()->putByIdContext());
506     stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
507     
508     if (accessType == static_cast<AccessType>(stubInfo->accessType)) {
509         stubInfo->setSeen();
510         tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, false);
511     }
512     
513     CHECK_FOR_EXCEPTION_AT_END();
514 }
515
516 DEFINE_STUB_FUNCTION(void, op_put_by_id_direct)
517 {
518     STUB_INIT_STACK_FRAME(stackFrame);
519     CallFrame* callFrame = stackFrame.callFrame;
520     Identifier& ident = stackFrame.args[1].identifier();
521     
522     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
523     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
524     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
525
526     PutPropertySlot slot(
527         callFrame->codeBlock()->isStrictMode(),
528         callFrame->codeBlock()->putByIdContext());
529     JSValue baseValue = stackFrame.args[0].jsValue();
530     ASSERT(baseValue.isObject());
531     
532     asObject(baseValue)->putDirect(callFrame->vm(), ident, stackFrame.args[2].jsValue(), slot);
533     
534     if (accessType == static_cast<AccessType>(stubInfo->accessType)) {
535         stubInfo->setSeen();
536         tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, true);
537     }
538     
539     CHECK_FOR_EXCEPTION_AT_END();
540 }
541
542 DEFINE_STUB_FUNCTION(void, op_put_by_id_fail)
543 {
544     STUB_INIT_STACK_FRAME(stackFrame);
545
546     CallFrame* callFrame = stackFrame.callFrame;
547     Identifier& ident = stackFrame.args[1].identifier();
548     
549     PutPropertySlot slot(
550         callFrame->codeBlock()->isStrictMode(),
551         callFrame->codeBlock()->putByIdContext());
552     stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
553
554     CHECK_FOR_EXCEPTION_AT_END();
555 }
556
557 DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_fail)
558 {
559     STUB_INIT_STACK_FRAME(stackFrame);
560     
561     CallFrame* callFrame = stackFrame.callFrame;
562     Identifier& ident = stackFrame.args[1].identifier();
563     
564     PutPropertySlot slot(
565         callFrame->codeBlock()->isStrictMode(),
566         callFrame->codeBlock()->putByIdContext());
567     JSValue baseValue = stackFrame.args[0].jsValue();
568     ASSERT(baseValue.isObject());
569     asObject(baseValue)->putDirect(callFrame->vm(), ident, stackFrame.args[2].jsValue(), slot);
570     
571     CHECK_FOR_EXCEPTION_AT_END();
572 }
573
574 DEFINE_STUB_FUNCTION(JSObject*, op_put_by_id_transition_realloc)
575 {
576     STUB_INIT_STACK_FRAME(stackFrame);
577
578     JSValue baseValue = stackFrame.args[0].jsValue();
579     int32_t oldSize = stackFrame.args[3].int32();
580     Structure* newStructure = stackFrame.args[4].structure();
581     int32_t newSize = newStructure->outOfLineCapacity();
582     
583     ASSERT(oldSize >= 0);
584     ASSERT(newSize > oldSize);
585
586     ASSERT(baseValue.isObject());
587     JSObject* base = asObject(baseValue);
588     VM& vm = *stackFrame.vm;
589     Butterfly* butterfly = base->growOutOfLineStorage(vm, oldSize, newSize);
590     base->setStructureAndButterfly(vm, newStructure, butterfly);
591
592     return base;
593 }
594
595 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id)
596 {
597     STUB_INIT_STACK_FRAME(stackFrame);
598     CallFrame* callFrame = stackFrame.callFrame;
599     Identifier& ident = stackFrame.args[1].identifier();
600
601     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
602     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
603     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
604
605     JSValue baseValue = stackFrame.args[0].jsValue();
606     PropertySlot slot(baseValue);
607     JSValue result = baseValue.get(callFrame, ident, slot);
608     
609     if (accessType != static_cast<AccessType>(stubInfo->accessType))
610         return JSValue::encode(result);
611
612     if (!stubInfo->seenOnce())
613         stubInfo->setSeen();
614     else
615         tryCacheGetByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, baseValue, ident, slot, stubInfo);
616
617     CHECK_FOR_EXCEPTION_AT_END();
618     return JSValue::encode(result);
619 }
620
621 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
622 {
623     STUB_INIT_STACK_FRAME(stackFrame);
624
625     CallFrame* callFrame = stackFrame.callFrame;
626     Identifier& ident = stackFrame.args[1].identifier();
627
628     CodeBlock* codeBlock = callFrame->codeBlock();
629     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
630     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
631
632     JSValue baseValue = stackFrame.args[0].jsValue();
633     PropertySlot slot(baseValue);
634     JSValue result = baseValue.get(callFrame, ident, slot);
635     
636     if (accessType != static_cast<AccessType>(stubInfo->accessType))
637         return JSValue::encode(result);
638
639     CHECK_FOR_EXCEPTION();
640
641     ConcurrentJITLocker locker(codeBlock->m_lock);
642     
643     if (baseValue.isCell()
644         && slot.isCacheable()
645         && !baseValue.asCell()->structure()->isUncacheableDictionary()
646         && slot.slotBase() == baseValue) {
647
648         PolymorphicAccessStructureList* polymorphicStructureList;
649         int listIndex = 1;
650
651         if (stubInfo->accessType == access_unset)
652             stubInfo->initGetByIdSelf(callFrame->vm(), codeBlock->ownerExecutable(), baseValue.asCell()->structure());
653
654         if (stubInfo->accessType == access_get_by_id_self) {
655             ASSERT(!stubInfo->stubRoutine);
656             polymorphicStructureList = new PolymorphicAccessStructureList(callFrame->vm(), codeBlock->ownerExecutable(), 0, stubInfo->u.getByIdSelf.baseObjectStructure.get(), true);
657             stubInfo->initGetByIdSelfList(polymorphicStructureList, 1);
658         } else {
659             polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList;
660             listIndex = stubInfo->u.getByIdSelfList.listSize;
661         }
662         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
663             stubInfo->u.getByIdSelfList.listSize++;
664             JIT::compileGetByIdSelfList(callFrame->scope()->vm(), codeBlock, stubInfo, polymorphicStructureList, listIndex, baseValue.asCell()->structure(), ident, slot, slot.cachedOffset());
665
666             if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
667                 ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic));
668         }
669     } else
670         ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic));
671     return JSValue::encode(result);
672 }
673
674 static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(VM& vm, ScriptExecutable* owner, StructureStubInfo* stubInfo, int& listIndex)
675 {
676     PolymorphicAccessStructureList* prototypeStructureList = 0;
677     listIndex = 1;
678
679     switch (stubInfo->accessType) {
680     case access_get_by_id_proto:
681         prototypeStructureList = new PolymorphicAccessStructureList(vm, owner, stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure.get(), stubInfo->u.getByIdProto.prototypeStructure.get(), true);
682         stubInfo->stubRoutine.clear();
683         stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
684         break;
685     case access_get_by_id_chain:
686         prototypeStructureList = new PolymorphicAccessStructureList(vm, owner, stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure.get(), stubInfo->u.getByIdChain.chain.get(), true);
687         stubInfo->stubRoutine.clear();
688         stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
689         break;
690     case access_get_by_id_proto_list:
691         prototypeStructureList = stubInfo->u.getByIdProtoList.structureList;
692         listIndex = stubInfo->u.getByIdProtoList.listSize;
693         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE)
694             stubInfo->u.getByIdProtoList.listSize++;
695         break;
696     default:
697         RELEASE_ASSERT_NOT_REACHED();
698     }
699     
700     ASSERT(listIndex <= POLYMORPHIC_LIST_CACHE_SIZE);
701     return prototypeStructureList;
702 }
703
704 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_getter_stub)
705 {
706     STUB_INIT_STACK_FRAME(stackFrame);
707     CallFrame* callFrame = stackFrame.callFrame;
708     JSValue result = callGetter(callFrame, stackFrame.args[1].jsObject(), stackFrame.args[0].jsObject());
709     if (callFrame->hadException())
710         returnToThrowTrampoline(&callFrame->vm(), stackFrame.args[2].returnAddress(), STUB_RETURN_ADDRESS);
711
712     return JSValue::encode(result);
713 }
714
715 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_custom_stub)
716 {
717     STUB_INIT_STACK_FRAME(stackFrame);
718     CallFrame* callFrame = stackFrame.callFrame;
719     JSObject* slotBase = stackFrame.args[0].jsObject();
720     PropertySlot::GetValueFunc getter = reinterpret_cast<PropertySlot::GetValueFunc>(stackFrame.args[1].asPointer);
721     const Identifier& ident = stackFrame.args[2].identifier();
722     JSValue result = getter(callFrame, slotBase, ident);
723     if (callFrame->hadException())
724         returnToThrowTrampoline(&callFrame->vm(), stackFrame.args[3].returnAddress(), STUB_RETURN_ADDRESS);
725     
726     return JSValue::encode(result);
727 }
728
729 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
730 {
731     STUB_INIT_STACK_FRAME(stackFrame);
732
733     CallFrame* callFrame = stackFrame.callFrame;
734     const Identifier& propertyName = stackFrame.args[1].identifier();
735
736     CodeBlock* codeBlock = callFrame->codeBlock();
737     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
738     AccessType accessType = static_cast<AccessType>(stubInfo->accessType);
739
740     JSValue baseValue = stackFrame.args[0].jsValue();
741     PropertySlot slot(baseValue);
742     JSValue result = baseValue.get(callFrame, propertyName, slot);
743
744     CHECK_FOR_EXCEPTION();
745
746     if (accessType != static_cast<AccessType>(stubInfo->accessType)
747         || !baseValue.isCell()
748         || !slot.isCacheable()
749         || baseValue.asCell()->structure()->isDictionary()
750         || baseValue.asCell()->structure()->typeInfo().prohibitsPropertyCaching()) {
751         ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
752         return JSValue::encode(result);
753     }
754
755     ConcurrentJITLocker locker(codeBlock->m_lock);
756     
757     Structure* structure = baseValue.asCell()->structure();
758
759     JSObject* slotBaseObject = asObject(slot.slotBase());
760     
761     PropertyOffset offset = slot.cachedOffset();
762
763     if (slot.slotBase() == baseValue)
764         ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
765     else if (slot.slotBase() == baseValue.asCell()->structure()->prototypeForLookup(callFrame)) {
766         ASSERT(!baseValue.asCell()->structure()->isDictionary());
767         
768         if (baseValue.asCell()->structure()->typeInfo().hasImpureGetOwnPropertySlot()) {
769             ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
770             return JSValue::encode(result);
771         }
772         
773         // Since we're accessing a prototype in a loop, it's a good bet that it
774         // should not be treated as a dictionary.
775         if (slotBaseObject->structure()->isDictionary()) {
776             slotBaseObject->flattenDictionaryObject(callFrame->vm());
777             offset = slotBaseObject->structure()->get(callFrame->vm(), propertyName);
778         }
779
780         int listIndex;
781         PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->vm(), codeBlock->ownerExecutable(), stubInfo, listIndex);
782         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
783             JIT::compileGetByIdProtoList(callFrame->scope()->vm(), callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset);
784
785             if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
786                 ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
787         }
788     } else {
789         size_t count = normalizePrototypeChainForChainAccess(callFrame, baseValue, slot.slotBase(), propertyName, offset);
790         if (count == InvalidPrototypeChain) {
791             ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
792             return JSValue::encode(result);
793         }
794         
795         ASSERT(!baseValue.asCell()->structure()->isDictionary());
796         int listIndex;
797         PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(callFrame->vm(), codeBlock->ownerExecutable(), stubInfo, listIndex);
798         
799         if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
800             StructureChain* protoChain = structure->prototypeChain(callFrame);
801             JIT::compileGetByIdChainList(callFrame->scope()->vm(), callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, propertyName, slot, offset);
802
803             if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
804                 ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
805         }
806     }
807
808     return JSValue::encode(result);
809 }
810
811 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list_full)
812 {
813     STUB_INIT_STACK_FRAME(stackFrame);
814
815     JSValue baseValue = stackFrame.args[0].jsValue();
816     PropertySlot slot(baseValue);
817     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
818
819     CHECK_FOR_EXCEPTION_AT_END();
820     return JSValue::encode(result);
821 }
822
823 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_fail)
824 {
825     STUB_INIT_STACK_FRAME(stackFrame);
826
827     JSValue baseValue = stackFrame.args[0].jsValue();
828     PropertySlot slot(baseValue);
829     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
830
831     CHECK_FOR_EXCEPTION_AT_END();
832     return JSValue::encode(result);
833 }
834
835 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_array_fail)
836 {
837     STUB_INIT_STACK_FRAME(stackFrame);
838
839     JSValue baseValue = stackFrame.args[0].jsValue();
840     PropertySlot slot(baseValue);
841     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
842
843     CHECK_FOR_EXCEPTION_AT_END();
844     return JSValue::encode(result);
845 }
846
847 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_string_fail)
848 {
849     STUB_INIT_STACK_FRAME(stackFrame);
850
851     JSValue baseValue = stackFrame.args[0].jsValue();
852     PropertySlot slot(baseValue);
853     JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
854
855     CHECK_FOR_EXCEPTION_AT_END();
856     return JSValue::encode(result);
857 }
858
859 DEFINE_STUB_FUNCTION(EncodedJSValue, op_check_has_instance)
860 {
861     STUB_INIT_STACK_FRAME(stackFrame);
862
863     CallFrame* callFrame = stackFrame.callFrame;
864     JSValue value = stackFrame.args[0].jsValue();
865     JSValue baseVal = stackFrame.args[1].jsValue();
866
867     if (baseVal.isObject()) {
868         JSObject* baseObject = asObject(baseVal);
869         ASSERT(!baseObject->structure()->typeInfo().implementsDefaultHasInstance());
870         if (baseObject->structure()->typeInfo().implementsHasInstance()) {
871             bool result = baseObject->methodTable()->customHasInstance(baseObject, callFrame, value);
872             CHECK_FOR_EXCEPTION_AT_END();
873             return JSValue::encode(jsBoolean(result));
874         }
875     }
876
877     stackFrame.vm->throwException(callFrame, createInvalidParameterError(callFrame, "instanceof", baseVal));
878     VM_THROW_EXCEPTION_AT_END();
879     return JSValue::encode(JSValue());
880 }
881
882 #if ENABLE(DFG_JIT)
883 DEFINE_STUB_FUNCTION(void, optimize)
884 {
885     STUB_INIT_STACK_FRAME(stackFrame);
886     
887     // Defer GC so that it doesn't run between when we enter into this slow path and
888     // when we figure out the state of our code block. This prevents a number of
889     // awkward reentrancy scenarios, including:
890     //
891     // - The optimized version of our code block being jettisoned by GC right after
892     //   we concluded that we wanted to use it.
893     //
894     // - An optimized version of our code block being installed just as we decided
895     //   that it wasn't ready yet.
896     //
897     // This still leaves the following: anytime we return from cti_optimize, we may
898     // GC, and the GC may either jettison the optimized version of our code block,
899     // or it may install the optimized version of our code block even though we
900     // concluded that it wasn't ready yet.
901     //
902     // Note that jettisoning won't happen if we already initiated OSR, because in
903     // that case we would have already planted the optimized code block into the JS
904     // stack.
905     DeferGC deferGC(stackFrame.vm->heap);
906     
907     CallFrame* callFrame = stackFrame.callFrame;
908     CodeBlock* codeBlock = callFrame->codeBlock();
909     unsigned bytecodeIndex = stackFrame.args[0].int32();
910
911     if (bytecodeIndex) {
912         // If we're attempting to OSR from a loop, assume that this should be
913         // separately optimized.
914         codeBlock->m_shouldAlwaysBeInlined = false;
915     }
916     
917     if (Options::verboseOSR()) {
918         dataLog(
919             *codeBlock, ": Entered optimize with bytecodeIndex = ", bytecodeIndex,
920             ", executeCounter = ", codeBlock->jitExecuteCounter(),
921             ", optimizationDelayCounter = ", codeBlock->reoptimizationRetryCounter(),
922             ", exitCounter = ");
923         if (codeBlock->hasOptimizedReplacement())
924             dataLog(codeBlock->replacement()->osrExitCounter());
925         else
926             dataLog("N/A");
927         dataLog("\n");
928     }
929
930     if (!codeBlock->checkIfOptimizationThresholdReached()) {
931         codeBlock->updateAllPredictions();
932         if (Options::verboseOSR())
933             dataLog("Choosing not to optimize ", *codeBlock, " yet, because the threshold hasn't been reached.\n");
934         return;
935     }
936     
937     if (codeBlock->m_shouldAlwaysBeInlined) {
938         codeBlock->updateAllPredictions();
939         codeBlock->optimizeAfterWarmUp();
940         if (Options::verboseOSR())
941             dataLog("Choosing not to optimize ", *codeBlock, " yet, because m_shouldAlwaysBeInlined == true.\n");
942         return;
943     }
944     
945     // We cannot be in the process of asynchronous compilation and also have an optimized
946     // replacement.
947     ASSERT(
948         !stackFrame.vm->worklist
949         || !(stackFrame.vm->worklist->compilationState(codeBlock) != DFG::Worklist::NotKnown
950              && codeBlock->hasOptimizedReplacement()));
951     
952     DFG::Worklist::State worklistState;
953     if (stackFrame.vm->worklist) {
954         // The call to DFG::Worklist::completeAllReadyPlansForVM() will complete all ready
955         // (i.e. compiled) code blocks. But if it completes ours, we also need to know
956         // what the result was so that we don't plow ahead and attempt OSR or immediate
957         // reoptimization. This will have already also set the appropriate JIT execution
958         // count threshold depending on what happened, so if the compilation was anything
959         // but successful we just want to return early. See the case for worklistState ==
960         // DFG::Worklist::Compiled, below.
961         
962         // Note that we could have alternatively just called Worklist::compilationState()
963         // here, and if it returned Compiled, we could have then called
964         // completeAndScheduleOSR() below. But that would have meant that it could take
965         // longer for code blocks to be completed: they would only complete when *their*
966         // execution count trigger fired; but that could take a while since the firing is
967         // racy. It could also mean that code blocks that never run again after being
968         // compiled would sit on the worklist until next GC. That's fine, but it's
969         // probably a waste of memory. Our goal here is to complete code blocks as soon as
970         // possible in order to minimize the chances of us executing baseline code after
971         // optimized code is already available.
972         
973         worklistState =
974             stackFrame.vm->worklist->completeAllReadyPlansForVM(*stackFrame.vm, codeBlock);
975     } else
976         worklistState = DFG::Worklist::NotKnown;
977     
978     if (worklistState == DFG::Worklist::Compiling) {
979         // We cannot be in the process of asynchronous compilation and also have an optimized
980         // replacement.
981         RELEASE_ASSERT(!codeBlock->hasOptimizedReplacement());
982         codeBlock->setOptimizationThresholdBasedOnCompilationResult(CompilationDeferred);
983         return;
984     }
985     
986     if (worklistState == DFG::Worklist::Compiled) {
987         // If we don't have an optimized replacement but we did just get compiled, then
988         // the compilation failed or was invalidated, in which case the execution count
989         // thresholds have already been set appropriately by
990         // CodeBlock::setOptimizationThresholdBasedOnCompilationResult() and we have
991         // nothing left to do.
992         if (!codeBlock->hasOptimizedReplacement()) {
993             codeBlock->updateAllPredictions();
994             if (Options::verboseOSR())
995                 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
996             return;
997         }
998     } else if (codeBlock->hasOptimizedReplacement()) {
999         if (Options::verboseOSR())
1000             dataLog("Considering OSR ", *codeBlock, " -> ", *codeBlock->replacement(), ".\n");
1001         // If we have an optimized replacement, then it must be the case that we entered
1002         // cti_optimize from a loop. That's because if there's an optimized replacement,
1003         // then all calls to this function will be relinked to the replacement and so
1004         // the prologue OSR will never fire.
1005         
1006         // This is an interesting threshold check. Consider that a function OSR exits
1007         // in the middle of a loop, while having a relatively low exit count. The exit
1008         // will reset the execution counter to some target threshold, meaning that this
1009         // code won't be reached until that loop heats up for >=1000 executions. But then
1010         // we do a second check here, to see if we should either reoptimize, or just
1011         // attempt OSR entry. Hence it might even be correct for
1012         // shouldReoptimizeFromLoopNow() to always return true. But we make it do some
1013         // additional checking anyway, to reduce the amount of recompilation thrashing.
1014         if (codeBlock->replacement()->shouldReoptimizeFromLoopNow()) {
1015             if (Options::verboseOSR()) {
1016                 dataLog(
1017                     "Triggering reoptimization of ", *codeBlock,
1018                     "(", *codeBlock->replacement(), ") (in loop).\n");
1019             }
1020             codeBlock->reoptimize();
1021             return;
1022         }
1023     } else {
1024         if (!codeBlock->shouldOptimizeNow()) {
1025             if (Options::verboseOSR()) {
1026                 dataLog(
1027                     "Delaying optimization for ", *codeBlock,
1028                     " because of insufficient profiling.\n");
1029             }
1030             return;
1031         }
1032         
1033         if (Options::verboseOSR())
1034             dataLog("Triggering optimized compilation of ", *codeBlock, "\n");
1035         
1036         RefPtr<DeferredCompilationCallback> callback =
1037             JITToDFGDeferredCompilationCallback::create();
1038         RefPtr<CodeBlock> newCodeBlock = codeBlock->newReplacement();
1039         CompilationResult result = newCodeBlock->prepareForExecutionAsynchronously(
1040             callFrame, JITCode::DFGJIT, callback, JITCompilationCanFail, bytecodeIndex);
1041         
1042         if (result != CompilationSuccessful)
1043             return;
1044     }
1045     
1046     CodeBlock* optimizedCodeBlock = codeBlock->replacement();
1047     ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
1048     
1049     if (optimizedCodeBlock->jitType() == JITCode::FTLJIT) {
1050         // FTL JIT doesn't support OSR entry yet.
1051         // https://bugs.webkit.org/show_bug.cgi?id=113625
1052         
1053         // Don't attempt OSR entry again.
1054         codeBlock->dontOptimizeAnytimeSoon();
1055         return;
1056     }
1057     
1058     if (void* address = DFG::prepareOSREntry(callFrame, optimizedCodeBlock, bytecodeIndex)) {
1059         if (Options::verboseOSR()) {
1060             dataLog(
1061                 "Performing OSR ", *codeBlock, " -> ", *optimizedCodeBlock, ", address ",
1062                 RawPointer((STUB_RETURN_ADDRESS).value()), " -> ", RawPointer(address), ".\n");
1063         }
1064
1065         codeBlock->optimizeSoon();
1066         STUB_SET_RETURN_ADDRESS(address);
1067         return;
1068     }
1069
1070     if (Options::verboseOSR()) {
1071         dataLog(
1072             "Optimizing ", *codeBlock, " -> ", *codeBlock->replacement(),
1073             " succeeded, OSR failed, after a delay of ",
1074             codeBlock->optimizationDelayCounter(), ".\n");
1075     }
1076
1077     // Count the OSR failure as a speculation failure. If this happens a lot, then
1078     // reoptimize.
1079     optimizedCodeBlock->countOSRExit();
1080     
1081     // We are a lot more conservative about triggering reoptimization after OSR failure than
1082     // before it. If we enter the optimize_from_loop trigger with a bucket full of fail
1083     // already, then we really would like to reoptimize immediately. But this case covers
1084     // something else: there weren't many (or any) speculation failures before, but we just
1085     // failed to enter the speculative code because some variable had the wrong value or
1086     // because the OSR code decided for any spurious reason that it did not want to OSR
1087     // right now. So, we only trigger reoptimization only upon the more conservative (non-loop)
1088     // reoptimization trigger.
1089     if (optimizedCodeBlock->shouldReoptimizeNow()) {
1090         if (Options::verboseOSR()) {
1091             dataLog(
1092                 "Triggering reoptimization of ", *codeBlock, " -> ",
1093                 *codeBlock->replacement(), " (after OSR fail).\n");
1094         }
1095         codeBlock->reoptimize();
1096         return;
1097     }
1098
1099     // OSR failed this time, but it might succeed next time! Let the code run a bit
1100     // longer and then try again.
1101     codeBlock->optimizeAfterWarmUp();
1102 }
1103 #endif // ENABLE(DFG_JIT)
1104
1105 DEFINE_STUB_FUNCTION(EncodedJSValue, op_instanceof)
1106 {
1107     STUB_INIT_STACK_FRAME(stackFrame);
1108
1109     CallFrame* callFrame = stackFrame.callFrame;
1110     JSValue value = stackFrame.args[0].jsValue();
1111     JSValue proto = stackFrame.args[1].jsValue();
1112     
1113     ASSERT(!value.isObject() || !proto.isObject());
1114
1115     bool result = JSObject::defaultHasInstance(callFrame, value, proto);
1116     CHECK_FOR_EXCEPTION_AT_END();
1117     return JSValue::encode(jsBoolean(result));
1118 }
1119
1120 DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_id)
1121 {
1122     STUB_INIT_STACK_FRAME(stackFrame);
1123
1124     CallFrame* callFrame = stackFrame.callFrame;
1125     
1126     JSObject* baseObj = stackFrame.args[0].jsValue().toObject(callFrame);
1127
1128     bool couldDelete = baseObj->methodTable()->deleteProperty(baseObj, callFrame, stackFrame.args[1].identifier());
1129     JSValue result = jsBoolean(couldDelete);
1130     if (!couldDelete && callFrame->codeBlock()->isStrictMode())
1131         stackFrame.vm->throwException(stackFrame.callFrame, createTypeError(stackFrame.callFrame, "Unable to delete property."));
1132
1133     CHECK_FOR_EXCEPTION_AT_END();
1134     return JSValue::encode(result);
1135 }
1136
1137 DEFINE_STUB_FUNCTION(JSObject*, op_new_func)
1138 {
1139     STUB_INIT_STACK_FRAME(stackFrame);
1140     
1141     ASSERT(stackFrame.callFrame->codeBlock()->codeType() != FunctionCode || !stackFrame.callFrame->codeBlock()->needsFullScopeChain() || stackFrame.callFrame->uncheckedR(stackFrame.callFrame->codeBlock()->activationRegister()).jsValue());
1142     return JSFunction::create(stackFrame.callFrame, stackFrame.args[0].function(), stackFrame.callFrame->scope());
1143 }
1144
1145 inline void* jitCompileFor(CallFrame* callFrame, CodeSpecializationKind kind)
1146 {
1147     // This function is called by cti_op_call_jitCompile() and
1148     // cti_op_construct_jitCompile() JIT glue trampolines to compile the
1149     // callee function that we want to call. Both cti glue trampolines are
1150     // called by JIT'ed code which has pushed a frame and initialized most of
1151     // the frame content except for the codeBlock.
1152     //
1153     // Normally, the prologue of the callee is supposed to set the frame's cb
1154     // pointer to the cb of the callee. But in this case, the callee code does
1155     // not exist yet until it is compiled below. The compilation process will
1156     // allocate memory which may trigger a GC. The GC, in turn, will scan the
1157     // JSStack, and will expect the frame's cb to either be valid or 0. If
1158     // we don't initialize it, the GC will be accessing invalid memory and may
1159     // crash.
1160     //
1161     // Hence, we should nullify it here before proceeding with the compilation.
1162     callFrame->setCodeBlock(0);
1163
1164     JSFunction* function = jsCast<JSFunction*>(callFrame->callee());
1165     ASSERT(!function->isHostFunction());
1166     FunctionExecutable* executable = function->jsExecutable();
1167     JSScope* callDataScopeChain = function->scope();
1168     JSObject* error = executable->prepareForExecution(callFrame, callDataScopeChain, kind);
1169     if (!error)
1170         return function;
1171     callFrame->vm().throwException(callFrame, error);
1172     return 0;
1173 }
1174
1175 DEFINE_STUB_FUNCTION(void*, op_call_jitCompile)
1176 {
1177     STUB_INIT_STACK_FRAME(stackFrame);
1178
1179 #if !ASSERT_DISABLED
1180     CallData callData;
1181     ASSERT(stackFrame.callFrame->callee()->methodTable()->getCallData(stackFrame.callFrame->callee(), callData) == CallTypeJS);
1182 #endif
1183     
1184     CallFrame* callFrame = stackFrame.callFrame;
1185     void* result = jitCompileFor(callFrame, CodeForCall);
1186     if (!result)
1187         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
1188
1189     return result;
1190 }
1191
1192 DEFINE_STUB_FUNCTION(void*, op_construct_jitCompile)
1193 {
1194     STUB_INIT_STACK_FRAME(stackFrame);
1195
1196 #if !ASSERT_DISABLED
1197     ConstructData constructData;
1198     ASSERT(jsCast<JSFunction*>(stackFrame.callFrame->callee())->methodTable()->getConstructData(stackFrame.callFrame->callee(), constructData) == ConstructTypeJS);
1199 #endif
1200
1201     CallFrame* callFrame = stackFrame.callFrame;    
1202     void* result = jitCompileFor(callFrame, CodeForConstruct);
1203     if (!result)
1204         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
1205
1206     return result;
1207 }
1208
1209 DEFINE_STUB_FUNCTION(int, op_call_arityCheck)
1210 {
1211     STUB_INIT_STACK_FRAME(stackFrame);
1212
1213     CallFrame* callFrame = stackFrame.callFrame;
1214
1215     int missingArgCount = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.stack, CodeForCall);
1216     if (missingArgCount < 0) {
1217         ErrorWithExecFunctor functor = ErrorWithExecFunctor(createStackOverflowError);
1218         return throwExceptionFromOpCall<int>(stackFrame, callFrame, STUB_RETURN_ADDRESS, &functor);
1219     }
1220     return missingArgCount;
1221 }
1222
1223 DEFINE_STUB_FUNCTION(int, op_construct_arityCheck)
1224 {
1225     STUB_INIT_STACK_FRAME(stackFrame);
1226
1227     CallFrame* callFrame = stackFrame.callFrame;
1228
1229     int missingArgCount = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.stack, CodeForConstruct);
1230     if (missingArgCount < 0) {
1231         ErrorWithExecFunctor functor = ErrorWithExecFunctor(createStackOverflowError);
1232         return throwExceptionFromOpCall<int>(stackFrame, callFrame, STUB_RETURN_ADDRESS, &functor);
1233     }
1234     return missingArgCount;
1235 }
1236
1237 inline void* lazyLinkFor(CallFrame* callFrame, CodeSpecializationKind kind)
1238 {
1239     JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
1240     ExecutableBase* executable = callee->executable();
1241
1242     MacroAssemblerCodePtr codePtr;
1243     CodeBlock* codeBlock = 0;
1244     CallLinkInfo* callLinkInfo = &callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC());
1245
1246     // This function is called by cti_vm_lazyLinkCall() and
1247     // cti_lazyLinkConstruct JIT glue trampolines to link the callee function
1248     // that we want to call. Both cti glue trampolines are called by JIT'ed
1249     // code which has pushed a frame and initialized most of the frame content
1250     // except for the codeBlock.
1251     //
1252     // Normally, the prologue of the callee is supposed to set the frame's cb
1253     // field to the cb of the callee. But in this case, the callee may not
1254     // exist yet, and if not, it will be generated in the compilation below.
1255     // The compilation will allocate memory which may trigger a GC. The GC, in
1256     // turn, will scan the JSStack, and will expect the frame's cb to be valid
1257     // or 0. If we don't initialize it, the GC will be accessing invalid
1258     // memory and may crash.
1259     //
1260     // Hence, we should nullify it here before proceeding with the compilation.
1261     callFrame->setCodeBlock(0);
1262
1263     if (executable->isHostFunction())
1264         codePtr = executable->generatedJITCodeFor(kind)->addressForCall();
1265     else {
1266         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1267         if (JSObject* error = functionExecutable->prepareForExecution(callFrame, callee->scope(), kind)) {
1268             callFrame->vm().throwException(callFrame, error);
1269             return 0;
1270         }
1271         codeBlock = &functionExecutable->generatedBytecodeFor(kind);
1272         if (callFrame->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters())
1273             || callLinkInfo->callType == CallLinkInfo::CallVarargs)
1274             codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
1275         else
1276             codePtr = functionExecutable->generatedJITCodeFor(kind)->addressForCall();
1277     }
1278     
1279     ConcurrentJITLocker locker(callFrame->callerFrame()->codeBlock()->m_lock);
1280     if (!callLinkInfo->seenOnce())
1281         callLinkInfo->setSeen();
1282     else
1283         JIT::linkFor(callFrame->callerFrame(), callee, callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, &callFrame->vm(), kind);
1284
1285     return codePtr.executableAddress();
1286 }
1287
1288 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
1289 {
1290     STUB_INIT_STACK_FRAME(stackFrame);
1291
1292     CallFrame* callFrame = stackFrame.callFrame;
1293     void* result = lazyLinkFor(callFrame, CodeForCall);
1294     if (!result)
1295         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
1296
1297     return result;
1298 }
1299
1300 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkClosureCall)
1301 {
1302     STUB_INIT_STACK_FRAME(stackFrame);
1303
1304     CallFrame* callFrame = stackFrame.callFrame;
1305     
1306     CodeBlock* callerCodeBlock = callFrame->callerFrame()->codeBlock();
1307     VM* vm = callerCodeBlock->vm();
1308     CallLinkInfo* callLinkInfo = &callerCodeBlock->getCallLinkInfo(callFrame->returnPC());
1309     JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
1310     ExecutableBase* executable = callee->executable();
1311     Structure* structure = callee->structure();
1312     
1313     ASSERT(callLinkInfo->callType == CallLinkInfo::Call);
1314     ASSERT(callLinkInfo->isLinked());
1315     ASSERT(callLinkInfo->callee);
1316     ASSERT(callee != callLinkInfo->callee.get());
1317     
1318     bool shouldLink = false;
1319     CodeBlock* calleeCodeBlock = 0;
1320     MacroAssemblerCodePtr codePtr;
1321     
1322     if (executable == callLinkInfo->callee.get()->executable()
1323         && structure == callLinkInfo->callee.get()->structure()) {
1324         
1325         shouldLink = true;
1326         
1327         ASSERT(executable->hasJITCodeForCall());
1328         codePtr = executable->generatedJITCodeForCall()->addressForCall();
1329         if (!callee->executable()->isHostFunction()) {
1330             calleeCodeBlock = &jsCast<FunctionExecutable*>(executable)->generatedBytecodeForCall();
1331             if (callFrame->argumentCountIncludingThis() < static_cast<size_t>(calleeCodeBlock->numParameters())) {
1332                 shouldLink = false;
1333                 codePtr = executable->generatedJITCodeWithArityCheckFor(CodeForCall);
1334             }
1335         }
1336     } else if (callee->isHostFunction())
1337         codePtr = executable->generatedJITCodeForCall()->addressForCall();
1338     else {
1339         // Need to clear the code block before compilation, because compilation can GC.
1340         callFrame->setCodeBlock(0);
1341         
1342         FunctionExecutable* functionExecutable = jsCast<FunctionExecutable*>(executable);
1343         JSScope* scopeChain = callee->scope();
1344         JSObject* error = functionExecutable->prepareForExecution(callFrame, scopeChain, CodeForCall);
1345         if (error) {
1346             callFrame->vm().throwException(callFrame, error);
1347             return 0;
1348         }
1349         
1350         codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(CodeForCall);
1351     }
1352     
1353     if (shouldLink) {
1354         ASSERT(codePtr);
1355         ConcurrentJITLocker locker(callerCodeBlock->m_lock);
1356         JIT::compileClosureCall(vm, callLinkInfo, callerCodeBlock, calleeCodeBlock, structure, executable, codePtr);
1357         callLinkInfo->hasSeenClosure = true;
1358     } else
1359         JIT::linkSlowCall(callerCodeBlock, callLinkInfo);
1360
1361     return codePtr.executableAddress();
1362 }
1363
1364 DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
1365 {
1366     STUB_INIT_STACK_FRAME(stackFrame);
1367
1368     CallFrame* callFrame = stackFrame.callFrame;
1369     void* result = lazyLinkFor(callFrame, CodeForConstruct);
1370     if (!result)
1371         return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
1372
1373     return result;
1374 }
1375
1376 DEFINE_STUB_FUNCTION(JSObject*, op_push_activation)
1377 {
1378     STUB_INIT_STACK_FRAME(stackFrame);
1379
1380     JSActivation* activation = JSActivation::create(stackFrame.callFrame->vm(), stackFrame.callFrame, stackFrame.callFrame->codeBlock());
1381     stackFrame.callFrame->setScope(activation);
1382     return activation;
1383 }
1384
1385 DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_NotJSFunction)
1386 {
1387     STUB_INIT_STACK_FRAME(stackFrame);
1388
1389     CallFrame* callFrame = stackFrame.callFrame;
1390     
1391     JSValue callee = callFrame->calleeAsValue();
1392
1393     CallData callData;
1394     CallType callType = getCallData(callee, callData);
1395
1396     ASSERT(callType != CallTypeJS);
1397     if (callType != CallTypeHost) {
1398         ASSERT(callType == CallTypeNone);
1399         ErrorWithExecAndCalleeFunctor functor = ErrorWithExecAndCalleeFunctor(createNotAFunctionError, callee);
1400         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, &functor);
1401     }
1402
1403     EncodedJSValue returnValue;
1404     {
1405         SamplingTool::CallRecord callRecord(CTI_SAMPLER, true);
1406         returnValue = callData.native.function(callFrame);
1407     }
1408
1409     if (stackFrame.vm->exception())
1410         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
1411
1412     return returnValue;
1413 }
1414
1415 DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_arguments)
1416 {
1417     STUB_INIT_STACK_FRAME(stackFrame);
1418
1419     Arguments* arguments = Arguments::create(*stackFrame.vm, stackFrame.callFrame);
1420     return JSValue::encode(JSValue(arguments));
1421 }
1422
1423 DEFINE_STUB_FUNCTION(void, op_tear_off_activation)
1424 {
1425     STUB_INIT_STACK_FRAME(stackFrame);
1426
1427     ASSERT(stackFrame.callFrame->codeBlock()->needsFullScopeChain());
1428     jsCast<JSActivation*>(stackFrame.args[0].jsValue())->tearOff(*stackFrame.vm);
1429 }
1430
1431 DEFINE_STUB_FUNCTION(void, op_tear_off_arguments)
1432 {
1433     STUB_INIT_STACK_FRAME(stackFrame);
1434
1435     CallFrame* callFrame = stackFrame.callFrame;
1436     ASSERT(callFrame->codeBlock()->usesArguments());
1437     Arguments* arguments = jsCast<Arguments*>(stackFrame.args[0].jsValue());
1438     if (JSValue activationValue = stackFrame.args[1].jsValue()) {
1439         arguments->didTearOffActivation(callFrame, jsCast<JSActivation*>(activationValue));
1440         return;
1441     }
1442     arguments->tearOff(callFrame);
1443 }
1444
1445 DEFINE_STUB_FUNCTION(void, op_profile_will_call)
1446 {
1447     STUB_INIT_STACK_FRAME(stackFrame);
1448
1449     if (LegacyProfiler* profiler = stackFrame.vm->enabledProfiler())
1450         profiler->willExecute(stackFrame.callFrame, stackFrame.args[0].jsValue());
1451 }
1452
1453 DEFINE_STUB_FUNCTION(void, op_profile_did_call)
1454 {
1455     STUB_INIT_STACK_FRAME(stackFrame);
1456
1457     if (LegacyProfiler* profiler = stackFrame.vm->enabledProfiler())
1458         profiler->didExecute(stackFrame.callFrame, stackFrame.args[0].jsValue());
1459 }
1460
1461 DEFINE_STUB_FUNCTION(JSObject*, op_new_array)
1462 {
1463     STUB_INIT_STACK_FRAME(stackFrame);
1464
1465     return constructArray(stackFrame.callFrame, stackFrame.args[2].arrayAllocationProfile(), reinterpret_cast<JSValue*>(&stackFrame.callFrame->registers()[stackFrame.args[0].int32()]), stackFrame.args[1].int32());
1466 }
1467
1468 DEFINE_STUB_FUNCTION(JSObject*, op_new_array_with_size)
1469 {
1470     STUB_INIT_STACK_FRAME(stackFrame);
1471     
1472     return constructArrayWithSizeQuirk(stackFrame.callFrame, stackFrame.args[1].arrayAllocationProfile(), stackFrame.callFrame->lexicalGlobalObject(), stackFrame.args[0].jsValue());
1473 }
1474
1475 DEFINE_STUB_FUNCTION(JSObject*, op_new_array_buffer)
1476 {
1477     STUB_INIT_STACK_FRAME(stackFrame);
1478     
1479     return constructArray(stackFrame.callFrame, stackFrame.args[2].arrayAllocationProfile(), stackFrame.callFrame->codeBlock()->constantBuffer(stackFrame.args[0].int32()), stackFrame.args[1].int32());
1480 }
1481
1482 DEFINE_STUB_FUNCTION(EncodedJSValue, op_construct_NotJSConstruct)
1483 {
1484     STUB_INIT_STACK_FRAME(stackFrame);
1485
1486     CallFrame* callFrame = stackFrame.callFrame;
1487     JSValue callee = callFrame->calleeAsValue();
1488
1489     ConstructData constructData;
1490     ConstructType constructType = getConstructData(callee, constructData);
1491
1492     ASSERT(constructType != ConstructTypeJS);
1493     if (constructType != ConstructTypeHost) {
1494         ASSERT(constructType == ConstructTypeNone);
1495         ErrorWithExecAndCalleeFunctor functor = ErrorWithExecAndCalleeFunctor(createNotAConstructorError, callee);
1496         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, &functor);
1497     }
1498
1499     EncodedJSValue returnValue;
1500     {
1501         SamplingTool::CallRecord callRecord(CTI_SAMPLER, true);
1502         returnValue = constructData.native.function(callFrame);
1503     }
1504
1505     if (stackFrame.vm->exception())
1506         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
1507
1508     return returnValue;
1509 }
1510
1511 static JSValue getByVal(
1512     CallFrame* callFrame, JSValue baseValue, JSValue subscript, ReturnAddressPtr returnAddress)
1513 {
1514     if (LIKELY(baseValue.isCell() && subscript.isString())) {
1515         if (JSValue result = baseValue.asCell()->fastGetOwnProperty(callFrame, asString(subscript)->value(callFrame)))
1516             return result;
1517     }
1518
1519     if (subscript.isUInt32()) {
1520         uint32_t i = subscript.asUInt32();
1521         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i)) {
1522             ctiPatchCallByReturnAddress(callFrame->codeBlock(), returnAddress, FunctionPtr(cti_op_get_by_val_string));
1523             return asString(baseValue)->getIndex(callFrame, i);
1524         }
1525         return baseValue.get(callFrame, i);
1526     }
1527
1528     if (isName(subscript))
1529         return baseValue.get(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName());
1530
1531     Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
1532     return baseValue.get(callFrame, property);
1533 }
1534
1535 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
1536 {
1537     STUB_INIT_STACK_FRAME(stackFrame);
1538
1539     CallFrame* callFrame = stackFrame.callFrame;
1540
1541     JSValue baseValue = stackFrame.args[0].jsValue();
1542     JSValue subscript = stackFrame.args[1].jsValue();
1543     
1544     if (baseValue.isObject() && subscript.isInt32()) {
1545         // See if it's worth optimizing this at all.
1546         JSObject* object = asObject(baseValue);
1547         bool didOptimize = false;
1548
1549         unsigned bytecodeOffset = callFrame->locationAsBytecodeOffset();
1550         ASSERT(bytecodeOffset);
1551         ByValInfo& byValInfo = callFrame->codeBlock()->getByValInfo(bytecodeOffset - 1);
1552         ASSERT(!byValInfo.stubRoutine);
1553         
1554         if (hasOptimizableIndexing(object->structure())) {
1555             // Attempt to optimize.
1556             JITArrayMode arrayMode = jitArrayModeForStructure(object->structure());
1557             if (arrayMode != byValInfo.arrayMode) {
1558                 JIT::compileGetByVal(&callFrame->vm(), callFrame->codeBlock(), &byValInfo, STUB_RETURN_ADDRESS, arrayMode);
1559                 didOptimize = true;
1560             }
1561         }
1562         
1563         if (!didOptimize) {
1564             // If we take slow path more than 10 times without patching then make sure we
1565             // never make that mistake again. Or, if we failed to patch and we have some object
1566             // that intercepts indexed get, then don't even wait until 10 times. For cases
1567             // where we see non-index-intercepting objects, this gives 10 iterations worth of
1568             // opportunity for us to observe that the get_by_val may be polymorphic.
1569             if (++byValInfo.slowPathCount >= 10
1570                 || object->structure()->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
1571                 // Don't ever try to optimize.
1572                 RepatchBuffer repatchBuffer(callFrame->codeBlock());
1573                 repatchBuffer.relinkCallerToFunction(STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_generic));
1574             }
1575         }
1576     }
1577     
1578     JSValue result = getByVal(callFrame, baseValue, subscript, STUB_RETURN_ADDRESS);
1579     CHECK_FOR_EXCEPTION();
1580     return JSValue::encode(result);
1581 }
1582     
1583 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_generic)
1584 {
1585     STUB_INIT_STACK_FRAME(stackFrame);
1586
1587     CallFrame* callFrame = stackFrame.callFrame;
1588
1589     JSValue baseValue = stackFrame.args[0].jsValue();
1590     JSValue subscript = stackFrame.args[1].jsValue();
1591     
1592     JSValue result = getByVal(callFrame, baseValue, subscript, STUB_RETURN_ADDRESS);
1593     CHECK_FOR_EXCEPTION();
1594     return JSValue::encode(result);
1595 }
1596     
1597 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string)
1598 {
1599     STUB_INIT_STACK_FRAME(stackFrame);
1600     
1601     CallFrame* callFrame = stackFrame.callFrame;
1602     
1603     JSValue baseValue = stackFrame.args[0].jsValue();
1604     JSValue subscript = stackFrame.args[1].jsValue();
1605     
1606     JSValue result;
1607     
1608     if (LIKELY(subscript.isUInt32())) {
1609         uint32_t i = subscript.asUInt32();
1610         if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
1611             result = asString(baseValue)->getIndex(callFrame, i);
1612         else {
1613             result = baseValue.get(callFrame, i);
1614             if (!isJSString(baseValue))
1615                 ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val));
1616         }
1617     } else if (isName(subscript))
1618         result = baseValue.get(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName());
1619     else {
1620         Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
1621         result = baseValue.get(callFrame, property);
1622     }
1623     
1624     CHECK_FOR_EXCEPTION_AT_END();
1625     return JSValue::encode(result);
1626 }
1627
1628 static void putByVal(CallFrame* callFrame, JSValue baseValue, JSValue subscript, JSValue value)
1629 {
1630     if (LIKELY(subscript.isUInt32())) {
1631         uint32_t i = subscript.asUInt32();
1632         if (baseValue.isObject()) {
1633             JSObject* object = asObject(baseValue);
1634             if (object->canSetIndexQuickly(i))
1635                 object->setIndexQuickly(callFrame->vm(), i, value);
1636             else
1637                 object->methodTable()->putByIndex(object, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
1638         } else
1639             baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
1640     } else if (isName(subscript)) {
1641         PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
1642         baseValue.put(callFrame, jsCast<NameInstance*>(subscript.asCell())->privateName(), value, slot);
1643     } else {
1644         Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
1645         if (!callFrame->vm().exception()) { // Don't put to an object if toString threw an exception.
1646             PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
1647             baseValue.put(callFrame, property, value, slot);
1648         }
1649     }
1650 }
1651
1652 DEFINE_STUB_FUNCTION(void, op_put_by_val)
1653 {
1654     STUB_INIT_STACK_FRAME(stackFrame);
1655
1656     CallFrame* callFrame = stackFrame.callFrame;
1657
1658     JSValue baseValue = stackFrame.args[0].jsValue();
1659     JSValue subscript = stackFrame.args[1].jsValue();
1660     JSValue value = stackFrame.args[2].jsValue();
1661     
1662     if (baseValue.isObject() && subscript.isInt32()) {
1663         // See if it's worth optimizing at all.
1664         JSObject* object = asObject(baseValue);
1665         bool didOptimize = false;
1666
1667         unsigned bytecodeOffset = callFrame->locationAsBytecodeOffset();
1668         ASSERT(bytecodeOffset);
1669         ByValInfo& byValInfo = callFrame->codeBlock()->getByValInfo(bytecodeOffset - 1);
1670         ASSERT(!byValInfo.stubRoutine);
1671         
1672         if (hasOptimizableIndexing(object->structure())) {
1673             // Attempt to optimize.
1674             JITArrayMode arrayMode = jitArrayModeForStructure(object->structure());
1675             if (arrayMode != byValInfo.arrayMode) {
1676                 JIT::compilePutByVal(&callFrame->vm(), callFrame->codeBlock(), &byValInfo, STUB_RETURN_ADDRESS, arrayMode);
1677                 didOptimize = true;
1678             }
1679         }
1680
1681         if (!didOptimize) {
1682             // If we take slow path more than 10 times without patching then make sure we
1683             // never make that mistake again. Or, if we failed to patch and we have some object
1684             // that intercepts indexed get, then don't even wait until 10 times. For cases
1685             // where we see non-index-intercepting objects, this gives 10 iterations worth of
1686             // opportunity for us to observe that the get_by_val may be polymorphic.
1687             if (++byValInfo.slowPathCount >= 10
1688                 || object->structure()->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero()) {
1689                 // Don't ever try to optimize.
1690                 RepatchBuffer repatchBuffer(callFrame->codeBlock());
1691                 repatchBuffer.relinkCallerToFunction(STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val_generic));
1692             }
1693         }
1694     }
1695     
1696     putByVal(callFrame, baseValue, subscript, value);
1697
1698     CHECK_FOR_EXCEPTION_AT_END();
1699 }
1700
1701 DEFINE_STUB_FUNCTION(void, op_put_by_val_generic)
1702 {
1703     STUB_INIT_STACK_FRAME(stackFrame);
1704
1705     CallFrame* callFrame = stackFrame.callFrame;
1706
1707     JSValue baseValue = stackFrame.args[0].jsValue();
1708     JSValue subscript = stackFrame.args[1].jsValue();
1709     JSValue value = stackFrame.args[2].jsValue();
1710     
1711     putByVal(callFrame, baseValue, subscript, value);
1712
1713     CHECK_FOR_EXCEPTION_AT_END();
1714 }
1715
1716 DEFINE_STUB_FUNCTION(void*, op_load_varargs)
1717 {
1718     STUB_INIT_STACK_FRAME(stackFrame);
1719
1720     CallFrame* callFrame = stackFrame.callFrame;
1721     JSStack* stack = stackFrame.stack;
1722     JSValue thisValue = stackFrame.args[0].jsValue();
1723     JSValue arguments = stackFrame.args[1].jsValue();
1724     int firstFreeRegister = stackFrame.args[2].int32();
1725
1726     CallFrame* newCallFrame = loadVarargs(callFrame, stack, thisValue, arguments, firstFreeRegister);
1727     if (!newCallFrame)
1728         VM_THROW_EXCEPTION();
1729     return newCallFrame;
1730 }
1731
1732 DEFINE_STUB_FUNCTION(int, op_jless)
1733 {
1734     STUB_INIT_STACK_FRAME(stackFrame);
1735
1736     JSValue src1 = stackFrame.args[0].jsValue();
1737     JSValue src2 = stackFrame.args[1].jsValue();
1738     CallFrame* callFrame = stackFrame.callFrame;
1739
1740     bool result = jsLess<true>(callFrame, src1, src2);
1741     CHECK_FOR_EXCEPTION_AT_END();
1742     return result;
1743 }
1744
1745 DEFINE_STUB_FUNCTION(int, op_jlesseq)
1746 {
1747     STUB_INIT_STACK_FRAME(stackFrame);
1748
1749     JSValue src1 = stackFrame.args[0].jsValue();
1750     JSValue src2 = stackFrame.args[1].jsValue();
1751     CallFrame* callFrame = stackFrame.callFrame;
1752
1753     bool result = jsLessEq<true>(callFrame, src1, src2);
1754     CHECK_FOR_EXCEPTION_AT_END();
1755     return result;
1756 }
1757
1758 DEFINE_STUB_FUNCTION(int, op_jgreater)
1759 {
1760     STUB_INIT_STACK_FRAME(stackFrame);
1761
1762     JSValue src1 = stackFrame.args[0].jsValue();
1763     JSValue src2 = stackFrame.args[1].jsValue();
1764     CallFrame* callFrame = stackFrame.callFrame;
1765
1766     bool result = jsLess<false>(callFrame, src2, src1);
1767     CHECK_FOR_EXCEPTION_AT_END();
1768     return result;
1769 }
1770
1771 DEFINE_STUB_FUNCTION(int, op_jgreatereq)
1772 {
1773     STUB_INIT_STACK_FRAME(stackFrame);
1774
1775     JSValue src1 = stackFrame.args[0].jsValue();
1776     JSValue src2 = stackFrame.args[1].jsValue();
1777     CallFrame* callFrame = stackFrame.callFrame;
1778
1779     bool result = jsLessEq<false>(callFrame, src2, src1);
1780     CHECK_FOR_EXCEPTION_AT_END();
1781     return result;
1782 }
1783
1784 DEFINE_STUB_FUNCTION(int, op_jtrue)
1785 {
1786     STUB_INIT_STACK_FRAME(stackFrame);
1787
1788     JSValue src1 = stackFrame.args[0].jsValue();
1789
1790     bool result = src1.toBoolean(stackFrame.callFrame);
1791     CHECK_FOR_EXCEPTION_AT_END();
1792     return result;
1793 }
1794
1795 DEFINE_STUB_FUNCTION(int, op_eq)
1796 {
1797     STUB_INIT_STACK_FRAME(stackFrame);
1798
1799     JSValue src1 = stackFrame.args[0].jsValue();
1800     JSValue src2 = stackFrame.args[1].jsValue();
1801
1802 #if USE(JSVALUE32_64)
1803     start:
1804     if (src2.isUndefined()) {
1805         return src1.isNull() || 
1806                (src1.isCell() && src1.asCell()->structure()->masqueradesAsUndefined(stackFrame.callFrame->lexicalGlobalObject()))
1807                || src1.isUndefined();
1808     }
1809     
1810     if (src2.isNull()) {
1811         return src1.isUndefined() || 
1812                (src1.isCell() && src1.asCell()->structure()->masqueradesAsUndefined(stackFrame.callFrame->lexicalGlobalObject()))
1813                || src1.isNull();
1814     }
1815
1816     if (src1.isInt32()) {
1817         if (src2.isDouble())
1818             return src1.asInt32() == src2.asDouble();
1819         double d = src2.toNumber(stackFrame.callFrame);
1820         CHECK_FOR_EXCEPTION();
1821         return src1.asInt32() == d;
1822     }
1823
1824     if (src1.isDouble()) {
1825         if (src2.isInt32())
1826             return src1.asDouble() == src2.asInt32();
1827         double d = src2.toNumber(stackFrame.callFrame);
1828         CHECK_FOR_EXCEPTION();
1829         return src1.asDouble() == d;
1830     }
1831
1832     if (src1.isTrue()) {
1833         if (src2.isFalse())
1834             return false;
1835         double d = src2.toNumber(stackFrame.callFrame);
1836         CHECK_FOR_EXCEPTION();
1837         return d == 1.0;
1838     }
1839
1840     if (src1.isFalse()) {
1841         if (src2.isTrue())
1842             return false;
1843         double d = src2.toNumber(stackFrame.callFrame);
1844         CHECK_FOR_EXCEPTION();
1845         return d == 0.0;
1846     }
1847     
1848     if (src1.isUndefined())
1849         return src2.isCell() && src2.asCell()->structure()->masqueradesAsUndefined(stackFrame.callFrame->lexicalGlobalObject());
1850     
1851     if (src1.isNull())
1852         return src2.isCell() && src2.asCell()->structure()->masqueradesAsUndefined(stackFrame.callFrame->lexicalGlobalObject());
1853
1854     JSCell* cell1 = src1.asCell();
1855
1856     if (cell1->isString()) {
1857         if (src2.isInt32())
1858             return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asInt32();
1859             
1860         if (src2.isDouble())
1861             return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asDouble();
1862
1863         if (src2.isTrue())
1864             return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == 1.0;
1865
1866         if (src2.isFalse())
1867             return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == 0.0;
1868
1869         JSCell* cell2 = src2.asCell();
1870         if (cell2->isString())
1871             return jsCast<JSString*>(cell1)->value(stackFrame.callFrame) == jsCast<JSString*>(cell2)->value(stackFrame.callFrame);
1872
1873         src2 = asObject(cell2)->toPrimitive(stackFrame.callFrame);
1874         CHECK_FOR_EXCEPTION();
1875         goto start;
1876     }
1877
1878     if (src2.isObject())
1879         return asObject(cell1) == asObject(src2);
1880     src1 = asObject(cell1)->toPrimitive(stackFrame.callFrame);
1881     CHECK_FOR_EXCEPTION();
1882     goto start;
1883     
1884 #else // USE(JSVALUE32_64)
1885     CallFrame* callFrame = stackFrame.callFrame;
1886     
1887     bool result = JSValue::equalSlowCaseInline(callFrame, src1, src2);
1888     CHECK_FOR_EXCEPTION_AT_END();
1889     return result;
1890 #endif // USE(JSVALUE32_64)
1891 }
1892
1893 DEFINE_STUB_FUNCTION(int, op_eq_strings)
1894 {
1895 #if USE(JSVALUE32_64)
1896     STUB_INIT_STACK_FRAME(stackFrame);
1897
1898     JSString* string1 = stackFrame.args[0].jsString();
1899     JSString* string2 = stackFrame.args[1].jsString();
1900
1901     ASSERT(string1->isString());
1902     ASSERT(string2->isString());
1903     return string1->value(stackFrame.callFrame) == string2->value(stackFrame.callFrame);
1904 #else
1905     UNUSED_PARAM(args);
1906     RELEASE_ASSERT_NOT_REACHED();
1907     return 0;
1908 #endif
1909 }
1910
1911 DEFINE_STUB_FUNCTION(JSObject*, op_new_func_exp)
1912 {
1913     STUB_INIT_STACK_FRAME(stackFrame);
1914     CallFrame* callFrame = stackFrame.callFrame;
1915
1916     FunctionExecutable* function = stackFrame.args[0].function();
1917     JSFunction* func = JSFunction::create(callFrame, function, callFrame->scope());
1918     ASSERT(callFrame->codeBlock()->codeType() != FunctionCode || !callFrame->codeBlock()->needsFullScopeChain() || callFrame->uncheckedR(callFrame->codeBlock()->activationRegister()).jsValue());
1919
1920     return func;
1921 }
1922
1923 DEFINE_STUB_FUNCTION(JSObject*, op_new_regexp)
1924 {
1925     STUB_INIT_STACK_FRAME(stackFrame);
1926
1927     CallFrame* callFrame = stackFrame.callFrame;
1928
1929     RegExp* regExp = stackFrame.args[0].regExp();
1930     if (!regExp->isValid()) {
1931         stackFrame.vm->throwException(callFrame, createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor."));
1932         VM_THROW_EXCEPTION();
1933     }
1934
1935     return RegExpObject::create(*stackFrame.vm, stackFrame.callFrame->lexicalGlobalObject(), stackFrame.callFrame->lexicalGlobalObject()->regExpStructure(), regExp);
1936 }
1937
1938 DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval)
1939 {
1940     STUB_INIT_STACK_FRAME(stackFrame);
1941
1942     CallFrame* callFrame = stackFrame.callFrame;
1943     CallFrame* callerFrame = callFrame->callerFrame();
1944     ASSERT(callFrame->callerFrame()->codeBlock()->codeType() != FunctionCode
1945         || !callFrame->callerFrame()->codeBlock()->needsFullScopeChain()
1946         || callFrame->callerFrame()->uncheckedR(callFrame->callerFrame()->codeBlock()->activationRegister()).jsValue());
1947
1948     callFrame->setScope(callerFrame->scope());
1949     callFrame->setReturnPC(static_cast<Instruction*>((STUB_RETURN_ADDRESS).value()));
1950     callFrame->setCodeBlock(0);
1951
1952     if (!isHostFunction(callFrame->calleeAsValue(), globalFuncEval))
1953         return JSValue::encode(JSValue());
1954
1955     JSValue result = eval(callFrame);
1956     if (stackFrame.vm->exception())
1957         return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
1958
1959     return JSValue::encode(result);
1960 }
1961
1962 DEFINE_STUB_FUNCTION(void*, op_throw)
1963 {
1964     STUB_INIT_STACK_FRAME(stackFrame);
1965     stackFrame.vm->throwException(stackFrame.callFrame, stackFrame.args[0].jsValue()); 
1966     ExceptionHandler handler = jitThrow(stackFrame.vm, stackFrame.callFrame, stackFrame.args[0].jsValue(), STUB_RETURN_ADDRESS);
1967     STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
1968     return handler.callFrame;
1969 }
1970
1971 DEFINE_STUB_FUNCTION(JSPropertyNameIterator*, op_get_pnames)
1972 {
1973     STUB_INIT_STACK_FRAME(stackFrame);
1974
1975     CallFrame* callFrame = stackFrame.callFrame;
1976     JSObject* o = stackFrame.args[0].jsObject();
1977     Structure* structure = o->structure();
1978     JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
1979     if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame))
1980         jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o);
1981     return jsPropertyNameIterator;
1982 }
1983
1984 DEFINE_STUB_FUNCTION(int, has_property)
1985 {
1986     STUB_INIT_STACK_FRAME(stackFrame);
1987
1988     JSObject* base = stackFrame.args[0].jsObject();
1989     JSString* property = stackFrame.args[1].jsString();
1990     int result = base->hasProperty(stackFrame.callFrame, Identifier(stackFrame.callFrame, property->value(stackFrame.callFrame)));
1991     CHECK_FOR_EXCEPTION_AT_END();
1992     return result;
1993 }
1994
1995 DEFINE_STUB_FUNCTION(void, op_push_with_scope)
1996 {
1997     STUB_INIT_STACK_FRAME(stackFrame);
1998
1999     JSObject* o = stackFrame.args[0].jsValue().toObject(stackFrame.callFrame);
2000     CHECK_FOR_EXCEPTION_VOID();
2001     stackFrame.callFrame->setScope(JSWithScope::create(stackFrame.callFrame, o));
2002 }
2003
2004 DEFINE_STUB_FUNCTION(void, op_pop_scope)
2005 {
2006     STUB_INIT_STACK_FRAME(stackFrame);
2007
2008     stackFrame.callFrame->setScope(stackFrame.callFrame->scope()->next());
2009 }
2010
2011 DEFINE_STUB_FUNCTION(void, op_push_name_scope)
2012 {
2013     STUB_INIT_STACK_FRAME(stackFrame);
2014
2015     JSNameScope* scope = JSNameScope::create(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.args[1].jsValue(), stackFrame.args[2].int32());
2016
2017     CallFrame* callFrame = stackFrame.callFrame;
2018     callFrame->setScope(scope);
2019 }
2020
2021 DEFINE_STUB_FUNCTION(void, op_put_by_index)
2022 {
2023     STUB_INIT_STACK_FRAME(stackFrame);
2024
2025     CallFrame* callFrame = stackFrame.callFrame;
2026     unsigned property = stackFrame.args[1].int32();
2027
2028     JSValue arrayValue = stackFrame.args[0].jsValue();
2029     ASSERT(isJSArray(arrayValue));
2030     asArray(arrayValue)->putDirectIndex(callFrame, property, stackFrame.args[2].jsValue());
2031 }
2032
2033 DEFINE_STUB_FUNCTION(void*, op_switch_imm)
2034 {
2035     STUB_INIT_STACK_FRAME(stackFrame);
2036
2037     JSValue scrutinee = stackFrame.args[0].jsValue();
2038     unsigned tableIndex = stackFrame.args[1].int32();
2039     CallFrame* callFrame = stackFrame.callFrame;
2040     CodeBlock* codeBlock = callFrame->codeBlock();
2041
2042     if (scrutinee.isInt32())
2043         return codeBlock->switchJumpTable(tableIndex).ctiForValue(scrutinee.asInt32()).executableAddress();
2044     if (scrutinee.isDouble() && scrutinee.asDouble() == static_cast<int32_t>(scrutinee.asDouble()))
2045         return codeBlock->switchJumpTable(tableIndex).ctiForValue(static_cast<int32_t>(scrutinee.asDouble())).executableAddress();
2046     return codeBlock->switchJumpTable(tableIndex).ctiDefault.executableAddress();
2047 }
2048
2049 DEFINE_STUB_FUNCTION(void*, op_switch_char)
2050 {
2051     STUB_INIT_STACK_FRAME(stackFrame);
2052
2053     JSValue scrutinee = stackFrame.args[0].jsValue();
2054     unsigned tableIndex = stackFrame.args[1].int32();
2055     CallFrame* callFrame = stackFrame.callFrame;
2056     CodeBlock* codeBlock = callFrame->codeBlock();
2057
2058     void* result = codeBlock->switchJumpTable(tableIndex).ctiDefault.executableAddress();
2059
2060     if (scrutinee.isString()) {
2061         StringImpl* value = asString(scrutinee)->value(callFrame).impl();
2062         if (value->length() == 1)
2063             result = codeBlock->switchJumpTable(tableIndex).ctiForValue((*value)[0]).executableAddress();
2064     }
2065
2066     CHECK_FOR_EXCEPTION_AT_END();
2067     return result;
2068 }
2069
2070 DEFINE_STUB_FUNCTION(void*, op_switch_string)
2071 {
2072     STUB_INIT_STACK_FRAME(stackFrame);
2073
2074     JSValue scrutinee = stackFrame.args[0].jsValue();
2075     unsigned tableIndex = stackFrame.args[1].int32();
2076     CallFrame* callFrame = stackFrame.callFrame;
2077     CodeBlock* codeBlock = callFrame->codeBlock();
2078
2079     void* result = codeBlock->stringSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
2080
2081     if (scrutinee.isString()) {
2082         StringImpl* value = asString(scrutinee)->value(callFrame).impl();
2083         result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value).executableAddress();
2084     }
2085
2086     CHECK_FOR_EXCEPTION_AT_END();
2087     return result;
2088 }
2089
2090 DEFINE_STUB_FUNCTION(void, op_put_getter_setter)
2091 {
2092     STUB_INIT_STACK_FRAME(stackFrame);
2093
2094     CallFrame* callFrame = stackFrame.callFrame;
2095
2096     ASSERT(stackFrame.args[0].jsValue().isObject());
2097     JSObject* baseObj = asObject(stackFrame.args[0].jsValue());
2098
2099     GetterSetter* accessor = GetterSetter::create(callFrame);
2100
2101     JSValue getter = stackFrame.args[2].jsValue();
2102     JSValue setter = stackFrame.args[3].jsValue();
2103     ASSERT(getter.isObject() || getter.isUndefined());
2104     ASSERT(setter.isObject() || setter.isUndefined());
2105     ASSERT(getter.isObject() || setter.isObject());
2106
2107     if (!getter.isUndefined())
2108         accessor->setGetter(callFrame->vm(), asObject(getter));
2109     if (!setter.isUndefined())
2110         accessor->setSetter(callFrame->vm(), asObject(setter));
2111     baseObj->putDirectAccessor(callFrame, stackFrame.args[1].identifier(), accessor, Accessor);
2112 }
2113
2114 DEFINE_STUB_FUNCTION(void, op_throw_static_error)
2115 {
2116     STUB_INIT_STACK_FRAME(stackFrame);
2117
2118     CallFrame* callFrame = stackFrame.callFrame;
2119     String message = errorDescriptionForValue(callFrame, stackFrame.args[0].jsValue())->value(callFrame);
2120     if (stackFrame.args[1].asInt32)
2121         stackFrame.vm->throwException(callFrame, createReferenceError(callFrame, message));
2122     else
2123         stackFrame.vm->throwException(callFrame, createTypeError(callFrame, message));
2124     VM_THROW_EXCEPTION_AT_END();
2125 }
2126
2127 DEFINE_STUB_FUNCTION(void, op_debug)
2128 {
2129     STUB_INIT_STACK_FRAME(stackFrame);
2130
2131     CallFrame* callFrame = stackFrame.callFrame;
2132
2133     int debugHookID = stackFrame.args[0].int32();
2134     int firstLine = stackFrame.args[1].int32();
2135     int lastLine = stackFrame.args[2].int32();
2136     int column = stackFrame.args[3].int32();
2137
2138     stackFrame.vm->interpreter->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine, column);
2139 }
2140
2141 DEFINE_STUB_FUNCTION(void*, vm_throw)
2142 {
2143     STUB_INIT_STACK_FRAME(stackFrame);
2144     VM* vm = stackFrame.vm;
2145     ExceptionHandler handler = jitThrow(vm, stackFrame.callFrame, vm->exception(), vm->exceptionLocation);
2146     STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
2147     return handler.callFrame;
2148 }
2149
2150 #if USE(JSVALUE32_64)
2151 EncodedExceptionHandler JIT_STUB cti_vm_handle_exception(CallFrame* callFrame)
2152 {
2153     ASSERT(!callFrame->hasHostCallFrameFlag());
2154     if (!callFrame) {
2155         // The entire stack has already been unwound. Nothing more to handle.
2156         return encode(uncaughtExceptionHandler());
2157     }
2158
2159     VM* vm = callFrame->codeBlock()->vm();
2160     vm->topCallFrame = callFrame;
2161     return encode(jitThrowNew(vm, callFrame, vm->exception()));
2162 }
2163 #else
2164 ExceptionHandler JIT_STUB cti_vm_handle_exception(CallFrame* callFrame)
2165 {
2166     ASSERT(!callFrame->hasHostCallFrameFlag());
2167     if (!callFrame) {
2168         // The entire stack has already been unwound. Nothing more to handle.
2169         return uncaughtExceptionHandler();
2170     }
2171
2172     VM* vm = callFrame->codeBlock()->vm();
2173     vm->topCallFrame = callFrame;
2174     return jitThrowNew(vm, callFrame, vm->exception());
2175 }
2176 #endif
2177
2178 DEFINE_STUB_FUNCTION(EncodedJSValue, to_object)
2179 {
2180     STUB_INIT_STACK_FRAME(stackFrame);
2181
2182     CallFrame* callFrame = stackFrame.callFrame;
2183     return JSValue::encode(stackFrame.args[0].jsValue().toObject(callFrame));
2184 }
2185
2186 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_scope)
2187 {
2188     STUB_INIT_STACK_FRAME(stackFrame);
2189     ExecState* exec = stackFrame.callFrame;
2190     Instruction* pc = stackFrame.args[0].pc();
2191
2192     const Identifier& ident = exec->codeBlock()->identifier(pc[2].u.operand);
2193     return JSValue::encode(JSScope::resolve(exec, exec->scope(), ident));
2194 }
2195
2196 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_from_scope)
2197 {
2198     STUB_INIT_STACK_FRAME(stackFrame);
2199     ExecState* exec = stackFrame.callFrame;
2200     Instruction* pc = stackFrame.args[0].pc();
2201
2202     const Identifier& ident = exec->codeBlock()->identifier(pc[3].u.operand);
2203     JSObject* scope = jsCast<JSObject*>(exec->uncheckedR(pc[2].u.operand).jsValue());
2204     ResolveModeAndType modeAndType(pc[4].u.operand);
2205
2206     PropertySlot slot(scope);
2207     if (!scope->getPropertySlot(exec, ident, slot)) {
2208         if (modeAndType.mode() == ThrowIfNotFound) {
2209             exec->vm().throwException(exec, createUndefinedVariableError(exec, ident));
2210             VM_THROW_EXCEPTION();
2211         }
2212         return JSValue::encode(jsUndefined());
2213     }
2214
2215     // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
2216     if (slot.isCacheableValue() && slot.slotBase() == scope && scope->structure()->propertyAccessesAreCacheable()) {
2217         if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
2218             CodeBlock* codeBlock = exec->codeBlock();
2219             ConcurrentJITLocker locker(codeBlock->m_lock);
2220             pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
2221             pc[6].u.operand = slot.cachedOffset();
2222         }
2223     }
2224
2225     return JSValue::encode(slot.getValue(exec, ident));
2226 }
2227
2228 DEFINE_STUB_FUNCTION(void, op_put_to_scope)
2229 {
2230     STUB_INIT_STACK_FRAME(stackFrame);
2231     ExecState* exec = stackFrame.callFrame;
2232     Instruction* pc = stackFrame.args[0].pc();
2233
2234     CodeBlock* codeBlock = exec->codeBlock();
2235     const Identifier& ident = codeBlock->identifier(pc[2].u.operand);
2236     JSObject* scope = jsCast<JSObject*>(exec->uncheckedR(pc[1].u.operand).jsValue());
2237     JSValue value = exec->r(pc[3].u.operand).jsValue();
2238     ResolveModeAndType modeAndType = ResolveModeAndType(pc[4].u.operand);
2239
2240     if (modeAndType.mode() == ThrowIfNotFound && !scope->hasProperty(exec, ident)) {
2241         exec->vm().throwException(exec, createUndefinedVariableError(exec, ident));
2242         VM_THROW_EXCEPTION_AT_END();
2243         return;
2244     }
2245
2246     PutPropertySlot slot(codeBlock->isStrictMode());
2247     scope->methodTable()->put(scope, exec, ident, value, slot);
2248     
2249     if (exec->vm().exception()) {
2250         VM_THROW_EXCEPTION_AT_END();
2251         return;
2252     }
2253
2254     // Covers implicit globals. Since they don't exist until they first execute, we didn't know how to cache them at compile time.
2255     if (modeAndType.type() == GlobalProperty || modeAndType.type() == GlobalPropertyWithVarInjectionChecks) {
2256         if (slot.isCacheable() && slot.base() == scope && scope->structure()->propertyAccessesAreCacheable()) {
2257             ConcurrentJITLocker locker(codeBlock->m_lock);
2258             pc[5].u.structure.set(exec->vm(), codeBlock->ownerExecutable(), scope->structure());
2259             pc[6].u.operand = slot.cachedOffset();
2260         }
2261     }
2262 }
2263
2264 } // namespace JSC
2265
2266 #endif // ENABLE(JIT)