]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGSpeculativeJIT.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / dfg / DFGSpeculativeJIT.h
CommitLineData
14957cd0 1/*
ed1e77d3 2 * Copyright (C) 2011-2015 Apple Inc. All rights reserved.
14957cd0
A
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef DFGSpeculativeJIT_h
27#define DFGSpeculativeJIT_h
28
29#if ENABLE(DFG_JIT)
30
81345200 31#include "DFGAbstractInterpreter.h"
6fe7ccc8 32#include "DFGGenerationInfo.h"
81345200 33#include "DFGInPlaceAbstractState.h"
6fe7ccc8
A
34#include "DFGJITCompiler.h"
35#include "DFGOSRExit.h"
93a37866 36#include "DFGOSRExitJumpPlaceholder.h"
93a37866
A
37#include "DFGSilentRegisterSavePlan.h"
38#include "DFGValueSource.h"
81345200 39#include "JITOperations.h"
6fe7ccc8 40#include "MarkedAllocator.h"
81345200 41#include "PutKind.h"
6fe7ccc8 42#include "ValueRecovery.h"
81345200 43#include "VirtualRegister.h"
14957cd0
A
44
45namespace JSC { namespace DFG {
46
93a37866 47class GPRTemporary;
6fe7ccc8 48class JSValueOperand;
93a37866 49class SlowPathGenerator;
14957cd0 50class SpeculativeJIT;
81345200 51class SpeculateInt32Operand;
6fe7ccc8
A
52class SpeculateStrictInt32Operand;
53class SpeculateDoubleOperand;
54class SpeculateCellOperand;
55class SpeculateBooleanOperand;
14957cd0 56
81345200
A
57enum GeneratedOperandType { GeneratedOperandTypeUnknown, GeneratedOperandInteger, GeneratedOperandJSValue};
58
59inline GPRReg extractResult(GPRReg result) { return result; }
60#if USE(JSVALUE64)
61inline GPRReg extractResult(JSValueRegs result) { return result.gpr(); }
62#else
63inline JSValueRegs extractResult(JSValueRegs result) { return result; }
64#endif
65inline NoResultTag extractResult(NoResultTag) { return NoResult; }
6fe7ccc8
A
66
67// === SpeculativeJIT ===
68//
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.
77class SpeculativeJIT {
81345200
A
78 WTF_MAKE_FAST_ALLOCATED;
79
6fe7ccc8
A
80 friend struct OSRExit;
81private:
82 typedef JITCompiler::TrustedImm32 TrustedImm32;
83 typedef JITCompiler::Imm32 Imm32;
84 typedef JITCompiler::TrustedImmPtr TrustedImmPtr;
85 typedef JITCompiler::ImmPtr ImmPtr;
93a37866
A
86 typedef JITCompiler::TrustedImm64 TrustedImm64;
87 typedef JITCompiler::Imm64 Imm64;
6fe7ccc8
A
88
89 // These constants are used to set priorities for spill order for
90 // the register allocator.
91#if USE(JSVALUE64)
92 enum SpillOrder {
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
101 };
102#elif USE(JSVALUE32_64)
103 enum SpillOrder {
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
112 };
113#endif
114
115 enum UseChildrenMode { CallUseChildren, UseChildrenCalledExplicitly };
116
117public:
118 SpeculativeJIT(JITCompiler&);
93a37866 119 ~SpeculativeJIT();
6fe7ccc8
A
120
121 bool compile();
81345200 122
6fe7ccc8
A
123 void createOSREntries();
124 void linkOSREntries(LinkBuffer&);
125
81345200 126 BasicBlock* nextBlock()
6fe7ccc8 127 {
81345200
A
128 for (BlockIndex resultIndex = m_block->index + 1; ; resultIndex++) {
129 if (resultIndex >= m_jit.graph().numBlocks())
130 return 0;
131 if (BasicBlock* result = m_jit.graph().block(resultIndex))
93a37866
A
132 return result;
133 }
6fe7ccc8
A
134 }
135
6fe7ccc8 136#if USE(JSVALUE64)
93a37866 137 GPRReg fillJSValue(Edge);
6fe7ccc8 138#elif USE(JSVALUE32_64)
93a37866 139 bool fillJSValue(Edge, GPRReg&, GPRReg&, FPRReg&);
6fe7ccc8 140#endif
93a37866 141 GPRReg fillStorage(Edge);
6fe7ccc8
A
142
143 // lock and unlock GPR & FPR registers.
144 void lock(GPRReg reg)
145 {
146 m_gprs.lock(reg);
147 }
148 void lock(FPRReg reg)
149 {
150 m_fprs.lock(reg);
151 }
152 void unlock(GPRReg reg)
153 {
154 m_gprs.unlock(reg);
155 }
156 void unlock(FPRReg reg)
157 {
158 m_fprs.unlock(reg);
159 }
160
161 // Used to check whether a child node is on its last use,
162 // and its machine registers may be reused.
93a37866 163 bool canReuse(Node* node)
6fe7ccc8 164 {
81345200 165 return generationInfo(node).canReuse();
6fe7ccc8
A
166 }
167 bool canReuse(Edge nodeUse)
168 {
93a37866 169 return canReuse(nodeUse.node());
6fe7ccc8
A
170 }
171 GPRReg reuse(GPRReg reg)
172 {
173 m_gprs.lock(reg);
174 return reg;
175 }
176 FPRReg reuse(FPRReg reg)
177 {
178 m_fprs.lock(reg);
179 return reg;
180 }
181
182 // Allocate a gpr/fpr.
183 GPRReg allocate()
184 {
93a37866
A
185#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
186 m_jit.addRegisterAllocationAtOffset(m_jit.debugOffset());
187#endif
6fe7ccc8
A
188 VirtualRegister spillMe;
189 GPRReg gpr = m_gprs.allocate(spillMe);
81345200 190 if (spillMe.isValid()) {
6fe7ccc8 191#if USE(JSVALUE32_64)
81345200 192 GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
6fe7ccc8
A
193 if ((info.registerFormat() & DataFormatJS))
194 m_gprs.release(info.tagGPR() == gpr ? info.payloadGPR() : info.tagGPR());
195#endif
196 spill(spillMe);
197 }
198 return gpr;
199 }
200 GPRReg allocate(GPRReg specific)
201 {
93a37866
A
202#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
203 m_jit.addRegisterAllocationAtOffset(m_jit.debugOffset());
204#endif
6fe7ccc8 205 VirtualRegister spillMe = m_gprs.allocateSpecific(specific);
81345200 206 if (spillMe.isValid()) {
6fe7ccc8 207#if USE(JSVALUE32_64)
81345200 208 GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
93a37866 209 RELEASE_ASSERT(info.registerFormat() != DataFormatJSDouble);
6fe7ccc8
A
210 if ((info.registerFormat() & DataFormatJS))
211 m_gprs.release(info.tagGPR() == specific ? info.payloadGPR() : info.tagGPR());
212#endif
213 spill(spillMe);
214 }
215 return specific;
216 }
217 GPRReg tryAllocate()
218 {
219 return m_gprs.tryAllocate();
220 }
221 FPRReg fprAllocate()
222 {
93a37866
A
223#if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
224 m_jit.addRegisterAllocationAtOffset(m_jit.debugOffset());
225#endif
6fe7ccc8
A
226 VirtualRegister spillMe;
227 FPRReg fpr = m_fprs.allocate(spillMe);
81345200 228 if (spillMe.isValid())
6fe7ccc8
A
229 spill(spillMe);
230 return fpr;
231 }
232
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).
93a37866 238 bool isFilled(Node* node)
6fe7ccc8 239 {
81345200 240 return generationInfo(node).registerFormat() != DataFormatNone;
6fe7ccc8 241 }
93a37866 242 bool isFilledDouble(Node* node)
6fe7ccc8 243 {
81345200 244 return generationInfo(node).registerFormat() == DataFormatDouble;
6fe7ccc8
A
245 }
246
247 // Called on an operand once it has been consumed by a parent node.
93a37866 248 void use(Node* node)
6fe7ccc8 249 {
93a37866
A
250 if (!node->hasResult())
251 return;
81345200 252 GenerationInfo& info = generationInfo(node);
6fe7ccc8
A
253
254 // use() returns true when the value becomes dead, and any
255 // associated resources may be freed.
93a37866 256 if (!info.use(*m_stream))
6fe7ccc8
A
257 return;
258
259 // Release the associated machine registers.
260 DataFormat registerFormat = info.registerFormat();
261#if USE(JSVALUE64)
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)
81345200 267 if (registerFormat == DataFormatDouble)
6fe7ccc8
A
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());
274#endif
275 }
276 void use(Edge nodeUse)
277 {
93a37866
A
278 use(nodeUse.node());
279 }
280
81345200
A
281 RegisterSet usedRegisters();
282
283 bool masqueradesAsUndefinedWatchpointIsStillValid(const CodeOrigin& codeOrigin)
93a37866 284 {
81345200
A
285 return m_jit.graph().masqueradesAsUndefinedWatchpointIsStillValid(codeOrigin);
286 }
287 bool masqueradesAsUndefinedWatchpointIsStillValid()
288 {
289 return masqueradesAsUndefinedWatchpointIsStillValid(m_currentNode->origin.semantic);
6fe7ccc8
A
290 }
291
81345200
A
292#if ENABLE(GGC)
293 void storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPRReg scratch2);
81345200
A
294
295 void writeBarrier(GPRReg owner, GPRReg scratch1, GPRReg scratch2);
6fe7ccc8 296
81345200 297 void writeBarrier(GPRReg owner, GPRReg value, Edge valueUse, GPRReg scratch1, GPRReg scratch2);
81345200
A
298#endif
299 void compileStoreBarrier(Node*);
6fe7ccc8
A
300
301 static GPRReg selectScratchGPR(GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg, GPRReg preserve4 = InvalidGPRReg)
302 {
303 return AssemblyHelpers::selectScratchGPR(preserve1, preserve2, preserve3, preserve4);
304 }
305
306 // Called by the speculative operand types, below, to fill operand to
307 // machine registers, implicitly generating speculation checks as needed.
81345200
A
308 GPRReg fillSpeculateInt32(Edge, DataFormat& returnFormat);
309 GPRReg fillSpeculateInt32Strict(Edge);
310 GPRReg fillSpeculateInt52(Edge, DataFormat desiredFormat);
93a37866
A
311 FPRReg fillSpeculateDouble(Edge);
312 GPRReg fillSpeculateCell(Edge);
313 GPRReg fillSpeculateBoolean(Edge);
314 GeneratedOperandType checkGeneratedTypeForToInt32(Node*);
315
ed1e77d3 316 void addSlowPathGenerator(std::unique_ptr<SlowPathGenerator>);
93a37866
A
317 void runSlowPathGenerators();
318
319 void compile(Node*);
320 void noticeOSRBirth(Node*);
81345200
A
321 void bail(AbortReason);
322 void compileCurrentBlock();
6fe7ccc8
A
323
324 void checkArgumentTypes();
325
326 void clearGenerationInfo();
327
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
93a37866 331 // slots in the JSStack without changing any state
6fe7ccc8 332 // in the GenerationInfo.
93a37866
A
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);
337
338 template<typename CollectionType>
339 void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, GPRReg exclude, GPRReg exclude2 = InvalidGPRReg, FPRReg fprExclude = InvalidFPRReg)
6fe7ccc8 340 {
93a37866
A
341 ASSERT(plans.isEmpty());
342 for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
343 GPRReg gpr = iter.regID();
81345200 344 if (iter.name().isValid() && gpr != exclude && gpr != exclude2) {
93a37866
A
345 SilentRegisterSavePlan plan = silentSavePlanForGPR(iter.name(), gpr);
346 if (doSpill)
347 silentSpill(plan);
348 plans.append(plan);
349 }
6fe7ccc8 350 }
93a37866 351 for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
81345200 352 if (iter.name().isValid() && iter.regID() != fprExclude) {
93a37866
A
353 SilentRegisterSavePlan plan = silentSavePlanForFPR(iter.name(), iter.regID());
354 if (doSpill)
355 silentSpill(plan);
356 plans.append(plan);
357 }
6fe7ccc8 358 }
6fe7ccc8 359 }
93a37866
A
360 template<typename CollectionType>
361 void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, NoResultTag)
6fe7ccc8 362 {
93a37866 363 silentSpillAllRegistersImpl(doSpill, plans, InvalidGPRReg, InvalidGPRReg, InvalidFPRReg);
6fe7ccc8 364 }
93a37866
A
365 template<typename CollectionType>
366 void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, FPRReg exclude)
6fe7ccc8 367 {
93a37866 368 silentSpillAllRegistersImpl(doSpill, plans, InvalidGPRReg, InvalidGPRReg, exclude);
6fe7ccc8 369 }
93a37866
A
370#if USE(JSVALUE32_64)
371 template<typename CollectionType>
372 void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, JSValueRegs exclude)
6fe7ccc8 373 {
93a37866 374 silentSpillAllRegistersImpl(doSpill, plans, exclude.tagGPR(), exclude.payloadGPR());
6fe7ccc8 375 }
93a37866
A
376#endif
377
378 void silentSpillAllRegisters(GPRReg exclude, GPRReg exclude2 = InvalidGPRReg, FPRReg fprExclude = InvalidFPRReg)
6fe7ccc8 379 {
93a37866 380 silentSpillAllRegistersImpl(true, m_plans, exclude, exclude2, fprExclude);
6fe7ccc8
A
381 }
382 void silentSpillAllRegisters(FPRReg exclude)
383 {
93a37866 384 silentSpillAllRegisters(InvalidGPRReg, InvalidGPRReg, exclude);
6fe7ccc8 385 }
93a37866
A
386
387 static GPRReg pickCanTrample(GPRReg exclude)
6fe7ccc8 388 {
93a37866
A
389 GPRReg result = GPRInfo::regT0;
390 if (result == exclude)
391 result = GPRInfo::regT1;
392 return result;
393 }
394 static GPRReg pickCanTrample(FPRReg)
395 {
396 return GPRInfo::regT0;
397 }
398 static GPRReg pickCanTrample(NoResultTag)
399 {
400 return GPRInfo::regT0;
401 }
402
403#if USE(JSVALUE32_64)
404 static GPRReg pickCanTrample(JSValueRegs exclude)
405 {
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;
6fe7ccc8 415 }
93a37866 416 return result;
6fe7ccc8 417 }
93a37866
A
418#endif
419
420 template<typename RegisterType>
421 void silentFillAllRegisters(RegisterType exclude)
6fe7ccc8 422 {
93a37866 423 GPRReg canTrample = pickCanTrample(exclude);
6fe7ccc8 424
93a37866
A
425 while (!m_plans.isEmpty()) {
426 SilentRegisterSavePlan& plan = m_plans.last();
427 silentFill(plan, canTrample);
428 m_plans.removeLast();
6fe7ccc8
A
429 }
430 }
431
432 // These methods convert between doubles, and doubles boxed and JSValues.
433#if USE(JSVALUE64)
434 GPRReg boxDouble(FPRReg fpr, GPRReg gpr)
435 {
436 return m_jit.boxDouble(fpr, gpr);
437 }
438 FPRReg unboxDouble(GPRReg gpr, FPRReg fpr)
439 {
440 return m_jit.unboxDouble(gpr, fpr);
441 }
442 GPRReg boxDouble(FPRReg fpr)
443 {
444 return boxDouble(fpr, allocate());
445 }
81345200
A
446
447 void boxInt52(GPRReg sourceGPR, GPRReg targetGPR, DataFormat);
6fe7ccc8
A
448#elif USE(JSVALUE32_64)
449 void boxDouble(FPRReg fpr, GPRReg tagGPR, GPRReg payloadGPR)
450 {
451 m_jit.boxDouble(fpr, tagGPR, payloadGPR);
452 }
453 void unboxDouble(GPRReg tagGPR, GPRReg payloadGPR, FPRReg fpr, FPRReg scratchFPR)
454 {
455 m_jit.unboxDouble(tagGPR, payloadGPR, fpr, scratchFPR);
456 }
457#endif
81345200
A
458 void boxDouble(FPRReg fpr, JSValueRegs regs)
459 {
460 m_jit.boxDouble(fpr, regs);
461 }
6fe7ccc8 462
93a37866 463 // Spill a VirtualRegister to the JSStack.
6fe7ccc8
A
464 void spill(VirtualRegister spillMe)
465 {
81345200 466 GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
6fe7ccc8
A
467
468#if USE(JSVALUE32_64)
469 if (info.registerFormat() == DataFormatNone) // it has been spilled. JS values which have two GPRs can reach here
470 return;
471#endif
472 // Check the GenerationInfo to see if this value need writing
93a37866 473 // to the JSStack - if not, mark it as spilled & return.
6fe7ccc8 474 if (!info.needsSpill()) {
93a37866 475 info.setSpilled(*m_stream, spillMe);
6fe7ccc8
A
476 return;
477 }
478
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
483 // code.
484 m_jit.storePtr(info.gpr(), JITCompiler::addressFor(spillMe));
93a37866 485 info.spill(*m_stream, spillMe, DataFormatStorage);
6fe7ccc8
A
486 return;
487 }
488
81345200 489 case DataFormatInt32: {
6fe7ccc8 490 m_jit.store32(info.gpr(), JITCompiler::payloadFor(spillMe));
81345200 491 info.spill(*m_stream, spillMe, DataFormatInt32);
6fe7ccc8
A
492 return;
493 }
494
495#if USE(JSVALUE64)
496 case DataFormatDouble: {
497 m_jit.storeDouble(info.fpr(), JITCompiler::addressFor(spillMe));
93a37866 498 info.spill(*m_stream, spillMe, DataFormatDouble);
6fe7ccc8
A
499 return;
500 }
81345200
A
501
502 case DataFormatInt52:
503 case DataFormatStrictInt52: {
504 m_jit.store64(info.gpr(), JITCompiler::addressFor(spillMe));
505 info.spill(*m_stream, spillMe, spillFormat);
506 return;
507 }
6fe7ccc8
A
508
509 default:
510 // The following code handles JSValues, int32s, and cells.
93a37866 511 RELEASE_ASSERT(spillFormat == DataFormatCell || spillFormat & DataFormatJS);
6fe7ccc8
A
512
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!
81345200 516 if (spillFormat == DataFormatInt32)
93a37866 517 m_jit.or64(GPRInfo::tagTypeNumberRegister, reg);
6fe7ccc8
A
518
519 // Spill the value, and record it as spilled in its boxed form.
93a37866
A
520 m_jit.store64(reg, JITCompiler::addressFor(spillMe));
521 info.spill(*m_stream, spillMe, (DataFormat)(spillFormat | DataFormatJS));
6fe7ccc8
A
522 return;
523#elif USE(JSVALUE32_64)
524 case DataFormatCell:
525 case DataFormatBoolean: {
526 m_jit.store32(info.gpr(), JITCompiler::payloadFor(spillMe));
93a37866 527 info.spill(*m_stream, spillMe, spillFormat);
6fe7ccc8
A
528 return;
529 }
530
81345200 531 case DataFormatDouble: {
6fe7ccc8
A
532 // On JSVALUE32_64 boxing a double is a no-op.
533 m_jit.storeDouble(info.fpr(), JITCompiler::addressFor(spillMe));
81345200 534 info.spill(*m_stream, spillMe, DataFormatDouble);
6fe7ccc8
A
535 return;
536 }
537
538 default:
539 // The following code handles JSValues.
93a37866 540 RELEASE_ASSERT(spillFormat & DataFormatJS);
6fe7ccc8
A
541 m_jit.store32(info.tagGPR(), JITCompiler::tagFor(spillMe));
542 m_jit.store32(info.payloadGPR(), JITCompiler::payloadFor(spillMe));
93a37866 543 info.spill(*m_stream, spillMe, spillFormat);
6fe7ccc8
A
544 return;
545#endif
546 }
547 }
548
81345200
A
549 bool isKnownInteger(Node* node) { return m_state.forNode(node).isType(SpecInt32); }
550 bool isKnownCell(Node* node) { return m_state.forNode(node).isType(SpecCell); }
6fe7ccc8 551
93a37866 552 bool isKnownNotInteger(Node* node) { return !(m_state.forNode(node).m_type & SpecInt32); }
81345200 553 bool isKnownNotNumber(Node* node) { return !(m_state.forNode(node).m_type & SpecFullNumber); }
93a37866 554 bool isKnownNotCell(Node* node) { return !(m_state.forNode(node).m_type & SpecCell); }
6fe7ccc8 555
ed1e77d3 556 UniquedStringImpl* identifierUID(unsigned index)
6fe7ccc8 557 {
81345200 558 return m_jit.graph().identifiers()[index];
6fe7ccc8
A
559 }
560
93a37866 561 // Spill all VirtualRegisters back to the JSStack.
6fe7ccc8
A
562 void flushRegisters()
563 {
564 for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
81345200 565 if (iter.name().isValid()) {
6fe7ccc8
A
566 spill(iter.name());
567 iter.release();
568 }
569 }
570 for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
81345200 571 if (iter.name().isValid()) {
6fe7ccc8
A
572 spill(iter.name());
573 iter.release();
574 }
575 }
576 }
577
6fe7ccc8
A
578 // Used to ASSERT flushRegisters() has been called prior to
579 // calling out from JIT code to a C helper function.
580 bool isFlushed()
581 {
582 for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
81345200 583 if (iter.name().isValid())
6fe7ccc8
A
584 return false;
585 }
586 for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
81345200 587 if (iter.name().isValid())
6fe7ccc8
A
588 return false;
589 }
590 return true;
591 }
6fe7ccc8
A
592
593#if USE(JSVALUE64)
ed1e77d3 594 static MacroAssembler::Imm64 valueOfJSConstantAsImm64(Node* node)
6fe7ccc8 595 {
ed1e77d3 596 return MacroAssembler::Imm64(JSValue::encode(node->asJSValue()));
6fe7ccc8
A
597 }
598#endif
599
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)
602 {
603 switch (op) {
604 case BitAnd:
605 m_jit.and32(Imm32(imm), op1, result);
606 break;
607 case BitOr:
608 m_jit.or32(Imm32(imm), op1, result);
609 break;
610 case BitXor:
611 m_jit.xor32(Imm32(imm), op1, result);
612 break;
613 default:
93a37866 614 RELEASE_ASSERT_NOT_REACHED();
6fe7ccc8
A
615 }
616 }
617 void bitOp(NodeType op, GPRReg op1, GPRReg op2, GPRReg result)
618 {
619 switch (op) {
620 case BitAnd:
621 m_jit.and32(op1, op2, result);
622 break;
623 case BitOr:
624 m_jit.or32(op1, op2, result);
625 break;
626 case BitXor:
627 m_jit.xor32(op1, op2, result);
628 break;
629 default:
93a37866 630 RELEASE_ASSERT_NOT_REACHED();
6fe7ccc8
A
631 }
632 }
633 void shiftOp(NodeType op, GPRReg op1, int32_t shiftAmount, GPRReg result)
634 {
635 switch (op) {
636 case BitRShift:
637 m_jit.rshift32(op1, Imm32(shiftAmount), result);
638 break;
639 case BitLShift:
640 m_jit.lshift32(op1, Imm32(shiftAmount), result);
641 break;
642 case BitURShift:
643 m_jit.urshift32(op1, Imm32(shiftAmount), result);
644 break;
645 default:
93a37866 646 RELEASE_ASSERT_NOT_REACHED();
6fe7ccc8
A
647 }
648 }
649 void shiftOp(NodeType op, GPRReg op1, GPRReg shiftAmount, GPRReg result)
650 {
651 switch (op) {
652 case BitRShift:
653 m_jit.rshift32(op1, shiftAmount, result);
654 break;
655 case BitLShift:
656 m_jit.lshift32(op1, shiftAmount, result);
657 break;
658 case BitURShift:
659 m_jit.urshift32(op1, shiftAmount, result);
660 break;
661 default:
93a37866 662 RELEASE_ASSERT_NOT_REACHED();
6fe7ccc8
A
663 }
664 }
665
666 // Returns the index of the branch node if peephole is okay, UINT_MAX otherwise.
667 unsigned detectPeepHoleBranch()
668 {
6fe7ccc8 669 // Check that no intervening nodes will be generated.
81345200
A
670 for (unsigned index = m_indexInBlock + 1; index < m_block->size() - 1; ++index) {
671 Node* node = m_block->at(index);
672 if (!node->shouldGenerate())
673 continue;
674 // Check if it's a Phantom that can be safely ignored.
675 if (node->op() == Phantom && !node->child1())
676 continue;
677 return UINT_MAX;
6fe7ccc8
A
678 }
679
680 // Check if the lastNode is a branch on this node.
ed1e77d3 681 Node* lastNode = m_block->terminal();
81345200 682 return lastNode->op() == Branch && lastNode->child1() == m_currentNode ? m_block->size() - 1 : UINT_MAX;
6fe7ccc8
A
683 }
684
93a37866
A
685 void compileMovHint(Node*);
686 void compileMovHintAndCheck(Node*);
6fe7ccc8 687
6fe7ccc8 688#if USE(JSVALUE64)
93a37866 689 void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
81345200 690 void cachedPutById(CodeOrigin, GPRReg base, GPRReg value, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
6fe7ccc8 691#elif USE(JSVALUE32_64)
93a37866 692 void cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
81345200 693 void cachedPutById(CodeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
6fe7ccc8 694#endif
81345200
A
695
696 void compileIn(Node*);
697
698 void compileBaseValueStoreBarrier(Edge& baseEdge, Edge& valueEdge);
6fe7ccc8
A
699
700 void nonSpeculativeNonPeepholeCompareNull(Edge operand, bool invert = false);
93a37866
A
701 void nonSpeculativePeepholeBranchNull(Edge operand, Node* branchNode, bool invert = false);
702 bool nonSpeculativeCompareNull(Node*, Edge operand, bool invert = false);
6fe7ccc8 703
81345200
A
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);
6fe7ccc8 707
93a37866
A
708 void nonSpeculativePeepholeStrictEq(Node*, Node* branchNode, bool invert = false);
709 void nonSpeculativeNonPeepholeStrictEq(Node*, bool invert = false);
710 bool nonSpeculativeStrictEq(Node*, bool invert = false);
6fe7ccc8 711
81345200 712 void compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg, GPRReg scratch2Reg);
93a37866 713 void compileInstanceOf(Node*);
6fe7ccc8 714
93a37866 715 void emitCall(Node*);
6fe7ccc8
A
716
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).
93a37866 721 void useChildren(Node*);
6fe7ccc8
A
722
723 // These method called to initialize the the GenerationInfo
724 // to describe the result of an operation.
81345200 725 void int32Result(GPRReg reg, Node* node, DataFormat format = DataFormatInt32, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 726 {
6fe7ccc8
A
727 if (mode == CallUseChildren)
728 useChildren(node);
729
93a37866 730 VirtualRegister virtualRegister = node->virtualRegister();
81345200 731 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
6fe7ccc8 732
81345200 733 if (format == DataFormatInt32) {
6fe7ccc8
A
734 m_jit.jitAssertIsInt32(reg);
735 m_gprs.retain(reg, virtualRegister, SpillOrderInteger);
81345200 736 info.initInt32(node, node->refCount(), reg);
6fe7ccc8
A
737 } else {
738#if USE(JSVALUE64)
81345200 739 RELEASE_ASSERT(format == DataFormatJSInt32);
6fe7ccc8
A
740 m_jit.jitAssertIsJSInt32(reg);
741 m_gprs.retain(reg, virtualRegister, SpillOrderJS);
93a37866 742 info.initJSValue(node, node->refCount(), reg, format);
6fe7ccc8 743#elif USE(JSVALUE32_64)
93a37866 744 RELEASE_ASSERT_NOT_REACHED();
6fe7ccc8
A
745#endif
746 }
747 }
81345200
A
748 void int32Result(GPRReg reg, Node* node, UseChildrenMode mode)
749 {
750 int32Result(reg, node, DataFormatInt32, mode);
751 }
752 void int52Result(GPRReg reg, Node* node, DataFormat format, UseChildrenMode mode = CallUseChildren)
753 {
754 if (mode == CallUseChildren)
755 useChildren(node);
756
757 VirtualRegister virtualRegister = node->virtualRegister();
758 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
759
760 m_gprs.retain(reg, virtualRegister, SpillOrderJS);
761 info.initInt52(node, node->refCount(), reg, format);
762 }
763 void int52Result(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
764 {
765 int52Result(reg, node, DataFormatInt52, mode);
766 }
767 void strictInt52Result(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 768 {
81345200 769 int52Result(reg, node, DataFormatStrictInt52, mode);
6fe7ccc8 770 }
93a37866 771 void noResult(Node* node, UseChildrenMode mode = CallUseChildren)
6fe7ccc8
A
772 {
773 if (mode == UseChildrenCalledExplicitly)
774 return;
6fe7ccc8
A
775 useChildren(node);
776 }
93a37866 777 void cellResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 778 {
6fe7ccc8
A
779 if (mode == CallUseChildren)
780 useChildren(node);
781
93a37866 782 VirtualRegister virtualRegister = node->virtualRegister();
6fe7ccc8 783 m_gprs.retain(reg, virtualRegister, SpillOrderCell);
81345200 784 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
93a37866 785 info.initCell(node, node->refCount(), reg);
6fe7ccc8 786 }
81345200 787 void blessedBooleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 788 {
81345200
A
789#if USE(JSVALUE64)
790 jsValueResult(reg, node, DataFormatJSBoolean, mode);
791#else
ed1e77d3 792 booleanResult(reg, node, mode);
81345200
A
793#endif
794 }
795 void unblessedBooleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
796 {
797#if USE(JSVALUE64)
798 blessBoolean(reg);
799#endif
800 blessedBooleanResult(reg, node, mode);
6fe7ccc8
A
801 }
802#if USE(JSVALUE64)
93a37866 803 void jsValueResult(GPRReg reg, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 804 {
81345200 805 if (format == DataFormatJSInt32)
6fe7ccc8
A
806 m_jit.jitAssertIsJSInt32(reg);
807
6fe7ccc8
A
808 if (mode == CallUseChildren)
809 useChildren(node);
810
93a37866 811 VirtualRegister virtualRegister = node->virtualRegister();
6fe7ccc8 812 m_gprs.retain(reg, virtualRegister, SpillOrderJS);
81345200 813 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
93a37866 814 info.initJSValue(node, node->refCount(), reg, format);
6fe7ccc8 815 }
93a37866 816 void jsValueResult(GPRReg reg, Node* node, UseChildrenMode mode)
6fe7ccc8 817 {
93a37866 818 jsValueResult(reg, node, DataFormatJS, mode);
6fe7ccc8
A
819 }
820#elif USE(JSVALUE32_64)
81345200
A
821 void booleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
822 {
823 if (mode == CallUseChildren)
824 useChildren(node);
825
826 VirtualRegister virtualRegister = node->virtualRegister();
827 m_gprs.retain(reg, virtualRegister, SpillOrderBoolean);
828 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
829 info.initBoolean(node, node->refCount(), reg);
830 }
93a37866 831 void jsValueResult(GPRReg tag, GPRReg payload, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 832 {
6fe7ccc8
A
833 if (mode == CallUseChildren)
834 useChildren(node);
835
93a37866 836 VirtualRegister virtualRegister = node->virtualRegister();
6fe7ccc8
A
837 m_gprs.retain(tag, virtualRegister, SpillOrderJS);
838 m_gprs.retain(payload, virtualRegister, SpillOrderJS);
81345200 839 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
93a37866 840 info.initJSValue(node, node->refCount(), tag, payload, format);
6fe7ccc8 841 }
93a37866 842 void jsValueResult(GPRReg tag, GPRReg payload, Node* node, UseChildrenMode mode)
6fe7ccc8 843 {
93a37866 844 jsValueResult(tag, payload, node, DataFormatJS, mode);
6fe7ccc8
A
845 }
846#endif
81345200
A
847 void jsValueResult(JSValueRegs regs, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
848 {
849#if USE(JSVALUE64)
850 jsValueResult(regs.gpr(), node, format, mode);
851#else
852 jsValueResult(regs.tagGPR(), regs.payloadGPR(), node, format, mode);
853#endif
854 }
93a37866 855 void storageResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 856 {
6fe7ccc8
A
857 if (mode == CallUseChildren)
858 useChildren(node);
859
93a37866 860 VirtualRegister virtualRegister = node->virtualRegister();
6fe7ccc8 861 m_gprs.retain(reg, virtualRegister, SpillOrderStorage);
81345200 862 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
93a37866 863 info.initStorage(node, node->refCount(), reg);
6fe7ccc8 864 }
93a37866 865 void doubleResult(FPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 866 {
6fe7ccc8
A
867 if (mode == CallUseChildren)
868 useChildren(node);
869
93a37866 870 VirtualRegister virtualRegister = node->virtualRegister();
6fe7ccc8 871 m_fprs.retain(reg, virtualRegister, SpillOrderDouble);
81345200 872 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
93a37866 873 info.initDouble(node, node->refCount(), reg);
6fe7ccc8 874 }
93a37866 875 void initConstantInfo(Node* node)
6fe7ccc8 876 {
ed1e77d3 877 ASSERT(node->hasConstant());
81345200 878 generationInfo(node).initConstant(node, node->refCount());
6fe7ccc8
A
879 }
880
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.
93a37866 886
ed1e77d3
A
887 JITCompiler::Call callOperation(V_JITOperation_E operation)
888 {
889 m_jit.setupArgumentsExecState();
890 return appendCallWithExceptionCheck(operation);
891 }
81345200 892 JITCompiler::Call callOperation(P_JITOperation_E operation, GPRReg result)
93a37866
A
893 {
894 m_jit.setupArgumentsExecState();
895 return appendCallWithExceptionCheckSetResult(operation, result);
896 }
81345200 897 JITCompiler::Call callOperation(P_JITOperation_EC operation, GPRReg result, GPRReg cell)
93a37866
A
898 {
899 m_jit.setupArgumentsWithExecState(cell);
900 return appendCallWithExceptionCheckSetResult(operation, result);
901 }
81345200 902 JITCompiler::Call callOperation(P_JITOperation_EO operation, GPRReg result, GPRReg object)
93a37866
A
903 {
904 m_jit.setupArgumentsWithExecState(object);
905 return appendCallWithExceptionCheckSetResult(operation, result);
906 }
81345200 907 JITCompiler::Call callOperation(P_JITOperation_EOS operation, GPRReg result, GPRReg object, size_t size)
93a37866
A
908 {
909 m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size));
910 return appendCallWithExceptionCheckSetResult(operation, result);
911 }
81345200 912 JITCompiler::Call callOperation(P_JITOperation_EOZ operation, GPRReg result, GPRReg object, int32_t size)
93a37866
A
913 {
914 m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size));
915 return appendCallWithExceptionCheckSetResult(operation, result);
916 }
81345200 917 JITCompiler::Call callOperation(C_JITOperation_EOZ operation, GPRReg result, GPRReg object, int32_t size)
93a37866
A
918 {
919 m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(static_cast<size_t>(size)));
920 return appendCallWithExceptionCheckSetResult(operation, result);
921 }
81345200 922 JITCompiler::Call callOperation(P_JITOperation_EPS operation, GPRReg result, GPRReg old, size_t size)
93a37866
A
923 {
924 m_jit.setupArgumentsWithExecState(old, TrustedImmPtr(size));
925 return appendCallWithExceptionCheckSetResult(operation, result);
926 }
81345200 927 JITCompiler::Call callOperation(P_JITOperation_ES operation, GPRReg result, size_t size)
93a37866
A
928 {
929 m_jit.setupArgumentsWithExecState(TrustedImmPtr(size));
930 return appendCallWithExceptionCheckSetResult(operation, result);
931 }
81345200
A
932 JITCompiler::Call callOperation(P_JITOperation_ESJss operation, GPRReg result, size_t index, GPRReg arg1)
933 {
934 m_jit.setupArgumentsWithExecState(TrustedImmPtr(index), arg1);
935 return appendCallWithExceptionCheckSetResult(operation, result);
936 }
937 JITCompiler::Call callOperation(P_JITOperation_ESt operation, GPRReg result, Structure* structure)
93a37866
A
938 {
939 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
940 return appendCallWithExceptionCheckSetResult(operation, result);
941 }
81345200 942 JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2)
93a37866
A
943 {
944 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
945 return appendCallWithExceptionCheckSetResult(operation, result);
946 }
81345200 947 JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, Structure* structure, size_t arg2)
93a37866
A
948 {
949 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2));
950 return appendCallWithExceptionCheckSetResult(operation, result);
951 }
81345200 952 JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
93a37866
A
953 {
954 m_jit.setupArgumentsWithExecState(arg1, arg2);
955 return appendCallWithExceptionCheckSetResult(operation, result);
956 }
81345200 957 JITCompiler::Call callOperation(P_JITOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size)
93a37866
A
958 {
959 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size));
960 return appendCallWithExceptionCheckSetResult(operation, result);
961 }
81345200 962 JITCompiler::Call callOperation(P_JITOperation_EStSS operation, GPRReg result, Structure* structure, size_t index, size_t size)
93a37866
A
963 {
964 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(index), TrustedImmPtr(size));
965 return appendCallWithExceptionCheckSetResult(operation, result);
966 }
81345200 967 JITCompiler::Call callOperation(C_JITOperation_E operation, GPRReg result)
93a37866
A
968 {
969 m_jit.setupArgumentsExecState();
970 return appendCallWithExceptionCheckSetResult(operation, result);
971 }
81345200 972 JITCompiler::Call callOperation(C_JITOperation_EC operation, GPRReg result, GPRReg arg1)
93a37866
A
973 {
974 m_jit.setupArgumentsWithExecState(arg1);
975 return appendCallWithExceptionCheckSetResult(operation, result);
976 }
81345200 977 JITCompiler::Call callOperation(C_JITOperation_EC operation, GPRReg result, JSCell* cell)
93a37866
A
978 {
979 m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
980 return appendCallWithExceptionCheckSetResult(operation, result);
981 }
ed1e77d3
A
982 JITCompiler::Call callOperation(C_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
983 {
984 m_jit.setupArgumentsWithExecState(arg1, arg2);
985 return appendCallWithExceptionCheckSetResult(operation, result);
986 }
987 JITCompiler::Call callOperation(C_JITOperation_ECZC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
988 {
989 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
990 return appendCallWithExceptionCheckSetResult(operation, result);
991 }
992 JITCompiler::Call callOperation(C_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell)
93a37866
A
993 {
994 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
995 return appendCallWithExceptionCheckSetResult(operation, result);
996 }
81345200 997 JITCompiler::Call callOperation(C_JITOperation_EIcf operation, GPRReg result, InlineCallFrame* inlineCallFrame)
93a37866
A
998 {
999 m_jit.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame));
1000 return appendCallWithExceptionCheckSetResult(operation, result);
1001 }
81345200 1002 JITCompiler::Call callOperation(C_JITOperation_ESt operation, GPRReg result, Structure* structure)
93a37866
A
1003 {
1004 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
1005 return appendCallWithExceptionCheckSetResult(operation, result);
1006 }
ed1e77d3
A
1007 JITCompiler::Call callOperation(C_JITOperation_EStJscSymtab operation, GPRReg result, Structure* structure, GPRReg scope, SymbolTable* table)
1008 {
1009 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), scope, TrustedImmPtr(table));
1010 return appendCallWithExceptionCheckSetResult(operation, result);
1011 }
1012 JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, Structure* structure, unsigned knownLength)
1013 {
1014 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength));
1015 return appendCallWithExceptionCheckSetResult(operation, result);
1016 }
1017 JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, Structure* structure, unsigned knownLength, unsigned minCapacity)
1018 {
1019 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength), TrustedImm32(minCapacity));
1020 return appendCallWithExceptionCheckSetResult(operation, result);
1021 }
1022 JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg length)
1023 {
1024 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length);
1025 return appendCallWithExceptionCheckSetResult(operation, result);
1026 }
1027 JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, Structure* structure, GPRReg length, unsigned minCapacity)
1028 {
1029 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length, TrustedImm32(minCapacity));
1030 return appendCallWithExceptionCheckSetResult(operation, result);
1031 }
81345200 1032 JITCompiler::Call callOperation(C_JITOperation_EJssSt operation, GPRReg result, GPRReg arg1, Structure* structure)
93a37866
A
1033 {
1034 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(structure));
1035 return appendCallWithExceptionCheckSetResult(operation, result);
1036 }
81345200 1037 JITCompiler::Call callOperation(C_JITOperation_EJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
93a37866
A
1038 {
1039 m_jit.setupArgumentsWithExecState(arg1, arg2);
1040 return appendCallWithExceptionCheckSetResult(operation, result);
1041 }
81345200 1042 JITCompiler::Call callOperation(C_JITOperation_EJssJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
93a37866
A
1043 {
1044 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1045 return appendCallWithExceptionCheckSetResult(operation, result);
1046 }
1047
81345200 1048 JITCompiler::Call callOperation(S_JITOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
93a37866
A
1049 {
1050 m_jit.setupArgumentsWithExecState(arg1, arg2);
1051 return appendCallWithExceptionCheckSetResult(operation, result);
1052 }
1053
ed1e77d3
A
1054 JITCompiler::Call callOperation(S_JITOperation_EGC operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg2)
1055 {
1056 m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg2);
1057 return appendCallWithExceptionCheckSetResult(operation, result);
1058 }
1059
1060 JITCompiler::Call callOperation(C_JITOperation_EGC operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg2)
1061 {
1062 m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg2);
1063 return appendCallWithExceptionCheckSetResult(operation, result);
1064 }
1065
81345200
A
1066 JITCompiler::Call callOperation(Jss_JITOperation_EZ operation, GPRReg result, GPRReg arg1)
1067 {
1068 m_jit.setupArgumentsWithExecState(arg1);
1069 return appendCallWithExceptionCheckSetResult(operation, result);
1070 }
1071
1072 JITCompiler::Call callOperation(V_JITOperation_EC operation, GPRReg arg1)
93a37866
A
1073 {
1074 m_jit.setupArgumentsWithExecState(arg1);
1075 return appendCallWithExceptionCheck(operation);
1076 }
1077
81345200
A
1078 JITCompiler::Call callOperation(V_JITOperation_EC operation, JSCell* arg1)
1079 {
1080 m_jit.setupArgumentsWithExecState(TrustedImmPtr(arg1));
1081 return appendCallWithExceptionCheck(operation);
1082 }
1083
1084 JITCompiler::Call callOperation(V_JITOperation_ECIcf operation, GPRReg arg1, InlineCallFrame* inlineCallFrame)
93a37866
A
1085 {
1086 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(inlineCallFrame));
1087 return appendCallWithExceptionCheck(operation);
1088 }
81345200 1089 JITCompiler::Call callOperation(V_JITOperation_ECCIcf operation, GPRReg arg1, GPRReg arg2, InlineCallFrame* inlineCallFrame)
93a37866
A
1090 {
1091 m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(inlineCallFrame));
1092 return appendCallWithExceptionCheck(operation);
1093 }
1094
81345200 1095 JITCompiler::Call callOperation(V_JITOperation_ECZ operation, GPRReg arg1, int arg2)
93a37866
A
1096 {
1097 m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1098 return appendCallWithExceptionCheck(operation);
1099 }
81345200 1100 JITCompiler::Call callOperation(V_JITOperation_ECC operation, GPRReg arg1, GPRReg arg2)
93a37866
A
1101 {
1102 m_jit.setupArgumentsWithExecState(arg1, arg2);
1103 return appendCallWithExceptionCheck(operation);
1104 }
81345200 1105 JITCompiler::Call callOperation(V_JITOperation_ECC operation, GPRReg arg1, JSCell* arg2)
93a37866 1106 {
81345200
A
1107 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
1108 return appendCallWithExceptionCheck(operation);
1109 }
1110 JITCompiler::Call callOperation(V_JITOperation_ECC operation, JSCell* arg1, GPRReg arg2)
1111 {
1112 m_jit.setupArgumentsWithExecState(TrustedImmPtr(arg1), arg2);
93a37866
A
1113 return appendCallWithExceptionCheck(operation);
1114 }
1115
81345200 1116 JITCompiler::Call callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb operation, void* pointer)
93a37866 1117 {
81345200
A
1118 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1119 return appendCallWithCallFrameRollbackOnException(operation);
1120 }
1121
1122 JITCompiler::Call callOperationWithCallFrameRollbackOnException(Z_JITOperation_E operation, GPRReg result)
1123 {
1124 m_jit.setupArgumentsExecState();
1125 return appendCallWithCallFrameRollbackOnExceptionSetResult(operation, result);
93a37866 1126 }
ed1e77d3
A
1127 JITCompiler::Call callOperation(Z_JITOperation_EC operation, GPRReg result, GPRReg arg1)
1128 {
1129 m_jit.setupArgumentsWithExecState(arg1);
1130 return appendCallWithExceptionCheckSetResult(operation, result);
1131 }
93a37866 1132
ed1e77d3
A
1133 template<typename FunctionType>
1134 JITCompiler::Call callOperation(FunctionType operation, NoResultTag)
1135 {
1136 return callOperation(operation);
1137 }
93a37866
A
1138 template<typename FunctionType, typename ArgumentType1>
1139 JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1)
1140 {
1141 return callOperation(operation, arg1);
1142 }
1143 template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
1144 JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2)
1145 {
1146 return callOperation(operation, arg1, arg2);
1147 }
1148 template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3>
1149 JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3)
1150 {
1151 return callOperation(operation, arg1, arg2, arg3);
1152 }
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)
1155 {
1156 return callOperation(operation, arg1, arg2, arg3, arg4);
1157 }
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)
1160 {
1161 return callOperation(operation, arg1, arg2, arg3, arg4, arg5);
1162 }
1163
81345200 1164 JITCompiler::Call callOperation(D_JITOperation_ZZ operation, FPRReg result, GPRReg arg1, GPRReg arg2)
93a37866
A
1165 {
1166 m_jit.setupArguments(arg1, arg2);
1167 return appendCallSetResult(operation, result);
1168 }
81345200
A
1169 JITCompiler::Call callOperation(D_JITOperation_D operation, FPRReg result, FPRReg arg1)
1170 {
1171 m_jit.setupArguments(arg1);
1172 return appendCallSetResult(operation, result);
1173 }
1174 JITCompiler::Call callOperation(D_JITOperation_DD operation, FPRReg result, FPRReg arg1, FPRReg arg2)
93a37866
A
1175 {
1176 m_jit.setupArguments(arg1, arg2);
1177 return appendCallSetResult(operation, result);
1178 }
ed1e77d3 1179 JITCompiler::Call callOperation(T_JITOperation_EJss operation, GPRReg result, GPRReg arg1)
93a37866
A
1180 {
1181 m_jit.setupArgumentsWithExecState(arg1);
1182 return appendCallWithExceptionCheckSetResult(operation, result);
1183 }
ed1e77d3
A
1184 JITCompiler::Call callOperation(C_JITOperation_EJscZ operation, GPRReg result, GPRReg arg1, int32_t arg2)
1185 {
1186 m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1187 return appendCallWithExceptionCheckSetResult(operation, result);
1188 }
81345200 1189 JITCompiler::Call callOperation(C_JITOperation_EZ operation, GPRReg result, GPRReg arg1)
93a37866
A
1190 {
1191 m_jit.setupArgumentsWithExecState(arg1);
1192 return appendCallWithExceptionCheckSetResult(operation, result);
1193 }
81345200
A
1194 JITCompiler::Call callOperation(C_JITOperation_EZ operation, GPRReg result, int32_t arg1)
1195 {
1196 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1197 return appendCallWithExceptionCheckSetResult(operation, result);
1198 }
93a37866 1199
ed1e77d3
A
1200 JITCompiler::Call callOperation(J_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell)
1201 {
1202 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
1203 return appendCallWithExceptionCheckSetResult(operation, result);
1204 }
1205
1206 JITCompiler::Call callOperation(V_JITOperation_EWs operation, WatchpointSet* watchpointSet)
1207 {
1208 m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet));
1209 return appendCall(operation);
1210 }
1211
6fe7ccc8 1212#if USE(JSVALUE64)
81345200 1213 JITCompiler::Call callOperation(J_JITOperation_E operation, GPRReg result)
93a37866
A
1214 {
1215 m_jit.setupArgumentsExecState();
1216 return appendCallWithExceptionCheckSetResult(operation, result);
1217 }
81345200 1218 JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg result, void* pointer)
6fe7ccc8
A
1219 {
1220 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1221 return appendCallWithExceptionCheckSetResult(operation, result);
1222 }
81345200 1223 JITCompiler::Call callOperation(Z_JITOperation_D operation, GPRReg result, FPRReg arg1)
6fe7ccc8
A
1224 {
1225 m_jit.setupArguments(arg1);
1226 JITCompiler::Call call = m_jit.appendCall(operation);
1227 m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1228 return call;
1229 }
81345200 1230 JITCompiler::Call callOperation(Q_JITOperation_J operation, GPRReg result, GPRReg value)
6fe7ccc8 1231 {
81345200
A
1232 m_jit.setupArguments(value);
1233 return appendCallSetResult(operation, result);
6fe7ccc8 1234 }
81345200 1235 JITCompiler::Call callOperation(Q_JITOperation_D operation, GPRReg result, FPRReg value)
6fe7ccc8 1236 {
81345200
A
1237 m_jit.setupArguments(value);
1238 return appendCallSetResult(operation, result);
6fe7ccc8 1239 }
ed1e77d3 1240 JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg result, UniquedStringImpl* uid)
93a37866 1241 {
81345200 1242 m_jit.setupArgumentsWithExecState(TrustedImmPtr(uid));
93a37866
A
1243 return appendCallWithExceptionCheckSetResult(operation, result);
1244 }
81345200 1245 JITCompiler::Call callOperation(J_JITOperation_EA operation, GPRReg result, GPRReg arg1)
93a37866 1246 {
81345200 1247 m_jit.setupArgumentsWithExecState(arg1);
93a37866
A
1248 return appendCallWithExceptionCheckSetResult(operation, result);
1249 }
81345200 1250 JITCompiler::Call callOperation(J_JITOperation_EAZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
6fe7ccc8 1251 {
81345200 1252 m_jit.setupArgumentsWithExecState(arg1, arg2);
6fe7ccc8
A
1253 return appendCallWithExceptionCheckSetResult(operation, result);
1254 }
81345200 1255 JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
93a37866
A
1256 {
1257 m_jit.setupArgumentsWithExecState(arg1, arg2);
1258 return appendCallWithExceptionCheckSetResult(operation, result);
1259 }
81345200 1260 JITCompiler::Call callOperation(J_JITOperation_EPS operation, GPRReg result, void* pointer, size_t size)
6fe7ccc8
A
1261 {
1262 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
1263 return appendCallWithExceptionCheckSetResult(operation, result);
1264 }
81345200 1265 JITCompiler::Call callOperation(J_JITOperation_ESS operation, GPRReg result, int startConstant, int numConstants)
6fe7ccc8
A
1266 {
1267 m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
1268 return appendCallWithExceptionCheckSetResult(operation, result);
1269 }
81345200 1270 JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg result, GPRReg arg1, void* pointer)
6fe7ccc8
A
1271 {
1272 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
1273 return appendCallWithExceptionCheckSetResult(operation, result);
1274 }
81345200 1275 JITCompiler::Call callOperation(J_JITOperation_EC operation, GPRReg result, JSCell* cell)
93a37866
A
1276 {
1277 m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
1278 return appendCallWithExceptionCheckSetResult(operation, result);
1279 }
ed1e77d3
A
1280 JITCompiler::Call callOperation(J_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1281 {
1282 m_jit.setupArgumentsWithExecState(arg1, arg2);
1283 return appendCallWithExceptionCheckSetResult(operation, result);
1284 }
1285 JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, const UniquedStringImpl* uid)
6fe7ccc8 1286 {
81345200 1287 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
6fe7ccc8
A
1288 return appendCallWithExceptionCheckSetResult(operation, result);
1289 }
ed1e77d3 1290 JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, UniquedStringImpl* uid)
6fe7ccc8 1291 {
81345200 1292 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
6fe7ccc8
A
1293 return appendCallWithExceptionCheckSetResult(operation, result);
1294 }
81345200 1295 JITCompiler::Call callOperation(J_JITOperation_EDA operation, GPRReg result, FPRReg arg1, GPRReg arg2)
93a37866
A
1296 {
1297 m_jit.setupArgumentsWithExecState(arg1, arg2);
1298 return appendCallWithExceptionCheckSetResult(operation, result);
1299 }
ed1e77d3
A
1300 JITCompiler::Call callOperation(J_JITOperation_EJC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1301 {
1302 m_jit.setupArgumentsWithExecState(arg1, arg2);
1303 return appendCallWithExceptionCheckSetResult(operation, result);
1304 }
1305 JITCompiler::Call callOperation(J_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1306 {
1307 m_jit.setupArgumentsWithExecState(arg1, arg2);
1308 return appendCallWithExceptionCheckSetResult(operation, result);
1309 }
81345200 1310 JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg result, GPRReg arg1, GPRReg arg2)
6fe7ccc8
A
1311 {
1312 m_jit.setupArgumentsWithExecState(arg1, arg2);
1313 return appendCallWithExceptionCheckSetResult(operation, result);
1314 }
81345200 1315 JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg result, GPRReg arg1)
6fe7ccc8
A
1316 {
1317 m_jit.setupArgumentsWithExecState(arg1);
1318 return appendCallWithExceptionCheckSetResult(operation, result);
1319 }
81345200 1320 JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg result, GPRReg arg1)
6fe7ccc8 1321 {
93a37866 1322 m_jit.setupArgumentsWithExecState(arg1);
6fe7ccc8
A
1323 return appendCallWithExceptionCheckSetResult(operation, result);
1324 }
81345200 1325 JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg result, int32_t arg1)
6fe7ccc8 1326 {
93a37866 1327 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
6fe7ccc8
A
1328 return appendCallWithExceptionCheckSetResult(operation, result);
1329 }
81345200 1330 JITCompiler::Call callOperation(J_JITOperation_EZZ operation, GPRReg result, int32_t arg1, GPRReg arg2)
6fe7ccc8 1331 {
93a37866 1332 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
6fe7ccc8
A
1333 return appendCallWithExceptionCheckSetResult(operation, result);
1334 }
81345200 1335 JITCompiler::Call callOperation(J_JITOperation_EZIcfZ operation, GPRReg result, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
6fe7ccc8 1336 {
93a37866
A
1337 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
1338 return appendCallWithExceptionCheckSetResult(operation, result);
1339 }
1340
81345200
A
1341 JITCompiler::Call callOperation(P_JITOperation_EJS operation, GPRReg result, GPRReg value, size_t index)
1342 {
1343 m_jit.setupArgumentsWithExecState(value, TrustedImmPtr(index));
1344 return appendCallSetResult(operation, result);
1345 }
1346
1347 JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, Structure* structure, GPRReg arg2)
1348 {
1349 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
1350 return appendCallWithExceptionCheckSetResult(operation, result);
1351 }
93a37866 1352
81345200 1353 JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
93a37866
A
1354 {
1355 m_jit.setupArgumentsWithExecState(arg1);
6fe7ccc8
A
1356 return appendCallWithExceptionCheckSetResult(operation, result);
1357 }
ed1e77d3
A
1358 JITCompiler::Call callOperation(C_JITOperation_EJJC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1359 {
1360 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1361 return appendCallWithExceptionCheckSetResult(operation, result);
1362 }
1363 JITCompiler::Call callOperation(C_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1364 {
1365 m_jit.setupArgumentsWithExecState(arg1, arg2);
1366 return appendCallWithExceptionCheckSetResult(operation, result);
1367 }
1368 JITCompiler::Call callOperation(C_JITOperation_EJZC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1369 {
1370 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1371 return appendCallWithExceptionCheckSetResult(operation, result);
1372 }
81345200 1373 JITCompiler::Call callOperation(S_JITOperation_J operation, GPRReg result, GPRReg arg1)
6fe7ccc8
A
1374 {
1375 m_jit.setupArguments(arg1);
1376 return appendCallSetResult(operation, result);
1377 }
81345200 1378 JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
6fe7ccc8
A
1379 {
1380 m_jit.setupArgumentsWithExecState(arg1);
1381 return appendCallWithExceptionCheckSetResult(operation, result);
1382 }
81345200 1383 JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
93a37866
A
1384 {
1385 m_jit.setupArgumentsWithExecState(arg1);
1386 return appendCallWithExceptionCheckSetResult(operation, result);
1387 }
81345200 1388 JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
6fe7ccc8
A
1389 {
1390 m_jit.setupArgumentsWithExecState(arg1, arg2);
1391 return appendCallWithExceptionCheckSetResult(operation, result);
1392 }
93a37866 1393
81345200 1394 JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg result, GPRReg arg1, GPRReg arg2)
6fe7ccc8
A
1395 {
1396 m_jit.setupArgumentsWithExecState(arg1, arg2);
1397 return appendCallWithExceptionCheckSetResult(operation, result);
1398 }
81345200 1399 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
6fe7ccc8
A
1400 {
1401 m_jit.setupArgumentsWithExecState(arg1, arg2);
1402 return appendCallWithExceptionCheckSetResult(operation, result);
1403 }
81345200 1404 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, MacroAssembler::TrustedImm32 imm)
6fe7ccc8 1405 {
93a37866 1406 m_jit.setupArgumentsWithExecState(arg1, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))));
6fe7ccc8
A
1407 return appendCallWithExceptionCheckSetResult(operation, result);
1408 }
81345200 1409 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, MacroAssembler::TrustedImm32 imm, GPRReg arg2)
6fe7ccc8 1410 {
93a37866 1411 m_jit.setupArgumentsWithExecState(MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))), arg2);
6fe7ccc8
A
1412 return appendCallWithExceptionCheckSetResult(operation, result);
1413 }
81345200 1414 JITCompiler::Call callOperation(J_JITOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
6fe7ccc8
A
1415 {
1416 m_jit.setupArgumentsWithExecState(arg1, arg2);
1417 return appendCallWithExceptionCheckSetResult(operation, result);
1418 }
81345200 1419 JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
6fe7ccc8
A
1420 {
1421 m_jit.setupArgumentsWithExecState(arg1, arg2);
1422 return appendCallWithExceptionCheckSetResult(operation, result);
1423 }
81345200
A
1424 JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg result, GPRReg arg1, JSValueRegs arg2)
1425 {
1426 m_jit.setupArgumentsWithExecState(arg1, arg2.gpr());
1427 return appendCallWithExceptionCheckSetResult(operation, result);
1428 }
93a37866 1429
81345200
A
1430 JITCompiler::Call callOperation(V_JITOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3)
1431 {
1432 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1433 return appendCallWithExceptionCheck(operation);
1434 }
1435 JITCompiler::Call callOperation(V_JITOperation_EJ operation, GPRReg arg1)
1436 {
1437 m_jit.setupArgumentsWithExecState(arg1);
1438 return appendCallWithExceptionCheck(operation);
1439 }
1440 JITCompiler::Call callOperation(V_JITOperation_EJPP operation, GPRReg arg1, GPRReg arg2, void* pointer)
6fe7ccc8
A
1441 {
1442 m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(pointer));
1443 return appendCallWithExceptionCheck(operation);
1444 }
ed1e77d3 1445 JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1, GPRReg arg2, UniquedStringImpl* uid)
6fe7ccc8 1446 {
81345200 1447 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, arg2, TrustedImmPtr(uid));
6fe7ccc8
A
1448 return appendCallWithExceptionCheck(operation);
1449 }
81345200 1450 JITCompiler::Call callOperation(V_JITOperation_EJJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
6fe7ccc8
A
1451 {
1452 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1453 return appendCallWithExceptionCheck(operation);
1454 }
81345200 1455 JITCompiler::Call callOperation(V_JITOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
6fe7ccc8
A
1456 {
1457 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1458 return appendCallWithExceptionCheck(operation);
1459 }
93a37866 1460
81345200 1461 JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
6fe7ccc8
A
1462 {
1463 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1464 return appendCallWithExceptionCheck(operation);
1465 }
81345200 1466 JITCompiler::Call callOperation(V_JITOperation_ECJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
6fe7ccc8
A
1467 {
1468 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1469 return appendCallWithExceptionCheck(operation);
1470 }
93a37866 1471
81345200 1472 JITCompiler::Call callOperation(D_JITOperation_EJ operation, FPRReg result, GPRReg arg1)
6fe7ccc8
A
1473 {
1474 m_jit.setupArgumentsWithExecState(arg1);
1475 return appendCallWithExceptionCheckSetResult(operation, result);
1476 }
93a37866 1477
ed1e77d3
A
1478 JITCompiler::Call callOperation(Z_JITOperation_EJZZ operation, GPRReg result, GPRReg arg1, unsigned arg2, unsigned arg3)
1479 {
1480 m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2), TrustedImm32(arg3));
1481 return appendCallWithExceptionCheckSetResult(operation, result);
1482 }
1483 JITCompiler::Call callOperation(F_JITOperation_EFJZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2, unsigned arg3, GPRReg arg4)
1484 {
1485 m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImm32(arg3), arg4);
1486 return appendCallWithExceptionCheckSetResult(operation, result);
1487 }
1488 JITCompiler::Call callOperation(Z_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, unsigned arg2)
1489 {
1490 m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1491 return appendCallWithExceptionCheckSetResult(operation, result);
1492 }
1493 JITCompiler::Call callOperation(V_JITOperation_EZJZZZ operation, unsigned arg1, GPRReg arg2, unsigned arg3, GPRReg arg4, unsigned arg5)
1494 {
1495 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2, TrustedImm32(arg3), arg4, TrustedImm32(arg5));
1496 return appendCallWithExceptionCheck(operation);
1497 }
93a37866
A
1498#else // USE(JSVALUE32_64)
1499
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),
6fe7ccc8 1504#else
93a37866
A
1505#define EABI_32BIT_DUMMY_ARG
1506#endif
1507
81345200
A
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.
1511#if CPU(SH4)
1512#define SH4_32BIT_DUMMY_ARG TrustedImm32(0),
1513#else
1514#define SH4_32BIT_DUMMY_ARG
1515#endif
1516
1517 JITCompiler::Call callOperation(Z_JITOperation_D operation, GPRReg result, FPRReg arg1)
6fe7ccc8
A
1518 {
1519 prepareForExternalCall();
1520 m_jit.setupArguments(arg1);
1521 JITCompiler::Call call = m_jit.appendCall(operation);
1522 m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1523 return call;
1524 }
81345200 1525 JITCompiler::Call callOperation(J_JITOperation_E operation, GPRReg resultTag, GPRReg resultPayload)
93a37866
A
1526 {
1527 m_jit.setupArgumentsExecState();
1528 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1529 }
81345200 1530 JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, void* pointer)
6fe7ccc8
A
1531 {
1532 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1533 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1534 }
81345200 1535 JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, void* pointer)
6fe7ccc8
A
1536 {
1537 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
1538 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1539 }
81345200 1540 JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
6fe7ccc8 1541 {
81345200 1542 m_jit.setupArgumentsWithExecState(arg1);
6fe7ccc8
A
1543 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1544 }
ed1e77d3 1545 JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg resultTag, GPRReg resultPayload, UniquedStringImpl* uid)
6fe7ccc8 1546 {
81345200 1547 m_jit.setupArgumentsWithExecState(TrustedImmPtr(uid));
6fe7ccc8
A
1548 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1549 }
81345200 1550 JITCompiler::Call callOperation(J_JITOperation_EA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
6fe7ccc8 1551 {
81345200 1552 m_jit.setupArgumentsWithExecState(arg1);
6fe7ccc8
A
1553 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1554 }
81345200 1555 JITCompiler::Call callOperation(J_JITOperation_EAZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
6fe7ccc8 1556 {
81345200 1557 m_jit.setupArgumentsWithExecState(arg1, arg2);
6fe7ccc8
A
1558 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1559 }
ed1e77d3
A
1560 JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg resultPayload, GPRReg resultTag, GPRReg arg1)
1561 {
1562 m_jit.setupArgumentsWithExecState(arg1);
1563 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1564 }
1565 JITCompiler::Call callOperation(J_JITOperation_EJC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1566 {
1567 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1568 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1569 }
81345200 1570 JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
93a37866
A
1571 {
1572 m_jit.setupArgumentsWithExecState(arg1, arg2);
1573 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1574 }
81345200 1575 JITCompiler::Call callOperation(J_JITOperation_EPS operation, GPRReg resultTag, GPRReg resultPayload, void* pointer, size_t size)
6fe7ccc8
A
1576 {
1577 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
1578 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1579 }
81345200 1580 JITCompiler::Call callOperation(J_JITOperation_ESS operation, GPRReg resultTag, GPRReg resultPayload, int startConstant, int numConstants)
6fe7ccc8
A
1581 {
1582 m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
1583 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1584 }
81345200 1585 JITCompiler::Call callOperation(J_JITOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, void* pointer)
6fe7ccc8 1586 {
93a37866 1587 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(pointer));
6fe7ccc8
A
1588 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1589 }
81345200 1590 JITCompiler::Call callOperation(J_JITOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
6fe7ccc8 1591 {
93a37866
A
1592 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1593 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1594 }
1595
81345200 1596 JITCompiler::Call callOperation(J_JITOperation_EC operation, GPRReg resultTag, GPRReg resultPayload, JSCell* cell)
93a37866
A
1597 {
1598 m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
6fe7ccc8
A
1599 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1600 }
ed1e77d3
A
1601 JITCompiler::Call callOperation(J_JITOperation_ECZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1602 {
1603 m_jit.setupArgumentsWithExecState(arg1, arg2);
1604 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1605 }
1606 JITCompiler::Call callOperation(J_JITOperation_EJscC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, JSCell* cell)
1607 {
1608 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
1609 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1610 }
1611 JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1, const UniquedStringImpl* uid)
6fe7ccc8 1612 {
81345200 1613 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
6fe7ccc8
A
1614 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1615 }
ed1e77d3 1616 JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid)
6fe7ccc8 1617 {
81345200 1618 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, TrustedImmPtr(uid));
6fe7ccc8
A
1619 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1620 }
ed1e77d3 1621 JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, int32_t arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid)
6fe7ccc8 1622 {
81345200 1623 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, TrustedImm32(arg1Tag), TrustedImmPtr(uid));
93a37866
A
1624 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1625 }
81345200 1626 JITCompiler::Call callOperation(J_JITOperation_EDA operation, GPRReg resultTag, GPRReg resultPayload, FPRReg arg1, GPRReg arg2)
93a37866 1627 {
81345200 1628 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1, arg2);
6fe7ccc8
A
1629 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1630 }
81345200 1631 JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
6fe7ccc8 1632 {
93a37866 1633 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
6fe7ccc8
A
1634 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1635 }
81345200 1636 JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, TrustedImm32 arg1Tag, GPRReg arg1Payload, GPRReg arg2)
6fe7ccc8 1637 {
93a37866 1638 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
6fe7ccc8
A
1639 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1640 }
81345200 1641 JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload)
6fe7ccc8 1642 {
93a37866
A
1643 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1644 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
6fe7ccc8 1645 }
81345200 1646 JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
6fe7ccc8
A
1647 {
1648 m_jit.setupArgumentsWithExecState(arg1);
93a37866 1649 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
6fe7ccc8 1650 }
81345200 1651 JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1)
6fe7ccc8 1652 {
93a37866
A
1653 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1654 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
6fe7ccc8 1655 }
81345200 1656 JITCompiler::Call callOperation(J_JITOperation_EZIcfZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
6fe7ccc8 1657 {
93a37866
A
1658 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
1659 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1660 }
81345200 1661 JITCompiler::Call callOperation(J_JITOperation_EZZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, GPRReg arg2)
93a37866
A
1662 {
1663 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
1664 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1665 }
1666
81345200
A
1667 JITCompiler::Call callOperation(P_JITOperation_EJS operation, GPRReg result, JSValueRegs value, size_t index)
1668 {
1669 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG value.payloadGPR(), value.tagGPR(), TrustedImmPtr(index));
1670 return appendCallSetResult(operation, result);
1671 }
1672
1673 JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, Structure* structure, GPRReg arg2Tag, GPRReg arg2Payload)
1674 {
1675 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2Payload, arg2Tag);
1676 return appendCallWithExceptionCheckSetResult(operation, result);
1677 }
93a37866 1678
81345200 1679 JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
93a37866
A
1680 {
1681 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
6fe7ccc8
A
1682 return appendCallWithExceptionCheckSetResult(operation, result);
1683 }
81345200 1684 JITCompiler::Call callOperation(S_JITOperation_J operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
6fe7ccc8
A
1685 {
1686 m_jit.setupArguments(arg1Payload, arg1Tag);
1687 return appendCallSetResult(operation, result);
1688 }
81345200 1689 JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
6fe7ccc8 1690 {
93a37866 1691 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
6fe7ccc8
A
1692 return appendCallWithExceptionCheckSetResult(operation, result);
1693 }
93a37866 1694
81345200 1695 JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
6fe7ccc8 1696 {
81345200 1697 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
6fe7ccc8
A
1698 return appendCallWithExceptionCheckSetResult(operation, result);
1699 }
81345200 1700 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
6fe7ccc8 1701 {
81345200 1702 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
6fe7ccc8
A
1703 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1704 }
81345200 1705 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, MacroAssembler::TrustedImm32 imm)
6fe7ccc8 1706 {
81345200 1707 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag));
6fe7ccc8
A
1708 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1709 }
81345200 1710 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, MacroAssembler::TrustedImm32 imm, GPRReg arg2Tag, GPRReg arg2Payload)
6fe7ccc8 1711 {
81345200 1712 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag), SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
6fe7ccc8
A
1713 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1714 }
93a37866 1715
81345200 1716 JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload)
93a37866 1717 {
81345200 1718 m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
93a37866
A
1719 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1720 }
ed1e77d3
A
1721 JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Payload)
1722 {
1723 m_jit.setupArgumentsWithExecState(arg1, arg2Payload, MacroAssembler::TrustedImm32(JSValue::CellTag));
1724 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1725 }
81345200
A
1726 JITCompiler::Call callOperation(J_JITOperation_ECJ operation, JSValueRegs result, GPRReg arg1, JSValueRegs arg2)
1727 {
1728 m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR());
1729 return appendCallWithExceptionCheckSetResult(operation, result.payloadGPR(), result.tagGPR());
1730 }
1731 JITCompiler::Call callOperation(J_JITOperation_ECC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
93a37866 1732 {
81345200 1733 m_jit.setupArgumentsWithExecState(arg1, arg2);
93a37866
A
1734 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1735 }
1736
81345200 1737 JITCompiler::Call callOperation(V_JITOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3)
6fe7ccc8 1738 {
81345200
A
1739 m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3);
1740 return appendCallWithExceptionCheck(operation);
6fe7ccc8 1741 }
81345200
A
1742
1743 JITCompiler::Call callOperation(V_JITOperation_EJ operation, GPRReg arg1Tag, GPRReg arg1Payload)
6fe7ccc8 1744 {
81345200
A
1745 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1746 return appendCallWithExceptionCheck(operation);
6fe7ccc8 1747 }
93a37866 1748
81345200 1749 JITCompiler::Call callOperation(V_JITOperation_EJPP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, void* pointer)
6fe7ccc8 1750 {
93a37866 1751 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(pointer));
6fe7ccc8
A
1752 return appendCallWithExceptionCheck(operation);
1753 }
ed1e77d3 1754 JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Payload, UniquedStringImpl* uid)
6fe7ccc8 1755 {
81345200 1756 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, arg2Payload, TrustedImm32(JSValue::CellTag), TrustedImmPtr(uid));
6fe7ccc8
A
1757 return appendCallWithExceptionCheck(operation);
1758 }
81345200 1759 JITCompiler::Call callOperation(V_JITOperation_ECJJ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
6fe7ccc8
A
1760 {
1761 m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, arg3Payload, arg3Tag);
1762 return appendCallWithExceptionCheck(operation);
1763 }
93a37866 1764
81345200 1765 JITCompiler::Call callOperation(V_JITOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
6fe7ccc8 1766 {
81345200 1767 m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
6fe7ccc8
A
1768 return appendCallWithExceptionCheck(operation);
1769 }
93a37866 1770
81345200 1771 JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
93a37866 1772 {
81345200 1773 m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
93a37866
A
1774 return appendCallWithExceptionCheck(operation);
1775 }
81345200 1776 JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, TrustedImm32 arg3Tag, GPRReg arg3Payload)
6fe7ccc8 1777 {
81345200 1778 m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
6fe7ccc8
A
1779 return appendCallWithExceptionCheck(operation);
1780 }
1781
81345200 1782 JITCompiler::Call callOperation(D_JITOperation_EJ operation, FPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
6fe7ccc8 1783 {
93a37866 1784 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
6fe7ccc8
A
1785 return appendCallWithExceptionCheckSetResult(operation, result);
1786 }
1787
ed1e77d3
A
1788 JITCompiler::Call callOperation(Z_JITOperation_EJZZ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, unsigned arg2, unsigned arg3)
1789 {
1790 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImm32(arg2), TrustedImm32(arg3));
1791 return appendCallWithExceptionCheckSetResult(operation, result);
1792 }
1793 JITCompiler::Call callOperation(F_JITOperation_EFJZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, unsigned arg3, GPRReg arg4)
1794 {
1795 m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, TrustedImm32(arg3), arg4);
1796 return appendCallWithExceptionCheckSetResult(operation, result);
1797 }
1798 JITCompiler::Call callOperation(Z_JITOperation_EJZ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, unsigned arg2)
1799 {
1800 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImm32(arg2));
1801 return appendCallWithExceptionCheckSetResult(operation, result);
1802 }
1803 JITCompiler::Call callOperation(V_JITOperation_EZJZZZ operation, unsigned arg1, GPRReg arg2Tag, GPRReg arg2Payload, unsigned arg3, GPRReg arg4, unsigned arg5)
1804 {
1805 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2Payload, arg2Tag, TrustedImm32(arg3), arg4, TrustedImm32(arg5));
1806 return appendCallWithExceptionCheck(operation);
1807 }
93a37866 1808#undef EABI_32BIT_DUMMY_ARG
81345200 1809#undef SH4_32BIT_DUMMY_ARG
93a37866
A
1810
1811 template<typename FunctionType>
1812 JITCompiler::Call callOperation(
1813 FunctionType operation, JSValueRegs result)
6fe7ccc8 1814 {
93a37866 1815 return callOperation(operation, result.tagGPR(), result.payloadGPR());
6fe7ccc8 1816 }
93a37866
A
1817 template<typename FunctionType, typename ArgumentType1>
1818 JITCompiler::Call callOperation(
1819 FunctionType operation, JSValueRegs result, ArgumentType1 arg1)
6fe7ccc8 1820 {
93a37866 1821 return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1);
6fe7ccc8 1822 }
93a37866
A
1823 template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
1824 JITCompiler::Call callOperation(
1825 FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2)
1826 {
1827 return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2);
1828 }
1829 template<
1830 typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1831 typename ArgumentType3>
1832 JITCompiler::Call callOperation(
1833 FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1834 ArgumentType3 arg3)
1835 {
1836 return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3);
1837 }
1838 template<
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)
1844 {
1845 return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4);
1846 }
1847 template<
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)
1853 {
1854 return callOperation(
1855 operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4, arg5);
1856 }
1857#endif // USE(JSVALUE32_64)
6fe7ccc8 1858
81345200 1859#if !defined(NDEBUG) && !CPU(ARM) && !CPU(MIPS) && !CPU(SH4)
6fe7ccc8
A
1860 void prepareForExternalCall()
1861 {
93a37866
A
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.
1865 //
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.
1870
6fe7ccc8 1871 for (unsigned i = 0; i < sizeof(void*) / 4; i++)
93a37866 1872 m_jit.store32(TrustedImm32(0xbadbeef), reinterpret_cast<char*>(&m_jit.vm()->topCallFrame) + i * 4);
6fe7ccc8
A
1873 }
1874#else
1875 void prepareForExternalCall() { }
1876#endif
1877
1878 // These methods add call instructions, with optional exception checks & setting results.
1879 JITCompiler::Call appendCallWithExceptionCheck(const FunctionPtr& function)
1880 {
1881 prepareForExternalCall();
81345200
A
1882 m_jit.emitStoreCodeOrigin(m_currentNode->origin.semantic);
1883 JITCompiler::Call call = m_jit.appendCall(function);
1884 m_jit.exceptionCheck();
1885 return call;
1886 }
1887 JITCompiler::Call appendCallWithCallFrameRollbackOnException(const FunctionPtr& function)
1888 {
1889 prepareForExternalCall();
1890 m_jit.emitStoreCodeOrigin(m_currentNode->origin.semantic);
6fe7ccc8 1891 JITCompiler::Call call = m_jit.appendCall(function);
81345200 1892 m_jit.exceptionCheckWithCallFrameRollback();
6fe7ccc8
A
1893 return call;
1894 }
1895 JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result)
1896 {
1897 JITCompiler::Call call = appendCallWithExceptionCheck(function);
81345200
A
1898 if ((result != InvalidGPRReg) && (result != GPRInfo::returnValueGPR))
1899 m_jit.move(GPRInfo::returnValueGPR, result);
1900 return call;
1901 }
1902 JITCompiler::Call appendCallWithCallFrameRollbackOnExceptionSetResult(const FunctionPtr& function, GPRReg result)
1903 {
1904 JITCompiler::Call call = appendCallWithCallFrameRollbackOnException(function);
1905 if ((result != InvalidGPRReg) && (result != GPRInfo::returnValueGPR))
1906 m_jit.move(GPRInfo::returnValueGPR, result);
6fe7ccc8
A
1907 return call;
1908 }
1909 JITCompiler::Call appendCallSetResult(const FunctionPtr& function, GPRReg result)
1910 {
1911 prepareForExternalCall();
81345200 1912 m_jit.emitStoreCodeOrigin(m_currentNode->origin.semantic);
6fe7ccc8 1913 JITCompiler::Call call = m_jit.appendCall(function);
81345200
A
1914 if (result != InvalidGPRReg)
1915 m_jit.move(GPRInfo::returnValueGPR, result);
6fe7ccc8
A
1916 return call;
1917 }
93a37866
A
1918 JITCompiler::Call appendCall(const FunctionPtr& function)
1919 {
1920 prepareForExternalCall();
81345200 1921 m_jit.emitStoreCodeOrigin(m_currentNode->origin.semantic);
93a37866
A
1922 return m_jit.appendCall(function);
1923 }
6fe7ccc8
A
1924 JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result1, GPRReg result2)
1925 {
1926 JITCompiler::Call call = appendCallWithExceptionCheck(function);
1927 m_jit.setupResults(result1, result2);
1928 return call;
1929 }
1930#if CPU(X86)
1931 JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
1932 {
1933 JITCompiler::Call call = appendCallWithExceptionCheck(function);
81345200
A
1934 if (result != InvalidFPRReg) {
1935 m_jit.assembler().fstpl(0, JITCompiler::stackPointerRegister);
1936 m_jit.loadDouble(JITCompiler::stackPointerRegister, result);
1937 }
6fe7ccc8
A
1938 return call;
1939 }
1940 JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1941 {
81345200
A
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);
1946 }
6fe7ccc8
A
1947 return call;
1948 }
81345200 1949#elif CPU(ARM) && !CPU(ARM_HARDFP)
6fe7ccc8 1950 JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
93a37866
A
1951 {
1952 JITCompiler::Call call = appendCallWithExceptionCheck(function);
81345200
A
1953 if (result != InvalidFPRReg)
1954 m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
6fe7ccc8
A
1955 return call;
1956 }
1957 JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1958 {
81345200
A
1959 JITCompiler::Call call = appendCall(function);
1960 if (result != InvalidFPRReg)
1961 m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
6fe7ccc8
A
1962 return call;
1963 }
81345200 1964#else // CPU(X86_64) || (CPU(ARM) && CPU(ARM_HARDFP)) || CPU(ARM64) || CPU(MIPS) || CPU(SH4)
6fe7ccc8
A
1965 JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
1966 {
1967 JITCompiler::Call call = appendCallWithExceptionCheck(function);
81345200
A
1968 if (result != InvalidFPRReg)
1969 m_jit.moveDouble(FPRInfo::returnValueFPR, result);
6fe7ccc8
A
1970 return call;
1971 }
1972 JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1973 {
81345200
A
1974 JITCompiler::Call call = appendCall(function);
1975 if (result != InvalidFPRReg)
1976 m_jit.moveDouble(FPRInfo::returnValueFPR, result);
6fe7ccc8
A
1977 return call;
1978 }
1979#endif
1980
81345200 1981 void branchDouble(JITCompiler::DoubleCondition cond, FPRReg left, FPRReg right, BasicBlock* destination)
6fe7ccc8 1982 {
81345200 1983 return addBranch(m_jit.branchDouble(cond, left, right), destination);
6fe7ccc8
A
1984 }
1985
81345200 1986 void branchDoubleNonZero(FPRReg value, FPRReg scratch, BasicBlock* destination)
6fe7ccc8 1987 {
81345200 1988 return addBranch(m_jit.branchDoubleNonZero(value, scratch), destination);
6fe7ccc8
A
1989 }
1990
1991 template<typename T, typename U>
81345200 1992 void branch32(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
6fe7ccc8 1993 {
81345200 1994 return addBranch(m_jit.branch32(cond, left, right), destination);
6fe7ccc8
A
1995 }
1996
1997 template<typename T, typename U>
81345200 1998 void branchTest32(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
6fe7ccc8 1999 {
81345200 2000 return addBranch(m_jit.branchTest32(cond, value, mask), destination);
6fe7ccc8
A
2001 }
2002
2003 template<typename T>
81345200 2004 void branchTest32(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
6fe7ccc8 2005 {
81345200 2006 return addBranch(m_jit.branchTest32(cond, value), destination);
6fe7ccc8
A
2007 }
2008
93a37866
A
2009#if USE(JSVALUE64)
2010 template<typename T, typename U>
81345200 2011 void branch64(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
93a37866 2012 {
81345200 2013 return addBranch(m_jit.branch64(cond, left, right), destination);
93a37866
A
2014 }
2015#endif
2016
6fe7ccc8 2017 template<typename T, typename U>
81345200 2018 void branch8(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
6fe7ccc8 2019 {
81345200 2020 return addBranch(m_jit.branch8(cond, left, right), destination);
6fe7ccc8
A
2021 }
2022
2023 template<typename T, typename U>
81345200 2024 void branchPtr(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
6fe7ccc8 2025 {
81345200
A
2026 return addBranch(m_jit.branchPtr(cond, left, right), destination);
2027 }
2028
2029 template<typename T, typename U>
2030 void branchTestPtr(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
2031 {
2032 return addBranch(m_jit.branchTestPtr(cond, value, mask), destination);
6fe7ccc8
A
2033 }
2034
2035 template<typename T>
81345200 2036 void branchTestPtr(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
6fe7ccc8 2037 {
81345200 2038 return addBranch(m_jit.branchTestPtr(cond, value), destination);
6fe7ccc8
A
2039 }
2040
2041 template<typename T, typename U>
81345200 2042 void branchTest8(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
6fe7ccc8 2043 {
81345200 2044 return addBranch(m_jit.branchTest8(cond, value, mask), destination);
6fe7ccc8
A
2045 }
2046
2047 template<typename T>
81345200 2048 void branchTest8(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
6fe7ccc8 2049 {
81345200 2050 return addBranch(m_jit.branchTest8(cond, value), destination);
6fe7ccc8
A
2051 }
2052
2053 enum FallThroughMode {
2054 AtFallThroughPoint,
2055 ForceJump
2056 };
81345200 2057 void jump(BasicBlock* destination, FallThroughMode fallThroughMode = AtFallThroughPoint)
6fe7ccc8 2058 {
93a37866 2059 if (destination == nextBlock()
6fe7ccc8
A
2060 && fallThroughMode == AtFallThroughPoint)
2061 return;
2062 addBranch(m_jit.jump(), destination);
2063 }
2064
81345200 2065 void addBranch(const MacroAssembler::Jump& jump, BasicBlock* destination)
6fe7ccc8
A
2066 {
2067 m_branches.append(BranchRecord(jump, destination));
2068 }
81345200 2069 void addBranch(const MacroAssembler::JumpList& jump, BasicBlock* destination);
6fe7ccc8 2070
81345200 2071 void linkBranches();
6fe7ccc8 2072
6fe7ccc8 2073 void dump(const char* label = 0);
6fe7ccc8 2074
81345200
A
2075 bool betterUseStrictInt52(Node* node)
2076 {
2077 return !generationInfo(node).isInt52();
2078 }
2079 bool betterUseStrictInt52(Edge edge)
2080 {
2081 return betterUseStrictInt52(edge.node());
2082 }
2083
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);
93a37866
A
2088 void compilePeepHoleBooleanBranch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
2089 void compilePeepHoleDoubleBranch(Node*, Node* branchNode, JITCompiler::DoubleCondition);
2090 void compilePeepHoleObjectEquality(Node*, Node* branchNode);
ed1e77d3 2091 void compilePeepHoleObjectStrictEquality(Edge objectChild, Edge otherChild, Node* branchNode);
93a37866
A
2092 void compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode);
2093 void compileObjectEquality(Node*);
ed1e77d3 2094 void compileObjectStrictEquality(Edge objectChild, Edge otherChild);
93a37866 2095 void compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild);
93a37866
A
2096 void compileObjectOrOtherLogicalNot(Edge value);
2097 void compileLogicalNot(Node*);
81345200
A
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);
93a37866 2103 void compileStringEquality(Node*);
81345200
A
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*);
2109
2110 void emitObjectOrOtherBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
ed1e77d3 2111 void emitStringBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
93a37866
A
2112 void emitBranch(Node*);
2113
81345200
A
2114 struct StringSwitchCase {
2115 StringSwitchCase() { }
2116
2117 StringSwitchCase(StringImpl* string, BasicBlock* target)
2118 : string(string)
2119 , target(target)
2120 {
2121 }
2122
ed1e77d3
A
2123 bool operator<(const StringSwitchCase& other) const
2124 {
2125 return stringLessThan(*string, *other.string);
2126 }
81345200
A
2127
2128 StringImpl* string;
2129 BasicBlock* target;
2130 };
2131
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*);
2143
ed1e77d3 2144 void compileToStringOrCallStringConstructorOnCell(Node*);
81345200
A
2145 void compileNewStringObject(Node*);
2146
2147 void compileNewTypedArray(Node*);
93a37866 2148
81345200
A
2149 void compileInt32Compare(Node*, MacroAssembler::RelationalCondition);
2150 void compileInt52Compare(Node*, MacroAssembler::RelationalCondition);
93a37866
A
2151 void compileBooleanCompare(Node*, MacroAssembler::RelationalCondition);
2152 void compileDoubleCompare(Node*, MacroAssembler::DoubleCondition);
2153
93a37866
A
2154 bool compileStrictEq(Node*);
2155
2156 void compileAllocatePropertyStorage(Node*);
2157 void compileReallocatePropertyStorage(Node*);
2158
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);
6fe7ccc8 2162#endif
93a37866
A
2163 void compileDoublePutByVal(Node*, SpeculateCellOperand& base, SpeculateStrictInt32Operand& property);
2164 bool putByValWillNeedExtraRegister(ArrayMode arrayMode)
6fe7ccc8 2165 {
93a37866
A
2166 return arrayMode.mayStoreToHole();
2167 }
2168 GPRReg temporaryRegisterForPutByVal(GPRTemporary&, ArrayMode);
2169 GPRReg temporaryRegisterForPutByVal(GPRTemporary& temporary, Node* node)
2170 {
2171 return temporaryRegisterForPutByVal(temporary, node->arrayMode());
2172 }
2173
2174 void compileGetCharCodeAt(Node*);
2175 void compileGetByValOnString(Node*);
2176 void compileFromCharCode(Node*);
6fe7ccc8 2177
ed1e77d3
A
2178 void compileGetByValOnDirectArguments(Node*);
2179 void compileGetByValOnScopedArguments(Node*);
93a37866 2180
ed1e77d3
A
2181 void compileGetScope(Node*);
2182 void compileSkipScope(Node*);
2183
93a37866
A
2184 void compileGetArrayLength(Node*);
2185
81345200
A
2186 void compileValueRep(Node*);
2187 void compileDoubleRep(Node*);
2188
93a37866
A
2189 void compileValueToInt32(Node*);
2190 void compileUInt32ToNumber(Node*);
2191 void compileDoubleAsInt32(Node*);
93a37866
A
2192 void compileAdd(Node*);
2193 void compileMakeRope(Node*);
ed1e77d3 2194 void compileArithClz32(Node*);
93a37866
A
2195 void compileArithSub(Node*);
2196 void compileArithNegate(Node*);
2197 void compileArithMul(Node*);
81345200 2198 void compileArithDiv(Node*);
93a37866 2199 void compileArithMod(Node*);
ed1e77d3
A
2200 void compileArithPow(Node*);
2201 void compileArithRound(Node*);
2202 void compileArithSqrt(Node*);
2203 void compileArithLog(Node*);
81345200 2204 void compileConstantStoragePointer(Node*);
93a37866 2205 void compileGetIndexedPropertyStorage(Node*);
81345200
A
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);
ed1e77d3
A
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*);
93a37866 2222 bool compileRegExpExec(Node*);
ed1e77d3
A
2223 void compileIsObjectOrNull(Node*);
2224 void compileIsFunction(Node*);
2225 void compileTypeOf(Node*);
81345200
A
2226
2227 void moveTrueTo(GPRReg);
2228 void moveFalseTo(GPRReg);
2229 void blessBoolean(GPRReg);
2230
93a37866
A
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)
2236 {
2237 CopiedAllocator* copiedAllocator = &m_jit.vm()->heap.storageAllocator();
81345200
A
2238
2239 // It's invalid to allocate zero bytes in CopiedSpace.
2240#ifndef NDEBUG
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);
2245#endif
2246
93a37866
A
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);
2252
2253 return slowPath;
2254 }
81345200 2255
93a37866
A
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)
2260 {
2261 m_jit.loadPtr(MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()), resultGPR);
6fe7ccc8
A
2262 slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR));
2263
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.
6fe7ccc8 2266 m_jit.loadPtr(MacroAssembler::Address(resultGPR), scratchGPR);
93a37866
A
2267 m_jit.storePtr(scratchGPR, MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()));
2268
2269 // Initialize the object's Structure.
81345200 2270 m_jit.emitStoreStructureWithTypeInfo(structure, resultGPR, scratchGPR);
93a37866
A
2271 }
2272
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)
2277 {
2278 emitAllocateJSCell(resultGPR, allocatorGPR, structure, scratchGPR, slowPath);
6fe7ccc8
A
2279
2280 // Initialize the object's property storage pointer.
93a37866 2281 m_jit.storePtr(storage, MacroAssembler::Address(resultGPR, JSObject::butterflyOffset()));
6fe7ccc8
A
2282 }
2283
ed1e77d3
A
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)
2288 {
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);
2292 }
2293
81345200 2294 // Convenience allocator for a built-in object.
93a37866
A
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)
6fe7ccc8 2298 {
ed1e77d3
A
2299 emitAllocateJSObjectWithKnownSize<ClassType>(
2300 resultGPR, structure, storage, scratchGPR1, scratchGPR2, slowPath,
2301 ClassType::allocationSize(0));
2302 }
2303
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)
2306 {
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.");
2309
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);
2316
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);
2323
2324 selectedSmallSpace.link(&m_jit);
2325
2326 emitAllocateJSObject(resultGPR, scratchGPR1, structure, TrustedImmPtr(0), scratchGPR2, slowPath);
6fe7ccc8
A
2327 }
2328
81345200
A
2329 template <typename T>
2330 void emitAllocateDestructibleObject(GPRReg resultGPR, Structure* structure,
2331 GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
2332 {
2333 emitAllocateJSObject<T>(resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR1, scratchGPR2, slowPath);
2334 m_jit.storePtr(TrustedImmPtr(structure->classInfo()), MacroAssembler::Address(resultGPR, JSDestructibleObject::classInfoOffset()));
2335 }
93a37866 2336
81345200 2337 void emitAllocateJSArray(GPRReg resultGPR, Structure*, GPRReg storageGPR, unsigned numElements);
ed1e77d3
A
2338
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);
2343
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();
2347
81345200 2348 // Add a speculation check.
93a37866 2349 void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);
93a37866 2350 void speculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail);
81345200
A
2351
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);
93a37866 2356 void speculationCheck(ExitKind, JSValueSource, Edge, const MacroAssembler::JumpList& jumpsToFail);
6fe7ccc8 2357 // Add a speculation check with additional recovery.
93a37866
A
2358 void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
2359 void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
81345200
A
2360
2361 void emitInvalidationPoint(Node*);
2362
6fe7ccc8 2363 // Called when we statically determine that a speculation will fail.
93a37866
A
2364 void terminateSpeculativeExecution(ExitKind, JSValueRegs, Node*);
2365 void terminateSpeculativeExecution(ExitKind, JSValueRegs, Edge);
2366
2367 // Helpers for performing type checks on an edge stored in the given registers.
81345200 2368 bool needsTypeCheck(Edge edge, SpeculatedType typesPassedThrough) { return m_interpreter.needsTypeCheck(edge, typesPassedThrough); }
93a37866 2369 void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
81345200 2370
ed1e77d3
A
2371 void speculateCellTypeWithoutTypeFiltering(Edge, GPRReg cellGPR, JSType);
2372 void speculateCellType(Edge, GPRReg cellGPR, SpeculatedType, JSType);
2373
93a37866 2374 void speculateInt32(Edge);
81345200
A
2375#if USE(JSVALUE64)
2376 void convertMachineInt(Edge, GPRReg resultGPR);
2377 void speculateMachineInt(Edge);
2378 void speculateDoubleRepMachineInt(Edge);
2379#endif // USE(JSVALUE64)
93a37866 2380 void speculateNumber(Edge);
ed1e77d3
A
2381 void speculateRealNumber(Edge);
2382 void speculateDoubleRepReal(Edge);
93a37866
A
2383 void speculateBoolean(Edge);
2384 void speculateCell(Edge);
2385 void speculateObject(Edge);
ed1e77d3 2386 void speculateFunction(Edge);
81345200 2387 void speculateFinalObject(Edge);
93a37866 2388 void speculateObjectOrOther(Edge);
81345200
A
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);
93a37866 2393 void speculateString(Edge);
81345200 2394 void speculateNotStringVar(Edge);
93a37866
A
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);
81345200
A
2402 void speculateMisc(Edge, JSValueRegs);
2403 void speculateMisc(Edge);
93a37866
A
2404 void speculate(Node*, Edge);
2405
93a37866
A
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*);
6fe7ccc8
A
2411
2412 template<bool strict>
81345200 2413 GPRReg fillSpeculateInt32Internal(Edge, DataFormat& returnFormat);
6fe7ccc8
A
2414
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.
2419 bool m_compileOkay;
2420
81345200
A
2421 void recordSetLocal(
2422 VirtualRegister bytecodeReg, VirtualRegister machineReg, DataFormat format)
6fe7ccc8 2423 {
81345200 2424 m_stream->appendAndLog(VariableEvent::setLocal(bytecodeReg, machineReg, format));
6fe7ccc8
A
2425 }
2426
81345200 2427 void recordSetLocal(DataFormat format)
6fe7ccc8 2428 {
81345200
A
2429 VariableAccessData* variable = m_currentNode->variableAccessData();
2430 recordSetLocal(variable->local(), variable->machineLocal(), format);
6fe7ccc8 2431 }
81345200
A
2432
2433 GenerationInfo& generationInfoFromVirtualRegister(VirtualRegister virtualRegister)
6fe7ccc8 2434 {
81345200 2435 return m_generationInfo[virtualRegister.toLocal()];
6fe7ccc8
A
2436 }
2437
81345200 2438 GenerationInfo& generationInfo(Node* node)
93a37866 2439 {
81345200 2440 return generationInfoFromVirtualRegister(node->virtualRegister());
93a37866
A
2441 }
2442
81345200
A
2443 GenerationInfo& generationInfo(Edge edge)
2444 {
2445 return generationInfo(edge.node());
2446 }
2447
6fe7ccc8
A
2448 // The JIT, while also provides MacroAssembler functionality.
2449 JITCompiler& m_jit;
93a37866 2450
6fe7ccc8 2451 // The current node being generated.
81345200 2452 BasicBlock* m_block;
93a37866 2453 Node* m_currentNode;
81345200 2454 NodeType m_lastGeneratedNode;
93a37866 2455 bool m_canExit;
6fe7ccc8
A
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;
2461
6fe7ccc8
A
2462 Vector<MacroAssembler::Label> m_osrEntryHeads;
2463
2464 struct BranchRecord {
81345200 2465 BranchRecord(MacroAssembler::Jump jump, BasicBlock* destination)
6fe7ccc8
A
2466 : jump(jump)
2467 , destination(destination)
2468 {
2469 }
2470
2471 MacroAssembler::Jump jump;
81345200 2472 BasicBlock* destination;
6fe7ccc8
A
2473 };
2474 Vector<BranchRecord, 8> m_branches;
2475
81345200
A
2476 CodeOrigin m_codeOriginForExitTarget;
2477 CodeOrigin m_codeOriginForExitProfile;
6fe7ccc8 2478
81345200
A
2479 InPlaceAbstractState m_state;
2480 AbstractInterpreter<InPlaceAbstractState> m_interpreter;
6fe7ccc8 2481
93a37866
A
2482 VariableEventStream* m_stream;
2483 MinifiedGraph* m_minifiedGraph;
2484
2485 bool m_isCheckingArgumentTypes;
2486
ed1e77d3 2487 Vector<std::unique_ptr<SlowPathGenerator>, 8> m_slowPathGenerators;
93a37866 2488 Vector<SilentRegisterSavePlan> m_plans;
14957cd0
A
2489};
2490
6fe7ccc8
A
2491
2492// === Operand types ===
2493//
6fe7ccc8
A
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.
2500
6fe7ccc8 2501class JSValueOperand {
14957cd0 2502public:
93a37866 2503 explicit JSValueOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
6fe7ccc8 2504 : m_jit(jit)
93a37866 2505 , m_edge(edge)
6fe7ccc8
A
2506#if USE(JSVALUE64)
2507 , m_gprOrInvalid(InvalidGPRReg)
2508#elif USE(JSVALUE32_64)
2509 , m_isDouble(false)
2510#endif
14957cd0 2511 {
6fe7ccc8 2512 ASSERT(m_jit);
93a37866 2513 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
6fe7ccc8 2514#if USE(JSVALUE64)
93a37866 2515 if (jit->isFilled(node()))
6fe7ccc8
A
2516 gpr();
2517#elif USE(JSVALUE32_64)
2518 m_register.pair.tagGPR = InvalidGPRReg;
2519 m_register.pair.payloadGPR = InvalidGPRReg;
93a37866 2520 if (jit->isFilled(node()))
6fe7ccc8
A
2521 fill();
2522#endif
14957cd0
A
2523 }
2524
6fe7ccc8
A
2525 ~JSValueOperand()
2526 {
2527#if USE(JSVALUE64)
2528 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2529 m_jit->unlock(m_gprOrInvalid);
2530#elif USE(JSVALUE32_64)
2531 if (m_isDouble) {
2532 ASSERT(m_register.fpr != InvalidFPRReg);
2533 m_jit->unlock(m_register.fpr);
2534 } else {
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);
2538 }
2539#endif
2540 }
93a37866
A
2541
2542 Edge edge() const
2543 {
2544 return m_edge;
2545 }
6fe7ccc8 2546
93a37866 2547 Node* node() const
6fe7ccc8 2548 {
93a37866 2549 return edge().node();
6fe7ccc8 2550 }
14957cd0 2551
6fe7ccc8
A
2552#if USE(JSVALUE64)
2553 GPRReg gpr()
14957cd0 2554 {
6fe7ccc8 2555 if (m_gprOrInvalid == InvalidGPRReg)
93a37866 2556 m_gprOrInvalid = m_jit->fillJSValue(m_edge);
6fe7ccc8 2557 return m_gprOrInvalid;
14957cd0 2558 }
6fe7ccc8 2559 JSValueRegs jsValueRegs()
14957cd0 2560 {
6fe7ccc8 2561 return JSValueRegs(gpr());
14957cd0 2562 }
6fe7ccc8
A
2563#elif USE(JSVALUE32_64)
2564 bool isDouble() { return m_isDouble; }
14957cd0 2565
6fe7ccc8
A
2566 void fill()
2567 {
2568 if (m_register.pair.tagGPR == InvalidGPRReg && m_register.pair.payloadGPR == InvalidGPRReg)
93a37866 2569 m_isDouble = !m_jit->fillJSValue(m_edge, m_register.pair.tagGPR, m_register.pair.payloadGPR, m_register.fpr);
6fe7ccc8 2570 }
14957cd0 2571
6fe7ccc8
A
2572 GPRReg tagGPR()
2573 {
2574 fill();
2575 ASSERT(!m_isDouble);
2576 return m_register.pair.tagGPR;
81345200 2577 }
14957cd0 2578
6fe7ccc8
A
2579 GPRReg payloadGPR()
2580 {
2581 fill();
2582 ASSERT(!m_isDouble);
2583 return m_register.pair.payloadGPR;
2584 }
81345200 2585
6fe7ccc8 2586 JSValueRegs jsValueRegs()
14957cd0 2587 {
6fe7ccc8
A
2588 return JSValueRegs(tagGPR(), payloadGPR());
2589 }
14957cd0 2590
81345200
A
2591 GPRReg gpr(WhichValueWord which)
2592 {
2593 return jsValueRegs().gpr(which);
2594 }
2595
6fe7ccc8
A
2596 FPRReg fpr()
2597 {
2598 fill();
2599 ASSERT(m_isDouble);
2600 return m_register.fpr;
2601 }
2602#endif
14957cd0 2603
6fe7ccc8
A
2604 void use()
2605 {
93a37866 2606 m_jit->use(node());
14957cd0
A
2607 }
2608
6fe7ccc8
A
2609private:
2610 SpeculativeJIT* m_jit;
93a37866 2611 Edge m_edge;
6fe7ccc8
A
2612#if USE(JSVALUE64)
2613 GPRReg m_gprOrInvalid;
2614#elif USE(JSVALUE32_64)
2615 union {
2616 struct {
2617 GPRReg tagGPR;
2618 GPRReg payloadGPR;
2619 } pair;
2620 FPRReg fpr;
2621 } m_register;
2622 bool m_isDouble;
2623#endif
2624};
2625
2626class StorageOperand {
2627public:
93a37866 2628 explicit StorageOperand(SpeculativeJIT* jit, Edge edge)
6fe7ccc8 2629 : m_jit(jit)
93a37866 2630 , m_edge(edge)
6fe7ccc8 2631 , m_gprOrInvalid(InvalidGPRReg)
14957cd0 2632 {
6fe7ccc8 2633 ASSERT(m_jit);
93a37866
A
2634 ASSERT(edge.useKind() == UntypedUse || edge.useKind() == KnownCellUse);
2635 if (jit->isFilled(node()))
6fe7ccc8
A
2636 gpr();
2637 }
2638
2639 ~StorageOperand()
2640 {
2641 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2642 m_jit->unlock(m_gprOrInvalid);
2643 }
2644
93a37866
A
2645 Edge edge() const
2646 {
2647 return m_edge;
2648 }
2649
2650 Node* node() const
6fe7ccc8 2651 {
93a37866 2652 return edge().node();
6fe7ccc8
A
2653 }
2654
2655 GPRReg gpr()
2656 {
2657 if (m_gprOrInvalid == InvalidGPRReg)
93a37866 2658 m_gprOrInvalid = m_jit->fillStorage(edge());
6fe7ccc8
A
2659 return m_gprOrInvalid;
2660 }
2661
2662 void use()
2663 {
93a37866 2664 m_jit->use(node());
6fe7ccc8
A
2665 }
2666
2667private:
2668 SpeculativeJIT* m_jit;
93a37866 2669 Edge m_edge;
6fe7ccc8
A
2670 GPRReg m_gprOrInvalid;
2671};
14957cd0 2672
6fe7ccc8
A
2673
2674// === Temporaries ===
2675//
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.
2680
81345200
A
2681enum ReuseTag { Reuse };
2682
6fe7ccc8
A
2683class GPRTemporary {
2684public:
2685 GPRTemporary();
2686 GPRTemporary(SpeculativeJIT*);
2687 GPRTemporary(SpeculativeJIT*, GPRReg specific);
81345200
A
2688 template<typename T>
2689 GPRTemporary(SpeculativeJIT* jit, ReuseTag, T& operand)
2690 : m_jit(jit)
2691 , m_gpr(InvalidGPRReg)
2692 {
2693 if (m_jit->canReuse(operand.node()))
2694 m_gpr = m_jit->reuse(operand.gpr());
2695 else
2696 m_gpr = m_jit->allocate();
2697 }
2698 template<typename T1, typename T2>
2699 GPRTemporary(SpeculativeJIT* jit, ReuseTag, T1& op1, T2& op2)
2700 : m_jit(jit)
2701 , m_gpr(InvalidGPRReg)
2702 {
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());
2707 else
2708 m_gpr = m_jit->allocate();
2709 }
2710#if USE(JSVALUE32_64)
2711 GPRTemporary(SpeculativeJIT*, ReuseTag, JSValueOperand&, WhichValueWord);
6fe7ccc8 2712#endif
6fe7ccc8
A
2713
2714 void adopt(GPRTemporary&);
2715
2716 ~GPRTemporary()
2717 {
2718 if (m_jit && m_gpr != InvalidGPRReg)
2719 m_jit->unlock(gpr());
14957cd0
A
2720 }
2721
6fe7ccc8 2722 GPRReg gpr()
14957cd0 2723 {
6fe7ccc8
A
2724 return m_gpr;
2725 }
14957cd0 2726
6fe7ccc8
A
2727private:
2728 SpeculativeJIT* m_jit;
2729 GPRReg m_gpr;
2730};
2731
81345200
A
2732class JSValueRegsTemporary {
2733public:
2734 JSValueRegsTemporary();
2735 JSValueRegsTemporary(SpeculativeJIT*);
2736 ~JSValueRegsTemporary();
2737
2738 JSValueRegs regs();
2739
2740private:
2741#if USE(JSVALUE64)
2742 GPRTemporary m_gpr;
2743#else
2744 GPRTemporary m_payloadGPR;
2745 GPRTemporary m_tagGPR;
2746#endif
2747};
2748
6fe7ccc8
A
2749class FPRTemporary {
2750public:
2751 FPRTemporary(SpeculativeJIT*);
6fe7ccc8
A
2752 FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&);
2753 FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&, SpeculateDoubleOperand&);
2754#if USE(JSVALUE32_64)
2755 FPRTemporary(SpeculativeJIT*, JSValueOperand&);
2756#endif
2757
2758 ~FPRTemporary()
2759 {
2760 m_jit->unlock(fpr());
14957cd0
A
2761 }
2762
6fe7ccc8
A
2763 FPRReg fpr() const
2764 {
2765 ASSERT(m_fpr != InvalidFPRReg);
2766 return m_fpr;
2767 }
14957cd0 2768
6fe7ccc8
A
2769protected:
2770 FPRTemporary(SpeculativeJIT* jit, FPRReg lockedFPR)
2771 : m_jit(jit)
2772 , m_fpr(lockedFPR)
14957cd0 2773 {
14957cd0 2774 }
6fe7ccc8
A
2775
2776private:
2777 SpeculativeJIT* m_jit;
2778 FPRReg m_fpr;
2779};
2780
2781
2782// === Results ===
2783//
2784// These classes lock the result of a call to a C++ helper function.
2785
ed1e77d3 2786class GPRFlushedCallResult : public GPRTemporary {
6fe7ccc8 2787public:
ed1e77d3 2788 GPRFlushedCallResult(SpeculativeJIT* jit)
6fe7ccc8 2789 : GPRTemporary(jit, GPRInfo::returnValueGPR)
14957cd0 2790 {
14957cd0 2791 }
6fe7ccc8 2792};
14957cd0 2793
6fe7ccc8 2794#if USE(JSVALUE32_64)
ed1e77d3 2795class GPRFlushedCallResult2 : public GPRTemporary {
6fe7ccc8 2796public:
ed1e77d3 2797 GPRFlushedCallResult2(SpeculativeJIT* jit)
6fe7ccc8 2798 : GPRTemporary(jit, GPRInfo::returnValueGPR2)
14957cd0 2799 {
14957cd0 2800 }
6fe7ccc8
A
2801};
2802#endif
14957cd0 2803
6fe7ccc8
A
2804class FPRResult : public FPRTemporary {
2805public:
2806 FPRResult(SpeculativeJIT* jit)
2807 : FPRTemporary(jit, lockedResult(jit))
2808 {
2809 }
14957cd0 2810
6fe7ccc8
A
2811private:
2812 static FPRReg lockedResult(SpeculativeJIT* jit)
2813 {
2814 jit->lock(FPRInfo::returnValueFPR);
2815 return FPRInfo::returnValueFPR;
2816 }
14957cd0
A
2817};
2818
2819
2820// === Speculative Operand types ===
2821//
81345200 2822// SpeculateInt32Operand, SpeculateStrictInt32Operand and SpeculateCellOperand.
14957cd0
A
2823//
2824// These are used to lock the operands to a node into machine registers within the
6fe7ccc8
A
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.
14957cd0 2829
81345200 2830class SpeculateInt32Operand {
14957cd0 2831public:
81345200 2832 explicit SpeculateInt32Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
14957cd0 2833 : m_jit(jit)
93a37866 2834 , m_edge(edge)
14957cd0
A
2835 , m_gprOrInvalid(InvalidGPRReg)
2836#ifndef NDEBUG
2837 , m_format(DataFormatNone)
2838#endif
2839 {
2840 ASSERT(m_jit);
93a37866
A
2841 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
2842 if (jit->isFilled(node()))
14957cd0
A
2843 gpr();
2844 }
2845
81345200 2846 ~SpeculateInt32Operand()
14957cd0
A
2847 {
2848 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2849 m_jit->unlock(m_gprOrInvalid);
2850 }
93a37866
A
2851
2852 Edge edge() const
2853 {
2854 return m_edge;
2855 }
14957cd0 2856
93a37866 2857 Node* node() const
14957cd0 2858 {
93a37866 2859 return edge().node();
14957cd0
A
2860 }
2861
2862 DataFormat format()
2863 {
2864 gpr(); // m_format is set when m_gpr is locked.
81345200 2865 ASSERT(m_format == DataFormatInt32 || m_format == DataFormatJSInt32);
14957cd0
A
2866 return m_format;
2867 }
2868
2869 GPRReg gpr()
2870 {
2871 if (m_gprOrInvalid == InvalidGPRReg)
81345200 2872 m_gprOrInvalid = m_jit->fillSpeculateInt32(edge(), m_format);
14957cd0
A
2873 return m_gprOrInvalid;
2874 }
93a37866
A
2875
2876 void use()
2877 {
2878 m_jit->use(node());
2879 }
14957cd0
A
2880
2881private:
2882 SpeculativeJIT* m_jit;
93a37866 2883 Edge m_edge;
14957cd0
A
2884 GPRReg m_gprOrInvalid;
2885 DataFormat m_format;
2886};
2887
2888class SpeculateStrictInt32Operand {
2889public:
93a37866 2890 explicit SpeculateStrictInt32Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
14957cd0 2891 : m_jit(jit)
93a37866 2892 , m_edge(edge)
14957cd0
A
2893 , m_gprOrInvalid(InvalidGPRReg)
2894 {
2895 ASSERT(m_jit);
93a37866
A
2896 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
2897 if (jit->isFilled(node()))
14957cd0
A
2898 gpr();
2899 }
2900
2901 ~SpeculateStrictInt32Operand()
2902 {
2903 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2904 m_jit->unlock(m_gprOrInvalid);
2905 }
93a37866
A
2906
2907 Edge edge() const
2908 {
2909 return m_edge;
2910 }
14957cd0 2911
93a37866 2912 Node* node() const
14957cd0 2913 {
93a37866 2914 return edge().node();
14957cd0
A
2915 }
2916
2917 GPRReg gpr()
2918 {
2919 if (m_gprOrInvalid == InvalidGPRReg)
81345200 2920 m_gprOrInvalid = m_jit->fillSpeculateInt32Strict(edge());
14957cd0
A
2921 return m_gprOrInvalid;
2922 }
6fe7ccc8
A
2923
2924 void use()
2925 {
93a37866 2926 m_jit->use(node());
6fe7ccc8 2927 }
14957cd0
A
2928
2929private:
2930 SpeculativeJIT* m_jit;
93a37866 2931 Edge m_edge;
14957cd0
A
2932 GPRReg m_gprOrInvalid;
2933};
2934
81345200
A
2935// Gives you a canonical Int52 (i.e. it's left-shifted by 16, low bits zero).
2936class SpeculateInt52Operand {
2937public:
2938 explicit SpeculateInt52Operand(SpeculativeJIT* jit, Edge edge)
2939 : m_jit(jit)
2940 , m_edge(edge)
2941 , m_gprOrInvalid(InvalidGPRReg)
2942 {
2943 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
2944 if (jit->isFilled(node()))
2945 gpr();
2946 }
2947
2948 ~SpeculateInt52Operand()
2949 {
2950 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2951 m_jit->unlock(m_gprOrInvalid);
2952 }
2953
2954 Edge edge() const
2955 {
2956 return m_edge;
2957 }
2958
2959 Node* node() const
2960 {
2961 return edge().node();
2962 }
2963
2964 GPRReg gpr()
2965 {
2966 if (m_gprOrInvalid == InvalidGPRReg)
2967 m_gprOrInvalid = m_jit->fillSpeculateInt52(edge(), DataFormatInt52);
2968 return m_gprOrInvalid;
2969 }
2970
2971 void use()
2972 {
2973 m_jit->use(node());
2974 }
2975
2976private:
2977 SpeculativeJIT* m_jit;
2978 Edge m_edge;
2979 GPRReg m_gprOrInvalid;
2980};
2981
2982// Gives you a strict Int52 (i.e. the payload is in the low 48 bits, high 16 bits are sign-extended).
2983class SpeculateStrictInt52Operand {
2984public:
2985 explicit SpeculateStrictInt52Operand(SpeculativeJIT* jit, Edge edge)
2986 : m_jit(jit)
2987 , m_edge(edge)
2988 , m_gprOrInvalid(InvalidGPRReg)
2989 {
2990 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
2991 if (jit->isFilled(node()))
2992 gpr();
2993 }
2994
2995 ~SpeculateStrictInt52Operand()
2996 {
2997 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2998 m_jit->unlock(m_gprOrInvalid);
2999 }
3000
3001 Edge edge() const
3002 {
3003 return m_edge;
3004 }
3005
3006 Node* node() const
3007 {
3008 return edge().node();
3009 }
3010
3011 GPRReg gpr()
3012 {
3013 if (m_gprOrInvalid == InvalidGPRReg)
3014 m_gprOrInvalid = m_jit->fillSpeculateInt52(edge(), DataFormatStrictInt52);
3015 return m_gprOrInvalid;
3016 }
3017
3018 void use()
3019 {
3020 m_jit->use(node());
3021 }
3022
3023private:
3024 SpeculativeJIT* m_jit;
3025 Edge m_edge;
3026 GPRReg m_gprOrInvalid;
3027};
3028
3029enum OppositeShiftTag { OppositeShift };
3030
3031class SpeculateWhicheverInt52Operand {
3032public:
3033 explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge)
3034 : m_jit(jit)
3035 , m_edge(edge)
3036 , m_gprOrInvalid(InvalidGPRReg)
3037 , m_strict(jit->betterUseStrictInt52(edge))
3038 {
3039 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
3040 if (jit->isFilled(node()))
3041 gpr();
3042 }
3043
3044 explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, const SpeculateWhicheverInt52Operand& other)
3045 : m_jit(jit)
3046 , m_edge(edge)
3047 , m_gprOrInvalid(InvalidGPRReg)
3048 , m_strict(other.m_strict)
3049 {
3050 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
3051 if (jit->isFilled(node()))
3052 gpr();
3053 }
3054
3055 explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, OppositeShiftTag, const SpeculateWhicheverInt52Operand& other)
3056 : m_jit(jit)
3057 , m_edge(edge)
3058 , m_gprOrInvalid(InvalidGPRReg)
3059 , m_strict(!other.m_strict)
3060 {
3061 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
3062 if (jit->isFilled(node()))
3063 gpr();
3064 }
3065
3066 ~SpeculateWhicheverInt52Operand()
3067 {
3068 ASSERT(m_gprOrInvalid != InvalidGPRReg);
3069 m_jit->unlock(m_gprOrInvalid);
3070 }
3071
3072 Edge edge() const
3073 {
3074 return m_edge;
3075 }
3076
3077 Node* node() const
3078 {
3079 return edge().node();
3080 }
3081
3082 GPRReg gpr()
3083 {
3084 if (m_gprOrInvalid == InvalidGPRReg) {
3085 m_gprOrInvalid = m_jit->fillSpeculateInt52(
3086 edge(), m_strict ? DataFormatStrictInt52 : DataFormatInt52);
3087 }
3088 return m_gprOrInvalid;
3089 }
3090
3091 void use()
3092 {
3093 m_jit->use(node());
3094 }
3095
3096 DataFormat format() const
3097 {
3098 return m_strict ? DataFormatStrictInt52 : DataFormatInt52;
3099 }
3100
3101private:
3102 SpeculativeJIT* m_jit;
3103 Edge m_edge;
3104 GPRReg m_gprOrInvalid;
3105 bool m_strict;
3106};
3107
6fe7ccc8
A
3108class SpeculateDoubleOperand {
3109public:
81345200 3110 explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge edge)
6fe7ccc8 3111 : m_jit(jit)
93a37866 3112 , m_edge(edge)
6fe7ccc8
A
3113 , m_fprOrInvalid(InvalidFPRReg)
3114 {
3115 ASSERT(m_jit);
81345200 3116 RELEASE_ASSERT(isDouble(edge.useKind()));
93a37866 3117 if (jit->isFilled(node()))
6fe7ccc8
A
3118 fpr();
3119 }
3120
3121 ~SpeculateDoubleOperand()
3122 {
3123 ASSERT(m_fprOrInvalid != InvalidFPRReg);
3124 m_jit->unlock(m_fprOrInvalid);
3125 }
93a37866
A
3126
3127 Edge edge() const
3128 {
3129 return m_edge;
3130 }
6fe7ccc8 3131
93a37866 3132 Node* node() const
6fe7ccc8 3133 {
93a37866 3134 return edge().node();
6fe7ccc8
A
3135 }
3136
3137 FPRReg fpr()
3138 {
3139 if (m_fprOrInvalid == InvalidFPRReg)
93a37866 3140 m_fprOrInvalid = m_jit->fillSpeculateDouble(edge());
6fe7ccc8
A
3141 return m_fprOrInvalid;
3142 }
93a37866
A
3143
3144 void use()
3145 {
3146 m_jit->use(node());
3147 }
6fe7ccc8
A
3148
3149private:
3150 SpeculativeJIT* m_jit;
93a37866 3151 Edge m_edge;
6fe7ccc8
A
3152 FPRReg m_fprOrInvalid;
3153};
3154
14957cd0
A
3155class SpeculateCellOperand {
3156public:
93a37866 3157 explicit SpeculateCellOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
14957cd0 3158 : m_jit(jit)
93a37866 3159 , m_edge(edge)
14957cd0
A
3160 , m_gprOrInvalid(InvalidGPRReg)
3161 {
3162 ASSERT(m_jit);
93a37866
A
3163 if (!edge)
3164 return;
81345200 3165 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isCell(edge.useKind()));
93a37866 3166 if (jit->isFilled(node()))
14957cd0
A
3167 gpr();
3168 }
3169
3170 ~SpeculateCellOperand()
3171 {
93a37866
A
3172 if (!m_edge)
3173 return;
14957cd0
A
3174 ASSERT(m_gprOrInvalid != InvalidGPRReg);
3175 m_jit->unlock(m_gprOrInvalid);
3176 }
93a37866
A
3177
3178 Edge edge() const
3179 {
3180 return m_edge;
3181 }
14957cd0 3182
93a37866 3183 Node* node() const
14957cd0 3184 {
93a37866 3185 return edge().node();
14957cd0
A
3186 }
3187
3188 GPRReg gpr()
3189 {
93a37866 3190 ASSERT(m_edge);
14957cd0 3191 if (m_gprOrInvalid == InvalidGPRReg)
93a37866 3192 m_gprOrInvalid = m_jit->fillSpeculateCell(edge());
14957cd0
A
3193 return m_gprOrInvalid;
3194 }
6fe7ccc8
A
3195
3196 void use()
3197 {
93a37866
A
3198 ASSERT(m_edge);
3199 m_jit->use(node());
6fe7ccc8 3200 }
14957cd0
A
3201
3202private:
3203 SpeculativeJIT* m_jit;
93a37866 3204 Edge m_edge;
14957cd0
A
3205 GPRReg m_gprOrInvalid;
3206};
3207
6fe7ccc8 3208class SpeculateBooleanOperand {
14957cd0 3209public:
93a37866 3210 explicit SpeculateBooleanOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
6fe7ccc8 3211 : m_jit(jit)
93a37866 3212 , m_edge(edge)
6fe7ccc8 3213 , m_gprOrInvalid(InvalidGPRReg)
14957cd0 3214 {
6fe7ccc8 3215 ASSERT(m_jit);
93a37866
A
3216 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse);
3217 if (jit->isFilled(node()))
6fe7ccc8 3218 gpr();
14957cd0 3219 }
6fe7ccc8
A
3220
3221 ~SpeculateBooleanOperand()
14957cd0 3222 {
6fe7ccc8
A
3223 ASSERT(m_gprOrInvalid != InvalidGPRReg);
3224 m_jit->unlock(m_gprOrInvalid);
3225 }
3226
93a37866 3227 Edge edge() const
6fe7ccc8 3228 {
93a37866
A
3229 return m_edge;
3230 }
3231
3232 Node* node() const
3233 {
3234 return edge().node();
6fe7ccc8
A
3235 }
3236
3237 GPRReg gpr()
3238 {
3239 if (m_gprOrInvalid == InvalidGPRReg)
93a37866 3240 m_gprOrInvalid = m_jit->fillSpeculateBoolean(edge());
6fe7ccc8
A
3241 return m_gprOrInvalid;
3242 }
3243
3244 void use()
3245 {
93a37866 3246 m_jit->use(node());
14957cd0
A
3247 }
3248
3249private:
6fe7ccc8 3250 SpeculativeJIT* m_jit;
93a37866 3251 Edge m_edge;
6fe7ccc8 3252 GPRReg m_gprOrInvalid;
14957cd0
A
3253};
3254
93a37866
A
3255template<typename StructureLocationType>
3256void SpeculativeJIT::speculateStringObjectForStructure(Edge edge, StructureLocationType structureLocation)
6fe7ccc8 3257{
93a37866 3258 Structure* stringObjectStructure =
81345200 3259 m_jit.globalObjectFor(m_currentNode->origin.semantic)->stringObjectStructure();
93a37866 3260
ed1e77d3 3261 if (!m_state.forNode(edge).m_structure.isSubsetOf(StructureSet(stringObjectStructure))) {
93a37866
A
3262 speculationCheck(
3263 NotStringObject, JSValueRegs(), 0,
81345200
A
3264 m_jit.branchStructurePtr(
3265 JITCompiler::NotEqual, structureLocation, stringObjectStructure));
93a37866 3266 }
6fe7ccc8 3267}
14957cd0 3268
93a37866 3269#define DFG_TYPE_CHECK(source, edge, typesPassedThrough, jumpToFail) do { \
81345200
A
3270 JSValueSource _dtc_source = (source); \
3271 Edge _dtc_edge = (edge); \
3272 SpeculatedType _dtc_typesPassedThrough = typesPassedThrough; \
3273 if (!needsTypeCheck(_dtc_edge, _dtc_typesPassedThrough)) \
93a37866 3274 break; \
81345200 3275 typeCheck(_dtc_source, _dtc_edge, _dtc_typesPassedThrough, (jumpToFail)); \
93a37866
A
3276 } while (0)
3277
14957cd0
A
3278} } // namespace JSC::DFG
3279
3280#endif
3281#endif
3282