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
).canReuse();
167 bool canReuse(Edge nodeUse
)
169 return canReuse(nodeUse
.node());
171 GPRReg
reuse(GPRReg reg
)
176 FPRReg
reuse(FPRReg reg
)
182 // Allocate a gpr/fpr.
185 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
186 m_jit
.addRegisterAllocationAtOffset(m_jit
.debugOffset());
188 VirtualRegister spillMe
;
189 GPRReg gpr
= m_gprs
.allocate(spillMe
);
190 if (spillMe
.isValid()) {
191 #if USE(JSVALUE32_64)
192 GenerationInfo
& info
= generationInfoFromVirtualRegister(spillMe
);
193 if ((info
.registerFormat() & DataFormatJS
))
194 m_gprs
.release(info
.tagGPR() == gpr
? info
.payloadGPR() : info
.tagGPR());
200 GPRReg
allocate(GPRReg specific
)
202 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
203 m_jit
.addRegisterAllocationAtOffset(m_jit
.debugOffset());
205 VirtualRegister spillMe
= m_gprs
.allocateSpecific(specific
);
206 if (spillMe
.isValid()) {
207 #if USE(JSVALUE32_64)
208 GenerationInfo
& info
= generationInfoFromVirtualRegister(spillMe
);
209 RELEASE_ASSERT(info
.registerFormat() != DataFormatJSDouble
);
210 if ((info
.registerFormat() & DataFormatJS
))
211 m_gprs
.release(info
.tagGPR() == specific
? info
.payloadGPR() : info
.tagGPR());
219 return m_gprs
.tryAllocate();
223 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
224 m_jit
.addRegisterAllocationAtOffset(m_jit
.debugOffset());
226 VirtualRegister spillMe
;
227 FPRReg fpr
= m_fprs
.allocate(spillMe
);
228 if (spillMe
.isValid())
233 // Check whether a VirtualRegsiter is currently in a machine register.
234 // We use this when filling operands to fill those that are already in
235 // machine registers first (by locking VirtualRegsiters that are already
236 // in machine register before filling those that are not we attempt to
237 // avoid spilling values we will need immediately).
238 bool isFilled(Node
* node
)
240 return generationInfo(node
).registerFormat() != DataFormatNone
;
242 bool isFilledDouble(Node
* node
)
244 return generationInfo(node
).registerFormat() == DataFormatDouble
;
247 // Called on an operand once it has been consumed by a parent node.
250 if (!node
->hasResult())
252 GenerationInfo
& info
= generationInfo(node
);
254 // use() returns true when the value becomes dead, and any
255 // associated resources may be freed.
256 if (!info
.use(*m_stream
))
259 // Release the associated machine registers.
260 DataFormat registerFormat
= info
.registerFormat();
262 if (registerFormat
== DataFormatDouble
)
263 m_fprs
.release(info
.fpr());
264 else if (registerFormat
!= DataFormatNone
)
265 m_gprs
.release(info
.gpr());
266 #elif USE(JSVALUE32_64)
267 if (registerFormat
== DataFormatDouble
)
268 m_fprs
.release(info
.fpr());
269 else if (registerFormat
& DataFormatJS
) {
270 m_gprs
.release(info
.tagGPR());
271 m_gprs
.release(info
.payloadGPR());
272 } else if (registerFormat
!= DataFormatNone
)
273 m_gprs
.release(info
.gpr());
276 void use(Edge nodeUse
)
281 RegisterSet
usedRegisters();
283 bool masqueradesAsUndefinedWatchpointIsStillValid(const CodeOrigin
& codeOrigin
)
285 return m_jit
.graph().masqueradesAsUndefinedWatchpointIsStillValid(codeOrigin
);
287 bool masqueradesAsUndefinedWatchpointIsStillValid()
289 return masqueradesAsUndefinedWatchpointIsStillValid(m_currentNode
->origin
.semantic
);
293 void storeToWriteBarrierBuffer(GPRReg cell
, GPRReg scratch1
, GPRReg scratch2
);
295 void writeBarrier(GPRReg owner
, GPRReg scratch1
, GPRReg scratch2
);
297 void writeBarrier(GPRReg owner
, GPRReg value
, Edge valueUse
, GPRReg scratch1
, GPRReg scratch2
);
299 void compileStoreBarrier(Node
*);
301 static GPRReg
selectScratchGPR(GPRReg preserve1
= InvalidGPRReg
, GPRReg preserve2
= InvalidGPRReg
, GPRReg preserve3
= InvalidGPRReg
, GPRReg preserve4
= InvalidGPRReg
)
303 return AssemblyHelpers::selectScratchGPR(preserve1
, preserve2
, preserve3
, preserve4
);
306 // Called by the speculative operand types, below, to fill operand to
307 // machine registers, implicitly generating speculation checks as needed.
308 GPRReg
fillSpeculateInt32(Edge
, DataFormat
& returnFormat
);
309 GPRReg
fillSpeculateInt32Strict(Edge
);
310 GPRReg
fillSpeculateInt52(Edge
, DataFormat desiredFormat
);
311 FPRReg
fillSpeculateDouble(Edge
);
312 GPRReg
fillSpeculateCell(Edge
);
313 GPRReg
fillSpeculateBoolean(Edge
);
314 GeneratedOperandType
checkGeneratedTypeForToInt32(Node
*);
316 void addSlowPathGenerator(std::unique_ptr
<SlowPathGenerator
>);
317 void runSlowPathGenerators();
320 void noticeOSRBirth(Node
*);
321 void bail(AbortReason
);
322 void compileCurrentBlock();
324 void checkArgumentTypes();
326 void clearGenerationInfo();
328 // These methods are used when generating 'unexpected'
329 // calls out from JIT code to C++ helper routines -
330 // they spill all live values to the appropriate
331 // slots in the JSStack without changing any state
332 // in the GenerationInfo.
333 SilentRegisterSavePlan
silentSavePlanForGPR(VirtualRegister spillMe
, GPRReg source
);
334 SilentRegisterSavePlan
silentSavePlanForFPR(VirtualRegister spillMe
, FPRReg source
);
335 void silentSpill(const SilentRegisterSavePlan
&);
336 void silentFill(const SilentRegisterSavePlan
&, GPRReg canTrample
);
338 template<typename CollectionType
>
339 void silentSpillAllRegistersImpl(bool doSpill
, CollectionType
& plans
, GPRReg exclude
, GPRReg exclude2
= InvalidGPRReg
, FPRReg fprExclude
= InvalidFPRReg
)
341 ASSERT(plans
.isEmpty());
342 for (gpr_iterator iter
= m_gprs
.begin(); iter
!= m_gprs
.end(); ++iter
) {
343 GPRReg gpr
= iter
.regID();
344 if (iter
.name().isValid() && gpr
!= exclude
&& gpr
!= exclude2
) {
345 SilentRegisterSavePlan plan
= silentSavePlanForGPR(iter
.name(), gpr
);
351 for (fpr_iterator iter
= m_fprs
.begin(); iter
!= m_fprs
.end(); ++iter
) {
352 if (iter
.name().isValid() && iter
.regID() != fprExclude
) {
353 SilentRegisterSavePlan plan
= silentSavePlanForFPR(iter
.name(), iter
.regID());
360 template<typename CollectionType
>
361 void silentSpillAllRegistersImpl(bool doSpill
, CollectionType
& plans
, NoResultTag
)
363 silentSpillAllRegistersImpl(doSpill
, plans
, InvalidGPRReg
, InvalidGPRReg
, InvalidFPRReg
);
365 template<typename CollectionType
>
366 void silentSpillAllRegistersImpl(bool doSpill
, CollectionType
& plans
, FPRReg exclude
)
368 silentSpillAllRegistersImpl(doSpill
, plans
, InvalidGPRReg
, InvalidGPRReg
, exclude
);
370 #if USE(JSVALUE32_64)
371 template<typename CollectionType
>
372 void silentSpillAllRegistersImpl(bool doSpill
, CollectionType
& plans
, JSValueRegs exclude
)
374 silentSpillAllRegistersImpl(doSpill
, plans
, exclude
.tagGPR(), exclude
.payloadGPR());
378 void silentSpillAllRegisters(GPRReg exclude
, GPRReg exclude2
= InvalidGPRReg
, FPRReg fprExclude
= InvalidFPRReg
)
380 silentSpillAllRegistersImpl(true, m_plans
, exclude
, exclude2
, fprExclude
);
382 void silentSpillAllRegisters(FPRReg exclude
)
384 silentSpillAllRegisters(InvalidGPRReg
, InvalidGPRReg
, exclude
);
387 static GPRReg
pickCanTrample(GPRReg exclude
)
389 GPRReg result
= GPRInfo::regT0
;
390 if (result
== exclude
)
391 result
= GPRInfo::regT1
;
394 static GPRReg
pickCanTrample(FPRReg
)
396 return GPRInfo::regT0
;
398 static GPRReg
pickCanTrample(NoResultTag
)
400 return GPRInfo::regT0
;
403 #if USE(JSVALUE32_64)
404 static GPRReg
pickCanTrample(JSValueRegs exclude
)
406 GPRReg result
= GPRInfo::regT0
;
407 if (result
== exclude
.tagGPR()) {
408 result
= GPRInfo::regT1
;
409 if (result
== exclude
.payloadGPR())
410 result
= GPRInfo::regT2
;
411 } else if (result
== exclude
.payloadGPR()) {
412 result
= GPRInfo::regT1
;
413 if (result
== exclude
.tagGPR())
414 result
= GPRInfo::regT2
;
420 template<typename RegisterType
>
421 void silentFillAllRegisters(RegisterType exclude
)
423 GPRReg canTrample
= pickCanTrample(exclude
);
425 while (!m_plans
.isEmpty()) {
426 SilentRegisterSavePlan
& plan
= m_plans
.last();
427 silentFill(plan
, canTrample
);
428 m_plans
.removeLast();
432 // These methods convert between doubles, and doubles boxed and JSValues.
434 GPRReg
boxDouble(FPRReg fpr
, GPRReg gpr
)
436 return m_jit
.boxDouble(fpr
, gpr
);
438 FPRReg
unboxDouble(GPRReg gpr
, FPRReg fpr
)
440 return m_jit
.unboxDouble(gpr
, fpr
);
442 GPRReg
boxDouble(FPRReg fpr
)
444 return boxDouble(fpr
, allocate());
447 void boxInt52(GPRReg sourceGPR
, GPRReg targetGPR
, DataFormat
);
448 #elif USE(JSVALUE32_64)
449 void boxDouble(FPRReg fpr
, GPRReg tagGPR
, GPRReg payloadGPR
)
451 m_jit
.boxDouble(fpr
, tagGPR
, payloadGPR
);
453 void unboxDouble(GPRReg tagGPR
, GPRReg payloadGPR
, FPRReg fpr
, FPRReg scratchFPR
)
455 m_jit
.unboxDouble(tagGPR
, payloadGPR
, fpr
, scratchFPR
);
458 void boxDouble(FPRReg fpr
, JSValueRegs regs
)
460 m_jit
.boxDouble(fpr
, regs
);
463 // Spill a VirtualRegister to the JSStack.
464 void spill(VirtualRegister spillMe
)
466 GenerationInfo
& info
= generationInfoFromVirtualRegister(spillMe
);
468 #if USE(JSVALUE32_64)
469 if (info
.registerFormat() == DataFormatNone
) // it has been spilled. JS values which have two GPRs can reach here
472 // Check the GenerationInfo to see if this value need writing
473 // to the JSStack - if not, mark it as spilled & return.
474 if (!info
.needsSpill()) {
475 info
.setSpilled(*m_stream
, spillMe
);
479 DataFormat spillFormat
= info
.registerFormat();
480 switch (spillFormat
) {
481 case DataFormatStorage
: {
482 // This is special, since it's not a JS value - as in it's not visible to JS
484 m_jit
.storePtr(info
.gpr(), JITCompiler::addressFor(spillMe
));
485 info
.spill(*m_stream
, spillMe
, DataFormatStorage
);
489 case DataFormatInt32
: {
490 m_jit
.store32(info
.gpr(), JITCompiler::payloadFor(spillMe
));
491 info
.spill(*m_stream
, spillMe
, DataFormatInt32
);
496 case DataFormatDouble
: {
497 m_jit
.storeDouble(info
.fpr(), JITCompiler::addressFor(spillMe
));
498 info
.spill(*m_stream
, spillMe
, DataFormatDouble
);
502 case DataFormatInt52
:
503 case DataFormatStrictInt52
: {
504 m_jit
.store64(info
.gpr(), JITCompiler::addressFor(spillMe
));
505 info
.spill(*m_stream
, spillMe
, spillFormat
);
510 // The following code handles JSValues, int32s, and cells.
511 RELEASE_ASSERT(spillFormat
== DataFormatCell
|| spillFormat
& DataFormatJS
);
513 GPRReg reg
= info
.gpr();
514 // We need to box int32 and cell values ...
515 // but on JSVALUE64 boxing a cell is a no-op!
516 if (spillFormat
== DataFormatInt32
)
517 m_jit
.or64(GPRInfo::tagTypeNumberRegister
, reg
);
519 // Spill the value, and record it as spilled in its boxed form.
520 m_jit
.store64(reg
, JITCompiler::addressFor(spillMe
));
521 info
.spill(*m_stream
, spillMe
, (DataFormat
)(spillFormat
| DataFormatJS
));
523 #elif USE(JSVALUE32_64)
525 case DataFormatBoolean
: {
526 m_jit
.store32(info
.gpr(), JITCompiler::payloadFor(spillMe
));
527 info
.spill(*m_stream
, spillMe
, spillFormat
);
531 case DataFormatDouble
: {
532 // On JSVALUE32_64 boxing a double is a no-op.
533 m_jit
.storeDouble(info
.fpr(), JITCompiler::addressFor(spillMe
));
534 info
.spill(*m_stream
, spillMe
, DataFormatDouble
);
539 // The following code handles JSValues.
540 RELEASE_ASSERT(spillFormat
& DataFormatJS
);
541 m_jit
.store32(info
.tagGPR(), JITCompiler::tagFor(spillMe
));
542 m_jit
.store32(info
.payloadGPR(), JITCompiler::payloadFor(spillMe
));
543 info
.spill(*m_stream
, spillMe
, spillFormat
);
549 bool isKnownInteger(Node
* node
) { return m_state
.forNode(node
).isType(SpecInt32
); }
550 bool isKnownCell(Node
* node
) { return m_state
.forNode(node
).isType(SpecCell
); }
552 bool isKnownNotInteger(Node
* node
) { return !(m_state
.forNode(node
).m_type
& SpecInt32
); }
553 bool isKnownNotNumber(Node
* node
) { return !(m_state
.forNode(node
).m_type
& SpecFullNumber
); }
554 bool isKnownNotCell(Node
* node
) { return !(m_state
.forNode(node
).m_type
& SpecCell
); }
556 UniquedStringImpl
* identifierUID(unsigned index
)
558 return m_jit
.graph().identifiers()[index
];
561 // Spill all VirtualRegisters back to the JSStack.
562 void flushRegisters()
564 for (gpr_iterator iter
= m_gprs
.begin(); iter
!= m_gprs
.end(); ++iter
) {
565 if (iter
.name().isValid()) {
570 for (fpr_iterator iter
= m_fprs
.begin(); iter
!= m_fprs
.end(); ++iter
) {
571 if (iter
.name().isValid()) {
578 // Used to ASSERT flushRegisters() has been called prior to
579 // calling out from JIT code to a C helper function.
582 for (gpr_iterator iter
= m_gprs
.begin(); iter
!= m_gprs
.end(); ++iter
) {
583 if (iter
.name().isValid())
586 for (fpr_iterator iter
= m_fprs
.begin(); iter
!= m_fprs
.end(); ++iter
) {
587 if (iter
.name().isValid())
594 static MacroAssembler::Imm64
valueOfJSConstantAsImm64(Node
* node
)
596 return MacroAssembler::Imm64(JSValue::encode(node
->asJSValue()));
600 // Helper functions to enable code sharing in implementations of bit/shift ops.
601 void bitOp(NodeType op
, int32_t imm
, GPRReg op1
, GPRReg result
)
605 m_jit
.and32(Imm32(imm
), op1
, result
);
608 m_jit
.or32(Imm32(imm
), op1
, result
);
611 m_jit
.xor32(Imm32(imm
), op1
, result
);
614 RELEASE_ASSERT_NOT_REACHED();
617 void bitOp(NodeType op
, GPRReg op1
, GPRReg op2
, GPRReg result
)
621 m_jit
.and32(op1
, op2
, result
);
624 m_jit
.or32(op1
, op2
, result
);
627 m_jit
.xor32(op1
, op2
, result
);
630 RELEASE_ASSERT_NOT_REACHED();
633 void shiftOp(NodeType op
, GPRReg op1
, int32_t shiftAmount
, GPRReg result
)
637 m_jit
.rshift32(op1
, Imm32(shiftAmount
), result
);
640 m_jit
.lshift32(op1
, Imm32(shiftAmount
), result
);
643 m_jit
.urshift32(op1
, Imm32(shiftAmount
), result
);
646 RELEASE_ASSERT_NOT_REACHED();
649 void shiftOp(NodeType op
, GPRReg op1
, GPRReg shiftAmount
, GPRReg result
)
653 m_jit
.rshift32(op1
, shiftAmount
, result
);
656 m_jit
.lshift32(op1
, shiftAmount
, result
);
659 m_jit
.urshift32(op1
, shiftAmount
, result
);
662 RELEASE_ASSERT_NOT_REACHED();
666 // Returns the index of the branch node if peephole is okay, UINT_MAX otherwise.
667 unsigned detectPeepHoleBranch()
669 // Check that no intervening nodes will be generated.
670 for (unsigned index
= m_indexInBlock
+ 1; index
< m_block
->size() - 1; ++index
) {
671 Node
* node
= m_block
->at(index
);
672 if (!node
->shouldGenerate())
674 // Check if it's a Phantom that can be safely ignored.
675 if (node
->op() == Phantom
&& !node
->child1())
680 // Check if the lastNode is a branch on this node.
681 Node
* lastNode
= m_block
->terminal();
682 return lastNode
->op() == Branch
&& lastNode
->child1() == m_currentNode
? m_block
->size() - 1 : UINT_MAX
;
685 void compileMovHint(Node
*);
686 void compileMovHintAndCheck(Node
*);
689 void cachedGetById(CodeOrigin
, GPRReg baseGPR
, GPRReg resultGPR
, unsigned identifierNumber
, JITCompiler::Jump slowPathTarget
= JITCompiler::Jump(), SpillRegistersMode
= NeedToSpill
);
690 void cachedPutById(CodeOrigin
, GPRReg base
, GPRReg value
, GPRReg scratchGPR
, unsigned identifierNumber
, PutKind
, JITCompiler::Jump slowPathTarget
= JITCompiler::Jump(), SpillRegistersMode
= NeedToSpill
);
691 #elif USE(JSVALUE32_64)
692 void cachedGetById(CodeOrigin
, GPRReg baseTagGPROrNone
, GPRReg basePayloadGPR
, GPRReg resultTagGPR
, GPRReg resultPayloadGPR
, unsigned identifierNumber
, JITCompiler::Jump slowPathTarget
= JITCompiler::Jump(), SpillRegistersMode
= NeedToSpill
);
693 void cachedPutById(CodeOrigin
, GPRReg basePayloadGPR
, GPRReg valueTagGPR
, GPRReg valuePayloadGPR
, GPRReg scratchGPR
, unsigned identifierNumber
, PutKind
, JITCompiler::Jump slowPathTarget
= JITCompiler::Jump(), SpillRegistersMode
= NeedToSpill
);
696 void compileIn(Node
*);
698 void compileBaseValueStoreBarrier(Edge
& baseEdge
, Edge
& valueEdge
);
700 void nonSpeculativeNonPeepholeCompareNull(Edge operand
, bool invert
= false);
701 void nonSpeculativePeepholeBranchNull(Edge operand
, Node
* branchNode
, bool invert
= false);
702 bool nonSpeculativeCompareNull(Node
*, Edge operand
, bool invert
= false);
704 void nonSpeculativePeepholeBranch(Node
*, Node
* branchNode
, MacroAssembler::RelationalCondition
, S_JITOperation_EJJ helperFunction
);
705 void nonSpeculativeNonPeepholeCompare(Node
*, MacroAssembler::RelationalCondition
, S_JITOperation_EJJ helperFunction
);
706 bool nonSpeculativeCompare(Node
*, MacroAssembler::RelationalCondition
, S_JITOperation_EJJ helperFunction
);
708 void nonSpeculativePeepholeStrictEq(Node
*, Node
* branchNode
, bool invert
= false);
709 void nonSpeculativeNonPeepholeStrictEq(Node
*, bool invert
= false);
710 bool nonSpeculativeStrictEq(Node
*, bool invert
= false);
712 void compileInstanceOfForObject(Node
*, GPRReg valueReg
, GPRReg prototypeReg
, GPRReg scratchAndResultReg
, GPRReg scratch2Reg
);
713 void compileInstanceOf(Node
*);
715 void emitCall(Node
*);
717 // Called once a node has completed code generation but prior to setting
718 // its result, to free up its children. (This must happen prior to setting
719 // the nodes result, since the node may have the same VirtualRegister as
720 // a child, and as such will use the same GeneratioInfo).
721 void useChildren(Node
*);
723 // These method called to initialize the the GenerationInfo
724 // to describe the result of an operation.
725 void int32Result(GPRReg reg
, Node
* node
, DataFormat format
= DataFormatInt32
, UseChildrenMode mode
= CallUseChildren
)
727 if (mode
== CallUseChildren
)
730 VirtualRegister virtualRegister
= node
->virtualRegister();
731 GenerationInfo
& info
= generationInfoFromVirtualRegister(virtualRegister
);
733 if (format
== DataFormatInt32
) {
734 m_jit
.jitAssertIsInt32(reg
);
735 m_gprs
.retain(reg
, virtualRegister
, SpillOrderInteger
);
736 info
.initInt32(node
, node
->refCount(), reg
);
739 RELEASE_ASSERT(format
== DataFormatJSInt32
);
740 m_jit
.jitAssertIsJSInt32(reg
);
741 m_gprs
.retain(reg
, virtualRegister
, SpillOrderJS
);
742 info
.initJSValue(node
, node
->refCount(), reg
, format
);
743 #elif USE(JSVALUE32_64)
744 RELEASE_ASSERT_NOT_REACHED();
748 void int32Result(GPRReg reg
, Node
* node
, UseChildrenMode mode
)
750 int32Result(reg
, node
, DataFormatInt32
, mode
);
752 void int52Result(GPRReg reg
, Node
* node
, DataFormat format
, UseChildrenMode mode
= CallUseChildren
)
754 if (mode
== CallUseChildren
)
757 VirtualRegister virtualRegister
= node
->virtualRegister();
758 GenerationInfo
& info
= generationInfoFromVirtualRegister(virtualRegister
);
760 m_gprs
.retain(reg
, virtualRegister
, SpillOrderJS
);
761 info
.initInt52(node
, node
->refCount(), reg
, format
);
763 void int52Result(GPRReg reg
, Node
* node
, UseChildrenMode mode
= CallUseChildren
)
765 int52Result(reg
, node
, DataFormatInt52
, mode
);
767 void strictInt52Result(GPRReg reg
, Node
* node
, UseChildrenMode mode
= CallUseChildren
)
769 int52Result(reg
, node
, DataFormatStrictInt52
, mode
);
771 void noResult(Node
* node
, UseChildrenMode mode
= CallUseChildren
)
773 if (mode
== UseChildrenCalledExplicitly
)
777 void cellResult(GPRReg reg
, Node
* node
, UseChildrenMode mode
= CallUseChildren
)
779 if (mode
== CallUseChildren
)
782 VirtualRegister virtualRegister
= node
->virtualRegister();
783 m_gprs
.retain(reg
, virtualRegister
, SpillOrderCell
);
784 GenerationInfo
& info
= generationInfoFromVirtualRegister(virtualRegister
);
785 info
.initCell(node
, node
->refCount(), reg
);
787 void blessedBooleanResult(GPRReg reg
, Node
* node
, UseChildrenMode mode
= CallUseChildren
)
790 jsValueResult(reg
, node
, DataFormatJSBoolean
, mode
);
792 booleanResult(reg
, node
, mode
);
795 void unblessedBooleanResult(GPRReg reg
, Node
* node
, UseChildrenMode mode
= CallUseChildren
)
800 blessedBooleanResult(reg
, node
, mode
);
803 void jsValueResult(GPRReg reg
, Node
* node
, DataFormat format
= DataFormatJS
, UseChildrenMode mode
= CallUseChildren
)
805 if (format
== DataFormatJSInt32
)
806 m_jit
.jitAssertIsJSInt32(reg
);
808 if (mode
== CallUseChildren
)
811 VirtualRegister virtualRegister
= node
->virtualRegister();
812 m_gprs
.retain(reg
, virtualRegister
, SpillOrderJS
);
813 GenerationInfo
& info
= generationInfoFromVirtualRegister(virtualRegister
);
814 info
.initJSValue(node
, node
->refCount(), reg
, format
);
816 void jsValueResult(GPRReg reg
, Node
* node
, UseChildrenMode mode
)
818 jsValueResult(reg
, node
, DataFormatJS
, mode
);
820 #elif USE(JSVALUE32_64)
821 void booleanResult(GPRReg reg
, Node
* node
, UseChildrenMode mode
= CallUseChildren
)
823 if (mode
== CallUseChildren
)
826 VirtualRegister virtualRegister
= node
->virtualRegister();
827 m_gprs
.retain(reg
, virtualRegister
, SpillOrderBoolean
);
828 GenerationInfo
& info
= generationInfoFromVirtualRegister(virtualRegister
);
829 info
.initBoolean(node
, node
->refCount(), reg
);
831 void jsValueResult(GPRReg tag
, GPRReg payload
, Node
* node
, DataFormat format
= DataFormatJS
, UseChildrenMode mode
= CallUseChildren
)
833 if (mode
== CallUseChildren
)
836 VirtualRegister virtualRegister
= node
->virtualRegister();
837 m_gprs
.retain(tag
, virtualRegister
, SpillOrderJS
);
838 m_gprs
.retain(payload
, virtualRegister
, SpillOrderJS
);
839 GenerationInfo
& info
= generationInfoFromVirtualRegister(virtualRegister
);
840 info
.initJSValue(node
, node
->refCount(), tag
, payload
, format
);
842 void jsValueResult(GPRReg tag
, GPRReg payload
, Node
* node
, UseChildrenMode mode
)
844 jsValueResult(tag
, payload
, node
, DataFormatJS
, mode
);
847 void jsValueResult(JSValueRegs regs
, Node
* node
, DataFormat format
= DataFormatJS
, UseChildrenMode mode
= CallUseChildren
)
850 jsValueResult(regs
.gpr(), node
, format
, mode
);
852 jsValueResult(regs
.tagGPR(), regs
.payloadGPR(), node
, format
, mode
);
855 void storageResult(GPRReg reg
, Node
* node
, UseChildrenMode mode
= CallUseChildren
)
857 if (mode
== CallUseChildren
)
860 VirtualRegister virtualRegister
= node
->virtualRegister();
861 m_gprs
.retain(reg
, virtualRegister
, SpillOrderStorage
);
862 GenerationInfo
& info
= generationInfoFromVirtualRegister(virtualRegister
);
863 info
.initStorage(node
, node
->refCount(), reg
);
865 void doubleResult(FPRReg reg
, Node
* node
, UseChildrenMode mode
= CallUseChildren
)
867 if (mode
== CallUseChildren
)
870 VirtualRegister virtualRegister
= node
->virtualRegister();
871 m_fprs
.retain(reg
, virtualRegister
, SpillOrderDouble
);
872 GenerationInfo
& info
= generationInfoFromVirtualRegister(virtualRegister
);
873 info
.initDouble(node
, node
->refCount(), reg
);
875 void initConstantInfo(Node
* node
)
877 ASSERT(node
->hasConstant());
878 generationInfo(node
).initConstant(node
, node
->refCount());
881 // These methods add calls to C++ helper functions.
882 // These methods are broadly value representation specific (i.e.
883 // deal with the fact that a JSValue may be passed in one or two
884 // machine registers, and delegate the calling convention specific
885 // decision as to how to fill the regsiters to setupArguments* methods.
887 JITCompiler::Call
callOperation(V_JITOperation_E operation
)
889 m_jit
.setupArgumentsExecState();
890 return appendCallWithExceptionCheck(operation
);
892 JITCompiler::Call
callOperation(P_JITOperation_E operation
, GPRReg result
)
894 m_jit
.setupArgumentsExecState();
895 return appendCallWithExceptionCheckSetResult(operation
, result
);
897 JITCompiler::Call
callOperation(P_JITOperation_EC operation
, GPRReg result
, GPRReg cell
)
899 m_jit
.setupArgumentsWithExecState(cell
);
900 return appendCallWithExceptionCheckSetResult(operation
, result
);
902 JITCompiler::Call
callOperation(P_JITOperation_EO operation
, GPRReg result
, GPRReg object
)
904 m_jit
.setupArgumentsWithExecState(object
);
905 return appendCallWithExceptionCheckSetResult(operation
, result
);
907 JITCompiler::Call
callOperation(P_JITOperation_EOS operation
, GPRReg result
, GPRReg object
, size_t size
)
909 m_jit
.setupArgumentsWithExecState(object
, TrustedImmPtr(size
));
910 return appendCallWithExceptionCheckSetResult(operation
, result
);
912 JITCompiler::Call
callOperation(P_JITOperation_EOZ operation
, GPRReg result
, GPRReg object
, int32_t size
)
914 m_jit
.setupArgumentsWithExecState(object
, TrustedImmPtr(size
));
915 return appendCallWithExceptionCheckSetResult(operation
, result
);
917 JITCompiler::Call
callOperation(C_JITOperation_EOZ operation
, GPRReg result
, GPRReg object
, int32_t size
)
919 m_jit
.setupArgumentsWithExecState(object
, TrustedImmPtr(static_cast<size_t>(size
)));
920 return appendCallWithExceptionCheckSetResult(operation
, result
);
922 JITCompiler::Call
callOperation(P_JITOperation_EPS operation
, GPRReg result
, GPRReg old
, size_t size
)
924 m_jit
.setupArgumentsWithExecState(old
, TrustedImmPtr(size
));
925 return appendCallWithExceptionCheckSetResult(operation
, result
);
927 JITCompiler::Call
callOperation(P_JITOperation_ES operation
, GPRReg result
, size_t size
)
929 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(size
));
930 return appendCallWithExceptionCheckSetResult(operation
, result
);
932 JITCompiler::Call
callOperation(P_JITOperation_ESJss operation
, GPRReg result
, size_t index
, GPRReg arg1
)
934 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(index
), arg1
);
935 return appendCallWithExceptionCheckSetResult(operation
, result
);
937 JITCompiler::Call
callOperation(P_JITOperation_ESt operation
, GPRReg result
, Structure
* structure
)
939 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(structure
));
940 return appendCallWithExceptionCheckSetResult(operation
, result
);
942 JITCompiler::Call
callOperation(P_JITOperation_EStZ operation
, GPRReg result
, Structure
* structure
, GPRReg arg2
)
944 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(structure
), arg2
);
945 return appendCallWithExceptionCheckSetResult(operation
, result
);
947 JITCompiler::Call
callOperation(P_JITOperation_EStZ operation
, GPRReg result
, Structure
* structure
, size_t arg2
)
949 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(structure
), TrustedImm32(arg2
));
950 return appendCallWithExceptionCheckSetResult(operation
, result
);
952 JITCompiler::Call
callOperation(P_JITOperation_EStZ operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
954 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
955 return appendCallWithExceptionCheckSetResult(operation
, result
);
957 JITCompiler::Call
callOperation(P_JITOperation_EStPS operation
, GPRReg result
, Structure
* structure
, void* pointer
, size_t size
)
959 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(structure
), TrustedImmPtr(pointer
), TrustedImmPtr(size
));
960 return appendCallWithExceptionCheckSetResult(operation
, result
);
962 JITCompiler::Call
callOperation(P_JITOperation_EStSS operation
, GPRReg result
, Structure
* structure
, size_t index
, size_t size
)
964 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(structure
), TrustedImmPtr(index
), TrustedImmPtr(size
));
965 return appendCallWithExceptionCheckSetResult(operation
, result
);
967 JITCompiler::Call
callOperation(C_JITOperation_E operation
, GPRReg result
)
969 m_jit
.setupArgumentsExecState();
970 return appendCallWithExceptionCheckSetResult(operation
, result
);
972 JITCompiler::Call
callOperation(C_JITOperation_EC operation
, GPRReg result
, GPRReg arg1
)
974 m_jit
.setupArgumentsWithExecState(arg1
);
975 return appendCallWithExceptionCheckSetResult(operation
, result
);
977 JITCompiler::Call
callOperation(C_JITOperation_EC operation
, GPRReg result
, JSCell
* cell
)
979 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(cell
));
980 return appendCallWithExceptionCheckSetResult(operation
, result
);
982 JITCompiler::Call
callOperation(C_JITOperation_ECZ operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
984 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
985 return appendCallWithExceptionCheckSetResult(operation
, result
);
987 JITCompiler::Call
callOperation(C_JITOperation_ECZC operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
, GPRReg arg3
)
989 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, arg3
);
990 return appendCallWithExceptionCheckSetResult(operation
, result
);
992 JITCompiler::Call
callOperation(C_JITOperation_EJscC operation
, GPRReg result
, GPRReg arg1
, JSCell
* cell
)
994 m_jit
.setupArgumentsWithExecState(arg1
, TrustedImmPtr(cell
));
995 return appendCallWithExceptionCheckSetResult(operation
, result
);
997 JITCompiler::Call
callOperation(C_JITOperation_EIcf operation
, GPRReg result
, InlineCallFrame
* inlineCallFrame
)
999 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame
));
1000 return appendCallWithExceptionCheckSetResult(operation
, result
);
1002 JITCompiler::Call
callOperation(C_JITOperation_ESt operation
, GPRReg result
, Structure
* structure
)
1004 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(structure
));
1005 return appendCallWithExceptionCheckSetResult(operation
, result
);
1007 JITCompiler::Call
callOperation(C_JITOperation_EStJscSymtab operation
, GPRReg result
, Structure
* structure
, GPRReg scope
, SymbolTable
* table
)
1009 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(structure
), scope
, TrustedImmPtr(table
));
1010 return appendCallWithExceptionCheckSetResult(operation
, result
);
1012 JITCompiler::Call
callOperation(C_JITOperation_EStZ operation
, GPRReg result
, Structure
* structure
, unsigned knownLength
)
1014 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(structure
), TrustedImm32(knownLength
));
1015 return appendCallWithExceptionCheckSetResult(operation
, result
);
1017 JITCompiler::Call
callOperation(C_JITOperation_EStZZ operation
, GPRReg result
, Structure
* structure
, unsigned knownLength
, unsigned minCapacity
)
1019 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(structure
), TrustedImm32(knownLength
), TrustedImm32(minCapacity
));
1020 return appendCallWithExceptionCheckSetResult(operation
, result
);
1022 JITCompiler::Call
callOperation(C_JITOperation_EStZ operation
, GPRReg result
, Structure
* structure
, GPRReg length
)
1024 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(structure
), length
);
1025 return appendCallWithExceptionCheckSetResult(operation
, result
);
1027 JITCompiler::Call
callOperation(C_JITOperation_EStZZ operation
, GPRReg result
, Structure
* structure
, GPRReg length
, unsigned minCapacity
)
1029 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(structure
), length
, TrustedImm32(minCapacity
));
1030 return appendCallWithExceptionCheckSetResult(operation
, result
);
1032 JITCompiler::Call
callOperation(C_JITOperation_EJssSt operation
, GPRReg result
, GPRReg arg1
, Structure
* structure
)
1034 m_jit
.setupArgumentsWithExecState(arg1
, TrustedImmPtr(structure
));
1035 return appendCallWithExceptionCheckSetResult(operation
, result
);
1037 JITCompiler::Call
callOperation(C_JITOperation_EJssJss operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
1039 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1040 return appendCallWithExceptionCheckSetResult(operation
, result
);
1042 JITCompiler::Call
callOperation(C_JITOperation_EJssJssJss operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
, GPRReg arg3
)
1044 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, arg3
);
1045 return appendCallWithExceptionCheckSetResult(operation
, result
);
1048 JITCompiler::Call
callOperation(S_JITOperation_ECC operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
1050 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1051 return appendCallWithExceptionCheckSetResult(operation
, result
);
1054 JITCompiler::Call
callOperation(S_JITOperation_EGC operation
, GPRReg result
, JSGlobalObject
* globalObject
, GPRReg arg2
)
1056 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(globalObject
), arg2
);
1057 return appendCallWithExceptionCheckSetResult(operation
, result
);
1060 JITCompiler::Call
callOperation(C_JITOperation_EGC operation
, GPRReg result
, JSGlobalObject
* globalObject
, GPRReg arg2
)
1062 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(globalObject
), arg2
);
1063 return appendCallWithExceptionCheckSetResult(operation
, result
);
1066 JITCompiler::Call
callOperation(Jss_JITOperation_EZ operation
, GPRReg result
, GPRReg arg1
)
1068 m_jit
.setupArgumentsWithExecState(arg1
);
1069 return appendCallWithExceptionCheckSetResult(operation
, result
);
1072 JITCompiler::Call
callOperation(V_JITOperation_EC operation
, GPRReg arg1
)
1074 m_jit
.setupArgumentsWithExecState(arg1
);
1075 return appendCallWithExceptionCheck(operation
);
1078 JITCompiler::Call
callOperation(V_JITOperation_EC operation
, JSCell
* arg1
)
1080 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(arg1
));
1081 return appendCallWithExceptionCheck(operation
);
1084 JITCompiler::Call
callOperation(V_JITOperation_ECIcf operation
, GPRReg arg1
, InlineCallFrame
* inlineCallFrame
)
1086 m_jit
.setupArgumentsWithExecState(arg1
, TrustedImmPtr(inlineCallFrame
));
1087 return appendCallWithExceptionCheck(operation
);
1089 JITCompiler::Call
callOperation(V_JITOperation_ECCIcf operation
, GPRReg arg1
, GPRReg arg2
, InlineCallFrame
* inlineCallFrame
)
1091 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, TrustedImmPtr(inlineCallFrame
));
1092 return appendCallWithExceptionCheck(operation
);
1095 JITCompiler::Call
callOperation(V_JITOperation_ECZ operation
, GPRReg arg1
, int arg2
)
1097 m_jit
.setupArgumentsWithExecState(arg1
, TrustedImm32(arg2
));
1098 return appendCallWithExceptionCheck(operation
);
1100 JITCompiler::Call
callOperation(V_JITOperation_ECC operation
, GPRReg arg1
, GPRReg arg2
)
1102 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1103 return appendCallWithExceptionCheck(operation
);
1105 JITCompiler::Call
callOperation(V_JITOperation_ECC operation
, GPRReg arg1
, JSCell
* arg2
)
1107 m_jit
.setupArgumentsWithExecState(arg1
, TrustedImmPtr(arg2
));
1108 return appendCallWithExceptionCheck(operation
);
1110 JITCompiler::Call
callOperation(V_JITOperation_ECC operation
, JSCell
* arg1
, GPRReg arg2
)
1112 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(arg1
), arg2
);
1113 return appendCallWithExceptionCheck(operation
);
1116 JITCompiler::Call
callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb operation
, void* pointer
)
1118 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(pointer
));
1119 return appendCallWithCallFrameRollbackOnException(operation
);
1122 JITCompiler::Call
callOperationWithCallFrameRollbackOnException(Z_JITOperation_E operation
, GPRReg result
)
1124 m_jit
.setupArgumentsExecState();
1125 return appendCallWithCallFrameRollbackOnExceptionSetResult(operation
, result
);
1127 JITCompiler::Call
callOperation(Z_JITOperation_EC operation
, GPRReg result
, GPRReg arg1
)
1129 m_jit
.setupArgumentsWithExecState(arg1
);
1130 return appendCallWithExceptionCheckSetResult(operation
, result
);
1133 template<typename FunctionType
>
1134 JITCompiler::Call
callOperation(FunctionType operation
, NoResultTag
)
1136 return callOperation(operation
);
1138 template<typename FunctionType
, typename ArgumentType1
>
1139 JITCompiler::Call
callOperation(FunctionType operation
, NoResultTag
, ArgumentType1 arg1
)
1141 return callOperation(operation
, arg1
);
1143 template<typename FunctionType
, typename ArgumentType1
, typename ArgumentType2
>
1144 JITCompiler::Call
callOperation(FunctionType operation
, NoResultTag
, ArgumentType1 arg1
, ArgumentType2 arg2
)
1146 return callOperation(operation
, arg1
, arg2
);
1148 template<typename FunctionType
, typename ArgumentType1
, typename ArgumentType2
, typename ArgumentType3
>
1149 JITCompiler::Call
callOperation(FunctionType operation
, NoResultTag
, ArgumentType1 arg1
, ArgumentType2 arg2
, ArgumentType3 arg3
)
1151 return callOperation(operation
, arg1
, arg2
, arg3
);
1153 template<typename FunctionType
, typename ArgumentType1
, typename ArgumentType2
, typename ArgumentType3
, typename ArgumentType4
>
1154 JITCompiler::Call
callOperation(FunctionType operation
, NoResultTag
, ArgumentType1 arg1
, ArgumentType2 arg2
, ArgumentType3 arg3
, ArgumentType4 arg4
)
1156 return callOperation(operation
, arg1
, arg2
, arg3
, arg4
);
1158 template<typename FunctionType
, typename ArgumentType1
, typename ArgumentType2
, typename ArgumentType3
, typename ArgumentType4
, typename ArgumentType5
>
1159 JITCompiler::Call
callOperation(FunctionType operation
, NoResultTag
, ArgumentType1 arg1
, ArgumentType2 arg2
, ArgumentType3 arg3
, ArgumentType4 arg4
, ArgumentType5 arg5
)
1161 return callOperation(operation
, arg1
, arg2
, arg3
, arg4
, arg5
);
1164 JITCompiler::Call
callOperation(D_JITOperation_ZZ operation
, FPRReg result
, GPRReg arg1
, GPRReg arg2
)
1166 m_jit
.setupArguments(arg1
, arg2
);
1167 return appendCallSetResult(operation
, result
);
1169 JITCompiler::Call
callOperation(D_JITOperation_D operation
, FPRReg result
, FPRReg arg1
)
1171 m_jit
.setupArguments(arg1
);
1172 return appendCallSetResult(operation
, result
);
1174 JITCompiler::Call
callOperation(D_JITOperation_DD operation
, FPRReg result
, FPRReg arg1
, FPRReg arg2
)
1176 m_jit
.setupArguments(arg1
, arg2
);
1177 return appendCallSetResult(operation
, result
);
1179 JITCompiler::Call
callOperation(T_JITOperation_EJss operation
, GPRReg result
, GPRReg arg1
)
1181 m_jit
.setupArgumentsWithExecState(arg1
);
1182 return appendCallWithExceptionCheckSetResult(operation
, result
);
1184 JITCompiler::Call
callOperation(C_JITOperation_EJscZ operation
, GPRReg result
, GPRReg arg1
, int32_t arg2
)
1186 m_jit
.setupArgumentsWithExecState(arg1
, TrustedImm32(arg2
));
1187 return appendCallWithExceptionCheckSetResult(operation
, result
);
1189 JITCompiler::Call
callOperation(C_JITOperation_EZ operation
, GPRReg result
, GPRReg arg1
)
1191 m_jit
.setupArgumentsWithExecState(arg1
);
1192 return appendCallWithExceptionCheckSetResult(operation
, result
);
1194 JITCompiler::Call
callOperation(C_JITOperation_EZ operation
, GPRReg result
, int32_t arg1
)
1196 m_jit
.setupArgumentsWithExecState(TrustedImm32(arg1
));
1197 return appendCallWithExceptionCheckSetResult(operation
, result
);
1200 JITCompiler::Call
callOperation(J_JITOperation_EJscC operation
, GPRReg result
, GPRReg arg1
, JSCell
* cell
)
1202 m_jit
.setupArgumentsWithExecState(arg1
, TrustedImmPtr(cell
));
1203 return appendCallWithExceptionCheckSetResult(operation
, result
);
1206 JITCompiler::Call
callOperation(V_JITOperation_EWs operation
, WatchpointSet
* watchpointSet
)
1208 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet
));
1209 return appendCall(operation
);
1213 JITCompiler::Call
callOperation(J_JITOperation_E operation
, GPRReg result
)
1215 m_jit
.setupArgumentsExecState();
1216 return appendCallWithExceptionCheckSetResult(operation
, result
);
1218 JITCompiler::Call
callOperation(J_JITOperation_EP operation
, GPRReg result
, void* pointer
)
1220 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(pointer
));
1221 return appendCallWithExceptionCheckSetResult(operation
, result
);
1223 JITCompiler::Call
callOperation(Z_JITOperation_D operation
, GPRReg result
, FPRReg arg1
)
1225 m_jit
.setupArguments(arg1
);
1226 JITCompiler::Call call
= m_jit
.appendCall(operation
);
1227 m_jit
.zeroExtend32ToPtr(GPRInfo::returnValueGPR
, result
);
1230 JITCompiler::Call
callOperation(Q_JITOperation_J operation
, GPRReg result
, GPRReg value
)
1232 m_jit
.setupArguments(value
);
1233 return appendCallSetResult(operation
, result
);
1235 JITCompiler::Call
callOperation(Q_JITOperation_D operation
, GPRReg result
, FPRReg value
)
1237 m_jit
.setupArguments(value
);
1238 return appendCallSetResult(operation
, result
);
1240 JITCompiler::Call
callOperation(J_JITOperation_EI operation
, GPRReg result
, UniquedStringImpl
* uid
)
1242 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(uid
));
1243 return appendCallWithExceptionCheckSetResult(operation
, result
);
1245 JITCompiler::Call
callOperation(J_JITOperation_EA operation
, GPRReg result
, GPRReg arg1
)
1247 m_jit
.setupArgumentsWithExecState(arg1
);
1248 return appendCallWithExceptionCheckSetResult(operation
, result
);
1250 JITCompiler::Call
callOperation(J_JITOperation_EAZ operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
1252 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1253 return appendCallWithExceptionCheckSetResult(operation
, result
);
1255 JITCompiler::Call
callOperation(J_JITOperation_EJssZ operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
1257 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1258 return appendCallWithExceptionCheckSetResult(operation
, result
);
1260 JITCompiler::Call
callOperation(J_JITOperation_EPS operation
, GPRReg result
, void* pointer
, size_t size
)
1262 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(pointer
), TrustedImmPtr(size
));
1263 return appendCallWithExceptionCheckSetResult(operation
, result
);
1265 JITCompiler::Call
callOperation(J_JITOperation_ESS operation
, GPRReg result
, int startConstant
, int numConstants
)
1267 m_jit
.setupArgumentsWithExecState(TrustedImm32(startConstant
), TrustedImm32(numConstants
));
1268 return appendCallWithExceptionCheckSetResult(operation
, result
);
1270 JITCompiler::Call
callOperation(J_JITOperation_EPP operation
, GPRReg result
, GPRReg arg1
, void* pointer
)
1272 m_jit
.setupArgumentsWithExecState(arg1
, TrustedImmPtr(pointer
));
1273 return appendCallWithExceptionCheckSetResult(operation
, result
);
1275 JITCompiler::Call
callOperation(J_JITOperation_EC operation
, GPRReg result
, JSCell
* cell
)
1277 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(cell
));
1278 return appendCallWithExceptionCheckSetResult(operation
, result
);
1280 JITCompiler::Call
callOperation(J_JITOperation_ECZ operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
1282 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1283 return appendCallWithExceptionCheckSetResult(operation
, result
);
1285 JITCompiler::Call
callOperation(J_JITOperation_ESsiCI operation
, GPRReg result
, StructureStubInfo
* stubInfo
, GPRReg arg1
, const UniquedStringImpl
* uid
)
1287 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(stubInfo
), arg1
, TrustedImmPtr(uid
));
1288 return appendCallWithExceptionCheckSetResult(operation
, result
);
1290 JITCompiler::Call
callOperation(J_JITOperation_ESsiJI operation
, GPRReg result
, StructureStubInfo
* stubInfo
, GPRReg arg1
, UniquedStringImpl
* uid
)
1292 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(stubInfo
), arg1
, TrustedImmPtr(uid
));
1293 return appendCallWithExceptionCheckSetResult(operation
, result
);
1295 JITCompiler::Call
callOperation(J_JITOperation_EDA operation
, GPRReg result
, FPRReg arg1
, GPRReg arg2
)
1297 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1298 return appendCallWithExceptionCheckSetResult(operation
, result
);
1300 JITCompiler::Call
callOperation(J_JITOperation_EJC operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
1302 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1303 return appendCallWithExceptionCheckSetResult(operation
, result
);
1305 JITCompiler::Call
callOperation(J_JITOperation_EJZ operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
1307 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1308 return appendCallWithExceptionCheckSetResult(operation
, result
);
1310 JITCompiler::Call
callOperation(J_JITOperation_EJA operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
1312 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1313 return appendCallWithExceptionCheckSetResult(operation
, result
);
1315 JITCompiler::Call
callOperation(J_JITOperation_EP operation
, GPRReg result
, GPRReg arg1
)
1317 m_jit
.setupArgumentsWithExecState(arg1
);
1318 return appendCallWithExceptionCheckSetResult(operation
, result
);
1320 JITCompiler::Call
callOperation(J_JITOperation_EZ operation
, GPRReg result
, GPRReg arg1
)
1322 m_jit
.setupArgumentsWithExecState(arg1
);
1323 return appendCallWithExceptionCheckSetResult(operation
, result
);
1325 JITCompiler::Call
callOperation(J_JITOperation_EZ operation
, GPRReg result
, int32_t arg1
)
1327 m_jit
.setupArgumentsWithExecState(TrustedImm32(arg1
));
1328 return appendCallWithExceptionCheckSetResult(operation
, result
);
1330 JITCompiler::Call
callOperation(J_JITOperation_EZZ operation
, GPRReg result
, int32_t arg1
, GPRReg arg2
)
1332 m_jit
.setupArgumentsWithExecState(TrustedImm32(arg1
), arg2
);
1333 return appendCallWithExceptionCheckSetResult(operation
, result
);
1335 JITCompiler::Call
callOperation(J_JITOperation_EZIcfZ operation
, GPRReg result
, int32_t arg1
, InlineCallFrame
* inlineCallFrame
, GPRReg arg2
)
1337 m_jit
.setupArgumentsWithExecState(TrustedImm32(arg1
), TrustedImmPtr(inlineCallFrame
), arg2
);
1338 return appendCallWithExceptionCheckSetResult(operation
, result
);
1341 JITCompiler::Call
callOperation(P_JITOperation_EJS operation
, GPRReg result
, GPRReg value
, size_t index
)
1343 m_jit
.setupArgumentsWithExecState(value
, TrustedImmPtr(index
));
1344 return appendCallSetResult(operation
, result
);
1347 JITCompiler::Call
callOperation(P_JITOperation_EStJ operation
, GPRReg result
, Structure
* structure
, GPRReg arg2
)
1349 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(structure
), arg2
);
1350 return appendCallWithExceptionCheckSetResult(operation
, result
);
1353 JITCompiler::Call
callOperation(C_JITOperation_EJ operation
, GPRReg result
, GPRReg arg1
)
1355 m_jit
.setupArgumentsWithExecState(arg1
);
1356 return appendCallWithExceptionCheckSetResult(operation
, result
);
1358 JITCompiler::Call
callOperation(C_JITOperation_EJJC operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
, GPRReg arg3
)
1360 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, arg3
);
1361 return appendCallWithExceptionCheckSetResult(operation
, result
);
1363 JITCompiler::Call
callOperation(C_JITOperation_EJZ operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
1365 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1366 return appendCallWithExceptionCheckSetResult(operation
, result
);
1368 JITCompiler::Call
callOperation(C_JITOperation_EJZC operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
, GPRReg arg3
)
1370 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, arg3
);
1371 return appendCallWithExceptionCheckSetResult(operation
, result
);
1373 JITCompiler::Call
callOperation(S_JITOperation_J operation
, GPRReg result
, GPRReg arg1
)
1375 m_jit
.setupArguments(arg1
);
1376 return appendCallSetResult(operation
, result
);
1378 JITCompiler::Call
callOperation(S_JITOperation_EJ operation
, GPRReg result
, GPRReg arg1
)
1380 m_jit
.setupArgumentsWithExecState(arg1
);
1381 return appendCallWithExceptionCheckSetResult(operation
, result
);
1383 JITCompiler::Call
callOperation(J_JITOperation_EJ operation
, GPRReg result
, GPRReg arg1
)
1385 m_jit
.setupArgumentsWithExecState(arg1
);
1386 return appendCallWithExceptionCheckSetResult(operation
, result
);
1388 JITCompiler::Call
callOperation(S_JITOperation_EJJ operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
1390 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1391 return appendCallWithExceptionCheckSetResult(operation
, result
);
1394 JITCompiler::Call
callOperation(J_JITOperation_EPP operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
1396 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1397 return appendCallWithExceptionCheckSetResult(operation
, result
);
1399 JITCompiler::Call
callOperation(J_JITOperation_EJJ operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
1401 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1402 return appendCallWithExceptionCheckSetResult(operation
, result
);
1404 JITCompiler::Call
callOperation(J_JITOperation_EJJ operation
, GPRReg result
, GPRReg arg1
, MacroAssembler::TrustedImm32 imm
)
1406 m_jit
.setupArgumentsWithExecState(arg1
, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm
.m_value
))));
1407 return appendCallWithExceptionCheckSetResult(operation
, result
);
1409 JITCompiler::Call
callOperation(J_JITOperation_EJJ operation
, GPRReg result
, MacroAssembler::TrustedImm32 imm
, GPRReg arg2
)
1411 m_jit
.setupArgumentsWithExecState(MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm
.m_value
))), arg2
);
1412 return appendCallWithExceptionCheckSetResult(operation
, result
);
1414 JITCompiler::Call
callOperation(J_JITOperation_ECC operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
1416 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1417 return appendCallWithExceptionCheckSetResult(operation
, result
);
1419 JITCompiler::Call
callOperation(J_JITOperation_ECJ operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
)
1421 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1422 return appendCallWithExceptionCheckSetResult(operation
, result
);
1424 JITCompiler::Call
callOperation(J_JITOperation_ECJ operation
, GPRReg result
, GPRReg arg1
, JSValueRegs arg2
)
1426 m_jit
.setupArgumentsWithExecState(arg1
, arg2
.gpr());
1427 return appendCallWithExceptionCheckSetResult(operation
, result
);
1430 JITCompiler::Call
callOperation(V_JITOperation_EOZD operation
, GPRReg arg1
, GPRReg arg2
, FPRReg arg3
)
1432 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, arg3
);
1433 return appendCallWithExceptionCheck(operation
);
1435 JITCompiler::Call
callOperation(V_JITOperation_EJ operation
, GPRReg arg1
)
1437 m_jit
.setupArgumentsWithExecState(arg1
);
1438 return appendCallWithExceptionCheck(operation
);
1440 JITCompiler::Call
callOperation(V_JITOperation_EJPP operation
, GPRReg arg1
, GPRReg arg2
, void* pointer
)
1442 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, TrustedImmPtr(pointer
));
1443 return appendCallWithExceptionCheck(operation
);
1445 JITCompiler::Call
callOperation(V_JITOperation_ESsiJJI operation
, StructureStubInfo
* stubInfo
, GPRReg arg1
, GPRReg arg2
, UniquedStringImpl
* uid
)
1447 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(stubInfo
), arg1
, arg2
, TrustedImmPtr(uid
));
1448 return appendCallWithExceptionCheck(operation
);
1450 JITCompiler::Call
callOperation(V_JITOperation_EJJJ operation
, GPRReg arg1
, GPRReg arg2
, GPRReg arg3
)
1452 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, arg3
);
1453 return appendCallWithExceptionCheck(operation
);
1455 JITCompiler::Call
callOperation(V_JITOperation_EPZJ operation
, GPRReg arg1
, GPRReg arg2
, GPRReg arg3
)
1457 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, arg3
);
1458 return appendCallWithExceptionCheck(operation
);
1461 JITCompiler::Call
callOperation(V_JITOperation_EOZJ operation
, GPRReg arg1
, GPRReg arg2
, GPRReg arg3
)
1463 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, arg3
);
1464 return appendCallWithExceptionCheck(operation
);
1466 JITCompiler::Call
callOperation(V_JITOperation_ECJJ operation
, GPRReg arg1
, GPRReg arg2
, GPRReg arg3
)
1468 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, arg3
);
1469 return appendCallWithExceptionCheck(operation
);
1472 JITCompiler::Call
callOperation(D_JITOperation_EJ operation
, FPRReg result
, GPRReg arg1
)
1474 m_jit
.setupArgumentsWithExecState(arg1
);
1475 return appendCallWithExceptionCheckSetResult(operation
, result
);
1478 JITCompiler::Call
callOperation(Z_JITOperation_EJZZ operation
, GPRReg result
, GPRReg arg1
, unsigned arg2
, unsigned arg3
)
1480 m_jit
.setupArgumentsWithExecState(arg1
, TrustedImm32(arg2
), TrustedImm32(arg3
));
1481 return appendCallWithExceptionCheckSetResult(operation
, result
);
1483 JITCompiler::Call
callOperation(F_JITOperation_EFJZZ operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2
, unsigned arg3
, GPRReg arg4
)
1485 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, TrustedImm32(arg3
), arg4
);
1486 return appendCallWithExceptionCheckSetResult(operation
, result
);
1488 JITCompiler::Call
callOperation(Z_JITOperation_EJZ operation
, GPRReg result
, GPRReg arg1
, unsigned arg2
)
1490 m_jit
.setupArgumentsWithExecState(arg1
, TrustedImm32(arg2
));
1491 return appendCallWithExceptionCheckSetResult(operation
, result
);
1493 JITCompiler::Call
callOperation(V_JITOperation_EZJZZZ operation
, unsigned arg1
, GPRReg arg2
, unsigned arg3
, GPRReg arg4
, unsigned arg5
)
1495 m_jit
.setupArgumentsWithExecState(TrustedImm32(arg1
), arg2
, TrustedImm32(arg3
), arg4
, TrustedImm32(arg5
));
1496 return appendCallWithExceptionCheck(operation
);
1498 #else // USE(JSVALUE32_64)
1500 // 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]).
1501 // To avoid assemblies from using wrong registers, let's occupy r1 or r3 with a dummy argument when necessary.
1502 #if (COMPILER_SUPPORTS(EABI) && CPU(ARM)) || CPU(MIPS)
1503 #define EABI_32BIT_DUMMY_ARG TrustedImm32(0),
1505 #define EABI_32BIT_DUMMY_ARG
1508 // JSVALUE32_64 is a 64-bit integer that cannot be put half in an argument register and half on stack when using SH4 architecture.
1509 // To avoid this, let's occupy the 4th argument register (r7) with a dummy argument when necessary. This must only be done when there
1510 // is no other 32-bit value argument behind this 64-bit JSValue.
1512 #define SH4_32BIT_DUMMY_ARG TrustedImm32(0),
1514 #define SH4_32BIT_DUMMY_ARG
1517 JITCompiler::Call
callOperation(Z_JITOperation_D operation
, GPRReg result
, FPRReg arg1
)
1519 prepareForExternalCall();
1520 m_jit
.setupArguments(arg1
);
1521 JITCompiler::Call call
= m_jit
.appendCall(operation
);
1522 m_jit
.zeroExtend32ToPtr(GPRInfo::returnValueGPR
, result
);
1525 JITCompiler::Call
callOperation(J_JITOperation_E operation
, GPRReg resultTag
, GPRReg resultPayload
)
1527 m_jit
.setupArgumentsExecState();
1528 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1530 JITCompiler::Call
callOperation(J_JITOperation_EP operation
, GPRReg resultTag
, GPRReg resultPayload
, void* pointer
)
1532 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(pointer
));
1533 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1535 JITCompiler::Call
callOperation(J_JITOperation_EPP operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1
, void* pointer
)
1537 m_jit
.setupArgumentsWithExecState(arg1
, TrustedImmPtr(pointer
));
1538 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1540 JITCompiler::Call
callOperation(J_JITOperation_EP operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1
)
1542 m_jit
.setupArgumentsWithExecState(arg1
);
1543 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1545 JITCompiler::Call
callOperation(J_JITOperation_EI operation
, GPRReg resultTag
, GPRReg resultPayload
, UniquedStringImpl
* uid
)
1547 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(uid
));
1548 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1550 JITCompiler::Call
callOperation(J_JITOperation_EA operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1
)
1552 m_jit
.setupArgumentsWithExecState(arg1
);
1553 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1555 JITCompiler::Call
callOperation(J_JITOperation_EAZ operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1
, GPRReg arg2
)
1557 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1558 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1560 JITCompiler::Call
callOperation(J_JITOperation_EJ operation
, GPRReg resultPayload
, GPRReg resultTag
, GPRReg arg1
)
1562 m_jit
.setupArgumentsWithExecState(arg1
);
1563 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1565 JITCompiler::Call
callOperation(J_JITOperation_EJC operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1Tag
, GPRReg arg1Payload
, GPRReg arg2
)
1567 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
, arg2
);
1568 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1570 JITCompiler::Call
callOperation(J_JITOperation_EJssZ operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1
, GPRReg arg2
)
1572 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1573 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1575 JITCompiler::Call
callOperation(J_JITOperation_EPS operation
, GPRReg resultTag
, GPRReg resultPayload
, void* pointer
, size_t size
)
1577 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(pointer
), TrustedImmPtr(size
));
1578 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1580 JITCompiler::Call
callOperation(J_JITOperation_ESS operation
, GPRReg resultTag
, GPRReg resultPayload
, int startConstant
, int numConstants
)
1582 m_jit
.setupArgumentsWithExecState(TrustedImm32(startConstant
), TrustedImm32(numConstants
));
1583 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1585 JITCompiler::Call
callOperation(J_JITOperation_EJP operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1Tag
, GPRReg arg1Payload
, void* pointer
)
1587 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
, TrustedImmPtr(pointer
));
1588 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1590 JITCompiler::Call
callOperation(J_JITOperation_EJP operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1Tag
, GPRReg arg1Payload
, GPRReg arg2
)
1592 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
, arg2
);
1593 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1596 JITCompiler::Call
callOperation(J_JITOperation_EC operation
, GPRReg resultTag
, GPRReg resultPayload
, JSCell
* cell
)
1598 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(cell
));
1599 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1601 JITCompiler::Call
callOperation(J_JITOperation_ECZ operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1
, GPRReg arg2
)
1603 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1604 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1606 JITCompiler::Call
callOperation(J_JITOperation_EJscC operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1
, JSCell
* cell
)
1608 m_jit
.setupArgumentsWithExecState(arg1
, TrustedImmPtr(cell
));
1609 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1611 JITCompiler::Call
callOperation(J_JITOperation_ESsiCI operation
, GPRReg resultTag
, GPRReg resultPayload
, StructureStubInfo
* stubInfo
, GPRReg arg1
, const UniquedStringImpl
* uid
)
1613 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(stubInfo
), arg1
, TrustedImmPtr(uid
));
1614 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1616 JITCompiler::Call
callOperation(J_JITOperation_ESsiJI operation
, GPRReg resultTag
, GPRReg resultPayload
, StructureStubInfo
* stubInfo
, GPRReg arg1Tag
, GPRReg arg1Payload
, UniquedStringImpl
* uid
)
1618 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(stubInfo
), arg1Payload
, arg1Tag
, TrustedImmPtr(uid
));
1619 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1621 JITCompiler::Call
callOperation(J_JITOperation_ESsiJI operation
, GPRReg resultTag
, GPRReg resultPayload
, StructureStubInfo
* stubInfo
, int32_t arg1Tag
, GPRReg arg1Payload
, UniquedStringImpl
* uid
)
1623 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(stubInfo
), arg1Payload
, TrustedImm32(arg1Tag
), TrustedImmPtr(uid
));
1624 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1626 JITCompiler::Call
callOperation(J_JITOperation_EDA operation
, GPRReg resultTag
, GPRReg resultPayload
, FPRReg arg1
, GPRReg arg2
)
1628 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1
, arg2
);
1629 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1631 JITCompiler::Call
callOperation(J_JITOperation_EJA operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1Tag
, GPRReg arg1Payload
, GPRReg arg2
)
1633 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
, arg2
);
1634 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1636 JITCompiler::Call
callOperation(J_JITOperation_EJA operation
, GPRReg resultTag
, GPRReg resultPayload
, TrustedImm32 arg1Tag
, GPRReg arg1Payload
, GPRReg arg2
)
1638 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
, arg2
);
1639 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1641 JITCompiler::Call
callOperation(J_JITOperation_EJ operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1Tag
, GPRReg arg1Payload
)
1643 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
);
1644 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1646 JITCompiler::Call
callOperation(J_JITOperation_EZ operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1
)
1648 m_jit
.setupArgumentsWithExecState(arg1
);
1649 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1651 JITCompiler::Call
callOperation(J_JITOperation_EZ operation
, GPRReg resultTag
, GPRReg resultPayload
, int32_t arg1
)
1653 m_jit
.setupArgumentsWithExecState(TrustedImm32(arg1
));
1654 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1656 JITCompiler::Call
callOperation(J_JITOperation_EZIcfZ operation
, GPRReg resultTag
, GPRReg resultPayload
, int32_t arg1
, InlineCallFrame
* inlineCallFrame
, GPRReg arg2
)
1658 m_jit
.setupArgumentsWithExecState(TrustedImm32(arg1
), TrustedImmPtr(inlineCallFrame
), arg2
);
1659 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1661 JITCompiler::Call
callOperation(J_JITOperation_EZZ operation
, GPRReg resultTag
, GPRReg resultPayload
, int32_t arg1
, GPRReg arg2
)
1663 m_jit
.setupArgumentsWithExecState(TrustedImm32(arg1
), arg2
);
1664 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1667 JITCompiler::Call
callOperation(P_JITOperation_EJS operation
, GPRReg result
, JSValueRegs value
, size_t index
)
1669 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG value
.payloadGPR(), value
.tagGPR(), TrustedImmPtr(index
));
1670 return appendCallSetResult(operation
, result
);
1673 JITCompiler::Call
callOperation(P_JITOperation_EStJ operation
, GPRReg result
, Structure
* structure
, GPRReg arg2Tag
, GPRReg arg2Payload
)
1675 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(structure
), arg2Payload
, arg2Tag
);
1676 return appendCallWithExceptionCheckSetResult(operation
, result
);
1679 JITCompiler::Call
callOperation(C_JITOperation_EJ operation
, GPRReg result
, GPRReg arg1Tag
, GPRReg arg1Payload
)
1681 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
);
1682 return appendCallWithExceptionCheckSetResult(operation
, result
);
1684 JITCompiler::Call
callOperation(S_JITOperation_J operation
, GPRReg result
, GPRReg arg1Tag
, GPRReg arg1Payload
)
1686 m_jit
.setupArguments(arg1Payload
, arg1Tag
);
1687 return appendCallSetResult(operation
, result
);
1689 JITCompiler::Call
callOperation(S_JITOperation_EJ operation
, GPRReg result
, GPRReg arg1Tag
, GPRReg arg1Payload
)
1691 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
);
1692 return appendCallWithExceptionCheckSetResult(operation
, result
);
1695 JITCompiler::Call
callOperation(S_JITOperation_EJJ operation
, GPRReg result
, GPRReg arg1Tag
, GPRReg arg1Payload
, GPRReg arg2Tag
, GPRReg arg2Payload
)
1697 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
, SH4_32BIT_DUMMY_ARG arg2Payload
, arg2Tag
);
1698 return appendCallWithExceptionCheckSetResult(operation
, result
);
1700 JITCompiler::Call
callOperation(J_JITOperation_EJJ operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1Tag
, GPRReg arg1Payload
, GPRReg arg2Tag
, GPRReg arg2Payload
)
1702 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
, SH4_32BIT_DUMMY_ARG arg2Payload
, arg2Tag
);
1703 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1705 JITCompiler::Call
callOperation(J_JITOperation_EJJ operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1Tag
, GPRReg arg1Payload
, MacroAssembler::TrustedImm32 imm
)
1707 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
, SH4_32BIT_DUMMY_ARG imm
, TrustedImm32(JSValue::Int32Tag
));
1708 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1710 JITCompiler::Call
callOperation(J_JITOperation_EJJ operation
, GPRReg resultTag
, GPRReg resultPayload
, MacroAssembler::TrustedImm32 imm
, GPRReg arg2Tag
, GPRReg arg2Payload
)
1712 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG imm
, TrustedImm32(JSValue::Int32Tag
), SH4_32BIT_DUMMY_ARG arg2Payload
, arg2Tag
);
1713 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1716 JITCompiler::Call
callOperation(J_JITOperation_ECJ operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1
, GPRReg arg2Tag
, GPRReg arg2Payload
)
1718 m_jit
.setupArgumentsWithExecState(arg1
, arg2Payload
, arg2Tag
);
1719 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1721 JITCompiler::Call
callOperation(J_JITOperation_ECJ operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1
, GPRReg arg2Payload
)
1723 m_jit
.setupArgumentsWithExecState(arg1
, arg2Payload
, MacroAssembler::TrustedImm32(JSValue::CellTag
));
1724 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1726 JITCompiler::Call
callOperation(J_JITOperation_ECJ operation
, JSValueRegs result
, GPRReg arg1
, JSValueRegs arg2
)
1728 m_jit
.setupArgumentsWithExecState(arg1
, arg2
.payloadGPR(), arg2
.tagGPR());
1729 return appendCallWithExceptionCheckSetResult(operation
, result
.payloadGPR(), result
.tagGPR());
1731 JITCompiler::Call
callOperation(J_JITOperation_ECC operation
, GPRReg resultTag
, GPRReg resultPayload
, GPRReg arg1
, GPRReg arg2
)
1733 m_jit
.setupArgumentsWithExecState(arg1
, arg2
);
1734 return appendCallWithExceptionCheckSetResult(operation
, resultPayload
, resultTag
);
1737 JITCompiler::Call
callOperation(V_JITOperation_EOZD operation
, GPRReg arg1
, GPRReg arg2
, FPRReg arg3
)
1739 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, EABI_32BIT_DUMMY_ARG arg3
);
1740 return appendCallWithExceptionCheck(operation
);
1743 JITCompiler::Call
callOperation(V_JITOperation_EJ operation
, GPRReg arg1Tag
, GPRReg arg1Payload
)
1745 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
);
1746 return appendCallWithExceptionCheck(operation
);
1749 JITCompiler::Call
callOperation(V_JITOperation_EJPP operation
, GPRReg arg1Tag
, GPRReg arg1Payload
, GPRReg arg2
, void* pointer
)
1751 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
, arg2
, TrustedImmPtr(pointer
));
1752 return appendCallWithExceptionCheck(operation
);
1754 JITCompiler::Call
callOperation(V_JITOperation_ESsiJJI operation
, StructureStubInfo
* stubInfo
, GPRReg arg1Tag
, GPRReg arg1Payload
, GPRReg arg2Payload
, UniquedStringImpl
* uid
)
1756 m_jit
.setupArgumentsWithExecState(TrustedImmPtr(stubInfo
), arg1Payload
, arg1Tag
, arg2Payload
, TrustedImm32(JSValue::CellTag
), TrustedImmPtr(uid
));
1757 return appendCallWithExceptionCheck(operation
);
1759 JITCompiler::Call
callOperation(V_JITOperation_ECJJ operation
, GPRReg arg1
, GPRReg arg2Tag
, GPRReg arg2Payload
, GPRReg arg3Tag
, GPRReg arg3Payload
)
1761 m_jit
.setupArgumentsWithExecState(arg1
, arg2Payload
, arg2Tag
, arg3Payload
, arg3Tag
);
1762 return appendCallWithExceptionCheck(operation
);
1765 JITCompiler::Call
callOperation(V_JITOperation_EPZJ operation
, GPRReg arg1
, GPRReg arg2
, GPRReg arg3Tag
, GPRReg arg3Payload
)
1767 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload
, arg3Tag
);
1768 return appendCallWithExceptionCheck(operation
);
1771 JITCompiler::Call
callOperation(V_JITOperation_EOZJ operation
, GPRReg arg1
, GPRReg arg2
, GPRReg arg3Tag
, GPRReg arg3Payload
)
1773 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload
, arg3Tag
);
1774 return appendCallWithExceptionCheck(operation
);
1776 JITCompiler::Call
callOperation(V_JITOperation_EOZJ operation
, GPRReg arg1
, GPRReg arg2
, TrustedImm32 arg3Tag
, GPRReg arg3Payload
)
1778 m_jit
.setupArgumentsWithExecState(arg1
, arg2
, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload
, arg3Tag
);
1779 return appendCallWithExceptionCheck(operation
);
1782 JITCompiler::Call
callOperation(D_JITOperation_EJ operation
, FPRReg result
, GPRReg arg1Tag
, GPRReg arg1Payload
)
1784 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
);
1785 return appendCallWithExceptionCheckSetResult(operation
, result
);
1788 JITCompiler::Call
callOperation(Z_JITOperation_EJZZ operation
, GPRReg result
, GPRReg arg1Tag
, GPRReg arg1Payload
, unsigned arg2
, unsigned arg3
)
1790 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
, TrustedImm32(arg2
), TrustedImm32(arg3
));
1791 return appendCallWithExceptionCheckSetResult(operation
, result
);
1793 JITCompiler::Call
callOperation(F_JITOperation_EFJZZ operation
, GPRReg result
, GPRReg arg1
, GPRReg arg2Tag
, GPRReg arg2Payload
, unsigned arg3
, GPRReg arg4
)
1795 m_jit
.setupArgumentsWithExecState(arg1
, arg2Payload
, arg2Tag
, TrustedImm32(arg3
), arg4
);
1796 return appendCallWithExceptionCheckSetResult(operation
, result
);
1798 JITCompiler::Call
callOperation(Z_JITOperation_EJZ operation
, GPRReg result
, GPRReg arg1Tag
, GPRReg arg1Payload
, unsigned arg2
)
1800 m_jit
.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload
, arg1Tag
, TrustedImm32(arg2
));
1801 return appendCallWithExceptionCheckSetResult(operation
, result
);
1803 JITCompiler::Call
callOperation(V_JITOperation_EZJZZZ operation
, unsigned arg1
, GPRReg arg2Tag
, GPRReg arg2Payload
, unsigned arg3
, GPRReg arg4
, unsigned arg5
)
1805 m_jit
.setupArgumentsWithExecState(TrustedImm32(arg1
), arg2Payload
, arg2Tag
, TrustedImm32(arg3
), arg4
, TrustedImm32(arg5
));
1806 return appendCallWithExceptionCheck(operation
);
1808 #undef EABI_32BIT_DUMMY_ARG
1809 #undef SH4_32BIT_DUMMY_ARG
1811 template<typename FunctionType
>
1812 JITCompiler::Call
callOperation(
1813 FunctionType operation
, JSValueRegs result
)
1815 return callOperation(operation
, result
.tagGPR(), result
.payloadGPR());
1817 template<typename FunctionType
, typename ArgumentType1
>
1818 JITCompiler::Call
callOperation(
1819 FunctionType operation
, JSValueRegs result
, ArgumentType1 arg1
)
1821 return callOperation(operation
, result
.tagGPR(), result
.payloadGPR(), arg1
);
1823 template<typename FunctionType
, typename ArgumentType1
, typename ArgumentType2
>
1824 JITCompiler::Call
callOperation(
1825 FunctionType operation
, JSValueRegs result
, ArgumentType1 arg1
, ArgumentType2 arg2
)
1827 return callOperation(operation
, result
.tagGPR(), result
.payloadGPR(), arg1
, arg2
);
1830 typename FunctionType
, typename ArgumentType1
, typename ArgumentType2
,
1831 typename ArgumentType3
>
1832 JITCompiler::Call
callOperation(
1833 FunctionType operation
, JSValueRegs result
, ArgumentType1 arg1
, ArgumentType2 arg2
,
1836 return callOperation(operation
, result
.tagGPR(), result
.payloadGPR(), arg1
, arg2
, arg3
);
1839 typename FunctionType
, typename ArgumentType1
, typename ArgumentType2
,
1840 typename ArgumentType3
, typename ArgumentType4
>
1841 JITCompiler::Call
callOperation(
1842 FunctionType operation
, JSValueRegs result
, ArgumentType1 arg1
, ArgumentType2 arg2
,
1843 ArgumentType3 arg3
, ArgumentType4 arg4
)
1845 return callOperation(operation
, result
.tagGPR(), result
.payloadGPR(), arg1
, arg2
, arg3
, arg4
);
1848 typename FunctionType
, typename ArgumentType1
, typename ArgumentType2
,
1849 typename ArgumentType3
, typename ArgumentType4
, typename ArgumentType5
>
1850 JITCompiler::Call
callOperation(
1851 FunctionType operation
, JSValueRegs result
, ArgumentType1 arg1
, ArgumentType2 arg2
,
1852 ArgumentType3 arg3
, ArgumentType4 arg4
, ArgumentType5 arg5
)
1854 return callOperation(
1855 operation
, result
.tagGPR(), result
.payloadGPR(), arg1
, arg2
, arg3
, arg4
, arg5
);
1857 #endif // USE(JSVALUE32_64)
1859 #if !defined(NDEBUG) && !CPU(ARM) && !CPU(MIPS) && !CPU(SH4)
1860 void prepareForExternalCall()
1862 // We're about to call out to a "native" helper function. The helper
1863 // function is expected to set topCallFrame itself with the ExecState
1864 // that is passed to it.
1866 // We explicitly trash topCallFrame here so that we'll know if some of
1867 // the helper functions are not setting topCallFrame when they should
1868 // be doing so. Note: the previous value in topcallFrame was not valid
1869 // anyway since it was not being updated by JIT'ed code by design.
1871 for (unsigned i
= 0; i
< sizeof(void*) / 4; i
++)
1872 m_jit
.store32(TrustedImm32(0xbadbeef), reinterpret_cast<char*>(&m_jit
.vm()->topCallFrame
) + i
* 4);
1875 void prepareForExternalCall() { }
1878 // These methods add call instructions, with optional exception checks & setting results.
1879 JITCompiler::Call
appendCallWithExceptionCheck(const FunctionPtr
& function
)
1881 prepareForExternalCall();
1882 m_jit
.emitStoreCodeOrigin(m_currentNode
->origin
.semantic
);
1883 JITCompiler::Call call
= m_jit
.appendCall(function
);
1884 m_jit
.exceptionCheck();
1887 JITCompiler::Call
appendCallWithCallFrameRollbackOnException(const FunctionPtr
& function
)
1889 prepareForExternalCall();
1890 m_jit
.emitStoreCodeOrigin(m_currentNode
->origin
.semantic
);
1891 JITCompiler::Call call
= m_jit
.appendCall(function
);
1892 m_jit
.exceptionCheckWithCallFrameRollback();
1895 JITCompiler::Call
appendCallWithExceptionCheckSetResult(const FunctionPtr
& function
, GPRReg result
)
1897 JITCompiler::Call call
= appendCallWithExceptionCheck(function
);
1898 if ((result
!= InvalidGPRReg
) && (result
!= GPRInfo::returnValueGPR
))
1899 m_jit
.move(GPRInfo::returnValueGPR
, result
);
1902 JITCompiler::Call
appendCallWithCallFrameRollbackOnExceptionSetResult(const FunctionPtr
& function
, GPRReg result
)
1904 JITCompiler::Call call
= appendCallWithCallFrameRollbackOnException(function
);
1905 if ((result
!= InvalidGPRReg
) && (result
!= GPRInfo::returnValueGPR
))
1906 m_jit
.move(GPRInfo::returnValueGPR
, result
);
1909 JITCompiler::Call
appendCallSetResult(const FunctionPtr
& function
, GPRReg result
)
1911 prepareForExternalCall();
1912 m_jit
.emitStoreCodeOrigin(m_currentNode
->origin
.semantic
);
1913 JITCompiler::Call call
= m_jit
.appendCall(function
);
1914 if (result
!= InvalidGPRReg
)
1915 m_jit
.move(GPRInfo::returnValueGPR
, result
);
1918 JITCompiler::Call
appendCall(const FunctionPtr
& function
)
1920 prepareForExternalCall();
1921 m_jit
.emitStoreCodeOrigin(m_currentNode
->origin
.semantic
);
1922 return m_jit
.appendCall(function
);
1924 JITCompiler::Call
appendCallWithExceptionCheckSetResult(const FunctionPtr
& function
, GPRReg result1
, GPRReg result2
)
1926 JITCompiler::Call call
= appendCallWithExceptionCheck(function
);
1927 m_jit
.setupResults(result1
, result2
);
1931 JITCompiler::Call
appendCallWithExceptionCheckSetResult(const FunctionPtr
& function
, FPRReg result
)
1933 JITCompiler::Call call
= appendCallWithExceptionCheck(function
);
1934 if (result
!= InvalidFPRReg
) {
1935 m_jit
.assembler().fstpl(0, JITCompiler::stackPointerRegister
);
1936 m_jit
.loadDouble(JITCompiler::stackPointerRegister
, result
);
1940 JITCompiler::Call
appendCallSetResult(const FunctionPtr
& function
, FPRReg result
)
1942 JITCompiler::Call call
= appendCall(function
);
1943 if (result
!= InvalidFPRReg
) {
1944 m_jit
.assembler().fstpl(0, JITCompiler::stackPointerRegister
);
1945 m_jit
.loadDouble(JITCompiler::stackPointerRegister
, result
);
1949 #elif CPU(ARM) && !CPU(ARM_HARDFP)
1950 JITCompiler::Call
appendCallWithExceptionCheckSetResult(const FunctionPtr
& function
, FPRReg result
)
1952 JITCompiler::Call call
= appendCallWithExceptionCheck(function
);
1953 if (result
!= InvalidFPRReg
)
1954 m_jit
.assembler().vmov(result
, GPRInfo::returnValueGPR
, GPRInfo::returnValueGPR2
);
1957 JITCompiler::Call
appendCallSetResult(const FunctionPtr
& function
, FPRReg result
)
1959 JITCompiler::Call call
= appendCall(function
);
1960 if (result
!= InvalidFPRReg
)
1961 m_jit
.assembler().vmov(result
, GPRInfo::returnValueGPR
, GPRInfo::returnValueGPR2
);
1964 #else // CPU(X86_64) || (CPU(ARM) && CPU(ARM_HARDFP)) || CPU(ARM64) || CPU(MIPS) || CPU(SH4)
1965 JITCompiler::Call
appendCallWithExceptionCheckSetResult(const FunctionPtr
& function
, FPRReg result
)
1967 JITCompiler::Call call
= appendCallWithExceptionCheck(function
);
1968 if (result
!= InvalidFPRReg
)
1969 m_jit
.moveDouble(FPRInfo::returnValueFPR
, result
);
1972 JITCompiler::Call
appendCallSetResult(const FunctionPtr
& function
, FPRReg result
)
1974 JITCompiler::Call call
= appendCall(function
);
1975 if (result
!= InvalidFPRReg
)
1976 m_jit
.moveDouble(FPRInfo::returnValueFPR
, result
);
1981 void branchDouble(JITCompiler::DoubleCondition cond
, FPRReg left
, FPRReg right
, BasicBlock
* destination
)
1983 return addBranch(m_jit
.branchDouble(cond
, left
, right
), destination
);
1986 void branchDoubleNonZero(FPRReg value
, FPRReg scratch
, BasicBlock
* destination
)
1988 return addBranch(m_jit
.branchDoubleNonZero(value
, scratch
), destination
);
1991 template<typename T
, typename U
>
1992 void branch32(JITCompiler::RelationalCondition cond
, T left
, U right
, BasicBlock
* destination
)
1994 return addBranch(m_jit
.branch32(cond
, left
, right
), destination
);
1997 template<typename T
, typename U
>
1998 void branchTest32(JITCompiler::ResultCondition cond
, T value
, U mask
, BasicBlock
* destination
)
2000 return addBranch(m_jit
.branchTest32(cond
, value
, mask
), destination
);
2003 template<typename T
>
2004 void branchTest32(JITCompiler::ResultCondition cond
, T value
, BasicBlock
* destination
)
2006 return addBranch(m_jit
.branchTest32(cond
, value
), destination
);
2010 template<typename T
, typename U
>
2011 void branch64(JITCompiler::RelationalCondition cond
, T left
, U right
, BasicBlock
* destination
)
2013 return addBranch(m_jit
.branch64(cond
, left
, right
), destination
);
2017 template<typename T
, typename U
>
2018 void branch8(JITCompiler::RelationalCondition cond
, T left
, U right
, BasicBlock
* destination
)
2020 return addBranch(m_jit
.branch8(cond
, left
, right
), destination
);
2023 template<typename T
, typename U
>
2024 void branchPtr(JITCompiler::RelationalCondition cond
, T left
, U right
, BasicBlock
* destination
)
2026 return addBranch(m_jit
.branchPtr(cond
, left
, right
), destination
);
2029 template<typename T
, typename U
>
2030 void branchTestPtr(JITCompiler::ResultCondition cond
, T value
, U mask
, BasicBlock
* destination
)
2032 return addBranch(m_jit
.branchTestPtr(cond
, value
, mask
), destination
);
2035 template<typename T
>
2036 void branchTestPtr(JITCompiler::ResultCondition cond
, T value
, BasicBlock
* destination
)
2038 return addBranch(m_jit
.branchTestPtr(cond
, value
), destination
);
2041 template<typename T
, typename U
>
2042 void branchTest8(JITCompiler::ResultCondition cond
, T value
, U mask
, BasicBlock
* destination
)
2044 return addBranch(m_jit
.branchTest8(cond
, value
, mask
), destination
);
2047 template<typename T
>
2048 void branchTest8(JITCompiler::ResultCondition cond
, T value
, BasicBlock
* destination
)
2050 return addBranch(m_jit
.branchTest8(cond
, value
), destination
);
2053 enum FallThroughMode
{
2057 void jump(BasicBlock
* destination
, FallThroughMode fallThroughMode
= AtFallThroughPoint
)
2059 if (destination
== nextBlock()
2060 && fallThroughMode
== AtFallThroughPoint
)
2062 addBranch(m_jit
.jump(), destination
);
2065 void addBranch(const MacroAssembler::Jump
& jump
, BasicBlock
* destination
)
2067 m_branches
.append(BranchRecord(jump
, destination
));
2069 void addBranch(const MacroAssembler::JumpList
& jump
, BasicBlock
* destination
);
2071 void linkBranches();
2073 void dump(const char* label
= 0);
2075 bool betterUseStrictInt52(Node
* node
)
2077 return !generationInfo(node
).isInt52();
2079 bool betterUseStrictInt52(Edge edge
)
2081 return betterUseStrictInt52(edge
.node());
2084 bool compare(Node
*, MacroAssembler::RelationalCondition
, MacroAssembler::DoubleCondition
, S_JITOperation_EJJ
);
2085 bool compilePeepHoleBranch(Node
*, MacroAssembler::RelationalCondition
, MacroAssembler::DoubleCondition
, S_JITOperation_EJJ
);
2086 void compilePeepHoleInt32Branch(Node
*, Node
* branchNode
, JITCompiler::RelationalCondition
);
2087 void compilePeepHoleInt52Branch(Node
*, Node
* branchNode
, JITCompiler::RelationalCondition
);
2088 void compilePeepHoleBooleanBranch(Node
*, Node
* branchNode
, JITCompiler::RelationalCondition
);
2089 void compilePeepHoleDoubleBranch(Node
*, Node
* branchNode
, JITCompiler::DoubleCondition
);
2090 void compilePeepHoleObjectEquality(Node
*, Node
* branchNode
);
2091 void compilePeepHoleObjectStrictEquality(Edge objectChild
, Edge otherChild
, Node
* branchNode
);
2092 void compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild
, Edge rightChild
, Node
* branchNode
);
2093 void compileObjectEquality(Node
*);
2094 void compileObjectStrictEquality(Edge objectChild
, Edge otherChild
);
2095 void compileObjectToObjectOrOtherEquality(Edge leftChild
, Edge rightChild
);
2096 void compileObjectOrOtherLogicalNot(Edge value
);
2097 void compileLogicalNot(Node
*);
2098 void compileStringEquality(
2099 Node
*, GPRReg leftGPR
, GPRReg rightGPR
, GPRReg lengthGPR
,
2100 GPRReg leftTempGPR
, GPRReg rightTempGPR
, GPRReg leftTemp2GPR
,
2101 GPRReg rightTemp2GPR
, JITCompiler::JumpList fastTrue
,
2102 JITCompiler::JumpList fastSlow
);
2103 void compileStringEquality(Node
*);
2104 void compileStringIdentEquality(Node
*);
2105 void compileStringToUntypedEquality(Node
*, Edge stringEdge
, Edge untypedEdge
);
2106 void compileStringIdentToNotStringVarEquality(Node
*, Edge stringEdge
, Edge notStringVarEdge
);
2107 void compileStringZeroLength(Node
*);
2108 void compileMiscStrictEq(Node
*);
2110 void emitObjectOrOtherBranch(Edge value
, BasicBlock
* taken
, BasicBlock
* notTaken
);
2111 void emitStringBranch(Edge value
, BasicBlock
* taken
, BasicBlock
* notTaken
);
2112 void emitBranch(Node
*);
2114 struct StringSwitchCase
{
2115 StringSwitchCase() { }
2117 StringSwitchCase(StringImpl
* string
, BasicBlock
* target
)
2123 bool operator<(const StringSwitchCase
& other
) const
2125 return stringLessThan(*string
, *other
.string
);
2132 void emitSwitchIntJump(SwitchData
*, GPRReg value
, GPRReg scratch
);
2133 void emitSwitchImm(Node
*, SwitchData
*);
2134 void emitSwitchCharStringJump(SwitchData
*, GPRReg value
, GPRReg scratch
);
2135 void emitSwitchChar(Node
*, SwitchData
*);
2136 void emitBinarySwitchStringRecurse(
2137 SwitchData
*, const Vector
<StringSwitchCase
>&, unsigned numChecked
,
2138 unsigned begin
, unsigned end
, GPRReg buffer
, GPRReg length
, GPRReg temp
,
2139 unsigned alreadyCheckedLength
, bool checkedExactLength
);
2140 void emitSwitchStringOnString(SwitchData
*, GPRReg string
);
2141 void emitSwitchString(Node
*, SwitchData
*);
2142 void emitSwitch(Node
*);
2144 void compileToStringOrCallStringConstructorOnCell(Node
*);
2145 void compileNewStringObject(Node
*);
2147 void compileNewTypedArray(Node
*);
2149 void compileInt32Compare(Node
*, MacroAssembler::RelationalCondition
);
2150 void compileInt52Compare(Node
*, MacroAssembler::RelationalCondition
);
2151 void compileBooleanCompare(Node
*, MacroAssembler::RelationalCondition
);
2152 void compileDoubleCompare(Node
*, MacroAssembler::DoubleCondition
);
2154 bool compileStrictEq(Node
*);
2156 void compileAllocatePropertyStorage(Node
*);
2157 void compileReallocatePropertyStorage(Node
*);
2159 #if USE(JSVALUE32_64)
2160 template<typename BaseOperandType
, typename PropertyOperandType
, typename ValueOperandType
, typename TagType
>
2161 void compileContiguousPutByVal(Node
*, BaseOperandType
&, PropertyOperandType
&, ValueOperandType
&, GPRReg valuePayloadReg
, TagType valueTag
);
2163 void compileDoublePutByVal(Node
*, SpeculateCellOperand
& base
, SpeculateStrictInt32Operand
& property
);
2164 bool putByValWillNeedExtraRegister(ArrayMode arrayMode
)
2166 return arrayMode
.mayStoreToHole();
2168 GPRReg
temporaryRegisterForPutByVal(GPRTemporary
&, ArrayMode
);
2169 GPRReg
temporaryRegisterForPutByVal(GPRTemporary
& temporary
, Node
* node
)
2171 return temporaryRegisterForPutByVal(temporary
, node
->arrayMode());
2174 void compileGetCharCodeAt(Node
*);
2175 void compileGetByValOnString(Node
*);
2176 void compileFromCharCode(Node
*);
2178 void compileGetByValOnDirectArguments(Node
*);
2179 void compileGetByValOnScopedArguments(Node
*);
2181 void compileGetScope(Node
*);
2182 void compileSkipScope(Node
*);
2184 void compileGetArrayLength(Node
*);
2186 void compileValueRep(Node
*);
2187 void compileDoubleRep(Node
*);
2189 void compileValueToInt32(Node
*);
2190 void compileUInt32ToNumber(Node
*);
2191 void compileDoubleAsInt32(Node
*);
2192 void compileAdd(Node
*);
2193 void compileMakeRope(Node
*);
2194 void compileArithClz32(Node
*);
2195 void compileArithSub(Node
*);
2196 void compileArithNegate(Node
*);
2197 void compileArithMul(Node
*);
2198 void compileArithDiv(Node
*);
2199 void compileArithMod(Node
*);
2200 void compileArithPow(Node
*);
2201 void compileArithRound(Node
*);
2202 void compileArithSqrt(Node
*);
2203 void compileArithLog(Node
*);
2204 void compileConstantStoragePointer(Node
*);
2205 void compileGetIndexedPropertyStorage(Node
*);
2206 JITCompiler::Jump
jumpForTypedArrayOutOfBounds(Node
*, GPRReg baseGPR
, GPRReg indexGPR
);
2207 void emitTypedArrayBoundsCheck(Node
*, GPRReg baseGPR
, GPRReg indexGPR
);
2208 void compileGetTypedArrayByteOffset(Node
*);
2209 void compileGetByValOnIntTypedArray(Node
*, TypedArrayType
);
2210 void compilePutByValForIntTypedArray(GPRReg base
, GPRReg property
, Node
*, TypedArrayType
);
2211 void compileGetByValOnFloatTypedArray(Node
*, TypedArrayType
);
2212 void compilePutByValForFloatTypedArray(GPRReg base
, GPRReg property
, Node
*, TypedArrayType
);
2213 void compileNewFunction(Node
*);
2214 void compileForwardVarargs(Node
*);
2215 void compileCreateActivation(Node
*);
2216 void compileCreateDirectArguments(Node
*);
2217 void compileGetFromArguments(Node
*);
2218 void compilePutToArguments(Node
*);
2219 void compileCreateScopedArguments(Node
*);
2220 void compileCreateClonedArguments(Node
*);
2221 void compileNotifyWrite(Node
*);
2222 bool compileRegExpExec(Node
*);
2223 void compileIsObjectOrNull(Node
*);
2224 void compileIsFunction(Node
*);
2225 void compileTypeOf(Node
*);
2227 void moveTrueTo(GPRReg
);
2228 void moveFalseTo(GPRReg
);
2229 void blessBoolean(GPRReg
);
2231 // size can be an immediate or a register, and must be in bytes. If size is a register,
2232 // it must be a different register than resultGPR. Emits code that place a pointer to
2233 // the end of the allocation. The returned jump is the jump to the slow path.
2234 template<typename SizeType
>
2235 MacroAssembler::Jump
emitAllocateBasicStorage(SizeType size
, GPRReg resultGPR
)
2237 CopiedAllocator
* copiedAllocator
= &m_jit
.vm()->heap
.storageAllocator();
2239 // It's invalid to allocate zero bytes in CopiedSpace.
2241 m_jit
.move(size
, resultGPR
);
2242 MacroAssembler::Jump nonZeroSize
= m_jit
.branchTest32(MacroAssembler::NonZero
, resultGPR
);
2243 m_jit
.abortWithReason(DFGBasicStorageAllocatorZeroSize
);
2244 nonZeroSize
.link(&m_jit
);
2247 m_jit
.loadPtr(&copiedAllocator
->m_currentRemaining
, resultGPR
);
2248 MacroAssembler::Jump slowPath
= m_jit
.branchSubPtr(JITCompiler::Signed
, size
, resultGPR
);
2249 m_jit
.storePtr(resultGPR
, &copiedAllocator
->m_currentRemaining
);
2250 m_jit
.negPtr(resultGPR
);
2251 m_jit
.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator
->m_currentPayloadEnd
), resultGPR
);
2256 // Allocator for a cell of a specific size.
2257 template <typename StructureType
> // StructureType can be GPR or ImmPtr.
2258 void emitAllocateJSCell(GPRReg resultGPR
, GPRReg allocatorGPR
, StructureType structure
,
2259 GPRReg scratchGPR
, MacroAssembler::JumpList
& slowPath
)
2261 m_jit
.loadPtr(MacroAssembler::Address(allocatorGPR
, MarkedAllocator::offsetOfFreeListHead()), resultGPR
);
2262 slowPath
.append(m_jit
.branchTestPtr(MacroAssembler::Zero
, resultGPR
));
2264 // The object is half-allocated: we have what we know is a fresh object, but
2265 // it's still on the GC's free list.
2266 m_jit
.loadPtr(MacroAssembler::Address(resultGPR
), scratchGPR
);
2267 m_jit
.storePtr(scratchGPR
, MacroAssembler::Address(allocatorGPR
, MarkedAllocator::offsetOfFreeListHead()));
2269 // Initialize the object's Structure.
2270 m_jit
.emitStoreStructureWithTypeInfo(structure
, resultGPR
, scratchGPR
);
2273 // Allocator for an object of a specific size.
2274 template <typename StructureType
, typename StorageType
> // StructureType and StorageType can be GPR or ImmPtr.
2275 void emitAllocateJSObject(GPRReg resultGPR
, GPRReg allocatorGPR
, StructureType structure
,
2276 StorageType storage
, GPRReg scratchGPR
, MacroAssembler::JumpList
& slowPath
)
2278 emitAllocateJSCell(resultGPR
, allocatorGPR
, structure
, scratchGPR
, slowPath
);
2280 // Initialize the object's property storage pointer.
2281 m_jit
.storePtr(storage
, MacroAssembler::Address(resultGPR
, JSObject::butterflyOffset()));
2284 template <typename ClassType
, typename StructureType
, typename StorageType
> // StructureType and StorageType can be GPR or ImmPtr.
2285 void emitAllocateJSObjectWithKnownSize(
2286 GPRReg resultGPR
, StructureType structure
, StorageType storage
, GPRReg scratchGPR1
,
2287 GPRReg scratchGPR2
, MacroAssembler::JumpList
& slowPath
, size_t size
)
2289 MarkedAllocator
* allocator
= &m_jit
.vm()->heap
.allocatorForObjectOfType
<ClassType
>(size
);
2290 m_jit
.move(TrustedImmPtr(allocator
), scratchGPR1
);
2291 emitAllocateJSObject(resultGPR
, scratchGPR1
, structure
, storage
, scratchGPR2
, slowPath
);
2294 // Convenience allocator for a built-in object.
2295 template <typename ClassType
, typename StructureType
, typename StorageType
> // StructureType and StorageType can be GPR or ImmPtr.
2296 void emitAllocateJSObject(GPRReg resultGPR
, StructureType structure
, StorageType storage
,
2297 GPRReg scratchGPR1
, GPRReg scratchGPR2
, MacroAssembler::JumpList
& slowPath
)
2299 emitAllocateJSObjectWithKnownSize
<ClassType
>(
2300 resultGPR
, structure
, storage
, scratchGPR1
, scratchGPR2
, slowPath
,
2301 ClassType::allocationSize(0));
2304 template <typename ClassType
, typename StructureType
> // StructureType and StorageType can be GPR or ImmPtr.
2305 void emitAllocateVariableSizedJSObject(GPRReg resultGPR
, StructureType structure
, GPRReg allocationSize
, GPRReg scratchGPR1
, GPRReg scratchGPR2
, MacroAssembler::JumpList
& slowPath
)
2307 static_assert(!(MarkedSpace::preciseStep
& (MarkedSpace::preciseStep
- 1)), "MarkedSpace::preciseStep must be a power of two.");
2308 static_assert(!(MarkedSpace::impreciseStep
& (MarkedSpace::impreciseStep
- 1)), "MarkedSpace::impreciseStep must be a power of two.");
2310 MarkedSpace::Subspace
& subspace
= m_jit
.vm()->heap
.subspaceForObjectOfType
<ClassType
>();
2311 m_jit
.add32(TrustedImm32(MarkedSpace::preciseStep
- 1), allocationSize
);
2312 MacroAssembler::Jump notSmall
= m_jit
.branch32(MacroAssembler::AboveOrEqual
, allocationSize
, TrustedImm32(MarkedSpace::preciseCutoff
));
2313 m_jit
.rshift32(allocationSize
, TrustedImm32(getLSBSet(MarkedSpace::preciseStep
)), scratchGPR1
);
2314 m_jit
.mul32(TrustedImm32(sizeof(MarkedAllocator
)), scratchGPR1
, scratchGPR1
);
2315 m_jit
.addPtr(MacroAssembler::TrustedImmPtr(&subspace
.preciseAllocators
[0]), scratchGPR1
);
2317 MacroAssembler::Jump selectedSmallSpace
= m_jit
.jump();
2318 notSmall
.link(&m_jit
);
2319 slowPath
.append(m_jit
.branch32(MacroAssembler::AboveOrEqual
, allocationSize
, TrustedImm32(MarkedSpace::impreciseCutoff
)));
2320 m_jit
.rshift32(allocationSize
, TrustedImm32(getLSBSet(MarkedSpace::impreciseStep
)), scratchGPR1
);
2321 m_jit
.mul32(TrustedImm32(sizeof(MarkedAllocator
)), scratchGPR1
, scratchGPR1
);
2322 m_jit
.addPtr(MacroAssembler::TrustedImmPtr(&subspace
.impreciseAllocators
[0]), scratchGPR1
);
2324 selectedSmallSpace
.link(&m_jit
);
2326 emitAllocateJSObject(resultGPR
, scratchGPR1
, structure
, TrustedImmPtr(0), scratchGPR2
, slowPath
);
2329 template <typename T
>
2330 void emitAllocateDestructibleObject(GPRReg resultGPR
, Structure
* structure
,
2331 GPRReg scratchGPR1
, GPRReg scratchGPR2
, MacroAssembler::JumpList
& slowPath
)
2333 emitAllocateJSObject
<T
>(resultGPR
, TrustedImmPtr(structure
), TrustedImmPtr(0), scratchGPR1
, scratchGPR2
, slowPath
);
2334 m_jit
.storePtr(TrustedImmPtr(structure
->classInfo()), MacroAssembler::Address(resultGPR
, JSDestructibleObject::classInfoOffset()));
2337 void emitAllocateJSArray(GPRReg resultGPR
, Structure
*, GPRReg storageGPR
, unsigned numElements
);
2339 void emitGetLength(InlineCallFrame
*, GPRReg lengthGPR
, bool includeThis
= false);
2340 void emitGetLength(CodeOrigin
, GPRReg lengthGPR
, bool includeThis
= false);
2341 void emitGetCallee(CodeOrigin
, GPRReg calleeGPR
);
2342 void emitGetArgumentStart(CodeOrigin
, GPRReg startGPR
);
2344 // Generate an OSR exit fuzz check. Returns Jump() if OSR exit fuzz is not enabled, or if
2345 // it's in training mode.
2346 MacroAssembler::Jump
emitOSRExitFuzzCheck();
2348 // Add a speculation check.
2349 void speculationCheck(ExitKind
, JSValueSource
, Node
*, MacroAssembler::Jump jumpToFail
);
2350 void speculationCheck(ExitKind
, JSValueSource
, Node
*, const MacroAssembler::JumpList
& jumpsToFail
);
2352 // Add a speculation check without additional recovery, and with a promise to supply a jump later.
2353 OSRExitJumpPlaceholder
speculationCheck(ExitKind
, JSValueSource
, Node
*);
2354 OSRExitJumpPlaceholder
speculationCheck(ExitKind
, JSValueSource
, Edge
);
2355 void speculationCheck(ExitKind
, JSValueSource
, Edge
, MacroAssembler::Jump jumpToFail
);
2356 void speculationCheck(ExitKind
, JSValueSource
, Edge
, const MacroAssembler::JumpList
& jumpsToFail
);
2357 // Add a speculation check with additional recovery.
2358 void speculationCheck(ExitKind
, JSValueSource
, Node
*, MacroAssembler::Jump jumpToFail
, const SpeculationRecovery
&);
2359 void speculationCheck(ExitKind
, JSValueSource
, Edge
, MacroAssembler::Jump jumpToFail
, const SpeculationRecovery
&);
2361 void emitInvalidationPoint(Node
*);
2363 // Called when we statically determine that a speculation will fail.
2364 void terminateSpeculativeExecution(ExitKind
, JSValueRegs
, Node
*);
2365 void terminateSpeculativeExecution(ExitKind
, JSValueRegs
, Edge
);
2367 // Helpers for performing type checks on an edge stored in the given registers.
2368 bool needsTypeCheck(Edge edge
, SpeculatedType typesPassedThrough
) { return m_interpreter
.needsTypeCheck(edge
, typesPassedThrough
); }
2369 void typeCheck(JSValueSource
, Edge
, SpeculatedType typesPassedThrough
, MacroAssembler::Jump jumpToFail
);
2371 void speculateCellTypeWithoutTypeFiltering(Edge
, GPRReg cellGPR
, JSType
);
2372 void speculateCellType(Edge
, GPRReg cellGPR
, SpeculatedType
, JSType
);
2374 void speculateInt32(Edge
);
2376 void convertMachineInt(Edge
, GPRReg resultGPR
);
2377 void speculateMachineInt(Edge
);
2378 void speculateDoubleRepMachineInt(Edge
);
2379 #endif // USE(JSVALUE64)
2380 void speculateNumber(Edge
);
2381 void speculateRealNumber(Edge
);
2382 void speculateDoubleRepReal(Edge
);
2383 void speculateBoolean(Edge
);
2384 void speculateCell(Edge
);
2385 void speculateObject(Edge
);
2386 void speculateFunction(Edge
);
2387 void speculateFinalObject(Edge
);
2388 void speculateObjectOrOther(Edge
);
2389 void speculateString(Edge edge
, GPRReg cell
);
2390 void speculateStringIdentAndLoadStorage(Edge edge
, GPRReg string
, GPRReg storage
);
2391 void speculateStringIdent(Edge edge
, GPRReg string
);
2392 void speculateStringIdent(Edge
);
2393 void speculateString(Edge
);
2394 void speculateNotStringVar(Edge
);
2395 template<typename StructureLocationType
>
2396 void speculateStringObjectForStructure(Edge
, StructureLocationType
);
2397 void speculateStringObject(Edge
, GPRReg
);
2398 void speculateStringObject(Edge
);
2399 void speculateStringOrStringObject(Edge
);
2400 void speculateNotCell(Edge
);
2401 void speculateOther(Edge
);
2402 void speculateMisc(Edge
, JSValueRegs
);
2403 void speculateMisc(Edge
);
2404 void speculate(Node
*, Edge
);
2406 JITCompiler::Jump
jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg
, ArrayMode
, IndexingType
);
2407 JITCompiler::JumpList
jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg
, ArrayMode
);
2408 void checkArray(Node
*);
2409 void arrayify(Node
*, GPRReg baseReg
, GPRReg propertyReg
);
2410 void arrayify(Node
*);
2412 template<bool strict
>
2413 GPRReg
fillSpeculateInt32Internal(Edge
, DataFormat
& returnFormat
);
2415 // It is possible, during speculative generation, to reach a situation in which we
2416 // can statically determine a speculation will fail (for example, when two nodes
2417 // will make conflicting speculations about the same operand). In such cases this
2418 // flag is cleared, indicating no further code generation should take place.
2421 void recordSetLocal(
2422 VirtualRegister bytecodeReg
, VirtualRegister machineReg
, DataFormat format
)
2424 m_stream
->appendAndLog(VariableEvent::setLocal(bytecodeReg
, machineReg
, format
));
2427 void recordSetLocal(DataFormat format
)
2429 VariableAccessData
* variable
= m_currentNode
->variableAccessData();
2430 recordSetLocal(variable
->local(), variable
->machineLocal(), format
);
2433 GenerationInfo
& generationInfoFromVirtualRegister(VirtualRegister virtualRegister
)
2435 return m_generationInfo
[virtualRegister
.toLocal()];
2438 GenerationInfo
& generationInfo(Node
* node
)
2440 return generationInfoFromVirtualRegister(node
->virtualRegister());
2443 GenerationInfo
& generationInfo(Edge edge
)
2445 return generationInfo(edge
.node());
2448 // The JIT, while also provides MacroAssembler functionality.
2451 // The current node being generated.
2452 BasicBlock
* m_block
;
2453 Node
* m_currentNode
;
2454 NodeType m_lastGeneratedNode
;
2456 unsigned m_indexInBlock
;
2457 // Virtual and physical register maps.
2458 Vector
<GenerationInfo
, 32> m_generationInfo
;
2459 RegisterBank
<GPRInfo
> m_gprs
;
2460 RegisterBank
<FPRInfo
> m_fprs
;
2462 Vector
<MacroAssembler::Label
> m_osrEntryHeads
;
2464 struct BranchRecord
{
2465 BranchRecord(MacroAssembler::Jump jump
, BasicBlock
* destination
)
2467 , destination(destination
)
2471 MacroAssembler::Jump jump
;
2472 BasicBlock
* destination
;
2474 Vector
<BranchRecord
, 8> m_branches
;
2476 CodeOrigin m_codeOriginForExitTarget
;
2477 CodeOrigin m_codeOriginForExitProfile
;
2479 InPlaceAbstractState m_state
;
2480 AbstractInterpreter
<InPlaceAbstractState
> m_interpreter
;
2482 VariableEventStream
* m_stream
;
2483 MinifiedGraph
* m_minifiedGraph
;
2485 bool m_isCheckingArgumentTypes
;
2487 Vector
<std::unique_ptr
<SlowPathGenerator
>, 8> m_slowPathGenerators
;
2488 Vector
<SilentRegisterSavePlan
> m_plans
;
2492 // === Operand types ===
2494 // These classes are used to lock the operands to a node into machine
2495 // registers. These classes implement of pattern of locking a value
2496 // into register at the point of construction only if it is already in
2497 // registers, and otherwise loading it lazily at the point it is first
2498 // used. We do so in order to attempt to avoid spilling one operand
2499 // in order to make space available for another.
2501 class JSValueOperand
{
2503 explicit JSValueOperand(SpeculativeJIT
* jit
, Edge edge
, OperandSpeculationMode mode
= AutomaticOperandSpeculation
)
2507 , m_gprOrInvalid(InvalidGPRReg
)
2508 #elif USE(JSVALUE32_64)
2513 ASSERT_UNUSED(mode
, mode
== ManualOperandSpeculation
|| edge
.useKind() == UntypedUse
);
2515 if (jit
->isFilled(node()))
2517 #elif USE(JSVALUE32_64)
2518 m_register
.pair
.tagGPR
= InvalidGPRReg
;
2519 m_register
.pair
.payloadGPR
= InvalidGPRReg
;
2520 if (jit
->isFilled(node()))
2528 ASSERT(m_gprOrInvalid
!= InvalidGPRReg
);
2529 m_jit
->unlock(m_gprOrInvalid
);
2530 #elif USE(JSVALUE32_64)
2532 ASSERT(m_register
.fpr
!= InvalidFPRReg
);
2533 m_jit
->unlock(m_register
.fpr
);
2535 ASSERT(m_register
.pair
.tagGPR
!= InvalidGPRReg
&& m_register
.pair
.payloadGPR
!= InvalidGPRReg
);
2536 m_jit
->unlock(m_register
.pair
.tagGPR
);
2537 m_jit
->unlock(m_register
.pair
.payloadGPR
);
2549 return edge().node();
2555 if (m_gprOrInvalid
== InvalidGPRReg
)
2556 m_gprOrInvalid
= m_jit
->fillJSValue(m_edge
);
2557 return m_gprOrInvalid
;
2559 JSValueRegs
jsValueRegs()
2561 return JSValueRegs(gpr());
2563 #elif USE(JSVALUE32_64)
2564 bool isDouble() { return m_isDouble
; }
2568 if (m_register
.pair
.tagGPR
== InvalidGPRReg
&& m_register
.pair
.payloadGPR
== InvalidGPRReg
)
2569 m_isDouble
= !m_jit
->fillJSValue(m_edge
, m_register
.pair
.tagGPR
, m_register
.pair
.payloadGPR
, m_register
.fpr
);
2575 ASSERT(!m_isDouble
);
2576 return m_register
.pair
.tagGPR
;
2582 ASSERT(!m_isDouble
);
2583 return m_register
.pair
.payloadGPR
;
2586 JSValueRegs
jsValueRegs()
2588 return JSValueRegs(tagGPR(), payloadGPR());
2591 GPRReg
gpr(WhichValueWord which
)
2593 return jsValueRegs().gpr(which
);
2600 return m_register
.fpr
;
2610 SpeculativeJIT
* m_jit
;
2613 GPRReg m_gprOrInvalid
;
2614 #elif USE(JSVALUE32_64)
2626 class StorageOperand
{
2628 explicit StorageOperand(SpeculativeJIT
* jit
, Edge edge
)
2631 , m_gprOrInvalid(InvalidGPRReg
)
2634 ASSERT(edge
.useKind() == UntypedUse
|| edge
.useKind() == KnownCellUse
);
2635 if (jit
->isFilled(node()))
2641 ASSERT(m_gprOrInvalid
!= InvalidGPRReg
);
2642 m_jit
->unlock(m_gprOrInvalid
);
2652 return edge().node();
2657 if (m_gprOrInvalid
== InvalidGPRReg
)
2658 m_gprOrInvalid
= m_jit
->fillStorage(edge());
2659 return m_gprOrInvalid
;
2668 SpeculativeJIT
* m_jit
;
2670 GPRReg m_gprOrInvalid
;
2674 // === Temporaries ===
2676 // These classes are used to allocate temporary registers.
2677 // A mechanism is provided to attempt to reuse the registers
2678 // currently allocated to child nodes whose value is consumed
2679 // by, and not live after, this operation.
2681 enum ReuseTag
{ Reuse
};
2683 class GPRTemporary
{
2686 GPRTemporary(SpeculativeJIT
*);
2687 GPRTemporary(SpeculativeJIT
*, GPRReg specific
);
2688 template<typename T
>
2689 GPRTemporary(SpeculativeJIT
* jit
, ReuseTag
, T
& operand
)
2691 , m_gpr(InvalidGPRReg
)
2693 if (m_jit
->canReuse(operand
.node()))
2694 m_gpr
= m_jit
->reuse(operand
.gpr());
2696 m_gpr
= m_jit
->allocate();
2698 template<typename T1
, typename T2
>
2699 GPRTemporary(SpeculativeJIT
* jit
, ReuseTag
, T1
& op1
, T2
& op2
)
2701 , m_gpr(InvalidGPRReg
)
2703 if (m_jit
->canReuse(op1
.node()))
2704 m_gpr
= m_jit
->reuse(op1
.gpr());
2705 else if (m_jit
->canReuse(op2
.node()))
2706 m_gpr
= m_jit
->reuse(op2
.gpr());
2708 m_gpr
= m_jit
->allocate();
2710 #if USE(JSVALUE32_64)
2711 GPRTemporary(SpeculativeJIT
*, ReuseTag
, JSValueOperand
&, WhichValueWord
);
2714 void adopt(GPRTemporary
&);
2718 if (m_jit
&& m_gpr
!= InvalidGPRReg
)
2719 m_jit
->unlock(gpr());
2728 SpeculativeJIT
* m_jit
;
2732 class JSValueRegsTemporary
{
2734 JSValueRegsTemporary();
2735 JSValueRegsTemporary(SpeculativeJIT
*);
2736 ~JSValueRegsTemporary();
2744 GPRTemporary m_payloadGPR
;
2745 GPRTemporary m_tagGPR
;
2749 class FPRTemporary
{
2751 FPRTemporary(SpeculativeJIT
*);
2752 FPRTemporary(SpeculativeJIT
*, SpeculateDoubleOperand
&);
2753 FPRTemporary(SpeculativeJIT
*, SpeculateDoubleOperand
&, SpeculateDoubleOperand
&);
2754 #if USE(JSVALUE32_64)
2755 FPRTemporary(SpeculativeJIT
*, JSValueOperand
&);
2760 m_jit
->unlock(fpr());
2765 ASSERT(m_fpr
!= InvalidFPRReg
);
2770 FPRTemporary(SpeculativeJIT
* jit
, FPRReg lockedFPR
)
2777 SpeculativeJIT
* m_jit
;
2784 // These classes lock the result of a call to a C++ helper function.
2786 class GPRFlushedCallResult
: public GPRTemporary
{
2788 GPRFlushedCallResult(SpeculativeJIT
* jit
)
2789 : GPRTemporary(jit
, GPRInfo::returnValueGPR
)
2794 #if USE(JSVALUE32_64)
2795 class GPRFlushedCallResult2
: public GPRTemporary
{
2797 GPRFlushedCallResult2(SpeculativeJIT
* jit
)
2798 : GPRTemporary(jit
, GPRInfo::returnValueGPR2
)
2804 class FPRResult
: public FPRTemporary
{
2806 FPRResult(SpeculativeJIT
* jit
)
2807 : FPRTemporary(jit
, lockedResult(jit
))
2812 static FPRReg
lockedResult(SpeculativeJIT
* jit
)
2814 jit
->lock(FPRInfo::returnValueFPR
);
2815 return FPRInfo::returnValueFPR
;
2820 // === Speculative Operand types ===
2822 // SpeculateInt32Operand, SpeculateStrictInt32Operand and SpeculateCellOperand.
2824 // These are used to lock the operands to a node into machine registers within the
2825 // SpeculativeJIT. The classes operate like those above, however these will
2826 // perform a speculative check for a more restrictive type than we can statically
2827 // determine the operand to have. If the operand does not have the requested type,
2828 // a bail-out to the non-speculative path will be taken.
2830 class SpeculateInt32Operand
{
2832 explicit SpeculateInt32Operand(SpeculativeJIT
* jit
, Edge edge
, OperandSpeculationMode mode
= AutomaticOperandSpeculation
)
2835 , m_gprOrInvalid(InvalidGPRReg
)
2837 , m_format(DataFormatNone
)
2841 ASSERT_UNUSED(mode
, mode
== ManualOperandSpeculation
|| (edge
.useKind() == Int32Use
|| edge
.useKind() == KnownInt32Use
));
2842 if (jit
->isFilled(node()))
2846 ~SpeculateInt32Operand()
2848 ASSERT(m_gprOrInvalid
!= InvalidGPRReg
);
2849 m_jit
->unlock(m_gprOrInvalid
);
2859 return edge().node();
2864 gpr(); // m_format is set when m_gpr is locked.
2865 ASSERT(m_format
== DataFormatInt32
|| m_format
== DataFormatJSInt32
);
2871 if (m_gprOrInvalid
== InvalidGPRReg
)
2872 m_gprOrInvalid
= m_jit
->fillSpeculateInt32(edge(), m_format
);
2873 return m_gprOrInvalid
;
2882 SpeculativeJIT
* m_jit
;
2884 GPRReg m_gprOrInvalid
;
2885 DataFormat m_format
;
2888 class SpeculateStrictInt32Operand
{
2890 explicit SpeculateStrictInt32Operand(SpeculativeJIT
* jit
, Edge edge
, OperandSpeculationMode mode
= AutomaticOperandSpeculation
)
2893 , m_gprOrInvalid(InvalidGPRReg
)
2896 ASSERT_UNUSED(mode
, mode
== ManualOperandSpeculation
|| (edge
.useKind() == Int32Use
|| edge
.useKind() == KnownInt32Use
));
2897 if (jit
->isFilled(node()))
2901 ~SpeculateStrictInt32Operand()
2903 ASSERT(m_gprOrInvalid
!= InvalidGPRReg
);
2904 m_jit
->unlock(m_gprOrInvalid
);
2914 return edge().node();
2919 if (m_gprOrInvalid
== InvalidGPRReg
)
2920 m_gprOrInvalid
= m_jit
->fillSpeculateInt32Strict(edge());
2921 return m_gprOrInvalid
;
2930 SpeculativeJIT
* m_jit
;
2932 GPRReg m_gprOrInvalid
;
2935 // Gives you a canonical Int52 (i.e. it's left-shifted by 16, low bits zero).
2936 class SpeculateInt52Operand
{
2938 explicit SpeculateInt52Operand(SpeculativeJIT
* jit
, Edge edge
)
2941 , m_gprOrInvalid(InvalidGPRReg
)
2943 RELEASE_ASSERT(edge
.useKind() == Int52RepUse
);
2944 if (jit
->isFilled(node()))
2948 ~SpeculateInt52Operand()
2950 ASSERT(m_gprOrInvalid
!= InvalidGPRReg
);
2951 m_jit
->unlock(m_gprOrInvalid
);
2961 return edge().node();
2966 if (m_gprOrInvalid
== InvalidGPRReg
)
2967 m_gprOrInvalid
= m_jit
->fillSpeculateInt52(edge(), DataFormatInt52
);
2968 return m_gprOrInvalid
;
2977 SpeculativeJIT
* m_jit
;
2979 GPRReg m_gprOrInvalid
;
2982 // Gives you a strict Int52 (i.e. the payload is in the low 48 bits, high 16 bits are sign-extended).
2983 class SpeculateStrictInt52Operand
{
2985 explicit SpeculateStrictInt52Operand(SpeculativeJIT
* jit
, Edge edge
)
2988 , m_gprOrInvalid(InvalidGPRReg
)
2990 RELEASE_ASSERT(edge
.useKind() == Int52RepUse
);
2991 if (jit
->isFilled(node()))
2995 ~SpeculateStrictInt52Operand()
2997 ASSERT(m_gprOrInvalid
!= InvalidGPRReg
);
2998 m_jit
->unlock(m_gprOrInvalid
);
3008 return edge().node();
3013 if (m_gprOrInvalid
== InvalidGPRReg
)
3014 m_gprOrInvalid
= m_jit
->fillSpeculateInt52(edge(), DataFormatStrictInt52
);
3015 return m_gprOrInvalid
;
3024 SpeculativeJIT
* m_jit
;
3026 GPRReg m_gprOrInvalid
;
3029 enum OppositeShiftTag
{ OppositeShift
};
3031 class SpeculateWhicheverInt52Operand
{
3033 explicit SpeculateWhicheverInt52Operand(SpeculativeJIT
* jit
, Edge edge
)
3036 , m_gprOrInvalid(InvalidGPRReg
)
3037 , m_strict(jit
->betterUseStrictInt52(edge
))
3039 RELEASE_ASSERT(edge
.useKind() == Int52RepUse
);
3040 if (jit
->isFilled(node()))
3044 explicit SpeculateWhicheverInt52Operand(SpeculativeJIT
* jit
, Edge edge
, const SpeculateWhicheverInt52Operand
& other
)
3047 , m_gprOrInvalid(InvalidGPRReg
)
3048 , m_strict(other
.m_strict
)
3050 RELEASE_ASSERT(edge
.useKind() == Int52RepUse
);
3051 if (jit
->isFilled(node()))
3055 explicit SpeculateWhicheverInt52Operand(SpeculativeJIT
* jit
, Edge edge
, OppositeShiftTag
, const SpeculateWhicheverInt52Operand
& other
)
3058 , m_gprOrInvalid(InvalidGPRReg
)
3059 , m_strict(!other
.m_strict
)
3061 RELEASE_ASSERT(edge
.useKind() == Int52RepUse
);
3062 if (jit
->isFilled(node()))
3066 ~SpeculateWhicheverInt52Operand()
3068 ASSERT(m_gprOrInvalid
!= InvalidGPRReg
);
3069 m_jit
->unlock(m_gprOrInvalid
);
3079 return edge().node();
3084 if (m_gprOrInvalid
== InvalidGPRReg
) {
3085 m_gprOrInvalid
= m_jit
->fillSpeculateInt52(
3086 edge(), m_strict
? DataFormatStrictInt52
: DataFormatInt52
);
3088 return m_gprOrInvalid
;
3096 DataFormat
format() const
3098 return m_strict
? DataFormatStrictInt52
: DataFormatInt52
;
3102 SpeculativeJIT
* m_jit
;
3104 GPRReg m_gprOrInvalid
;
3108 class SpeculateDoubleOperand
{
3110 explicit SpeculateDoubleOperand(SpeculativeJIT
* jit
, Edge edge
)
3113 , m_fprOrInvalid(InvalidFPRReg
)
3116 RELEASE_ASSERT(isDouble(edge
.useKind()));
3117 if (jit
->isFilled(node()))
3121 ~SpeculateDoubleOperand()
3123 ASSERT(m_fprOrInvalid
!= InvalidFPRReg
);
3124 m_jit
->unlock(m_fprOrInvalid
);
3134 return edge().node();
3139 if (m_fprOrInvalid
== InvalidFPRReg
)
3140 m_fprOrInvalid
= m_jit
->fillSpeculateDouble(edge());
3141 return m_fprOrInvalid
;
3150 SpeculativeJIT
* m_jit
;
3152 FPRReg m_fprOrInvalid
;
3155 class SpeculateCellOperand
{
3157 explicit SpeculateCellOperand(SpeculativeJIT
* jit
, Edge edge
, OperandSpeculationMode mode
= AutomaticOperandSpeculation
)
3160 , m_gprOrInvalid(InvalidGPRReg
)
3165 ASSERT_UNUSED(mode
, mode
== ManualOperandSpeculation
|| isCell(edge
.useKind()));
3166 if (jit
->isFilled(node()))
3170 ~SpeculateCellOperand()
3174 ASSERT(m_gprOrInvalid
!= InvalidGPRReg
);
3175 m_jit
->unlock(m_gprOrInvalid
);
3185 return edge().node();
3191 if (m_gprOrInvalid
== InvalidGPRReg
)
3192 m_gprOrInvalid
= m_jit
->fillSpeculateCell(edge());
3193 return m_gprOrInvalid
;
3203 SpeculativeJIT
* m_jit
;
3205 GPRReg m_gprOrInvalid
;
3208 class SpeculateBooleanOperand
{
3210 explicit SpeculateBooleanOperand(SpeculativeJIT
* jit
, Edge edge
, OperandSpeculationMode mode
= AutomaticOperandSpeculation
)
3213 , m_gprOrInvalid(InvalidGPRReg
)
3216 ASSERT_UNUSED(mode
, mode
== ManualOperandSpeculation
|| edge
.useKind() == BooleanUse
);
3217 if (jit
->isFilled(node()))
3221 ~SpeculateBooleanOperand()
3223 ASSERT(m_gprOrInvalid
!= InvalidGPRReg
);
3224 m_jit
->unlock(m_gprOrInvalid
);
3234 return edge().node();
3239 if (m_gprOrInvalid
== InvalidGPRReg
)
3240 m_gprOrInvalid
= m_jit
->fillSpeculateBoolean(edge());
3241 return m_gprOrInvalid
;
3250 SpeculativeJIT
* m_jit
;
3252 GPRReg m_gprOrInvalid
;
3255 template<typename StructureLocationType
>
3256 void SpeculativeJIT::speculateStringObjectForStructure(Edge edge
, StructureLocationType structureLocation
)
3258 Structure
* stringObjectStructure
=
3259 m_jit
.globalObjectFor(m_currentNode
->origin
.semantic
)->stringObjectStructure();
3261 if (!m_state
.forNode(edge
).m_structure
.isSubsetOf(StructureSet(stringObjectStructure
))) {
3263 NotStringObject
, JSValueRegs(), 0,
3264 m_jit
.branchStructurePtr(
3265 JITCompiler::NotEqual
, structureLocation
, stringObjectStructure
));
3269 #define DFG_TYPE_CHECK(source, edge, typesPassedThrough, jumpToFail) do { \
3270 JSValueSource _dtc_source = (source); \
3271 Edge _dtc_edge = (edge); \
3272 SpeculatedType _dtc_typesPassedThrough = typesPassedThrough; \
3273 if (!needsTypeCheck(_dtc_edge, _dtc_typesPassedThrough)) \
3275 typeCheck(_dtc_source, _dtc_edge, _dtc_typesPassedThrough, (jumpToFail)); \
3278 } } // namespace JSC::DFG