2 * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef DFGSpeculativeJIT_h
27 #define DFGSpeculativeJIT_h
31 #include "DFGAbstractInterpreter.h"
32 #include "DFGGenerationInfo.h"
33 #include "DFGInPlaceAbstractState.h"
34 #include "DFGJITCompiler.h"
35 #include "DFGOSRExit.h"
36 #include "DFGOSRExitJumpPlaceholder.h"
37 #include "DFGSilentRegisterSavePlan.h"
38 #include "DFGValueSource.h"
39 #include "JITOperations.h"
40 #include "MarkedAllocator.h"
42 #include "ValueRecovery.h"
43 #include "VirtualRegister.h"
45 namespace JSC { namespace DFG {
49 class SlowPathGenerator;
51 class SpeculateInt32Operand;
52 class SpeculateStrictInt32Operand;
53 class SpeculateDoubleOperand;
54 class SpeculateCellOperand;
55 class SpeculateBooleanOperand;
57 enum GeneratedOperandType { GeneratedOperandTypeUnknown, GeneratedOperandInteger, GeneratedOperandJSValue};
59 inline GPRReg extractResult(GPRReg result) { return result; }
61 inline GPRReg extractResult(JSValueRegs result) { return result.gpr(); }
63 inline JSValueRegs extractResult(JSValueRegs result) { return result; }
65 inline NoResultTag extractResult(NoResultTag) { return NoResult; }
67 // === SpeculativeJIT ===
69 // The SpeculativeJIT is used to generate a fast, but potentially
70 // incomplete code path for the dataflow. When code generating
71 // we may make assumptions about operand types, dynamically check,
72 // and bail-out to an alternate code path if these checks fail.
73 // Importantly, the speculative code path cannot be reentered once
74 // a speculative check has failed. This allows the SpeculativeJIT
75 // to propagate type information (including information that has
76 // only speculatively been asserted) through the dataflow.
77 class SpeculativeJIT {
78 WTF_MAKE_FAST_ALLOCATED;
80 friend struct OSRExit;
82 typedef JITCompiler::TrustedImm32 TrustedImm32;
83 typedef JITCompiler::Imm32 Imm32;
84 typedef JITCompiler::TrustedImmPtr TrustedImmPtr;
85 typedef JITCompiler::ImmPtr ImmPtr;
86 typedef JITCompiler::TrustedImm64 TrustedImm64;
87 typedef JITCompiler::Imm64 Imm64;
89 // These constants are used to set priorities for spill order for
90 // the register allocator.
93 SpillOrderConstant = 1, // no spill, and cheap fill
94 SpillOrderSpilled = 2, // no spill
95 SpillOrderJS = 4, // needs spill
96 SpillOrderCell = 4, // needs spill
97 SpillOrderStorage = 4, // needs spill
98 SpillOrderInteger = 5, // needs spill and box
99 SpillOrderBoolean = 5, // needs spill and box
100 SpillOrderDouble = 6, // needs spill and convert
102 #elif USE(JSVALUE32_64)
104 SpillOrderConstant = 1, // no spill, and cheap fill
105 SpillOrderSpilled = 2, // no spill
106 SpillOrderJS = 4, // needs spill
107 SpillOrderStorage = 4, // needs spill
108 SpillOrderDouble = 4, // needs spill
109 SpillOrderInteger = 5, // needs spill and box
110 SpillOrderCell = 5, // needs spill and box
111 SpillOrderBoolean = 5, // needs spill and box
115 enum UseChildrenMode { CallUseChildren, UseChildrenCalledExplicitly };
118 SpeculativeJIT(JITCompiler&);
123 void createOSREntries();
124 void linkOSREntries(LinkBuffer&);
126 BasicBlock* nextBlock()
128 for (BlockIndex resultIndex = m_block->index + 1; ; resultIndex++) {
129 if (resultIndex >= m_jit.graph().numBlocks())
131 if (BasicBlock* result = m_jit.graph().block(resultIndex))
137 GPRReg fillJSValue(Edge);
138 #elif USE(JSVALUE32_64)
139 bool fillJSValue(Edge, GPRReg&, GPRReg&, FPRReg&);
141 GPRReg fillStorage(Edge);
143 // lock and unlock GPR & FPR registers.
144 void lock(GPRReg reg)
148 void lock(FPRReg reg)
152 void unlock(GPRReg reg)
156 void unlock(FPRReg reg)
161 // Used to check whether a child node is on its last use,
162 // and its machine registers may be reused.
163 bool canReuse(Node* node)
165 return generationInfo(node).useCount() == 1;
167 bool canReuse(Node* nodeA, Node* nodeB)
169 return nodeA == nodeB && generationInfo(nodeA).useCount() == 2;
171 bool canReuse(Edge nodeUse)
173 return canReuse(nodeUse.node());
175 GPRReg reuse(GPRReg reg)
180 FPRReg reuse(FPRReg reg)
186 // Allocate a gpr/fpr.
189 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
190 m_jit.addRegisterAllocationAtOffset(m_jit.debugOffset());
192 VirtualRegister spillMe;
193 GPRReg gpr = m_gprs.allocate(spillMe);
194 if (spillMe.isValid()) {
195 #if USE(JSVALUE32_64)
196 GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
197 if ((info.registerFormat() & DataFormatJS))
198 m_gprs.release(info.tagGPR() == gpr ? info.payloadGPR() : info.tagGPR());
204 GPRReg allocate(GPRReg specific)
206 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
207 m_jit.addRegisterAllocationAtOffset(m_jit.debugOffset());
209 VirtualRegister spillMe = m_gprs.allocateSpecific(specific);
210 if (spillMe.isValid()) {
211 #if USE(JSVALUE32_64)
212 GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
213 RELEASE_ASSERT(info.registerFormat() != DataFormatJSDouble);
214 if ((info.registerFormat() & DataFormatJS))
215 m_gprs.release(info.tagGPR() == specific ? info.payloadGPR() : info.tagGPR());
223 return m_gprs.tryAllocate();
227 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
228 m_jit.addRegisterAllocationAtOffset(m_jit.debugOffset());
230 VirtualRegister spillMe;
231 FPRReg fpr = m_fprs.allocate(spillMe);
232 if (spillMe.isValid())
237 // Check whether a VirtualRegsiter is currently in a machine register.
238 // We use this when filling operands to fill those that are already in
239 // machine registers first (by locking VirtualRegsiters that are already
240 // in machine register before filling those that are not we attempt to
241 // avoid spilling values we will need immediately).
242 bool isFilled(Node* node)
244 return generationInfo(node).registerFormat() != DataFormatNone;
246 bool isFilledDouble(Node* node)
248 return generationInfo(node).registerFormat() == DataFormatDouble;
251 // Called on an operand once it has been consumed by a parent node.
254 if (!node->hasResult())
256 GenerationInfo& info = generationInfo(node);
258 // use() returns true when the value becomes dead, and any
259 // associated resources may be freed.
260 if (!info.use(*m_stream))
263 // Release the associated machine registers.
264 DataFormat registerFormat = info.registerFormat();
266 if (registerFormat == DataFormatDouble)
267 m_fprs.release(info.fpr());
268 else if (registerFormat != DataFormatNone)
269 m_gprs.release(info.gpr());
270 #elif USE(JSVALUE32_64)
271 if (registerFormat == DataFormatDouble)
272 m_fprs.release(info.fpr());
273 else if (registerFormat & DataFormatJS) {
274 m_gprs.release(info.tagGPR());
275 m_gprs.release(info.payloadGPR());
276 } else if (registerFormat != DataFormatNone)
277 m_gprs.release(info.gpr());
280 void use(Edge nodeUse)
285 RegisterSet usedRegisters();
287 bool masqueradesAsUndefinedWatchpointIsStillValid(const CodeOrigin& codeOrigin)
289 return m_jit.graph().masqueradesAsUndefinedWatchpointIsStillValid(codeOrigin);
291 bool masqueradesAsUndefinedWatchpointIsStillValid()
293 return masqueradesAsUndefinedWatchpointIsStillValid(m_currentNode->origin.semantic);
296 void storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPRReg scratch2);
298 void writeBarrier(GPRReg owner, GPRReg scratch1, GPRReg scratch2);
300 void writeBarrier(GPRReg owner, GPRReg value, Edge valueUse, GPRReg scratch1, GPRReg scratch2);
302 void compileStoreBarrier(Node*);
304 static GPRReg selectScratchGPR(GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg, GPRReg preserve4 = InvalidGPRReg)
306 return AssemblyHelpers::selectScratchGPR(preserve1, preserve2, preserve3, preserve4);
309 // Called by the speculative operand types, below, to fill operand to
310 // machine registers, implicitly generating speculation checks as needed.
311 GPRReg fillSpeculateInt32(Edge, DataFormat& returnFormat);
312 GPRReg fillSpeculateInt32Strict(Edge);
313 GPRReg fillSpeculateInt52(Edge, DataFormat desiredFormat);
314 FPRReg fillSpeculateDouble(Edge);
315 GPRReg fillSpeculateCell(Edge);
316 GPRReg fillSpeculateBoolean(Edge);
317 GeneratedOperandType checkGeneratedTypeForToInt32(Node*);
319 void addSlowPathGenerator(std::unique_ptr<SlowPathGenerator>);
320 void runSlowPathGenerators();
323 void noticeOSRBirth(Node*);
324 void bail(AbortReason);
325 void compileCurrentBlock();
327 void checkArgumentTypes();
329 void clearGenerationInfo();
331 // These methods are used when generating 'unexpected'
332 // calls out from JIT code to C++ helper routines -
333 // they spill all live values to the appropriate
334 // slots in the JSStack without changing any state
335 // in the GenerationInfo.
336 SilentRegisterSavePlan silentSavePlanForGPR(VirtualRegister spillMe, GPRReg source);
337 SilentRegisterSavePlan silentSavePlanForFPR(VirtualRegister spillMe, FPRReg source);
338 void silentSpill(const SilentRegisterSavePlan&);
339 void silentFill(const SilentRegisterSavePlan&, GPRReg canTrample);
341 template<typename CollectionType>
342 void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, GPRReg exclude, GPRReg exclude2 = InvalidGPRReg, FPRReg fprExclude = InvalidFPRReg)
344 ASSERT(plans.isEmpty());
345 for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
346 GPRReg gpr = iter.regID();
347 if (iter.name().isValid() && gpr != exclude && gpr != exclude2) {
348 SilentRegisterSavePlan plan = silentSavePlanForGPR(iter.name(), gpr);
354 for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
355 if (iter.name().isValid() && iter.regID() != fprExclude) {
356 SilentRegisterSavePlan plan = silentSavePlanForFPR(iter.name(), iter.regID());
363 template<typename CollectionType>
364 void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, NoResultTag)
366 silentSpillAllRegistersImpl(doSpill, plans, InvalidGPRReg, InvalidGPRReg, InvalidFPRReg);
368 template<typename CollectionType>
369 void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, FPRReg exclude)
371 silentSpillAllRegistersImpl(doSpill, plans, InvalidGPRReg, InvalidGPRReg, exclude);
373 #if USE(JSVALUE32_64)
374 template<typename CollectionType>
375 void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, JSValueRegs exclude)
377 silentSpillAllRegistersImpl(doSpill, plans, exclude.tagGPR(), exclude.payloadGPR());
381 void silentSpillAllRegisters(GPRReg exclude, GPRReg exclude2 = InvalidGPRReg, FPRReg fprExclude = InvalidFPRReg)
383 silentSpillAllRegistersImpl(true, m_plans, exclude, exclude2, fprExclude);
385 void silentSpillAllRegisters(FPRReg exclude)
387 silentSpillAllRegisters(InvalidGPRReg, InvalidGPRReg, exclude);
389 void silentSpillAllRegisters(JSValueRegs exclude)
392 silentSpillAllRegisters(exclude.payloadGPR());
394 silentSpillAllRegisters(exclude.payloadGPR(), exclude.tagGPR());
398 static GPRReg pickCanTrample(GPRReg exclude)
400 GPRReg result = GPRInfo::regT0;
401 if (result == exclude)
402 result = GPRInfo::regT1;
405 static GPRReg pickCanTrample(FPRReg)
407 return GPRInfo::regT0;
409 static GPRReg pickCanTrample(NoResultTag)
411 return GPRInfo::regT0;
415 static GPRReg pickCanTrample(JSValueRegs exclude)
417 return pickCanTrample(exclude.payloadGPR());
420 static GPRReg pickCanTrample(JSValueRegs exclude)
422 GPRReg result = GPRInfo::regT0;
423 if (result == exclude.tagGPR()) {
424 result = GPRInfo::regT1;
425 if (result == exclude.payloadGPR())
426 result = GPRInfo::regT2;
427 } else if (result == exclude.payloadGPR()) {
428 result = GPRInfo::regT1;
429 if (result == exclude.tagGPR())
430 result = GPRInfo::regT2;
436 template<typename RegisterType>
437 void silentFillAllRegisters(RegisterType exclude)
439 GPRReg canTrample = pickCanTrample(exclude);
441 while (!m_plans.isEmpty()) {
442 SilentRegisterSavePlan& plan = m_plans.last();
443 silentFill(plan, canTrample);
444 m_plans.removeLast();
448 // These methods convert between doubles, and doubles boxed and JSValues.
450 GPRReg boxDouble(FPRReg fpr, GPRReg gpr)
452 return m_jit.boxDouble(fpr, gpr);
454 FPRReg unboxDouble(GPRReg gpr, FPRReg fpr)
456 return m_jit.unboxDouble(gpr, fpr);
458 GPRReg boxDouble(FPRReg fpr)
460 return boxDouble(fpr, allocate());
463 void boxInt52(GPRReg sourceGPR, GPRReg targetGPR, DataFormat);
464 #elif USE(JSVALUE32_64)
465 void boxDouble(FPRReg fpr, GPRReg tagGPR, GPRReg payloadGPR)
467 m_jit.boxDouble(fpr, tagGPR, payloadGPR);
469 void unboxDouble(GPRReg tagGPR, GPRReg payloadGPR, FPRReg fpr, FPRReg scratchFPR)
471 m_jit.unboxDouble(tagGPR, payloadGPR, fpr, scratchFPR);
474 void boxDouble(FPRReg fpr, JSValueRegs regs)
476 m_jit.boxDouble(fpr, regs);
479 // Spill a VirtualRegister to the JSStack.
480 void spill(VirtualRegister spillMe)
482 GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
484 #if USE(JSVALUE32_64)
485 if (info.registerFormat() == DataFormatNone) // it has been spilled. JS values which have two GPRs can reach here
488 // Check the GenerationInfo to see if this value need writing
489 // to the JSStack - if not, mark it as spilled & return.
490 if (!info.needsSpill()) {
491 info.setSpilled(*m_stream, spillMe);
495 DataFormat spillFormat = info.registerFormat();
496 switch (spillFormat) {
497 case DataFormatStorage: {
498 // This is special, since it's not a JS value - as in it's not visible to JS
500 m_jit.storePtr(info.gpr(), JITCompiler::addressFor(spillMe));
501 info.spill(*m_stream, spillMe, DataFormatStorage);
505 case DataFormatInt32: {
506 m_jit.store32(info.gpr(), JITCompiler::payloadFor(spillMe));
507 info.spill(*m_stream, spillMe, DataFormatInt32);
512 case DataFormatDouble: {
513 m_jit.storeDouble(info.fpr(), JITCompiler::addressFor(spillMe));
514 info.spill(*m_stream, spillMe, DataFormatDouble);
518 case DataFormatInt52:
519 case DataFormatStrictInt52: {
520 m_jit.store64(info.gpr(), JITCompiler::addressFor(spillMe));
521 info.spill(*m_stream, spillMe, spillFormat);
526 // The following code handles JSValues, int32s, and cells.
527 RELEASE_ASSERT(spillFormat == DataFormatCell || spillFormat & DataFormatJS);
529 GPRReg reg = info.gpr();
530 // We need to box int32 and cell values ...
531 // but on JSVALUE64 boxing a cell is a no-op!
532 if (spillFormat == DataFormatInt32)
533 m_jit.or64(GPRInfo::tagTypeNumberRegister, reg);
535 // Spill the value, and record it as spilled in its boxed form.
536 m_jit.store64(reg, JITCompiler::addressFor(spillMe));
537 info.spill(*m_stream, spillMe, (DataFormat)(spillFormat | DataFormatJS));
539 #elif USE(JSVALUE32_64)
541 case DataFormatBoolean: {
542 m_jit.store32(info.gpr(), JITCompiler::payloadFor(spillMe));
543 info.spill(*m_stream, spillMe, spillFormat);
547 case DataFormatDouble: {
548 // On JSVALUE32_64 boxing a double is a no-op.
549 m_jit.storeDouble(info.fpr(), JITCompiler::addressFor(spillMe));
550 info.spill(*m_stream, spillMe, DataFormatDouble);
555 // The following code handles JSValues.
556 RELEASE_ASSERT(spillFormat & DataFormatJS);
557 m_jit.store32(info.tagGPR(), JITCompiler::tagFor(spillMe));
558 m_jit.store32(info.payloadGPR(), JITCompiler::payloadFor(spillMe));
559 info.spill(*m_stream, spillMe, spillFormat);
565 bool isKnownInteger(Node* node) { return m_state.forNode(node).isType(SpecInt32); }
566 bool isKnownCell(Node* node) { return m_state.forNode(node).isType(SpecCell); }
568 bool isKnownNotInteger(Node* node) { return !(m_state.forNode(node).m_type & SpecInt32); }
569 bool isKnownNotNumber(Node* node) { return !(m_state.forNode(node).m_type & SpecFullNumber); }
570 bool isKnownNotCell(Node* node) { return !(m_state.forNode(node).m_type & SpecCell); }
571 bool isKnownNotOther(Node* node) { return !(m_state.forNode(node).m_type & SpecOther); }
573 UniquedStringImpl* identifierUID(unsigned index)
575 return m_jit.graph().identifiers()[index];
578 // Spill all VirtualRegisters back to the JSStack.
579 void flushRegisters()
581 for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
582 if (iter.name().isValid()) {
587 for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
588 if (iter.name().isValid()) {
595 // Used to ASSERT flushRegisters() has been called prior to
596 // calling out from JIT code to a C helper function.
599 for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
600 if (iter.name().isValid())
603 for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
604 if (iter.name().isValid())
611 static MacroAssembler::Imm64 valueOfJSConstantAsImm64(Node* node)
613 return MacroAssembler::Imm64(JSValue::encode(node->asJSValue()));
617 // Helper functions to enable code sharing in implementations of bit/shift ops.
618 void bitOp(NodeType op, int32_t imm, GPRReg op1, GPRReg result)
622 m_jit.and32(Imm32(imm), op1, result);
625 m_jit.or32(Imm32(imm), op1, result);
628 m_jit.xor32(Imm32(imm), op1, result);
631 RELEASE_ASSERT_NOT_REACHED();
634 void bitOp(NodeType op, GPRReg op1, GPRReg op2, GPRReg result)
638 m_jit.and32(op1, op2, result);
641 m_jit.or32(op1, op2, result);
644 m_jit.xor32(op1, op2, result);
647 RELEASE_ASSERT_NOT_REACHED();
650 void shiftOp(NodeType op, GPRReg op1, int32_t shiftAmount, GPRReg result)
654 m_jit.rshift32(op1, Imm32(shiftAmount), result);
657 m_jit.lshift32(op1, Imm32(shiftAmount), result);
660 m_jit.urshift32(op1, Imm32(shiftAmount), result);
663 RELEASE_ASSERT_NOT_REACHED();
666 void shiftOp(NodeType op, GPRReg op1, GPRReg shiftAmount, GPRReg result)
670 m_jit.rshift32(op1, shiftAmount, result);
673 m_jit.lshift32(op1, shiftAmount, result);
676 m_jit.urshift32(op1, shiftAmount, result);
679 RELEASE_ASSERT_NOT_REACHED();
683 // Returns the index of the branch node if peephole is okay, UINT_MAX otherwise.
684 unsigned detectPeepHoleBranch()
686 // Check that no intervening nodes will be generated.
687 for (unsigned index = m_indexInBlock + 1; index < m_block->size() - 1; ++index) {
688 Node* node = m_block->at(index);
689 if (!node->shouldGenerate())
691 // Check if it's a Phantom that can be safely ignored.
692 if (node->op() == Phantom && !node->child1())
697 // Check if the lastNode is a branch on this node.
698 Node* lastNode = m_block->terminal();
699 return lastNode->op() == Branch && lastNode->child1() == m_currentNode ? m_block->size() - 1 : UINT_MAX;
702 void compileMovHint(Node*);
703 void compileMovHintAndCheck(Node*);
706 void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
707 void cachedPutById(CodeOrigin, GPRReg base, GPRReg value, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
708 #elif USE(JSVALUE32_64)
709 void cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
710 void cachedPutById(CodeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
713 void compileIn(Node*);
715 void compileBaseValueStoreBarrier(Edge& baseEdge, Edge& valueEdge);
717 void nonSpeculativeNonPeepholeCompareNullOrUndefined(Edge operand);
718 void nonSpeculativePeepholeBranchNullOrUndefined(Edge operand, Node* branchNode);
720 void nonSpeculativePeepholeBranch(Node*, Node* branchNode, MacroAssembler::RelationalCondition, S_JITOperation_EJJ helperFunction);
721 void nonSpeculativeNonPeepholeCompare(Node*, MacroAssembler::RelationalCondition, S_JITOperation_EJJ helperFunction);
722 bool nonSpeculativeCompare(Node*, MacroAssembler::RelationalCondition, S_JITOperation_EJJ helperFunction);
724 void nonSpeculativePeepholeStrictEq(Node*, Node* branchNode, bool invert = false);
725 void nonSpeculativeNonPeepholeStrictEq(Node*, bool invert = false);
726 bool nonSpeculativeStrictEq(Node*, bool invert = false);
728 void compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg, GPRReg scratch2Reg);
729 void compileInstanceOf(Node*);
731 void emitCall(Node*);
733 // Called once a node has completed code generation but prior to setting
734 // its result, to free up its children. (This must happen prior to setting
735 // the nodes result, since the node may have the same VirtualRegister as
736 // a child, and as such will use the same GeneratioInfo).
737 void useChildren(Node*);
739 // These method called to initialize the the GenerationInfo
740 // to describe the result of an operation.
741 void int32Result(GPRReg reg, Node* node, DataFormat format = DataFormatInt32, UseChildrenMode mode = CallUseChildren)
743 if (mode == CallUseChildren)
746 VirtualRegister virtualRegister = node->virtualRegister();
747 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
749 if (format == DataFormatInt32) {
750 m_jit.jitAssertIsInt32(reg);
751 m_gprs.retain(reg, virtualRegister, SpillOrderInteger);
752 info.initInt32(node, node->refCount(), reg);
755 RELEASE_ASSERT(format == DataFormatJSInt32);
756 m_jit.jitAssertIsJSInt32(reg);
757 m_gprs.retain(reg, virtualRegister, SpillOrderJS);
758 info.initJSValue(node, node->refCount(), reg, format);
759 #elif USE(JSVALUE32_64)
760 RELEASE_ASSERT_NOT_REACHED();
764 void int32Result(GPRReg reg, Node* node, UseChildrenMode mode)
766 int32Result(reg, node, DataFormatInt32, mode);
768 void int52Result(GPRReg reg, Node* node, DataFormat format, UseChildrenMode mode = CallUseChildren)
770 if (mode == CallUseChildren)
773 VirtualRegister virtualRegister = node->virtualRegister();
774 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
776 m_gprs.retain(reg, virtualRegister, SpillOrderJS);
777 info.initInt52(node, node->refCount(), reg, format);
779 void int52Result(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
781 int52Result(reg, node, DataFormatInt52, mode);
783 void strictInt52Result(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
785 int52Result(reg, node, DataFormatStrictInt52, mode);
787 void noResult(Node* node, UseChildrenMode mode = CallUseChildren)
789 if (mode == UseChildrenCalledExplicitly)
793 void cellResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
795 if (mode == CallUseChildren)
798 VirtualRegister virtualRegister = node->virtualRegister();
799 m_gprs.retain(reg, virtualRegister, SpillOrderCell);
800 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
801 info.initCell(node, node->refCount(), reg);
803 void blessedBooleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
806 jsValueResult(reg, node, DataFormatJSBoolean, mode);
808 booleanResult(reg, node, mode);
811 void unblessedBooleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
816 blessedBooleanResult(reg, node, mode);
819 void jsValueResult(GPRReg reg, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
821 if (format == DataFormatJSInt32)
822 m_jit.jitAssertIsJSInt32(reg);
824 if (mode == CallUseChildren)
827 VirtualRegister virtualRegister = node->virtualRegister();
828 m_gprs.retain(reg, virtualRegister, SpillOrderJS);
829 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
830 info.initJSValue(node, node->refCount(), reg, format);
832 void jsValueResult(GPRReg reg, Node* node, UseChildrenMode mode)
834 jsValueResult(reg, node, DataFormatJS, mode);
836 #elif USE(JSVALUE32_64)
837 void booleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
839 if (mode == CallUseChildren)
842 VirtualRegister virtualRegister = node->virtualRegister();
843 m_gprs.retain(reg, virtualRegister, SpillOrderBoolean);
844 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
845 info.initBoolean(node, node->refCount(), reg);
847 void jsValueResult(GPRReg tag, GPRReg payload, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
849 if (mode == CallUseChildren)
852 VirtualRegister virtualRegister = node->virtualRegister();
853 m_gprs.retain(tag, virtualRegister, SpillOrderJS);
854 m_gprs.retain(payload, virtualRegister, SpillOrderJS);
855 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
856 info.initJSValue(node, node->refCount(), tag, payload, format);
858 void jsValueResult(GPRReg tag, GPRReg payload, Node* node, UseChildrenMode mode)
860 jsValueResult(tag, payload, node, DataFormatJS, mode);
863 void jsValueResult(JSValueRegs regs, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
866 jsValueResult(regs.gpr(), node, format, mode);
868 jsValueResult(regs.tagGPR(), regs.payloadGPR(), node, format, mode);
871 void storageResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
873 if (mode == CallUseChildren)
876 VirtualRegister virtualRegister = node->virtualRegister();
877 m_gprs.retain(reg, virtualRegister, SpillOrderStorage);
878 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
879 info.initStorage(node, node->refCount(), reg);
881 void doubleResult(FPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
883 if (mode == CallUseChildren)
886 VirtualRegister virtualRegister = node->virtualRegister();
887 m_fprs.retain(reg, virtualRegister, SpillOrderDouble);
888 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
889 info.initDouble(node, node->refCount(), reg);
891 void initConstantInfo(Node* node)
893 ASSERT(node->hasConstant());
894 generationInfo(node).initConstant(node, node->refCount());
897 // These methods add calls to C++ helper functions.
898 // These methods are broadly value representation specific (i.e.
899 // deal with the fact that a JSValue may be passed in one or two
900 // machine registers, and delegate the calling convention specific
901 // decision as to how to fill the regsiters to setupArguments* methods.
903 JITCompiler::Call callOperation(V_JITOperation_E operation)
905 m_jit.setupArgumentsExecState();
906 return appendCall(operation);
908 JITCompiler::Call callOperation(P_JITOperation_E operation, GPRReg result)
910 m_jit.setupArgumentsExecState();
911 return appendCallSetResult(operation, result);
913 JITCompiler::Call callOperation(P_JITOperation_EC operation, GPRReg result, GPRReg cell)
915 m_jit.setupArgumentsWithExecState(cell);
916 return appendCallSetResult(operation, result);
918 JITCompiler::Call callOperation(P_JITOperation_EO operation, GPRReg result, GPRReg object)
920 m_jit.setupArgumentsWithExecState(object);
921 return appendCallSetResult(operation, result);
923 JITCompiler::Call callOperation(P_JITOperation_EOS operation, GPRReg result, GPRReg object, size_t size)
925 m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size));
926 return appendCallSetResult(operation, result);
928 JITCompiler::Call callOperation(P_JITOperation_EOZ operation, GPRReg result, GPRReg object, int32_t size)
930 m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size));
931 return appendCallSetResult(operation, result);
933 JITCompiler::Call callOperation(C_JITOperation_EOZ operation, GPRReg result, GPRReg object, int32_t size)
935 m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(static_cast<size_t>(size)));
936 return appendCallSetResult(operation, result);
938 JITCompiler::Call callOperation(P_JITOperation_EPS operation, GPRReg result, GPRReg old, size_t size)
940 m_jit.setupArgumentsWithExecState(old, TrustedImmPtr(size));
941 return appendCallSetResult(operation, result);
943 JITCompiler::Call callOperation(P_JITOperation_ES operation, GPRReg result, size_t size)
945 m_jit.setupArgumentsWithExecState(TrustedImmPtr(size));
946 return appendCallSetResult(operation, result);
948 JITCompiler::Call callOperation(P_JITOperation_ESJss operation, GPRReg result, size_t index, GPRReg arg1)
950 m_jit.setupArgumentsWithExecState(TrustedImmPtr(index), arg1);
951 return appendCallSetResult(operation, result);
953 JITCompiler::Call callOperation(P_JITOperation_ESt operation, GPRReg result, Structure* structure)
955 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
956 return appendCallSetResult(operation, result);
958 JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2)
960 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
961 return appendCallSetResult(operation, result);
963 JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, Structure* structure, size_t arg2)
965 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2));
966 return appendCallSetResult(operation, result);
968 JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
970 m_jit.setupArgumentsWithExecState(arg1, arg2);
971 return appendCallSetResult(operation, result);
973 JITCompiler::Call callOperation(P_JITOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size)
975 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size));
976 return appendCallSetResult(operation, result);
978 JITCompiler::Call callOperation(P_JITOperation_EStSS operation, GPRReg result, Structure* structure, size_t index, size_t size)
980 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(index), TrustedImmPtr(size));
981 return appendCallSetResult(operation, result);
983 JITCompiler::Call callOperation(C_JITOperation_E operation, GPRReg result)
985 m_jit.setupArgumentsExecState();
986 return appendCallSetResult(operation, result);
988 JITCompiler::Call callOperation(C_JITOperation_EC operation, GPRReg result, GPRReg arg1)
990 m_jit.setupArgumentsWithExecState(arg1);
991 return appendCallSetResult(operation, result);
993 JITCompiler::Call callOperation(C_JITOperation_EC operation, GPRReg result, JSCell* cell)
995 m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
996 return appendCallSetResult(operation, result);
998 JITCompiler::Call callOperation(C_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1000 m_jit.setupArgumentsWithExecState(arg1, arg2);
1001 return appendCallSetResult(operation, result);
1003 JITCompiler::Call callOperation(C_JITOperation_ECZC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1005 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1006 return appendCallSetResult(operation, result);
1008 JITCompiler::Call callOperation(C_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell)
1010 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
1011 return appendCallSetResult(operation, result);
1013 JITCompiler::Call callOperation(C_JITOperation_EIcf operation, GPRReg result, InlineCallFrame* inlineCallFrame)
1015 m_jit.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame));
1016 return appendCallSetResult(operation, result);
1018 JITCompiler::Call callOperation(C_JITOperation_ESt operation, GPRReg result, Structure* structure)
1020 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
1021 return appendCallSetResult(operation, result);
1025 JITCompiler::Call callOperation(C_JITOperation_EStJscSymtabJ operation, GPRReg result, Structure* structure, GPRReg scope, SymbolTable* table, TrustedImm64 initialValue)
1027 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), scope, TrustedImmPtr(table), initialValue);
1028 return appendCallSetResult(operation, result);
1031 JITCompiler::Call callOperation(C_JITOperation_EStJscSymtabJ operation, GPRReg result, Structure* structure, GPRReg scope, SymbolTable* table, TrustedImm32 tag, TrustedImm32 payload)
1033 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), scope, TrustedImmPtr(table), payload, tag);
1034 return appendCallSetResult(operation, result);
1037 JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, Structure* structure, unsigned knownLength)
1039 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength));
1040 return appendCallSetResult(operation, result);
1042 JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, Structure* structure, unsigned knownLength, unsigned minCapacity)
1044 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength), TrustedImm32(minCapacity));
1045 return appendCallSetResult(operation, result);
1047 JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg length)
1049 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length);
1050 return appendCallSetResult(operation, result);
1052 JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, Structure* structure, GPRReg length, unsigned minCapacity)
1054 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length, TrustedImm32(minCapacity));
1055 return appendCallSetResult(operation, result);
1057 JITCompiler::Call callOperation(C_JITOperation_EJssSt operation, GPRReg result, GPRReg arg1, Structure* structure)
1059 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(structure));
1060 return appendCallSetResult(operation, result);
1062 JITCompiler::Call callOperation(C_JITOperation_EJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1064 m_jit.setupArgumentsWithExecState(arg1, arg2);
1065 return appendCallSetResult(operation, result);
1067 JITCompiler::Call callOperation(C_JITOperation_EJssJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1069 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1070 return appendCallSetResult(operation, result);
1073 JITCompiler::Call callOperation(S_JITOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1075 m_jit.setupArgumentsWithExecState(arg1, arg2);
1076 return appendCallSetResult(operation, result);
1079 JITCompiler::Call callOperation(S_JITOperation_EGC operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg2)
1081 m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg2);
1082 return appendCallSetResult(operation, result);
1085 JITCompiler::Call callOperation(C_JITOperation_EGC operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg2)
1087 m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg2);
1088 return appendCallSetResult(operation, result);
1091 JITCompiler::Call callOperation(Jss_JITOperation_EZ operation, GPRReg result, GPRReg arg1)
1093 m_jit.setupArgumentsWithExecState(arg1);
1094 return appendCallSetResult(operation, result);
1097 JITCompiler::Call callOperation(V_JITOperation_EC operation, GPRReg arg1)
1099 m_jit.setupArgumentsWithExecState(arg1);
1100 return appendCall(operation);
1103 JITCompiler::Call callOperation(V_JITOperation_EC operation, JSCell* arg1)
1105 m_jit.setupArgumentsWithExecState(TrustedImmPtr(arg1));
1106 return appendCall(operation);
1109 JITCompiler::Call callOperation(V_JITOperation_ECIcf operation, GPRReg arg1, InlineCallFrame* inlineCallFrame)
1111 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(inlineCallFrame));
1112 return appendCall(operation);
1114 JITCompiler::Call callOperation(V_JITOperation_ECCIcf operation, GPRReg arg1, GPRReg arg2, InlineCallFrame* inlineCallFrame)
1116 m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(inlineCallFrame));
1117 return appendCall(operation);
1120 JITCompiler::Call callOperation(V_JITOperation_ECZ operation, GPRReg arg1, int arg2)
1122 m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1123 return appendCall(operation);
1125 JITCompiler::Call callOperation(V_JITOperation_ECC operation, GPRReg arg1, GPRReg arg2)
1127 m_jit.setupArgumentsWithExecState(arg1, arg2);
1128 return appendCall(operation);
1130 JITCompiler::Call callOperation(V_JITOperation_ECC operation, GPRReg arg1, JSCell* arg2)
1132 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
1133 return appendCall(operation);
1135 JITCompiler::Call callOperation(V_JITOperation_ECC operation, JSCell* arg1, GPRReg arg2)
1137 m_jit.setupArgumentsWithExecState(TrustedImmPtr(arg1), arg2);
1138 return appendCall(operation);
1141 JITCompiler::Call callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb operation, void* pointer)
1143 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1144 return appendCallWithCallFrameRollbackOnException(operation);
1147 JITCompiler::Call callOperationWithCallFrameRollbackOnException(Z_JITOperation_E operation, GPRReg result)
1149 m_jit.setupArgumentsExecState();
1150 return appendCallWithCallFrameRollbackOnExceptionSetResult(operation, result);
1152 JITCompiler::Call callOperation(Z_JITOperation_EC operation, GPRReg result, GPRReg arg1)
1154 m_jit.setupArgumentsWithExecState(arg1);
1155 return appendCallSetResult(operation, result);
1158 JITCompiler::Call callOperation(V_JITOperation_ECIZC operation, GPRReg regOp1, UniquedStringImpl* identOp2, int32_t op3, GPRReg regOp4)
1160 m_jit.setupArgumentsWithExecState(regOp1, TrustedImmPtr(identOp2), TrustedImm32(op3), regOp4);
1161 return appendCall(operation);
1164 template<typename FunctionType, typename... Args>
1165 JITCompiler::Call callOperation(FunctionType operation, NoResultTag, Args... args)
1167 return callOperation(operation, args...);
1170 JITCompiler::Call callOperation(D_JITOperation_ZZ operation, FPRReg result, GPRReg arg1, GPRReg arg2)
1172 m_jit.setupArguments(arg1, arg2);
1173 return appendCallSetResult(operation, result);
1175 JITCompiler::Call callOperation(D_JITOperation_D operation, FPRReg result, FPRReg arg1)
1177 m_jit.setupArguments(arg1);
1178 return appendCallSetResult(operation, result);
1180 JITCompiler::Call callOperation(D_JITOperation_DD operation, FPRReg result, FPRReg arg1, FPRReg arg2)
1182 m_jit.setupArguments(arg1, arg2);
1183 return appendCallSetResult(operation, result);
1185 JITCompiler::Call callOperation(T_JITOperation_EJss operation, GPRReg result, GPRReg arg1)
1187 m_jit.setupArgumentsWithExecState(arg1);
1188 return appendCallSetResult(operation, result);
1190 JITCompiler::Call callOperation(C_JITOperation_EJscZ operation, GPRReg result, GPRReg arg1, int32_t arg2)
1192 m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1193 return appendCallSetResult(operation, result);
1195 JITCompiler::Call callOperation(C_JITOperation_EZ operation, GPRReg result, GPRReg arg1)
1197 m_jit.setupArgumentsWithExecState(arg1);
1198 return appendCallSetResult(operation, result);
1200 JITCompiler::Call callOperation(C_JITOperation_EZ operation, GPRReg result, int32_t arg1)
1202 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1203 return appendCallSetResult(operation, result);
1206 JITCompiler::Call callOperation(J_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell)
1208 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
1209 return appendCallSetResult(operation, result);
1212 JITCompiler::Call callOperation(J_JITOperation_EJscCJ operation, GPRReg result, GPRReg arg1, JSCell* cell, GPRReg arg2)
1214 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell), arg2);
1215 return appendCallSetResult(operation, result);
1218 JITCompiler::Call callOperation(V_JITOperation_EWs operation, WatchpointSet* watchpointSet)
1220 m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet));
1221 return appendCall(operation);
1225 JITCompiler::Call callOperation(J_JITOperation_E operation, GPRReg result)
1227 m_jit.setupArgumentsExecState();
1228 return appendCallSetResult(operation, result);
1230 JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg result, void* pointer)
1232 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1233 return appendCallSetResult(operation, result);
1235 JITCompiler::Call callOperation(Z_JITOperation_D operation, GPRReg result, FPRReg arg1)
1237 m_jit.setupArguments(arg1);
1238 JITCompiler::Call call = m_jit.appendCall(operation);
1239 m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1242 JITCompiler::Call callOperation(Q_JITOperation_J operation, GPRReg result, GPRReg value)
1244 m_jit.setupArguments(value);
1245 return appendCallSetResult(operation, result);
1247 JITCompiler::Call callOperation(Q_JITOperation_D operation, GPRReg result, FPRReg value)
1249 m_jit.setupArguments(value);
1250 return appendCallSetResult(operation, result);
1252 JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg result, UniquedStringImpl* uid)
1254 m_jit.setupArgumentsWithExecState(TrustedImmPtr(uid));
1255 return appendCallSetResult(operation, result);
1257 JITCompiler::Call callOperation(J_JITOperation_EA operation, GPRReg result, GPRReg arg1)
1259 m_jit.setupArgumentsWithExecState(arg1);
1260 return appendCallSetResult(operation, result);
1262 JITCompiler::Call callOperation(J_JITOperation_EAZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1264 m_jit.setupArgumentsWithExecState(arg1, arg2);
1265 return appendCallSetResult(operation, result);
1267 JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1269 m_jit.setupArgumentsWithExecState(arg1, arg2);
1270 return appendCallSetResult(operation, result);
1272 JITCompiler::Call callOperation(J_JITOperation_EPS operation, GPRReg result, void* pointer, size_t size)
1274 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
1275 return appendCallSetResult(operation, result);
1277 JITCompiler::Call callOperation(J_JITOperation_ESS operation, GPRReg result, int startConstant, int numConstants)
1279 m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
1280 return appendCallSetResult(operation, result);
1282 JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg result, GPRReg arg1, void* pointer)
1284 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
1285 return appendCallSetResult(operation, result);
1287 JITCompiler::Call callOperation(J_JITOperation_EC operation, GPRReg result, JSCell* cell)
1289 m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
1290 return appendCallSetResult(operation, result);
1292 JITCompiler::Call callOperation(J_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1294 m_jit.setupArgumentsWithExecState(arg1, arg2);
1295 return appendCallSetResult(operation, result);
1297 JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, const UniquedStringImpl* uid)
1299 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
1300 return appendCallSetResult(operation, result);
1302 JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, UniquedStringImpl* uid)
1304 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
1305 return appendCallSetResult(operation, result);
1307 JITCompiler::Call callOperation(J_JITOperation_EDA operation, GPRReg result, FPRReg arg1, GPRReg arg2)
1309 m_jit.setupArgumentsWithExecState(arg1, arg2);
1310 return appendCallSetResult(operation, result);
1312 JITCompiler::Call callOperation(J_JITOperation_EJC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1314 m_jit.setupArgumentsWithExecState(arg1, arg2);
1315 return appendCallSetResult(operation, result);
1317 JITCompiler::Call callOperation(J_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1319 m_jit.setupArgumentsWithExecState(arg1, arg2);
1320 return appendCallSetResult(operation, result);
1322 JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1324 m_jit.setupArgumentsWithExecState(arg1, arg2);
1325 return appendCallSetResult(operation, result);
1327 JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg result, GPRReg arg1)
1329 m_jit.setupArgumentsWithExecState(arg1);
1330 return appendCallSetResult(operation, result);
1332 JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg result, GPRReg arg1)
1334 m_jit.setupArgumentsWithExecState(arg1);
1335 return appendCallSetResult(operation, result);
1337 JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg result, int32_t arg1)
1339 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1340 return appendCallSetResult(operation, result);
1342 JITCompiler::Call callOperation(J_JITOperation_EZZ operation, GPRReg result, int32_t arg1, GPRReg arg2)
1344 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
1345 return appendCallSetResult(operation, result);
1347 JITCompiler::Call callOperation(J_JITOperation_EZIcfZ operation, GPRReg result, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
1349 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
1350 return appendCallSetResult(operation, result);
1353 JITCompiler::Call callOperation(P_JITOperation_EJS operation, GPRReg result, GPRReg value, size_t index)
1355 m_jit.setupArgumentsWithExecState(value, TrustedImmPtr(index));
1356 return appendCallSetResult(operation, result);
1359 JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, Structure* structure, GPRReg arg2)
1361 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
1362 return appendCallSetResult(operation, result);
1365 JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
1367 m_jit.setupArgumentsWithExecState(arg1);
1368 return appendCallSetResult(operation, result);
1370 JITCompiler::Call callOperation(C_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1372 m_jit.setupArgumentsWithExecState(arg1, arg2);
1373 return appendCallSetResult(operation, result);
1375 JITCompiler::Call callOperation(C_JITOperation_EJJC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1377 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1378 return appendCallSetResult(operation, result);
1380 JITCompiler::Call callOperation(C_JITOperation_EJJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1382 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1383 return appendCallSetResult(operation, result);
1385 JITCompiler::Call callOperation(C_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1387 m_jit.setupArgumentsWithExecState(arg1, arg2);
1388 return appendCallSetResult(operation, result);
1390 JITCompiler::Call callOperation(C_JITOperation_EJZC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1392 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1393 return appendCallSetResult(operation, result);
1395 JITCompiler::Call callOperation(S_JITOperation_J operation, GPRReg result, GPRReg arg1)
1397 m_jit.setupArguments(arg1);
1398 return appendCallSetResult(operation, result);
1400 JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
1402 m_jit.setupArgumentsWithExecState(arg1);
1403 return appendCallSetResult(operation, result);
1405 JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
1407 m_jit.setupArgumentsWithExecState(arg1);
1408 return appendCallSetResult(operation, result);
1410 JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1412 m_jit.setupArgumentsWithExecState(arg1, arg2);
1413 return appendCallSetResult(operation, result);
1416 JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1418 m_jit.setupArgumentsWithExecState(arg1, arg2);
1419 return appendCallSetResult(operation, result);
1421 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1423 m_jit.setupArgumentsWithExecState(arg1, arg2);
1424 return appendCallSetResult(operation, result);
1426 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, MacroAssembler::TrustedImm32 imm)
1428 m_jit.setupArgumentsWithExecState(arg1, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))));
1429 return appendCallSetResult(operation, result);
1431 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, MacroAssembler::TrustedImm32 imm, GPRReg arg2)
1433 m_jit.setupArgumentsWithExecState(MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))), arg2);
1434 return appendCallSetResult(operation, result);
1436 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2)
1438 return callOperation(operation, result.payloadGPR(), arg1.payloadGPR(), arg2.payloadGPR());
1440 JITCompiler::Call callOperation(J_JITOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1442 m_jit.setupArgumentsWithExecState(arg1, arg2);
1443 return appendCallSetResult(operation, result);
1445 JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1447 m_jit.setupArgumentsWithExecState(arg1, arg2);
1448 return appendCallSetResult(operation, result);
1450 JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg result, GPRReg arg1, JSValueRegs arg2)
1452 m_jit.setupArgumentsWithExecState(arg1, arg2.gpr());
1453 return appendCallSetResult(operation, result);
1456 JITCompiler::Call callOperation(V_JITOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3)
1458 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1459 return appendCall(operation);
1461 JITCompiler::Call callOperation(V_JITOperation_EJ operation, GPRReg arg1)
1463 m_jit.setupArgumentsWithExecState(arg1);
1464 return appendCall(operation);
1466 JITCompiler::Call callOperation(V_JITOperation_EJPP operation, GPRReg arg1, GPRReg arg2, void* pointer)
1468 m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(pointer));
1469 return appendCall(operation);
1471 JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1, GPRReg arg2, UniquedStringImpl* uid)
1473 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, arg2, TrustedImmPtr(uid));
1474 return appendCall(operation);
1476 JITCompiler::Call callOperation(V_JITOperation_EJJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1478 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1479 return appendCall(operation);
1481 JITCompiler::Call callOperation(V_JITOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1483 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1484 return appendCall(operation);
1487 JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1489 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1490 return appendCall(operation);
1492 JITCompiler::Call callOperation(V_JITOperation_ECJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1494 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1495 return appendCall(operation);
1498 JITCompiler::Call callOperation(Z_JITOperation_EJZZ operation, GPRReg result, GPRReg arg1, unsigned arg2, unsigned arg3)
1500 m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2), TrustedImm32(arg3));
1501 return appendCallSetResult(operation, result);
1503 JITCompiler::Call callOperation(F_JITOperation_EFJZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2, unsigned arg3, GPRReg arg4)
1505 m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImm32(arg3), arg4);
1506 return appendCallSetResult(operation, result);
1508 JITCompiler::Call callOperation(Z_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, unsigned arg2)
1510 m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1511 return appendCallSetResult(operation, result);
1513 JITCompiler::Call callOperation(V_JITOperation_EZJZZZ operation, unsigned arg1, GPRReg arg2, unsigned arg3, GPRReg arg4, unsigned arg5)
1515 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2, TrustedImm32(arg3), arg4, TrustedImm32(arg5));
1516 return appendCall(operation);
1518 JITCompiler::Call callOperation(V_JITOperation_ECJZC operation, GPRReg regOp1, GPRReg regOp2, int32_t op3, GPRReg regOp4)
1520 m_jit.setupArgumentsWithExecState(regOp1, regOp2, TrustedImm32(op3), regOp4);
1521 return appendCall(operation);
1523 JITCompiler::Call callOperation(V_JITOperation_ECIZJJ operation, GPRReg regOp1, UniquedStringImpl* identOp2, int32_t op3, GPRReg regOp4, GPRReg regOp5)
1525 m_jit.setupArgumentsWithExecState(regOp1, TrustedImmPtr(identOp2), TrustedImm32(op3), regOp4, regOp5);
1526 return appendCall(operation);
1528 #else // USE(JSVALUE32_64)
1530 // EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]).
1531 // To avoid assemblies from using wrong registers, let's occupy r1 or r3 with a dummy argument when necessary.
1532 #if (COMPILER_SUPPORTS(EABI) && CPU(ARM)) || CPU(MIPS)
1533 #define EABI_32BIT_DUMMY_ARG TrustedImm32(0),
1535 #define EABI_32BIT_DUMMY_ARG
1538 // JSVALUE32_64 is a 64-bit integer that cannot be put half in an argument register and half on stack when using SH4 architecture.
1539 // To avoid this, let's occupy the 4th argument register (r7) with a dummy argument when necessary. This must only be done when there
1540 // is no other 32-bit value argument behind this 64-bit JSValue.
1542 #define SH4_32BIT_DUMMY_ARG TrustedImm32(0),
1544 #define SH4_32BIT_DUMMY_ARG
1547 JITCompiler::Call callOperation(Z_JITOperation_D operation, GPRReg result, FPRReg arg1)
1549 prepareForExternalCall();
1550 m_jit.setupArguments(arg1);
1551 JITCompiler::Call call = m_jit.appendCall(operation);
1552 m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1555 JITCompiler::Call callOperation(J_JITOperation_E operation, GPRReg resultTag, GPRReg resultPayload)
1557 m_jit.setupArgumentsExecState();
1558 return appendCallSetResult(operation, resultPayload, resultTag);
1560 JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, void* pointer)
1562 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1563 return appendCallSetResult(operation, resultPayload, resultTag);
1565 JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, void* pointer)
1567 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
1568 return appendCallSetResult(operation, resultPayload, resultTag);
1570 JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1572 m_jit.setupArgumentsWithExecState(arg1);
1573 return appendCallSetResult(operation, resultPayload, resultTag);
1575 JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg resultTag, GPRReg resultPayload, UniquedStringImpl* uid)
1577 m_jit.setupArgumentsWithExecState(TrustedImmPtr(uid));
1578 return appendCallSetResult(operation, resultPayload, resultTag);
1580 JITCompiler::Call callOperation(J_JITOperation_EA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1582 m_jit.setupArgumentsWithExecState(arg1);
1583 return appendCallSetResult(operation, resultPayload, resultTag);
1585 JITCompiler::Call callOperation(J_JITOperation_EAZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1587 m_jit.setupArgumentsWithExecState(arg1, arg2);
1588 return appendCallSetResult(operation, resultPayload, resultTag);
1590 JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg resultPayload, GPRReg resultTag, GPRReg arg1)
1592 m_jit.setupArgumentsWithExecState(arg1);
1593 return appendCallSetResult(operation, resultPayload, resultTag);
1595 JITCompiler::Call callOperation(J_JITOperation_EJC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1597 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1598 return appendCallSetResult(operation, resultPayload, resultTag);
1600 JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1602 m_jit.setupArgumentsWithExecState(arg1, arg2);
1603 return appendCallSetResult(operation, resultPayload, resultTag);
1605 JITCompiler::Call callOperation(J_JITOperation_EPS operation, GPRReg resultTag, GPRReg resultPayload, void* pointer, size_t size)
1607 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
1608 return appendCallSetResult(operation, resultPayload, resultTag);
1610 JITCompiler::Call callOperation(J_JITOperation_ESS operation, GPRReg resultTag, GPRReg resultPayload, int startConstant, int numConstants)
1612 m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
1613 return appendCallSetResult(operation, resultPayload, resultTag);
1615 JITCompiler::Call callOperation(J_JITOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, void* pointer)
1617 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(pointer));
1618 return appendCallSetResult(operation, resultPayload, resultTag);
1620 JITCompiler::Call callOperation(J_JITOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1622 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1623 return appendCallSetResult(operation, resultPayload, resultTag);
1626 JITCompiler::Call callOperation(J_JITOperation_EC operation, GPRReg resultTag, GPRReg resultPayload, JSCell* cell)
1628 m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
1629 return appendCallSetResult(operation, resultPayload, resultTag);
1631 JITCompiler::Call callOperation(J_JITOperation_ECZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1633 m_jit.setupArgumentsWithExecState(arg1, arg2);
1634 return appendCallSetResult(operation, resultPayload, resultTag);
1636 JITCompiler::Call callOperation(J_JITOperation_EJscC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, JSCell* cell)
1638 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
1639 return appendCallSetResult(operation, resultPayload, resultTag);
1641 JITCompiler::Call callOperation(J_JITOperation_EJscCJ operation, GPRReg result, GPRReg arg1, JSCell* cell, GPRReg arg2Tag, GPRReg arg2Payload)
1643 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell), EABI_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
1644 return appendCallSetResult(operation, result);
1646 JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1, const UniquedStringImpl* uid)
1648 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
1649 return appendCallSetResult(operation, resultPayload, resultTag);
1651 JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid)
1653 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, TrustedImmPtr(uid));
1654 return appendCallSetResult(operation, resultPayload, resultTag);
1656 JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, int32_t arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid)
1658 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, TrustedImm32(arg1Tag), TrustedImmPtr(uid));
1659 return appendCallSetResult(operation, resultPayload, resultTag);
1661 JITCompiler::Call callOperation(J_JITOperation_EDA operation, GPRReg resultTag, GPRReg resultPayload, FPRReg arg1, GPRReg arg2)
1663 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1, arg2);
1664 return appendCallSetResult(operation, resultPayload, resultTag);
1666 JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1668 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1669 return appendCallSetResult(operation, resultPayload, resultTag);
1671 JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, TrustedImm32 arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1673 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1674 return appendCallSetResult(operation, resultPayload, resultTag);
1676 JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload)
1678 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1679 return appendCallSetResult(operation, resultPayload, resultTag);
1681 JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1683 m_jit.setupArgumentsWithExecState(arg1);
1684 return appendCallSetResult(operation, resultPayload, resultTag);
1686 JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1)
1688 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1689 return appendCallSetResult(operation, resultPayload, resultTag);
1691 JITCompiler::Call callOperation(J_JITOperation_EZIcfZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
1693 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
1694 return appendCallSetResult(operation, resultPayload, resultTag);
1696 JITCompiler::Call callOperation(J_JITOperation_EZZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, GPRReg arg2)
1698 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
1699 return appendCallSetResult(operation, resultPayload, resultTag);
1702 JITCompiler::Call callOperation(P_JITOperation_EJS operation, GPRReg result, JSValueRegs value, size_t index)
1704 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG value.payloadGPR(), value.tagGPR(), TrustedImmPtr(index));
1705 return appendCallSetResult(operation, result);
1708 JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, Structure* structure, GPRReg arg2Tag, GPRReg arg2Payload)
1710 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2Payload, arg2Tag);
1711 return appendCallSetResult(operation, result);
1714 JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
1716 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1717 return appendCallSetResult(operation, result);
1720 JITCompiler::Call callOperation(C_JITOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
1722 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag);
1723 return appendCallSetResult(operation, result);
1726 JITCompiler::Call callOperation(C_JITOperation_EJJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
1728 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag, arg3Payload, arg3Tag);
1729 return appendCallSetResult(operation, result);
1732 JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
1734 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1735 return appendCallSetResult(operation, result);
1738 JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
1740 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
1741 return appendCallSetResult(operation, result);
1743 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
1745 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
1746 return appendCallSetResult(operation, resultPayload, resultTag);
1748 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, MacroAssembler::TrustedImm32 imm)
1750 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag));
1751 return appendCallSetResult(operation, resultPayload, resultTag);
1753 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, MacroAssembler::TrustedImm32 imm, GPRReg arg2Tag, GPRReg arg2Payload)
1755 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag), SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
1756 return appendCallSetResult(operation, resultPayload, resultTag);
1758 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2)
1760 return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1.tagGPR(), arg1.payloadGPR(), arg2.tagGPR(), arg2.payloadGPR());
1763 JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload)
1765 m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
1766 return appendCallSetResult(operation, resultPayload, resultTag);
1768 JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Payload)
1770 m_jit.setupArgumentsWithExecState(arg1, arg2Payload, MacroAssembler::TrustedImm32(JSValue::CellTag));
1771 return appendCallSetResult(operation, resultPayload, resultTag);
1773 JITCompiler::Call callOperation(J_JITOperation_ECJ operation, JSValueRegs result, GPRReg arg1, JSValueRegs arg2)
1775 m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR());
1776 return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
1778 JITCompiler::Call callOperation(J_JITOperation_ECC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1780 m_jit.setupArgumentsWithExecState(arg1, arg2);
1781 return appendCallSetResult(operation, resultPayload, resultTag);
1784 JITCompiler::Call callOperation(V_JITOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3)
1786 m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3);
1787 return appendCall(operation);
1790 JITCompiler::Call callOperation(V_JITOperation_EJ operation, GPRReg arg1Tag, GPRReg arg1Payload)
1792 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1793 return appendCall(operation);
1796 JITCompiler::Call callOperation(V_JITOperation_EJPP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, void* pointer)
1798 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(pointer));
1799 return appendCall(operation);
1801 JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Payload, UniquedStringImpl* uid)
1803 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, arg2Payload, TrustedImm32(JSValue::CellTag), TrustedImmPtr(uid));
1804 return appendCall(operation);
1806 JITCompiler::Call callOperation(V_JITOperation_ECJJ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
1808 m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, arg3Payload, arg3Tag);
1809 return appendCall(operation);
1812 JITCompiler::Call callOperation(V_JITOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
1814 m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
1815 return appendCall(operation);
1818 JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
1820 m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
1821 return appendCall(operation);
1823 JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, TrustedImm32 arg3Tag, GPRReg arg3Payload)
1825 m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
1826 return appendCall(operation);
1829 JITCompiler::Call callOperation(Z_JITOperation_EJZZ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, unsigned arg2, unsigned arg3)
1831 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImm32(arg2), TrustedImm32(arg3));
1832 return appendCallSetResult(operation, result);
1834 JITCompiler::Call callOperation(F_JITOperation_EFJZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, unsigned arg3, GPRReg arg4)
1836 m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, TrustedImm32(arg3), arg4);
1837 return appendCallSetResult(operation, result);
1839 JITCompiler::Call callOperation(Z_JITOperation_EJZ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, unsigned arg2)
1841 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImm32(arg2));
1842 return appendCallSetResult(operation, result);
1844 JITCompiler::Call callOperation(V_JITOperation_EZJZZZ operation, unsigned arg1, GPRReg arg2Tag, GPRReg arg2Payload, unsigned arg3, GPRReg arg4, unsigned arg5)
1846 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2Payload, arg2Tag, TrustedImm32(arg3), arg4, TrustedImm32(arg5));
1847 return appendCall(operation);
1849 JITCompiler::Call callOperation(V_JITOperation_ECJZC operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, int32_t arg3, GPRReg arg4)
1851 m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, TrustedImm32(arg3), arg4);
1852 return appendCall(operation);
1854 JITCompiler::Call callOperation(V_JITOperation_ECIZCC operation, GPRReg arg1, UniquedStringImpl* identOp2, int32_t op3, GPRReg arg4, GPRReg arg5)
1856 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identOp2), TrustedImm32(op3), arg4, arg5);
1857 return appendCall(operation);
1859 #undef EABI_32BIT_DUMMY_ARG
1860 #undef SH4_32BIT_DUMMY_ARG
1862 template<typename FunctionType>
1863 JITCompiler::Call callOperation(
1864 FunctionType operation, JSValueRegs result)
1866 return callOperation(operation, result.tagGPR(), result.payloadGPR());
1868 template<typename FunctionType, typename ArgumentType1>
1869 JITCompiler::Call callOperation(
1870 FunctionType operation, JSValueRegs result, ArgumentType1 arg1)
1872 return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1);
1874 template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
1875 JITCompiler::Call callOperation(
1876 FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2)
1878 return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2);
1881 typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1882 typename ArgumentType3>
1883 JITCompiler::Call callOperation(
1884 FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1887 return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3);
1890 typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1891 typename ArgumentType3, typename ArgumentType4>
1892 JITCompiler::Call callOperation(
1893 FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1894 ArgumentType3 arg3, ArgumentType4 arg4)
1896 return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4);
1899 typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1900 typename ArgumentType3, typename ArgumentType4, typename ArgumentType5>
1901 JITCompiler::Call callOperation(
1902 FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1903 ArgumentType3 arg3, ArgumentType4 arg4, ArgumentType5 arg5)
1905 return callOperation(
1906 operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4, arg5);
1908 #endif // USE(JSVALUE32_64)
1910 #if !defined(NDEBUG) && !CPU(ARM) && !CPU(MIPS) && !CPU(SH4)
1911 void prepareForExternalCall()
1913 // We're about to call out to a "native" helper function. The helper
1914 // function is expected to set topCallFrame itself with the ExecState
1915 // that is passed to it.
1917 // We explicitly trash topCallFrame here so that we'll know if some of
1918 // the helper functions are not setting topCallFrame when they should
1919 // be doing so. Note: the previous value in topcallFrame was not valid
1920 // anyway since it was not being updated by JIT'ed code by design.
1922 for (unsigned i = 0; i < sizeof(void*) / 4; i++)
1923 m_jit.store32(TrustedImm32(0xbadbeef), reinterpret_cast<char*>(&m_jit.vm()->topCallFrame) + i * 4);
1926 void prepareForExternalCall() { }
1929 // These methods add call instructions, optionally setting results, and optionally rolling back the call frame on an exception.
1930 JITCompiler::Call appendCall(const FunctionPtr& function)
1932 prepareForExternalCall();
1933 m_jit.emitStoreCodeOrigin(m_currentNode->origin.semantic);
1934 return m_jit.appendCall(function);
1936 JITCompiler::Call appendCallWithCallFrameRollbackOnException(const FunctionPtr& function)
1938 JITCompiler::Call call = appendCall(function);
1939 m_jit.exceptionCheckWithCallFrameRollback();
1942 JITCompiler::Call appendCallWithCallFrameRollbackOnExceptionSetResult(const FunctionPtr& function, GPRReg result)
1944 JITCompiler::Call call = appendCallWithCallFrameRollbackOnException(function);
1945 if ((result != InvalidGPRReg) && (result != GPRInfo::returnValueGPR))
1946 m_jit.move(GPRInfo::returnValueGPR, result);
1949 JITCompiler::Call appendCallSetResult(const FunctionPtr& function, GPRReg result)
1951 JITCompiler::Call call = appendCall(function);
1952 if (result != InvalidGPRReg)
1953 m_jit.move(GPRInfo::returnValueGPR, result);
1956 JITCompiler::Call appendCallSetResult(const FunctionPtr& function, GPRReg result1, GPRReg result2)
1958 JITCompiler::Call call = appendCall(function);
1959 m_jit.setupResults(result1, result2);
1963 JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1965 JITCompiler::Call call = appendCall(function);
1966 if (result != InvalidFPRReg) {
1967 m_jit.assembler().fstpl(0, JITCompiler::stackPointerRegister);
1968 m_jit.loadDouble(JITCompiler::stackPointerRegister, result);
1972 #elif CPU(ARM) && !CPU(ARM_HARDFP)
1973 JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1975 JITCompiler::Call call = appendCall(function);
1976 if (result != InvalidFPRReg)
1977 m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
1980 #else // CPU(X86_64) || (CPU(ARM) && CPU(ARM_HARDFP)) || CPU(ARM64) || CPU(MIPS) || CPU(SH4)
1981 JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1983 JITCompiler::Call call = appendCall(function);
1984 if (result != InvalidFPRReg)
1985 m_jit.moveDouble(FPRInfo::returnValueFPR, result);
1990 void branchDouble(JITCompiler::DoubleCondition cond, FPRReg left, FPRReg right, BasicBlock* destination)
1992 return addBranch(m_jit.branchDouble(cond, left, right), destination);
1995 void branchDoubleNonZero(FPRReg value, FPRReg scratch, BasicBlock* destination)
1997 return addBranch(m_jit.branchDoubleNonZero(value, scratch), destination);
2000 template<typename T, typename U>
2001 void branch32(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
2003 return addBranch(m_jit.branch32(cond, left, right), destination);
2006 template<typename T, typename U>
2007 void branchTest32(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
2009 return addBranch(m_jit.branchTest32(cond, value, mask), destination);
2012 template<typename T>
2013 void branchTest32(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
2015 return addBranch(m_jit.branchTest32(cond, value), destination);
2019 template<typename T, typename U>
2020 void branch64(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
2022 return addBranch(m_jit.branch64(cond, left, right), destination);
2026 template<typename T, typename U>
2027 void branch8(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
2029 return addBranch(m_jit.branch8(cond, left, right), destination);
2032 template<typename T, typename U>
2033 void branchPtr(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
2035 return addBranch(m_jit.branchPtr(cond, left, right), destination);
2038 template<typename T, typename U>
2039 void branchTestPtr(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
2041 return addBranch(m_jit.branchTestPtr(cond, value, mask), destination);
2044 template<typename T>
2045 void branchTestPtr(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
2047 return addBranch(m_jit.branchTestPtr(cond, value), destination);
2050 template<typename T, typename U>
2051 void branchTest8(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
2053 return addBranch(m_jit.branchTest8(cond, value, mask), destination);
2056 template<typename T>
2057 void branchTest8(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
2059 return addBranch(m_jit.branchTest8(cond, value), destination);
2062 enum FallThroughMode {
2066 void jump(BasicBlock* destination, FallThroughMode fallThroughMode = AtFallThroughPoint)
2068 if (destination == nextBlock()
2069 && fallThroughMode == AtFallThroughPoint)
2071 addBranch(m_jit.jump(), destination);
2074 void addBranch(const MacroAssembler::Jump& jump, BasicBlock* destination)
2076 m_branches.append(BranchRecord(jump, destination));
2078 void addBranch(const MacroAssembler::JumpList& jump, BasicBlock* destination);
2080 void linkBranches();
2082 void dump(const char* label = 0);
2084 bool betterUseStrictInt52(Node* node)
2086 return !generationInfo(node).isInt52();
2088 bool betterUseStrictInt52(Edge edge)
2090 return betterUseStrictInt52(edge.node());
2093 bool compare(Node*, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_JITOperation_EJJ);
2094 bool compilePeepHoleBranch(Node*, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_JITOperation_EJJ);
2095 void compilePeepHoleInt32Branch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
2096 void compilePeepHoleInt52Branch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
2097 void compilePeepHoleBooleanBranch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
2098 void compilePeepHoleDoubleBranch(Node*, Node* branchNode, JITCompiler::DoubleCondition);
2099 void compilePeepHoleObjectEquality(Node*, Node* branchNode);
2100 void compilePeepHoleObjectStrictEquality(Edge objectChild, Edge otherChild, Node* branchNode);
2101 void compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode);
2102 void compileObjectEquality(Node*);
2103 void compileObjectStrictEquality(Edge objectChild, Edge otherChild);
2104 void compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild);
2105 void compileObjectOrOtherLogicalNot(Edge value);
2106 void compileLogicalNot(Node*);
2107 void compileStringEquality(
2108 Node*, GPRReg leftGPR, GPRReg rightGPR, GPRReg lengthGPR,
2109 GPRReg leftTempGPR, GPRReg rightTempGPR, GPRReg leftTemp2GPR,
2110 GPRReg rightTemp2GPR, JITCompiler::JumpList fastTrue,
2111 JITCompiler::JumpList fastSlow);
2112 void compileStringEquality(Node*);
2113 void compileStringIdentEquality(Node*);
2114 void compileStringToUntypedEquality(Node*, Edge stringEdge, Edge untypedEdge);
2115 void compileStringIdentToNotStringVarEquality(Node*, Edge stringEdge, Edge notStringVarEdge);
2116 void compileStringZeroLength(Node*);
2117 void compileMiscStrictEq(Node*);
2119 template<typename Functor>
2120 void extractStringImplFromBinarySymbols(Edge leftSymbolEdge, Edge rightSymbolEdge, const Functor&);
2121 void compileSymbolEquality(Node*);
2122 void compilePeepHoleSymbolEquality(Node*, Node* branchNode);
2124 void emitObjectOrOtherBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
2125 void emitStringBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
2126 void emitBranch(Node*);
2128 struct StringSwitchCase {
2129 StringSwitchCase() { }
2131 StringSwitchCase(StringImpl* string, BasicBlock* target)
2137 bool operator<(const StringSwitchCase& other) const
2139 return stringLessThan(*string, *other.string);
2146 void emitSwitchIntJump(SwitchData*, GPRReg value, GPRReg scratch);
2147 void emitSwitchImm(Node*, SwitchData*);
2148 void emitSwitchCharStringJump(SwitchData*, GPRReg value, GPRReg scratch);
2149 void emitSwitchChar(Node*, SwitchData*);
2150 void emitBinarySwitchStringRecurse(
2151 SwitchData*, const Vector<StringSwitchCase>&, unsigned numChecked,
2152 unsigned begin, unsigned end, GPRReg buffer, GPRReg length, GPRReg temp,
2153 unsigned alreadyCheckedLength, bool checkedExactLength);
2154 void emitSwitchStringOnString(SwitchData*, GPRReg string);
2155 void emitSwitchString(Node*, SwitchData*);
2156 void emitSwitch(Node*);
2158 void compileToStringOrCallStringConstructorOnCell(Node*);
2159 void compileNewStringObject(Node*);
2161 void compileNewTypedArray(Node*);
2163 void compileInt32Compare(Node*, MacroAssembler::RelationalCondition);
2164 void compileInt52Compare(Node*, MacroAssembler::RelationalCondition);
2165 void compileBooleanCompare(Node*, MacroAssembler::RelationalCondition);
2166 void compileDoubleCompare(Node*, MacroAssembler::DoubleCondition);
2168 bool compileStrictEq(Node*);
2170 void compileAllocatePropertyStorage(Node*);
2171 void compileReallocatePropertyStorage(Node*);
2172 void compileGetButterfly(Node*);
2174 #if USE(JSVALUE32_64)
2175 template<typename BaseOperandType, typename PropertyOperandType, typename ValueOperandType, typename TagType>
2176 void compileContiguousPutByVal(Node*, BaseOperandType&, PropertyOperandType&, ValueOperandType&, GPRReg valuePayloadReg, TagType valueTag);
2178 void compileDoublePutByVal(Node*, SpeculateCellOperand& base, SpeculateStrictInt32Operand& property);
2179 bool putByValWillNeedExtraRegister(ArrayMode arrayMode)
2181 return arrayMode.mayStoreToHole();
2183 GPRReg temporaryRegisterForPutByVal(GPRTemporary&, ArrayMode);
2184 GPRReg temporaryRegisterForPutByVal(GPRTemporary& temporary, Node* node)
2186 return temporaryRegisterForPutByVal(temporary, node->arrayMode());
2189 void compileGetCharCodeAt(Node*);
2190 void compileGetByValOnString(Node*);
2191 void compileFromCharCode(Node*);
2193 void compileGetByValOnDirectArguments(Node*);
2194 void compileGetByValOnScopedArguments(Node*);
2196 void compileGetScope(Node*);
2197 void compileLoadArrowFunctionThis(Node*);
2198 void compileSkipScope(Node*);
2200 void compileGetArrayLength(Node*);
2202 void compileCheckIdent(Node*);
2204 void compileValueRep(Node*);
2205 void compileDoubleRep(Node*);
2207 void compileValueToInt32(Node*);
2208 void compileUInt32ToNumber(Node*);
2209 void compileDoubleAsInt32(Node*);
2210 void compileAdd(Node*);
2211 void compileMakeRope(Node*);
2212 void compileArithClz32(Node*);
2213 void compileArithSub(Node*);
2214 void compileArithNegate(Node*);
2215 void compileArithMul(Node*);
2216 void compileArithDiv(Node*);
2217 void compileArithMod(Node*);
2218 void compileArithPow(Node*);
2219 void compileArithRound(Node*);
2220 void compileArithSqrt(Node*);
2221 void compileArithLog(Node*);
2222 void compileConstantStoragePointer(Node*);
2223 void compileGetIndexedPropertyStorage(Node*);
2224 JITCompiler::Jump jumpForTypedArrayOutOfBounds(Node*, GPRReg baseGPR, GPRReg indexGPR);
2225 void emitTypedArrayBoundsCheck(Node*, GPRReg baseGPR, GPRReg indexGPR);
2226 void compileGetTypedArrayByteOffset(Node*);
2227 void compileGetByValOnIntTypedArray(Node*, TypedArrayType);
2228 void compilePutByValForIntTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
2229 void compileGetByValOnFloatTypedArray(Node*, TypedArrayType);
2230 void compilePutByValForFloatTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
2231 template <typename ClassType> void compileNewFunctionCommon(GPRReg, Structure*, GPRReg, GPRReg, GPRReg, MacroAssembler::JumpList&, size_t, FunctionExecutable*, ptrdiff_t, ptrdiff_t, ptrdiff_t);
2232 void compileNewFunction(Node*);
2233 void compileForwardVarargs(Node*);
2234 void compileCreateActivation(Node*);
2235 void compileCreateDirectArguments(Node*);
2236 void compileGetFromArguments(Node*);
2237 void compilePutToArguments(Node*);
2238 void compileCreateScopedArguments(Node*);
2239 void compileCreateClonedArguments(Node*);
2240 void compileNotifyWrite(Node*);
2241 bool compileRegExpExec(Node*);
2242 void compileIsObjectOrNull(Node*);
2243 void compileIsFunction(Node*);
2244 void compileTypeOf(Node*);
2245 void compileCheckStructure(Node*, GPRReg cellGPR, GPRReg tempGPR);
2246 void compileCheckStructure(Node*);
2247 void compilePutAccessorById(Node*);
2248 void compilePutGetterSetterById(Node*);
2249 void compilePutAccessorByVal(Node*);
2251 void moveTrueTo(GPRReg);
2252 void moveFalseTo(GPRReg);
2253 void blessBoolean(GPRReg);
2255 // size can be an immediate or a register, and must be in bytes. If size is a register,
2256 // it must be a different register than resultGPR. Emits code that place a pointer to
2257 // the end of the allocation. The returned jump is the jump to the slow path.
2258 template<typename SizeType>
2259 MacroAssembler::Jump emitAllocateBasicStorage(SizeType size, GPRReg resultGPR)
2261 CopiedAllocator* copiedAllocator = &m_jit.vm()->heap.storageAllocator();
2263 // It's invalid to allocate zero bytes in CopiedSpace.
2265 m_jit.move(size, resultGPR);
2266 MacroAssembler::Jump nonZeroSize = m_jit.branchTest32(MacroAssembler::NonZero, resultGPR);
2267 m_jit.abortWithReason(DFGBasicStorageAllocatorZeroSize);
2268 nonZeroSize.link(&m_jit);
2271 m_jit.loadPtr(&copiedAllocator->m_currentRemaining, resultGPR);
2272 MacroAssembler::Jump slowPath = m_jit.branchSubPtr(JITCompiler::Signed, size, resultGPR);
2273 m_jit.storePtr(resultGPR, &copiedAllocator->m_currentRemaining);
2274 m_jit.negPtr(resultGPR);
2275 m_jit.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), resultGPR);
2280 // Allocator for a cell of a specific size.
2281 template <typename StructureType> // StructureType can be GPR or ImmPtr.
2282 void emitAllocateJSCell(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure,
2283 GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
2285 m_jit.loadPtr(MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()), resultGPR);
2286 slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR));
2288 // The object is half-allocated: we have what we know is a fresh object, but
2289 // it's still on the GC's free list.
2290 m_jit.loadPtr(MacroAssembler::Address(resultGPR), scratchGPR);
2291 m_jit.storePtr(scratchGPR, MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()));
2293 // Initialize the object's Structure.
2294 m_jit.emitStoreStructureWithTypeInfo(structure, resultGPR, scratchGPR);
2297 // Allocator for an object of a specific size.
2298 template <typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
2299 void emitAllocateJSObject(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure,
2300 StorageType storage, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
2302 emitAllocateJSCell(resultGPR, allocatorGPR, structure, scratchGPR, slowPath);
2304 // Initialize the object's property storage pointer.
2305 m_jit.storePtr(storage, MacroAssembler::Address(resultGPR, JSObject::butterflyOffset()));
2308 template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
2309 void emitAllocateJSObjectWithKnownSize(
2310 GPRReg resultGPR, StructureType structure, StorageType storage, GPRReg scratchGPR1,
2311 GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath, size_t size)
2313 MarkedAllocator* allocator = &m_jit.vm()->heap.allocatorForObjectOfType<ClassType>(size);
2314 m_jit.move(TrustedImmPtr(allocator), scratchGPR1);
2315 emitAllocateJSObject(resultGPR, scratchGPR1, structure, storage, scratchGPR2, slowPath);
2318 // Convenience allocator for a built-in object.
2319 template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
2320 void emitAllocateJSObject(GPRReg resultGPR, StructureType structure, StorageType storage,
2321 GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
2323 emitAllocateJSObjectWithKnownSize<ClassType>(
2324 resultGPR, structure, storage, scratchGPR1, scratchGPR2, slowPath,
2325 ClassType::allocationSize(0));
2328 template <typename ClassType, typename StructureType> // StructureType and StorageType can be GPR or ImmPtr.
2329 void emitAllocateVariableSizedJSObject(GPRReg resultGPR, StructureType structure, GPRReg allocationSize, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
2331 static_assert(!(MarkedSpace::preciseStep & (MarkedSpace::preciseStep - 1)), "MarkedSpace::preciseStep must be a power of two.");
2332 static_assert(!(MarkedSpace::impreciseStep & (MarkedSpace::impreciseStep - 1)), "MarkedSpace::impreciseStep must be a power of two.");
2334 MarkedSpace::Subspace& subspace = m_jit.vm()->heap.subspaceForObjectOfType<ClassType>();
2335 m_jit.add32(TrustedImm32(MarkedSpace::preciseStep - 1), allocationSize);
2336 MacroAssembler::Jump notSmall = m_jit.branch32(MacroAssembler::AboveOrEqual, allocationSize, TrustedImm32(MarkedSpace::preciseCutoff));
2337 m_jit.rshift32(allocationSize, TrustedImm32(getLSBSet(MarkedSpace::preciseStep)), scratchGPR1);
2338 m_jit.mul32(TrustedImm32(sizeof(MarkedAllocator)), scratchGPR1, scratchGPR1);
2339 m_jit.addPtr(MacroAssembler::TrustedImmPtr(&subspace.preciseAllocators[0]), scratchGPR1);
2341 MacroAssembler::Jump selectedSmallSpace = m_jit.jump();
2342 notSmall.link(&m_jit);
2343 slowPath.append(m_jit.branch32(MacroAssembler::AboveOrEqual, allocationSize, TrustedImm32(MarkedSpace::impreciseCutoff)));
2344 m_jit.rshift32(allocationSize, TrustedImm32(getLSBSet(MarkedSpace::impreciseStep)), scratchGPR1);
2345 m_jit.mul32(TrustedImm32(sizeof(MarkedAllocator)), scratchGPR1, scratchGPR1);
2346 m_jit.addPtr(MacroAssembler::TrustedImmPtr(&subspace.impreciseAllocators[0]), scratchGPR1);
2348 selectedSmallSpace.link(&m_jit);
2350 emitAllocateJSObject(resultGPR, scratchGPR1, structure, TrustedImmPtr(0), scratchGPR2, slowPath);
2353 template <typename T>
2354 void emitAllocateDestructibleObject(GPRReg resultGPR, Structure* structure,
2355 GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
2357 emitAllocateJSObject<T>(resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR1, scratchGPR2, slowPath);
2358 m_jit.storePtr(TrustedImmPtr(structure->classInfo()), MacroAssembler::Address(resultGPR, JSDestructibleObject::classInfoOffset()));
2361 void emitAllocateJSArray(GPRReg resultGPR, Structure*, GPRReg storageGPR, unsigned numElements);
2363 void emitGetLength(InlineCallFrame*, GPRReg lengthGPR, bool includeThis = false);
2364 void emitGetLength(CodeOrigin, GPRReg lengthGPR, bool includeThis = false);
2365 void emitGetCallee(CodeOrigin, GPRReg calleeGPR);
2366 void emitGetArgumentStart(CodeOrigin, GPRReg startGPR);
2368 // Generate an OSR exit fuzz check. Returns Jump() if OSR exit fuzz is not enabled, or if
2369 // it's in training mode.
2370 MacroAssembler::Jump emitOSRExitFuzzCheck();
2372 // Add a speculation check.
2373 void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);
2374 void speculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail);
2376 // Add a speculation check without additional recovery, and with a promise to supply a jump later.
2377 OSRExitJumpPlaceholder speculationCheck(ExitKind, JSValueSource, Node*);
2378 OSRExitJumpPlaceholder speculationCheck(ExitKind, JSValueSource, Edge);
2379 void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail);
2380 void speculationCheck(ExitKind, JSValueSource, Edge, const MacroAssembler::JumpList& jumpsToFail);
2381 // Add a speculation check with additional recovery.
2382 void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
2383 void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
2385 void emitInvalidationPoint(Node*);
2387 // Called when we statically determine that a speculation will fail.
2388 void terminateSpeculativeExecution(ExitKind, JSValueRegs, Node*);
2389 void terminateSpeculativeExecution(ExitKind, JSValueRegs, Edge);
2391 // Helpers for performing type checks on an edge stored in the given registers.
2392 bool needsTypeCheck(Edge edge, SpeculatedType typesPassedThrough) { return m_interpreter.needsTypeCheck(edge, typesPassedThrough); }
2393 void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
2395 void speculateCellTypeWithoutTypeFiltering(Edge, GPRReg cellGPR, JSType);
2396 void speculateCellType(Edge, GPRReg cellGPR, SpeculatedType, JSType);
2398 void speculateInt32(Edge);
2400 void convertMachineInt(Edge, GPRReg resultGPR);
2401 void speculateMachineInt(Edge);
2402 void speculateDoubleRepMachineInt(Edge);
2403 #endif // USE(JSVALUE64)
2404 void speculateNumber(Edge);
2405 void speculateRealNumber(Edge);
2406 void speculateDoubleRepReal(Edge);
2407 void speculateBoolean(Edge);
2408 void speculateCell(Edge);
2409 void speculateCellOrOther(Edge);
2410 void speculateObject(Edge);
2411 void speculateFunction(Edge);
2412 void speculateFinalObject(Edge);
2413 void speculateObjectOrOther(Edge);
2414 void speculateString(Edge edge, GPRReg cell);
2415 void speculateStringIdentAndLoadStorage(Edge edge, GPRReg string, GPRReg storage);
2416 void speculateStringIdent(Edge edge, GPRReg string);
2417 void speculateStringIdent(Edge);
2418 void speculateString(Edge);
2419 void speculateNotStringVar(Edge);
2420 template<typename StructureLocationType>
2421 void speculateStringObjectForStructure(Edge, StructureLocationType);
2422 void speculateStringObject(Edge, GPRReg);
2423 void speculateStringObject(Edge);
2424 void speculateStringOrStringObject(Edge);
2425 void speculateSymbol(Edge, GPRReg cell);
2426 void speculateSymbol(Edge);
2427 void speculateNotCell(Edge);
2428 void speculateOther(Edge);
2429 void speculateMisc(Edge, JSValueRegs);
2430 void speculateMisc(Edge);
2431 void speculate(Node*, Edge);
2433 JITCompiler::Jump jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode, IndexingType);
2434 JITCompiler::JumpList jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode);
2435 void checkArray(Node*);
2436 void arrayify(Node*, GPRReg baseReg, GPRReg propertyReg);
2437 void arrayify(Node*);
2439 template<bool strict>
2440 GPRReg fillSpeculateInt32Internal(Edge, DataFormat& returnFormat);
2442 // It is possible, during speculative generation, to reach a situation in which we
2443 // can statically determine a speculation will fail (for example, when two nodes
2444 // will make conflicting speculations about the same operand). In such cases this
2445 // flag is cleared, indicating no further code generation should take place.
2448 void recordSetLocal(
2449 VirtualRegister bytecodeReg, VirtualRegister machineReg, DataFormat format)
2451 m_stream->appendAndLog(VariableEvent::setLocal(bytecodeReg, machineReg, format));
2454 void recordSetLocal(DataFormat format)
2456 VariableAccessData* variable = m_currentNode->variableAccessData();
2457 recordSetLocal(variable->local(), variable->machineLocal(), format);
2460 GenerationInfo& generationInfoFromVirtualRegister(VirtualRegister virtualRegister)
2462 return m_generationInfo[virtualRegister.toLocal()];
2465 GenerationInfo& generationInfo(Node* node)
2467 return generationInfoFromVirtualRegister(node->virtualRegister());
2470 GenerationInfo& generationInfo(Edge edge)
2472 return generationInfo(edge.node());
2475 // The JIT, while also provides MacroAssembler functionality.
2478 // The current node being generated.
2479 BasicBlock* m_block;
2480 Node* m_currentNode;
2481 NodeType m_lastGeneratedNode;
2482 unsigned m_indexInBlock;
2483 // Virtual and physical register maps.
2484 Vector<GenerationInfo, 32> m_generationInfo;
2485 RegisterBank<GPRInfo> m_gprs;
2486 RegisterBank<FPRInfo> m_fprs;
2488 Vector<MacroAssembler::Label> m_osrEntryHeads;
2490 struct BranchRecord {
2491 BranchRecord(MacroAssembler::Jump jump, BasicBlock* destination)
2493 , destination(destination)
2497 MacroAssembler::Jump jump;
2498 BasicBlock* destination;
2500 Vector<BranchRecord, 8> m_branches;
2502 NodeOrigin m_origin;
2504 InPlaceAbstractState m_state;
2505 AbstractInterpreter<InPlaceAbstractState> m_interpreter;
2507 VariableEventStream* m_stream;
2508 MinifiedGraph* m_minifiedGraph;
2510 Vector<std::unique_ptr<SlowPathGenerator>, 8> m_slowPathGenerators;
2511 Vector<SilentRegisterSavePlan> m_plans;
2512 unsigned m_outOfLineStreamIndex { UINT_MAX };
2516 // === Operand types ===
2518 // These classes are used to lock the operands to a node into machine
2519 // registers. These classes implement of pattern of locking a value
2520 // into register at the point of construction only if it is already in
2521 // registers, and otherwise loading it lazily at the point it is first
2522 // used. We do so in order to attempt to avoid spilling one operand
2523 // in order to make space available for another.
2525 class JSValueOperand {
2527 explicit JSValueOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2531 , m_gprOrInvalid(InvalidGPRReg)
2532 #elif USE(JSVALUE32_64)
2539 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
2541 if (jit->isFilled(node()))
2543 #elif USE(JSVALUE32_64)
2544 m_register.pair.tagGPR = InvalidGPRReg;
2545 m_register.pair.payloadGPR = InvalidGPRReg;
2546 if (jit->isFilled(node()))
2556 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2557 m_jit->unlock(m_gprOrInvalid);
2558 #elif USE(JSVALUE32_64)
2560 ASSERT(m_register.fpr != InvalidFPRReg);
2561 m_jit->unlock(m_register.fpr);
2563 ASSERT(m_register.pair.tagGPR != InvalidGPRReg && m_register.pair.payloadGPR != InvalidGPRReg);
2564 m_jit->unlock(m_register.pair.tagGPR);
2565 m_jit->unlock(m_register.pair.payloadGPR);
2577 return edge().node();
2583 if (m_gprOrInvalid == InvalidGPRReg)
2584 m_gprOrInvalid = m_jit->fillJSValue(m_edge);
2585 return m_gprOrInvalid;
2587 JSValueRegs jsValueRegs()
2589 return JSValueRegs(gpr());
2591 #elif USE(JSVALUE32_64)
2592 bool isDouble() { return m_isDouble; }
2596 if (m_register.pair.tagGPR == InvalidGPRReg && m_register.pair.payloadGPR == InvalidGPRReg)
2597 m_isDouble = !m_jit->fillJSValue(m_edge, m_register.pair.tagGPR, m_register.pair.payloadGPR, m_register.fpr);
2603 ASSERT(!m_isDouble);
2604 return m_register.pair.tagGPR;
2610 ASSERT(!m_isDouble);
2611 return m_register.pair.payloadGPR;
2614 JSValueRegs jsValueRegs()
2616 return JSValueRegs(tagGPR(), payloadGPR());
2619 GPRReg gpr(WhichValueWord which)
2621 return jsValueRegs().gpr(which);
2628 return m_register.fpr;
2638 SpeculativeJIT* m_jit;
2641 GPRReg m_gprOrInvalid;
2642 #elif USE(JSVALUE32_64)
2654 class StorageOperand {
2656 explicit StorageOperand(SpeculativeJIT* jit, Edge edge)
2659 , m_gprOrInvalid(InvalidGPRReg)
2662 ASSERT(edge.useKind() == UntypedUse || edge.useKind() == KnownCellUse);
2663 if (jit->isFilled(node()))
2669 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2670 m_jit->unlock(m_gprOrInvalid);
2680 return edge().node();
2685 if (m_gprOrInvalid == InvalidGPRReg)
2686 m_gprOrInvalid = m_jit->fillStorage(edge());
2687 return m_gprOrInvalid;
2696 SpeculativeJIT* m_jit;
2698 GPRReg m_gprOrInvalid;
2702 // === Temporaries ===
2704 // These classes are used to allocate temporary registers.
2705 // A mechanism is provided to attempt to reuse the registers
2706 // currently allocated to child nodes whose value is consumed
2707 // by, and not live after, this operation.
2709 enum ReuseTag { Reuse };
2711 class GPRTemporary {
2714 GPRTemporary(SpeculativeJIT*);
2715 GPRTemporary(SpeculativeJIT*, GPRReg specific);
2716 template<typename T>
2717 GPRTemporary(SpeculativeJIT* jit, ReuseTag, T& operand)
2719 , m_gpr(InvalidGPRReg)
2721 if (m_jit->canReuse(operand.node()))
2722 m_gpr = m_jit->reuse(operand.gpr());
2724 m_gpr = m_jit->allocate();
2726 template<typename T1, typename T2>
2727 GPRTemporary(SpeculativeJIT* jit, ReuseTag, T1& op1, T2& op2)
2729 , m_gpr(InvalidGPRReg)
2731 if (m_jit->canReuse(op1.node()))
2732 m_gpr = m_jit->reuse(op1.gpr());
2733 else if (m_jit->canReuse(op2.node()))
2734 m_gpr = m_jit->reuse(op2.gpr());
2735 else if (m_jit->canReuse(op1.node(), op2.node()) && op1.gpr() == op2.gpr())
2736 m_gpr = m_jit->reuse(op1.gpr());
2738 m_gpr = m_jit->allocate();
2740 #if USE(JSVALUE32_64)
2741 GPRTemporary(SpeculativeJIT*, ReuseTag, JSValueOperand&, WhichValueWord);
2744 void adopt(GPRTemporary&);
2748 if (m_jit && m_gpr != InvalidGPRReg)
2749 m_jit->unlock(gpr());
2758 SpeculativeJIT* m_jit;
2762 class JSValueRegsTemporary {
2764 JSValueRegsTemporary();
2765 JSValueRegsTemporary(SpeculativeJIT*);
2766 ~JSValueRegsTemporary();
2774 GPRTemporary m_payloadGPR;
2775 GPRTemporary m_tagGPR;
2779 class FPRTemporary {
2781 FPRTemporary(SpeculativeJIT*);
2782 FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&);
2783 FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&, SpeculateDoubleOperand&);
2784 #if USE(JSVALUE32_64)
2785 FPRTemporary(SpeculativeJIT*, JSValueOperand&);
2790 m_jit->unlock(fpr());
2795 ASSERT(m_fpr != InvalidFPRReg);
2800 FPRTemporary(SpeculativeJIT* jit, FPRReg lockedFPR)
2807 SpeculativeJIT* m_jit;
2814 // These classes lock the result of a call to a C++ helper function.
2816 class GPRFlushedCallResult : public GPRTemporary {
2818 GPRFlushedCallResult(SpeculativeJIT* jit)
2819 : GPRTemporary(jit, GPRInfo::returnValueGPR)
2824 #if USE(JSVALUE32_64)
2825 class GPRFlushedCallResult2 : public GPRTemporary {
2827 GPRFlushedCallResult2(SpeculativeJIT* jit)
2828 : GPRTemporary(jit, GPRInfo::returnValueGPR2)
2834 class FPRResult : public FPRTemporary {
2836 FPRResult(SpeculativeJIT* jit)
2837 : FPRTemporary(jit, lockedResult(jit))
2842 static FPRReg lockedResult(SpeculativeJIT* jit)
2844 jit->lock(FPRInfo::returnValueFPR);
2845 return FPRInfo::returnValueFPR;
2850 // === Speculative Operand types ===
2852 // SpeculateInt32Operand, SpeculateStrictInt32Operand and SpeculateCellOperand.
2854 // These are used to lock the operands to a node into machine registers within the
2855 // SpeculativeJIT. The classes operate like those above, however these will
2856 // perform a speculative check for a more restrictive type than we can statically
2857 // determine the operand to have. If the operand does not have the requested type,
2858 // a bail-out to the non-speculative path will be taken.
2860 class SpeculateInt32Operand {
2862 explicit SpeculateInt32Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2865 , m_gprOrInvalid(InvalidGPRReg)
2867 , m_format(DataFormatNone)
2871 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
2872 if (jit->isFilled(node()))
2876 ~SpeculateInt32Operand()
2878 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2879 m_jit->unlock(m_gprOrInvalid);
2889 return edge().node();
2894 gpr(); // m_format is set when m_gpr is locked.
2895 ASSERT(m_format == DataFormatInt32 || m_format == DataFormatJSInt32);
2901 if (m_gprOrInvalid == InvalidGPRReg)
2902 m_gprOrInvalid = m_jit->fillSpeculateInt32(edge(), m_format);
2903 return m_gprOrInvalid;
2912 SpeculativeJIT* m_jit;
2914 GPRReg m_gprOrInvalid;
2915 DataFormat m_format;
2918 class SpeculateStrictInt32Operand {
2920 explicit SpeculateStrictInt32Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2923 , m_gprOrInvalid(InvalidGPRReg)
2926 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
2927 if (jit->isFilled(node()))
2931 ~SpeculateStrictInt32Operand()
2933 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2934 m_jit->unlock(m_gprOrInvalid);
2944 return edge().node();
2949 if (m_gprOrInvalid == InvalidGPRReg)
2950 m_gprOrInvalid = m_jit->fillSpeculateInt32Strict(edge());
2951 return m_gprOrInvalid;
2960 SpeculativeJIT* m_jit;
2962 GPRReg m_gprOrInvalid;
2965 // Gives you a canonical Int52 (i.e. it's left-shifted by 16, low bits zero).
2966 class SpeculateInt52Operand {
2968 explicit SpeculateInt52Operand(SpeculativeJIT* jit, Edge edge)
2971 , m_gprOrInvalid(InvalidGPRReg)
2973 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
2974 if (jit->isFilled(node()))
2978 ~SpeculateInt52Operand()
2980 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2981 m_jit->unlock(m_gprOrInvalid);
2991 return edge().node();
2996 if (m_gprOrInvalid == InvalidGPRReg)
2997 m_gprOrInvalid = m_jit->fillSpeculateInt52(edge(), DataFormatInt52);
2998 return m_gprOrInvalid;
3007 SpeculativeJIT* m_jit;
3009 GPRReg m_gprOrInvalid;
3012 // Gives you a strict Int52 (i.e. the payload is in the low 48 bits, high 16 bits are sign-extended).
3013 class SpeculateStrictInt52Operand {
3015 explicit SpeculateStrictInt52Operand(SpeculativeJIT* jit, Edge edge)
3018 , m_gprOrInvalid(InvalidGPRReg)
3020 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
3021 if (jit->isFilled(node()))
3025 ~SpeculateStrictInt52Operand()
3027 ASSERT(m_gprOrInvalid != InvalidGPRReg);
3028 m_jit->unlock(m_gprOrInvalid);
3038 return edge().node();
3043 if (m_gprOrInvalid == InvalidGPRReg)
3044 m_gprOrInvalid = m_jit->fillSpeculateInt52(edge(), DataFormatStrictInt52);
3045 return m_gprOrInvalid;
3054 SpeculativeJIT* m_jit;
3056 GPRReg m_gprOrInvalid;
3059 enum OppositeShiftTag { OppositeShift };
3061 class SpeculateWhicheverInt52Operand {
3063 explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge)
3066 , m_gprOrInvalid(InvalidGPRReg)
3067 , m_strict(jit->betterUseStrictInt52(edge))
3069 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
3070 if (jit->isFilled(node()))
3074 explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, const SpeculateWhicheverInt52Operand& other)
3077 , m_gprOrInvalid(InvalidGPRReg)
3078 , m_strict(other.m_strict)
3080 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
3081 if (jit->isFilled(node()))
3085 explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, OppositeShiftTag, const SpeculateWhicheverInt52Operand& other)
3088 , m_gprOrInvalid(InvalidGPRReg)
3089 , m_strict(!other.m_strict)
3091 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
3092 if (jit->isFilled(node()))
3096 ~SpeculateWhicheverInt52Operand()
3098 ASSERT(m_gprOrInvalid != InvalidGPRReg);
3099 m_jit->unlock(m_gprOrInvalid);
3109 return edge().node();
3114 if (m_gprOrInvalid == InvalidGPRReg) {
3115 m_gprOrInvalid = m_jit->fillSpeculateInt52(
3116 edge(), m_strict ? DataFormatStrictInt52 : DataFormatInt52);
3118 return m_gprOrInvalid;
3126 DataFormat format() const
3128 return m_strict ? DataFormatStrictInt52 : DataFormatInt52;
3132 SpeculativeJIT* m_jit;
3134 GPRReg m_gprOrInvalid;
3138 class SpeculateDoubleOperand {
3140 explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge edge)
3143 , m_fprOrInvalid(InvalidFPRReg)
3146 RELEASE_ASSERT(isDouble(edge.useKind()));
3147 if (jit->isFilled(node()))
3151 ~SpeculateDoubleOperand()
3153 ASSERT(m_fprOrInvalid != InvalidFPRReg);
3154 m_jit->unlock(m_fprOrInvalid);
3164 return edge().node();
3169 if (m_fprOrInvalid == InvalidFPRReg)
3170 m_fprOrInvalid = m_jit->fillSpeculateDouble(edge());
3171 return m_fprOrInvalid;
3180 SpeculativeJIT* m_jit;
3182 FPRReg m_fprOrInvalid;
3185 class SpeculateCellOperand {
3187 explicit SpeculateCellOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
3190 , m_gprOrInvalid(InvalidGPRReg)
3195 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isCell(edge.useKind()));
3196 if (jit->isFilled(node()))
3200 ~SpeculateCellOperand()
3204 ASSERT(m_gprOrInvalid != InvalidGPRReg);
3205 m_jit->unlock(m_gprOrInvalid);
3215 return edge().node();
3221 if (m_gprOrInvalid == InvalidGPRReg)
3222 m_gprOrInvalid = m_jit->fillSpeculateCell(edge());
3223 return m_gprOrInvalid;
3233 SpeculativeJIT* m_jit;
3235 GPRReg m_gprOrInvalid;
3238 class SpeculateBooleanOperand {
3240 explicit SpeculateBooleanOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
3243 , m_gprOrInvalid(InvalidGPRReg)
3246 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse || edge.useKind() == KnownBooleanUse);
3247 if (jit->isFilled(node()))
3251 ~SpeculateBooleanOperand()
3253 ASSERT(m_gprOrInvalid != InvalidGPRReg);
3254 m_jit->unlock(m_gprOrInvalid);
3264 return edge().node();
3269 if (m_gprOrInvalid == InvalidGPRReg)
3270 m_gprOrInvalid = m_jit->fillSpeculateBoolean(edge());
3271 return m_gprOrInvalid;
3280 SpeculativeJIT* m_jit;
3282 GPRReg m_gprOrInvalid;
3285 template<typename StructureLocationType>
3286 void SpeculativeJIT::speculateStringObjectForStructure(Edge edge, StructureLocationType structureLocation)
3288 Structure* stringObjectStructure =
3289 m_jit.globalObjectFor(m_currentNode->origin.semantic)->stringObjectStructure();
3291 if (!m_state.forNode(edge).m_structure.isSubsetOf(StructureSet(stringObjectStructure))) {
3293 NotStringObject, JSValueRegs(), 0,
3294 m_jit.branchStructure(
3295 JITCompiler::NotEqual, structureLocation, stringObjectStructure));
3299 #define DFG_TYPE_CHECK(source, edge, typesPassedThrough, jumpToFail) do { \
3300 JSValueSource _dtc_source = (source); \
3301 Edge _dtc_edge = (edge); \
3302 SpeculatedType _dtc_typesPassedThrough = typesPassedThrough; \
3303 if (!needsTypeCheck(_dtc_edge, _dtc_typesPassedThrough)) \
3305 typeCheck(_dtc_source, _dtc_edge, _dtc_typesPassedThrough, (jumpToFail)); \
3308 } } // namespace JSC::DFG