Unreviewed, rolling out r208208 and r208210.
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLLowerDFGToB3.cpp
1 /*
2  * Copyright (C) 2013-2016 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 "FTLLowerDFGToB3.h"
28
29 #if ENABLE(FTL_JIT)
30
31 #include "AirGenerationContext.h"
32 #include "AllowMacroScratchRegisterUsage.h"
33 #include "B3CheckValue.h"
34 #include "B3FenceValue.h"
35 #include "B3PatchpointValue.h"
36 #include "B3SlotBaseValue.h"
37 #include "B3StackmapGenerationParams.h"
38 #include "B3ValueInlines.h"
39 #include "CallFrameShuffler.h"
40 #include "CodeBlockWithJITType.h"
41 #include "DFGAbstractInterpreterInlines.h"
42 #include "DFGCapabilities.h"
43 #include "DFGDominators.h"
44 #include "DFGInPlaceAbstractState.h"
45 #include "DFGOSRAvailabilityAnalysisPhase.h"
46 #include "DFGOSRExitFuzz.h"
47 #include "DOMJITPatchpoint.h"
48 #include "DirectArguments.h"
49 #include "FTLAbstractHeapRepository.h"
50 #include "FTLAvailableRecovery.h"
51 #include "FTLDOMJITPatchpointParams.h"
52 #include "FTLExceptionTarget.h"
53 #include "FTLForOSREntryJITCode.h"
54 #include "FTLFormattedValue.h"
55 #include "FTLLazySlowPathCall.h"
56 #include "FTLLoweredNodeValue.h"
57 #include "FTLOperations.h"
58 #include "FTLOutput.h"
59 #include "FTLPatchpointExceptionHandle.h"
60 #include "FTLThunks.h"
61 #include "FTLWeightedTarget.h"
62 #include "JITAddGenerator.h"
63 #include "JITBitAndGenerator.h"
64 #include "JITBitOrGenerator.h"
65 #include "JITBitXorGenerator.h"
66 #include "JITDivGenerator.h"
67 #include "JITInlineCacheGenerator.h"
68 #include "JITLeftShiftGenerator.h"
69 #include "JITMathIC.h"
70 #include "JITMulGenerator.h"
71 #include "JITRightShiftGenerator.h"
72 #include "JITSubGenerator.h"
73 #include "JSCInlines.h"
74 #include "JSGeneratorFunction.h"
75 #include "JSLexicalEnvironment.h"
76 #include "JSMap.h"
77 #include "OperandsInlines.h"
78 #include "ScopedArguments.h"
79 #include "ScopedArgumentsTable.h"
80 #include "ScratchRegisterAllocator.h"
81 #include "SetupVarargsFrame.h"
82 #include "ShadowChicken.h"
83 #include "StructureStubInfo.h"
84 #include "VirtualRegister.h"
85 #include "Watchdog.h"
86 #include <atomic>
87 #if !OS(WINDOWS)
88 #include <dlfcn.h>
89 #endif
90 #include <unordered_set>
91 #include <wtf/Box.h>
92 #include <wtf/ProcessID.h>
93
94 namespace JSC { namespace FTL {
95
96 using namespace B3;
97 using namespace DFG;
98
99 namespace {
100
101 std::atomic<int> compileCounter;
102
103 #if !ASSERT_DISABLED
104 NO_RETURN_DUE_TO_CRASH static void ftlUnreachable(
105     CodeBlock* codeBlock, BlockIndex blockIndex, unsigned nodeIndex)
106 {
107     dataLog("Crashing in thought-to-be-unreachable FTL-generated code for ", pointerDump(codeBlock), " at basic block #", blockIndex);
108     if (nodeIndex != UINT_MAX)
109         dataLog(", node @", nodeIndex);
110     dataLog(".\n");
111     CRASH();
112 }
113 #endif
114
115 // Using this instead of typeCheck() helps to reduce the load on B3, by creating
116 // significantly less dead code.
117 #define FTL_TYPE_CHECK_WITH_EXIT_KIND(exitKind, lowValue, highValue, typesPassedThrough, failCondition) do { \
118         FormattedValue _ftc_lowValue = (lowValue);                      \
119         Edge _ftc_highValue = (highValue);                              \
120         SpeculatedType _ftc_typesPassedThrough = (typesPassedThrough);  \
121         if (!m_interpreter.needsTypeCheck(_ftc_highValue, _ftc_typesPassedThrough)) \
122             break;                                                      \
123         typeCheck(_ftc_lowValue, _ftc_highValue, _ftc_typesPassedThrough, (failCondition), exitKind); \
124     } while (false)
125
126 #define FTL_TYPE_CHECK(lowValue, highValue, typesPassedThrough, failCondition) \
127     FTL_TYPE_CHECK_WITH_EXIT_KIND(BadType, lowValue, highValue, typesPassedThrough, failCondition)
128
129 class LowerDFGToB3 {
130     WTF_MAKE_NONCOPYABLE(LowerDFGToB3);
131 public:
132     LowerDFGToB3(State& state)
133         : m_graph(state.graph)
134         , m_ftlState(state)
135         , m_out(state)
136         , m_proc(*state.proc)
137         , m_state(state.graph)
138         , m_interpreter(state.graph, m_state)
139     {
140     }
141     
142     void lower()
143     {
144         State* state = &m_ftlState;
145         
146         CString name;
147         if (verboseCompilationEnabled()) {
148             name = toCString(
149                 "jsBody_", ++compileCounter, "_", codeBlock()->inferredName(),
150                 "_", codeBlock()->hash());
151         } else
152             name = "jsBody";
153         
154         m_graph.ensureDominators();
155
156         if (verboseCompilationEnabled())
157             dataLog("Function ready, beginning lowering.\n");
158
159         m_out.initialize(m_heaps);
160
161         // We use prologue frequency for all of the initialization code.
162         m_out.setFrequency(1);
163         
164         m_prologue = m_out.newBlock();
165         m_handleExceptions = m_out.newBlock();
166
167         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
168             m_highBlock = m_graph.block(blockIndex);
169             if (!m_highBlock)
170                 continue;
171             m_out.setFrequency(m_highBlock->executionCount);
172             m_blocks.add(m_highBlock, m_out.newBlock());
173         }
174
175         // Back to prologue frequency for any bocks that get sneakily created in the initialization code.
176         m_out.setFrequency(1);
177         
178         m_out.appendTo(m_prologue, m_handleExceptions);
179         m_out.initializeConstants(m_proc, m_prologue);
180         createPhiVariables();
181
182         size_t sizeOfCaptured = sizeof(JSValue) * m_graph.m_nextMachineLocal;
183         B3::SlotBaseValue* capturedBase = m_out.lockedStackSlot(sizeOfCaptured);
184         m_captured = m_out.add(capturedBase, m_out.constIntPtr(sizeOfCaptured));
185         state->capturedValue = capturedBase->slot();
186
187         auto preOrder = m_graph.blocksInPreOrder();
188
189         m_callFrame = m_out.framePointer();
190         m_tagTypeNumber = m_out.constInt64(TagTypeNumber);
191         m_tagMask = m_out.constInt64(TagMask);
192
193         // Make sure that B3 knows that we really care about the mask registers. This forces the
194         // constants to be materialized in registers.
195         m_proc.addFastConstant(m_tagTypeNumber->key());
196         m_proc.addFastConstant(m_tagMask->key());
197         
198         m_out.storePtr(m_out.constIntPtr(codeBlock()), addressFor(CallFrameSlot::codeBlock));
199
200         // Stack Overflow Check.
201         unsigned exitFrameSize = m_graph.requiredRegisterCountForExit() * sizeof(Register);
202         MacroAssembler::AbsoluteAddress addressOfStackLimit(vm().addressOfSoftStackLimit());
203         PatchpointValue* stackOverflowHandler = m_out.patchpoint(Void);
204         CallSiteIndex callSiteIndex = callSiteIndexForCodeOrigin(m_ftlState, CodeOrigin(0));
205         stackOverflowHandler->appendSomeRegister(m_callFrame);
206         stackOverflowHandler->clobber(RegisterSet::macroScratchRegisters());
207         stackOverflowHandler->numGPScratchRegisters = 1;
208         stackOverflowHandler->setGenerator(
209             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
210                 AllowMacroScratchRegisterUsage allowScratch(jit);
211                 GPRReg fp = params[0].gpr();
212                 GPRReg scratch = params.gpScratch(0);
213
214                 unsigned ftlFrameSize = params.proc().frameSize();
215
216                 jit.addPtr(MacroAssembler::TrustedImm32(-std::max(exitFrameSize, ftlFrameSize)), fp, scratch);
217                 MacroAssembler::Jump stackOverflow = jit.branchPtr(MacroAssembler::Above, addressOfStackLimit, scratch);
218
219                 params.addLatePath([=] (CCallHelpers& jit) {
220                     AllowMacroScratchRegisterUsage allowScratch(jit);
221
222                     stackOverflow.link(&jit);
223                     jit.store32(
224                         MacroAssembler::TrustedImm32(callSiteIndex.bits()),
225                         CCallHelpers::tagFor(VirtualRegister(CallFrameSlot::argumentCount)));
226                     jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer();
227
228                     jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
229                     jit.move(CCallHelpers::TrustedImmPtr(jit.codeBlock()), GPRInfo::argumentGPR1);
230                     CCallHelpers::Call throwCall = jit.call();
231
232                     jit.move(CCallHelpers::TrustedImmPtr(jit.vm()), GPRInfo::argumentGPR0);
233                     jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
234                     CCallHelpers::Call lookupExceptionHandlerCall = jit.call();
235                     jit.jumpToExceptionHandler();
236
237                     jit.addLinkTask(
238                         [=] (LinkBuffer& linkBuffer) {
239                             linkBuffer.link(throwCall, FunctionPtr(operationThrowStackOverflowError));
240                             linkBuffer.link(lookupExceptionHandlerCall, FunctionPtr(lookupExceptionHandlerFromCallerFrame));
241                     });
242                 });
243             });
244
245         LBasicBlock firstDFGBasicBlock = lowBlock(m_graph.block(0));
246         // Check Arguments.
247         availabilityMap().clear();
248         availabilityMap().m_locals = Operands<Availability>(codeBlock()->numParameters(), 0);
249         for (unsigned i = codeBlock()->numParameters(); i--;) {
250             availabilityMap().m_locals.argument(i) =
251                 Availability(FlushedAt(FlushedJSValue, virtualRegisterForArgument(i)));
252         }
253         m_node = nullptr;
254         m_origin = NodeOrigin(CodeOrigin(0), CodeOrigin(0), true);
255         for (unsigned i = codeBlock()->numParameters(); i--;) {
256             Node* node = m_graph.m_arguments[i];
257             VirtualRegister operand = virtualRegisterForArgument(i);
258             
259             LValue jsValue = m_out.load64(addressFor(operand));
260             
261             if (node) {
262                 DFG_ASSERT(m_graph, node, operand == node->stackAccessData()->machineLocal);
263                 
264                 // This is a hack, but it's an effective one. It allows us to do CSE on the
265                 // primordial load of arguments. This assumes that the GetLocal that got put in
266                 // place of the original SetArgument doesn't have any effects before it. This
267                 // should hold true.
268                 m_loadedArgumentValues.add(node, jsValue);
269             }
270             
271             switch (m_graph.m_argumentFormats[i]) {
272             case FlushedInt32:
273                 speculate(BadType, jsValueValue(jsValue), node, isNotInt32(jsValue));
274                 break;
275             case FlushedBoolean:
276                 speculate(BadType, jsValueValue(jsValue), node, isNotBoolean(jsValue));
277                 break;
278             case FlushedCell:
279                 speculate(BadType, jsValueValue(jsValue), node, isNotCell(jsValue));
280                 break;
281             case FlushedJSValue:
282                 break;
283             default:
284                 DFG_CRASH(m_graph, node, "Bad flush format for argument");
285                 break;
286             }
287         }
288         m_out.jump(firstDFGBasicBlock);
289
290         m_out.appendTo(m_handleExceptions, firstDFGBasicBlock);
291         Box<CCallHelpers::Label> exceptionHandler = state->exceptionHandler;
292         m_out.patchpoint(Void)->setGenerator(
293             [=] (CCallHelpers& jit, const StackmapGenerationParams&) {
294                 CCallHelpers::Jump jump = jit.jump();
295                 jit.addLinkTask(
296                     [=] (LinkBuffer& linkBuffer) {
297                         linkBuffer.link(jump, linkBuffer.locationOf(*exceptionHandler));
298                     });
299             });
300         m_out.unreachable();
301
302         for (DFG::BasicBlock* block : preOrder)
303             compileBlock(block);
304
305         // Make sure everything is decorated. This does a bunch of deferred decorating. This has
306         // to happen last because our abstract heaps are generated lazily. They have to be
307         // generated lazily because we have an infiniten number of numbered, indexed, and
308         // absolute heaps. We only become aware of the ones we actually mention while lowering.
309         m_heaps.computeRangesAndDecorateInstructions();
310
311         // We create all Phi's up front, but we may then decide not to compile the basic block
312         // that would have contained one of them. So this creates orphans, which triggers B3
313         // validation failures. Calling this fixes the issue.
314         //
315         // Note that you should avoid the temptation to make this call conditional upon
316         // validation being enabled. B3 makes no guarantees of any kind of correctness when
317         // dealing with IR that would have failed validation. For example, it would be valid to
318         // write a B3 phase that so aggressively assumes the lack of orphans that it would crash
319         // if any orphans were around. We might even have such phases already.
320         m_proc.deleteOrphans();
321
322         // We put the blocks into the B3 procedure in a super weird order. Now we reorder them.
323         m_out.applyBlockOrder();
324     }
325
326 private:
327     
328     void createPhiVariables()
329     {
330         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
331             DFG::BasicBlock* block = m_graph.block(blockIndex);
332             if (!block)
333                 continue;
334             for (unsigned nodeIndex = block->size(); nodeIndex--;) {
335                 Node* node = block->at(nodeIndex);
336                 if (node->op() != DFG::Phi)
337                     continue;
338                 LType type;
339                 switch (node->flags() & NodeResultMask) {
340                 case NodeResultDouble:
341                     type = Double;
342                     break;
343                 case NodeResultInt32:
344                     type = Int32;
345                     break;
346                 case NodeResultInt52:
347                     type = Int64;
348                     break;
349                 case NodeResultBoolean:
350                     type = Int32;
351                     break;
352                 case NodeResultJS:
353                     type = Int64;
354                     break;
355                 default:
356                     DFG_CRASH(m_graph, node, "Bad Phi node result type");
357                     break;
358                 }
359                 m_phis.add(node, m_proc.add<Value>(B3::Phi, type, Origin(node)));
360             }
361         }
362     }
363     
364     void compileBlock(DFG::BasicBlock* block)
365     {
366         if (!block)
367             return;
368         
369         if (verboseCompilationEnabled())
370             dataLog("Compiling block ", *block, "\n");
371         
372         m_highBlock = block;
373         
374         // Make sure that any blocks created while lowering code in the high block have the frequency of
375         // the high block. This is appropriate because B3 doesn't need precise frequencies. It just needs
376         // something roughly approximate for things like register allocation.
377         m_out.setFrequency(m_highBlock->executionCount);
378         
379         LBasicBlock lowBlock = m_blocks.get(m_highBlock);
380         
381         m_nextHighBlock = 0;
382         for (BlockIndex nextBlockIndex = m_highBlock->index + 1; nextBlockIndex < m_graph.numBlocks(); ++nextBlockIndex) {
383             m_nextHighBlock = m_graph.block(nextBlockIndex);
384             if (m_nextHighBlock)
385                 break;
386         }
387         m_nextLowBlock = m_nextHighBlock ? m_blocks.get(m_nextHighBlock) : 0;
388         
389         // All of this effort to find the next block gives us the ability to keep the
390         // generated IR in roughly program order. This ought not affect the performance
391         // of the generated code (since we expect B3 to reorder things) but it will
392         // make IR dumps easier to read.
393         m_out.appendTo(lowBlock, m_nextLowBlock);
394         
395         if (Options::ftlCrashes())
396             m_out.trap();
397         
398         if (!m_highBlock->cfaHasVisited) {
399             if (verboseCompilationEnabled())
400                 dataLog("Bailing because CFA didn't reach.\n");
401             crash(m_highBlock, nullptr);
402             return;
403         }
404         
405         m_availabilityCalculator.beginBlock(m_highBlock);
406         
407         m_state.reset();
408         m_state.beginBasicBlock(m_highBlock);
409         
410         for (m_nodeIndex = 0; m_nodeIndex < m_highBlock->size(); ++m_nodeIndex) {
411             if (!compileNode(m_nodeIndex))
412                 break;
413         }
414     }
415
416     void safelyInvalidateAfterTermination()
417     {
418         if (verboseCompilationEnabled())
419             dataLog("Bailing.\n");
420         crash();
421
422         // Invalidate dominated blocks. Under normal circumstances we would expect
423         // them to be invalidated already. But you can have the CFA become more
424         // precise over time because the structures of objects change on the main
425         // thread. Failing to do this would result in weird crashes due to a value
426         // being used but not defined. Race conditions FTW!
427         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
428             DFG::BasicBlock* target = m_graph.block(blockIndex);
429             if (!target)
430                 continue;
431             if (m_graph.m_dominators->dominates(m_highBlock, target)) {
432                 if (verboseCompilationEnabled())
433                     dataLog("Block ", *target, " will bail also.\n");
434                 target->cfaHasVisited = false;
435             }
436         }
437     }
438
439     bool compileNode(unsigned nodeIndex)
440     {
441         if (!m_state.isValid()) {
442             safelyInvalidateAfterTermination();
443             return false;
444         }
445         
446         m_node = m_highBlock->at(nodeIndex);
447         m_origin = m_node->origin;
448         m_out.setOrigin(m_node);
449         
450         if (verboseCompilationEnabled())
451             dataLog("Lowering ", m_node, "\n");
452         
453         m_availableRecoveries.resize(0);
454         
455         m_interpreter.startExecuting();
456         m_interpreter.executeKnownEdgeTypes(m_node);
457         
458         switch (m_node->op()) {
459         case DFG::Upsilon:
460             compileUpsilon();
461             break;
462         case DFG::Phi:
463             compilePhi();
464             break;
465         case JSConstant:
466             break;
467         case DoubleConstant:
468             compileDoubleConstant();
469             break;
470         case Int52Constant:
471             compileInt52Constant();
472             break;
473         case LazyJSConstant:
474             compileLazyJSConstant();
475             break;
476         case DoubleRep:
477             compileDoubleRep();
478             break;
479         case DoubleAsInt32:
480             compileDoubleAsInt32();
481             break;
482         case DFG::ValueRep:
483             compileValueRep();
484             break;
485         case Int52Rep:
486             compileInt52Rep();
487             break;
488         case ValueToInt32:
489             compileValueToInt32();
490             break;
491         case BooleanToNumber:
492             compileBooleanToNumber();
493             break;
494         case ExtractOSREntryLocal:
495             compileExtractOSREntryLocal();
496             break;
497         case GetStack:
498             compileGetStack();
499             break;
500         case PutStack:
501             compilePutStack();
502             break;
503         case DFG::Check:
504             compileNoOp();
505             break;
506         case CallObjectConstructor:
507             compileCallObjectConstructor();
508             break;
509         case ToThis:
510             compileToThis();
511             break;
512         case ValueAdd:
513             compileValueAdd();
514             break;
515         case StrCat:
516             compileStrCat();
517             break;
518         case ArithAdd:
519         case ArithSub:
520             compileArithAddOrSub();
521             break;
522         case ArithClz32:
523             compileArithClz32();
524             break;
525         case ArithMul:
526             compileArithMul();
527             break;
528         case ArithDiv:
529             compileArithDiv();
530             break;
531         case ArithMod:
532             compileArithMod();
533             break;
534         case ArithMin:
535         case ArithMax:
536             compileArithMinOrMax();
537             break;
538         case ArithAbs:
539             compileArithAbs();
540             break;
541         case ArithSin:
542             compileArithSin();
543             break;
544         case ArithCos:
545             compileArithCos();
546             break;
547         case ArithTan:
548             compileArithTan();
549             break;
550         case ArithPow:
551             compileArithPow();
552             break;
553         case ArithRandom:
554             compileArithRandom();
555             break;
556         case ArithRound:
557             compileArithRound();
558             break;
559         case ArithFloor:
560             compileArithFloor();
561             break;
562         case ArithCeil:
563             compileArithCeil();
564             break;
565         case ArithTrunc:
566             compileArithTrunc();
567             break;
568         case ArithSqrt:
569             compileArithSqrt();
570             break;
571         case ArithLog:
572             compileArithLog();
573             break;
574         case ArithFRound:
575             compileArithFRound();
576             break;
577         case ArithNegate:
578             compileArithNegate();
579             break;
580         case DFG::BitAnd:
581             compileBitAnd();
582             break;
583         case DFG::BitOr:
584             compileBitOr();
585             break;
586         case DFG::BitXor:
587             compileBitXor();
588             break;
589         case BitRShift:
590             compileBitRShift();
591             break;
592         case BitLShift:
593             compileBitLShift();
594             break;
595         case BitURShift:
596             compileBitURShift();
597             break;
598         case UInt32ToNumber:
599             compileUInt32ToNumber();
600             break;
601         case CheckStructure:
602             compileCheckStructure();
603             break;
604         case CheckCell:
605             compileCheckCell();
606             break;
607         case CheckNotEmpty:
608             compileCheckNotEmpty();
609             break;
610         case CheckBadCell:
611             compileCheckBadCell();
612             break;
613         case CheckStringIdent:
614             compileCheckStringIdent();
615             break;
616         case GetExecutable:
617             compileGetExecutable();
618             break;
619         case ArrayifyToStructure:
620             compileArrayifyToStructure();
621             break;
622         case PutStructure:
623             compilePutStructure();
624             break;
625         case TryGetById:
626             compileGetById(AccessType::TryGet);
627             break;
628         case PureGetById:
629             compileGetById(AccessType::PureGet);
630             break;
631         case GetById:
632         case GetByIdFlush:
633             compileGetById(AccessType::Get);
634             break;
635         case GetByIdWithThis:
636             compileGetByIdWithThis();
637             break;
638         case In:
639             compileIn();
640             break;
641         case HasOwnProperty:
642             compileHasOwnProperty();
643             break;
644         case PutById:
645         case PutByIdDirect:
646         case PutByIdFlush:
647             compilePutById();
648             break;
649         case PutByIdWithThis:
650             compilePutByIdWithThis();
651             break;
652         case PutGetterById:
653         case PutSetterById:
654             compilePutAccessorById();
655             break;
656         case PutGetterSetterById:
657             compilePutGetterSetterById();
658             break;
659         case PutGetterByVal:
660         case PutSetterByVal:
661             compilePutAccessorByVal();
662             break;
663         case GetButterfly:
664             compileGetButterfly();
665             break;
666         case ConstantStoragePointer:
667             compileConstantStoragePointer();
668             break;
669         case GetIndexedPropertyStorage:
670             compileGetIndexedPropertyStorage();
671             break;
672         case CheckArray:
673             compileCheckArray();
674             break;
675         case GetArrayLength:
676             compileGetArrayLength();
677             break;
678         case CheckInBounds:
679             compileCheckInBounds();
680             break;
681         case GetByVal:
682             compileGetByVal();
683             break;
684         case GetMyArgumentByVal:
685         case GetMyArgumentByValOutOfBounds:
686             compileGetMyArgumentByVal();
687             break;
688         case GetByValWithThis:
689             compileGetByValWithThis();
690             break;
691         case PutByVal:
692         case PutByValAlias:
693         case PutByValDirect:
694             compilePutByVal();
695             break;
696         case PutByValWithThis:
697             compilePutByValWithThis();
698             break;
699         case DefineDataProperty:
700             compileDefineDataProperty();
701             break;
702         case DefineAccessorProperty:
703             compileDefineAccessorProperty();
704             break;
705         case ArrayPush:
706             compileArrayPush();
707             break;
708         case ArrayPop:
709             compileArrayPop();
710             break;
711         case CreateActivation:
712             compileCreateActivation();
713             break;
714         case NewFunction:
715         case NewGeneratorFunction:
716             compileNewFunction();
717             break;
718         case CreateDirectArguments:
719             compileCreateDirectArguments();
720             break;
721         case CreateScopedArguments:
722             compileCreateScopedArguments();
723             break;
724         case CreateClonedArguments:
725             compileCreateClonedArguments();
726             break;
727         case NewObject:
728             compileNewObject();
729             break;
730         case NewArray:
731             compileNewArray();
732             break;
733         case NewArrayBuffer:
734             compileNewArrayBuffer();
735             break;
736         case NewArrayWithSize:
737             compileNewArrayWithSize();
738             break;
739         case NewTypedArray:
740             compileNewTypedArray();
741             break;
742         case GetTypedArrayByteOffset:
743             compileGetTypedArrayByteOffset();
744             break;
745         case AllocatePropertyStorage:
746             compileAllocatePropertyStorage();
747             break;
748         case ReallocatePropertyStorage:
749             compileReallocatePropertyStorage();
750             break;
751         case ToNumber:
752             compileToNumber();
753             break;
754         case ToString:
755         case CallStringConstructor:
756             compileToStringOrCallStringConstructor();
757             break;
758         case ToPrimitive:
759             compileToPrimitive();
760             break;
761         case MakeRope:
762             compileMakeRope();
763             break;
764         case StringCharAt:
765             compileStringCharAt();
766             break;
767         case StringCharCodeAt:
768             compileStringCharCodeAt();
769             break;
770         case StringFromCharCode:
771             compileStringFromCharCode();
772             break;
773         case GetByOffset:
774         case GetGetterSetterByOffset:
775             compileGetByOffset();
776             break;
777         case GetGetter:
778             compileGetGetter();
779             break;
780         case GetSetter:
781             compileGetSetter();
782             break;
783         case MultiGetByOffset:
784             compileMultiGetByOffset();
785             break;
786         case PutByOffset:
787             compilePutByOffset();
788             break;
789         case MultiPutByOffset:
790             compileMultiPutByOffset();
791             break;
792         case GetGlobalVar:
793         case GetGlobalLexicalVariable:
794             compileGetGlobalVariable();
795             break;
796         case PutGlobalVariable:
797             compilePutGlobalVariable();
798             break;
799         case NotifyWrite:
800             compileNotifyWrite();
801             break;
802         case GetCallee:
803             compileGetCallee();
804             break;
805         case GetArgumentCountIncludingThis:
806             compileGetArgumentCountIncludingThis();
807             break;
808         case GetScope:
809             compileGetScope();
810             break;
811         case SkipScope:
812             compileSkipScope();
813             break;
814         case GetGlobalObject:
815             compileGetGlobalObject();
816             break;
817         case GetClosureVar:
818             compileGetClosureVar();
819             break;
820         case PutClosureVar:
821             compilePutClosureVar();
822             break;
823         case GetFromArguments:
824             compileGetFromArguments();
825             break;
826         case PutToArguments:
827             compilePutToArguments();
828             break;
829         case CompareEq:
830             compileCompareEq();
831             break;
832         case CompareStrictEq:
833             compileCompareStrictEq();
834             break;
835         case CompareLess:
836             compileCompareLess();
837             break;
838         case CompareLessEq:
839             compileCompareLessEq();
840             break;
841         case CompareGreater:
842             compileCompareGreater();
843             break;
844         case CompareGreaterEq:
845             compileCompareGreaterEq();
846             break;
847         case CompareEqPtr:
848             compileCompareEqPtr();
849             break;
850         case LogicalNot:
851             compileLogicalNot();
852             break;
853         case Call:
854         case TailCallInlinedCaller:
855         case Construct:
856             compileCallOrConstruct();
857             break;
858         case DirectCall:
859         case DirectTailCallInlinedCaller:
860         case DirectConstruct:
861         case DirectTailCall:
862             compileDirectCallOrConstruct();
863             break;
864         case TailCall:
865             compileTailCall();
866             break;
867         case CallVarargs:
868         case CallForwardVarargs:
869         case TailCallVarargs:
870         case TailCallVarargsInlinedCaller:
871         case TailCallForwardVarargs:
872         case TailCallForwardVarargsInlinedCaller:
873         case ConstructVarargs:
874         case ConstructForwardVarargs:
875             compileCallOrConstructVarargs();
876             break;
877         case CallEval:
878             compileCallEval();
879             break;
880         case LoadVarargs:
881             compileLoadVarargs();
882             break;
883         case ForwardVarargs:
884             compileForwardVarargs();
885             break;
886         case DFG::Jump:
887             compileJump();
888             break;
889         case DFG::Branch:
890             compileBranch();
891             break;
892         case DFG::Switch:
893             compileSwitch();
894             break;
895         case DFG::Return:
896             compileReturn();
897             break;
898         case ForceOSRExit:
899             compileForceOSRExit();
900             break;
901         case Throw:
902         case ThrowStaticError:
903             compileThrow();
904             break;
905         case InvalidationPoint:
906             compileInvalidationPoint();
907             break;
908         case IsEmpty:
909             compileIsEmpty();
910             break;
911         case IsUndefined:
912             compileIsUndefined();
913             break;
914         case IsBoolean:
915             compileIsBoolean();
916             break;
917         case IsNumber:
918             compileIsNumber();
919             break;
920         case IsCellWithType:
921             compileIsCellWithType();
922             break;
923         case MapHash:
924             compileMapHash();
925             break;
926         case GetMapBucket:
927             compileGetMapBucket();
928             break;
929         case LoadFromJSMapBucket:
930             compileLoadFromJSMapBucket();
931             break;
932         case IsNonEmptyMapBucket:
933             compileIsNonEmptyMapBucket();
934             break;
935         case IsObject:
936             compileIsObject();
937             break;
938         case IsObjectOrNull:
939             compileIsObjectOrNull();
940             break;
941         case IsFunction:
942             compileIsFunction();
943             break;
944         case IsTypedArrayView:
945             compileIsTypedArrayView();
946             break;
947         case TypeOf:
948             compileTypeOf();
949             break;
950         case CheckTypeInfoFlags:
951             compileCheckTypeInfoFlags();
952             break;
953         case OverridesHasInstance:
954             compileOverridesHasInstance();
955             break;
956         case InstanceOf:
957             compileInstanceOf();
958             break;
959         case InstanceOfCustom:
960             compileInstanceOfCustom();
961             break;
962         case CountExecution:
963             compileCountExecution();
964             break;
965         case StoreBarrier:
966         case FencedStoreBarrier:
967             compileStoreBarrier();
968             break;
969         case HasIndexedProperty:
970             compileHasIndexedProperty();
971             break;
972         case HasGenericProperty:
973             compileHasGenericProperty();
974             break;
975         case HasStructureProperty:
976             compileHasStructureProperty();
977             break;
978         case GetDirectPname:
979             compileGetDirectPname();
980             break;
981         case GetEnumerableLength:
982             compileGetEnumerableLength();
983             break;
984         case GetPropertyEnumerator:
985             compileGetPropertyEnumerator();
986             break;
987         case GetEnumeratorStructurePname:
988             compileGetEnumeratorStructurePname();
989             break;
990         case GetEnumeratorGenericPname:
991             compileGetEnumeratorGenericPname();
992             break;
993         case ToIndexString:
994             compileToIndexString();
995             break;
996         case CheckStructureImmediate:
997             compileCheckStructureImmediate();
998             break;
999         case MaterializeNewObject:
1000             compileMaterializeNewObject();
1001             break;
1002         case MaterializeCreateActivation:
1003             compileMaterializeCreateActivation();
1004             break;
1005         case CheckWatchdogTimer:
1006             compileCheckWatchdogTimer();
1007             break;
1008         case CreateRest:
1009             compileCreateRest();
1010             break;
1011         case GetRestLength:
1012             compileGetRestLength();
1013             break;
1014         case RegExpExec:
1015             compileRegExpExec();
1016             break;
1017         case RegExpTest:
1018             compileRegExpTest();
1019             break;
1020         case NewRegexp:
1021             compileNewRegexp();
1022             break;
1023         case SetFunctionName:
1024             compileSetFunctionName();
1025             break;
1026         case StringReplace:
1027         case StringReplaceRegExp:
1028             compileStringReplace();
1029             break;
1030         case GetRegExpObjectLastIndex:
1031             compileGetRegExpObjectLastIndex();
1032             break;
1033         case SetRegExpObjectLastIndex:
1034             compileSetRegExpObjectLastIndex();
1035             break;
1036         case LogShadowChickenPrologue:
1037             compileLogShadowChickenPrologue();
1038             break;
1039         case LogShadowChickenTail:
1040             compileLogShadowChickenTail();
1041             break;
1042         case RecordRegExpCachedResult:
1043             compileRecordRegExpCachedResult();
1044             break;
1045         case ResolveScope:
1046             compileResolveScope();
1047             break;
1048         case GetDynamicVar:
1049             compileGetDynamicVar();
1050             break;
1051         case PutDynamicVar:
1052             compilePutDynamicVar();
1053             break;
1054         case Unreachable:
1055             compileUnreachable();
1056             break;
1057         case ToLowerCase:
1058             compileToLowerCase();
1059             break;
1060         case CheckDOM:
1061             compileCheckDOM();
1062             break;
1063         case CallDOMGetter:
1064             compileCallDOMGetter();
1065             break;
1066
1067         case PhantomLocal:
1068         case LoopHint:
1069         case MovHint:
1070         case ZombieHint:
1071         case ExitOK:
1072         case PhantomNewObject:
1073         case PhantomNewFunction:
1074         case PhantomNewGeneratorFunction:
1075         case PhantomCreateActivation:
1076         case PhantomDirectArguments:
1077         case PhantomClonedArguments:
1078         case PutHint:
1079         case BottomValue:
1080         case KillStack:
1081             break;
1082         default:
1083             DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
1084             break;
1085         }
1086         
1087         if (m_node->isTerminal())
1088             return false;
1089         
1090         if (!m_state.isValid()) {
1091             safelyInvalidateAfterTermination();
1092             return false;
1093         }
1094
1095         m_availabilityCalculator.executeNode(m_node);
1096         m_interpreter.executeEffects(nodeIndex);
1097         
1098         return true;
1099     }
1100
1101     void compileUpsilon()
1102     {
1103         LValue upsilonValue = nullptr;
1104         switch (m_node->child1().useKind()) {
1105         case DoubleRepUse:
1106             upsilonValue = lowDouble(m_node->child1());
1107             break;
1108         case Int32Use:
1109         case KnownInt32Use:
1110             upsilonValue = lowInt32(m_node->child1());
1111             break;
1112         case Int52RepUse:
1113             upsilonValue = lowInt52(m_node->child1());
1114             break;
1115         case BooleanUse:
1116         case KnownBooleanUse:
1117             upsilonValue = lowBoolean(m_node->child1());
1118             break;
1119         case CellUse:
1120         case KnownCellUse:
1121             upsilonValue = lowCell(m_node->child1());
1122             break;
1123         case UntypedUse:
1124             upsilonValue = lowJSValue(m_node->child1());
1125             break;
1126         default:
1127             DFG_CRASH(m_graph, m_node, "Bad use kind");
1128             break;
1129         }
1130         ValueFromBlock upsilon = m_out.anchor(upsilonValue);
1131         LValue phiNode = m_phis.get(m_node->phi());
1132         m_out.addIncomingToPhi(phiNode, upsilon);
1133     }
1134     
1135     void compilePhi()
1136     {
1137         LValue phi = m_phis.get(m_node);
1138         m_out.m_block->append(phi);
1139
1140         switch (m_node->flags() & NodeResultMask) {
1141         case NodeResultDouble:
1142             setDouble(phi);
1143             break;
1144         case NodeResultInt32:
1145             setInt32(phi);
1146             break;
1147         case NodeResultInt52:
1148             setInt52(phi);
1149             break;
1150         case NodeResultBoolean:
1151             setBoolean(phi);
1152             break;
1153         case NodeResultJS:
1154             setJSValue(phi);
1155             break;
1156         default:
1157             DFG_CRASH(m_graph, m_node, "Bad use kind");
1158             break;
1159         }
1160     }
1161     
1162     void compileDoubleConstant()
1163     {
1164         setDouble(m_out.constDouble(m_node->asNumber()));
1165     }
1166     
1167     void compileInt52Constant()
1168     {
1169         int64_t value = m_node->asAnyInt();
1170         
1171         setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
1172         setStrictInt52(m_out.constInt64(value));
1173     }
1174
1175     void compileLazyJSConstant()
1176     {
1177         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1178         LazyJSValue value = m_node->lazyJSValue();
1179         patchpoint->setGenerator(
1180             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1181                 value.emit(jit, JSValueRegs(params[0].gpr()));
1182             });
1183         patchpoint->effects = Effects::none();
1184         setJSValue(patchpoint);
1185     }
1186
1187     void compileDoubleRep()
1188     {
1189         switch (m_node->child1().useKind()) {
1190         case RealNumberUse: {
1191             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1192             
1193             LValue doubleValue = unboxDouble(value);
1194             
1195             LBasicBlock intCase = m_out.newBlock();
1196             LBasicBlock continuation = m_out.newBlock();
1197             
1198             ValueFromBlock fastResult = m_out.anchor(doubleValue);
1199             m_out.branch(
1200                 m_out.doubleEqual(doubleValue, doubleValue),
1201                 usually(continuation), rarely(intCase));
1202             
1203             LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
1204
1205             FTL_TYPE_CHECK(
1206                 jsValueValue(value), m_node->child1(), SpecBytecodeRealNumber,
1207                 isNotInt32(value, provenType(m_node->child1()) & ~SpecDoubleReal));
1208             ValueFromBlock slowResult = m_out.anchor(m_out.intToDouble(unboxInt32(value)));
1209             m_out.jump(continuation);
1210             
1211             m_out.appendTo(continuation, lastNext);
1212             
1213             setDouble(m_out.phi(Double, fastResult, slowResult));
1214             return;
1215         }
1216             
1217         case NotCellUse:
1218         case NumberUse: {
1219             bool shouldConvertNonNumber = m_node->child1().useKind() == NotCellUse;
1220             
1221             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1222
1223             LBasicBlock intCase = m_out.newBlock();
1224             LBasicBlock doubleTesting = m_out.newBlock();
1225             LBasicBlock doubleCase = m_out.newBlock();
1226             LBasicBlock nonDoubleCase = m_out.newBlock();
1227             LBasicBlock continuation = m_out.newBlock();
1228             
1229             m_out.branch(
1230                 isNotInt32(value, provenType(m_node->child1())),
1231                 unsure(doubleTesting), unsure(intCase));
1232             
1233             LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
1234             
1235             ValueFromBlock intToDouble = m_out.anchor(
1236                 m_out.intToDouble(unboxInt32(value)));
1237             m_out.jump(continuation);
1238             
1239             m_out.appendTo(doubleTesting, doubleCase);
1240             LValue valueIsNumber = isNumber(value, provenType(m_node->child1()));
1241             m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
1242
1243             m_out.appendTo(doubleCase, nonDoubleCase);
1244             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(value));
1245             m_out.jump(continuation);
1246
1247             if (shouldConvertNonNumber) {
1248                 LBasicBlock undefinedCase = m_out.newBlock();
1249                 LBasicBlock testNullCase = m_out.newBlock();
1250                 LBasicBlock nullCase = m_out.newBlock();
1251                 LBasicBlock testBooleanTrueCase = m_out.newBlock();
1252                 LBasicBlock convertBooleanTrueCase = m_out.newBlock();
1253                 LBasicBlock convertBooleanFalseCase = m_out.newBlock();
1254
1255                 m_out.appendTo(nonDoubleCase, undefinedCase);
1256                 LValue valueIsUndefined = m_out.equal(value, m_out.constInt64(ValueUndefined));
1257                 m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
1258
1259                 m_out.appendTo(undefinedCase, testNullCase);
1260                 ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
1261                 m_out.jump(continuation);
1262
1263                 m_out.appendTo(testNullCase, nullCase);
1264                 LValue valueIsNull = m_out.equal(value, m_out.constInt64(ValueNull));
1265                 m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
1266
1267                 m_out.appendTo(nullCase, testBooleanTrueCase);
1268                 ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
1269                 m_out.jump(continuation);
1270
1271                 m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
1272                 LValue valueIsBooleanTrue = m_out.equal(value, m_out.constInt64(ValueTrue));
1273                 m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
1274
1275                 m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
1276                 ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
1277                 m_out.jump(continuation);
1278
1279                 m_out.appendTo(convertBooleanFalseCase, continuation);
1280
1281                 LValue valueIsNotBooleanFalse = m_out.notEqual(value, m_out.constInt64(ValueFalse));
1282                 FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), ~SpecCell, valueIsNotBooleanFalse);
1283                 ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
1284                 m_out.jump(continuation);
1285
1286                 m_out.appendTo(continuation, lastNext);
1287                 setDouble(m_out.phi(Double, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse));
1288                 return;
1289             }
1290             m_out.appendTo(nonDoubleCase, continuation);
1291             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecBytecodeNumber, m_out.booleanTrue);
1292             m_out.unreachable();
1293
1294             m_out.appendTo(continuation, lastNext);
1295
1296             setDouble(m_out.phi(Double, intToDouble, unboxedDouble));
1297             return;
1298         }
1299             
1300         case Int52RepUse: {
1301             setDouble(strictInt52ToDouble(lowStrictInt52(m_node->child1())));
1302             return;
1303         }
1304             
1305         default:
1306             DFG_CRASH(m_graph, m_node, "Bad use kind");
1307         }
1308     }
1309
1310     void compileDoubleAsInt32()
1311     {
1312         LValue integerValue = convertDoubleToInt32(lowDouble(m_node->child1()), shouldCheckNegativeZero(m_node->arithMode()));
1313         setInt32(integerValue);
1314     }
1315
1316     void compileValueRep()
1317     {
1318         switch (m_node->child1().useKind()) {
1319         case DoubleRepUse: {
1320             LValue value = lowDouble(m_node->child1());
1321             
1322             if (m_interpreter.needsTypeCheck(m_node->child1(), ~SpecDoubleImpureNaN)) {
1323                 value = m_out.select(
1324                     m_out.doubleEqual(value, value), value, m_out.constDouble(PNaN));
1325             }
1326             
1327             setJSValue(boxDouble(value));
1328             return;
1329         }
1330             
1331         case Int52RepUse: {
1332             setJSValue(strictInt52ToJSValue(lowStrictInt52(m_node->child1())));
1333             return;
1334         }
1335             
1336         default:
1337             DFG_CRASH(m_graph, m_node, "Bad use kind");
1338         }
1339     }
1340     
1341     void compileInt52Rep()
1342     {
1343         switch (m_node->child1().useKind()) {
1344         case Int32Use:
1345             setStrictInt52(m_out.signExt32To64(lowInt32(m_node->child1())));
1346             return;
1347             
1348         case AnyIntUse:
1349             setStrictInt52(
1350                 jsValueToStrictInt52(
1351                     m_node->child1(), lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1352             return;
1353             
1354         case DoubleRepAnyIntUse:
1355             setStrictInt52(
1356                 doubleToStrictInt52(
1357                     m_node->child1(), lowDouble(m_node->child1())));
1358             return;
1359             
1360         default:
1361             RELEASE_ASSERT_NOT_REACHED();
1362         }
1363     }
1364     
1365     void compileValueToInt32()
1366     {
1367         switch (m_node->child1().useKind()) {
1368         case Int52RepUse:
1369             setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
1370             break;
1371             
1372         case DoubleRepUse:
1373             setInt32(doubleToInt32(lowDouble(m_node->child1())));
1374             break;
1375             
1376         case NumberUse:
1377         case NotCellUse: {
1378             LoweredNodeValue value = m_int32Values.get(m_node->child1().node());
1379             if (isValid(value)) {
1380                 setInt32(value.value());
1381                 break;
1382             }
1383             
1384             value = m_jsValueValues.get(m_node->child1().node());
1385             if (isValid(value)) {
1386                 setInt32(numberOrNotCellToInt32(m_node->child1(), value.value()));
1387                 break;
1388             }
1389             
1390             // We'll basically just get here for constants. But it's good to have this
1391             // catch-all since we often add new representations into the mix.
1392             setInt32(
1393                 numberOrNotCellToInt32(
1394                     m_node->child1(),
1395                     lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1396             break;
1397         }
1398             
1399         default:
1400             DFG_CRASH(m_graph, m_node, "Bad use kind");
1401             break;
1402         }
1403     }
1404     
1405     void compileBooleanToNumber()
1406     {
1407         switch (m_node->child1().useKind()) {
1408         case BooleanUse: {
1409             setInt32(m_out.zeroExt(lowBoolean(m_node->child1()), Int32));
1410             return;
1411         }
1412             
1413         case UntypedUse: {
1414             LValue value = lowJSValue(m_node->child1());
1415             
1416             if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecBoolInt32 | SpecBoolean)) {
1417                 setInt32(m_out.bitAnd(m_out.castToInt32(value), m_out.int32One));
1418                 return;
1419             }
1420             
1421             LBasicBlock booleanCase = m_out.newBlock();
1422             LBasicBlock continuation = m_out.newBlock();
1423             
1424             ValueFromBlock notBooleanResult = m_out.anchor(value);
1425             m_out.branch(
1426                 isBoolean(value, provenType(m_node->child1())),
1427                 unsure(booleanCase), unsure(continuation));
1428             
1429             LBasicBlock lastNext = m_out.appendTo(booleanCase, continuation);
1430             ValueFromBlock booleanResult = m_out.anchor(m_out.bitOr(
1431                 m_out.zeroExt(unboxBoolean(value), Int64), m_tagTypeNumber));
1432             m_out.jump(continuation);
1433             
1434             m_out.appendTo(continuation, lastNext);
1435             setJSValue(m_out.phi(Int64, booleanResult, notBooleanResult));
1436             return;
1437         }
1438             
1439         default:
1440             RELEASE_ASSERT_NOT_REACHED();
1441             return;
1442         }
1443     }
1444
1445     void compileExtractOSREntryLocal()
1446     {
1447         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(
1448             m_ftlState.jitCode->ftlForOSREntry()->entryBuffer()->dataBuffer());
1449         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->unlinkedLocal().toLocal())));
1450     }
1451     
1452     void compileGetStack()
1453     {
1454         // GetLocals arise only for captured variables and arguments. For arguments, we might have
1455         // already loaded it.
1456         if (LValue value = m_loadedArgumentValues.get(m_node)) {
1457             setJSValue(value);
1458             return;
1459         }
1460         
1461         StackAccessData* data = m_node->stackAccessData();
1462         AbstractValue& value = m_state.variables().operand(data->local);
1463         
1464         DFG_ASSERT(m_graph, m_node, isConcrete(data->format));
1465         DFG_ASSERT(m_graph, m_node, data->format != FlushedDouble); // This just happens to not arise for GetStacks, right now. It would be trivial to support.
1466         
1467         if (isInt32Speculation(value.m_type))
1468             setInt32(m_out.load32(payloadFor(data->machineLocal)));
1469         else
1470             setJSValue(m_out.load64(addressFor(data->machineLocal)));
1471     }
1472     
1473     void compilePutStack()
1474     {
1475         StackAccessData* data = m_node->stackAccessData();
1476         switch (data->format) {
1477         case FlushedJSValue: {
1478             LValue value = lowJSValue(m_node->child1());
1479             m_out.store64(value, addressFor(data->machineLocal));
1480             break;
1481         }
1482             
1483         case FlushedDouble: {
1484             LValue value = lowDouble(m_node->child1());
1485             m_out.storeDouble(value, addressFor(data->machineLocal));
1486             break;
1487         }
1488             
1489         case FlushedInt32: {
1490             LValue value = lowInt32(m_node->child1());
1491             m_out.store32(value, payloadFor(data->machineLocal));
1492             break;
1493         }
1494             
1495         case FlushedInt52: {
1496             LValue value = lowInt52(m_node->child1());
1497             m_out.store64(value, addressFor(data->machineLocal));
1498             break;
1499         }
1500             
1501         case FlushedCell: {
1502             LValue value = lowCell(m_node->child1());
1503             m_out.store64(value, addressFor(data->machineLocal));
1504             break;
1505         }
1506             
1507         case FlushedBoolean: {
1508             speculateBoolean(m_node->child1());
1509             m_out.store64(
1510                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1511                 addressFor(data->machineLocal));
1512             break;
1513         }
1514             
1515         default:
1516             DFG_CRASH(m_graph, m_node, "Bad flush format");
1517             break;
1518         }
1519     }
1520     
1521     void compileNoOp()
1522     {
1523         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
1524     }
1525
1526     void compileCallObjectConstructor()
1527     {
1528         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
1529         LValue value = lowJSValue(m_node->child1());
1530
1531         LBasicBlock isCellCase = m_out.newBlock();
1532         LBasicBlock slowCase = m_out.newBlock();
1533         LBasicBlock continuation = m_out.newBlock();
1534
1535         m_out.branch(isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1536
1537         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1538         ValueFromBlock fastResult = m_out.anchor(value);
1539         m_out.branch(isObject(value), usually(continuation), rarely(slowCase));
1540
1541         m_out.appendTo(slowCase, continuation);
1542         ValueFromBlock slowResult = m_out.anchor(vmCall(Int64, m_out.operation(operationObjectConstructor), m_callFrame, m_out.constIntPtr(globalObject), value));
1543         m_out.jump(continuation);
1544
1545         m_out.appendTo(continuation, lastNext);
1546         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1547     }
1548     
1549     void compileToThis()
1550     {
1551         LValue value = lowJSValue(m_node->child1());
1552         
1553         LBasicBlock isCellCase = m_out.newBlock();
1554         LBasicBlock slowCase = m_out.newBlock();
1555         LBasicBlock continuation = m_out.newBlock();
1556         
1557         m_out.branch(
1558             isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1559         
1560         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1561         ValueFromBlock fastResult = m_out.anchor(value);
1562         m_out.branch(
1563             m_out.testIsZero32(
1564                 m_out.load8ZeroExt32(value, m_heaps.JSCell_typeInfoFlags),
1565                 m_out.constInt32(OverridesToThis)),
1566             usually(continuation), rarely(slowCase));
1567         
1568         m_out.appendTo(slowCase, continuation);
1569         J_JITOperation_EJ function;
1570         if (m_graph.isStrictModeFor(m_node->origin.semantic))
1571             function = operationToThisStrict;
1572         else
1573             function = operationToThis;
1574         ValueFromBlock slowResult = m_out.anchor(
1575             vmCall(Int64, m_out.operation(function), m_callFrame, value));
1576         m_out.jump(continuation);
1577         
1578         m_out.appendTo(continuation, lastNext);
1579         setJSValue(m_out.phi(Int64, fastResult, slowResult));
1580     }
1581
1582     void compileValueAdd()
1583     {
1584         ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
1585         JITAddIC* addIC = codeBlock()->addJITAddIC(arithProfile);
1586         auto repatchingFunction = operationValueAddOptimize;
1587         auto nonRepatchingFunction = operationValueAdd;
1588         compileMathIC(addIC, repatchingFunction, nonRepatchingFunction);
1589     }
1590
1591     template <typename Generator>
1592     void compileMathIC(JITUnaryMathIC<Generator>* mathIC, FunctionPtr repatchingFunction, FunctionPtr nonRepatchingFunction)
1593     {
1594         Node* node = m_node;
1595
1596         LValue operand = lowJSValue(node->child1());
1597
1598         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1599         patchpoint->appendSomeRegister(operand);
1600         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1601         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1602         RefPtr<PatchpointExceptionHandle> exceptionHandle = preparePatchpointForExceptions(patchpoint);
1603         patchpoint->numGPScratchRegisters = 1;
1604         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1605         State* state = &m_ftlState;
1606         patchpoint->setGenerator(
1607             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1608                 AllowMacroScratchRegisterUsage allowScratch(jit);
1609
1610                 Box<CCallHelpers::JumpList> exceptions =
1611                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1612
1613 #if ENABLE(MATH_IC_STATS)
1614                 auto inlineStart = jit.label();
1615 #endif
1616
1617                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1618                 mathIC->m_generator = Generator(JSValueRegs(params[0].gpr()), JSValueRegs(params[1].gpr()), params.gpScratch(0));
1619
1620                 bool shouldEmitProfiling = false;
1621                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1622
1623                 if (generatedInline) {
1624                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1625                     auto done = jit.label();
1626                     params.addLatePath([=] (CCallHelpers& jit) {
1627                         AllowMacroScratchRegisterUsage allowScratch(jit);
1628                         mathICGenerationState->slowPathJumps.link(&jit);
1629                         mathICGenerationState->slowPathStart = jit.label();
1630 #if ENABLE(MATH_IC_STATS)
1631                         auto slowPathStart = jit.label();
1632 #endif
1633
1634                         if (mathICGenerationState->shouldSlowPathRepatch) {
1635                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1636                                 repatchingFunction, params[0].gpr(), params[1].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1637                             mathICGenerationState->slowPathCall = call.call();
1638                         } else {
1639                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1640                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr());
1641                             mathICGenerationState->slowPathCall = call.call();
1642                         }
1643                         jit.jump().linkTo(done, &jit);
1644
1645                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1646                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1647                         });
1648
1649 #if ENABLE(MATH_IC_STATS)
1650                         auto slowPathEnd = jit.label();
1651                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1652                             size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
1653                             mathIC->m_generatedCodeSize += size;
1654                         });
1655 #endif
1656                     });
1657                 } else {
1658                     callOperation(
1659                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1660                         nonRepatchingFunction, params[0].gpr(), params[1].gpr());
1661                 }
1662
1663 #if ENABLE(MATH_IC_STATS)
1664                 auto inlineEnd = jit.label();
1665                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1666                     size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
1667                     mathIC->m_generatedCodeSize += size;
1668                 });
1669 #endif
1670             });
1671
1672         setJSValue(patchpoint);
1673     }
1674
1675     template <typename Generator>
1676     void compileMathIC(JITBinaryMathIC<Generator>* mathIC, FunctionPtr repatchingFunction, FunctionPtr nonRepatchingFunction)
1677     {
1678         Node* node = m_node;
1679         
1680         LValue left = lowJSValue(node->child1());
1681         LValue right = lowJSValue(node->child2());
1682
1683         SnippetOperand leftOperand(m_state.forNode(node->child1()).resultType());
1684         SnippetOperand rightOperand(m_state.forNode(node->child2()).resultType());
1685             
1686         PatchpointValue* patchpoint = m_out.patchpoint(Int64);
1687         patchpoint->appendSomeRegister(left);
1688         patchpoint->appendSomeRegister(right);
1689         patchpoint->append(m_tagMask, ValueRep::lateReg(GPRInfo::tagMaskRegister));
1690         patchpoint->append(m_tagTypeNumber, ValueRep::lateReg(GPRInfo::tagTypeNumberRegister));
1691         RefPtr<PatchpointExceptionHandle> exceptionHandle =
1692             preparePatchpointForExceptions(patchpoint);
1693         patchpoint->numGPScratchRegisters = 1;
1694         patchpoint->numFPScratchRegisters = 2;
1695         patchpoint->clobber(RegisterSet::macroScratchRegisters());
1696         State* state = &m_ftlState;
1697         patchpoint->setGenerator(
1698             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1699                 AllowMacroScratchRegisterUsage allowScratch(jit);
1700
1701                 Box<CCallHelpers::JumpList> exceptions =
1702                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
1703
1704 #if ENABLE(MATH_IC_STATS)
1705                 auto inlineStart = jit.label();
1706 #endif
1707
1708                 Box<MathICGenerationState> mathICGenerationState = Box<MathICGenerationState>::create();
1709                 mathIC->m_generator = Generator(leftOperand, rightOperand, JSValueRegs(params[0].gpr()),
1710                     JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()), params.fpScratch(0),
1711                     params.fpScratch(1), params.gpScratch(0), InvalidFPRReg);
1712
1713                 bool shouldEmitProfiling = false;
1714                 bool generatedInline = mathIC->generateInline(jit, *mathICGenerationState, shouldEmitProfiling);
1715
1716                 if (generatedInline) {
1717                     ASSERT(!mathICGenerationState->slowPathJumps.empty());
1718                     auto done = jit.label();
1719                     params.addLatePath([=] (CCallHelpers& jit) {
1720                         AllowMacroScratchRegisterUsage allowScratch(jit);
1721                         mathICGenerationState->slowPathJumps.link(&jit);
1722                         mathICGenerationState->slowPathStart = jit.label();
1723 #if ENABLE(MATH_IC_STATS)
1724                         auto slowPathStart = jit.label();
1725 #endif
1726
1727                         if (mathICGenerationState->shouldSlowPathRepatch) {
1728                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1729                                 repatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr(), CCallHelpers::TrustedImmPtr(mathIC));
1730                             mathICGenerationState->slowPathCall = call.call();
1731                         } else {
1732                             SlowPathCall call = callOperation(*state, params.unavailableRegisters(), jit, node->origin.semantic,
1733                                 exceptions.get(), nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1734                             mathICGenerationState->slowPathCall = call.call();
1735                         }
1736                         jit.jump().linkTo(done, &jit);
1737
1738                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1739                             mathIC->finalizeInlineCode(*mathICGenerationState, linkBuffer);
1740                         });
1741
1742 #if ENABLE(MATH_IC_STATS)
1743                         auto slowPathEnd = jit.label();
1744                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1745                             size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
1746                             mathIC->m_generatedCodeSize += size;
1747                         });
1748 #endif
1749                     });
1750                 } else {
1751                     callOperation(
1752                         *state, params.unavailableRegisters(), jit, node->origin.semantic, exceptions.get(),
1753                         nonRepatchingFunction, params[0].gpr(), params[1].gpr(), params[2].gpr());
1754                 }
1755
1756 #if ENABLE(MATH_IC_STATS)
1757                 auto inlineEnd = jit.label();
1758                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
1759                     size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
1760                     mathIC->m_generatedCodeSize += size;
1761                 });
1762 #endif
1763             });
1764
1765         setJSValue(patchpoint);
1766     }
1767     
1768     void compileStrCat()
1769     {
1770         LValue result;
1771         if (m_node->child3()) {
1772             result = vmCall(
1773                 Int64, m_out.operation(operationStrCat3), m_callFrame,
1774                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1775                 lowJSValue(m_node->child2(), ManualOperandSpeculation),
1776                 lowJSValue(m_node->child3(), ManualOperandSpeculation));
1777         } else {
1778             result = vmCall(
1779                 Int64, m_out.operation(operationStrCat2), m_callFrame,
1780                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1781                 lowJSValue(m_node->child2(), ManualOperandSpeculation));
1782         }
1783         setJSValue(result);
1784     }
1785     
1786     void compileArithAddOrSub()
1787     {
1788         bool isSub =  m_node->op() == ArithSub;
1789         switch (m_node->binaryUseKind()) {
1790         case Int32Use: {
1791             LValue left = lowInt32(m_node->child1());
1792             LValue right = lowInt32(m_node->child2());
1793
1794             if (!shouldCheckOverflow(m_node->arithMode())) {
1795                 setInt32(isSub ? m_out.sub(left, right) : m_out.add(left, right));
1796                 break;
1797             }
1798
1799             CheckValue* result =
1800                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1801             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1802             setInt32(result);
1803             break;
1804         }
1805             
1806         case Int52RepUse: {
1807             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)
1808                 && !abstractValue(m_node->child2()).couldBeType(SpecInt52Only)) {
1809                 Int52Kind kind;
1810                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
1811                 LValue right = lowInt52(m_node->child2(), kind);
1812                 setInt52(isSub ? m_out.sub(left, right) : m_out.add(left, right), kind);
1813                 break;
1814             }
1815
1816             LValue left = lowInt52(m_node->child1());
1817             LValue right = lowInt52(m_node->child2());
1818             CheckValue* result =
1819                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1820             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1821             setInt52(result);
1822             break;
1823         }
1824             
1825         case DoubleRepUse: {
1826             LValue C1 = lowDouble(m_node->child1());
1827             LValue C2 = lowDouble(m_node->child2());
1828
1829             setDouble(isSub ? m_out.doubleSub(C1, C2) : m_out.doubleAdd(C1, C2));
1830             break;
1831         }
1832
1833         case UntypedUse: {
1834             if (!isSub) {
1835                 DFG_CRASH(m_graph, m_node, "Bad use kind");
1836                 break;
1837             }
1838
1839             ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
1840             JITSubIC* subIC = codeBlock()->addJITSubIC(arithProfile);
1841             auto repatchingFunction = operationValueSubOptimize;
1842             auto nonRepatchingFunction = operationValueSub;
1843             compileMathIC(subIC, repatchingFunction, nonRepatchingFunction);
1844             break;
1845         }
1846
1847         default:
1848             DFG_CRASH(m_graph, m_node, "Bad use kind");
1849             break;
1850         }
1851     }
1852
1853     void compileArithClz32()
1854     {
1855         if (m_node->child1().useKind() == Int32Use || m_node->child1().useKind() == KnownInt32Use) {
1856             LValue operand = lowInt32(m_node->child1());
1857             setInt32(m_out.ctlz32(operand));
1858             return;
1859         }
1860         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
1861         LValue argument = lowJSValue(m_node->child1());
1862         LValue result = vmCall(Int32, m_out.operation(operationArithClz32), m_callFrame, argument);
1863         setInt32(result);
1864     }
1865     
1866     void compileArithMul()
1867     {
1868         switch (m_node->binaryUseKind()) {
1869         case Int32Use: {
1870             LValue left = lowInt32(m_node->child1());
1871             LValue right = lowInt32(m_node->child2());
1872             
1873             LValue result;
1874
1875             if (!shouldCheckOverflow(m_node->arithMode()))
1876                 result = m_out.mul(left, right);
1877             else {
1878                 CheckValue* speculation = m_out.speculateMul(left, right);
1879                 blessSpeculation(speculation, Overflow, noValue(), nullptr, m_origin);
1880                 result = speculation;
1881             }
1882             
1883             if (shouldCheckNegativeZero(m_node->arithMode())) {
1884                 LBasicBlock slowCase = m_out.newBlock();
1885                 LBasicBlock continuation = m_out.newBlock();
1886                 
1887                 m_out.branch(
1888                     m_out.notZero32(result), usually(continuation), rarely(slowCase));
1889                 
1890                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1891                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int32Zero));
1892                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int32Zero));
1893                 m_out.jump(continuation);
1894                 m_out.appendTo(continuation, lastNext);
1895             }
1896             
1897             setInt32(result);
1898             break;
1899         }
1900             
1901         case Int52RepUse: {
1902             Int52Kind kind;
1903             LValue left = lowWhicheverInt52(m_node->child1(), kind);
1904             LValue right = lowInt52(m_node->child2(), opposite(kind));
1905
1906             CheckValue* result = m_out.speculateMul(left, right);
1907             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1908
1909             if (shouldCheckNegativeZero(m_node->arithMode())) {
1910                 LBasicBlock slowCase = m_out.newBlock();
1911                 LBasicBlock continuation = m_out.newBlock();
1912                 
1913                 m_out.branch(
1914                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
1915                 
1916                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1917                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int64Zero));
1918                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int64Zero));
1919                 m_out.jump(continuation);
1920                 m_out.appendTo(continuation, lastNext);
1921             }
1922             
1923             setInt52(result);
1924             break;
1925         }
1926             
1927         case DoubleRepUse: {
1928             setDouble(
1929                 m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1930             break;
1931         }
1932
1933         case UntypedUse: {
1934             ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
1935             JITMulIC* mulIC = codeBlock()->addJITMulIC(arithProfile);
1936             auto repatchingFunction = operationValueMulOptimize;
1937             auto nonRepatchingFunction = operationValueMul;
1938             compileMathIC(mulIC, repatchingFunction, nonRepatchingFunction);
1939             break;
1940         }
1941
1942         default:
1943             DFG_CRASH(m_graph, m_node, "Bad use kind");
1944             break;
1945         }
1946     }
1947
1948     void compileArithDiv()
1949     {
1950         switch (m_node->binaryUseKind()) {
1951         case Int32Use: {
1952             LValue numerator = lowInt32(m_node->child1());
1953             LValue denominator = lowInt32(m_node->child2());
1954
1955             if (shouldCheckNegativeZero(m_node->arithMode())) {
1956                 LBasicBlock zeroNumerator = m_out.newBlock();
1957                 LBasicBlock numeratorContinuation = m_out.newBlock();
1958
1959                 m_out.branch(
1960                     m_out.isZero32(numerator),
1961                     rarely(zeroNumerator), usually(numeratorContinuation));
1962
1963                 LBasicBlock innerLastNext = m_out.appendTo(zeroNumerator, numeratorContinuation);
1964
1965                 speculate(
1966                     NegativeZero, noValue(), 0, m_out.lessThan(denominator, m_out.int32Zero));
1967
1968                 m_out.jump(numeratorContinuation);
1969
1970                 m_out.appendTo(numeratorContinuation, innerLastNext);
1971             }
1972             
1973             if (shouldCheckOverflow(m_node->arithMode())) {
1974                 LBasicBlock unsafeDenominator = m_out.newBlock();
1975                 LBasicBlock continuation = m_out.newBlock();
1976
1977                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
1978                 m_out.branch(
1979                     m_out.above(adjustedDenominator, m_out.int32One),
1980                     usually(continuation), rarely(unsafeDenominator));
1981
1982                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
1983                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
1984                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
1985                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
1986                 m_out.jump(continuation);
1987
1988                 m_out.appendTo(continuation, lastNext);
1989                 LValue result = m_out.div(numerator, denominator);
1990                 speculate(
1991                     Overflow, noValue(), 0,
1992                     m_out.notEqual(m_out.mul(result, denominator), numerator));
1993                 setInt32(result);
1994             } else
1995                 setInt32(m_out.chillDiv(numerator, denominator));
1996
1997             break;
1998         }
1999             
2000         case DoubleRepUse: {
2001             setDouble(m_out.doubleDiv(
2002                 lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2003             break;
2004         }
2005
2006         case UntypedUse: {
2007             emitBinarySnippet<JITDivGenerator, NeedScratchFPR>(operationValueDiv);
2008             break;
2009         }
2010
2011         default:
2012             DFG_CRASH(m_graph, m_node, "Bad use kind");
2013             break;
2014         }
2015     }
2016     
2017     void compileArithMod()
2018     {
2019         switch (m_node->binaryUseKind()) {
2020         case Int32Use: {
2021             LValue numerator = lowInt32(m_node->child1());
2022             LValue denominator = lowInt32(m_node->child2());
2023
2024             LValue remainder;
2025             if (shouldCheckOverflow(m_node->arithMode())) {
2026                 LBasicBlock unsafeDenominator = m_out.newBlock();
2027                 LBasicBlock continuation = m_out.newBlock();
2028
2029                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
2030                 m_out.branch(
2031                     m_out.above(adjustedDenominator, m_out.int32One),
2032                     usually(continuation), rarely(unsafeDenominator));
2033
2034                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
2035                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
2036                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
2037                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
2038                 m_out.jump(continuation);
2039
2040                 m_out.appendTo(continuation, lastNext);
2041                 LValue result = m_out.mod(numerator, denominator);
2042                 remainder = result;
2043             } else
2044                 remainder = m_out.chillMod(numerator, denominator);
2045
2046             if (shouldCheckNegativeZero(m_node->arithMode())) {
2047                 LBasicBlock negativeNumerator = m_out.newBlock();
2048                 LBasicBlock numeratorContinuation = m_out.newBlock();
2049
2050                 m_out.branch(
2051                     m_out.lessThan(numerator, m_out.int32Zero),
2052                     unsure(negativeNumerator), unsure(numeratorContinuation));
2053
2054                 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
2055
2056                 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
2057
2058                 m_out.jump(numeratorContinuation);
2059
2060                 m_out.appendTo(numeratorContinuation, innerLastNext);
2061             }
2062
2063             setInt32(remainder);
2064             break;
2065         }
2066             
2067         case DoubleRepUse: {
2068             setDouble(
2069                 m_out.doubleMod(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
2070             break;
2071         }
2072             
2073         default:
2074             DFG_CRASH(m_graph, m_node, "Bad use kind");
2075             break;
2076         }
2077     }
2078
2079     void compileArithMinOrMax()
2080     {
2081         switch (m_node->binaryUseKind()) {
2082         case Int32Use: {
2083             LValue left = lowInt32(m_node->child1());
2084             LValue right = lowInt32(m_node->child2());
2085             
2086             setInt32(
2087                 m_out.select(
2088                     m_node->op() == ArithMin
2089                         ? m_out.lessThan(left, right)
2090                         : m_out.lessThan(right, left),
2091                     left, right));
2092             break;
2093         }
2094             
2095         case DoubleRepUse: {
2096             LValue left = lowDouble(m_node->child1());
2097             LValue right = lowDouble(m_node->child2());
2098             
2099             LBasicBlock notLessThan = m_out.newBlock();
2100             LBasicBlock continuation = m_out.newBlock();
2101             
2102             Vector<ValueFromBlock, 2> results;
2103             
2104             results.append(m_out.anchor(left));
2105             m_out.branch(
2106                 m_node->op() == ArithMin
2107                     ? m_out.doubleLessThan(left, right)
2108                     : m_out.doubleGreaterThan(left, right),
2109                 unsure(continuation), unsure(notLessThan));
2110             
2111             LBasicBlock lastNext = m_out.appendTo(notLessThan, continuation);
2112             results.append(m_out.anchor(m_out.select(
2113                 m_node->op() == ArithMin
2114                     ? m_out.doubleGreaterThanOrEqual(left, right)
2115                     : m_out.doubleLessThanOrEqual(left, right),
2116                 right, m_out.constDouble(PNaN))));
2117             m_out.jump(continuation);
2118             
2119             m_out.appendTo(continuation, lastNext);
2120             setDouble(m_out.phi(Double, results));
2121             break;
2122         }
2123             
2124         default:
2125             DFG_CRASH(m_graph, m_node, "Bad use kind");
2126             break;
2127         }
2128     }
2129     
2130     void compileArithAbs()
2131     {
2132         switch (m_node->child1().useKind()) {
2133         case Int32Use: {
2134             LValue value = lowInt32(m_node->child1());
2135
2136             LValue mask = m_out.aShr(value, m_out.constInt32(31));
2137             LValue result = m_out.bitXor(mask, m_out.add(mask, value));
2138
2139             if (shouldCheckOverflow(m_node->arithMode()))
2140                 speculate(Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
2141
2142             setInt32(result);
2143             break;
2144         }
2145             
2146         case DoubleRepUse: {
2147             setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
2148             break;
2149         }
2150             
2151         default: {
2152             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2153             LValue argument = lowJSValue(m_node->child1());
2154             LValue result = vmCall(Double, m_out.operation(operationArithAbs), m_callFrame, argument);
2155             setDouble(result);
2156             break;
2157         }
2158         }
2159     }
2160
2161     void compileArithSin()
2162     {
2163         if (m_node->child1().useKind() == DoubleRepUse) {
2164             setDouble(m_out.doubleSin(lowDouble(m_node->child1())));
2165             return;
2166         }
2167         LValue argument = lowJSValue(m_node->child1());
2168         LValue result = vmCall(Double, m_out.operation(operationArithSin), m_callFrame, argument);
2169         setDouble(result);
2170     }
2171
2172     void compileArithCos()
2173     {
2174         if (m_node->child1().useKind() == DoubleRepUse) {
2175             setDouble(m_out.doubleCos(lowDouble(m_node->child1())));
2176             return;
2177         }
2178         LValue argument = lowJSValue(m_node->child1());
2179         LValue result = vmCall(Double, m_out.operation(operationArithCos), m_callFrame, argument);
2180         setDouble(result);
2181     }
2182
2183     void compileArithTan()
2184     {
2185         if (m_node->child1().useKind() == DoubleRepUse) {
2186             setDouble(m_out.doubleTan(lowDouble(m_node->child1())));
2187             return;
2188         }
2189         LValue argument = lowJSValue(m_node->child1());
2190         LValue result = vmCall(Double, m_out.operation(operationArithTan), m_callFrame, argument);
2191         setDouble(result);
2192     }
2193
2194     void compileArithPow()
2195     {
2196         if (m_node->child2().useKind() == Int32Use)
2197             setDouble(m_out.doublePowi(lowDouble(m_node->child1()), lowInt32(m_node->child2())));
2198         else {
2199             LValue base = lowDouble(m_node->child1());
2200             LValue exponent = lowDouble(m_node->child2());
2201
2202             LBasicBlock integerExponentIsSmallBlock = m_out.newBlock();
2203             LBasicBlock integerExponentPowBlock = m_out.newBlock();
2204             LBasicBlock doubleExponentPowBlockEntry = m_out.newBlock();
2205             LBasicBlock nanExceptionBaseIsOne = m_out.newBlock();
2206             LBasicBlock nanExceptionExponentIsInfinity = m_out.newBlock();
2207             LBasicBlock testExponentIsOneHalf = m_out.newBlock();
2208             LBasicBlock handleBaseZeroExponentIsOneHalf = m_out.newBlock();
2209             LBasicBlock handleInfinityForExponentIsOneHalf = m_out.newBlock();
2210             LBasicBlock exponentIsOneHalfNormal = m_out.newBlock();
2211             LBasicBlock exponentIsOneHalfInfinity = m_out.newBlock();
2212             LBasicBlock testExponentIsNegativeOneHalf = m_out.newBlock();
2213             LBasicBlock testBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2214             LBasicBlock handleBaseZeroExponentIsNegativeOneHalf = m_out.newBlock();
2215             LBasicBlock handleInfinityForExponentIsNegativeOneHalf = m_out.newBlock();
2216             LBasicBlock exponentIsNegativeOneHalfNormal = m_out.newBlock();
2217             LBasicBlock exponentIsNegativeOneHalfInfinity = m_out.newBlock();
2218             LBasicBlock powBlock = m_out.newBlock();
2219             LBasicBlock nanExceptionResultIsNaN = m_out.newBlock();
2220             LBasicBlock continuation = m_out.newBlock();
2221
2222             LValue integerExponent = m_out.doubleToInt(exponent);
2223             LValue integerExponentConvertedToDouble = m_out.intToDouble(integerExponent);
2224             LValue exponentIsInteger = m_out.doubleEqual(exponent, integerExponentConvertedToDouble);
2225             m_out.branch(exponentIsInteger, unsure(integerExponentIsSmallBlock), unsure(doubleExponentPowBlockEntry));
2226
2227             LBasicBlock lastNext = m_out.appendTo(integerExponentIsSmallBlock, integerExponentPowBlock);
2228             LValue integerExponentBelowMax = m_out.belowOrEqual(integerExponent, m_out.constInt32(maxExponentForIntegerMathPow));
2229             m_out.branch(integerExponentBelowMax, usually(integerExponentPowBlock), rarely(doubleExponentPowBlockEntry));
2230
2231             m_out.appendTo(integerExponentPowBlock, doubleExponentPowBlockEntry);
2232             ValueFromBlock powDoubleIntResult = m_out.anchor(m_out.doublePowi(base, integerExponent));
2233             m_out.jump(continuation);
2234
2235             // If y is NaN, the result is NaN.
2236             m_out.appendTo(doubleExponentPowBlockEntry, nanExceptionBaseIsOne);
2237             LValue exponentIsNaN;
2238             if (provenType(m_node->child2()) & SpecDoubleNaN)
2239                 exponentIsNaN = m_out.doubleNotEqualOrUnordered(exponent, exponent);
2240             else
2241                 exponentIsNaN = m_out.booleanFalse;
2242             m_out.branch(exponentIsNaN, rarely(nanExceptionResultIsNaN), usually(nanExceptionBaseIsOne));
2243
2244             // If abs(x) is 1 and y is +infinity, the result is NaN.
2245             // If abs(x) is 1 and y is -infinity, the result is NaN.
2246
2247             //     Test if base == 1.
2248             m_out.appendTo(nanExceptionBaseIsOne, nanExceptionExponentIsInfinity);
2249             LValue absoluteBase = m_out.doubleAbs(base);
2250             LValue absoluteBaseIsOne = m_out.doubleEqual(absoluteBase, m_out.constDouble(1));
2251             m_out.branch(absoluteBaseIsOne, rarely(nanExceptionExponentIsInfinity), usually(testExponentIsOneHalf));
2252
2253             //     Test if abs(y) == Infinity.
2254             m_out.appendTo(nanExceptionExponentIsInfinity, testExponentIsOneHalf);
2255             LValue absoluteExponent = m_out.doubleAbs(exponent);
2256             LValue absoluteExponentIsInfinity = m_out.doubleEqual(absoluteExponent, m_out.constDouble(std::numeric_limits<double>::infinity()));
2257             m_out.branch(absoluteExponentIsInfinity, rarely(nanExceptionResultIsNaN), usually(testExponentIsOneHalf));
2258
2259             // If y == 0.5 or y == -0.5, handle it through SQRT.
2260             // We have be carefuly with -0 and -Infinity.
2261
2262             //     Test if y == 0.5
2263             m_out.appendTo(testExponentIsOneHalf, handleBaseZeroExponentIsOneHalf);
2264             LValue exponentIsOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(0.5));
2265             m_out.branch(exponentIsOneHalf, rarely(handleBaseZeroExponentIsOneHalf), usually(testExponentIsNegativeOneHalf));
2266
2267             //     Handle x == -0.
2268             m_out.appendTo(handleBaseZeroExponentIsOneHalf, handleInfinityForExponentIsOneHalf);
2269             LValue baseIsZeroExponentIsOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2270             ValueFromBlock zeroResultExponentIsOneHalf = m_out.anchor(m_out.doubleZero);
2271             m_out.branch(baseIsZeroExponentIsOneHalf, rarely(continuation), usually(handleInfinityForExponentIsOneHalf));
2272
2273             //     Test if abs(x) == Infinity.
2274             m_out.appendTo(handleInfinityForExponentIsOneHalf, exponentIsOneHalfNormal);
2275             LValue absoluteBaseIsInfinityOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2276             m_out.branch(absoluteBaseIsInfinityOneHalf, rarely(exponentIsOneHalfInfinity), usually(exponentIsOneHalfNormal));
2277
2278             //     The exponent is 0.5, the base is finite or NaN, we can use SQRT.
2279             m_out.appendTo(exponentIsOneHalfNormal, exponentIsOneHalfInfinity);
2280             ValueFromBlock sqrtResult = m_out.anchor(m_out.doubleSqrt(base));
2281             m_out.jump(continuation);
2282
2283             //     The exponent is 0.5, the base is infinite, the result is always infinite.
2284             m_out.appendTo(exponentIsOneHalfInfinity, testExponentIsNegativeOneHalf);
2285             ValueFromBlock sqrtInfinityResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2286             m_out.jump(continuation);
2287
2288             //     Test if y == -0.5
2289             m_out.appendTo(testExponentIsNegativeOneHalf, testBaseZeroExponentIsNegativeOneHalf);
2290             LValue exponentIsNegativeOneHalf = m_out.doubleEqual(exponent, m_out.constDouble(-0.5));
2291             m_out.branch(exponentIsNegativeOneHalf, rarely(testBaseZeroExponentIsNegativeOneHalf), usually(powBlock));
2292
2293             //     Handle x == -0.
2294             m_out.appendTo(testBaseZeroExponentIsNegativeOneHalf, handleBaseZeroExponentIsNegativeOneHalf);
2295             LValue baseIsZeroExponentIsNegativeOneHalf = m_out.doubleEqual(base, m_out.doubleZero);
2296             m_out.branch(baseIsZeroExponentIsNegativeOneHalf, rarely(handleBaseZeroExponentIsNegativeOneHalf), usually(handleInfinityForExponentIsNegativeOneHalf));
2297
2298             m_out.appendTo(handleBaseZeroExponentIsNegativeOneHalf, handleInfinityForExponentIsNegativeOneHalf);
2299             ValueFromBlock oneOverSqrtZeroResult = m_out.anchor(m_out.constDouble(std::numeric_limits<double>::infinity()));
2300             m_out.jump(continuation);
2301
2302             //     Test if abs(x) == Infinity.
2303             m_out.appendTo(handleInfinityForExponentIsNegativeOneHalf, exponentIsNegativeOneHalfNormal);
2304             LValue absoluteBaseIsInfinityNegativeOneHalf = m_out.doubleEqual(absoluteBase, m_out.constDouble(std::numeric_limits<double>::infinity()));
2305             m_out.branch(absoluteBaseIsInfinityNegativeOneHalf, rarely(exponentIsNegativeOneHalfInfinity), usually(exponentIsNegativeOneHalfNormal));
2306
2307             //     The exponent is -0.5, the base is finite or NaN, we can use 1/SQRT.
2308             m_out.appendTo(exponentIsNegativeOneHalfNormal, exponentIsNegativeOneHalfInfinity);
2309             LValue sqrtBase = m_out.doubleSqrt(base);
2310             ValueFromBlock oneOverSqrtResult = m_out.anchor(m_out.div(m_out.constDouble(1.), sqrtBase));
2311             m_out.jump(continuation);
2312
2313             //     The exponent is -0.5, the base is infinite, the result is always zero.
2314             m_out.appendTo(exponentIsNegativeOneHalfInfinity, powBlock);
2315             ValueFromBlock oneOverSqrtInfinityResult = m_out.anchor(m_out.doubleZero);
2316             m_out.jump(continuation);
2317
2318             m_out.appendTo(powBlock, nanExceptionResultIsNaN);
2319             ValueFromBlock powResult = m_out.anchor(m_out.doublePow(base, exponent));
2320             m_out.jump(continuation);
2321
2322             m_out.appendTo(nanExceptionResultIsNaN, continuation);
2323             ValueFromBlock pureNan = m_out.anchor(m_out.constDouble(PNaN));
2324             m_out.jump(continuation);
2325
2326             m_out.appendTo(continuation, lastNext);
2327             setDouble(m_out.phi(Double, powDoubleIntResult, zeroResultExponentIsOneHalf, sqrtResult, sqrtInfinityResult, oneOverSqrtZeroResult, oneOverSqrtResult, oneOverSqrtInfinityResult, powResult, pureNan));
2328         }
2329     }
2330
2331     void compileArithRandom()
2332     {
2333         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
2334
2335         // Inlined WeakRandom::advance().
2336         // uint64_t x = m_low;
2337         void* lowAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset();
2338         LValue low = m_out.load64(m_out.absolute(lowAddress));
2339         // uint64_t y = m_high;
2340         void* highAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset();
2341         LValue high = m_out.load64(m_out.absolute(highAddress));
2342         // m_low = y;
2343         m_out.store64(high, m_out.absolute(lowAddress));
2344
2345         // x ^= x << 23;
2346         LValue phase1 = m_out.bitXor(m_out.shl(low, m_out.constInt64(23)), low);
2347
2348         // x ^= x >> 17;
2349         LValue phase2 = m_out.bitXor(m_out.lShr(phase1, m_out.constInt64(17)), phase1);
2350
2351         // x ^= y ^ (y >> 26);
2352         LValue phase3 = m_out.bitXor(m_out.bitXor(high, m_out.lShr(high, m_out.constInt64(26))), phase2);
2353
2354         // m_high = x;
2355         m_out.store64(phase3, m_out.absolute(highAddress));
2356
2357         // return x + y;
2358         LValue random64 = m_out.add(phase3, high);
2359
2360         // Extract random 53bit. [0, 53] bit is safe integer number ranges in double representation.
2361         LValue random53 = m_out.bitAnd(random64, m_out.constInt64((1ULL << 53) - 1));
2362
2363         LValue double53Integer = m_out.intToDouble(random53);
2364
2365         // Convert `(53bit double integer value) / (1 << 53)` to `(53bit double integer value) * (1.0 / (1 << 53))`.
2366         // In latter case, `1.0 / (1 << 53)` will become a double value represented as (mantissa = 0 & exp = 970, it means 1e-(2**54)).
2367         static const double scale = 1.0 / (1ULL << 53);
2368
2369         // Multiplying 1e-(2**54) with the double integer does not change anything of the mantissa part of the double integer.
2370         // It just reduces the exp part of the given 53bit double integer.
2371         // (Except for 0.0. This is specially handled and in this case, exp just becomes 0.)
2372         // Now we get 53bit precision random double value in [0, 1).
2373         LValue result = m_out.doubleMul(double53Integer, m_out.constDouble(scale));
2374
2375         setDouble(result);
2376     }
2377
2378     void compileArithRound()
2379     {
2380         if (m_node->child1().useKind() == DoubleRepUse) {
2381             LValue result = nullptr;
2382             if (producesInteger(m_node->arithRoundingMode()) && !shouldCheckNegativeZero(m_node->arithRoundingMode())) {
2383                 LValue value = lowDouble(m_node->child1());
2384                 result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
2385             } else {
2386                 LBasicBlock realPartIsMoreThanHalf = m_out.newBlock();
2387                 LBasicBlock continuation = m_out.newBlock();
2388
2389                 LValue value = lowDouble(m_node->child1());
2390                 LValue integerValue = m_out.doubleCeil(value);
2391                 ValueFromBlock integerValueResult = m_out.anchor(integerValue);
2392
2393                 LValue realPart = m_out.doubleSub(integerValue, value);
2394
2395                 m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
2396
2397                 LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
2398                 LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
2399                 ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
2400                 m_out.jump(continuation);
2401                 m_out.appendTo(continuation, lastNext);
2402
2403                 result = m_out.phi(Double, integerValueResult, integerValueRoundedDownResult);
2404             }
2405
2406             if (producesInteger(m_node->arithRoundingMode())) {
2407                 LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
2408                 setInt32(integerValue);
2409             } else
2410                 setDouble(result);
2411             return;
2412         }
2413
2414         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2415         LValue argument = lowJSValue(m_node->child1());
2416         setJSValue(vmCall(Int64, m_out.operation(operationArithRound), m_callFrame, argument));
2417     }
2418
2419     void compileArithFloor()
2420     {
2421         if (m_node->child1().useKind() == DoubleRepUse) {
2422             LValue value = lowDouble(m_node->child1());
2423             LValue integerValue = m_out.doubleFloor(value);
2424             if (producesInteger(m_node->arithRoundingMode()))
2425                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2426             else
2427                 setDouble(integerValue);
2428             return;
2429         }
2430         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2431         LValue argument = lowJSValue(m_node->child1());
2432         setJSValue(vmCall(Int64, m_out.operation(operationArithFloor), m_callFrame, argument));
2433     }
2434
2435     void compileArithCeil()
2436     {
2437         if (m_node->child1().useKind() == DoubleRepUse) {
2438             LValue value = lowDouble(m_node->child1());
2439             LValue integerValue = m_out.doubleCeil(value);
2440             if (producesInteger(m_node->arithRoundingMode()))
2441                 setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2442             else
2443                 setDouble(integerValue);
2444             return;
2445         }
2446         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2447         LValue argument = lowJSValue(m_node->child1());
2448         setJSValue(vmCall(Int64, m_out.operation(operationArithCeil), m_callFrame, argument));
2449     }
2450
2451     void compileArithTrunc()
2452     {
2453         if (m_node->child1().useKind() == DoubleRepUse) {
2454             LValue value = lowDouble(m_node->child1());
2455             LValue result = m_out.doubleTrunc(value);
2456             if (producesInteger(m_node->arithRoundingMode()))
2457                 setInt32(convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode())));
2458             else
2459                 setDouble(result);
2460             return;
2461         }
2462         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2463         LValue argument = lowJSValue(m_node->child1());
2464         setJSValue(vmCall(Int64, m_out.operation(operationArithTrunc), m_callFrame, argument));
2465     }
2466
2467     void compileArithSqrt()
2468     {
2469         if (m_node->child1().useKind() == DoubleRepUse) {
2470             setDouble(m_out.doubleSqrt(lowDouble(m_node->child1())));
2471             return;
2472         }
2473         LValue argument = lowJSValue(m_node->child1());
2474         LValue result = vmCall(Double, m_out.operation(operationArithSqrt), m_callFrame, argument);
2475         setDouble(result);
2476     }
2477
2478     void compileArithLog()
2479     {
2480         if (m_node->child1().useKind() == DoubleRepUse) {
2481             setDouble(m_out.doubleLog(lowDouble(m_node->child1())));
2482             return;
2483         }
2484         LValue argument = lowJSValue(m_node->child1());
2485         LValue result = vmCall(Double, m_out.operation(operationArithLog), m_callFrame, argument);
2486         setDouble(result);
2487     }
2488     
2489     void compileArithFRound()
2490     {
2491         if (m_node->child1().useKind() == DoubleRepUse) {
2492             setDouble(m_out.fround(lowDouble(m_node->child1())));
2493             return;
2494         }
2495         LValue argument = lowJSValue(m_node->child1());
2496         LValue result = vmCall(Double, m_out.operation(operationArithFRound), m_callFrame, argument);
2497         setDouble(result);
2498     }
2499     
2500     void compileArithNegate()
2501     {
2502         switch (m_node->child1().useKind()) {
2503         case Int32Use: {
2504             LValue value = lowInt32(m_node->child1());
2505             
2506             LValue result;
2507             if (!shouldCheckOverflow(m_node->arithMode()))
2508                 result = m_out.neg(value);
2509             else if (!shouldCheckNegativeZero(m_node->arithMode())) {
2510                 CheckValue* check = m_out.speculateSub(m_out.int32Zero, value);
2511                 blessSpeculation(check, Overflow, noValue(), nullptr, m_origin);
2512                 result = check;
2513             } else {
2514                 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff)));
2515                 result = m_out.neg(value);
2516             }
2517
2518             setInt32(result);
2519             break;
2520         }
2521             
2522         case Int52RepUse: {
2523             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52Only)) {
2524                 Int52Kind kind;
2525                 LValue value = lowWhicheverInt52(m_node->child1(), kind);
2526                 LValue result = m_out.neg(value);
2527                 if (shouldCheckNegativeZero(m_node->arithMode()))
2528                     speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2529                 setInt52(result, kind);
2530                 break;
2531             }
2532             
2533             LValue value = lowInt52(m_node->child1());
2534             CheckValue* result = m_out.speculateSub(m_out.int64Zero, value);
2535             blessSpeculation(result, Int52Overflow, noValue(), nullptr, m_origin);
2536             speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2537             setInt52(result);
2538             break;
2539         }
2540             
2541         case DoubleRepUse: {
2542             setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
2543             break;
2544         }
2545             
2546         default:
2547             DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == UntypedUse);
2548             ArithProfile* arithProfile = m_ftlState.graph.baselineCodeBlockFor(m_node->origin.semantic)->arithProfileForBytecodeOffset(m_node->origin.semantic.bytecodeIndex);
2549             JITNegIC* negIC = codeBlock()->addJITNegIC(arithProfile);
2550             auto repatchingFunction = operationArithNegateOptimize;
2551             auto nonRepatchingFunction = operationArithNegate;
2552             compileMathIC(negIC, repatchingFunction, nonRepatchingFunction);
2553             break;
2554         }
2555     }
2556     
2557     void compileBitAnd()
2558     {
2559         if (m_node->isBinaryUseKind(UntypedUse)) {
2560             emitBinaryBitOpSnippet<JITBitAndGenerator>(operationValueBitAnd);
2561             return;
2562         }
2563         setInt32(m_out.bitAnd(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2564     }
2565     
2566     void compileBitOr()
2567     {
2568         if (m_node->isBinaryUseKind(UntypedUse)) {
2569             emitBinaryBitOpSnippet<JITBitOrGenerator>(operationValueBitOr);
2570             return;
2571         }
2572         setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2573     }
2574     
2575     void compileBitXor()
2576     {
2577         if (m_node->isBinaryUseKind(UntypedUse)) {
2578             emitBinaryBitOpSnippet<JITBitXorGenerator>(operationValueBitXor);
2579             return;
2580         }
2581         setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2582     }
2583     
2584     void compileBitRShift()
2585     {
2586         if (m_node->isBinaryUseKind(UntypedUse)) {
2587             emitRightShiftSnippet(JITRightShiftGenerator::SignedShift);
2588             return;
2589         }
2590         setInt32(m_out.aShr(
2591             lowInt32(m_node->child1()),
2592             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2593     }
2594     
2595     void compileBitLShift()
2596     {
2597         if (m_node->isBinaryUseKind(UntypedUse)) {
2598             emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift);
2599             return;
2600         }
2601         setInt32(m_out.shl(
2602             lowInt32(m_node->child1()),
2603             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2604     }
2605     
2606     void compileBitURShift()
2607     {
2608         if (m_node->isBinaryUseKind(UntypedUse)) {
2609             emitRightShiftSnippet(JITRightShiftGenerator::UnsignedShift);
2610             return;
2611         }
2612         setInt32(m_out.lShr(
2613             lowInt32(m_node->child1()),
2614             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2615     }
2616     
2617     void compileUInt32ToNumber()
2618     {
2619         LValue value = lowInt32(m_node->child1());
2620
2621         if (doesOverflow(m_node->arithMode())) {
2622             setStrictInt52(m_out.zeroExtPtr(value));
2623             return;
2624         }
2625
2626         speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
2627         setInt32(value);
2628     }
2629     
2630     void compileCheckStructure()
2631     {
2632         ExitKind exitKind;
2633         if (m_node->child1()->hasConstant())
2634             exitKind = BadConstantCache;
2635         else
2636             exitKind = BadCache;
2637
2638         switch (m_node->child1().useKind()) {
2639         case CellUse:
2640         case KnownCellUse: {
2641             LValue cell = lowCell(m_node->child1());
2642             
2643             checkStructure(
2644                 m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2645                 exitKind, m_node->structureSet(),
2646                 [&] (Structure* structure) {
2647                     return weakStructureID(structure);
2648                 });
2649             return;
2650         }
2651
2652         case CellOrOtherUse: {
2653             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
2654
2655             LBasicBlock cellCase = m_out.newBlock();
2656             LBasicBlock notCellCase = m_out.newBlock();
2657             LBasicBlock continuation = m_out.newBlock();
2658
2659             m_out.branch(
2660                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2661
2662             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2663             checkStructure(
2664                 m_out.load32(value, m_heaps.JSCell_structureID), jsValueValue(value),
2665                 exitKind, m_node->structureSet(),
2666                 [&] (Structure* structure) {
2667                     return weakStructureID(structure);
2668                 });
2669             m_out.jump(continuation);
2670
2671             m_out.appendTo(notCellCase, continuation);
2672             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecCell | SpecOther, isNotOther(value));
2673             m_out.jump(continuation);
2674
2675             m_out.appendTo(continuation, lastNext);
2676             return;
2677         }
2678
2679         default:
2680             DFG_CRASH(m_graph, m_node, "Bad use kind");
2681             return;
2682         }
2683     }
2684     
2685     void compileCheckCell()
2686     {
2687         LValue cell = lowCell(m_node->child1());
2688         
2689         speculate(
2690             BadCell, jsValueValue(cell), m_node->child1().node(),
2691             m_out.notEqual(cell, weakPointer(m_node->cellOperand()->cell())));
2692     }
2693     
2694     void compileCheckBadCell()
2695     {
2696         terminate(BadCell);
2697     }
2698
2699     void compileCheckNotEmpty()
2700     {
2701         speculate(TDZFailure, noValue(), nullptr, m_out.isZero64(lowJSValue(m_node->child1())));
2702     }
2703
2704     void compileCheckStringIdent()
2705     {
2706         UniquedStringImpl* uid = m_node->uidOperand();
2707         LValue stringImpl = lowStringIdent(m_node->child1());
2708         speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2709     }
2710
2711     void compileGetExecutable()
2712     {
2713         LValue cell = lowCell(m_node->child1());
2714         speculateFunction(m_node->child1(), cell);
2715         setJSValue(m_out.loadPtr(cell, m_heaps.JSFunction_executable));
2716     }
2717     
2718     void compileArrayifyToStructure()
2719     {
2720         LValue cell = lowCell(m_node->child1());
2721         LValue property = !!m_node->child2() ? lowInt32(m_node->child2()) : 0;
2722         
2723         LBasicBlock unexpectedStructure = m_out.newBlock();
2724         LBasicBlock continuation = m_out.newBlock();
2725         
2726         LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2727         
2728         m_out.branch(
2729             m_out.notEqual(structureID, weakStructureID(m_node->structure())),
2730             rarely(unexpectedStructure), usually(continuation));
2731         
2732         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
2733         
2734         if (property) {
2735             switch (m_node->arrayMode().type()) {
2736             case Array::Int32:
2737             case Array::Double:
2738             case Array::Contiguous:
2739                 speculate(
2740                     Uncountable, noValue(), 0,
2741                     m_out.aboveOrEqual(property, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)));
2742                 break;
2743             default:
2744                 break;
2745             }
2746         }
2747         
2748         switch (m_node->arrayMode().type()) {
2749         case Array::Int32:
2750             vmCall(Void, m_out.operation(operationEnsureInt32), m_callFrame, cell);
2751             break;
2752         case Array::Double:
2753             vmCall(Void, m_out.operation(operationEnsureDouble), m_callFrame, cell);
2754             break;
2755         case Array::Contiguous:
2756             vmCall(Void, m_out.operation(operationEnsureContiguous), m_callFrame, cell);
2757             break;
2758         case Array::ArrayStorage:
2759         case Array::SlowPutArrayStorage:
2760             vmCall(Void, m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
2761             break;
2762         default:
2763             DFG_CRASH(m_graph, m_node, "Bad array type");
2764             break;
2765         }
2766         
2767         structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2768         speculate(
2769             BadIndexingType, jsValueValue(cell), 0,
2770             m_out.notEqual(structureID, weakStructureID(m_node->structure())));
2771         m_out.jump(continuation);
2772         
2773         m_out.appendTo(continuation, lastNext);
2774     }
2775     
2776     void compilePutStructure()
2777     {
2778         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
2779
2780         Structure* oldStructure = m_node->transition()->previous;
2781         Structure* newStructure = m_node->transition()->next;
2782         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
2783         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
2784         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
2785
2786         LValue cell = lowCell(m_node->child1()); 
2787         m_out.store32(
2788             weakStructureID(newStructure),
2789             cell, m_heaps.JSCell_structureID);
2790     }
2791     
2792     void compileGetById(AccessType type)
2793     {
2794         ASSERT(type == AccessType::Get || type == AccessType::TryGet || type == AccessType::PureGet);
2795         switch (m_node->child1().useKind()) {
2796         case CellUse: {
2797             setJSValue(getById(lowCell(m_node->child1()), type));
2798             return;
2799         }
2800             
2801         case UntypedUse: {
2802             // This is pretty weird, since we duplicate the slow path both here and in the
2803             // code generated by the IC. We should investigate making this less bad.
2804             // https://bugs.webkit.org/show_bug.cgi?id=127830
2805             LValue value = lowJSValue(m_node->child1());
2806             
2807             LBasicBlock cellCase = m_out.newBlock();
2808             LBasicBlock notCellCase = m_out.newBlock();
2809             LBasicBlock continuation = m_out.newBlock();
2810             
2811             m_out.branch(
2812                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2813             
2814             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2815             ValueFromBlock cellResult = m_out.anchor(getById(value, type));
2816             m_out.jump(continuation);
2817
2818             J_JITOperation_EJI getByIdFunction;
2819             if (type == AccessType::Get)
2820                 getByIdFunction = operationGetByIdGeneric;
2821             else if (type == AccessType::PureGet)
2822                 getByIdFunction = operationPureGetByIdGeneric;
2823             else
2824                 getByIdFunction = operationTryGetByIdGeneric;
2825
2826             m_out.appendTo(notCellCase, continuation);
2827             ValueFromBlock notCellResult = m_out.anchor(vmCall(
2828                 Int64, m_out.operation(getByIdFunction),
2829                 m_callFrame, value,
2830                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
2831             m_out.jump(continuation);
2832             
2833             m_out.appendTo(continuation, lastNext);
2834             setJSValue(m_out.phi(Int64, cellResult, notCellResult));
2835             return;
2836         }
2837             
2838         default:
2839             DFG_CRASH(m_graph, m_node, "Bad use kind");
2840             return;
2841         }
2842     }
2843
2844     void compileGetByIdWithThis()
2845     {
2846         LValue base = lowJSValue(m_node->child1());
2847         LValue thisValue = lowJSValue(m_node->child2());
2848         LValue result = vmCall(Int64, m_out.operation(operationGetByIdWithThis), m_callFrame, base, thisValue, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()]));
2849         setJSValue(result);
2850     }
2851
2852     void compileGetByValWithThis()
2853     {
2854         LValue base = lowJSValue(m_node->child1());
2855         LValue thisValue = lowJSValue(m_node->child2());
2856         LValue subscript = lowJSValue(m_node->child3());
2857
2858         LValue result = vmCall(Int64, m_out.operation(operationGetByValWithThis), m_callFrame, base, thisValue, subscript);
2859         setJSValue(result);
2860     }
2861
2862     void compilePutByIdWithThis()
2863     {
2864         LValue base = lowJSValue(m_node->child1());
2865         LValue thisValue = lowJSValue(m_node->child2());
2866         LValue value = lowJSValue(m_node->child3());
2867
2868         vmCall(Void, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByIdWithThisStrict : operationPutByIdWithThis),
2869             m_callFrame, base, thisValue, value, m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()]));
2870     }
2871
2872     void compilePutByValWithThis()
2873     {
2874         LValue base = lowJSValue(m_graph.varArgChild(m_node, 0));
2875         LValue thisValue = lowJSValue(m_graph.varArgChild(m_node, 1));
2876         LValue property = lowJSValue(m_graph.varArgChild(m_node, 2));
2877         LValue value = lowJSValue(m_graph.varArgChild(m_node, 3));
2878
2879         vmCall(Void, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByValWithThisStrict : operationPutByValWithThis),
2880             m_callFrame, base, thisValue, property, value);
2881     }
2882
2883     void compileDefineDataProperty()
2884     {
2885         LValue base = lowCell(m_graph.varArgChild(m_node, 0));
2886         LValue value  = lowJSValue(m_graph.varArgChild(m_node, 2));
2887         LValue attributes = lowInt32(m_graph.varArgChild(m_node, 3));
2888         Edge& propertyEdge = m_graph.varArgChild(m_node, 1);
2889         switch (propertyEdge.useKind()) {
2890         case StringUse: {
2891             LValue property = lowString(propertyEdge);
2892             vmCall(Void, m_out.operation(operationDefineDataPropertyString), m_callFrame, base, property, value, attributes);
2893             break;
2894         }
2895         case StringIdentUse: {
2896             LValue property = lowStringIdent(propertyEdge);
2897             vmCall(Void, m_out.operation(operationDefineDataPropertyStringIdent), m_callFrame, base, property, value, attributes);
2898             break;
2899         }
2900         case SymbolUse: {
2901             LValue property = lowSymbol(propertyEdge);
2902             vmCall(Void, m_out.operation(operationDefineDataPropertySymbol), m_callFrame, base, property, value, attributes);
2903             break;
2904         }
2905         case UntypedUse: {
2906             LValue property = lowJSValue(propertyEdge);
2907             vmCall(Void, m_out.operation(operationDefineDataProperty), m_callFrame, base, property, value, attributes);
2908             break;
2909         }
2910         default:
2911             RELEASE_ASSERT_NOT_REACHED();
2912         }
2913     }
2914
2915     void compileDefineAccessorProperty()
2916     {
2917         LValue base = lowCell(m_graph.varArgChild(m_node, 0));
2918         LValue getter = lowCell(m_graph.varArgChild(m_node, 2));
2919         LValue setter = lowCell(m_graph.varArgChild(m_node, 3));
2920         LValue attributes = lowInt32(m_graph.varArgChild(m_node, 4));
2921         Edge& propertyEdge = m_graph.varArgChild(m_node, 1);
2922         switch (propertyEdge.useKind()) {
2923         case StringUse: {
2924             LValue property = lowString(propertyEdge);
2925             vmCall(Void, m_out.operation(operationDefineAccessorPropertyString), m_callFrame, base, property, getter, setter, attributes);
2926             break;
2927         }
2928         case StringIdentUse: {
2929             LValue property = lowStringIdent(propertyEdge);
2930             vmCall(Void, m_out.operation(operationDefineAccessorPropertyStringIdent), m_callFrame, base, property, getter, setter, attributes);
2931             break;
2932         }
2933         case SymbolUse: {
2934             LValue property = lowSymbol(propertyEdge);
2935             vmCall(Void, m_out.operation(operationDefineAccessorPropertySymbol), m_callFrame, base, property, getter, setter, attributes);
2936             break;
2937         }
2938         case UntypedUse: {
2939             LValue property = lowJSValue(propertyEdge);
2940             vmCall(Void, m_out.operation(operationDefineAccessorProperty), m_callFrame, base, property, getter, setter, attributes);
2941             break;
2942         }
2943         default:
2944             RELEASE_ASSERT_NOT_REACHED();
2945         }
2946     }
2947     
2948     void compilePutById()
2949     {
2950         DFG_ASSERT(m_graph, m_node, m_node->child1().useKind() == CellUse);
2951
2952         Node* node = m_node;
2953         LValue base = lowCell(node->child1());
2954         LValue value = lowJSValue(node->child2());
2955         auto uid = m_graph.identifiers()[node->identifierNumber()];
2956
2957         B3::PatchpointValue* patchpoint = m_out.patchpoint(Void);
2958         patchpoint->appendSomeRegister(base);
2959         patchpoint->appendSomeRegister(value);
2960         patchpoint->append(m_tagMask, ValueRep::reg(GPRInfo::tagMaskRegister));
2961         patchpoint->append(m_tagTypeNumber, ValueRep::reg(GPRInfo::tagTypeNumberRegister));
2962         patchpoint->clobber(RegisterSet::macroScratchRegisters());
2963
2964         // FIXME: If this is a PutByIdFlush, we might want to late-clobber volatile registers.
2965         // https://bugs.webkit.org/show_bug.cgi?id=152848
2966
2967         RefPtr<PatchpointExceptionHandle> exceptionHandle =
2968             preparePatchpointForExceptions(patchpoint);
2969
2970         State* state = &m_ftlState;
2971         ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->ecmaMode();
2972         
2973         patchpoint->setGenerator(
2974             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2975                 AllowMacroScratchRegisterUsage allowScratch(jit);
2976
2977                 CallSiteIndex callSiteIndex =
2978                     state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
2979
2980                 Box<CCallHelpers::JumpList> exceptions =
2981                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
2982
2983                 // JS setter call ICs generated by the PutById IC will need this.
2984                 exceptionHandle->scheduleExitCreationForUnwind(params, callSiteIndex);
2985
2986                 auto generator = Box<JITPutByIdGenerator>::create(
2987                     jit.codeBlock(), node->origin.semantic, callSiteIndex,
2988                     params.unavailableRegisters(), JSValueRegs(params[0].gpr()),
2989                     JSValueRegs(params[1].gpr()), GPRInfo::patchpointScratchRegister, ecmaMode,
2990                     node->op() == PutByIdDirect ? Direct : NotDirect);
2991
2992                 generator->generateFastPath(jit);
2993                 CCallHelpers::Label done = jit.label();
2994
2995                 params.addLatePath(
2996                     [=] (CCallHelpers& jit) {
2997                         AllowMacroScratchRegisterUsage allowScratch(jit);
2998
2999                         generator->slowPathJump().link(&jit);
3000                         CCallHelpers::Label slowPathBegin = jit.label();
3001                         CCallHelpers::Call slowPathCall = callOperation(
3002                             *state, params.unavailableRegisters(), jit, node->origin.semantic,
3003                             exceptions.get(), generator->slowPathFunction(), InvalidGPRReg,
3004                             CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(),
3005                             params[0].gpr(), CCallHelpers::TrustedImmPtr(uid)).call();
3006                         jit.jump().linkTo(done, &jit);
3007
3008                         generator->reportSlowPathCall(slowPathBegin, slowPathCall);
3009
3010                         jit.addLinkTask(
3011                             [=] (LinkBuffer& linkBuffer) {
3012                                 generator->finalize(linkBuffer);
3013                             });
3014                     });
3015             });
3016     }
3017     
3018     void compileGetButterfly()
3019     {
3020         setStorage(m_out.loadPtr(lowCell(m_node->child1()), m_heaps.JSObject_butterfly));
3021     }
3022
3023     void compileConstantStoragePointer()
3024     {
3025         setStorage(m_out.constIntPtr(m_node->storagePointer()));
3026     }
3027     
3028     void compileGetIndexedPropertyStorage()
3029     {
3030         LValue cell = lowCell(m_node->child1());
3031         
3032         if (m_node->arrayMode().type() == Array::String) {
3033             LBasicBlock slowPath = m_out.newBlock();
3034             LBasicBlock continuation = m_out.newBlock();
3035
3036             LValue fastResultValue = m_out.loadPtr(cell, m_heaps.JSString_value);
3037             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
3038             
3039             m_out.branch(
3040                 m_out.notNull(fastResultValue), usually(continuation), rarely(slowPath));
3041             
3042             LBasicBlock lastNext = m_out.appendTo(slowPath, continuation);
3043             
3044             ValueFromBlock slowResult = m_out.anchor(
3045                 vmCall(pointerType(), m_out.operation(operationResolveRope), m_callFrame, cell));
3046             
3047             m_out.jump(continuation);
3048             
3049             m_out.appendTo(continuation, lastNext);
3050             
3051             setStorage(m_out.loadPtr(m_out.phi(pointerType(), fastResult, slowResult), m_heaps.StringImpl_data));
3052             return;
3053         }
3054
3055         DFG_ASSERT(m_graph, m_node, isTypedView(m_node->arrayMode().typedArrayType()));
3056         setStorage(m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector));
3057     }
3058     
3059     void compileCheckArray()
3060     {
3061         Edge edge = m_node->child1();
3062         LValue cell = lowCell(edge);
3063         
3064         if (m_node->arrayMode().alreadyChecked(m_graph, m_node, abstractValue(edge)))
3065             return;
3066         
3067         speculate(
3068             BadIndexingType, jsValueValue(cell), 0,
3069             m_out.logicalNot(isArrayType(cell, m_node->arrayMode())));
3070     }
3071
3072     void compileGetTypedArrayByteOffset()
3073     {
3074         LValue basePtr = lowCell(m_node->child1());    
3075
3076         LBasicBlock simpleCase = m_out.newBlock();
3077         LBasicBlock wastefulCase = m_out.newBlock();
3078         LBasicBlock continuation = m_out.newBlock();
3079         
3080         LValue mode = m_out.load32(basePtr, m_heaps.JSArrayBufferView_mode);
3081         m_out.branch(
3082             m_out.notEqual(mode, m_out.constInt32(WastefulTypedArray)),
3083             unsure(simpleCase), unsure(wastefulCase));
3084
3085         LBasicBlock lastNext = m_out.appendTo(simpleCase, wastefulCase);
3086
3087         ValueFromBlock simpleOut = m_out.anchor(m_out.constIntPtr(0));
3088
3089         m_out.jump(continuation);
3090
3091         m_out.appendTo(wastefulCase, continuation);
3092
3093         LValue vectorPtr = m_out.loadPtr(basePtr, m_heaps.JSArrayBufferView_vector);
3094         LValue butterflyPtr = m_out.loadPtr(basePtr, m_heaps.JSObject_butterfly);
3095         LValue arrayBufferPtr = m_out.loadPtr(butterflyPtr, m_heaps.Butterfly_arrayBuffer);
3096         LValue dataPtr = m_out.loadPtr(arrayBufferPtr, m_heaps.ArrayBuffer_data);
3097
3098         ValueFromBlock wastefulOut = m_out.anchor(m_out.sub(vectorPtr, dataPtr));
3099
3100         m_out.jump(continuation);
3101         m_out.appendTo(continuation, lastNext);
3102
3103         setInt32(m_out.castToInt32(m_out.phi(pointerType(), simpleOut, wastefulOut)));
3104     }
3105     
3106     void compileGetArrayLength()
3107     {
3108         switch (m_node->arrayMode().type()) {
3109         case Array::Undecided:
3110         case Array::Int32:
3111         case Array::Double:
3112         case Array::Contiguous: {
3113             setInt32(m_out.load32NonNegative(lowStorage(m_node->child2()), m_heaps.Butterfly_publicLength));
3114             return;
3115         }
3116             
3117         case Array::String: {
3118             LValue string = lowCell(m_node->child1());
3119             setInt32(m_out.load32NonNegative(string, m_heaps.JSString_length));
3120             return;
3121         }
3122             
3123         case Array::DirectArguments: {
3124             LValue arguments = lowCell(m_node->child1());
3125             speculate(
3126                 ExoticObjectMode, noValue(), nullptr,
3127                 m_out.notNull(m_out.loadPtr(arguments, m_heaps.DirectArguments_overrides)));
3128             setInt32(m_out.load32NonNegative(arguments, m_heaps.DirectArguments_length));
3129             return;
3130         }
3131             
3132         case Array::ScopedArguments: {
3133             LValue arguments = lowCell(m_node->child1());
3134             speculate(
3135                 ExoticObjectMode, noValue(), nullptr,
3136                 m_out.notZero32(m_out.load8ZeroExt32(arguments, m_heaps.ScopedArguments_overrodeThings)));
3137             setInt32(m_out.load32NonNegative(arguments, m_heaps.ScopedArguments_totalLength));
3138             return;
3139         }
3140             
3141         default:
3142             if (m_node->arrayMode().isSomeTypedArrayView()) {
3143                 setInt32(
3144                     m_out.load32NonNegative(lowCell(m_node->child1()), m_heaps.JSArrayBufferView_length));
3145                 return;
3146             }
3147             
3148             DFG_CRASH(m_graph, m_node, "Bad array type");
3149             return;
3150         }
3151     }
3152     
3153     void compileCheckInBounds()
3154     {
3155         speculate(
3156             OutOfBounds, noValue(), 0,
3157             m_out.aboveOrEqual(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
3158     }
3159     
3160     void compileGetByVal()
3161     {
3162         switch (m_node->arrayMode().type()) {
3163         case Array::Int32:
3164         case Array::Contiguous: {
3165             LValue index = lowInt32(m_node->child2());
3166             LValue storage = lowStorage(m_node->child3());
3167             
3168             IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ?
3169                 m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
3170             
3171             if (m_node->arrayMode().isInBounds()) {
3172                 LValue result = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
3173                 LValue isHole = m_out.isZero64(result);
3174                 if (m_node->arrayMode().isSaneChain()) {
3175                     DFG_ASSERT(
3176                         m_graph, m_node, m_node->arrayMode().type() == Array::Contiguous);
3177                     result = m_out.select(
3178                         isHole, m_out.constInt64(JSValue::encode(jsUndefined())), result);
3179                 } else
3180                     speculate(LoadFromHole, noValue(), 0, isHole);
3181                 setJSValue(result);
3182                 return;
3183             }
3184             
3185             LValue base = lowCell(m_node->child1());
3186             
3187             LBasicBlock fastCase = m_out.newBlock();
3188             LBasicBlock slowCase = m_out.newBlock();
3189             LBasicBlock continuation = m_out.newBlock();
3190             
3191             m_out.branch(
3192                 m_out.aboveOrEqual(
3193                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
3194                 rarely(slowCase), usually(fastCase));
3195             
3196             LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
3197
3198             LValue fastResultValue = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
3199             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
3200             m_out.branch(
3201                 m_out.isZero64(fastResultValue), rarely(slowCase), usually(continuation));
3202             
3203             m_out.appendTo(slowCase, continuation);
3204             ValueFromBlock slowResult = m_out.anchor(
3205                 vmCall(Int64, m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
3206             m_out.jump(continuation);
3207             
3208             m_out.appendTo(continuation, lastNext);
3209             setJSValue(m_out.phi(Int64, fastResult, slowResult));
3210             return;
3211         }
3212             
3213         case Array::Double: {
3214             LValue index = lowInt32(m_node->child2());
3215             LValue storage = lowStorage(m_node->child3());
3216             
3217             IndexedAbstractHeap& heap = m_heaps.indexedDoubleProperties;
3218             
3219             if (m_node->arrayMode().isInBounds()) {
3220                 LValue result = m_out.loadDouble(
3221                     baseIndex(heap, storage, index, m_node->child2()));
3222                 
3223                 if (!m_node->arrayMode().isSaneChain()) {
3224                     speculate(
3225                         LoadFromHole, noValue(), 0,
3226                         m_out.doubleNotEqualOrUnordered(result, result));
3227                 }
3228                 setDouble(result);
3229                 break;
3230             }
3231             
3232             LValue base = lowCell(m_node->child1());
3233             
3234             LBasicBlock inBounds = m_out.newBlock();
3235             LBasicBlock boxPath = m_out.newBlock();
3236             LBasicBlock slowCase = m_out.newBlock();
3237             LBasicBlock continuation = m_out.newBlock();
3238             
3239             m_out.branch(
3240                 m_out.aboveOrEqual(
3241                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
3242                 rarely(slowCase), usually(inBounds));
3243             
3244             LBasicBlock lastNext = m_out.appendTo(inBounds, boxPath);
3245             LValue doubleValue = m_out.loadDouble(
3246                 baseIndex(heap, storage, index, m_node->child2()));
3247             m_out.branch(
3248                 m_out.doubleNotEqualOrUnordered(doubleValue, doubleValue),
3249                 rarely(slowCase), usually(boxPath));
3250             
3251             m_out.appendTo(boxPath, slowCase);
3252             ValueFromBlock fastResult = m_out.anchor(boxDouble(doubleValue));
3253             m_out.jump(continuation);
3254             
3255             m_out.appendTo(slowCase, continuation);
3256             ValueFromBlock slowResult = m_out.anchor(
3257                 vmCall(Int64, m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
3258             m_out.jump(continuation);
3259             
3260             m_out.appendTo(continuation, lastNext);
3261             setJSValue(m_out.phi(Int64, fastResult, slowResult));
3262             return;
3263         }
3264
3265         case Array::Undecided: {
3266             LValue index = lowInt32(m_node->child2());
3267
3268             speculate(OutOfBounds, noValue(), m_node, m_out.lessThan(index, m_out.int32Zero));
3269             setJSValue(m_out.constInt64(ValueUndefined));
3270             return;
3271         }
3272             
3273         case Array::DirectArguments: {
3274             LValue base = lowCell(m_node->child1());
3275             LValue index = lowInt32(m_node->child2());
3276             
3277             speculate(
3278                 ExoticObjectMode, noValue(), nullptr,
3279                 m_out.notNull(m_out.loadPtr(base, m_heaps.DirectArguments_overrides)));
3280             speculate(
3281                 ExoticObjectMode, noValue(), nullptr,
3282                 m_out.aboveOrEqual(
3283                     index,
3284                     m_out.load32NonNegative(base, m_heaps.DirectArguments_length)));
3285
3286             TypedPointer address = m_out.baseIndex(
3287                 m_heaps.DirectArguments_storage, base, m_out.zeroExtPtr(index));
3288             setJSValue(m_out.load64(address));
3289             return;
3290         }
3291             
3292         case Array::ScopedArguments: {
3293             LValue base = lowCell(m_node->child1());
3294             LValue index = lowInt32(m_node->child2());
3295             
3296             speculate(
3297                 ExoticObjectMode, noValue(), nullptr,
3298                 m_out.aboveOrEqual(
3299                     index,
3300                     m_out.load32NonNegative(base, m_heaps.ScopedArguments_totalLength)));
3301             
3302             LValue table = m_out.loadPtr(base, m_heaps.ScopedArguments_table);
3303             LValue namedLength = m_out.load32(table, m_heaps.ScopedArgumentsTable_length);
3304             
3305             LBasicBlock namedCase = m_out.newBlock();
3306             LBasicBlock overflowCase = m_out.newBlock();
3307             LBasicBlock continuation = m_out.newBlock();
3308             
3309             m_out.branch(
3310                 m_out.aboveOrEqual(index, namedLength), unsure(overflowCase), unsure(namedCase));
3311             
3312             LBasicBlock lastNext = m_out.appendTo(namedCase, overflowCase);
3313             
3314             LValue scope = m_out.loadPtr(base, m_heaps.ScopedArguments_scope);
3315             LValue arguments = m_out.loadPtr(table, m_heaps.ScopedArgumentsTable_arguments);
3316             
3317             TypedPointer address = m_out.baseIndex(
3318                 m_heaps.scopedArgumentsTableArguments, arguments, m_out.zeroExtPtr(index));
3319             LValue scopeOffset = m_out.load32(address);
3320             
3321             speculate(
3322                 ExoticObjectMode, noValue(), nullptr,
3323                 m_out.equal(scopeOffset, m_out.constInt32(ScopeOffset::invalidOffset)));
3324             
3325             address = m_out.baseIndex(
3326                 m_heaps.JSEnvironmentRecord_variables, scope, m_out.zeroExtPtr(scopeOffset));
3327             ValueFromBlock namedResult = m_out.anchor(m_out.load64(address));
3328             m_out.jump(continuation);
3329             
3330             m_out.appendTo(overflowCase, continuation);
3331             
3332             address = m_out.baseIndex(
3333                 m_heaps.ScopedArguments_overflowStorage, base,
3334                 m_out.zeroExtPtr(m_out.sub(index, namedLength)));
3335             LValue overflowValue = m_out.load64(address);
3336             speculate(ExoticObjectMode, noValue(), nullptr, m_out.isZero64(overflowValue));
3337             ValueFromBlock overflowResult = m_out.anchor(overflowValue);
3338             m_out.jump(continuation);
3339             
3340             m_out.appendTo(continuation, lastNext);
3341             setJSValue(m_out.phi(Int64, namedResult, overflowResult));
3342             return;
3343         }
3344             
3345         case Array::Generic: {
3346             setJSValue(vmCall(
3347                 Int64, m_out.operation(operationGetByVal), m_callFrame,
3348                 lowJSValue(m_node->child1()), lowJSValue(m_node->child2())));
3349             return;
3350         }
3351             
3352         case Array::String: {
3353             compileStringCharAt();
3354             return;
3355         }
3356             
3357         default: {
3358             LValue index = lowInt32(m_node->child2());
3359             LValue storage = lowStorage(m_node->child3());
3360             
3361             TypedArrayType type = m_node->arrayMode().typedArrayType();
3362             
3363             if (isTypedView(type)) {
3364                 TypedPointer pointer = TypedPointer(
3365                     m_heaps.typedArrayProperties,
3366                     m_out.add(
3367                         storage,
3368                         m_out.shl(
3369                             m_out.zeroExtPtr(index),
3370                             m_out.constIntPtr(logElementSize(type)))));
3371                 
3372                 if (isInt(type)) {
3373                     LValue result;
3374                     switch (elementSize(type)) {
3375                     case 1:
3376                         result = isSigned(type) ? m_out.load8SignExt32(pointer) :  m_out.load8ZeroExt32(pointer);
3377                         break;
3378                     case 2:
3379                         result = isSigned(type) ? m_out.load16SignExt32(pointer) :  m_out.load16ZeroExt32(pointer);
3380                         break;
3381                     case 4:
3382                         result = m_out.load32(pointer);
3383                         break;
3384                     default:
3385                         DFG_CRASH(m_graph, m_node, "Bad element size");
3386                     }
3387                     
3388                     if (elementSize(type) < 4 || isSigned(type)) {
3389                         setInt32(result);
3390                         return;
3391                     }
3392
3393                     if (m_node->shouldSpeculateInt32()) {
3394                         speculate(
3395                             Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
3396                         setInt32(result);
3397                         return;
3398                     }
3399                     
3400                     if (m_node->shouldSpeculateAnyInt()) {
3401                         setStrictInt52(m_out.zeroExt(result, Int64));
3402                         return;
3403                     }
3404                     
3405                     setDouble(m_out.unsignedToDouble(result));
3406                     return;
3407                 }
3408             
3409                 ASSERT(isFloat(type));
3410                 
3411                 LValue result;
3412                 switch (type) {
3413                 case TypeFloat32:
3414                     result = m_out.floatToDouble(m_out.loadFloat(pointer));
3415                     break;
3416                 case TypeFloat64:
3417                     result = m_out.loadDouble(pointer);
3418                     break;
3419                 default:
3420                     DFG_CRASH(m_graph, m_node, "Bad typed array type");
3421                 }
3422                 
3423                 setDouble(result);
3424                 return;
3425             }
3426             
3427             DFG_CRASH(m_graph, m_node, "Bad array type");
3428             return;
3429         } }
3430     }
3431     
3432     void compileGetMyArgumentByVal()
3433     {
3434         InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
3435         
3436         LValue index = lowInt32(m_node->child2());
3437         
3438         LValue limit;
3439         if (inlineCallFrame && !inlineCallFrame->isVarargs())
3440             limit = m_out.constInt32(inlineCallFrame->arguments.size() - 1);
3441         else {
3442             VirtualRegister argumentCountRegister;
3443             if (!inlineCallFrame)
3444                 argumentCountRegister = VirtualRegister(CallFrameSlot::argumentCount);
3445             else
3446                 argumentCountRegister = inlineCallFrame->argumentCountRegister;
3447             limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
3448         }
3449         
3450         LValue isOutOfBounds = m_out.aboveOrEqual(index, limit);
3451         LBasicBlock continuation = nullptr;
3452         LBasicBlock lastNext = nullptr;
3453         ValueFromBlock slowResult;
3454         if (m_node->op() == GetMyArgumentByValOutOfBounds) {
3455             LBasicBlock normalCase = m_out.newBlock();
3456             continuation = m_out.newBlock();
3457             
3458             slowResult = m_out.anchor(m_out.constInt64(JSValue::encode(jsUndefined())));
3459             m_out.branch(isOutOfBounds, unsure(continuation), unsure(normalCase));
3460             
3461             lastNext = m_out.appendTo(normalCase, continuation);
3462         } else
3463             speculate(ExoticObjectMode, noValue(), 0, isOutOfBounds);
3464         
3465         TypedPointer base;
3466         if (inlineCallFrame) {
3467             if (inlineCallFrame->arguments.size() > 1)
3468                 base = addressFor(inlineCallFrame->arguments[1].virtualRegister());
3469         } else
3470             base = addressFor(virtualRegisterForArgument(1));
3471         
3472         LValue result;
3473         if (base) {
3474             LValue pointer = m_out.baseIndex(
3475                 base.value(), m_out.zeroExt(index, pointerType()), ScaleEight);
3476             result = m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer));
3477         } else
3478             result = m_out.constInt64(JSValue::encode(jsUndefined()));
3479         
3480         if (m_node->op() == GetMyArgumentByValOutOfBounds) {
3481             ValueFromBlock normalResult = m_out.anchor(result);
3482             m_out.jump(continuation);
3483             
3484             m_out.appendTo(continuation, lastNext);
3485             result = m_out.phi(Int64, slowResult, normalResult);
3486         }
3487         
3488         setJSValue(result);
3489     }
3490     
3491     void compilePutByVal()
3492     {
3493         Edge child1 = m_graph.varArgChild(m_node, 0);
3494         Edge child2 = m_graph.varArgChild(m_node, 1);
3495         Edge child3 = m_graph.varArgChild(m_node, 2);
3496         Edge child4 = m_graph.varArgChild(m_node, 3);
3497         Edge child5 = m_graph.varArgChild(m_node, 4);
3498         
3499         switch (m_node->arrayMode().type()) {
3500         case Array::Generic: {
3501             V_JITOperation_EJJJ operation;
3502             if (m_node->op() == PutByValDirect) {
3503                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
3504                     operation = operationPutByValDirectStrict;
3505                 else
3506                     operation = operationPutByValDirectNonStrict;
3507             } else {
3508                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
3509                     operation = operationPutByValStrict;
3510                 else
3511                     operation = operationPutByValNonStrict;
3512             }
3513                 
3514             vmCall(
3515                 Void, m_out.operation(operation), m_callFrame,
3516                 lowJSValue(child1), lowJSValue(child2), lowJSValue(child3));
3517             return;
3518         }
3519             
3520         default:
3521             break;
3522         }
3523
3524         LValue base = lowCell(child1);
3525         LValue index = lowInt32(child2);
3526         LValue storage = lowStorage(child4);
3527         
3528         switch (m_node->arrayMode().type()) {
3529         case Array::Int32:
3530         case Array::Double:
3531         case Array::Contiguous: {
3532             LBasicBlock continuation = m_out.newBlock();
3533             LBasicBlock outerLastNext = m_out.appendTo(m_out.m_block, continuation);
3534             
3535             switch (m_node->arrayMode().type()) {
3536             case Array::Int32:
3537             case Array::Contiguous: {
3538                 LValue value = lowJSValue(child3, ManualOperandSpeculation);
3539                 
3540                 if (m_node->arrayMode().type() == Array::Int32)
3541                     FTL_TYPE_CHECK(jsValueValue(value), child3, SpecInt32Only, isNotInt32(value));
3542                 
3543                 TypedPointer elementPointer = m_out.baseIndex(
3544                     m_node->arrayMode().type() == Array::Int32 ?
3545                     m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
3546                     storage, m_out.zeroExtPtr(index), provenValue(child2));
3547                 
3548                 if (m_node->op() == PutByValAlias) {
3549                     m_out.store64(value, elementPointer);
3550                     break;
3551                 }
3552                 
3553                 contiguousPutByValOutOfBounds(
3554                     codeBlock()->isStrictMode()
3555                     ? operationPutByValBeyondArrayBoundsStrict
3556                     : operationPutByValBeyondArrayBoundsNonStrict,
3557                     base, storage, index, value, continuation);
3558                 
3559                 m_out.store64(value, elementPointer);
3560                 break;
3561             }
3562                 
3563             case Array::Double: {
3564                 LValue value = lowDouble(child3);
3565                 
3566                 FTL_TYPE_CHECK(
3567                     doubleValue(value), child3, SpecDoubleReal,
3568                     m_out.doubleNotEqualOrUnordered(value, value));
3569                 
3570                 TypedPointer elementPointer = m_out.baseIndex(
3571                     m_heaps.indexedDoubleProperties, storage, m_out.zeroExtPtr(index),
3572                     provenValue(child2));
3573                 
3574                 if (m_node->op() == PutByValAlias) {
3575                     m_out.storeDouble(value, elementPointer);
3576                     break;
3577                 }
3578                 
3579                 contiguousPutByValOutOfBounds(
3580                     codeBlock()->isStrictMode()
3581                     ? operationPutDoubleByValBeyondArrayBoundsStrict
3582                     : operationPutDoubleByValBeyondArrayBoundsNonStrict,
3583                     base, storage, index, value, continuation);
3584                 
3585                 m_out.storeDouble(value, elementPointer);
3586                 break;
3587             }