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