Unreviewed, revert http://trac.webkit.org/changeset/156235. It won't work on Windows.
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGOperations.cpp
1 /*
2  * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "DFGOperations.h"
28
29 #include "Arguments.h"
30 #include "ButterflyInlines.h"
31 #include "CodeBlock.h"
32 #include "CommonSlowPaths.h"
33 #include "CopiedSpaceInlines.h"
34 #include "DFGDriver.h"
35 #include "DFGOSRExit.h"
36 #include "DFGRepatch.h"
37 #include "DFGThunks.h"
38 #include "DFGToFTLDeferredCompilationCallback.h"
39 #include "DFGToFTLForOSREntryDeferredCompilationCallback.h"
40 #include "DFGWorklist.h"
41 #include "FTLForOSREntryJITCode.h"
42 #include "FTLOSREntry.h"
43 #include "HostCallReturnValue.h"
44 #include "GetterSetter.h"
45 #include "Interpreter.h"
46 #include "JIT.h"
47 #include "JITExceptions.h"
48 #include "JSActivation.h"
49 #include "VM.h"
50 #include "JSNameScope.h"
51 #include "NameInstance.h"
52 #include "ObjectConstructor.h"
53 #include "Operations.h"
54 #include "StringConstructor.h"
55 #include "TypedArrayInlines.h"
56 #include <wtf/InlineASM.h>
57
58 #if ENABLE(JIT)
59
60 #if CPU(MIPS)
61 #if WTF_MIPS_PIC
62 #define LOAD_FUNCTION_TO_T9(function) \
63         ".set noreorder" "\n" \
64         ".cpload $25" "\n" \
65         ".set reorder" "\n" \
66         "la $t9, " LOCAL_REFERENCE(function) "\n"
67 #else
68 #define LOAD_FUNCTION_TO_T9(function) "" "\n"
69 #endif
70 #endif
71
72 #if ENABLE(DFG_JIT)
73
74 #if COMPILER(GCC) && CPU(X86_64)
75
76 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, register) \
77     asm( \
78     ".globl " SYMBOL_STRING(function) "\n" \
79     HIDE_SYMBOL(function) "\n" \
80     SYMBOL_STRING(function) ":" "\n" \
81         "mov (%rsp), %" STRINGIZE(register) "\n" \
82         "jmp " LOCAL_REFERENCE(function##WithReturnAddress) "\n" \
83     );
84 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function)    FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rsi)
85 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)  FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
86 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)  FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, rcx)
87 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, r8)
88
89 #elif COMPILER(GCC) && CPU(X86)
90
91 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, offset) \
92     asm( \
93     ".text" "\n" \
94     ".globl " SYMBOL_STRING(function) "\n" \
95     HIDE_SYMBOL(function) "\n" \
96     SYMBOL_STRING(function) ":" "\n" \
97         "mov (%esp), %eax\n" \
98         "mov %eax, " STRINGIZE(offset) "(%esp)\n" \
99         "jmp " LOCAL_REFERENCE(function##WithReturnAddress) "\n" \
100     );
101 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function)    FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 8)
102 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)  FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 16)
103 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)  FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 20)
104 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 24)
105
106 #elif COMPILER(GCC) && CPU(ARM_THUMB2)
107
108 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
109     asm ( \
110     ".text" "\n" \
111     ".align 2" "\n" \
112     ".globl " SYMBOL_STRING(function) "\n" \
113     HIDE_SYMBOL(function) "\n" \
114     ".thumb" "\n" \
115     ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
116     SYMBOL_STRING(function) ":" "\n" \
117         "mov a2, lr" "\n" \
118         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
119     );
120
121 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
122     asm ( \
123     ".text" "\n" \
124     ".align 2" "\n" \
125     ".globl " SYMBOL_STRING(function) "\n" \
126     HIDE_SYMBOL(function) "\n" \
127     ".thumb" "\n" \
128     ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
129     SYMBOL_STRING(function) ":" "\n" \
130         "mov a4, lr" "\n" \
131         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
132     );
133
134 // EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]).
135 // As a result, return address will be at a 4-byte further location in the following cases.
136 #if COMPILER_SUPPORTS(EABI) && CPU(ARM)
137 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #4]"
138 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #8]"
139 #else
140 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #0]"
141 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #4]"
142 #endif
143
144 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
145     asm ( \
146     ".text" "\n" \
147     ".align 2" "\n" \
148     ".globl " SYMBOL_STRING(function) "\n" \
149     HIDE_SYMBOL(function) "\n" \
150     ".thumb" "\n" \
151     ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
152     SYMBOL_STRING(function) ":" "\n" \
153         INSTRUCTION_STORE_RETURN_ADDRESS_EJI "\n" \
154         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
155     );
156
157 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
158     asm ( \
159     ".text" "\n" \
160     ".align 2" "\n" \
161     ".globl " SYMBOL_STRING(function) "\n" \
162     HIDE_SYMBOL(function) "\n" \
163     ".thumb" "\n" \
164     ".thumb_func " THUMB_FUNC_PARAM(function) "\n" \
165     SYMBOL_STRING(function) ":" "\n" \
166         INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "\n" \
167         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
168     );
169
170 #elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
171
172 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
173     asm ( \
174     ".text" "\n" \
175     ".globl " SYMBOL_STRING(function) "\n" \
176     HIDE_SYMBOL(function) "\n" \
177     INLINE_ARM_FUNCTION(function) \
178     SYMBOL_STRING(function) ":" "\n" \
179         "mov a2, lr" "\n" \
180         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
181     );
182
183 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
184     asm ( \
185     ".text" "\n" \
186     ".globl " SYMBOL_STRING(function) "\n" \
187     HIDE_SYMBOL(function) "\n" \
188     INLINE_ARM_FUNCTION(function) \
189     SYMBOL_STRING(function) ":" "\n" \
190         "mov a4, lr" "\n" \
191         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
192     );
193
194 // EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]).
195 // As a result, return address will be at a 4-byte further location in the following cases.
196 #if COMPILER_SUPPORTS(EABI) && CPU(ARM)
197 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #4]"
198 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #8]"
199 #else
200 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJI "str lr, [sp, #0]"
201 #define INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "str lr, [sp, #4]"
202 #endif
203
204 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
205     asm ( \
206     ".text" "\n" \
207     ".globl " SYMBOL_STRING(function) "\n" \
208     HIDE_SYMBOL(function) "\n" \
209     INLINE_ARM_FUNCTION(function) \
210     SYMBOL_STRING(function) ":" "\n" \
211         INSTRUCTION_STORE_RETURN_ADDRESS_EJI "\n" \
212         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
213     );
214
215 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
216     asm ( \
217     ".text" "\n" \
218     ".globl " SYMBOL_STRING(function) "\n" \
219     HIDE_SYMBOL(function) "\n" \
220     INLINE_ARM_FUNCTION(function) \
221     SYMBOL_STRING(function) ":" "\n" \
222         INSTRUCTION_STORE_RETURN_ADDRESS_EJCI "\n" \
223         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
224     );
225
226 #elif COMPILER(GCC) && CPU(MIPS)
227
228 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
229     asm( \
230     ".text" "\n" \
231     ".globl " SYMBOL_STRING(function) "\n" \
232     HIDE_SYMBOL(function) "\n" \
233     SYMBOL_STRING(function) ":" "\n" \
234     LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
235         "move $a1, $ra" "\n" \
236         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
237     );
238
239 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
240     asm( \
241     ".text" "\n" \
242     ".globl " SYMBOL_STRING(function) "\n" \
243     HIDE_SYMBOL(function) "\n" \
244     SYMBOL_STRING(function) ":" "\n" \
245     LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
246         "move $a3, $ra" "\n" \
247         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
248     );
249
250 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
251     asm( \
252     ".text" "\n" \
253     ".globl " SYMBOL_STRING(function) "\n" \
254     HIDE_SYMBOL(function) "\n" \
255     SYMBOL_STRING(function) ":" "\n" \
256     LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
257         "sw $ra, 20($sp)" "\n" \
258         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
259     );
260
261 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
262     asm( \
263     ".text" "\n" \
264     ".globl " SYMBOL_STRING(function) "\n" \
265     HIDE_SYMBOL(function) "\n" \
266     SYMBOL_STRING(function) ":" "\n" \
267     LOAD_FUNCTION_TO_T9(function##WithReturnAddress) \
268         "sw $ra, 24($sp)" "\n" \
269         "b " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
270     );
271
272 #elif COMPILER(GCC) && CPU(SH4)
273
274 #define SH4_SCRATCH_REGISTER "r11"
275
276 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
277     asm( \
278     ".text" "\n" \
279     ".globl " SYMBOL_STRING(function) "\n" \
280     HIDE_SYMBOL(function) "\n" \
281     SYMBOL_STRING(function) ":" "\n" \
282         "sts pr, r5" "\n" \
283         "bra " LOCAL_REFERENCE(function) "WithReturnAddress" "\n" \
284         "nop" "\n" \
285     );
286
287 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
288     asm( \
289     ".text" "\n" \
290     ".globl " SYMBOL_STRING(function) "\n" \
291     HIDE_SYMBOL(function) "\n" \
292     SYMBOL_STRING(function) ":" "\n" \
293         "sts pr, r7" "\n" \
294         "mov.l 2f, " SH4_SCRATCH_REGISTER "\n" \
295         "braf " SH4_SCRATCH_REGISTER "\n" \
296         "nop" "\n" \
297         "1: .balign 4" "\n" \
298         "2: .long " LOCAL_REFERENCE(function) "WithReturnAddress-1b" "\n" \
299     );
300
301 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, offset, scratch) \
302     asm( \
303     ".text" "\n" \
304     ".globl " SYMBOL_STRING(function) "\n" \
305     HIDE_SYMBOL(function) "\n" \
306     SYMBOL_STRING(function) ":" "\n" \
307         "sts pr, " scratch "\n" \
308         "mov.l " scratch ", @(" STRINGIZE(offset) ", r15)" "\n" \
309         "mov.l 2f, " scratch "\n" \
310         "braf " scratch "\n" \
311         "nop" "\n" \
312         "1: .balign 4" "\n" \
313         "2: .long " LOCAL_REFERENCE(function) "WithReturnAddress-1b" "\n" \
314     );
315
316 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)  FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 0, SH4_SCRATCH_REGISTER)
317 #define FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) FUNCTION_WRAPPER_WITH_RETURN_ADDRESS(function, 4, SH4_SCRATCH_REGISTER)
318
319 #endif
320
321 #define P_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function) \
322 void* DFG_OPERATION function##WithReturnAddress(ExecState*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
323 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_E(function)
324
325 #define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function) \
326 EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, JSCell*, StringImpl*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
327 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(function)
328
329 #define J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function) \
330 EncodedJSValue DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, StringImpl*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
331 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(function)
332
333 #define V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function) \
334 void DFG_OPERATION function##WithReturnAddress(ExecState*, EncodedJSValue, JSCell*, StringImpl*, ReturnAddressPtr) REFERENCED_FROM_ASM WTF_INTERNAL; \
335 FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(function)
336
337 namespace JSC { namespace DFG {
338
339 template<bool strict>
340 static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
341 {
342     VM& vm = exec->vm();
343     NativeCallFrameTracer tracer(&vm, exec);
344     
345     if (baseValue.isObject()) {
346         JSObject* object = asObject(baseValue);
347         if (object->canSetIndexQuickly(index)) {
348             object->setIndexQuickly(vm, index, value);
349             return;
350         }
351
352         object->methodTable()->putByIndex(object, exec, index, value, strict);
353         return;
354     }
355
356     baseValue.putByIndex(exec, index, value, strict);
357 }
358
359 template<bool strict>
360 ALWAYS_INLINE static void DFG_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
361 {
362     VM* vm = &exec->vm();
363     NativeCallFrameTracer tracer(vm, exec);
364
365     JSValue baseValue = JSValue::decode(encodedBase);
366     JSValue property = JSValue::decode(encodedProperty);
367     JSValue value = JSValue::decode(encodedValue);
368
369     if (LIKELY(property.isUInt32())) {
370         putByVal<strict>(exec, baseValue, property.asUInt32(), value);
371         return;
372     }
373
374     if (property.isDouble()) {
375         double propertyAsDouble = property.asDouble();
376         uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
377         if (propertyAsDouble == propertyAsUInt32) {
378             putByVal<strict>(exec, baseValue, propertyAsUInt32, value);
379             return;
380         }
381     }
382
383     if (isName(property)) {
384         PutPropertySlot slot(strict);
385         baseValue.put(exec, jsCast<NameInstance*>(property.asCell())->privateName(), value, slot);
386         return;
387     }
388
389     // Don't put to an object if toString throws an exception.
390     Identifier ident(exec, property.toString(exec)->value(exec));
391     if (!vm->exception()) {
392         PutPropertySlot slot(strict);
393         baseValue.put(exec, ident, value, slot);
394     }
395 }
396
397 template<typename ViewClass>
398 char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size)
399 {
400     VM& vm = exec->vm();
401     NativeCallFrameTracer tracer(&vm, exec);
402     if (size < 0) {
403         vm.throwException(exec, createRangeError(exec, "Requested length is negative"));
404         return 0;
405     }
406     return bitwise_cast<char*>(ViewClass::create(exec, structure, size));
407 }
408
409 template<typename ViewClass>
410 char* newTypedArrayWithOneArgument(
411     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
412 {
413     VM& vm = exec->vm();
414     NativeCallFrameTracer tracer(&vm, exec);
415     
416     JSValue value = JSValue::decode(encodedValue);
417     
418     if (JSArrayBuffer* jsBuffer = jsDynamicCast<JSArrayBuffer*>(value)) {
419         RefPtr<ArrayBuffer> buffer = jsBuffer->impl();
420         
421         if (buffer->byteLength() % ViewClass::elementSize) {
422             vm.throwException(exec, createRangeError(exec, "ArrayBuffer length minus the byteOffset is not a multiple of the element size"));
423             return 0;
424         }
425         return bitwise_cast<char*>(
426             ViewClass::create(
427                 exec, structure, buffer, 0, buffer->byteLength() / ViewClass::elementSize));
428     }
429     
430     if (JSObject* object = jsDynamicCast<JSObject*>(value)) {
431         unsigned length = object->get(exec, vm.propertyNames->length).toUInt32(exec);
432         if (exec->hadException())
433             return 0;
434         
435         ViewClass* result = ViewClass::createUninitialized(exec, structure, length);
436         if (!result)
437             return 0;
438         
439         if (!result->set(exec, object, 0, length))
440             return 0;
441         
442         return bitwise_cast<char*>(result);
443     }
444     
445     int length;
446     if (value.isInt32())
447         length = value.asInt32();
448     else if (!value.isNumber()) {
449         vm.throwException(exec, createTypeError(exec, "Invalid array length argument"));
450         return 0;
451     } else {
452         length = static_cast<int>(value.asNumber());
453         if (length != value.asNumber()) {
454             vm.throwException(exec, createTypeError(exec, "Invalid array length argument (fractional lengths not allowed)"));
455             return 0;
456         }
457     }
458     
459     if (length < 0) {
460         vm.throwException(exec, createRangeError(exec, "Requested length is negative"));
461         return 0;
462     }
463     
464     return bitwise_cast<char*>(ViewClass::create(exec, structure, length));
465 }
466
467 extern "C" {
468
469 EncodedJSValue DFG_OPERATION operationToThis(ExecState* exec, EncodedJSValue encodedOp)
470 {
471     VM* vm = &exec->vm();
472     NativeCallFrameTracer tracer(vm, exec);
473
474     return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, NotStrictMode));
475 }
476
477 EncodedJSValue DFG_OPERATION operationToThisStrict(ExecState* exec, EncodedJSValue encodedOp)
478 {
479     VM* vm = &exec->vm();
480     NativeCallFrameTracer tracer(vm, exec);
481
482     return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, StrictMode));
483 }
484
485 JSCell* DFG_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor, int32_t inlineCapacity)
486 {
487     VM* vm = &exec->vm();
488     NativeCallFrameTracer tracer(vm, exec);
489
490 #if !ASSERT_DISABLED
491     ConstructData constructData;
492     ASSERT(jsCast<JSFunction*>(constructor)->methodTable()->getConstructData(jsCast<JSFunction*>(constructor), constructData) == ConstructTypeJS);
493 #endif
494     
495     return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->allocationProfile(exec, inlineCapacity)->structure());
496 }
497
498 JSCell* DFG_OPERATION operationNewObject(ExecState* exec, Structure* structure)
499 {
500     VM* vm = &exec->vm();
501     NativeCallFrameTracer tracer(vm, exec);
502     
503     return constructEmptyObject(exec, structure);
504 }
505
506 EncodedJSValue DFG_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
507 {
508     VM* vm = &exec->vm();
509     NativeCallFrameTracer tracer(vm, exec);
510     
511     JSValue op1 = JSValue::decode(encodedOp1);
512     JSValue op2 = JSValue::decode(encodedOp2);
513     
514     return JSValue::encode(jsAdd(exec, op1, op2));
515 }
516
517 EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
518 {
519     VM* vm = &exec->vm();
520     NativeCallFrameTracer tracer(vm, exec);
521     
522     JSValue op1 = JSValue::decode(encodedOp1);
523     JSValue op2 = JSValue::decode(encodedOp2);
524     
525     ASSERT(!op1.isNumber() || !op2.isNumber());
526     
527     if (op1.isString() && !op2.isObject())
528         return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec)));
529
530     return JSValue::encode(jsAddSlowCase(exec, op1, op2));
531 }
532
533 static inline EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
534 {
535     VM& vm = exec->vm();
536     NativeCallFrameTracer tracer(&vm, exec);
537     
538     if (base->isObject()) {
539         JSObject* object = asObject(base);
540         if (object->canGetIndexQuickly(index))
541             return JSValue::encode(object->getIndexQuickly(index));
542     }
543
544     if (isJSString(base) && asString(base)->canGetIndex(index))
545         return JSValue::encode(asString(base)->getIndex(exec, index));
546
547     return JSValue::encode(JSValue(base).get(exec, index));
548 }
549
550 EncodedJSValue DFG_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
551 {
552     VM* vm = &exec->vm();
553     NativeCallFrameTracer tracer(vm, exec);
554     
555     JSValue baseValue = JSValue::decode(encodedBase);
556     JSValue property = JSValue::decode(encodedProperty);
557
558     if (LIKELY(baseValue.isCell())) {
559         JSCell* base = baseValue.asCell();
560
561         if (property.isUInt32()) {
562             return getByVal(exec, base, property.asUInt32());
563         } else if (property.isDouble()) {
564             double propertyAsDouble = property.asDouble();
565             uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
566             if (propertyAsUInt32 == propertyAsDouble)
567                 return getByVal(exec, base, propertyAsUInt32);
568         } else if (property.isString()) {
569             if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec)))
570                 return JSValue::encode(result);
571         }
572     }
573
574     if (isName(property))
575         return JSValue::encode(baseValue.get(exec, jsCast<NameInstance*>(property.asCell())->privateName()));
576
577     Identifier ident(exec, property.toString(exec)->value(exec));
578     return JSValue::encode(baseValue.get(exec, ident));
579 }
580
581 EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
582 {
583     VM* vm = &exec->vm();
584     NativeCallFrameTracer tracer(vm, exec);
585     
586     JSValue property = JSValue::decode(encodedProperty);
587
588     if (property.isUInt32())
589         return getByVal(exec, base, property.asUInt32());
590     if (property.isDouble()) {
591         double propertyAsDouble = property.asDouble();
592         uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
593         if (propertyAsUInt32 == propertyAsDouble)
594             return getByVal(exec, base, propertyAsUInt32);
595     } else if (property.isString()) {
596         if (JSValue result = base->fastGetOwnProperty(exec, asString(property)->value(exec)))
597             return JSValue::encode(result);
598     }
599
600     if (isName(property))
601         return JSValue::encode(JSValue(base).get(exec, jsCast<NameInstance*>(property.asCell())->privateName()));
602
603     Identifier ident(exec, property.toString(exec)->value(exec));
604     return JSValue::encode(JSValue(base).get(exec, ident));
605 }
606
607 ALWAYS_INLINE EncodedJSValue getByValCellInt(ExecState* exec, JSCell* base, int32_t index)
608 {
609     VM* vm = &exec->vm();
610     NativeCallFrameTracer tracer(vm, exec);
611     
612     if (index < 0) {
613         // Go the slowest way possible becase negative indices don't use indexed storage.
614         return JSValue::encode(JSValue(base).get(exec, Identifier::from(exec, index)));
615     }
616
617     // Use this since we know that the value is out of bounds.
618     return JSValue::encode(JSValue(base).get(exec, index));
619 }
620
621 EncodedJSValue DFG_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray* base, int32_t index)
622 {
623     return getByValCellInt(exec, base, index);
624 }
625
626 EncodedJSValue DFG_OPERATION operationGetByValStringInt(ExecState* exec, JSString* base, int32_t index)
627 {
628     return getByValCellInt(exec, base, index);
629 }
630
631 EncodedJSValue DFG_OPERATION operationGetById(ExecState* exec, EncodedJSValue base, StringImpl* uid)
632 {
633     VM* vm = &exec->vm();
634     NativeCallFrameTracer tracer(vm, exec);
635     
636     JSValue baseValue = JSValue::decode(base);
637     PropertySlot slot(baseValue);
638     Identifier ident(vm, uid);
639     return JSValue::encode(baseValue.get(exec, ident, slot));
640 }
641
642 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdBuildList);
643 EncodedJSValue DFG_OPERATION operationGetByIdBuildListWithReturnAddress(ExecState* exec, EncodedJSValue base, StringImpl* uid, ReturnAddressPtr returnAddress)
644 {
645     VM* vm = &exec->vm();
646     NativeCallFrameTracer tracer(vm, exec);
647
648     Identifier ident(vm, uid);
649     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
650     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
651
652     JSValue baseValue = JSValue::decode(base);
653     PropertySlot slot(baseValue);
654     JSValue result = baseValue.get(exec, ident, slot);
655
656     if (accessType == static_cast<AccessType>(stubInfo.accessType))
657         buildGetByIDList(exec, baseValue, ident, slot, stubInfo);
658
659     return JSValue::encode(result);
660 }
661
662 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJI(operationGetByIdOptimize);
663 EncodedJSValue DFG_OPERATION operationGetByIdOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue base, StringImpl* uid, ReturnAddressPtr returnAddress)
664 {
665     VM* vm = &exec->vm();
666     NativeCallFrameTracer tracer(vm, exec);
667
668     Identifier ident(vm, uid);
669     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
670     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
671
672     JSValue baseValue = JSValue::decode(base);
673     PropertySlot slot(baseValue);
674     JSValue result = baseValue.get(exec, ident, slot);
675     
676     if (accessType == static_cast<AccessType>(stubInfo.accessType)) {
677         if (stubInfo.seen)
678             repatchGetByID(exec, baseValue, ident, slot, stubInfo);
679         else
680             stubInfo.seen = true;
681     }
682
683     return JSValue::encode(result);
684 }
685
686 J_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_ECI(operationInOptimize);
687 EncodedJSValue DFG_OPERATION operationInOptimizeWithReturnAddress(ExecState* exec, JSCell* base, StringImpl* key, ReturnAddressPtr returnAddress)
688 {
689     VM* vm = &exec->vm();
690     NativeCallFrameTracer tracer(vm, exec);
691     
692     if (!base->isObject()) {
693         vm->throwException(exec, createInvalidParameterError(exec, "in", base));
694         return JSValue::encode(jsUndefined());
695     }
696     
697     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
698     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
699
700     Identifier ident(vm, key);
701     PropertySlot slot(base);
702     bool result = asObject(base)->getPropertySlot(exec, ident, slot);
703     
704     RELEASE_ASSERT(accessType == stubInfo.accessType);
705     
706     if (stubInfo.seen)
707         repatchIn(exec, base, ident, result, slot, stubInfo);
708     else
709         stubInfo.seen = true;
710     
711     return JSValue::encode(jsBoolean(result));
712 }
713
714 EncodedJSValue DFG_OPERATION operationIn(ExecState* exec, JSCell* base, StringImpl* key)
715 {
716     VM* vm = &exec->vm();
717     NativeCallFrameTracer tracer(vm, exec);
718
719     if (!base->isObject()) {
720         vm->throwException(exec, createInvalidParameterError(exec, "in", base));
721         return JSValue::encode(jsUndefined());
722     }
723
724     Identifier ident(vm, key);
725     return JSValue::encode(jsBoolean(asObject(base)->hasProperty(exec, ident)));
726 }
727
728 EncodedJSValue DFG_OPERATION operationGenericIn(ExecState* exec, JSCell* base, EncodedJSValue key)
729 {
730     VM* vm = &exec->vm();
731     NativeCallFrameTracer tracer(vm, exec);
732
733     return JSValue::encode(jsBoolean(CommonSlowPaths::opIn(exec, JSValue::decode(key), base)));
734 }
735
736 EncodedJSValue DFG_OPERATION operationCallCustomGetter(ExecState* exec, JSCell* base, PropertySlot::GetValueFunc function, StringImpl* uid)
737 {
738     VM* vm = &exec->vm();
739     NativeCallFrameTracer tracer(vm, exec);
740     
741     Identifier ident(vm, uid);
742     
743     return JSValue::encode(function(exec, asObject(base), ident));
744 }
745
746 EncodedJSValue DFG_OPERATION operationCallGetter(ExecState* exec, JSCell* base, JSCell* getterSetter)
747 {
748     VM* vm = &exec->vm();
749     NativeCallFrameTracer tracer(vm, exec);
750
751     return JSValue::encode(callGetter(exec, base, getterSetter));
752 }
753
754 void DFG_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
755 {
756     VM* vm = &exec->vm();
757     NativeCallFrameTracer tracer(vm, exec);
758     
759     operationPutByValInternal<true>(exec, encodedBase, encodedProperty, encodedValue);
760 }
761
762 void DFG_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
763 {
764     VM* vm = &exec->vm();
765     NativeCallFrameTracer tracer(vm, exec);
766     
767     operationPutByValInternal<false>(exec, encodedBase, encodedProperty, encodedValue);
768 }
769
770 void DFG_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
771 {
772     VM* vm = &exec->vm();
773     NativeCallFrameTracer tracer(vm, exec);
774     
775     operationPutByValInternal<true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
776 }
777
778 void DFG_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
779 {
780     VM* vm = &exec->vm();
781     NativeCallFrameTracer tracer(vm, exec);
782     
783     operationPutByValInternal<false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
784 }
785
786 void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
787 {
788     VM* vm = &exec->vm();
789     NativeCallFrameTracer tracer(vm, exec);
790     
791     if (index >= 0) {
792         array->putByIndexInline(exec, index, JSValue::decode(encodedValue), true);
793         return;
794     }
795     
796     PutPropertySlot slot(true);
797     array->methodTable()->put(
798         array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
799 }
800
801 void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
802 {
803     VM* vm = &exec->vm();
804     NativeCallFrameTracer tracer(vm, exec);
805     
806     if (index >= 0) {
807         array->putByIndexInline(exec, index, JSValue::decode(encodedValue), false);
808         return;
809     }
810     
811     PutPropertySlot slot(false);
812     array->methodTable()->put(
813         array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
814 }
815
816 void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, double value)
817 {
818     VM* vm = &exec->vm();
819     NativeCallFrameTracer tracer(vm, exec);
820     
821     JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
822     
823     if (index >= 0) {
824         array->putByIndexInline(exec, index, jsValue, true);
825         return;
826     }
827     
828     PutPropertySlot slot(true);
829     array->methodTable()->put(
830         array, exec, Identifier::from(exec, index), jsValue, slot);
831 }
832
833 void DFG_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, double value)
834 {
835     VM* vm = &exec->vm();
836     NativeCallFrameTracer tracer(vm, exec);
837     
838     JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
839     
840     if (index >= 0) {
841         array->putByIndexInline(exec, index, jsValue, false);
842         return;
843     }
844     
845     PutPropertySlot slot(false);
846     array->methodTable()->put(
847         array, exec, Identifier::from(exec, index), jsValue, slot);
848 }
849
850 EncodedJSValue DFG_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
851 {
852     VM* vm = &exec->vm();
853     NativeCallFrameTracer tracer(vm, exec);
854     
855     array->push(exec, JSValue::decode(encodedValue));
856     return JSValue::encode(jsNumber(array->length()));
857 }
858
859 EncodedJSValue DFG_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array)
860 {
861     VM* vm = &exec->vm();
862     NativeCallFrameTracer tracer(vm, exec);
863     
864     array->push(exec, JSValue(JSValue::EncodeAsDouble, value));
865     return JSValue::encode(jsNumber(array->length()));
866 }
867
868 EncodedJSValue DFG_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
869 {
870     VM* vm = &exec->vm();
871     NativeCallFrameTracer tracer(vm, exec);
872     
873     return JSValue::encode(array->pop(exec));
874 }
875         
876 EncodedJSValue DFG_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array)
877 {
878     VM* vm = &exec->vm();
879     NativeCallFrameTracer tracer(vm, exec);
880     
881     array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1);
882     
883     return JSValue::encode(array->pop(exec));
884 }
885         
886 EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, JSCell* argument)
887 {
888     VM& vm = exec->vm();
889     NativeCallFrameTracer tracer(&vm, exec);
890     
891     if (!base->inherits(RegExpObject::info()))
892         return throwVMTypeError(exec);
893
894     ASSERT(argument->isString() || argument->isObject());
895     JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
896     return JSValue::encode(asRegExpObject(base)->exec(exec, input));
897 }
898         
899 size_t DFG_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell* argument)
900 {
901     VM& vm = exec->vm();
902     NativeCallFrameTracer tracer(&vm, exec);
903
904     if (!base->inherits(RegExpObject::info())) {
905         throwTypeError(exec);
906         return false;
907     }
908
909     ASSERT(argument->isString() || argument->isObject());
910     JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
911     return asRegExpObject(base)->test(exec, input);
912 }
913         
914 void DFG_OPERATION operationPutByIdStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, StringImpl* uid)
915 {
916     VM* vm = &exec->vm();
917     NativeCallFrameTracer tracer(vm, exec);
918     
919     Identifier ident(vm, uid);
920     PutPropertySlot slot(true, exec->codeBlock()->putByIdContext());
921     base->methodTable()->put(base, exec, ident, JSValue::decode(encodedValue), slot);
922 }
923
924 void DFG_OPERATION operationPutByIdNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, StringImpl* uid)
925 {
926     VM* vm = &exec->vm();
927     NativeCallFrameTracer tracer(vm, exec);
928     
929     Identifier ident(vm, uid);
930     PutPropertySlot slot(false, exec->codeBlock()->putByIdContext());
931     base->methodTable()->put(base, exec, ident, JSValue::decode(encodedValue), slot);
932 }
933
934 void DFG_OPERATION operationPutByIdDirectStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, StringImpl* uid)
935 {
936     VM* vm = &exec->vm();
937     NativeCallFrameTracer tracer(vm, exec);
938     
939     Identifier ident(vm, uid);
940     PutPropertySlot slot(true, exec->codeBlock()->putByIdContext());
941     ASSERT(base->isObject());
942     asObject(base)->putDirect(exec->vm(), ident, JSValue::decode(encodedValue), slot);
943 }
944
945 void DFG_OPERATION operationPutByIdDirectNonStrict(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, StringImpl* uid)
946 {
947     VM* vm = &exec->vm();
948     NativeCallFrameTracer tracer(vm, exec);
949     
950     Identifier ident(vm, uid);
951     PutPropertySlot slot(false, exec->codeBlock()->putByIdContext());
952     ASSERT(base->isObject());
953     asObject(base)->putDirect(exec->vm(), ident, JSValue::decode(encodedValue), slot);
954 }
955
956 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictOptimize);
957 void DFG_OPERATION operationPutByIdStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, StringImpl* uid, ReturnAddressPtr returnAddress)
958 {
959     VM* vm = &exec->vm();
960     NativeCallFrameTracer tracer(vm, exec);
961     
962     Identifier ident(vm, uid);
963     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
964     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
965
966     JSValue value = JSValue::decode(encodedValue);
967     JSValue baseValue(base);
968     PutPropertySlot slot(true, exec->codeBlock()->putByIdContext());
969     
970     baseValue.put(exec, ident, value, slot);
971     
972     if (accessType != static_cast<AccessType>(stubInfo.accessType))
973         return;
974     
975     if (stubInfo.seen)
976         repatchPutByID(exec, baseValue, ident, slot, stubInfo, NotDirect);
977     else
978         stubInfo.seen = true;
979 }
980
981 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictOptimize);
982 void DFG_OPERATION operationPutByIdNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, StringImpl* uid, ReturnAddressPtr returnAddress)
983 {
984     VM* vm = &exec->vm();
985     NativeCallFrameTracer tracer(vm, exec);
986     
987     Identifier ident(vm, uid);
988     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
989     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
990
991     JSValue value = JSValue::decode(encodedValue);
992     JSValue baseValue(base);
993     PutPropertySlot slot(false, exec->codeBlock()->putByIdContext());
994     
995     baseValue.put(exec, ident, value, slot);
996     
997     if (accessType != static_cast<AccessType>(stubInfo.accessType))
998         return;
999     
1000     if (stubInfo.seen)
1001         repatchPutByID(exec, baseValue, ident, slot, stubInfo, NotDirect);
1002     else
1003         stubInfo.seen = true;
1004 }
1005
1006 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictOptimize);
1007 void DFG_OPERATION operationPutByIdDirectStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, StringImpl* uid, ReturnAddressPtr returnAddress)
1008 {
1009     VM* vm = &exec->vm();
1010     NativeCallFrameTracer tracer(vm, exec);
1011     
1012     Identifier ident(vm, uid);
1013     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
1014     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
1015
1016     JSValue value = JSValue::decode(encodedValue);
1017     PutPropertySlot slot(true, exec->codeBlock()->putByIdContext());
1018     
1019     ASSERT(base->isObject());
1020     asObject(base)->putDirect(exec->vm(), ident, value, slot);
1021     
1022     if (accessType != static_cast<AccessType>(stubInfo.accessType))
1023         return;
1024     
1025     if (stubInfo.seen)
1026         repatchPutByID(exec, base, ident, slot, stubInfo, Direct);
1027     else
1028         stubInfo.seen = true;
1029 }
1030
1031 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictOptimize);
1032 void DFG_OPERATION operationPutByIdDirectNonStrictOptimizeWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, StringImpl* uid, ReturnAddressPtr returnAddress)
1033 {
1034     VM* vm = &exec->vm();
1035     NativeCallFrameTracer tracer(vm, exec);
1036     
1037     Identifier ident(vm, uid);
1038     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
1039     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
1040
1041     JSValue value = JSValue::decode(encodedValue);
1042     PutPropertySlot slot(false, exec->codeBlock()->putByIdContext());
1043     
1044     ASSERT(base->isObject());
1045     asObject(base)->putDirect(exec->vm(), ident, value, slot);
1046     
1047     if (accessType != static_cast<AccessType>(stubInfo.accessType))
1048         return;
1049     
1050     if (stubInfo.seen)
1051         repatchPutByID(exec, base, ident, slot, stubInfo, Direct);
1052     else
1053         stubInfo.seen = true;
1054 }
1055
1056 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdStrictBuildList);
1057 void DFG_OPERATION operationPutByIdStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, StringImpl* uid, ReturnAddressPtr returnAddress)
1058 {
1059     VM* vm = &exec->vm();
1060     NativeCallFrameTracer tracer(vm, exec);
1061     
1062     Identifier ident(vm, uid);
1063     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
1064     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
1065
1066     JSValue value = JSValue::decode(encodedValue);
1067     JSValue baseValue(base);
1068     PutPropertySlot slot(true, exec->codeBlock()->putByIdContext());
1069     
1070     baseValue.put(exec, ident, value, slot);
1071     
1072     if (accessType != static_cast<AccessType>(stubInfo.accessType))
1073         return;
1074     
1075     buildPutByIdList(exec, baseValue, ident, slot, stubInfo, NotDirect);
1076 }
1077
1078 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdNonStrictBuildList);
1079 void DFG_OPERATION operationPutByIdNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, StringImpl* uid, ReturnAddressPtr returnAddress)
1080 {
1081     VM* vm = &exec->vm();
1082     NativeCallFrameTracer tracer(vm, exec);
1083     
1084     Identifier ident(vm, uid);
1085     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
1086     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
1087
1088     JSValue value = JSValue::decode(encodedValue);
1089     JSValue baseValue(base);
1090     PutPropertySlot slot(false, exec->codeBlock()->putByIdContext());
1091     
1092     baseValue.put(exec, ident, value, slot);
1093     
1094     if (accessType != static_cast<AccessType>(stubInfo.accessType))
1095         return;
1096     
1097     buildPutByIdList(exec, baseValue, ident, slot, stubInfo, NotDirect);
1098 }
1099
1100 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectStrictBuildList);
1101 void DFG_OPERATION operationPutByIdDirectStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, StringImpl* uid, ReturnAddressPtr returnAddress)
1102 {
1103     VM* vm = &exec->vm();
1104     NativeCallFrameTracer tracer(vm, exec);
1105     
1106     Identifier ident(vm, uid);
1107     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
1108     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
1109     
1110     JSValue value = JSValue::decode(encodedValue);
1111     PutPropertySlot slot(true, exec->codeBlock()->putByIdContext());
1112     
1113     ASSERT(base->isObject());
1114     asObject(base)->putDirect(exec->vm(), ident, value, slot);
1115     
1116     if (accessType != static_cast<AccessType>(stubInfo.accessType))
1117         return;
1118     
1119     buildPutByIdList(exec, base, ident, slot, stubInfo, Direct);
1120 }
1121
1122 V_FUNCTION_WRAPPER_WITH_RETURN_ADDRESS_EJCI(operationPutByIdDirectNonStrictBuildList);
1123 void DFG_OPERATION operationPutByIdDirectNonStrictBuildListWithReturnAddress(ExecState* exec, EncodedJSValue encodedValue, JSCell* base, StringImpl* uid, ReturnAddressPtr returnAddress)
1124 {
1125     VM* vm = &exec->vm();
1126     NativeCallFrameTracer tracer(vm, exec);
1127     
1128     Identifier ident(vm, uid);
1129     StructureStubInfo& stubInfo = exec->codeBlock()->getStubInfo(returnAddress);
1130     AccessType accessType = static_cast<AccessType>(stubInfo.accessType);
1131
1132     JSValue value = JSValue::decode(encodedValue);
1133     PutPropertySlot slot(false, exec->codeBlock()->putByIdContext());
1134     
1135     ASSERT(base->isObject());
1136     asObject(base)->putDirect(exec->vm(), ident, value, slot);
1137     
1138     if (accessType != static_cast<AccessType>(stubInfo.accessType))
1139         return;
1140     
1141     buildPutByIdList(exec, base, ident, slot, stubInfo, Direct);
1142 }
1143
1144 size_t DFG_OPERATION operationCompareLess(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1145 {
1146     VM* vm = &exec->vm();
1147     NativeCallFrameTracer tracer(vm, exec);
1148     
1149     return jsLess<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
1150 }
1151
1152 size_t DFG_OPERATION operationCompareLessEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1153 {
1154     VM* vm = &exec->vm();
1155     NativeCallFrameTracer tracer(vm, exec);
1156     
1157     return jsLessEq<true>(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
1158 }
1159
1160 size_t DFG_OPERATION operationCompareGreater(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1161 {
1162     VM* vm = &exec->vm();
1163     NativeCallFrameTracer tracer(vm, exec);
1164     
1165     return jsLess<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
1166 }
1167
1168 size_t DFG_OPERATION operationCompareGreaterEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1169 {
1170     VM* vm = &exec->vm();
1171     NativeCallFrameTracer tracer(vm, exec);
1172     
1173     return jsLessEq<false>(exec, JSValue::decode(encodedOp2), JSValue::decode(encodedOp1));
1174 }
1175
1176 size_t DFG_OPERATION operationCompareEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1177 {
1178     VM* vm = &exec->vm();
1179     NativeCallFrameTracer tracer(vm, exec);
1180     
1181     return JSValue::equalSlowCaseInline(exec, JSValue::decode(encodedOp1), JSValue::decode(encodedOp2));
1182 }
1183
1184 #if USE(JSVALUE64)
1185 EncodedJSValue DFG_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right)
1186 #else
1187 size_t DFG_OPERATION operationCompareStringEq(ExecState* exec, JSCell* left, JSCell* right)
1188 #endif
1189 {
1190     VM* vm = &exec->vm();
1191     NativeCallFrameTracer tracer(vm, exec);
1192     
1193     bool result = asString(left)->value(exec) == asString(right)->value(exec);
1194 #if USE(JSVALUE64)
1195     return JSValue::encode(jsBoolean(result));
1196 #else
1197     return result;
1198 #endif
1199 }
1200
1201 size_t DFG_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1202 {
1203     VM* vm = &exec->vm();
1204     NativeCallFrameTracer tracer(vm, exec);
1205     
1206     JSValue op1 = JSValue::decode(encodedOp1);
1207     JSValue op2 = JSValue::decode(encodedOp2);
1208     
1209     ASSERT(op1.isCell());
1210     ASSERT(op2.isCell());
1211     
1212     return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
1213 }
1214
1215 size_t DFG_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
1216 {
1217     VM* vm = &exec->vm();
1218     NativeCallFrameTracer tracer(vm, exec);
1219
1220     JSValue src1 = JSValue::decode(encodedOp1);
1221     JSValue src2 = JSValue::decode(encodedOp2);
1222     
1223     return JSValue::strictEqual(exec, src1, src2);
1224 }
1225
1226 static void* handleHostCall(ExecState* execCallee, JSValue callee, CodeSpecializationKind kind)
1227 {
1228     ExecState* exec = execCallee->callerFrame();
1229     VM* vm = &exec->vm();
1230
1231     execCallee->setScope(exec->scope());
1232     execCallee->setCodeBlock(0);
1233
1234     if (kind == CodeForCall) {
1235         CallData callData;
1236         CallType callType = getCallData(callee, callData);
1237     
1238         ASSERT(callType != CallTypeJS);
1239     
1240         if (callType == CallTypeHost) {
1241             NativeCallFrameTracer tracer(vm, execCallee);
1242             execCallee->setCallee(asObject(callee));
1243             vm->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
1244             if (vm->exception())
1245                 return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
1246
1247             return reinterpret_cast<void*>(getHostCallReturnValue);
1248         }
1249     
1250         ASSERT(callType == CallTypeNone);
1251         exec->vm().throwException(exec, createNotAFunctionError(exec, callee));
1252         return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
1253     }
1254
1255     ASSERT(kind == CodeForConstruct);
1256     
1257     ConstructData constructData;
1258     ConstructType constructType = getConstructData(callee, constructData);
1259     
1260     ASSERT(constructType != ConstructTypeJS);
1261     
1262     if (constructType == ConstructTypeHost) {
1263         NativeCallFrameTracer tracer(vm, execCallee);
1264         execCallee->setCallee(asObject(callee));
1265         vm->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
1266         if (vm->exception())
1267             return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
1268
1269         return reinterpret_cast<void*>(getHostCallReturnValue);
1270     }
1271     
1272     ASSERT(constructType == ConstructTypeNone);
1273     exec->vm().throwException(exec, createNotAConstructorError(exec, callee));
1274     return vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress();
1275 }
1276
1277 inline char* linkFor(ExecState* execCallee, CodeSpecializationKind kind)
1278 {
1279     ExecState* exec = execCallee->callerFrame();
1280     VM* vm = &exec->vm();
1281     NativeCallFrameTracer tracer(vm, exec);
1282     
1283     JSValue calleeAsValue = execCallee->calleeAsValue();
1284     JSCell* calleeAsFunctionCell = getJSFunction(calleeAsValue);
1285     if (!calleeAsFunctionCell)
1286         return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
1287
1288     JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1289     execCallee->setScope(callee->scopeUnchecked());
1290     ExecutableBase* executable = callee->executable();
1291
1292     MacroAssemblerCodePtr codePtr;
1293     CodeBlock* codeBlock = 0;
1294     if (executable->isHostFunction())
1295         codePtr = executable->generatedJITCodeFor(kind)->addressForCall();
1296     else {
1297         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1298         JSObject* error = functionExecutable->prepareForExecution(execCallee, callee->scope(), kind);
1299         if (error) {
1300             vm->throwException(exec, createStackOverflowError(exec));
1301             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
1302         }
1303         codeBlock = functionExecutable->codeBlockFor(kind);
1304         if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1305             codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
1306         else
1307             codePtr = functionExecutable->generatedJITCodeFor(kind)->addressForCall();
1308     }
1309     CallLinkInfo& callLinkInfo = exec->codeBlock()->getCallLinkInfo(execCallee->returnPC());
1310     if (!callLinkInfo.seenOnce())
1311         callLinkInfo.setSeen();
1312     else
1313         linkFor(execCallee, callLinkInfo, codeBlock, callee, codePtr, kind);
1314     return reinterpret_cast<char*>(codePtr.executableAddress());
1315 }
1316
1317 char* DFG_OPERATION operationLinkCall(ExecState* execCallee)
1318 {
1319     return linkFor(execCallee, CodeForCall);
1320 }
1321
1322 char* DFG_OPERATION operationLinkConstruct(ExecState* execCallee)
1323 {
1324     return linkFor(execCallee, CodeForConstruct);
1325 }
1326
1327 inline char* virtualForWithFunction(ExecState* execCallee, CodeSpecializationKind kind, JSCell*& calleeAsFunctionCell)
1328 {
1329     ExecState* exec = execCallee->callerFrame();
1330     VM* vm = &exec->vm();
1331     NativeCallFrameTracer tracer(vm, exec);
1332
1333     JSValue calleeAsValue = execCallee->calleeAsValue();
1334     calleeAsFunctionCell = getJSFunction(calleeAsValue);
1335     if (UNLIKELY(!calleeAsFunctionCell))
1336         return reinterpret_cast<char*>(handleHostCall(execCallee, calleeAsValue, kind));
1337     
1338     JSFunction* function = jsCast<JSFunction*>(calleeAsFunctionCell);
1339     execCallee->setScope(function->scopeUnchecked());
1340     ExecutableBase* executable = function->executable();
1341     if (UNLIKELY(!executable->hasJITCodeFor(kind))) {
1342         FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
1343         JSObject* error = functionExecutable->prepareForExecution(execCallee, function->scope(), kind);
1344         if (error) {
1345             exec->vm().throwException(execCallee, error);
1346             return reinterpret_cast<char*>(vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress());
1347         }
1348     }
1349     return reinterpret_cast<char*>(executable->generatedJITCodeWithArityCheckFor(kind).executableAddress());
1350 }
1351
1352 inline char* virtualFor(ExecState* execCallee, CodeSpecializationKind kind)
1353 {
1354     JSCell* calleeAsFunctionCellIgnored;
1355     return virtualForWithFunction(execCallee, kind, calleeAsFunctionCellIgnored);
1356 }
1357
1358 static bool attemptToOptimizeClosureCall(ExecState* execCallee, JSCell* calleeAsFunctionCell, CallLinkInfo& callLinkInfo)
1359 {
1360     if (!calleeAsFunctionCell)
1361         return false;
1362     
1363     JSFunction* callee = jsCast<JSFunction*>(calleeAsFunctionCell);
1364     JSFunction* oldCallee = callLinkInfo.callee.get();
1365     
1366     if (!oldCallee
1367         || oldCallee->structure() != callee->structure()
1368         || oldCallee->executable() != callee->executable())
1369         return false;
1370     
1371     ASSERT(callee->executable()->hasJITCodeForCall());
1372     MacroAssemblerCodePtr codePtr = callee->executable()->generatedJITCodeForCall()->addressForCall();
1373     
1374     CodeBlock* codeBlock;
1375     if (callee->executable()->isHostFunction())
1376         codeBlock = 0;
1377     else {
1378         codeBlock = jsCast<FunctionExecutable*>(callee->executable())->codeBlockForCall();
1379         if (execCallee->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters()))
1380             return false;
1381     }
1382     
1383     linkClosureCall(
1384         execCallee, callLinkInfo, codeBlock,
1385         callee->structure(), callee->executable(), codePtr);
1386     
1387     return true;
1388 }
1389
1390 char* DFG_OPERATION operationLinkClosureCall(ExecState* execCallee)
1391 {
1392     JSCell* calleeAsFunctionCell;
1393     char* result = virtualForWithFunction(execCallee, CodeForCall, calleeAsFunctionCell);
1394     CallLinkInfo& callLinkInfo = execCallee->callerFrame()->codeBlock()->getCallLinkInfo(execCallee->returnPC());
1395
1396     if (!attemptToOptimizeClosureCall(execCallee, calleeAsFunctionCell, callLinkInfo))
1397         linkSlowFor(execCallee, callLinkInfo, CodeForCall);
1398     
1399     return result;
1400 }
1401
1402 char* DFG_OPERATION operationVirtualCall(ExecState* execCallee)
1403 {    
1404     return virtualFor(execCallee, CodeForCall);
1405 }
1406
1407 char* DFG_OPERATION operationVirtualConstruct(ExecState* execCallee)
1408 {
1409     return virtualFor(execCallee, CodeForConstruct);
1410 }
1411
1412 EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
1413 {
1414     VM* vm = &exec->vm();
1415     NativeCallFrameTracer tracer(vm, exec);
1416     
1417     return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
1418 }
1419
1420 char* DFG_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size)
1421 {
1422     VM* vm = &exec->vm();
1423     NativeCallFrameTracer tracer(vm, exec);
1424     
1425     return bitwise_cast<char*>(constructArrayNegativeIndexed(exec, arrayStructure, static_cast<JSValue*>(buffer), size));
1426 }
1427
1428 char* DFG_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure)
1429 {
1430     VM* vm = &exec->vm();
1431     NativeCallFrameTracer tracer(vm, exec);
1432     
1433     return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure));
1434 }
1435
1436 char* DFG_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size)
1437 {
1438     VM* vm = &exec->vm();
1439     NativeCallFrameTracer tracer(vm, exec);
1440
1441     if (UNLIKELY(size < 0))
1442         return bitwise_cast<char*>(exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))));
1443
1444     return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure, size));
1445 }
1446
1447 char* DFG_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, size_t start, size_t size)
1448 {
1449     VM& vm = exec->vm();
1450     NativeCallFrameTracer tracer(&vm, exec);
1451     return bitwise_cast<char*>(constructArrayNegativeIndexed(exec, arrayStructure, exec->codeBlock()->constantBuffer(start), size));
1452 }
1453
1454 char* DFG_OPERATION operationNewInt8ArrayWithSize(
1455     ExecState* exec, Structure* structure, int32_t length)
1456 {
1457     return newTypedArrayWithSize<JSInt8Array>(exec, structure, length);
1458 }
1459
1460 char* DFG_OPERATION operationNewInt8ArrayWithOneArgument(
1461     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1462 {
1463     return newTypedArrayWithOneArgument<JSInt8Array>(exec, structure, encodedValue);
1464 }
1465
1466 char* DFG_OPERATION operationNewInt16ArrayWithSize(
1467     ExecState* exec, Structure* structure, int32_t length)
1468 {
1469     return newTypedArrayWithSize<JSInt16Array>(exec, structure, length);
1470 }
1471
1472 char* DFG_OPERATION operationNewInt16ArrayWithOneArgument(
1473     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1474 {
1475     return newTypedArrayWithOneArgument<JSInt16Array>(exec, structure, encodedValue);
1476 }
1477
1478 char* DFG_OPERATION operationNewInt32ArrayWithSize(
1479     ExecState* exec, Structure* structure, int32_t length)
1480 {
1481     return newTypedArrayWithSize<JSInt32Array>(exec, structure, length);
1482 }
1483
1484 char* DFG_OPERATION operationNewInt32ArrayWithOneArgument(
1485     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1486 {
1487     return newTypedArrayWithOneArgument<JSInt32Array>(exec, structure, encodedValue);
1488 }
1489
1490 char* DFG_OPERATION operationNewUint8ArrayWithSize(
1491     ExecState* exec, Structure* structure, int32_t length)
1492 {
1493     return newTypedArrayWithSize<JSUint8Array>(exec, structure, length);
1494 }
1495
1496 char* DFG_OPERATION operationNewUint8ArrayWithOneArgument(
1497     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1498 {
1499     return newTypedArrayWithOneArgument<JSUint8Array>(exec, structure, encodedValue);
1500 }
1501
1502 char* DFG_OPERATION operationNewUint8ClampedArrayWithSize(
1503     ExecState* exec, Structure* structure, int32_t length)
1504 {
1505     return newTypedArrayWithSize<JSUint8ClampedArray>(exec, structure, length);
1506 }
1507
1508 char* DFG_OPERATION operationNewUint8ClampedArrayWithOneArgument(
1509     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1510 {
1511     return newTypedArrayWithOneArgument<JSUint8ClampedArray>(exec, structure, encodedValue);
1512 }
1513
1514 char* DFG_OPERATION operationNewUint16ArrayWithSize(
1515     ExecState* exec, Structure* structure, int32_t length)
1516 {
1517     return newTypedArrayWithSize<JSUint16Array>(exec, structure, length);
1518 }
1519
1520 char* DFG_OPERATION operationNewUint16ArrayWithOneArgument(
1521     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1522 {
1523     return newTypedArrayWithOneArgument<JSUint16Array>(exec, structure, encodedValue);
1524 }
1525
1526 char* DFG_OPERATION operationNewUint32ArrayWithSize(
1527     ExecState* exec, Structure* structure, int32_t length)
1528 {
1529     return newTypedArrayWithSize<JSUint32Array>(exec, structure, length);
1530 }
1531
1532 char* DFG_OPERATION operationNewUint32ArrayWithOneArgument(
1533     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1534 {
1535     return newTypedArrayWithOneArgument<JSUint32Array>(exec, structure, encodedValue);
1536 }
1537
1538 char* DFG_OPERATION operationNewFloat32ArrayWithSize(
1539     ExecState* exec, Structure* structure, int32_t length)
1540 {
1541     return newTypedArrayWithSize<JSFloat32Array>(exec, structure, length);
1542 }
1543
1544 char* DFG_OPERATION operationNewFloat32ArrayWithOneArgument(
1545     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1546 {
1547     return newTypedArrayWithOneArgument<JSFloat32Array>(exec, structure, encodedValue);
1548 }
1549
1550 char* DFG_OPERATION operationNewFloat64ArrayWithSize(
1551     ExecState* exec, Structure* structure, int32_t length)
1552 {
1553     return newTypedArrayWithSize<JSFloat64Array>(exec, structure, length);
1554 }
1555
1556 char* DFG_OPERATION operationNewFloat64ArrayWithOneArgument(
1557     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
1558 {
1559     return newTypedArrayWithOneArgument<JSFloat64Array>(exec, structure, encodedValue);
1560 }
1561
1562 EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState* exec, void* regexpPtr)
1563 {
1564     VM& vm = exec->vm();
1565     NativeCallFrameTracer tracer(&vm, exec);
1566     RegExp* regexp = static_cast<RegExp*>(regexpPtr);
1567     if (!regexp->isValid()) {
1568         exec->vm().throwException(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
1569         return JSValue::encode(jsUndefined());
1570     }
1571     
1572     return JSValue::encode(RegExpObject::create(exec->vm(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regexp));
1573 }
1574
1575 JSCell* DFG_OPERATION operationCreateActivation(ExecState* exec)
1576 {
1577     VM& vm = exec->vm();
1578     NativeCallFrameTracer tracer(&vm, exec);
1579     JSActivation* activation = JSActivation::create(vm, exec, exec->codeBlock());
1580     exec->setScope(activation);
1581     return activation;
1582 }
1583
1584 JSCell* DFG_OPERATION operationCreateArguments(ExecState* exec)
1585 {
1586     VM& vm = exec->vm();
1587     NativeCallFrameTracer tracer(&vm, exec);
1588     // NB: This needs to be exceedingly careful with top call frame tracking, since it
1589     // may be called from OSR exit, while the state of the call stack is bizarre.
1590     Arguments* result = Arguments::create(vm, exec);
1591     ASSERT(!vm.exception());
1592     return result;
1593 }
1594
1595 JSCell* DFG_OPERATION operationCreateInlinedArguments(
1596     ExecState* exec, InlineCallFrame* inlineCallFrame)
1597 {
1598     VM& vm = exec->vm();
1599     NativeCallFrameTracer tracer(&vm, exec);
1600     // NB: This needs to be exceedingly careful with top call frame tracking, since it
1601     // may be called from OSR exit, while the state of the call stack is bizarre.
1602     Arguments* result = Arguments::create(vm, exec, inlineCallFrame);
1603     ASSERT(!vm.exception());
1604     return result;
1605 }
1606
1607 void DFG_OPERATION operationTearOffArguments(ExecState* exec, JSCell* argumentsCell, JSCell* activationCell)
1608 {
1609     ASSERT(exec->codeBlock()->usesArguments());
1610     if (activationCell) {
1611         jsCast<Arguments*>(argumentsCell)->didTearOffActivation(exec, jsCast<JSActivation*>(activationCell));
1612         return;
1613     }
1614     jsCast<Arguments*>(argumentsCell)->tearOff(exec);
1615 }
1616
1617 void DFG_OPERATION operationTearOffInlinedArguments(
1618     ExecState* exec, JSCell* argumentsCell, JSCell* activationCell, InlineCallFrame* inlineCallFrame)
1619 {
1620     ASSERT_UNUSED(activationCell, !activationCell); // Currently, we don't inline functions with activations.
1621     jsCast<Arguments*>(argumentsCell)->tearOff(exec, inlineCallFrame);
1622 }
1623
1624 EncodedJSValue DFG_OPERATION operationGetArgumentsLength(ExecState* exec, int32_t argumentsRegister)
1625 {
1626     VM& vm = exec->vm();
1627     NativeCallFrameTracer tracer(&vm, exec);
1628     // Here we can assume that the argumernts were created. Because otherwise the JIT code would
1629     // have not made this call.
1630     Identifier ident(&vm, "length");
1631     JSValue baseValue = exec->uncheckedR(argumentsRegister).jsValue();
1632     PropertySlot slot(baseValue);
1633     return JSValue::encode(baseValue.get(exec, ident, slot));
1634 }
1635
1636 EncodedJSValue DFG_OPERATION operationGetArgumentByVal(ExecState* exec, int32_t argumentsRegister, int32_t index)
1637 {
1638     VM& vm = exec->vm();
1639     NativeCallFrameTracer tracer(&vm, exec);
1640
1641     JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
1642     
1643     // If there are no arguments, and we're accessing out of bounds, then we have to create the
1644     // arguments in case someone has installed a getter on a numeric property.
1645     if (!argumentsValue)
1646         exec->uncheckedR(argumentsRegister) = argumentsValue = Arguments::create(exec->vm(), exec);
1647     
1648     return JSValue::encode(argumentsValue.get(exec, index));
1649 }
1650
1651 EncodedJSValue DFG_OPERATION operationGetInlinedArgumentByVal(
1652     ExecState* exec, int32_t argumentsRegister, InlineCallFrame* inlineCallFrame, int32_t index)
1653 {
1654     VM& vm = exec->vm();
1655     NativeCallFrameTracer tracer(&vm, exec);
1656
1657     JSValue argumentsValue = exec->uncheckedR(argumentsRegister).jsValue();
1658     
1659     // If there are no arguments, and we're accessing out of bounds, then we have to create the
1660     // arguments in case someone has installed a getter on a numeric property.
1661     if (!argumentsValue) {
1662         exec->uncheckedR(argumentsRegister) = argumentsValue =
1663             Arguments::create(exec->vm(), exec, inlineCallFrame);
1664     }
1665     
1666     return JSValue::encode(argumentsValue.get(exec, index));
1667 }
1668
1669 JSCell* DFG_OPERATION operationNewFunctionNoCheck(ExecState* exec, JSCell* functionExecutable)
1670 {
1671     ASSERT(functionExecutable->inherits(FunctionExecutable::info()));
1672     VM& vm = exec->vm();
1673     NativeCallFrameTracer tracer(&vm, exec);
1674     return JSFunction::create(exec, static_cast<FunctionExecutable*>(functionExecutable), exec->scope());
1675 }
1676
1677 EncodedJSValue DFG_OPERATION operationNewFunction(ExecState* exec, JSCell* functionExecutable)
1678 {
1679     ASSERT(functionExecutable->inherits(FunctionExecutable::info()));
1680     VM& vm = exec->vm();
1681     NativeCallFrameTracer tracer(&vm, exec);
1682     return JSValue::encode(JSFunction::create(exec, static_cast<FunctionExecutable*>(functionExecutable), exec->scope()));
1683 }
1684
1685 JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState* exec, JSCell* functionExecutableAsCell)
1686 {
1687     ASSERT(functionExecutableAsCell->inherits(FunctionExecutable::info()));
1688
1689     VM& vm = exec->vm();
1690     NativeCallFrameTracer tracer(&vm, exec);
1691
1692     FunctionExecutable* functionExecutable =
1693         static_cast<FunctionExecutable*>(functionExecutableAsCell);
1694     return JSFunction::create(exec, functionExecutable, exec->scope());
1695 }
1696
1697 size_t DFG_OPERATION operationIsObject(ExecState* exec, EncodedJSValue value)
1698 {
1699     return jsIsObjectType(exec, JSValue::decode(value));
1700 }
1701
1702 size_t DFG_OPERATION operationIsFunction(EncodedJSValue value)
1703 {
1704     return jsIsFunctionType(JSValue::decode(value));
1705 }
1706
1707 JSCell* DFG_OPERATION operationTypeOf(ExecState* exec, JSCell* value)
1708 {
1709     return jsTypeStringForValue(exec, JSValue(value)).asCell();
1710 }
1711
1712 void DFG_OPERATION operationReallocateStorageAndFinishPut(ExecState* exec, JSObject* base, Structure* structure, PropertyOffset offset, EncodedJSValue value)
1713 {
1714     VM& vm = exec->vm();
1715     NativeCallFrameTracer tracer(&vm, exec);
1716
1717     ASSERT(structure->outOfLineCapacity() > base->structure()->outOfLineCapacity());
1718     ASSERT(!vm.heap.storageAllocator().fastPathShouldSucceed(structure->outOfLineCapacity() * sizeof(JSValue)));
1719     base->setStructureAndReallocateStorageIfNecessary(vm, structure);
1720     base->putDirect(vm, offset, JSValue::decode(value));
1721 }
1722
1723 char* DFG_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec)
1724 {
1725     VM& vm = exec->vm();
1726     NativeCallFrameTracer tracer(&vm, exec);
1727
1728     return reinterpret_cast<char*>(
1729         Butterfly::createUninitialized(vm, 0, 0, initialOutOfLineCapacity, false, 0));
1730 }
1731
1732 char* DFG_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize)
1733 {
1734     VM& vm = exec->vm();
1735     NativeCallFrameTracer tracer(&vm, exec);
1736
1737     return reinterpret_cast<char*>(
1738         Butterfly::createUninitialized(vm, 0, 0, newSize, false, 0));
1739 }
1740
1741 char* DFG_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
1742 {
1743     VM& vm = exec->vm();
1744     NativeCallFrameTracer tracer(&vm, exec);
1745
1746     ASSERT(!object->structure()->outOfLineCapacity());
1747     Butterfly* result = object->growOutOfLineStorage(vm, 0, initialOutOfLineCapacity);
1748     object->setButterflyWithoutChangingStructure(result);
1749     return reinterpret_cast<char*>(result);
1750 }
1751
1752 char* DFG_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState* exec, JSObject* object, size_t newSize)
1753 {
1754     VM& vm = exec->vm();
1755     NativeCallFrameTracer tracer(&vm, exec);
1756
1757     Butterfly* result = object->growOutOfLineStorage(vm, object->structure()->outOfLineCapacity(), newSize);
1758     object->setButterflyWithoutChangingStructure(result);
1759     return reinterpret_cast<char*>(result);
1760 }
1761
1762 char* DFG_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
1763 {
1764     VM& vm = exec->vm();
1765     NativeCallFrameTracer tracer(&vm, exec);
1766     
1767     if (!cell->isObject())
1768         return 0;
1769     
1770     return reinterpret_cast<char*>(asObject(cell)->ensureInt32(vm).data());
1771 }
1772
1773 char* DFG_OPERATION operationEnsureDouble(ExecState* exec, JSCell* cell)
1774 {
1775     VM& vm = exec->vm();
1776     NativeCallFrameTracer tracer(&vm, exec);
1777     
1778     if (!cell->isObject())
1779         return 0;
1780     
1781     return reinterpret_cast<char*>(asObject(cell)->ensureDouble(vm).data());
1782 }
1783
1784 char* DFG_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell)
1785 {
1786     VM& vm = exec->vm();
1787     NativeCallFrameTracer tracer(&vm, exec);
1788     
1789     if (!cell->isObject())
1790         return 0;
1791     
1792     return reinterpret_cast<char*>(asObject(cell)->ensureContiguous(vm).data());
1793 }
1794
1795 char* DFG_OPERATION operationRageEnsureContiguous(ExecState* exec, JSCell* cell)
1796 {
1797     VM& vm = exec->vm();
1798     NativeCallFrameTracer tracer(&vm, exec);
1799     
1800     if (!cell->isObject())
1801         return 0;
1802     
1803     return reinterpret_cast<char*>(asObject(cell)->rageEnsureContiguous(vm).data());
1804 }
1805
1806 char* DFG_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell)
1807 {
1808     VM& vm = exec->vm();
1809     NativeCallFrameTracer tracer(&vm, exec);
1810     
1811     if (!cell->isObject())
1812         return 0;
1813
1814     return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm));
1815 }
1816
1817 StringImpl* DFG_OPERATION operationResolveRope(ExecState* exec, JSString* string)
1818 {
1819     VM& vm = exec->vm();
1820     NativeCallFrameTracer tracer(&vm, exec);
1821
1822     return string->value(exec).impl();
1823 }
1824
1825 JSString* DFG_OPERATION operationSingleCharacterString(ExecState* exec, int32_t character)
1826 {
1827     VM& vm = exec->vm();
1828     NativeCallFrameTracer tracer(&vm, exec);
1829     
1830     return jsSingleCharacterString(exec, static_cast<UChar>(character));
1831 }
1832
1833 JSCell* DFG_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
1834 {
1835     VM& vm = exec->vm();
1836     NativeCallFrameTracer tracer(&vm, exec);
1837     
1838     return StringObject::create(exec, structure, string);
1839 }
1840
1841 JSCell* DFG_OPERATION operationToStringOnCell(ExecState* exec, JSCell* cell)
1842 {
1843     VM& vm = exec->vm();
1844     NativeCallFrameTracer tracer(&vm, exec);
1845     
1846     return JSValue(cell).toString(exec);
1847 }
1848
1849 JSCell* DFG_OPERATION operationToString(ExecState* exec, EncodedJSValue value)
1850 {
1851     VM& vm = exec->vm();
1852     NativeCallFrameTracer tracer(&vm, exec);
1853
1854     return JSValue::decode(value).toString(exec);
1855 }
1856
1857 JSCell* DFG_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right)
1858 {
1859     VM& vm = exec->vm();
1860     NativeCallFrameTracer tracer(&vm, exec);
1861
1862     return JSRopeString::create(vm, left, right);
1863 }
1864
1865 JSCell* DFG_OPERATION operationMakeRope3(ExecState* exec, JSString* a, JSString* b, JSString* c)
1866 {
1867     VM& vm = exec->vm();
1868     NativeCallFrameTracer tracer(&vm, exec);
1869
1870     return JSRopeString::create(vm, a, b, c);
1871 }
1872
1873 char* DFG_OPERATION operationFindSwitchImmTargetForDouble(
1874     ExecState* exec, EncodedJSValue encodedValue, size_t tableIndex)
1875 {
1876     CodeBlock* codeBlock = exec->codeBlock();
1877     SimpleJumpTable& table = codeBlock->switchJumpTable(tableIndex);
1878     JSValue value = JSValue::decode(encodedValue);
1879     ASSERT(value.isDouble());
1880     double asDouble = value.asDouble();
1881     int32_t asInt32 = static_cast<int32_t>(asDouble);
1882     if (asDouble == asInt32)
1883         return static_cast<char*>(table.ctiForValue(asInt32).executableAddress());
1884     return static_cast<char*>(table.ctiDefault.executableAddress());
1885 }
1886
1887 char* DFG_OPERATION operationSwitchString(ExecState* exec, size_t tableIndex, JSString* string)
1888 {
1889     VM& vm = exec->vm();
1890     NativeCallFrameTracer tracer(&vm, exec);
1891
1892     return static_cast<char*>(exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(string->value(exec).impl()).executableAddress());
1893 }
1894
1895 double DFG_OPERATION operationFModOnInts(int32_t a, int32_t b)
1896 {
1897     return fmod(a, b);
1898 }
1899
1900 JSCell* DFG_OPERATION operationStringFromCharCode(ExecState* exec, int32_t op1)
1901 {
1902     VM* vm = &exec->vm();
1903     NativeCallFrameTracer tracer(vm, exec);
1904     return JSC::stringFromCharCode(exec, op1);
1905 }
1906
1907 DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState* exec, uint32_t callIndex)
1908 {
1909     VM* vm = &exec->vm();
1910     NativeCallFrameTracer tracer(vm, exec);
1911
1912     JSValue exceptionValue = exec->exception();
1913     ASSERT(exceptionValue);
1914     
1915     unsigned vPCIndex = exec->codeBlock()->bytecodeOffsetForCallAtIndex(callIndex);
1916     ExceptionHandler handler = genericUnwind(vm, exec, exceptionValue, vPCIndex);
1917     ASSERT(handler.catchRoutine);
1918     return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine);
1919 }
1920
1921 DFGHandlerEncoded DFG_OPERATION lookupExceptionHandlerInStub(ExecState* exec, StructureStubInfo* stubInfo)
1922 {
1923     VM* vm = &exec->vm();
1924     NativeCallFrameTracer tracer(vm, exec);
1925
1926     JSValue exceptionValue = exec->exception();
1927     ASSERT(exceptionValue);
1928     
1929     CodeOrigin codeOrigin = stubInfo->codeOrigin;
1930     while (codeOrigin.inlineCallFrame)
1931         codeOrigin = codeOrigin.inlineCallFrame->caller;
1932     
1933     ExceptionHandler handler = genericUnwind(vm, exec, exceptionValue, codeOrigin.bytecodeIndex);
1934     ASSERT(handler.catchRoutine);
1935     return dfgHandlerEncoded(handler.callFrame, handler.catchRoutine);
1936 }
1937
1938 size_t DFG_OPERATION dfgConvertJSValueToInt32(ExecState* exec, EncodedJSValue value)
1939 {
1940     VM* vm = &exec->vm();
1941     NativeCallFrameTracer tracer(vm, exec);
1942     
1943     // toInt32/toUInt32 return the same value; we want the value zero extended to fill the register.
1944     return JSValue::decode(value).toUInt32(exec);
1945 }
1946
1947 size_t DFG_OPERATION dfgConvertJSValueToBoolean(ExecState* exec, EncodedJSValue encodedOp)
1948 {
1949     VM* vm = &exec->vm();
1950     NativeCallFrameTracer tracer(vm, exec);
1951     
1952     return JSValue::decode(encodedOp).toBoolean(exec);
1953 }
1954
1955 void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw, void* scratch)
1956 {
1957     VM* vm = &exec->vm();
1958     NativeCallFrameTracer tracer(vm, exec);
1959     
1960     SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
1961     CodeBlock* codeBlock = debugInfo->codeBlock;
1962     CodeBlock* alternative = codeBlock->alternative();
1963     dataLog(
1964         "Speculation failure in ", *codeBlock, " with ");
1965     if (alternative) {
1966         dataLog(
1967             "executeCounter = ", alternative->jitExecuteCounter(),
1968             ", reoptimizationRetryCounter = ", alternative->reoptimizationRetryCounter(),
1969             ", optimizationDelayCounter = ", alternative->optimizationDelayCounter());
1970     } else
1971         dataLog("no alternative code block (i.e. we've been jettisoned)");
1972     dataLog(", osrExitCounter = ", codeBlock->osrExitCounter(), "\n");
1973     dataLog("    GPRs at time of exit:");
1974     char* scratchPointer = static_cast<char*>(scratch);
1975     for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) {
1976         GPRReg gpr = GPRInfo::toRegister(i);
1977         dataLog(" ", GPRInfo::debugName(gpr), ":", RawPointer(*reinterpret_cast_ptr<void**>(scratchPointer)));
1978         scratchPointer += sizeof(EncodedJSValue);
1979     }
1980     dataLog("\n");
1981     dataLog("    FPRs at time of exit:");
1982     for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
1983         FPRReg fpr = FPRInfo::toRegister(i);
1984         dataLog(" ", FPRInfo::debugName(fpr), ":");
1985         uint64_t bits = *reinterpret_cast_ptr<uint64_t*>(scratchPointer);
1986         double value = *reinterpret_cast_ptr<double*>(scratchPointer);
1987         dataLogF("%llx:%lf", static_cast<long long>(bits), value);
1988         scratchPointer += sizeof(EncodedJSValue);
1989     }
1990     dataLog("\n");
1991 }
1992
1993 extern "C" void DFG_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock)
1994 {
1995     // It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
1996     // really be profitable.
1997     DeferGCForAWhile deferGC(codeBlock->vm()->heap);
1998     
1999     if (Options::verboseOSR())
2000         dataLog(*codeBlock, ": Entered reoptimize\n");
2001     // We must be called with the baseline code block.
2002     ASSERT(JITCode::isBaselineCode(codeBlock->jitType()));
2003
2004     // If I am my own replacement, then reoptimization has already been triggered.
2005     // This can happen in recursive functions.
2006     if (codeBlock->replacement() == codeBlock) {
2007         if (Options::verboseOSR())
2008             dataLog(*codeBlock, ": Not reoptimizing because we've already been jettisoned.\n");
2009         return;
2010     }
2011     
2012     // Otherwise, the replacement must be optimized code. Use this as an opportunity
2013     // to check our logic.
2014     ASSERT(codeBlock->hasOptimizedReplacement());
2015     CodeBlock* optimizedCodeBlock = codeBlock->replacement();
2016     ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
2017
2018     // In order to trigger reoptimization, one of two things must have happened:
2019     // 1) We exited more than some number of times.
2020     // 2) We exited and got stuck in a loop, and now we're exiting again.
2021     bool didExitABunch = optimizedCodeBlock->shouldReoptimizeNow();
2022     bool didGetStuckInLoop =
2023         codeBlock->checkIfOptimizationThresholdReached()
2024         && optimizedCodeBlock->shouldReoptimizeFromLoopNow();
2025     
2026     if (!didExitABunch && !didGetStuckInLoop) {
2027         if (Options::verboseOSR())
2028             dataLog(*codeBlock, ": Not reoptimizing ", *optimizedCodeBlock, " because it either didn't exit enough or didn't loop enough after exit.\n");
2029         codeBlock->optimizeAfterLongWarmUp();
2030         return;
2031     }
2032
2033     codeBlock->reoptimize();
2034 }
2035
2036 #if ENABLE(FTL_JIT)
2037 void DFG_OPERATION triggerTierUpNow(ExecState* exec)
2038 {
2039     VM* vm = &exec->vm();
2040     NativeCallFrameTracer tracer(vm, exec);
2041     DeferGC deferGC(vm->heap);
2042     CodeBlock* codeBlock = exec->codeBlock();
2043     
2044     JITCode* jitCode = codeBlock->jitCode()->dfg();
2045     
2046     if (Options::verboseOSR()) {
2047         dataLog(
2048             *codeBlock, ": Entered triggerTierUpNow with executeCounter = ",
2049             jitCode->tierUpCounter, "\n");
2050     }
2051     
2052     if (codeBlock->baselineVersion()->m_didFailFTLCompilation) {
2053         if (Options::verboseOSR())
2054             dataLog("Deferring FTL-optimization of ", *codeBlock, " indefinitely because there was an FTL failure.\n");
2055         jitCode->dontOptimizeAnytimeSoon(codeBlock);
2056         return;
2057     }
2058     
2059     if (!jitCode->checkIfOptimizationThresholdReached(codeBlock)) {
2060         if (Options::verboseOSR())
2061             dataLog("Choosing not to FTL-optimize ", *codeBlock, " yet.\n");
2062         return;
2063     }
2064     
2065     Worklist::State worklistState;
2066     if (Worklist* worklist = vm->worklist.get()) {
2067         worklistState = worklist->completeAllReadyPlansForVM(
2068             *vm, CompilationKey(codeBlock->baselineVersion(), FTLMode));
2069     } else
2070         worklistState = Worklist::NotKnown;
2071     
2072     if (worklistState == Worklist::Compiling) {
2073         jitCode->setOptimizationThresholdBasedOnCompilationResult(
2074             codeBlock, CompilationDeferred);
2075         return;
2076     }
2077     
2078     if (codeBlock->hasOptimizedReplacement()) {
2079         // That's great, we've compiled the code - next time we call this function,
2080         // we'll enter that replacement.
2081         jitCode->optimizeSoon(codeBlock);
2082         return;
2083     }
2084     
2085     if (worklistState == Worklist::Compiled) {
2086         // This means that we finished compiling, but failed somehow; in that case the
2087         // thresholds will be set appropriately.
2088         if (Options::verboseOSR())
2089             dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
2090         return;
2091     }
2092
2093     // We need to compile the code.
2094     compile(
2095         *vm, codeBlock->newReplacement().get(), FTLMode, UINT_MAX, Operands<JSValue>(),
2096         ToFTLDeferredCompilationCallback::create(codeBlock), vm->ensureWorklist());
2097 }
2098
2099 char* DFG_OPERATION triggerOSREntryNow(
2100     ExecState* exec, int32_t bytecodeIndex, int32_t streamIndex)
2101 {
2102     VM* vm = &exec->vm();
2103     NativeCallFrameTracer tracer(vm, exec);
2104     DeferGC deferGC(vm->heap);
2105     CodeBlock* codeBlock = exec->codeBlock();
2106     
2107     JITCode* jitCode = codeBlock->jitCode()->dfg();
2108     
2109     if (Options::verboseOSR()) {
2110         dataLog(
2111             *codeBlock, ": Entered triggerTierUpNow with executeCounter = ",
2112             jitCode->tierUpCounter, "\n");
2113     }
2114     
2115     if (codeBlock->baselineVersion()->m_didFailFTLCompilation) {
2116         if (Options::verboseOSR())
2117             dataLog("Deferring FTL-optimization of ", *codeBlock, " indefinitely because there was an FTL failure.\n");
2118         jitCode->dontOptimizeAnytimeSoon(codeBlock);
2119         return 0;
2120     }
2121     
2122     if (!jitCode->checkIfOptimizationThresholdReached(codeBlock)) {
2123         if (Options::verboseOSR())
2124             dataLog("Choosing not to FTL-optimize ", *codeBlock, " yet.\n");
2125         return 0;
2126     }
2127     
2128     Worklist::State worklistState;
2129     if (Worklist* worklist = vm->worklist.get()) {
2130         worklistState = worklist->completeAllReadyPlansForVM(
2131             *vm, CompilationKey(codeBlock->baselineVersion(), FTLForOSREntryMode));
2132     } else
2133         worklistState = Worklist::NotKnown;
2134     
2135     if (worklistState == Worklist::Compiling) {
2136         ASSERT(!jitCode->osrEntryBlock);
2137         jitCode->setOptimizationThresholdBasedOnCompilationResult(
2138             codeBlock, CompilationDeferred);
2139         return 0;
2140     }
2141     
2142     if (CodeBlock* entryBlock = jitCode->osrEntryBlock.get()) {
2143         void* address = FTL::prepareOSREntry(
2144             exec, codeBlock, entryBlock, bytecodeIndex, streamIndex);
2145         if (address) {
2146             jitCode->optimizeSoon(codeBlock);
2147             return static_cast<char*>(address);
2148         }
2149         
2150         FTL::ForOSREntryJITCode* entryCode = entryBlock->jitCode()->ftlForOSREntry();
2151         entryCode->countEntryFailure();
2152         if (entryCode->entryFailureCount() <
2153             Options::ftlOSREntryFailureCountForReoptimization()) {
2154             
2155             jitCode->optimizeSoon(codeBlock);
2156             return 0;
2157         }
2158         
2159         // OSR entry failed. Oh no! This implies that we need to retry. We retry
2160         // without exponential backoff and we only do this for the entry code block.
2161         jitCode->osrEntryBlock.clear();
2162         
2163         jitCode->optimizeAfterWarmUp(codeBlock);
2164         return 0;
2165     }
2166     
2167     if (worklistState == Worklist::Compiled) {
2168         // This means that compilation failed and we already set the thresholds.
2169         if (Options::verboseOSR())
2170             dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
2171         return 0;
2172     }
2173
2174     // The first order of business is to trigger a for-entry compile.
2175     Operands<JSValue> mustHandleValues;
2176     jitCode->reconstruct(
2177         exec, codeBlock, CodeOrigin(bytecodeIndex), streamIndex, mustHandleValues);
2178     CompilationResult forEntryResult = DFG::compile(
2179         *vm, codeBlock->newReplacement().get(), FTLForOSREntryMode, bytecodeIndex,
2180         mustHandleValues, ToFTLForOSREntryDeferredCompilationCallback::create(codeBlock),
2181         vm->ensureWorklist());
2182     
2183     // But we also want to trigger a replacement compile. Of course, we don't want to
2184     // trigger it if we don't need to. Note that this is kind of weird because we might
2185     // have just finished an FTL compile and that compile failed or was invalidated.
2186     // But this seems uncommon enough that we sort of don't care. It's certainly sound
2187     // to fire off another compile right now so long as we're not already compiling and
2188     // we don't already have an optimized replacement. Note, we don't do this for
2189     // obviously bad cases like global code, where we know that there is a slim chance
2190     // of this code being invoked ever again.
2191     CompilationKey keyForReplacement(codeBlock->baselineVersion(), FTLMode);
2192     if (codeBlock->codeType() != GlobalCode
2193         && !codeBlock->hasOptimizedReplacement()
2194         && (!vm->worklist.get()
2195             || vm->worklist->compilationState(keyForReplacement) == Worklist::NotKnown)) {
2196         compile(
2197             *vm, codeBlock->newReplacement().get(), FTLMode, UINT_MAX, Operands<JSValue>(),
2198             ToFTLDeferredCompilationCallback::create(codeBlock), vm->ensureWorklist());
2199     }
2200     
2201     if (forEntryResult != CompilationSuccessful)
2202         return 0;
2203     
2204     // It's possible that the for-entry compile already succeeded. In that case OSR
2205     // entry will succeed unless we ran out of stack. It's not clear what we should do.
2206     // We signal to try again after a while if that happens.
2207     void* address = FTL::prepareOSREntry(
2208         exec, codeBlock, jitCode->osrEntryBlock.get(), bytecodeIndex, streamIndex);
2209     if (address)
2210         jitCode->optimizeSoon(codeBlock);
2211     else
2212         jitCode->optimizeAfterWarmUp(codeBlock);
2213     return static_cast<char*>(address);
2214 }
2215
2216 // FIXME: Make calls work well. Currently they're a pure regression.
2217 // https://bugs.webkit.org/show_bug.cgi?id=113621
2218 EncodedJSValue DFG_OPERATION operationFTLCall(ExecState* exec)
2219 {
2220     ExecState* callerExec = exec->callerFrame();
2221     
2222     VM* vm = &callerExec->vm();
2223     NativeCallFrameTracer tracer(vm, callerExec);
2224     
2225     JSValue callee = exec->calleeAsValue();
2226     CallData callData;
2227     CallType callType = getCallData(callee, callData);
2228     if (callType == CallTypeNone) {
2229         vm->throwException(callerExec, createNotAFunctionError(callerExec, callee));
2230         return JSValue::encode(jsUndefined());
2231     }
2232     
2233     return JSValue::encode(call(callerExec, callee, callType, callData, exec->thisValue(), exec));
2234 }
2235
2236 // FIXME: Make calls work well. Currently they're a pure regression.
2237 // https://bugs.webkit.org/show_bug.cgi?id=113621
2238 EncodedJSValue DFG_OPERATION operationFTLConstruct(ExecState* exec)
2239 {
2240     ExecState* callerExec = exec->callerFrame();
2241     
2242     VM* vm = &callerExec->vm();
2243     NativeCallFrameTracer tracer(vm, callerExec);
2244     
2245     JSValue callee = exec->calleeAsValue();
2246     ConstructData constructData;
2247     ConstructType constructType = getConstructData(callee, constructData);
2248     if (constructType == ConstructTypeNone) {
2249         vm->throwException(callerExec, createNotAFunctionError(callerExec, callee));
2250         return JSValue::encode(jsUndefined());
2251     }
2252     
2253     return JSValue::encode(construct(callerExec, callee, constructType, constructData, exec));
2254 }
2255 #endif // ENABLE(FTL_JIT)
2256
2257 } // extern "C"
2258 } } // namespace JSC::DFG
2259
2260 #endif // ENABLE(DFG_JIT)
2261
2262 namespace JSC {
2263
2264 #if COMPILER(GCC) && CPU(X86_64)
2265 asm (
2266 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2267 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2268 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2269     "mov 40(%r13), %r13\n"
2270     "mov %r13, %rdi\n"
2271     "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2272 );
2273 #elif COMPILER(GCC) && CPU(X86)
2274 asm (
2275 ".text" "\n" \
2276 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2277 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2278 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2279     "mov 40(%edi), %edi\n"
2280     "mov %edi, 4(%esp)\n"
2281     "jmp " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2282 );
2283 #elif COMPILER(GCC) && CPU(ARM_THUMB2)
2284 asm (
2285 ".text" "\n"
2286 ".align 2" "\n"
2287 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2288 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2289 ".thumb" "\n"
2290 ".thumb_func " THUMB_FUNC_PARAM(getHostCallReturnValue) "\n"
2291 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2292     "ldr r5, [r5, #40]" "\n"
2293     "mov r0, r5" "\n"
2294     "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2295 );
2296 #elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
2297 asm (
2298 ".text" "\n"
2299 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2300 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2301 INLINE_ARM_FUNCTION(getHostCallReturnValue)
2302 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2303     "ldr r5, [r5, #40]" "\n"
2304     "mov r0, r5" "\n"
2305     "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2306 );
2307 #elif COMPILER(GCC) && CPU(MIPS)
2308 asm(
2309 ".text" "\n"
2310 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2311 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2312 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2313     LOAD_FUNCTION_TO_T9(getHostCallReturnValueWithExecState)
2314     "lw $s0, 40($s0)" "\n"
2315     "move $a0, $s0" "\n"
2316     "b " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "\n"
2317 );
2318 #elif COMPILER(GCC) && CPU(SH4)
2319 asm(
2320 ".text" "\n"
2321 ".globl " SYMBOL_STRING(getHostCallReturnValue) "\n"
2322 HIDE_SYMBOL(getHostCallReturnValue) "\n"
2323 SYMBOL_STRING(getHostCallReturnValue) ":" "\n"
2324     "add #40, r14" "\n"
2325     "mov.l @r14, r14" "\n"
2326     "mov r14, r4" "\n"
2327     "mov.l 2f, " SH4_SCRATCH_REGISTER "\n"
2328     "braf " SH4_SCRATCH_REGISTER "\n"
2329     "nop" "\n"
2330     "1: .balign 4" "\n"
2331     "2: .long " LOCAL_REFERENCE(getHostCallReturnValueWithExecState) "-1b\n"
2332 );
2333 #endif
2334
2335 extern "C" EncodedJSValue HOST_CALL_RETURN_VALUE_OPTION getHostCallReturnValueWithExecState(ExecState* exec)
2336 {
2337     if (!exec)
2338         return JSValue::encode(JSValue());
2339     return JSValue::encode(exec->vm().hostCallReturnValue);
2340 }
2341
2342 } // namespace JSC
2343
2344 #endif // ENABLE(JIT)