]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGSpeculativeJIT.h
JavaScriptCore-7600.1.4.17.5.tar.gz
[apple/javascriptcore.git] / dfg / DFGSpeculativeJIT.h
CommitLineData
14957cd0 1/*
81345200 2 * Copyright (C) 2011, 2012, 2013, 2014 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);
294 void storeToWriteBarrierBuffer(JSCell*, GPRReg scratch1, GPRReg scratch2);
295
296 void writeBarrier(GPRReg owner, GPRReg scratch1, GPRReg scratch2);
297 void writeBarrier(GPRReg owner, JSCell* value, GPRReg scratch1, GPRReg scratch2);
6fe7ccc8 298
81345200
A
299 void writeBarrier(GPRReg owner, GPRReg value, Edge valueUse, GPRReg scratch1, GPRReg scratch2);
300 void writeBarrier(JSCell* owner, GPRReg value, Edge valueUse, GPRReg scratch1, GPRReg scratch2);
301#endif
302 void compileStoreBarrier(Node*);
6fe7ccc8
A
303
304 static GPRReg selectScratchGPR(GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg, GPRReg preserve4 = InvalidGPRReg)
305 {
306 return AssemblyHelpers::selectScratchGPR(preserve1, preserve2, preserve3, preserve4);
307 }
308
309 // Called by the speculative operand types, below, to fill operand to
310 // machine registers, implicitly generating speculation checks as needed.
81345200
A
311 GPRReg fillSpeculateInt32(Edge, DataFormat& returnFormat);
312 GPRReg fillSpeculateInt32Strict(Edge);
313 GPRReg fillSpeculateInt52(Edge, DataFormat desiredFormat);
93a37866
A
314 FPRReg fillSpeculateDouble(Edge);
315 GPRReg fillSpeculateCell(Edge);
316 GPRReg fillSpeculateBoolean(Edge);
317 GeneratedOperandType checkGeneratedTypeForToInt32(Node*);
318
319 void addSlowPathGenerator(PassOwnPtr<SlowPathGenerator>);
320 void runSlowPathGenerators();
321
322 void compile(Node*);
323 void noticeOSRBirth(Node*);
81345200
A
324 void bail(AbortReason);
325 void compileCurrentBlock();
6fe7ccc8
A
326
327 void checkArgumentTypes();
328
329 void clearGenerationInfo();
330
331 // These methods are used when generating 'unexpected'
332 // calls out from JIT code to C++ helper routines -
333 // they spill all live values to the appropriate
93a37866 334 // slots in the JSStack without changing any state
6fe7ccc8 335 // in the GenerationInfo.
93a37866
A
336 SilentRegisterSavePlan silentSavePlanForGPR(VirtualRegister spillMe, GPRReg source);
337 SilentRegisterSavePlan silentSavePlanForFPR(VirtualRegister spillMe, FPRReg source);
338 void silentSpill(const SilentRegisterSavePlan&);
339 void silentFill(const SilentRegisterSavePlan&, GPRReg canTrample);
340
341 template<typename CollectionType>
342 void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, GPRReg exclude, GPRReg exclude2 = InvalidGPRReg, FPRReg fprExclude = InvalidFPRReg)
6fe7ccc8 343 {
93a37866
A
344 ASSERT(plans.isEmpty());
345 for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
346 GPRReg gpr = iter.regID();
81345200 347 if (iter.name().isValid() && gpr != exclude && gpr != exclude2) {
93a37866
A
348 SilentRegisterSavePlan plan = silentSavePlanForGPR(iter.name(), gpr);
349 if (doSpill)
350 silentSpill(plan);
351 plans.append(plan);
352 }
6fe7ccc8 353 }
93a37866 354 for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
81345200 355 if (iter.name().isValid() && iter.regID() != fprExclude) {
93a37866
A
356 SilentRegisterSavePlan plan = silentSavePlanForFPR(iter.name(), iter.regID());
357 if (doSpill)
358 silentSpill(plan);
359 plans.append(plan);
360 }
6fe7ccc8 361 }
6fe7ccc8 362 }
93a37866
A
363 template<typename CollectionType>
364 void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, NoResultTag)
6fe7ccc8 365 {
93a37866 366 silentSpillAllRegistersImpl(doSpill, plans, InvalidGPRReg, InvalidGPRReg, InvalidFPRReg);
6fe7ccc8 367 }
93a37866
A
368 template<typename CollectionType>
369 void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, FPRReg exclude)
6fe7ccc8 370 {
93a37866 371 silentSpillAllRegistersImpl(doSpill, plans, InvalidGPRReg, InvalidGPRReg, exclude);
6fe7ccc8 372 }
93a37866
A
373#if USE(JSVALUE32_64)
374 template<typename CollectionType>
375 void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, JSValueRegs exclude)
6fe7ccc8 376 {
93a37866 377 silentSpillAllRegistersImpl(doSpill, plans, exclude.tagGPR(), exclude.payloadGPR());
6fe7ccc8 378 }
93a37866
A
379#endif
380
381 void silentSpillAllRegisters(GPRReg exclude, GPRReg exclude2 = InvalidGPRReg, FPRReg fprExclude = InvalidFPRReg)
6fe7ccc8 382 {
93a37866 383 silentSpillAllRegistersImpl(true, m_plans, exclude, exclude2, fprExclude);
6fe7ccc8
A
384 }
385 void silentSpillAllRegisters(FPRReg exclude)
386 {
93a37866 387 silentSpillAllRegisters(InvalidGPRReg, InvalidGPRReg, exclude);
6fe7ccc8 388 }
93a37866
A
389
390 static GPRReg pickCanTrample(GPRReg exclude)
6fe7ccc8 391 {
93a37866
A
392 GPRReg result = GPRInfo::regT0;
393 if (result == exclude)
394 result = GPRInfo::regT1;
395 return result;
396 }
397 static GPRReg pickCanTrample(FPRReg)
398 {
399 return GPRInfo::regT0;
400 }
401 static GPRReg pickCanTrample(NoResultTag)
402 {
403 return GPRInfo::regT0;
404 }
405
406#if USE(JSVALUE32_64)
407 static GPRReg pickCanTrample(JSValueRegs exclude)
408 {
409 GPRReg result = GPRInfo::regT0;
410 if (result == exclude.tagGPR()) {
411 result = GPRInfo::regT1;
412 if (result == exclude.payloadGPR())
413 result = GPRInfo::regT2;
414 } else if (result == exclude.payloadGPR()) {
415 result = GPRInfo::regT1;
416 if (result == exclude.tagGPR())
417 result = GPRInfo::regT2;
6fe7ccc8 418 }
93a37866 419 return result;
6fe7ccc8 420 }
93a37866
A
421#endif
422
423 template<typename RegisterType>
424 void silentFillAllRegisters(RegisterType exclude)
6fe7ccc8 425 {
93a37866 426 GPRReg canTrample = pickCanTrample(exclude);
6fe7ccc8 427
93a37866
A
428 while (!m_plans.isEmpty()) {
429 SilentRegisterSavePlan& plan = m_plans.last();
430 silentFill(plan, canTrample);
431 m_plans.removeLast();
6fe7ccc8
A
432 }
433 }
434
435 // These methods convert between doubles, and doubles boxed and JSValues.
436#if USE(JSVALUE64)
437 GPRReg boxDouble(FPRReg fpr, GPRReg gpr)
438 {
439 return m_jit.boxDouble(fpr, gpr);
440 }
441 FPRReg unboxDouble(GPRReg gpr, FPRReg fpr)
442 {
443 return m_jit.unboxDouble(gpr, fpr);
444 }
445 GPRReg boxDouble(FPRReg fpr)
446 {
447 return boxDouble(fpr, allocate());
448 }
81345200
A
449
450 void boxInt52(GPRReg sourceGPR, GPRReg targetGPR, DataFormat);
6fe7ccc8
A
451#elif USE(JSVALUE32_64)
452 void boxDouble(FPRReg fpr, GPRReg tagGPR, GPRReg payloadGPR)
453 {
454 m_jit.boxDouble(fpr, tagGPR, payloadGPR);
455 }
456 void unboxDouble(GPRReg tagGPR, GPRReg payloadGPR, FPRReg fpr, FPRReg scratchFPR)
457 {
458 m_jit.unboxDouble(tagGPR, payloadGPR, fpr, scratchFPR);
459 }
460#endif
81345200
A
461 void boxDouble(FPRReg fpr, JSValueRegs regs)
462 {
463 m_jit.boxDouble(fpr, regs);
464 }
6fe7ccc8 465
93a37866 466 // Spill a VirtualRegister to the JSStack.
6fe7ccc8
A
467 void spill(VirtualRegister spillMe)
468 {
81345200 469 GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
6fe7ccc8
A
470
471#if USE(JSVALUE32_64)
472 if (info.registerFormat() == DataFormatNone) // it has been spilled. JS values which have two GPRs can reach here
473 return;
474#endif
475 // Check the GenerationInfo to see if this value need writing
93a37866 476 // to the JSStack - if not, mark it as spilled & return.
6fe7ccc8 477 if (!info.needsSpill()) {
93a37866 478 info.setSpilled(*m_stream, spillMe);
6fe7ccc8
A
479 return;
480 }
481
482 DataFormat spillFormat = info.registerFormat();
483 switch (spillFormat) {
484 case DataFormatStorage: {
485 // This is special, since it's not a JS value - as in it's not visible to JS
486 // code.
487 m_jit.storePtr(info.gpr(), JITCompiler::addressFor(spillMe));
93a37866 488 info.spill(*m_stream, spillMe, DataFormatStorage);
6fe7ccc8
A
489 return;
490 }
491
81345200 492 case DataFormatInt32: {
6fe7ccc8 493 m_jit.store32(info.gpr(), JITCompiler::payloadFor(spillMe));
81345200 494 info.spill(*m_stream, spillMe, DataFormatInt32);
6fe7ccc8
A
495 return;
496 }
497
498#if USE(JSVALUE64)
499 case DataFormatDouble: {
500 m_jit.storeDouble(info.fpr(), JITCompiler::addressFor(spillMe));
93a37866 501 info.spill(*m_stream, spillMe, DataFormatDouble);
6fe7ccc8
A
502 return;
503 }
81345200
A
504
505 case DataFormatInt52:
506 case DataFormatStrictInt52: {
507 m_jit.store64(info.gpr(), JITCompiler::addressFor(spillMe));
508 info.spill(*m_stream, spillMe, spillFormat);
509 return;
510 }
6fe7ccc8
A
511
512 default:
513 // The following code handles JSValues, int32s, and cells.
93a37866 514 RELEASE_ASSERT(spillFormat == DataFormatCell || spillFormat & DataFormatJS);
6fe7ccc8
A
515
516 GPRReg reg = info.gpr();
517 // We need to box int32 and cell values ...
518 // but on JSVALUE64 boxing a cell is a no-op!
81345200 519 if (spillFormat == DataFormatInt32)
93a37866 520 m_jit.or64(GPRInfo::tagTypeNumberRegister, reg);
6fe7ccc8
A
521
522 // Spill the value, and record it as spilled in its boxed form.
93a37866
A
523 m_jit.store64(reg, JITCompiler::addressFor(spillMe));
524 info.spill(*m_stream, spillMe, (DataFormat)(spillFormat | DataFormatJS));
6fe7ccc8
A
525 return;
526#elif USE(JSVALUE32_64)
527 case DataFormatCell:
528 case DataFormatBoolean: {
529 m_jit.store32(info.gpr(), JITCompiler::payloadFor(spillMe));
93a37866 530 info.spill(*m_stream, spillMe, spillFormat);
6fe7ccc8
A
531 return;
532 }
533
81345200 534 case DataFormatDouble: {
6fe7ccc8
A
535 // On JSVALUE32_64 boxing a double is a no-op.
536 m_jit.storeDouble(info.fpr(), JITCompiler::addressFor(spillMe));
81345200 537 info.spill(*m_stream, spillMe, DataFormatDouble);
6fe7ccc8
A
538 return;
539 }
540
541 default:
542 // The following code handles JSValues.
93a37866 543 RELEASE_ASSERT(spillFormat & DataFormatJS);
6fe7ccc8
A
544 m_jit.store32(info.tagGPR(), JITCompiler::tagFor(spillMe));
545 m_jit.store32(info.payloadGPR(), JITCompiler::payloadFor(spillMe));
93a37866 546 info.spill(*m_stream, spillMe, spillFormat);
6fe7ccc8
A
547 return;
548#endif
549 }
550 }
551
81345200
A
552 bool isKnownInteger(Node* node) { return m_state.forNode(node).isType(SpecInt32); }
553 bool isKnownCell(Node* node) { return m_state.forNode(node).isType(SpecCell); }
6fe7ccc8 554
93a37866 555 bool isKnownNotInteger(Node* node) { return !(m_state.forNode(node).m_type & SpecInt32); }
81345200 556 bool isKnownNotNumber(Node* node) { return !(m_state.forNode(node).m_type & SpecFullNumber); }
93a37866 557 bool isKnownNotCell(Node* node) { return !(m_state.forNode(node).m_type & SpecCell); }
6fe7ccc8
A
558
559 // Checks/accessors for constant values.
93a37866
A
560 bool isConstant(Node* node) { return m_jit.graph().isConstant(node); }
561 bool isJSConstant(Node* node) { return m_jit.graph().isJSConstant(node); }
562 bool isInt32Constant(Node* node) { return m_jit.graph().isInt32Constant(node); }
563 bool isDoubleConstant(Node* node) { return m_jit.graph().isDoubleConstant(node); }
564 bool isNumberConstant(Node* node) { return m_jit.graph().isNumberConstant(node); }
565 bool isBooleanConstant(Node* node) { return m_jit.graph().isBooleanConstant(node); }
566 bool isFunctionConstant(Node* node) { return m_jit.graph().isFunctionConstant(node); }
567 int32_t valueOfInt32Constant(Node* node) { return m_jit.graph().valueOfInt32Constant(node); }
568 double valueOfNumberConstant(Node* node) { return m_jit.graph().valueOfNumberConstant(node); }
6fe7ccc8 569#if USE(JSVALUE32_64)
93a37866 570 void* addressOfDoubleConstant(Node* node) { return m_jit.addressOfDoubleConstant(node); }
6fe7ccc8 571#endif
93a37866
A
572 JSValue valueOfJSConstant(Node* node) { return m_jit.graph().valueOfJSConstant(node); }
573 bool valueOfBooleanConstant(Node* node) { return m_jit.graph().valueOfBooleanConstant(node); }
574 JSFunction* valueOfFunctionConstant(Node* node) { return m_jit.graph().valueOfFunctionConstant(node); }
575 bool isNullConstant(Node* node)
6fe7ccc8 576 {
93a37866 577 if (!isConstant(node))
6fe7ccc8 578 return false;
93a37866 579 return valueOfJSConstant(node).isNull();
6fe7ccc8
A
580 }
581
81345200 582 StringImpl* identifierUID(unsigned index)
6fe7ccc8 583 {
81345200 584 return m_jit.graph().identifiers()[index];
6fe7ccc8
A
585 }
586
93a37866 587 // Spill all VirtualRegisters back to the JSStack.
6fe7ccc8
A
588 void flushRegisters()
589 {
590 for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
81345200 591 if (iter.name().isValid()) {
6fe7ccc8
A
592 spill(iter.name());
593 iter.release();
594 }
595 }
596 for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
81345200 597 if (iter.name().isValid()) {
6fe7ccc8
A
598 spill(iter.name());
599 iter.release();
600 }
601 }
602 }
603
604#ifndef NDEBUG
605 // Used to ASSERT flushRegisters() has been called prior to
606 // calling out from JIT code to a C helper function.
607 bool isFlushed()
608 {
609 for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
81345200 610 if (iter.name().isValid())
6fe7ccc8
A
611 return false;
612 }
613 for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
81345200 614 if (iter.name().isValid())
6fe7ccc8
A
615 return false;
616 }
617 return true;
618 }
619#endif
620
621#if USE(JSVALUE64)
93a37866 622 MacroAssembler::Imm64 valueOfJSConstantAsImm64(Node* node)
6fe7ccc8 623 {
93a37866 624 return MacroAssembler::Imm64(JSValue::encode(valueOfJSConstant(node)));
6fe7ccc8
A
625 }
626#endif
627
628 // Helper functions to enable code sharing in implementations of bit/shift ops.
629 void bitOp(NodeType op, int32_t imm, GPRReg op1, GPRReg result)
630 {
631 switch (op) {
632 case BitAnd:
633 m_jit.and32(Imm32(imm), op1, result);
634 break;
635 case BitOr:
636 m_jit.or32(Imm32(imm), op1, result);
637 break;
638 case BitXor:
639 m_jit.xor32(Imm32(imm), op1, result);
640 break;
641 default:
93a37866 642 RELEASE_ASSERT_NOT_REACHED();
6fe7ccc8
A
643 }
644 }
645 void bitOp(NodeType op, GPRReg op1, GPRReg op2, GPRReg result)
646 {
647 switch (op) {
648 case BitAnd:
649 m_jit.and32(op1, op2, result);
650 break;
651 case BitOr:
652 m_jit.or32(op1, op2, result);
653 break;
654 case BitXor:
655 m_jit.xor32(op1, op2, result);
656 break;
657 default:
93a37866 658 RELEASE_ASSERT_NOT_REACHED();
6fe7ccc8
A
659 }
660 }
661 void shiftOp(NodeType op, GPRReg op1, int32_t shiftAmount, GPRReg result)
662 {
663 switch (op) {
664 case BitRShift:
665 m_jit.rshift32(op1, Imm32(shiftAmount), result);
666 break;
667 case BitLShift:
668 m_jit.lshift32(op1, Imm32(shiftAmount), result);
669 break;
670 case BitURShift:
671 m_jit.urshift32(op1, Imm32(shiftAmount), result);
672 break;
673 default:
93a37866 674 RELEASE_ASSERT_NOT_REACHED();
6fe7ccc8
A
675 }
676 }
677 void shiftOp(NodeType op, GPRReg op1, GPRReg shiftAmount, GPRReg result)
678 {
679 switch (op) {
680 case BitRShift:
681 m_jit.rshift32(op1, shiftAmount, result);
682 break;
683 case BitLShift:
684 m_jit.lshift32(op1, shiftAmount, result);
685 break;
686 case BitURShift:
687 m_jit.urshift32(op1, shiftAmount, result);
688 break;
689 default:
93a37866 690 RELEASE_ASSERT_NOT_REACHED();
6fe7ccc8
A
691 }
692 }
693
694 // Returns the index of the branch node if peephole is okay, UINT_MAX otherwise.
695 unsigned detectPeepHoleBranch()
696 {
6fe7ccc8 697 // Check that no intervening nodes will be generated.
81345200
A
698 for (unsigned index = m_indexInBlock + 1; index < m_block->size() - 1; ++index) {
699 Node* node = m_block->at(index);
700 if (!node->shouldGenerate())
701 continue;
702 // Check if it's a Phantom that can be safely ignored.
703 if (node->op() == Phantom && !node->child1())
704 continue;
705 return UINT_MAX;
6fe7ccc8
A
706 }
707
708 // Check if the lastNode is a branch on this node.
81345200
A
709 Node* lastNode = m_block->last();
710 return lastNode->op() == Branch && lastNode->child1() == m_currentNode ? m_block->size() - 1 : UINT_MAX;
6fe7ccc8
A
711 }
712
93a37866
A
713 void compileMovHint(Node*);
714 void compileMovHintAndCheck(Node*);
6fe7ccc8 715
6fe7ccc8 716#if USE(JSVALUE64)
93a37866 717 void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
81345200 718 void cachedPutById(CodeOrigin, GPRReg base, GPRReg value, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
6fe7ccc8 719#elif USE(JSVALUE32_64)
93a37866 720 void cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
81345200 721 void cachedPutById(CodeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
6fe7ccc8 722#endif
81345200
A
723
724 void compileIn(Node*);
725
726 void compileBaseValueStoreBarrier(Edge& baseEdge, Edge& valueEdge);
6fe7ccc8
A
727
728 void nonSpeculativeNonPeepholeCompareNull(Edge operand, bool invert = false);
93a37866
A
729 void nonSpeculativePeepholeBranchNull(Edge operand, Node* branchNode, bool invert = false);
730 bool nonSpeculativeCompareNull(Node*, Edge operand, bool invert = false);
6fe7ccc8 731
81345200
A
732 void nonSpeculativePeepholeBranch(Node*, Node* branchNode, MacroAssembler::RelationalCondition, S_JITOperation_EJJ helperFunction);
733 void nonSpeculativeNonPeepholeCompare(Node*, MacroAssembler::RelationalCondition, S_JITOperation_EJJ helperFunction);
734 bool nonSpeculativeCompare(Node*, MacroAssembler::RelationalCondition, S_JITOperation_EJJ helperFunction);
6fe7ccc8 735
93a37866
A
736 void nonSpeculativePeepholeStrictEq(Node*, Node* branchNode, bool invert = false);
737 void nonSpeculativeNonPeepholeStrictEq(Node*, bool invert = false);
738 bool nonSpeculativeStrictEq(Node*, bool invert = false);
6fe7ccc8 739
81345200 740 void compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg, GPRReg scratch2Reg);
93a37866 741 void compileInstanceOf(Node*);
6fe7ccc8 742
81345200
A
743 ptrdiff_t calleeFrameOffset(int numArgs)
744 {
745 return virtualRegisterForLocal(m_jit.graph().m_nextMachineLocal - 1 + JSStack::CallFrameHeaderSize + numArgs).offset() * sizeof(Register);
746 }
747
6fe7ccc8 748 // Access to our fixed callee CallFrame.
81345200 749 MacroAssembler::Address calleeFrameSlot(int slot)
6fe7ccc8 750 {
81345200
A
751 ASSERT(slot >= JSStack::CallerFrameAndPCSize);
752 return MacroAssembler::Address(MacroAssembler::stackPointerRegister, sizeof(Register) * (slot - JSStack::CallerFrameAndPCSize));
6fe7ccc8
A
753 }
754
755 // Access to our fixed callee CallFrame.
81345200
A
756 MacroAssembler::Address calleeArgumentSlot(int argument)
757 {
758 return calleeFrameSlot(virtualRegisterForArgument(argument).offset());
759 }
760
761 MacroAssembler::Address calleeFrameTagSlot(int slot)
6fe7ccc8 762 {
81345200 763 return calleeFrameSlot(slot).withOffset(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
6fe7ccc8
A
764 }
765
81345200 766 MacroAssembler::Address calleeFramePayloadSlot(int slot)
6fe7ccc8 767 {
81345200 768 return calleeFrameSlot(slot).withOffset(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
6fe7ccc8
A
769 }
770
81345200 771 MacroAssembler::Address calleeArgumentTagSlot(int argument)
6fe7ccc8 772 {
81345200 773 return calleeArgumentSlot(argument).withOffset(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
6fe7ccc8
A
774 }
775
81345200 776 MacroAssembler::Address calleeArgumentPayloadSlot(int argument)
6fe7ccc8 777 {
81345200 778 return calleeArgumentSlot(argument).withOffset(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
6fe7ccc8
A
779 }
780
81345200 781 MacroAssembler::Address calleeFrameCallerFrame()
6fe7ccc8 782 {
81345200 783 return calleeFrameSlot(0).withOffset(CallFrame::callerFrameOffset());
6fe7ccc8
A
784 }
785
93a37866 786 void emitCall(Node*);
6fe7ccc8 787
81345200
A
788 int32_t framePointerOffsetToGetActivationRegisters()
789 {
790 return m_jit.codeBlock()->framePointerOffsetToGetActivationRegisters(
791 m_jit.graph().m_machineCaptureStart);
792 }
793
6fe7ccc8
A
794 // Called once a node has completed code generation but prior to setting
795 // its result, to free up its children. (This must happen prior to setting
796 // the nodes result, since the node may have the same VirtualRegister as
797 // a child, and as such will use the same GeneratioInfo).
93a37866 798 void useChildren(Node*);
6fe7ccc8
A
799
800 // These method called to initialize the the GenerationInfo
801 // to describe the result of an operation.
81345200 802 void int32Result(GPRReg reg, Node* node, DataFormat format = DataFormatInt32, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 803 {
6fe7ccc8
A
804 if (mode == CallUseChildren)
805 useChildren(node);
806
93a37866 807 VirtualRegister virtualRegister = node->virtualRegister();
81345200 808 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
6fe7ccc8 809
81345200 810 if (format == DataFormatInt32) {
6fe7ccc8
A
811 m_jit.jitAssertIsInt32(reg);
812 m_gprs.retain(reg, virtualRegister, SpillOrderInteger);
81345200 813 info.initInt32(node, node->refCount(), reg);
6fe7ccc8
A
814 } else {
815#if USE(JSVALUE64)
81345200 816 RELEASE_ASSERT(format == DataFormatJSInt32);
6fe7ccc8
A
817 m_jit.jitAssertIsJSInt32(reg);
818 m_gprs.retain(reg, virtualRegister, SpillOrderJS);
93a37866 819 info.initJSValue(node, node->refCount(), reg, format);
6fe7ccc8 820#elif USE(JSVALUE32_64)
93a37866 821 RELEASE_ASSERT_NOT_REACHED();
6fe7ccc8
A
822#endif
823 }
824 }
81345200
A
825 void int32Result(GPRReg reg, Node* node, UseChildrenMode mode)
826 {
827 int32Result(reg, node, DataFormatInt32, mode);
828 }
829 void int52Result(GPRReg reg, Node* node, DataFormat format, UseChildrenMode mode = CallUseChildren)
830 {
831 if (mode == CallUseChildren)
832 useChildren(node);
833
834 VirtualRegister virtualRegister = node->virtualRegister();
835 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
836
837 m_gprs.retain(reg, virtualRegister, SpillOrderJS);
838 info.initInt52(node, node->refCount(), reg, format);
839 }
840 void int52Result(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
841 {
842 int52Result(reg, node, DataFormatInt52, mode);
843 }
844 void strictInt52Result(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 845 {
81345200 846 int52Result(reg, node, DataFormatStrictInt52, mode);
6fe7ccc8 847 }
93a37866 848 void noResult(Node* node, UseChildrenMode mode = CallUseChildren)
6fe7ccc8
A
849 {
850 if (mode == UseChildrenCalledExplicitly)
851 return;
6fe7ccc8
A
852 useChildren(node);
853 }
93a37866 854 void cellResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 855 {
6fe7ccc8
A
856 if (mode == CallUseChildren)
857 useChildren(node);
858
93a37866 859 VirtualRegister virtualRegister = node->virtualRegister();
6fe7ccc8 860 m_gprs.retain(reg, virtualRegister, SpillOrderCell);
81345200 861 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
93a37866 862 info.initCell(node, node->refCount(), reg);
6fe7ccc8 863 }
81345200 864 void blessedBooleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 865 {
81345200
A
866#if USE(JSVALUE64)
867 jsValueResult(reg, node, DataFormatJSBoolean, mode);
868#else
6fe7ccc8
A
869 if (mode == CallUseChildren)
870 useChildren(node);
871
93a37866 872 VirtualRegister virtualRegister = node->virtualRegister();
6fe7ccc8 873 m_gprs.retain(reg, virtualRegister, SpillOrderBoolean);
81345200 874 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
93a37866 875 info.initBoolean(node, node->refCount(), reg);
81345200
A
876#endif
877 }
878 void unblessedBooleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
879 {
880#if USE(JSVALUE64)
881 blessBoolean(reg);
882#endif
883 blessedBooleanResult(reg, node, mode);
6fe7ccc8
A
884 }
885#if USE(JSVALUE64)
93a37866 886 void jsValueResult(GPRReg reg, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 887 {
81345200 888 if (format == DataFormatJSInt32)
6fe7ccc8
A
889 m_jit.jitAssertIsJSInt32(reg);
890
6fe7ccc8
A
891 if (mode == CallUseChildren)
892 useChildren(node);
893
93a37866 894 VirtualRegister virtualRegister = node->virtualRegister();
6fe7ccc8 895 m_gprs.retain(reg, virtualRegister, SpillOrderJS);
81345200 896 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
93a37866 897 info.initJSValue(node, node->refCount(), reg, format);
6fe7ccc8 898 }
93a37866 899 void jsValueResult(GPRReg reg, Node* node, UseChildrenMode mode)
6fe7ccc8 900 {
93a37866 901 jsValueResult(reg, node, DataFormatJS, mode);
6fe7ccc8
A
902 }
903#elif USE(JSVALUE32_64)
81345200
A
904 void booleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
905 {
906 if (mode == CallUseChildren)
907 useChildren(node);
908
909 VirtualRegister virtualRegister = node->virtualRegister();
910 m_gprs.retain(reg, virtualRegister, SpillOrderBoolean);
911 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
912 info.initBoolean(node, node->refCount(), reg);
913 }
93a37866 914 void jsValueResult(GPRReg tag, GPRReg payload, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 915 {
6fe7ccc8
A
916 if (mode == CallUseChildren)
917 useChildren(node);
918
93a37866 919 VirtualRegister virtualRegister = node->virtualRegister();
6fe7ccc8
A
920 m_gprs.retain(tag, virtualRegister, SpillOrderJS);
921 m_gprs.retain(payload, virtualRegister, SpillOrderJS);
81345200 922 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
93a37866 923 info.initJSValue(node, node->refCount(), tag, payload, format);
6fe7ccc8 924 }
93a37866 925 void jsValueResult(GPRReg tag, GPRReg payload, Node* node, UseChildrenMode mode)
6fe7ccc8 926 {
93a37866 927 jsValueResult(tag, payload, node, DataFormatJS, mode);
6fe7ccc8
A
928 }
929#endif
81345200
A
930 void jsValueResult(JSValueRegs regs, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
931 {
932#if USE(JSVALUE64)
933 jsValueResult(regs.gpr(), node, format, mode);
934#else
935 jsValueResult(regs.tagGPR(), regs.payloadGPR(), node, format, mode);
936#endif
937 }
93a37866 938 void storageResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 939 {
6fe7ccc8
A
940 if (mode == CallUseChildren)
941 useChildren(node);
942
93a37866 943 VirtualRegister virtualRegister = node->virtualRegister();
6fe7ccc8 944 m_gprs.retain(reg, virtualRegister, SpillOrderStorage);
81345200 945 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
93a37866 946 info.initStorage(node, node->refCount(), reg);
6fe7ccc8 947 }
93a37866 948 void doubleResult(FPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
6fe7ccc8 949 {
6fe7ccc8
A
950 if (mode == CallUseChildren)
951 useChildren(node);
952
93a37866 953 VirtualRegister virtualRegister = node->virtualRegister();
6fe7ccc8 954 m_fprs.retain(reg, virtualRegister, SpillOrderDouble);
81345200 955 GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
93a37866 956 info.initDouble(node, node->refCount(), reg);
6fe7ccc8 957 }
93a37866 958 void initConstantInfo(Node* node)
6fe7ccc8 959 {
93a37866 960 ASSERT(isInt32Constant(node) || isNumberConstant(node) || isJSConstant(node));
81345200 961 generationInfo(node).initConstant(node, node->refCount());
6fe7ccc8
A
962 }
963
964 // These methods add calls to C++ helper functions.
965 // These methods are broadly value representation specific (i.e.
966 // deal with the fact that a JSValue may be passed in one or two
967 // machine registers, and delegate the calling convention specific
968 // decision as to how to fill the regsiters to setupArguments* methods.
93a37866 969
81345200 970 JITCompiler::Call callOperation(P_JITOperation_E operation, GPRReg result)
93a37866
A
971 {
972 m_jit.setupArgumentsExecState();
973 return appendCallWithExceptionCheckSetResult(operation, result);
974 }
81345200 975 JITCompiler::Call callOperation(P_JITOperation_EC operation, GPRReg result, GPRReg cell)
93a37866
A
976 {
977 m_jit.setupArgumentsWithExecState(cell);
978 return appendCallWithExceptionCheckSetResult(operation, result);
979 }
81345200 980 JITCompiler::Call callOperation(P_JITOperation_EO operation, GPRReg result, GPRReg object)
93a37866
A
981 {
982 m_jit.setupArgumentsWithExecState(object);
983 return appendCallWithExceptionCheckSetResult(operation, result);
984 }
81345200 985 JITCompiler::Call callOperation(P_JITOperation_EOS operation, GPRReg result, GPRReg object, size_t size)
93a37866
A
986 {
987 m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size));
988 return appendCallWithExceptionCheckSetResult(operation, result);
989 }
81345200 990 JITCompiler::Call callOperation(P_JITOperation_EOZ operation, GPRReg result, GPRReg object, int32_t size)
93a37866
A
991 {
992 m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size));
993 return appendCallWithExceptionCheckSetResult(operation, result);
994 }
81345200 995 JITCompiler::Call callOperation(C_JITOperation_EOZ operation, GPRReg result, GPRReg object, int32_t size)
93a37866
A
996 {
997 m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(static_cast<size_t>(size)));
998 return appendCallWithExceptionCheckSetResult(operation, result);
999 }
81345200 1000 JITCompiler::Call callOperation(P_JITOperation_EPS operation, GPRReg result, GPRReg old, size_t size)
93a37866
A
1001 {
1002 m_jit.setupArgumentsWithExecState(old, TrustedImmPtr(size));
1003 return appendCallWithExceptionCheckSetResult(operation, result);
1004 }
81345200 1005 JITCompiler::Call callOperation(P_JITOperation_ES operation, GPRReg result, size_t size)
93a37866
A
1006 {
1007 m_jit.setupArgumentsWithExecState(TrustedImmPtr(size));
1008 return appendCallWithExceptionCheckSetResult(operation, result);
1009 }
81345200
A
1010 JITCompiler::Call callOperation(P_JITOperation_ESJss operation, GPRReg result, size_t index, GPRReg arg1)
1011 {
1012 m_jit.setupArgumentsWithExecState(TrustedImmPtr(index), arg1);
1013 return appendCallWithExceptionCheckSetResult(operation, result);
1014 }
1015 JITCompiler::Call callOperation(P_JITOperation_ESt operation, GPRReg result, Structure* structure)
93a37866
A
1016 {
1017 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
1018 return appendCallWithExceptionCheckSetResult(operation, result);
1019 }
81345200 1020 JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2)
93a37866
A
1021 {
1022 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
1023 return appendCallWithExceptionCheckSetResult(operation, result);
1024 }
81345200 1025 JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, Structure* structure, size_t arg2)
93a37866
A
1026 {
1027 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2));
1028 return appendCallWithExceptionCheckSetResult(operation, result);
1029 }
81345200 1030 JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
93a37866
A
1031 {
1032 m_jit.setupArgumentsWithExecState(arg1, arg2);
1033 return appendCallWithExceptionCheckSetResult(operation, result);
1034 }
81345200 1035 JITCompiler::Call callOperation(P_JITOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size)
93a37866
A
1036 {
1037 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size));
1038 return appendCallWithExceptionCheckSetResult(operation, result);
1039 }
81345200 1040 JITCompiler::Call callOperation(P_JITOperation_EStSS operation, GPRReg result, Structure* structure, size_t index, size_t size)
93a37866
A
1041 {
1042 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(index), TrustedImmPtr(size));
1043 return appendCallWithExceptionCheckSetResult(operation, result);
1044 }
81345200 1045 JITCompiler::Call callOperation(C_JITOperation_E operation, GPRReg result)
93a37866
A
1046 {
1047 m_jit.setupArgumentsExecState();
1048 return appendCallWithExceptionCheckSetResult(operation, result);
1049 }
81345200 1050 JITCompiler::Call callOperation(C_JITOperation_EC operation, GPRReg result, GPRReg arg1)
93a37866
A
1051 {
1052 m_jit.setupArgumentsWithExecState(arg1);
1053 return appendCallWithExceptionCheckSetResult(operation, result);
1054 }
81345200 1055 JITCompiler::Call callOperation(C_JITOperation_EC operation, GPRReg result, JSCell* cell)
93a37866
A
1056 {
1057 m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
1058 return appendCallWithExceptionCheckSetResult(operation, result);
1059 }
81345200 1060 JITCompiler::Call callOperation(C_JITOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell)
93a37866
A
1061 {
1062 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
1063 return appendCallWithExceptionCheckSetResult(operation, result);
1064 }
81345200 1065 JITCompiler::Call callOperation(C_JITOperation_EIcf operation, GPRReg result, InlineCallFrame* inlineCallFrame)
93a37866
A
1066 {
1067 m_jit.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame));
1068 return appendCallWithExceptionCheckSetResult(operation, result);
1069 }
81345200 1070 JITCompiler::Call callOperation(C_JITOperation_ESt operation, GPRReg result, Structure* structure)
93a37866
A
1071 {
1072 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
1073 return appendCallWithExceptionCheckSetResult(operation, result);
1074 }
81345200 1075 JITCompiler::Call callOperation(C_JITOperation_EJssSt operation, GPRReg result, GPRReg arg1, Structure* structure)
93a37866
A
1076 {
1077 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(structure));
1078 return appendCallWithExceptionCheckSetResult(operation, result);
1079 }
81345200 1080 JITCompiler::Call callOperation(C_JITOperation_EJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
93a37866
A
1081 {
1082 m_jit.setupArgumentsWithExecState(arg1, arg2);
1083 return appendCallWithExceptionCheckSetResult(operation, result);
1084 }
81345200 1085 JITCompiler::Call callOperation(C_JITOperation_EJssJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
93a37866
A
1086 {
1087 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1088 return appendCallWithExceptionCheckSetResult(operation, result);
1089 }
1090
81345200 1091 JITCompiler::Call callOperation(S_JITOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
93a37866
A
1092 {
1093 m_jit.setupArgumentsWithExecState(arg1, arg2);
1094 return appendCallWithExceptionCheckSetResult(operation, result);
1095 }
1096
81345200
A
1097 JITCompiler::Call callOperation(Jss_JITOperation_EZ operation, GPRReg result, GPRReg arg1)
1098 {
1099 m_jit.setupArgumentsWithExecState(arg1);
1100 return appendCallWithExceptionCheckSetResult(operation, result);
1101 }
1102
1103 JITCompiler::Call callOperation(V_JITOperation_EC operation, GPRReg arg1)
93a37866
A
1104 {
1105 m_jit.setupArgumentsWithExecState(arg1);
1106 return appendCallWithExceptionCheck(operation);
1107 }
1108
81345200
A
1109 JITCompiler::Call callOperation(V_JITOperation_EC operation, JSCell* arg1)
1110 {
1111 m_jit.setupArgumentsWithExecState(TrustedImmPtr(arg1));
1112 return appendCallWithExceptionCheck(operation);
1113 }
1114
1115 JITCompiler::Call callOperation(V_JITOperation_ECIcf operation, GPRReg arg1, InlineCallFrame* inlineCallFrame)
93a37866
A
1116 {
1117 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(inlineCallFrame));
1118 return appendCallWithExceptionCheck(operation);
1119 }
81345200 1120 JITCompiler::Call callOperation(V_JITOperation_ECCIcf operation, GPRReg arg1, GPRReg arg2, InlineCallFrame* inlineCallFrame)
93a37866
A
1121 {
1122 m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(inlineCallFrame));
1123 return appendCallWithExceptionCheck(operation);
1124 }
1125
81345200 1126 JITCompiler::Call callOperation(V_JITOperation_ECZ operation, GPRReg arg1, int arg2)
93a37866
A
1127 {
1128 m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1129 return appendCallWithExceptionCheck(operation);
1130 }
81345200 1131 JITCompiler::Call callOperation(V_JITOperation_ECC operation, GPRReg arg1, GPRReg arg2)
93a37866
A
1132 {
1133 m_jit.setupArgumentsWithExecState(arg1, arg2);
1134 return appendCallWithExceptionCheck(operation);
1135 }
81345200 1136 JITCompiler::Call callOperation(V_JITOperation_ECC operation, GPRReg arg1, JSCell* arg2)
93a37866 1137 {
81345200
A
1138 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
1139 return appendCallWithExceptionCheck(operation);
1140 }
1141 JITCompiler::Call callOperation(V_JITOperation_ECC operation, JSCell* arg1, GPRReg arg2)
1142 {
1143 m_jit.setupArgumentsWithExecState(TrustedImmPtr(arg1), arg2);
93a37866
A
1144 return appendCallWithExceptionCheck(operation);
1145 }
1146
81345200 1147 JITCompiler::Call callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb operation, void* pointer)
93a37866 1148 {
81345200
A
1149 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1150 return appendCallWithCallFrameRollbackOnException(operation);
1151 }
1152
1153 JITCompiler::Call callOperationWithCallFrameRollbackOnException(Z_JITOperation_E operation, GPRReg result)
1154 {
1155 m_jit.setupArgumentsExecState();
1156 return appendCallWithCallFrameRollbackOnExceptionSetResult(operation, result);
93a37866
A
1157 }
1158
1159 template<typename FunctionType, typename ArgumentType1>
1160 JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1)
1161 {
1162 return callOperation(operation, arg1);
1163 }
1164 template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
1165 JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2)
1166 {
1167 return callOperation(operation, arg1, arg2);
1168 }
1169 template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3>
1170 JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3)
1171 {
1172 return callOperation(operation, arg1, arg2, arg3);
1173 }
1174 template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3, typename ArgumentType4>
1175 JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3, ArgumentType4 arg4)
1176 {
1177 return callOperation(operation, arg1, arg2, arg3, arg4);
1178 }
1179 template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3, typename ArgumentType4, typename ArgumentType5>
1180 JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3, ArgumentType4 arg4, ArgumentType5 arg5)
1181 {
1182 return callOperation(operation, arg1, arg2, arg3, arg4, arg5);
1183 }
1184
81345200 1185 JITCompiler::Call callOperation(D_JITOperation_ZZ operation, FPRReg result, GPRReg arg1, GPRReg arg2)
93a37866
A
1186 {
1187 m_jit.setupArguments(arg1, arg2);
1188 return appendCallSetResult(operation, result);
1189 }
81345200
A
1190 JITCompiler::Call callOperation(D_JITOperation_D operation, FPRReg result, FPRReg arg1)
1191 {
1192 m_jit.setupArguments(arg1);
1193 return appendCallSetResult(operation, result);
1194 }
1195 JITCompiler::Call callOperation(D_JITOperation_DD operation, FPRReg result, FPRReg arg1, FPRReg arg2)
93a37866
A
1196 {
1197 m_jit.setupArguments(arg1, arg2);
1198 return appendCallSetResult(operation, result);
1199 }
81345200 1200 JITCompiler::Call callOperation(I_JITOperation_EJss operation, GPRReg result, GPRReg arg1)
93a37866
A
1201 {
1202 m_jit.setupArgumentsWithExecState(arg1);
1203 return appendCallWithExceptionCheckSetResult(operation, result);
1204 }
81345200 1205 JITCompiler::Call callOperation(C_JITOperation_EZ operation, GPRReg result, GPRReg arg1)
93a37866
A
1206 {
1207 m_jit.setupArgumentsWithExecState(arg1);
1208 return appendCallWithExceptionCheckSetResult(operation, result);
1209 }
81345200
A
1210 JITCompiler::Call callOperation(C_JITOperation_EZ operation, GPRReg result, int32_t arg1)
1211 {
1212 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1213 return appendCallWithExceptionCheckSetResult(operation, result);
1214 }
93a37866 1215
6fe7ccc8 1216#if USE(JSVALUE64)
81345200 1217 JITCompiler::Call callOperation(J_JITOperation_E operation, GPRReg result)
93a37866
A
1218 {
1219 m_jit.setupArgumentsExecState();
1220 return appendCallWithExceptionCheckSetResult(operation, result);
1221 }
81345200 1222 JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg result, void* pointer)
6fe7ccc8
A
1223 {
1224 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1225 return appendCallWithExceptionCheckSetResult(operation, result);
1226 }
81345200 1227 JITCompiler::Call callOperation(Z_JITOperation_D operation, GPRReg result, FPRReg arg1)
6fe7ccc8
A
1228 {
1229 m_jit.setupArguments(arg1);
1230 JITCompiler::Call call = m_jit.appendCall(operation);
1231 m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1232 return call;
1233 }
81345200 1234 JITCompiler::Call callOperation(Q_JITOperation_J operation, GPRReg result, GPRReg value)
6fe7ccc8 1235 {
81345200
A
1236 m_jit.setupArguments(value);
1237 return appendCallSetResult(operation, result);
6fe7ccc8 1238 }
81345200 1239 JITCompiler::Call callOperation(Q_JITOperation_D operation, GPRReg result, FPRReg value)
6fe7ccc8 1240 {
81345200
A
1241 m_jit.setupArguments(value);
1242 return appendCallSetResult(operation, result);
6fe7ccc8 1243 }
81345200 1244 JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg result, StringImpl* uid)
93a37866 1245 {
81345200 1246 m_jit.setupArgumentsWithExecState(TrustedImmPtr(uid));
93a37866
A
1247 return appendCallWithExceptionCheckSetResult(operation, result);
1248 }
81345200 1249 JITCompiler::Call callOperation(J_JITOperation_EA operation, GPRReg result, GPRReg arg1)
93a37866 1250 {
81345200 1251 m_jit.setupArgumentsWithExecState(arg1);
93a37866
A
1252 return appendCallWithExceptionCheckSetResult(operation, result);
1253 }
81345200 1254 JITCompiler::Call callOperation(J_JITOperation_EAZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
6fe7ccc8 1255 {
81345200 1256 m_jit.setupArgumentsWithExecState(arg1, arg2);
6fe7ccc8
A
1257 return appendCallWithExceptionCheckSetResult(operation, result);
1258 }
81345200 1259 JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
93a37866
A
1260 {
1261 m_jit.setupArgumentsWithExecState(arg1, arg2);
1262 return appendCallWithExceptionCheckSetResult(operation, result);
1263 }
81345200 1264 JITCompiler::Call callOperation(J_JITOperation_EPS operation, GPRReg result, void* pointer, size_t size)
6fe7ccc8
A
1265 {
1266 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
1267 return appendCallWithExceptionCheckSetResult(operation, result);
1268 }
81345200 1269 JITCompiler::Call callOperation(J_JITOperation_ESS operation, GPRReg result, int startConstant, int numConstants)
6fe7ccc8
A
1270 {
1271 m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
1272 return appendCallWithExceptionCheckSetResult(operation, result);
1273 }
81345200 1274 JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg result, GPRReg arg1, void* pointer)
6fe7ccc8
A
1275 {
1276 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
1277 return appendCallWithExceptionCheckSetResult(operation, result);
1278 }
81345200 1279 JITCompiler::Call callOperation(J_JITOperation_EC operation, GPRReg result, JSCell* cell)
93a37866
A
1280 {
1281 m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
1282 return appendCallWithExceptionCheckSetResult(operation, result);
1283 }
81345200 1284 JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, const StringImpl* uid)
6fe7ccc8 1285 {
81345200 1286 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
6fe7ccc8
A
1287 return appendCallWithExceptionCheckSetResult(operation, result);
1288 }
81345200 1289 JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, StringImpl* uid)
6fe7ccc8 1290 {
81345200 1291 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
6fe7ccc8
A
1292 return appendCallWithExceptionCheckSetResult(operation, result);
1293 }
81345200 1294 JITCompiler::Call callOperation(J_JITOperation_EDA operation, GPRReg result, FPRReg arg1, GPRReg arg2)
93a37866
A
1295 {
1296 m_jit.setupArgumentsWithExecState(arg1, arg2);
1297 return appendCallWithExceptionCheckSetResult(operation, result);
1298 }
81345200 1299 JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg result, GPRReg arg1, GPRReg arg2)
6fe7ccc8
A
1300 {
1301 m_jit.setupArgumentsWithExecState(arg1, arg2);
1302 return appendCallWithExceptionCheckSetResult(operation, result);
1303 }
81345200 1304 JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg result, GPRReg arg1)
6fe7ccc8
A
1305 {
1306 m_jit.setupArgumentsWithExecState(arg1);
1307 return appendCallWithExceptionCheckSetResult(operation, result);
1308 }
81345200 1309 JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg result, GPRReg arg1)
6fe7ccc8 1310 {
93a37866 1311 m_jit.setupArgumentsWithExecState(arg1);
6fe7ccc8
A
1312 return appendCallWithExceptionCheckSetResult(operation, result);
1313 }
81345200 1314 JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg result, int32_t arg1)
6fe7ccc8 1315 {
93a37866 1316 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
6fe7ccc8
A
1317 return appendCallWithExceptionCheckSetResult(operation, result);
1318 }
81345200 1319 JITCompiler::Call callOperation(J_JITOperation_EZZ operation, GPRReg result, int32_t arg1, GPRReg arg2)
6fe7ccc8 1320 {
93a37866 1321 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
6fe7ccc8
A
1322 return appendCallWithExceptionCheckSetResult(operation, result);
1323 }
81345200 1324 JITCompiler::Call callOperation(J_JITOperation_EZIcfZ operation, GPRReg result, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
6fe7ccc8 1325 {
93a37866
A
1326 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
1327 return appendCallWithExceptionCheckSetResult(operation, result);
1328 }
1329
81345200
A
1330 JITCompiler::Call callOperation(P_JITOperation_EJS operation, GPRReg result, GPRReg value, size_t index)
1331 {
1332 m_jit.setupArgumentsWithExecState(value, TrustedImmPtr(index));
1333 return appendCallSetResult(operation, result);
1334 }
1335
1336 JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, Structure* structure, GPRReg arg2)
1337 {
1338 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
1339 return appendCallWithExceptionCheckSetResult(operation, result);
1340 }
93a37866 1341
81345200 1342 JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
93a37866
A
1343 {
1344 m_jit.setupArgumentsWithExecState(arg1);
6fe7ccc8
A
1345 return appendCallWithExceptionCheckSetResult(operation, result);
1346 }
81345200 1347 JITCompiler::Call callOperation(S_JITOperation_J operation, GPRReg result, GPRReg arg1)
6fe7ccc8
A
1348 {
1349 m_jit.setupArguments(arg1);
1350 return appendCallSetResult(operation, result);
1351 }
81345200 1352 JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
6fe7ccc8
A
1353 {
1354 m_jit.setupArgumentsWithExecState(arg1);
1355 return appendCallWithExceptionCheckSetResult(operation, result);
1356 }
81345200 1357 JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
93a37866
A
1358 {
1359 m_jit.setupArgumentsWithExecState(arg1);
1360 return appendCallWithExceptionCheckSetResult(operation, result);
1361 }
81345200 1362 JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
6fe7ccc8
A
1363 {
1364 m_jit.setupArgumentsWithExecState(arg1, arg2);
1365 return appendCallWithExceptionCheckSetResult(operation, result);
1366 }
93a37866 1367
81345200 1368 JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg result, GPRReg arg1, GPRReg arg2)
6fe7ccc8
A
1369 {
1370 m_jit.setupArgumentsWithExecState(arg1, arg2);
1371 return appendCallWithExceptionCheckSetResult(operation, result);
1372 }
81345200 1373 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
6fe7ccc8
A
1374 {
1375 m_jit.setupArgumentsWithExecState(arg1, arg2);
1376 return appendCallWithExceptionCheckSetResult(operation, result);
1377 }
81345200 1378 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, MacroAssembler::TrustedImm32 imm)
6fe7ccc8 1379 {
93a37866 1380 m_jit.setupArgumentsWithExecState(arg1, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))));
6fe7ccc8
A
1381 return appendCallWithExceptionCheckSetResult(operation, result);
1382 }
81345200 1383 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, MacroAssembler::TrustedImm32 imm, GPRReg arg2)
6fe7ccc8 1384 {
93a37866 1385 m_jit.setupArgumentsWithExecState(MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))), arg2);
6fe7ccc8
A
1386 return appendCallWithExceptionCheckSetResult(operation, result);
1387 }
81345200 1388 JITCompiler::Call callOperation(J_JITOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
6fe7ccc8
A
1389 {
1390 m_jit.setupArgumentsWithExecState(arg1, arg2);
1391 return appendCallWithExceptionCheckSetResult(operation, result);
1392 }
81345200 1393 JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
6fe7ccc8
A
1394 {
1395 m_jit.setupArgumentsWithExecState(arg1, arg2);
1396 return appendCallWithExceptionCheckSetResult(operation, result);
1397 }
81345200
A
1398 JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg result, GPRReg arg1, JSValueRegs arg2)
1399 {
1400 m_jit.setupArgumentsWithExecState(arg1, arg2.gpr());
1401 return appendCallWithExceptionCheckSetResult(operation, result);
1402 }
93a37866 1403
81345200
A
1404 JITCompiler::Call callOperation(V_JITOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3)
1405 {
1406 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1407 return appendCallWithExceptionCheck(operation);
1408 }
1409 JITCompiler::Call callOperation(V_JITOperation_EJ operation, GPRReg arg1)
1410 {
1411 m_jit.setupArgumentsWithExecState(arg1);
1412 return appendCallWithExceptionCheck(operation);
1413 }
1414 JITCompiler::Call callOperation(V_JITOperation_EJPP operation, GPRReg arg1, GPRReg arg2, void* pointer)
6fe7ccc8
A
1415 {
1416 m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(pointer));
1417 return appendCallWithExceptionCheck(operation);
1418 }
81345200 1419 JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1, GPRReg arg2, StringImpl* uid)
6fe7ccc8 1420 {
81345200 1421 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, arg2, TrustedImmPtr(uid));
6fe7ccc8
A
1422 return appendCallWithExceptionCheck(operation);
1423 }
81345200 1424 JITCompiler::Call callOperation(V_JITOperation_EJJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
6fe7ccc8
A
1425 {
1426 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1427 return appendCallWithExceptionCheck(operation);
1428 }
81345200 1429 JITCompiler::Call callOperation(V_JITOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
6fe7ccc8
A
1430 {
1431 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1432 return appendCallWithExceptionCheck(operation);
1433 }
93a37866 1434
81345200 1435 JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
6fe7ccc8
A
1436 {
1437 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1438 return appendCallWithExceptionCheck(operation);
1439 }
81345200 1440 JITCompiler::Call callOperation(V_JITOperation_ECJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
6fe7ccc8
A
1441 {
1442 m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1443 return appendCallWithExceptionCheck(operation);
1444 }
93a37866 1445
81345200
A
1446 JITCompiler::Call callOperation(V_JITOperation_EVwsJ operation, VariableWatchpointSet* watchpointSet, GPRReg arg)
1447 {
1448 m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet), arg);
1449 return appendCall(operation);
1450 }
1451
1452 JITCompiler::Call callOperation(D_JITOperation_EJ operation, FPRReg result, GPRReg arg1)
6fe7ccc8
A
1453 {
1454 m_jit.setupArgumentsWithExecState(arg1);
1455 return appendCallWithExceptionCheckSetResult(operation, result);
1456 }
93a37866
A
1457
1458#else // USE(JSVALUE32_64)
1459
1460// 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]).
1461// To avoid assemblies from using wrong registers, let's occupy r1 or r3 with a dummy argument when necessary.
1462#if (COMPILER_SUPPORTS(EABI) && CPU(ARM)) || CPU(MIPS)
1463#define EABI_32BIT_DUMMY_ARG TrustedImm32(0),
6fe7ccc8 1464#else
93a37866
A
1465#define EABI_32BIT_DUMMY_ARG
1466#endif
1467
81345200
A
1468// JSVALUE32_64 is a 64-bit integer that cannot be put half in an argument register and half on stack when using SH4 architecture.
1469// To avoid this, let's occupy the 4th argument register (r7) with a dummy argument when necessary. This must only be done when there
1470// is no other 32-bit value argument behind this 64-bit JSValue.
1471#if CPU(SH4)
1472#define SH4_32BIT_DUMMY_ARG TrustedImm32(0),
1473#else
1474#define SH4_32BIT_DUMMY_ARG
1475#endif
1476
1477 JITCompiler::Call callOperation(Z_JITOperation_D operation, GPRReg result, FPRReg arg1)
6fe7ccc8
A
1478 {
1479 prepareForExternalCall();
1480 m_jit.setupArguments(arg1);
1481 JITCompiler::Call call = m_jit.appendCall(operation);
1482 m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1483 return call;
1484 }
81345200 1485 JITCompiler::Call callOperation(J_JITOperation_E operation, GPRReg resultTag, GPRReg resultPayload)
93a37866
A
1486 {
1487 m_jit.setupArgumentsExecState();
1488 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1489 }
81345200 1490 JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, void* pointer)
6fe7ccc8
A
1491 {
1492 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1493 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1494 }
81345200 1495 JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, void* pointer)
6fe7ccc8
A
1496 {
1497 m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
1498 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1499 }
81345200 1500 JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
6fe7ccc8 1501 {
81345200 1502 m_jit.setupArgumentsWithExecState(arg1);
6fe7ccc8
A
1503 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1504 }
81345200 1505 JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg resultTag, GPRReg resultPayload, StringImpl* uid)
6fe7ccc8 1506 {
81345200 1507 m_jit.setupArgumentsWithExecState(TrustedImmPtr(uid));
6fe7ccc8
A
1508 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1509 }
81345200 1510 JITCompiler::Call callOperation(J_JITOperation_EA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
6fe7ccc8 1511 {
81345200 1512 m_jit.setupArgumentsWithExecState(arg1);
6fe7ccc8
A
1513 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1514 }
81345200 1515 JITCompiler::Call callOperation(J_JITOperation_EAZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
6fe7ccc8 1516 {
81345200 1517 m_jit.setupArgumentsWithExecState(arg1, arg2);
6fe7ccc8
A
1518 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1519 }
81345200 1520 JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
93a37866
A
1521 {
1522 m_jit.setupArgumentsWithExecState(arg1, arg2);
1523 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1524 }
81345200 1525 JITCompiler::Call callOperation(J_JITOperation_EPS operation, GPRReg resultTag, GPRReg resultPayload, void* pointer, size_t size)
6fe7ccc8
A
1526 {
1527 m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
1528 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1529 }
81345200 1530 JITCompiler::Call callOperation(J_JITOperation_ESS operation, GPRReg resultTag, GPRReg resultPayload, int startConstant, int numConstants)
6fe7ccc8
A
1531 {
1532 m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
1533 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1534 }
81345200 1535 JITCompiler::Call callOperation(J_JITOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, void* pointer)
6fe7ccc8 1536 {
93a37866 1537 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(pointer));
6fe7ccc8
A
1538 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1539 }
81345200 1540 JITCompiler::Call callOperation(J_JITOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
6fe7ccc8 1541 {
93a37866
A
1542 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1543 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1544 }
1545
81345200 1546 JITCompiler::Call callOperation(J_JITOperation_EC operation, GPRReg resultTag, GPRReg resultPayload, JSCell* cell)
93a37866
A
1547 {
1548 m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
6fe7ccc8
A
1549 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1550 }
81345200 1551 JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1, const StringImpl* uid)
6fe7ccc8 1552 {
81345200 1553 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
6fe7ccc8
A
1554 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1555 }
81345200 1556 JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, StringImpl* uid)
6fe7ccc8 1557 {
81345200 1558 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, TrustedImmPtr(uid));
6fe7ccc8
A
1559 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1560 }
81345200 1561 JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, int32_t arg1Tag, GPRReg arg1Payload, StringImpl* uid)
6fe7ccc8 1562 {
81345200 1563 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, TrustedImm32(arg1Tag), TrustedImmPtr(uid));
93a37866
A
1564 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1565 }
81345200 1566 JITCompiler::Call callOperation(J_JITOperation_EDA operation, GPRReg resultTag, GPRReg resultPayload, FPRReg arg1, GPRReg arg2)
93a37866 1567 {
81345200 1568 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1, arg2);
6fe7ccc8
A
1569 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1570 }
81345200 1571 JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
6fe7ccc8 1572 {
93a37866 1573 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
6fe7ccc8
A
1574 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1575 }
81345200 1576 JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, TrustedImm32 arg1Tag, GPRReg arg1Payload, GPRReg arg2)
6fe7ccc8 1577 {
93a37866 1578 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
6fe7ccc8
A
1579 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1580 }
81345200 1581 JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload)
6fe7ccc8 1582 {
93a37866
A
1583 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1584 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
6fe7ccc8 1585 }
81345200 1586 JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
6fe7ccc8
A
1587 {
1588 m_jit.setupArgumentsWithExecState(arg1);
93a37866 1589 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
6fe7ccc8 1590 }
81345200 1591 JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1)
6fe7ccc8 1592 {
93a37866
A
1593 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1594 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
6fe7ccc8 1595 }
81345200 1596 JITCompiler::Call callOperation(J_JITOperation_EZIcfZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
6fe7ccc8 1597 {
93a37866
A
1598 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
1599 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1600 }
81345200 1601 JITCompiler::Call callOperation(J_JITOperation_EZZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, GPRReg arg2)
93a37866
A
1602 {
1603 m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
1604 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1605 }
1606
81345200
A
1607 JITCompiler::Call callOperation(P_JITOperation_EJS operation, GPRReg result, JSValueRegs value, size_t index)
1608 {
1609 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG value.payloadGPR(), value.tagGPR(), TrustedImmPtr(index));
1610 return appendCallSetResult(operation, result);
1611 }
1612
1613 JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, Structure* structure, GPRReg arg2Tag, GPRReg arg2Payload)
1614 {
1615 m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2Payload, arg2Tag);
1616 return appendCallWithExceptionCheckSetResult(operation, result);
1617 }
93a37866 1618
81345200 1619 JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
93a37866
A
1620 {
1621 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
6fe7ccc8
A
1622 return appendCallWithExceptionCheckSetResult(operation, result);
1623 }
81345200 1624 JITCompiler::Call callOperation(S_JITOperation_J operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
6fe7ccc8
A
1625 {
1626 m_jit.setupArguments(arg1Payload, arg1Tag);
1627 return appendCallSetResult(operation, result);
1628 }
81345200 1629 JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
6fe7ccc8 1630 {
93a37866 1631 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
6fe7ccc8
A
1632 return appendCallWithExceptionCheckSetResult(operation, result);
1633 }
93a37866 1634
81345200 1635 JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
6fe7ccc8 1636 {
81345200 1637 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
6fe7ccc8
A
1638 return appendCallWithExceptionCheckSetResult(operation, result);
1639 }
81345200 1640 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
6fe7ccc8 1641 {
81345200 1642 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
6fe7ccc8
A
1643 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1644 }
81345200 1645 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, MacroAssembler::TrustedImm32 imm)
6fe7ccc8 1646 {
81345200 1647 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag));
6fe7ccc8
A
1648 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1649 }
81345200 1650 JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, MacroAssembler::TrustedImm32 imm, GPRReg arg2Tag, GPRReg arg2Payload)
6fe7ccc8 1651 {
81345200 1652 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag), SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
6fe7ccc8
A
1653 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1654 }
93a37866 1655
81345200 1656 JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload)
93a37866 1657 {
81345200 1658 m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
93a37866
A
1659 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1660 }
81345200
A
1661 JITCompiler::Call callOperation(J_JITOperation_ECJ operation, JSValueRegs result, GPRReg arg1, JSValueRegs arg2)
1662 {
1663 m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR());
1664 return appendCallWithExceptionCheckSetResult(operation, result.payloadGPR(), result.tagGPR());
1665 }
1666 JITCompiler::Call callOperation(J_JITOperation_ECC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
93a37866 1667 {
81345200 1668 m_jit.setupArgumentsWithExecState(arg1, arg2);
93a37866
A
1669 return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1670 }
1671
81345200 1672 JITCompiler::Call callOperation(V_JITOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3)
6fe7ccc8 1673 {
81345200
A
1674 m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3);
1675 return appendCallWithExceptionCheck(operation);
6fe7ccc8 1676 }
81345200
A
1677
1678 JITCompiler::Call callOperation(V_JITOperation_EJ operation, GPRReg arg1Tag, GPRReg arg1Payload)
6fe7ccc8 1679 {
81345200
A
1680 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1681 return appendCallWithExceptionCheck(operation);
6fe7ccc8 1682 }
93a37866 1683
81345200 1684 JITCompiler::Call callOperation(V_JITOperation_EJPP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, void* pointer)
6fe7ccc8 1685 {
93a37866 1686 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(pointer));
6fe7ccc8
A
1687 return appendCallWithExceptionCheck(operation);
1688 }
81345200 1689 JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Payload, StringImpl* uid)
6fe7ccc8 1690 {
81345200 1691 m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, arg2Payload, TrustedImm32(JSValue::CellTag), TrustedImmPtr(uid));
6fe7ccc8
A
1692 return appendCallWithExceptionCheck(operation);
1693 }
81345200 1694 JITCompiler::Call callOperation(V_JITOperation_ECJJ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
6fe7ccc8
A
1695 {
1696 m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, arg3Payload, arg3Tag);
1697 return appendCallWithExceptionCheck(operation);
1698 }
93a37866 1699
81345200 1700 JITCompiler::Call callOperation(V_JITOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
6fe7ccc8 1701 {
81345200 1702 m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
6fe7ccc8
A
1703 return appendCallWithExceptionCheck(operation);
1704 }
93a37866 1705
81345200 1706 JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
93a37866 1707 {
81345200 1708 m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
93a37866
A
1709 return appendCallWithExceptionCheck(operation);
1710 }
81345200 1711 JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, TrustedImm32 arg3Tag, GPRReg arg3Payload)
6fe7ccc8 1712 {
81345200 1713 m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
6fe7ccc8
A
1714 return appendCallWithExceptionCheck(operation);
1715 }
1716
81345200
A
1717 JITCompiler::Call callOperation(V_JITOperation_EVwsJ operation, VariableWatchpointSet* watchpointSet, GPRReg argTag, GPRReg argPayload)
1718 {
1719 m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet), argPayload, argTag);
1720 return appendCall(operation);
1721 }
1722
1723 JITCompiler::Call callOperation(D_JITOperation_EJ operation, FPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
6fe7ccc8 1724 {
93a37866 1725 m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
6fe7ccc8
A
1726 return appendCallWithExceptionCheckSetResult(operation, result);
1727 }
1728
93a37866 1729#undef EABI_32BIT_DUMMY_ARG
81345200 1730#undef SH4_32BIT_DUMMY_ARG
93a37866
A
1731
1732 template<typename FunctionType>
1733 JITCompiler::Call callOperation(
1734 FunctionType operation, JSValueRegs result)
6fe7ccc8 1735 {
93a37866 1736 return callOperation(operation, result.tagGPR(), result.payloadGPR());
6fe7ccc8 1737 }
93a37866
A
1738 template<typename FunctionType, typename ArgumentType1>
1739 JITCompiler::Call callOperation(
1740 FunctionType operation, JSValueRegs result, ArgumentType1 arg1)
6fe7ccc8 1741 {
93a37866 1742 return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1);
6fe7ccc8 1743 }
93a37866
A
1744 template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
1745 JITCompiler::Call callOperation(
1746 FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2)
1747 {
1748 return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2);
1749 }
1750 template<
1751 typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1752 typename ArgumentType3>
1753 JITCompiler::Call callOperation(
1754 FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1755 ArgumentType3 arg3)
1756 {
1757 return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3);
1758 }
1759 template<
1760 typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1761 typename ArgumentType3, typename ArgumentType4>
1762 JITCompiler::Call callOperation(
1763 FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1764 ArgumentType3 arg3, ArgumentType4 arg4)
1765 {
1766 return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4);
1767 }
1768 template<
1769 typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1770 typename ArgumentType3, typename ArgumentType4, typename ArgumentType5>
1771 JITCompiler::Call callOperation(
1772 FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1773 ArgumentType3 arg3, ArgumentType4 arg4, ArgumentType5 arg5)
1774 {
1775 return callOperation(
1776 operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4, arg5);
1777 }
1778#endif // USE(JSVALUE32_64)
6fe7ccc8 1779
81345200 1780#if !defined(NDEBUG) && !CPU(ARM) && !CPU(MIPS) && !CPU(SH4)
6fe7ccc8
A
1781 void prepareForExternalCall()
1782 {
93a37866
A
1783 // We're about to call out to a "native" helper function. The helper
1784 // function is expected to set topCallFrame itself with the ExecState
1785 // that is passed to it.
1786 //
1787 // We explicitly trash topCallFrame here so that we'll know if some of
1788 // the helper functions are not setting topCallFrame when they should
1789 // be doing so. Note: the previous value in topcallFrame was not valid
1790 // anyway since it was not being updated by JIT'ed code by design.
1791
6fe7ccc8 1792 for (unsigned i = 0; i < sizeof(void*) / 4; i++)
93a37866 1793 m_jit.store32(TrustedImm32(0xbadbeef), reinterpret_cast<char*>(&m_jit.vm()->topCallFrame) + i * 4);
6fe7ccc8
A
1794 }
1795#else
1796 void prepareForExternalCall() { }
1797#endif
1798
1799 // These methods add call instructions, with optional exception checks & setting results.
1800 JITCompiler::Call appendCallWithExceptionCheck(const FunctionPtr& function)
1801 {
1802 prepareForExternalCall();
81345200
A
1803 m_jit.emitStoreCodeOrigin(m_currentNode->origin.semantic);
1804 JITCompiler::Call call = m_jit.appendCall(function);
1805 m_jit.exceptionCheck();
1806 return call;
1807 }
1808 JITCompiler::Call appendCallWithCallFrameRollbackOnException(const FunctionPtr& function)
1809 {
1810 prepareForExternalCall();
1811 m_jit.emitStoreCodeOrigin(m_currentNode->origin.semantic);
6fe7ccc8 1812 JITCompiler::Call call = m_jit.appendCall(function);
81345200 1813 m_jit.exceptionCheckWithCallFrameRollback();
6fe7ccc8
A
1814 return call;
1815 }
1816 JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result)
1817 {
1818 JITCompiler::Call call = appendCallWithExceptionCheck(function);
81345200
A
1819 if ((result != InvalidGPRReg) && (result != GPRInfo::returnValueGPR))
1820 m_jit.move(GPRInfo::returnValueGPR, result);
1821 return call;
1822 }
1823 JITCompiler::Call appendCallWithCallFrameRollbackOnExceptionSetResult(const FunctionPtr& function, GPRReg result)
1824 {
1825 JITCompiler::Call call = appendCallWithCallFrameRollbackOnException(function);
1826 if ((result != InvalidGPRReg) && (result != GPRInfo::returnValueGPR))
1827 m_jit.move(GPRInfo::returnValueGPR, result);
6fe7ccc8
A
1828 return call;
1829 }
1830 JITCompiler::Call appendCallSetResult(const FunctionPtr& function, GPRReg result)
1831 {
1832 prepareForExternalCall();
81345200 1833 m_jit.emitStoreCodeOrigin(m_currentNode->origin.semantic);
6fe7ccc8 1834 JITCompiler::Call call = m_jit.appendCall(function);
81345200
A
1835 if (result != InvalidGPRReg)
1836 m_jit.move(GPRInfo::returnValueGPR, result);
6fe7ccc8
A
1837 return call;
1838 }
93a37866
A
1839 JITCompiler::Call appendCall(const FunctionPtr& function)
1840 {
1841 prepareForExternalCall();
81345200 1842 m_jit.emitStoreCodeOrigin(m_currentNode->origin.semantic);
93a37866
A
1843 return m_jit.appendCall(function);
1844 }
6fe7ccc8
A
1845 JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result1, GPRReg result2)
1846 {
1847 JITCompiler::Call call = appendCallWithExceptionCheck(function);
1848 m_jit.setupResults(result1, result2);
1849 return call;
1850 }
1851#if CPU(X86)
1852 JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
1853 {
1854 JITCompiler::Call call = appendCallWithExceptionCheck(function);
81345200
A
1855 if (result != InvalidFPRReg) {
1856 m_jit.assembler().fstpl(0, JITCompiler::stackPointerRegister);
1857 m_jit.loadDouble(JITCompiler::stackPointerRegister, result);
1858 }
6fe7ccc8
A
1859 return call;
1860 }
1861 JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1862 {
81345200
A
1863 JITCompiler::Call call = appendCall(function);
1864 if (result != InvalidFPRReg) {
1865 m_jit.assembler().fstpl(0, JITCompiler::stackPointerRegister);
1866 m_jit.loadDouble(JITCompiler::stackPointerRegister, result);
1867 }
6fe7ccc8
A
1868 return call;
1869 }
81345200 1870#elif CPU(ARM) && !CPU(ARM_HARDFP)
6fe7ccc8 1871 JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
93a37866
A
1872 {
1873 JITCompiler::Call call = appendCallWithExceptionCheck(function);
81345200
A
1874 if (result != InvalidFPRReg)
1875 m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
6fe7ccc8
A
1876 return call;
1877 }
1878 JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1879 {
81345200
A
1880 JITCompiler::Call call = appendCall(function);
1881 if (result != InvalidFPRReg)
1882 m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
6fe7ccc8
A
1883 return call;
1884 }
81345200 1885#else // CPU(X86_64) || (CPU(ARM) && CPU(ARM_HARDFP)) || CPU(ARM64) || CPU(MIPS) || CPU(SH4)
6fe7ccc8
A
1886 JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
1887 {
1888 JITCompiler::Call call = appendCallWithExceptionCheck(function);
81345200
A
1889 if (result != InvalidFPRReg)
1890 m_jit.moveDouble(FPRInfo::returnValueFPR, result);
6fe7ccc8
A
1891 return call;
1892 }
1893 JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1894 {
81345200
A
1895 JITCompiler::Call call = appendCall(function);
1896 if (result != InvalidFPRReg)
1897 m_jit.moveDouble(FPRInfo::returnValueFPR, result);
6fe7ccc8
A
1898 return call;
1899 }
1900#endif
1901
81345200 1902 void branchDouble(JITCompiler::DoubleCondition cond, FPRReg left, FPRReg right, BasicBlock* destination)
6fe7ccc8 1903 {
81345200 1904 return addBranch(m_jit.branchDouble(cond, left, right), destination);
6fe7ccc8
A
1905 }
1906
81345200 1907 void branchDoubleNonZero(FPRReg value, FPRReg scratch, BasicBlock* destination)
6fe7ccc8 1908 {
81345200 1909 return addBranch(m_jit.branchDoubleNonZero(value, scratch), destination);
6fe7ccc8
A
1910 }
1911
1912 template<typename T, typename U>
81345200 1913 void branch32(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
6fe7ccc8 1914 {
81345200 1915 return addBranch(m_jit.branch32(cond, left, right), destination);
6fe7ccc8
A
1916 }
1917
1918 template<typename T, typename U>
81345200 1919 void branchTest32(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
6fe7ccc8 1920 {
81345200 1921 return addBranch(m_jit.branchTest32(cond, value, mask), destination);
6fe7ccc8
A
1922 }
1923
1924 template<typename T>
81345200 1925 void branchTest32(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
6fe7ccc8 1926 {
81345200 1927 return addBranch(m_jit.branchTest32(cond, value), destination);
6fe7ccc8
A
1928 }
1929
93a37866
A
1930#if USE(JSVALUE64)
1931 template<typename T, typename U>
81345200 1932 void branch64(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
93a37866 1933 {
81345200 1934 return addBranch(m_jit.branch64(cond, left, right), destination);
93a37866
A
1935 }
1936#endif
1937
6fe7ccc8 1938 template<typename T, typename U>
81345200 1939 void branch8(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
6fe7ccc8 1940 {
81345200 1941 return addBranch(m_jit.branch8(cond, left, right), destination);
6fe7ccc8
A
1942 }
1943
1944 template<typename T, typename U>
81345200 1945 void branchPtr(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
6fe7ccc8 1946 {
81345200
A
1947 return addBranch(m_jit.branchPtr(cond, left, right), destination);
1948 }
1949
1950 template<typename T, typename U>
1951 void branchTestPtr(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
1952 {
1953 return addBranch(m_jit.branchTestPtr(cond, value, mask), destination);
6fe7ccc8
A
1954 }
1955
1956 template<typename T>
81345200 1957 void branchTestPtr(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
6fe7ccc8 1958 {
81345200 1959 return addBranch(m_jit.branchTestPtr(cond, value), destination);
6fe7ccc8
A
1960 }
1961
1962 template<typename T, typename U>
81345200 1963 void branchTest8(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
6fe7ccc8 1964 {
81345200 1965 return addBranch(m_jit.branchTest8(cond, value, mask), destination);
6fe7ccc8
A
1966 }
1967
1968 template<typename T>
81345200 1969 void branchTest8(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
6fe7ccc8 1970 {
81345200 1971 return addBranch(m_jit.branchTest8(cond, value), destination);
6fe7ccc8
A
1972 }
1973
1974 enum FallThroughMode {
1975 AtFallThroughPoint,
1976 ForceJump
1977 };
81345200 1978 void jump(BasicBlock* destination, FallThroughMode fallThroughMode = AtFallThroughPoint)
6fe7ccc8 1979 {
93a37866 1980 if (destination == nextBlock()
6fe7ccc8
A
1981 && fallThroughMode == AtFallThroughPoint)
1982 return;
1983 addBranch(m_jit.jump(), destination);
1984 }
1985
81345200 1986 void addBranch(const MacroAssembler::Jump& jump, BasicBlock* destination)
6fe7ccc8
A
1987 {
1988 m_branches.append(BranchRecord(jump, destination));
1989 }
81345200 1990 void addBranch(const MacroAssembler::JumpList& jump, BasicBlock* destination);
6fe7ccc8 1991
81345200 1992 void linkBranches();
6fe7ccc8 1993
6fe7ccc8 1994 void dump(const char* label = 0);
6fe7ccc8 1995
93a37866 1996 bool isInteger(Node* node)
6fe7ccc8 1997 {
93a37866 1998 if (node->hasInt32Result())
6fe7ccc8
A
1999 return true;
2000
93a37866 2001 if (isInt32Constant(node))
6fe7ccc8
A
2002 return true;
2003
81345200 2004 return generationInfo(node).isJSInt32();
6fe7ccc8
A
2005 }
2006
81345200
A
2007 bool betterUseStrictInt52(Node* node)
2008 {
2009 return !generationInfo(node).isInt52();
2010 }
2011 bool betterUseStrictInt52(Edge edge)
2012 {
2013 return betterUseStrictInt52(edge.node());
2014 }
2015
2016 bool compare(Node*, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_JITOperation_EJJ);
2017 bool compilePeepHoleBranch(Node*, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_JITOperation_EJJ);
2018 void compilePeepHoleInt32Branch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
2019 void compilePeepHoleInt52Branch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
93a37866
A
2020 void compilePeepHoleBooleanBranch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
2021 void compilePeepHoleDoubleBranch(Node*, Node* branchNode, JITCompiler::DoubleCondition);
2022 void compilePeepHoleObjectEquality(Node*, Node* branchNode);
2023 void compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode);
2024 void compileObjectEquality(Node*);
2025 void compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild);
93a37866
A
2026 void compileObjectOrOtherLogicalNot(Edge value);
2027 void compileLogicalNot(Node*);
81345200
A
2028 void compileStringEquality(
2029 Node*, GPRReg leftGPR, GPRReg rightGPR, GPRReg lengthGPR,
2030 GPRReg leftTempGPR, GPRReg rightTempGPR, GPRReg leftTemp2GPR,
2031 GPRReg rightTemp2GPR, JITCompiler::JumpList fastTrue,
2032 JITCompiler::JumpList fastSlow);
93a37866 2033 void compileStringEquality(Node*);
81345200
A
2034 void compileStringIdentEquality(Node*);
2035 void compileStringToUntypedEquality(Node*, Edge stringEdge, Edge untypedEdge);
2036 void compileStringIdentToNotStringVarEquality(Node*, Edge stringEdge, Edge notStringVarEdge);
2037 void compileStringZeroLength(Node*);
2038 void compileMiscStrictEq(Node*);
2039
2040 void emitObjectOrOtherBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
93a37866
A
2041 void emitBranch(Node*);
2042
81345200
A
2043 struct StringSwitchCase {
2044 StringSwitchCase() { }
2045
2046 StringSwitchCase(StringImpl* string, BasicBlock* target)
2047 : string(string)
2048 , target(target)
2049 {
2050 }
2051
2052 bool operator<(const StringSwitchCase& other) const;
2053
2054 StringImpl* string;
2055 BasicBlock* target;
2056 };
2057
2058 void emitSwitchIntJump(SwitchData*, GPRReg value, GPRReg scratch);
2059 void emitSwitchImm(Node*, SwitchData*);
2060 void emitSwitchCharStringJump(SwitchData*, GPRReg value, GPRReg scratch);
2061 void emitSwitchChar(Node*, SwitchData*);
2062 void emitBinarySwitchStringRecurse(
2063 SwitchData*, const Vector<StringSwitchCase>&, unsigned numChecked,
2064 unsigned begin, unsigned end, GPRReg buffer, GPRReg length, GPRReg temp,
2065 unsigned alreadyCheckedLength, bool checkedExactLength);
2066 void emitSwitchStringOnString(SwitchData*, GPRReg string);
2067 void emitSwitchString(Node*, SwitchData*);
2068 void emitSwitch(Node*);
2069
2070 void compileToStringOnCell(Node*);
2071 void compileNewStringObject(Node*);
2072
2073 void compileNewTypedArray(Node*);
93a37866 2074
81345200
A
2075 void compileInt32Compare(Node*, MacroAssembler::RelationalCondition);
2076 void compileInt52Compare(Node*, MacroAssembler::RelationalCondition);
93a37866
A
2077 void compileBooleanCompare(Node*, MacroAssembler::RelationalCondition);
2078 void compileDoubleCompare(Node*, MacroAssembler::DoubleCondition);
2079
93a37866
A
2080 bool compileStrictEq(Node*);
2081
2082 void compileAllocatePropertyStorage(Node*);
2083 void compileReallocatePropertyStorage(Node*);
2084
2085#if USE(JSVALUE32_64)
2086 template<typename BaseOperandType, typename PropertyOperandType, typename ValueOperandType, typename TagType>
2087 void compileContiguousPutByVal(Node*, BaseOperandType&, PropertyOperandType&, ValueOperandType&, GPRReg valuePayloadReg, TagType valueTag);
6fe7ccc8 2088#endif
93a37866
A
2089 void compileDoublePutByVal(Node*, SpeculateCellOperand& base, SpeculateStrictInt32Operand& property);
2090 bool putByValWillNeedExtraRegister(ArrayMode arrayMode)
6fe7ccc8 2091 {
93a37866
A
2092 return arrayMode.mayStoreToHole();
2093 }
2094 GPRReg temporaryRegisterForPutByVal(GPRTemporary&, ArrayMode);
2095 GPRReg temporaryRegisterForPutByVal(GPRTemporary& temporary, Node* node)
2096 {
2097 return temporaryRegisterForPutByVal(temporary, node->arrayMode());
2098 }
2099
2100 void compileGetCharCodeAt(Node*);
2101 void compileGetByValOnString(Node*);
2102 void compileFromCharCode(Node*);
6fe7ccc8 2103
93a37866
A
2104 void compileGetByValOnArguments(Node*);
2105 void compileGetArgumentsLength(Node*);
2106
2107 void compileGetArrayLength(Node*);
2108
81345200
A
2109 void compileValueRep(Node*);
2110 void compileDoubleRep(Node*);
2111
93a37866
A
2112 void compileValueToInt32(Node*);
2113 void compileUInt32ToNumber(Node*);
2114 void compileDoubleAsInt32(Node*);
93a37866
A
2115 void compileAdd(Node*);
2116 void compileMakeRope(Node*);
2117 void compileArithSub(Node*);
2118 void compileArithNegate(Node*);
2119 void compileArithMul(Node*);
81345200 2120 void compileArithDiv(Node*);
93a37866 2121 void compileArithMod(Node*);
81345200 2122 void compileConstantStoragePointer(Node*);
93a37866 2123 void compileGetIndexedPropertyStorage(Node*);
81345200
A
2124 JITCompiler::Jump jumpForTypedArrayOutOfBounds(Node*, GPRReg baseGPR, GPRReg indexGPR);
2125 void emitTypedArrayBoundsCheck(Node*, GPRReg baseGPR, GPRReg indexGPR);
2126 void compileGetTypedArrayByteOffset(Node*);
2127 void compileGetByValOnIntTypedArray(Node*, TypedArrayType);
2128 void compilePutByValForIntTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
2129 void compileGetByValOnFloatTypedArray(Node*, TypedArrayType);
2130 void compilePutByValForFloatTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
93a37866
A
2131 void compileNewFunctionNoCheck(Node*);
2132 void compileNewFunctionExpression(Node*);
2133 bool compileRegExpExec(Node*);
2134
81345200
A
2135 JITCompiler::Jump branchIsCell(JSValueRegs);
2136 JITCompiler::Jump branchNotCell(JSValueRegs);
2137 JITCompiler::Jump branchIsOther(JSValueRegs, GPRReg tempGPR);
2138 JITCompiler::Jump branchNotOther(JSValueRegs, GPRReg tempGPR);
2139
2140 void moveTrueTo(GPRReg);
2141 void moveFalseTo(GPRReg);
2142 void blessBoolean(GPRReg);
2143
93a37866
A
2144 // size can be an immediate or a register, and must be in bytes. If size is a register,
2145 // it must be a different register than resultGPR. Emits code that place a pointer to
2146 // the end of the allocation. The returned jump is the jump to the slow path.
2147 template<typename SizeType>
2148 MacroAssembler::Jump emitAllocateBasicStorage(SizeType size, GPRReg resultGPR)
2149 {
2150 CopiedAllocator* copiedAllocator = &m_jit.vm()->heap.storageAllocator();
81345200
A
2151
2152 // It's invalid to allocate zero bytes in CopiedSpace.
2153#ifndef NDEBUG
2154 m_jit.move(size, resultGPR);
2155 MacroAssembler::Jump nonZeroSize = m_jit.branchTest32(MacroAssembler::NonZero, resultGPR);
2156 m_jit.abortWithReason(DFGBasicStorageAllocatorZeroSize);
2157 nonZeroSize.link(&m_jit);
2158#endif
2159
93a37866
A
2160 m_jit.loadPtr(&copiedAllocator->m_currentRemaining, resultGPR);
2161 MacroAssembler::Jump slowPath = m_jit.branchSubPtr(JITCompiler::Signed, size, resultGPR);
2162 m_jit.storePtr(resultGPR, &copiedAllocator->m_currentRemaining);
2163 m_jit.negPtr(resultGPR);
2164 m_jit.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), resultGPR);
2165
2166 return slowPath;
2167 }
81345200 2168
93a37866
A
2169 // Allocator for a cell of a specific size.
2170 template <typename StructureType> // StructureType can be GPR or ImmPtr.
2171 void emitAllocateJSCell(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure,
2172 GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
2173 {
2174 m_jit.loadPtr(MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()), resultGPR);
6fe7ccc8
A
2175 slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR));
2176
2177 // The object is half-allocated: we have what we know is a fresh object, but
2178 // it's still on the GC's free list.
6fe7ccc8 2179 m_jit.loadPtr(MacroAssembler::Address(resultGPR), scratchGPR);
93a37866
A
2180 m_jit.storePtr(scratchGPR, MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()));
2181
2182 // Initialize the object's Structure.
81345200 2183 m_jit.emitStoreStructureWithTypeInfo(structure, resultGPR, scratchGPR);
93a37866
A
2184 }
2185
2186 // Allocator for an object of a specific size.
2187 template <typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
2188 void emitAllocateJSObject(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure,
2189 StorageType storage, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
2190 {
2191 emitAllocateJSCell(resultGPR, allocatorGPR, structure, scratchGPR, slowPath);
6fe7ccc8
A
2192
2193 // Initialize the object's property storage pointer.
93a37866 2194 m_jit.storePtr(storage, MacroAssembler::Address(resultGPR, JSObject::butterflyOffset()));
6fe7ccc8
A
2195 }
2196
81345200 2197 // Convenience allocator for a built-in object.
93a37866
A
2198 template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
2199 void emitAllocateJSObject(GPRReg resultGPR, StructureType structure, StorageType storage,
2200 GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
6fe7ccc8 2201 {
93a37866
A
2202 MarkedAllocator* allocator = 0;
2203 size_t size = ClassType::allocationSize(0);
2204 if (ClassType::needsDestruction && ClassType::hasImmortalStructure)
2205 allocator = &m_jit.vm()->heap.allocatorForObjectWithImmortalStructureDestructor(size);
2206 else if (ClassType::needsDestruction)
2207 allocator = &m_jit.vm()->heap.allocatorForObjectWithNormalDestructor(size);
2208 else
2209 allocator = &m_jit.vm()->heap.allocatorForObjectWithoutDestructor(size);
2210 m_jit.move(TrustedImmPtr(allocator), scratchGPR1);
2211 emitAllocateJSObject(resultGPR, scratchGPR1, structure, storage, scratchGPR2, slowPath);
6fe7ccc8
A
2212 }
2213
81345200
A
2214 template <typename T>
2215 void emitAllocateDestructibleObject(GPRReg resultGPR, Structure* structure,
2216 GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
2217 {
2218 emitAllocateJSObject<T>(resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR1, scratchGPR2, slowPath);
2219 m_jit.storePtr(TrustedImmPtr(structure->classInfo()), MacroAssembler::Address(resultGPR, JSDestructibleObject::classInfoOffset()));
2220 }
93a37866 2221
81345200
A
2222 void emitAllocateJSArray(GPRReg resultGPR, Structure*, GPRReg storageGPR, unsigned numElements);
2223 void emitAllocateArguments(GPRReg resultGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath);
6fe7ccc8 2224
81345200 2225 // Add a speculation check.
93a37866 2226 void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);
93a37866 2227 void speculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail);
81345200
A
2228
2229 // Add a speculation check without additional recovery, and with a promise to supply a jump later.
2230 OSRExitJumpPlaceholder speculationCheck(ExitKind, JSValueSource, Node*);
2231 OSRExitJumpPlaceholder speculationCheck(ExitKind, JSValueSource, Edge);
2232 void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail);
93a37866 2233 void speculationCheck(ExitKind, JSValueSource, Edge, const MacroAssembler::JumpList& jumpsToFail);
6fe7ccc8 2234 // Add a speculation check with additional recovery.
93a37866
A
2235 void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
2236 void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
81345200
A
2237
2238 void emitInvalidationPoint(Node*);
2239
6fe7ccc8 2240 // Called when we statically determine that a speculation will fail.
93a37866
A
2241 void terminateSpeculativeExecution(ExitKind, JSValueRegs, Node*);
2242 void terminateSpeculativeExecution(ExitKind, JSValueRegs, Edge);
2243
2244 // Helpers for performing type checks on an edge stored in the given registers.
81345200 2245 bool needsTypeCheck(Edge edge, SpeculatedType typesPassedThrough) { return m_interpreter.needsTypeCheck(edge, typesPassedThrough); }
93a37866 2246 void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
81345200 2247
93a37866 2248 void speculateInt32(Edge);
81345200
A
2249#if USE(JSVALUE64)
2250 void convertMachineInt(Edge, GPRReg resultGPR);
2251 void speculateMachineInt(Edge);
2252 void speculateDoubleRepMachineInt(Edge);
2253#endif // USE(JSVALUE64)
93a37866 2254 void speculateNumber(Edge);
81345200 2255 void speculateDoubleReal(Edge);
93a37866
A
2256 void speculateBoolean(Edge);
2257 void speculateCell(Edge);
2258 void speculateObject(Edge);
81345200 2259 void speculateFinalObject(Edge);
93a37866 2260 void speculateObjectOrOther(Edge);
81345200
A
2261 void speculateString(Edge edge, GPRReg cell);
2262 void speculateStringIdentAndLoadStorage(Edge edge, GPRReg string, GPRReg storage);
2263 void speculateStringIdent(Edge edge, GPRReg string);
2264 void speculateStringIdent(Edge);
93a37866 2265 void speculateString(Edge);
81345200 2266 void speculateNotStringVar(Edge);
93a37866
A
2267 template<typename StructureLocationType>
2268 void speculateStringObjectForStructure(Edge, StructureLocationType);
2269 void speculateStringObject(Edge, GPRReg);
2270 void speculateStringObject(Edge);
2271 void speculateStringOrStringObject(Edge);
2272 void speculateNotCell(Edge);
2273 void speculateOther(Edge);
81345200
A
2274 void speculateMisc(Edge, JSValueRegs);
2275 void speculateMisc(Edge);
93a37866
A
2276 void speculate(Node*, Edge);
2277
93a37866
A
2278 JITCompiler::Jump jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode, IndexingType);
2279 JITCompiler::JumpList jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode);
2280 void checkArray(Node*);
2281 void arrayify(Node*, GPRReg baseReg, GPRReg propertyReg);
2282 void arrayify(Node*);
6fe7ccc8
A
2283
2284 template<bool strict>
81345200 2285 GPRReg fillSpeculateInt32Internal(Edge, DataFormat& returnFormat);
6fe7ccc8
A
2286
2287 // It is possible, during speculative generation, to reach a situation in which we
2288 // can statically determine a speculation will fail (for example, when two nodes
2289 // will make conflicting speculations about the same operand). In such cases this
2290 // flag is cleared, indicating no further code generation should take place.
2291 bool m_compileOkay;
2292
81345200
A
2293 void recordSetLocal(
2294 VirtualRegister bytecodeReg, VirtualRegister machineReg, DataFormat format)
6fe7ccc8 2295 {
81345200 2296 m_stream->appendAndLog(VariableEvent::setLocal(bytecodeReg, machineReg, format));
6fe7ccc8
A
2297 }
2298
81345200 2299 void recordSetLocal(DataFormat format)
6fe7ccc8 2300 {
81345200
A
2301 VariableAccessData* variable = m_currentNode->variableAccessData();
2302 recordSetLocal(variable->local(), variable->machineLocal(), format);
6fe7ccc8 2303 }
81345200
A
2304
2305 GenerationInfo& generationInfoFromVirtualRegister(VirtualRegister virtualRegister)
6fe7ccc8 2306 {
81345200 2307 return m_generationInfo[virtualRegister.toLocal()];
6fe7ccc8
A
2308 }
2309
81345200 2310 GenerationInfo& generationInfo(Node* node)
93a37866 2311 {
81345200 2312 return generationInfoFromVirtualRegister(node->virtualRegister());
93a37866
A
2313 }
2314
81345200
A
2315 GenerationInfo& generationInfo(Edge edge)
2316 {
2317 return generationInfo(edge.node());
2318 }
2319
6fe7ccc8
A
2320 // The JIT, while also provides MacroAssembler functionality.
2321 JITCompiler& m_jit;
93a37866 2322
6fe7ccc8 2323 // The current node being generated.
81345200 2324 BasicBlock* m_block;
93a37866 2325 Node* m_currentNode;
81345200 2326 NodeType m_lastGeneratedNode;
93a37866 2327 bool m_canExit;
6fe7ccc8
A
2328 unsigned m_indexInBlock;
2329 // Virtual and physical register maps.
2330 Vector<GenerationInfo, 32> m_generationInfo;
2331 RegisterBank<GPRInfo> m_gprs;
2332 RegisterBank<FPRInfo> m_fprs;
2333
6fe7ccc8
A
2334 Vector<MacroAssembler::Label> m_osrEntryHeads;
2335
2336 struct BranchRecord {
81345200 2337 BranchRecord(MacroAssembler::Jump jump, BasicBlock* destination)
6fe7ccc8
A
2338 : jump(jump)
2339 , destination(destination)
2340 {
2341 }
2342
2343 MacroAssembler::Jump jump;
81345200 2344 BasicBlock* destination;
6fe7ccc8
A
2345 };
2346 Vector<BranchRecord, 8> m_branches;
2347
81345200
A
2348 CodeOrigin m_codeOriginForExitTarget;
2349 CodeOrigin m_codeOriginForExitProfile;
6fe7ccc8 2350
81345200
A
2351 InPlaceAbstractState m_state;
2352 AbstractInterpreter<InPlaceAbstractState> m_interpreter;
6fe7ccc8 2353
93a37866
A
2354 VariableEventStream* m_stream;
2355 MinifiedGraph* m_minifiedGraph;
2356
2357 bool m_isCheckingArgumentTypes;
2358
2359 Vector<OwnPtr<SlowPathGenerator>, 8> m_slowPathGenerators;
2360 Vector<SilentRegisterSavePlan> m_plans;
14957cd0
A
2361};
2362
6fe7ccc8
A
2363
2364// === Operand types ===
2365//
6fe7ccc8
A
2366// These classes are used to lock the operands to a node into machine
2367// registers. These classes implement of pattern of locking a value
2368// into register at the point of construction only if it is already in
2369// registers, and otherwise loading it lazily at the point it is first
2370// used. We do so in order to attempt to avoid spilling one operand
2371// in order to make space available for another.
2372
6fe7ccc8 2373class JSValueOperand {
14957cd0 2374public:
93a37866 2375 explicit JSValueOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
6fe7ccc8 2376 : m_jit(jit)
93a37866 2377 , m_edge(edge)
6fe7ccc8
A
2378#if USE(JSVALUE64)
2379 , m_gprOrInvalid(InvalidGPRReg)
2380#elif USE(JSVALUE32_64)
2381 , m_isDouble(false)
2382#endif
14957cd0 2383 {
6fe7ccc8 2384 ASSERT(m_jit);
93a37866 2385 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
6fe7ccc8 2386#if USE(JSVALUE64)
93a37866 2387 if (jit->isFilled(node()))
6fe7ccc8
A
2388 gpr();
2389#elif USE(JSVALUE32_64)
2390 m_register.pair.tagGPR = InvalidGPRReg;
2391 m_register.pair.payloadGPR = InvalidGPRReg;
93a37866 2392 if (jit->isFilled(node()))
6fe7ccc8
A
2393 fill();
2394#endif
14957cd0
A
2395 }
2396
6fe7ccc8
A
2397 ~JSValueOperand()
2398 {
2399#if USE(JSVALUE64)
2400 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2401 m_jit->unlock(m_gprOrInvalid);
2402#elif USE(JSVALUE32_64)
2403 if (m_isDouble) {
2404 ASSERT(m_register.fpr != InvalidFPRReg);
2405 m_jit->unlock(m_register.fpr);
2406 } else {
2407 ASSERT(m_register.pair.tagGPR != InvalidGPRReg && m_register.pair.payloadGPR != InvalidGPRReg);
2408 m_jit->unlock(m_register.pair.tagGPR);
2409 m_jit->unlock(m_register.pair.payloadGPR);
2410 }
2411#endif
2412 }
93a37866
A
2413
2414 Edge edge() const
2415 {
2416 return m_edge;
2417 }
6fe7ccc8 2418
93a37866 2419 Node* node() const
6fe7ccc8 2420 {
93a37866 2421 return edge().node();
6fe7ccc8 2422 }
14957cd0 2423
6fe7ccc8
A
2424#if USE(JSVALUE64)
2425 GPRReg gpr()
14957cd0 2426 {
6fe7ccc8 2427 if (m_gprOrInvalid == InvalidGPRReg)
93a37866 2428 m_gprOrInvalid = m_jit->fillJSValue(m_edge);
6fe7ccc8 2429 return m_gprOrInvalid;
14957cd0 2430 }
6fe7ccc8 2431 JSValueRegs jsValueRegs()
14957cd0 2432 {
6fe7ccc8 2433 return JSValueRegs(gpr());
14957cd0 2434 }
6fe7ccc8
A
2435#elif USE(JSVALUE32_64)
2436 bool isDouble() { return m_isDouble; }
14957cd0 2437
6fe7ccc8
A
2438 void fill()
2439 {
2440 if (m_register.pair.tagGPR == InvalidGPRReg && m_register.pair.payloadGPR == InvalidGPRReg)
93a37866 2441 m_isDouble = !m_jit->fillJSValue(m_edge, m_register.pair.tagGPR, m_register.pair.payloadGPR, m_register.fpr);
6fe7ccc8 2442 }
14957cd0 2443
6fe7ccc8
A
2444 GPRReg tagGPR()
2445 {
2446 fill();
2447 ASSERT(!m_isDouble);
2448 return m_register.pair.tagGPR;
81345200 2449 }
14957cd0 2450
6fe7ccc8
A
2451 GPRReg payloadGPR()
2452 {
2453 fill();
2454 ASSERT(!m_isDouble);
2455 return m_register.pair.payloadGPR;
2456 }
81345200 2457
6fe7ccc8 2458 JSValueRegs jsValueRegs()
14957cd0 2459 {
6fe7ccc8
A
2460 return JSValueRegs(tagGPR(), payloadGPR());
2461 }
14957cd0 2462
81345200
A
2463 GPRReg gpr(WhichValueWord which)
2464 {
2465 return jsValueRegs().gpr(which);
2466 }
2467
6fe7ccc8
A
2468 FPRReg fpr()
2469 {
2470 fill();
2471 ASSERT(m_isDouble);
2472 return m_register.fpr;
2473 }
2474#endif
14957cd0 2475
6fe7ccc8
A
2476 void use()
2477 {
93a37866 2478 m_jit->use(node());
14957cd0
A
2479 }
2480
6fe7ccc8
A
2481private:
2482 SpeculativeJIT* m_jit;
93a37866 2483 Edge m_edge;
6fe7ccc8
A
2484#if USE(JSVALUE64)
2485 GPRReg m_gprOrInvalid;
2486#elif USE(JSVALUE32_64)
2487 union {
2488 struct {
2489 GPRReg tagGPR;
2490 GPRReg payloadGPR;
2491 } pair;
2492 FPRReg fpr;
2493 } m_register;
2494 bool m_isDouble;
2495#endif
2496};
2497
2498class StorageOperand {
2499public:
93a37866 2500 explicit StorageOperand(SpeculativeJIT* jit, Edge edge)
6fe7ccc8 2501 : m_jit(jit)
93a37866 2502 , m_edge(edge)
6fe7ccc8 2503 , m_gprOrInvalid(InvalidGPRReg)
14957cd0 2504 {
6fe7ccc8 2505 ASSERT(m_jit);
93a37866
A
2506 ASSERT(edge.useKind() == UntypedUse || edge.useKind() == KnownCellUse);
2507 if (jit->isFilled(node()))
6fe7ccc8
A
2508 gpr();
2509 }
2510
2511 ~StorageOperand()
2512 {
2513 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2514 m_jit->unlock(m_gprOrInvalid);
2515 }
2516
93a37866
A
2517 Edge edge() const
2518 {
2519 return m_edge;
2520 }
2521
2522 Node* node() const
6fe7ccc8 2523 {
93a37866 2524 return edge().node();
6fe7ccc8
A
2525 }
2526
2527 GPRReg gpr()
2528 {
2529 if (m_gprOrInvalid == InvalidGPRReg)
93a37866 2530 m_gprOrInvalid = m_jit->fillStorage(edge());
6fe7ccc8
A
2531 return m_gprOrInvalid;
2532 }
2533
2534 void use()
2535 {
93a37866 2536 m_jit->use(node());
6fe7ccc8
A
2537 }
2538
2539private:
2540 SpeculativeJIT* m_jit;
93a37866 2541 Edge m_edge;
6fe7ccc8
A
2542 GPRReg m_gprOrInvalid;
2543};
14957cd0 2544
6fe7ccc8
A
2545
2546// === Temporaries ===
2547//
2548// These classes are used to allocate temporary registers.
2549// A mechanism is provided to attempt to reuse the registers
2550// currently allocated to child nodes whose value is consumed
2551// by, and not live after, this operation.
2552
81345200
A
2553enum ReuseTag { Reuse };
2554
6fe7ccc8
A
2555class GPRTemporary {
2556public:
2557 GPRTemporary();
2558 GPRTemporary(SpeculativeJIT*);
2559 GPRTemporary(SpeculativeJIT*, GPRReg specific);
81345200
A
2560 template<typename T>
2561 GPRTemporary(SpeculativeJIT* jit, ReuseTag, T& operand)
2562 : m_jit(jit)
2563 , m_gpr(InvalidGPRReg)
2564 {
2565 if (m_jit->canReuse(operand.node()))
2566 m_gpr = m_jit->reuse(operand.gpr());
2567 else
2568 m_gpr = m_jit->allocate();
2569 }
2570 template<typename T1, typename T2>
2571 GPRTemporary(SpeculativeJIT* jit, ReuseTag, T1& op1, T2& op2)
2572 : m_jit(jit)
2573 , m_gpr(InvalidGPRReg)
2574 {
2575 if (m_jit->canReuse(op1.node()))
2576 m_gpr = m_jit->reuse(op1.gpr());
2577 else if (m_jit->canReuse(op2.node()))
2578 m_gpr = m_jit->reuse(op2.gpr());
2579 else
2580 m_gpr = m_jit->allocate();
2581 }
2582#if USE(JSVALUE32_64)
2583 GPRTemporary(SpeculativeJIT*, ReuseTag, JSValueOperand&, WhichValueWord);
6fe7ccc8 2584#endif
6fe7ccc8
A
2585
2586 void adopt(GPRTemporary&);
2587
2588 ~GPRTemporary()
2589 {
2590 if (m_jit && m_gpr != InvalidGPRReg)
2591 m_jit->unlock(gpr());
14957cd0
A
2592 }
2593
6fe7ccc8 2594 GPRReg gpr()
14957cd0 2595 {
6fe7ccc8
A
2596 return m_gpr;
2597 }
14957cd0 2598
6fe7ccc8
A
2599private:
2600 SpeculativeJIT* m_jit;
2601 GPRReg m_gpr;
2602};
2603
81345200
A
2604class JSValueRegsTemporary {
2605public:
2606 JSValueRegsTemporary();
2607 JSValueRegsTemporary(SpeculativeJIT*);
2608 ~JSValueRegsTemporary();
2609
2610 JSValueRegs regs();
2611
2612private:
2613#if USE(JSVALUE64)
2614 GPRTemporary m_gpr;
2615#else
2616 GPRTemporary m_payloadGPR;
2617 GPRTemporary m_tagGPR;
2618#endif
2619};
2620
6fe7ccc8
A
2621class FPRTemporary {
2622public:
2623 FPRTemporary(SpeculativeJIT*);
6fe7ccc8
A
2624 FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&);
2625 FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&, SpeculateDoubleOperand&);
2626#if USE(JSVALUE32_64)
2627 FPRTemporary(SpeculativeJIT*, JSValueOperand&);
2628#endif
2629
2630 ~FPRTemporary()
2631 {
2632 m_jit->unlock(fpr());
14957cd0
A
2633 }
2634
6fe7ccc8
A
2635 FPRReg fpr() const
2636 {
2637 ASSERT(m_fpr != InvalidFPRReg);
2638 return m_fpr;
2639 }
14957cd0 2640
6fe7ccc8
A
2641protected:
2642 FPRTemporary(SpeculativeJIT* jit, FPRReg lockedFPR)
2643 : m_jit(jit)
2644 , m_fpr(lockedFPR)
14957cd0 2645 {
14957cd0 2646 }
6fe7ccc8
A
2647
2648private:
2649 SpeculativeJIT* m_jit;
2650 FPRReg m_fpr;
2651};
2652
2653
2654// === Results ===
2655//
2656// These classes lock the result of a call to a C++ helper function.
2657
2658class GPRResult : public GPRTemporary {
2659public:
2660 GPRResult(SpeculativeJIT* jit)
2661 : GPRTemporary(jit, GPRInfo::returnValueGPR)
14957cd0 2662 {
14957cd0 2663 }
6fe7ccc8 2664};
14957cd0 2665
6fe7ccc8
A
2666#if USE(JSVALUE32_64)
2667class GPRResult2 : public GPRTemporary {
2668public:
2669 GPRResult2(SpeculativeJIT* jit)
2670 : GPRTemporary(jit, GPRInfo::returnValueGPR2)
14957cd0 2671 {
14957cd0 2672 }
6fe7ccc8
A
2673};
2674#endif
14957cd0 2675
6fe7ccc8
A
2676class FPRResult : public FPRTemporary {
2677public:
2678 FPRResult(SpeculativeJIT* jit)
2679 : FPRTemporary(jit, lockedResult(jit))
2680 {
2681 }
14957cd0 2682
6fe7ccc8
A
2683private:
2684 static FPRReg lockedResult(SpeculativeJIT* jit)
2685 {
2686 jit->lock(FPRInfo::returnValueFPR);
2687 return FPRInfo::returnValueFPR;
2688 }
14957cd0
A
2689};
2690
2691
2692// === Speculative Operand types ===
2693//
81345200 2694// SpeculateInt32Operand, SpeculateStrictInt32Operand and SpeculateCellOperand.
14957cd0
A
2695//
2696// These are used to lock the operands to a node into machine registers within the
6fe7ccc8
A
2697// SpeculativeJIT. The classes operate like those above, however these will
2698// perform a speculative check for a more restrictive type than we can statically
2699// determine the operand to have. If the operand does not have the requested type,
2700// a bail-out to the non-speculative path will be taken.
14957cd0 2701
81345200 2702class SpeculateInt32Operand {
14957cd0 2703public:
81345200 2704 explicit SpeculateInt32Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
14957cd0 2705 : m_jit(jit)
93a37866 2706 , m_edge(edge)
14957cd0
A
2707 , m_gprOrInvalid(InvalidGPRReg)
2708#ifndef NDEBUG
2709 , m_format(DataFormatNone)
2710#endif
2711 {
2712 ASSERT(m_jit);
93a37866
A
2713 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
2714 if (jit->isFilled(node()))
14957cd0
A
2715 gpr();
2716 }
2717
81345200 2718 ~SpeculateInt32Operand()
14957cd0
A
2719 {
2720 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2721 m_jit->unlock(m_gprOrInvalid);
2722 }
93a37866
A
2723
2724 Edge edge() const
2725 {
2726 return m_edge;
2727 }
14957cd0 2728
93a37866 2729 Node* node() const
14957cd0 2730 {
93a37866 2731 return edge().node();
14957cd0
A
2732 }
2733
2734 DataFormat format()
2735 {
2736 gpr(); // m_format is set when m_gpr is locked.
81345200 2737 ASSERT(m_format == DataFormatInt32 || m_format == DataFormatJSInt32);
14957cd0
A
2738 return m_format;
2739 }
2740
2741 GPRReg gpr()
2742 {
2743 if (m_gprOrInvalid == InvalidGPRReg)
81345200 2744 m_gprOrInvalid = m_jit->fillSpeculateInt32(edge(), m_format);
14957cd0
A
2745 return m_gprOrInvalid;
2746 }
93a37866
A
2747
2748 void use()
2749 {
2750 m_jit->use(node());
2751 }
14957cd0
A
2752
2753private:
2754 SpeculativeJIT* m_jit;
93a37866 2755 Edge m_edge;
14957cd0
A
2756 GPRReg m_gprOrInvalid;
2757 DataFormat m_format;
2758};
2759
2760class SpeculateStrictInt32Operand {
2761public:
93a37866 2762 explicit SpeculateStrictInt32Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
14957cd0 2763 : m_jit(jit)
93a37866 2764 , m_edge(edge)
14957cd0
A
2765 , m_gprOrInvalid(InvalidGPRReg)
2766 {
2767 ASSERT(m_jit);
93a37866
A
2768 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
2769 if (jit->isFilled(node()))
14957cd0
A
2770 gpr();
2771 }
2772
2773 ~SpeculateStrictInt32Operand()
2774 {
2775 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2776 m_jit->unlock(m_gprOrInvalid);
2777 }
93a37866
A
2778
2779 Edge edge() const
2780 {
2781 return m_edge;
2782 }
14957cd0 2783
93a37866 2784 Node* node() const
14957cd0 2785 {
93a37866 2786 return edge().node();
14957cd0
A
2787 }
2788
2789 GPRReg gpr()
2790 {
2791 if (m_gprOrInvalid == InvalidGPRReg)
81345200 2792 m_gprOrInvalid = m_jit->fillSpeculateInt32Strict(edge());
14957cd0
A
2793 return m_gprOrInvalid;
2794 }
6fe7ccc8
A
2795
2796 void use()
2797 {
93a37866 2798 m_jit->use(node());
6fe7ccc8 2799 }
14957cd0
A
2800
2801private:
2802 SpeculativeJIT* m_jit;
93a37866 2803 Edge m_edge;
14957cd0
A
2804 GPRReg m_gprOrInvalid;
2805};
2806
81345200
A
2807// Gives you a canonical Int52 (i.e. it's left-shifted by 16, low bits zero).
2808class SpeculateInt52Operand {
2809public:
2810 explicit SpeculateInt52Operand(SpeculativeJIT* jit, Edge edge)
2811 : m_jit(jit)
2812 , m_edge(edge)
2813 , m_gprOrInvalid(InvalidGPRReg)
2814 {
2815 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
2816 if (jit->isFilled(node()))
2817 gpr();
2818 }
2819
2820 ~SpeculateInt52Operand()
2821 {
2822 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2823 m_jit->unlock(m_gprOrInvalid);
2824 }
2825
2826 Edge edge() const
2827 {
2828 return m_edge;
2829 }
2830
2831 Node* node() const
2832 {
2833 return edge().node();
2834 }
2835
2836 GPRReg gpr()
2837 {
2838 if (m_gprOrInvalid == InvalidGPRReg)
2839 m_gprOrInvalid = m_jit->fillSpeculateInt52(edge(), DataFormatInt52);
2840 return m_gprOrInvalid;
2841 }
2842
2843 void use()
2844 {
2845 m_jit->use(node());
2846 }
2847
2848private:
2849 SpeculativeJIT* m_jit;
2850 Edge m_edge;
2851 GPRReg m_gprOrInvalid;
2852};
2853
2854// Gives you a strict Int52 (i.e. the payload is in the low 48 bits, high 16 bits are sign-extended).
2855class SpeculateStrictInt52Operand {
2856public:
2857 explicit SpeculateStrictInt52Operand(SpeculativeJIT* jit, Edge edge)
2858 : m_jit(jit)
2859 , m_edge(edge)
2860 , m_gprOrInvalid(InvalidGPRReg)
2861 {
2862 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
2863 if (jit->isFilled(node()))
2864 gpr();
2865 }
2866
2867 ~SpeculateStrictInt52Operand()
2868 {
2869 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2870 m_jit->unlock(m_gprOrInvalid);
2871 }
2872
2873 Edge edge() const
2874 {
2875 return m_edge;
2876 }
2877
2878 Node* node() const
2879 {
2880 return edge().node();
2881 }
2882
2883 GPRReg gpr()
2884 {
2885 if (m_gprOrInvalid == InvalidGPRReg)
2886 m_gprOrInvalid = m_jit->fillSpeculateInt52(edge(), DataFormatStrictInt52);
2887 return m_gprOrInvalid;
2888 }
2889
2890 void use()
2891 {
2892 m_jit->use(node());
2893 }
2894
2895private:
2896 SpeculativeJIT* m_jit;
2897 Edge m_edge;
2898 GPRReg m_gprOrInvalid;
2899};
2900
2901enum OppositeShiftTag { OppositeShift };
2902
2903class SpeculateWhicheverInt52Operand {
2904public:
2905 explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge)
2906 : m_jit(jit)
2907 , m_edge(edge)
2908 , m_gprOrInvalid(InvalidGPRReg)
2909 , m_strict(jit->betterUseStrictInt52(edge))
2910 {
2911 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
2912 if (jit->isFilled(node()))
2913 gpr();
2914 }
2915
2916 explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, const SpeculateWhicheverInt52Operand& other)
2917 : m_jit(jit)
2918 , m_edge(edge)
2919 , m_gprOrInvalid(InvalidGPRReg)
2920 , m_strict(other.m_strict)
2921 {
2922 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
2923 if (jit->isFilled(node()))
2924 gpr();
2925 }
2926
2927 explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, OppositeShiftTag, const SpeculateWhicheverInt52Operand& other)
2928 : m_jit(jit)
2929 , m_edge(edge)
2930 , m_gprOrInvalid(InvalidGPRReg)
2931 , m_strict(!other.m_strict)
2932 {
2933 RELEASE_ASSERT(edge.useKind() == Int52RepUse);
2934 if (jit->isFilled(node()))
2935 gpr();
2936 }
2937
2938 ~SpeculateWhicheverInt52Operand()
2939 {
2940 ASSERT(m_gprOrInvalid != InvalidGPRReg);
2941 m_jit->unlock(m_gprOrInvalid);
2942 }
2943
2944 Edge edge() const
2945 {
2946 return m_edge;
2947 }
2948
2949 Node* node() const
2950 {
2951 return edge().node();
2952 }
2953
2954 GPRReg gpr()
2955 {
2956 if (m_gprOrInvalid == InvalidGPRReg) {
2957 m_gprOrInvalid = m_jit->fillSpeculateInt52(
2958 edge(), m_strict ? DataFormatStrictInt52 : DataFormatInt52);
2959 }
2960 return m_gprOrInvalid;
2961 }
2962
2963 void use()
2964 {
2965 m_jit->use(node());
2966 }
2967
2968 DataFormat format() const
2969 {
2970 return m_strict ? DataFormatStrictInt52 : DataFormatInt52;
2971 }
2972
2973private:
2974 SpeculativeJIT* m_jit;
2975 Edge m_edge;
2976 GPRReg m_gprOrInvalid;
2977 bool m_strict;
2978};
2979
6fe7ccc8
A
2980class SpeculateDoubleOperand {
2981public:
81345200 2982 explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge edge)
6fe7ccc8 2983 : m_jit(jit)
93a37866 2984 , m_edge(edge)
6fe7ccc8
A
2985 , m_fprOrInvalid(InvalidFPRReg)
2986 {
2987 ASSERT(m_jit);
81345200 2988 RELEASE_ASSERT(isDouble(edge.useKind()));
93a37866 2989 if (jit->isFilled(node()))
6fe7ccc8
A
2990 fpr();
2991 }
2992
2993 ~SpeculateDoubleOperand()
2994 {
2995 ASSERT(m_fprOrInvalid != InvalidFPRReg);
2996 m_jit->unlock(m_fprOrInvalid);
2997 }
93a37866
A
2998
2999 Edge edge() const
3000 {
3001 return m_edge;
3002 }
6fe7ccc8 3003
93a37866 3004 Node* node() const
6fe7ccc8 3005 {
93a37866 3006 return edge().node();
6fe7ccc8
A
3007 }
3008
3009 FPRReg fpr()
3010 {
3011 if (m_fprOrInvalid == InvalidFPRReg)
93a37866 3012 m_fprOrInvalid = m_jit->fillSpeculateDouble(edge());
6fe7ccc8
A
3013 return m_fprOrInvalid;
3014 }
93a37866
A
3015
3016 void use()
3017 {
3018 m_jit->use(node());
3019 }
6fe7ccc8
A
3020
3021private:
3022 SpeculativeJIT* m_jit;
93a37866 3023 Edge m_edge;
6fe7ccc8
A
3024 FPRReg m_fprOrInvalid;
3025};
3026
14957cd0
A
3027class SpeculateCellOperand {
3028public:
93a37866 3029 explicit SpeculateCellOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
14957cd0 3030 : m_jit(jit)
93a37866 3031 , m_edge(edge)
14957cd0
A
3032 , m_gprOrInvalid(InvalidGPRReg)
3033 {
3034 ASSERT(m_jit);
93a37866
A
3035 if (!edge)
3036 return;
81345200 3037 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isCell(edge.useKind()));
93a37866 3038 if (jit->isFilled(node()))
14957cd0
A
3039 gpr();
3040 }
3041
3042 ~SpeculateCellOperand()
3043 {
93a37866
A
3044 if (!m_edge)
3045 return;
14957cd0
A
3046 ASSERT(m_gprOrInvalid != InvalidGPRReg);
3047 m_jit->unlock(m_gprOrInvalid);
3048 }
93a37866
A
3049
3050 Edge edge() const
3051 {
3052 return m_edge;
3053 }
14957cd0 3054
93a37866 3055 Node* node() const
14957cd0 3056 {
93a37866 3057 return edge().node();
14957cd0
A
3058 }
3059
3060 GPRReg gpr()
3061 {
93a37866 3062 ASSERT(m_edge);
14957cd0 3063 if (m_gprOrInvalid == InvalidGPRReg)
93a37866 3064 m_gprOrInvalid = m_jit->fillSpeculateCell(edge());
14957cd0
A
3065 return m_gprOrInvalid;
3066 }
6fe7ccc8
A
3067
3068 void use()
3069 {
93a37866
A
3070 ASSERT(m_edge);
3071 m_jit->use(node());
6fe7ccc8 3072 }
14957cd0
A
3073
3074private:
3075 SpeculativeJIT* m_jit;
93a37866 3076 Edge m_edge;
14957cd0
A
3077 GPRReg m_gprOrInvalid;
3078};
3079
6fe7ccc8 3080class SpeculateBooleanOperand {
14957cd0 3081public:
93a37866 3082 explicit SpeculateBooleanOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
6fe7ccc8 3083 : m_jit(jit)
93a37866 3084 , m_edge(edge)
6fe7ccc8 3085 , m_gprOrInvalid(InvalidGPRReg)
14957cd0 3086 {
6fe7ccc8 3087 ASSERT(m_jit);
93a37866
A
3088 ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse);
3089 if (jit->isFilled(node()))
6fe7ccc8 3090 gpr();
14957cd0 3091 }
6fe7ccc8
A
3092
3093 ~SpeculateBooleanOperand()
14957cd0 3094 {
6fe7ccc8
A
3095 ASSERT(m_gprOrInvalid != InvalidGPRReg);
3096 m_jit->unlock(m_gprOrInvalid);
3097 }
3098
93a37866 3099 Edge edge() const
6fe7ccc8 3100 {
93a37866
A
3101 return m_edge;
3102 }
3103
3104 Node* node() const
3105 {
3106 return edge().node();
6fe7ccc8
A
3107 }
3108
3109 GPRReg gpr()
3110 {
3111 if (m_gprOrInvalid == InvalidGPRReg)
93a37866 3112 m_gprOrInvalid = m_jit->fillSpeculateBoolean(edge());
6fe7ccc8
A
3113 return m_gprOrInvalid;
3114 }
3115
3116 void use()
3117 {
93a37866 3118 m_jit->use(node());
14957cd0
A
3119 }
3120
3121private:
6fe7ccc8 3122 SpeculativeJIT* m_jit;
93a37866 3123 Edge m_edge;
6fe7ccc8 3124 GPRReg m_gprOrInvalid;
14957cd0
A
3125};
3126
93a37866
A
3127template<typename StructureLocationType>
3128void SpeculativeJIT::speculateStringObjectForStructure(Edge edge, StructureLocationType structureLocation)
6fe7ccc8 3129{
93a37866 3130 Structure* stringObjectStructure =
81345200 3131 m_jit.globalObjectFor(m_currentNode->origin.semantic)->stringObjectStructure();
93a37866 3132
81345200 3133 if (!m_state.forNode(edge).m_currentKnownStructure.isSubsetOf(StructureSet(stringObjectStructure))) {
93a37866
A
3134 speculationCheck(
3135 NotStringObject, JSValueRegs(), 0,
81345200
A
3136 m_jit.branchStructurePtr(
3137 JITCompiler::NotEqual, structureLocation, stringObjectStructure));
93a37866 3138 }
6fe7ccc8 3139}
14957cd0 3140
93a37866 3141#define DFG_TYPE_CHECK(source, edge, typesPassedThrough, jumpToFail) do { \
81345200
A
3142 JSValueSource _dtc_source = (source); \
3143 Edge _dtc_edge = (edge); \
3144 SpeculatedType _dtc_typesPassedThrough = typesPassedThrough; \
3145 if (!needsTypeCheck(_dtc_edge, _dtc_typesPassedThrough)) \
93a37866 3146 break; \
81345200 3147 typeCheck(_dtc_source, _dtc_edge, _dtc_typesPassedThrough, (jumpToFail)); \
93a37866
A
3148 } while (0)
3149
14957cd0
A
3150} } // namespace JSC::DFG
3151
3152#endif
3153#endif
3154