1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
10 #include "mozilla/Attributes.h"
13 #include "jit/Snapshots.h"
18 // [SMDOC] IonMonkey Recover Instructions
20 // This file contains all recover instructions.
22 // A recover instruction is an equivalent of a MIR instruction which is executed
23 // before the reconstruction of a baseline frame. Recover instructions are used
24 // by resume points to fill the value which are not produced by the code
25 // compiled by IonMonkey. For example, if a value is optimized away by
26 // IonMonkey, but required by Baseline, then we should have a recover
27 // instruction to fill the missing baseline frame slot.
29 // Recover instructions are executed either during a bailout, or under a call
30 // when the stack frame is introspected. If the stack is introspected, then any
31 // use of recover instruction must lead to an invalidation of the code.
33 // For each MIR instruction where |canRecoverOnBailout| might return true, we
34 // have a RInstruction of the same name.
36 // Recover instructions are encoded by the code generator into a compact buffer
37 // (RecoverWriter). The MIR instruction method |writeRecoverData| should write a
38 // tag in the |CompactBufferWriter| which is used by
39 // |RInstruction::readRecoverData| to dispatch to the right Recover
40 // instruction. Then |writeRecoverData| writes any local fields which are
41 // necessary for the execution of the |recover| method. These fields are decoded
42 // by the Recover instruction constructor which has a |CompactBufferReader| as
43 // argument. The constructor of the Recover instruction should follow the same
44 // sequence as the |writeRecoverData| method of the MIR instruction.
46 // Recover instructions are decoded by the |SnapshotIterator| (RecoverReader),
47 // which is given as argument of the |recover| methods, in order to read the
48 // operands. The number of operands read should be the same as the result of
49 // |numOperands|, which corresponds to the number of operands of the MIR
50 // instruction. Operands should be decoded in the same order as the operands of
51 // the MIR instruction.
53 // The result of the |recover| method should either be a failure, or a value
54 // stored on the |SnapshotIterator|, by using the |storeInstructionResult|
57 #define RECOVER_OPCODE_LIST(_) \
98 _(FromCharCodeEmptyIfNegative) \
128 _(FunctionWithProto) \
132 _(AtomicIsLockFree) \
135 _(CreateArgumentsObject) \
136 _(CreateInlinedArgumentsObject) \
138 _(AssertRecoveredOnBailout)
141 class SnapshotIterator
;
143 class MOZ_NON_PARAM RInstruction
{
146 #define DEFINE_OPCODES_(op) Recover_##op,
147 RECOVER_OPCODE_LIST(DEFINE_OPCODES_
)
148 #undef DEFINE_OPCODES_
152 virtual Opcode
opcode() const = 0;
154 // As opposed to the MIR, there is no need to add more methods as every
155 // other instruction is well abstracted under the "recover" method.
156 bool isResumePoint() const { return opcode() == Recover_ResumePoint
; }
157 inline const RResumePoint
* toResumePoint() const;
159 // Call the copy constructor of a specific RInstruction, to do a copy of the
160 // RInstruction content.
161 virtual void cloneInto(RInstructionStorage
* raw
) const = 0;
163 // Number of allocations which are encoded in the Snapshot for recovering
164 // the current instruction.
165 virtual uint32_t numOperands() const = 0;
167 // Function used to recover the value computed by this instruction. This
168 // function reads its arguments from the allocations listed on the snapshot
169 // iterator and stores its returned value on the snapshot iterator too.
170 [[nodiscard
]] virtual bool recover(JSContext
* cx
,
171 SnapshotIterator
& iter
) const = 0;
173 // Decode an RInstruction on top of the reserved storage space, based on the
174 // tag written by the writeRecoverData function of the corresponding MIR
176 static void readRecoverData(CompactBufferReader
& reader
,
177 RInstructionStorage
* raw
);
180 #define RINSTRUCTION_HEADER_(op) \
182 friend class RInstruction; \
183 explicit R##op(CompactBufferReader& reader); \
184 explicit R##op(const R##op& src) = default; \
187 Opcode opcode() const override { return RInstruction::Recover_##op; } \
188 void cloneInto(RInstructionStorage* raw) const override { \
189 new (raw->addr()) R##op(*this); \
192 #define RINSTRUCTION_HEADER_NUM_OP_MAIN(op, numOp) \
193 RINSTRUCTION_HEADER_(op) \
194 uint32_t numOperands() const override { return numOp; }
197 # define RINSTRUCTION_HEADER_NUM_OP_(op, numOp) \
198 RINSTRUCTION_HEADER_NUM_OP_MAIN(op, numOp) \
200 M##op::staticNumOperands == numOp, \
201 "The recover instructions's numOperands should equal to the " \
202 "MIR's numOperands");
204 # define RINSTRUCTION_HEADER_NUM_OP_(op, numOp) \
205 RINSTRUCTION_HEADER_NUM_OP_MAIN(op, numOp)
208 class RResumePoint final
: public RInstruction
{
210 uint32_t pcOffsetAndMode_
; // Offset from script->code and ResumeMode.
211 uint32_t numOperands_
; // Number of slots.
214 RINSTRUCTION_HEADER_(ResumePoint
)
216 // Used to encode/decode pcOffsetAndMode_.
217 static constexpr uint32_t PCOffsetShift
= 4;
218 static constexpr uint32_t ResumeModeMask
= 0b1111;
219 static_assert(uint32_t(ResumeMode::Last
) <= ResumeModeMask
);
221 uint32_t pcOffset() const { return pcOffsetAndMode_
>> PCOffsetShift
; }
222 ResumeMode
mode() const {
223 return ResumeMode(pcOffsetAndMode_
& ResumeModeMask
);
226 uint32_t numOperands() const override
{ return numOperands_
; }
227 [[nodiscard
]] bool recover(JSContext
* cx
,
228 SnapshotIterator
& iter
) const override
;
231 class RBitNot final
: public RInstruction
{
233 RINSTRUCTION_HEADER_NUM_OP_(BitNot
, 1)
235 [[nodiscard
]] bool recover(JSContext
* cx
,
236 SnapshotIterator
& iter
) const override
;
239 class RBitAnd final
: public RInstruction
{
241 RINSTRUCTION_HEADER_NUM_OP_(BitAnd
, 2)
243 [[nodiscard
]] bool recover(JSContext
* cx
,
244 SnapshotIterator
& iter
) const override
;
247 class RBitOr final
: public RInstruction
{
249 RINSTRUCTION_HEADER_NUM_OP_(BitOr
, 2)
251 [[nodiscard
]] bool recover(JSContext
* cx
,
252 SnapshotIterator
& iter
) const override
;
255 class RBitXor final
: public RInstruction
{
257 RINSTRUCTION_HEADER_NUM_OP_(BitXor
, 2)
259 [[nodiscard
]] bool recover(JSContext
* cx
,
260 SnapshotIterator
& iter
) const override
;
263 class RLsh final
: public RInstruction
{
265 RINSTRUCTION_HEADER_NUM_OP_(Lsh
, 2)
267 [[nodiscard
]] bool recover(JSContext
* cx
,
268 SnapshotIterator
& iter
) const override
;
271 class RRsh final
: public RInstruction
{
273 RINSTRUCTION_HEADER_NUM_OP_(Rsh
, 2)
275 [[nodiscard
]] bool recover(JSContext
* cx
,
276 SnapshotIterator
& iter
) const override
;
279 class RUrsh final
: public RInstruction
{
281 RINSTRUCTION_HEADER_NUM_OP_(Ursh
, 2)
283 [[nodiscard
]] bool recover(JSContext
* cx
,
284 SnapshotIterator
& iter
) const override
;
287 class RSignExtendInt32 final
: public RInstruction
{
292 RINSTRUCTION_HEADER_NUM_OP_(SignExtendInt32
, 1)
294 [[nodiscard
]] bool recover(JSContext
* cx
,
295 SnapshotIterator
& iter
) const override
;
298 class RAdd final
: public RInstruction
{
300 bool isFloatOperation_
;
303 RINSTRUCTION_HEADER_NUM_OP_(Add
, 2)
305 [[nodiscard
]] bool recover(JSContext
* cx
,
306 SnapshotIterator
& iter
) const override
;
309 class RSub final
: public RInstruction
{
311 bool isFloatOperation_
;
314 RINSTRUCTION_HEADER_NUM_OP_(Sub
, 2)
316 [[nodiscard
]] bool recover(JSContext
* cx
,
317 SnapshotIterator
& iter
) const override
;
320 class RMul final
: public RInstruction
{
322 bool isFloatOperation_
;
326 RINSTRUCTION_HEADER_NUM_OP_(Mul
, 2)
328 [[nodiscard
]] bool recover(JSContext
* cx
,
329 SnapshotIterator
& iter
) const override
;
332 class RDiv final
: public RInstruction
{
334 bool isFloatOperation_
;
337 RINSTRUCTION_HEADER_NUM_OP_(Div
, 2)
339 [[nodiscard
]] bool recover(JSContext
* cx
,
340 SnapshotIterator
& iter
) const override
;
343 class RMod final
: public RInstruction
{
345 RINSTRUCTION_HEADER_NUM_OP_(Mod
, 2)
347 [[nodiscard
]] bool recover(JSContext
* cx
,
348 SnapshotIterator
& iter
) const override
;
351 class RNot final
: public RInstruction
{
353 RINSTRUCTION_HEADER_NUM_OP_(Not
, 1)
355 [[nodiscard
]] bool recover(JSContext
* cx
,
356 SnapshotIterator
& iter
) const override
;
359 class RBigIntAdd final
: public RInstruction
{
361 RINSTRUCTION_HEADER_NUM_OP_(BigIntAdd
, 2)
363 [[nodiscard
]] bool recover(JSContext
* cx
,
364 SnapshotIterator
& iter
) const override
;
367 class RBigIntSub final
: public RInstruction
{
369 RINSTRUCTION_HEADER_NUM_OP_(BigIntSub
, 2)
371 [[nodiscard
]] bool recover(JSContext
* cx
,
372 SnapshotIterator
& iter
) const override
;
375 class RBigIntMul final
: public RInstruction
{
377 RINSTRUCTION_HEADER_NUM_OP_(BigIntMul
, 2)
379 [[nodiscard
]] bool recover(JSContext
* cx
,
380 SnapshotIterator
& iter
) const override
;
383 class RBigIntDiv final
: public RInstruction
{
385 RINSTRUCTION_HEADER_NUM_OP_(BigIntDiv
, 2)
387 [[nodiscard
]] bool recover(JSContext
* cx
,
388 SnapshotIterator
& iter
) const override
;
391 class RBigIntMod final
: public RInstruction
{
393 RINSTRUCTION_HEADER_NUM_OP_(BigIntMod
, 2)
395 [[nodiscard
]] bool recover(JSContext
* cx
,
396 SnapshotIterator
& iter
) const override
;
399 class RBigIntPow final
: public RInstruction
{
401 RINSTRUCTION_HEADER_NUM_OP_(BigIntPow
, 2)
403 [[nodiscard
]] bool recover(JSContext
* cx
,
404 SnapshotIterator
& iter
) const override
;
407 class RBigIntBitAnd final
: public RInstruction
{
409 RINSTRUCTION_HEADER_NUM_OP_(BigIntBitAnd
, 2)
411 [[nodiscard
]] bool recover(JSContext
* cx
,
412 SnapshotIterator
& iter
) const override
;
415 class RBigIntBitOr final
: public RInstruction
{
417 RINSTRUCTION_HEADER_NUM_OP_(BigIntBitOr
, 2)
419 [[nodiscard
]] bool recover(JSContext
* cx
,
420 SnapshotIterator
& iter
) const override
;
423 class RBigIntBitXor final
: public RInstruction
{
425 RINSTRUCTION_HEADER_NUM_OP_(BigIntBitXor
, 2)
427 [[nodiscard
]] bool recover(JSContext
* cx
,
428 SnapshotIterator
& iter
) const override
;
431 class RBigIntLsh final
: public RInstruction
{
433 RINSTRUCTION_HEADER_NUM_OP_(BigIntLsh
, 2)
435 [[nodiscard
]] bool recover(JSContext
* cx
,
436 SnapshotIterator
& iter
) const override
;
439 class RBigIntRsh final
: public RInstruction
{
441 RINSTRUCTION_HEADER_NUM_OP_(BigIntRsh
, 2)
443 [[nodiscard
]] bool recover(JSContext
* cx
,
444 SnapshotIterator
& iter
) const override
;
447 class RBigIntIncrement final
: public RInstruction
{
449 RINSTRUCTION_HEADER_NUM_OP_(BigIntIncrement
, 1)
451 [[nodiscard
]] bool recover(JSContext
* cx
,
452 SnapshotIterator
& iter
) const override
;
455 class RBigIntDecrement final
: public RInstruction
{
457 RINSTRUCTION_HEADER_NUM_OP_(BigIntDecrement
, 1)
459 [[nodiscard
]] bool recover(JSContext
* cx
,
460 SnapshotIterator
& iter
) const override
;
463 class RBigIntNegate final
: public RInstruction
{
465 RINSTRUCTION_HEADER_NUM_OP_(BigIntNegate
, 1)
467 [[nodiscard
]] bool recover(JSContext
* cx
,
468 SnapshotIterator
& iter
) const override
;
471 class RBigIntBitNot final
: public RInstruction
{
473 RINSTRUCTION_HEADER_NUM_OP_(BigIntBitNot
, 1)
475 [[nodiscard
]] bool recover(JSContext
* cx
,
476 SnapshotIterator
& iter
) const override
;
479 class RCompare final
: public RInstruction
{
483 RINSTRUCTION_HEADER_NUM_OP_(Compare
, 2)
485 [[nodiscard
]] bool recover(JSContext
* cx
,
486 SnapshotIterator
& iter
) const override
;
489 class RConcat final
: public RInstruction
{
491 RINSTRUCTION_HEADER_NUM_OP_(Concat
, 2)
493 [[nodiscard
]] bool recover(JSContext
* cx
,
494 SnapshotIterator
& iter
) const override
;
497 class RStringLength final
: public RInstruction
{
499 RINSTRUCTION_HEADER_NUM_OP_(StringLength
, 1)
501 [[nodiscard
]] bool recover(JSContext
* cx
,
502 SnapshotIterator
& iter
) const override
;
505 class RArgumentsLength final
: public RInstruction
{
507 RINSTRUCTION_HEADER_NUM_OP_(ArgumentsLength
, 0)
509 [[nodiscard
]] bool recover(JSContext
* cx
,
510 SnapshotIterator
& iter
) const override
;
513 class RFloor final
: public RInstruction
{
515 RINSTRUCTION_HEADER_NUM_OP_(Floor
, 1)
517 [[nodiscard
]] bool recover(JSContext
* cx
,
518 SnapshotIterator
& iter
) const override
;
521 class RCeil final
: public RInstruction
{
523 RINSTRUCTION_HEADER_NUM_OP_(Ceil
, 1)
525 [[nodiscard
]] bool recover(JSContext
* cx
,
526 SnapshotIterator
& iter
) const override
;
529 class RRound final
: public RInstruction
{
531 RINSTRUCTION_HEADER_NUM_OP_(Round
, 1)
533 [[nodiscard
]] bool recover(JSContext
* cx
,
534 SnapshotIterator
& iter
) const override
;
537 class RTrunc final
: public RInstruction
{
539 RINSTRUCTION_HEADER_NUM_OP_(Trunc
, 1)
541 [[nodiscard
]] bool recover(JSContext
* cx
,
542 SnapshotIterator
& iter
) const override
;
545 class RCharCodeAt final
: public RInstruction
{
547 RINSTRUCTION_HEADER_NUM_OP_(CharCodeAt
, 2)
549 [[nodiscard
]] bool recover(JSContext
* cx
,
550 SnapshotIterator
& iter
) const override
;
553 class RFromCharCode final
: public RInstruction
{
555 RINSTRUCTION_HEADER_NUM_OP_(FromCharCode
, 1)
557 [[nodiscard
]] bool recover(JSContext
* cx
,
558 SnapshotIterator
& iter
) const override
;
561 class RFromCharCodeEmptyIfNegative final
: public RInstruction
{
563 RINSTRUCTION_HEADER_NUM_OP_(FromCharCodeEmptyIfNegative
, 1)
565 [[nodiscard
]] bool recover(JSContext
* cx
,
566 SnapshotIterator
& iter
) const override
;
569 class RPow final
: public RInstruction
{
571 RINSTRUCTION_HEADER_NUM_OP_(Pow
, 2)
573 [[nodiscard
]] bool recover(JSContext
* cx
,
574 SnapshotIterator
& iter
) const override
;
577 class RPowHalf final
: public RInstruction
{
579 RINSTRUCTION_HEADER_NUM_OP_(PowHalf
, 1)
581 [[nodiscard
]] bool recover(JSContext
* cx
,
582 SnapshotIterator
& iter
) const override
;
585 class RMinMax final
: public RInstruction
{
590 RINSTRUCTION_HEADER_NUM_OP_(MinMax
, 2)
592 [[nodiscard
]] bool recover(JSContext
* cx
,
593 SnapshotIterator
& iter
) const override
;
596 class RAbs final
: public RInstruction
{
598 RINSTRUCTION_HEADER_NUM_OP_(Abs
, 1)
600 [[nodiscard
]] bool recover(JSContext
* cx
,
601 SnapshotIterator
& iter
) const override
;
604 class RSqrt final
: public RInstruction
{
606 bool isFloatOperation_
;
609 RINSTRUCTION_HEADER_NUM_OP_(Sqrt
, 1)
611 [[nodiscard
]] bool recover(JSContext
* cx
,
612 SnapshotIterator
& iter
) const override
;
615 class RAtan2 final
: public RInstruction
{
617 RINSTRUCTION_HEADER_NUM_OP_(Atan2
, 2)
619 [[nodiscard
]] bool recover(JSContext
* cx
,
620 SnapshotIterator
& iter
) const override
;
623 class RHypot final
: public RInstruction
{
625 uint32_t numOperands_
;
628 RINSTRUCTION_HEADER_(Hypot
)
630 uint32_t numOperands() const override
{ return numOperands_
; }
632 [[nodiscard
]] bool recover(JSContext
* cx
,
633 SnapshotIterator
& iter
) const override
;
636 class RNearbyInt final
: public RInstruction
{
638 uint8_t roundingMode_
;
641 RINSTRUCTION_HEADER_NUM_OP_(NearbyInt
, 1)
643 [[nodiscard
]] bool recover(JSContext
* cx
,
644 SnapshotIterator
& iter
) const override
;
647 class RSign final
: public RInstruction
{
649 RINSTRUCTION_HEADER_NUM_OP_(Sign
, 1)
651 [[nodiscard
]] bool recover(JSContext
* cx
,
652 SnapshotIterator
& iter
) const override
;
655 class RMathFunction final
: public RInstruction
{
657 UnaryMathFunction function_
;
660 RINSTRUCTION_HEADER_NUM_OP_(MathFunction
, 1)
662 [[nodiscard
]] bool recover(JSContext
* cx
,
663 SnapshotIterator
& iter
) const override
;
666 class RRandom final
: public RInstruction
{
667 RINSTRUCTION_HEADER_NUM_OP_(Random
, 0)
669 [[nodiscard
]] bool recover(JSContext
* cx
,
670 SnapshotIterator
& iter
) const override
;
673 class RStringSplit final
: public RInstruction
{
675 RINSTRUCTION_HEADER_NUM_OP_(StringSplit
, 2)
677 [[nodiscard
]] bool recover(JSContext
* cx
,
678 SnapshotIterator
& iter
) const override
;
681 class RNaNToZero final
: public RInstruction
{
683 RINSTRUCTION_HEADER_NUM_OP_(NaNToZero
, 1);
685 bool recover(JSContext
* cx
, SnapshotIterator
& iter
) const override
;
688 class RRegExpMatcher final
: public RInstruction
{
690 RINSTRUCTION_HEADER_NUM_OP_(RegExpMatcher
, 3)
692 [[nodiscard
]] bool recover(JSContext
* cx
,
693 SnapshotIterator
& iter
) const override
;
696 class RStringReplace final
: public RInstruction
{
698 bool isFlatReplacement_
;
701 RINSTRUCTION_HEADER_NUM_OP_(StringReplace
, 3)
703 [[nodiscard
]] bool recover(JSContext
* cx
,
704 SnapshotIterator
& iter
) const override
;
707 class RSubstr final
: public RInstruction
{
709 RINSTRUCTION_HEADER_NUM_OP_(Substr
, 3)
711 [[nodiscard
]] bool recover(JSContext
* cx
,
712 SnapshotIterator
& iter
) const override
;
715 class RTypeOf final
: public RInstruction
{
717 RINSTRUCTION_HEADER_NUM_OP_(TypeOf
, 1)
719 [[nodiscard
]] bool recover(JSContext
* cx
,
720 SnapshotIterator
& iter
) const override
;
723 class RTypeOfName final
: public RInstruction
{
725 RINSTRUCTION_HEADER_NUM_OP_(TypeOfName
, 1)
727 [[nodiscard
]] bool recover(JSContext
* cx
,
728 SnapshotIterator
& iter
) const override
;
731 class RToDouble final
: public RInstruction
{
733 RINSTRUCTION_HEADER_NUM_OP_(ToDouble
, 1)
735 [[nodiscard
]] bool recover(JSContext
* cx
,
736 SnapshotIterator
& iter
) const override
;
739 class RToFloat32 final
: public RInstruction
{
741 RINSTRUCTION_HEADER_NUM_OP_(ToFloat32
, 1)
743 [[nodiscard
]] bool recover(JSContext
* cx
,
744 SnapshotIterator
& iter
) const override
;
747 class RTruncateToInt32 final
: public RInstruction
{
749 RINSTRUCTION_HEADER_NUM_OP_(TruncateToInt32
, 1)
751 [[nodiscard
]] bool recover(JSContext
* cx
,
752 SnapshotIterator
& iter
) const override
;
755 class RNewObject final
: public RInstruction
{
757 RINSTRUCTION_HEADER_NUM_OP_(NewObject
, 1)
759 [[nodiscard
]] bool recover(JSContext
* cx
,
760 SnapshotIterator
& iter
) const override
;
763 class RNewPlainObject final
: public RInstruction
{
765 gc::AllocKind allocKind_
;
766 gc::Heap initialHeap_
;
769 RINSTRUCTION_HEADER_NUM_OP_(NewPlainObject
, 1)
771 [[nodiscard
]] bool recover(JSContext
* cx
,
772 SnapshotIterator
& iter
) const override
;
775 class RNewArrayObject final
: public RInstruction
{
778 gc::Heap initialHeap_
;
781 RINSTRUCTION_HEADER_NUM_OP_(NewArrayObject
, 1)
783 [[nodiscard
]] bool recover(JSContext
* cx
,
784 SnapshotIterator
& iter
) const override
;
787 class RNewTypedArray final
: public RInstruction
{
789 RINSTRUCTION_HEADER_NUM_OP_(NewTypedArray
, 1)
791 [[nodiscard
]] bool recover(JSContext
* cx
,
792 SnapshotIterator
& iter
) const override
;
795 class RNewArray final
: public RInstruction
{
800 RINSTRUCTION_HEADER_NUM_OP_(NewArray
, 1)
802 [[nodiscard
]] bool recover(JSContext
* cx
,
803 SnapshotIterator
& iter
) const override
;
806 class RNewIterator final
: public RInstruction
{
811 RINSTRUCTION_HEADER_NUM_OP_(NewIterator
, 1)
813 [[nodiscard
]] bool recover(JSContext
* cx
,
814 SnapshotIterator
& iter
) const override
;
817 class RLambda final
: public RInstruction
{
819 RINSTRUCTION_HEADER_NUM_OP_(Lambda
, 2)
821 [[nodiscard
]] bool recover(JSContext
* cx
,
822 SnapshotIterator
& iter
) const override
;
825 class RFunctionWithProto final
: public RInstruction
{
827 RINSTRUCTION_HEADER_NUM_OP_(FunctionWithProto
, 3)
829 [[nodiscard
]] bool recover(JSContext
* cx
,
830 SnapshotIterator
& iter
) const override
;
833 class RNewCallObject final
: public RInstruction
{
835 RINSTRUCTION_HEADER_NUM_OP_(NewCallObject
, 1)
837 [[nodiscard
]] bool recover(JSContext
* cx
,
838 SnapshotIterator
& iter
) const override
;
841 class RObjectKeys final
: public RInstruction
{
843 RINSTRUCTION_HEADER_NUM_OP_(ObjectKeys
, 1)
845 [[nodiscard
]] bool recover(JSContext
* cx
,
846 SnapshotIterator
& iter
) const override
;
849 class RObjectState final
: public RInstruction
{
851 uint32_t numSlots_
; // Number of slots.
854 RINSTRUCTION_HEADER_(ObjectState
)
856 uint32_t numSlots() const { return numSlots_
; }
857 uint32_t numOperands() const override
{
858 // +1 for the object.
859 return numSlots() + 1;
862 [[nodiscard
]] bool recover(JSContext
* cx
,
863 SnapshotIterator
& iter
) const override
;
866 class RArrayState final
: public RInstruction
{
868 uint32_t numElements_
;
871 RINSTRUCTION_HEADER_(ArrayState
)
873 uint32_t numElements() const { return numElements_
; }
874 uint32_t numOperands() const override
{
876 // +1 for the initalized length.
877 return numElements() + 2;
880 [[nodiscard
]] bool recover(JSContext
* cx
,
881 SnapshotIterator
& iter
) const override
;
884 class RAtomicIsLockFree final
: public RInstruction
{
886 RINSTRUCTION_HEADER_NUM_OP_(AtomicIsLockFree
, 1)
888 [[nodiscard
]] bool recover(JSContext
* cx
,
889 SnapshotIterator
& iter
) const override
;
892 class RBigIntAsIntN final
: public RInstruction
{
894 RINSTRUCTION_HEADER_NUM_OP_(BigIntAsIntN
, 2)
896 [[nodiscard
]] bool recover(JSContext
* cx
,
897 SnapshotIterator
& iter
) const override
;
900 class RBigIntAsUintN final
: public RInstruction
{
902 RINSTRUCTION_HEADER_NUM_OP_(BigIntAsUintN
, 2)
904 [[nodiscard
]] bool recover(JSContext
* cx
,
905 SnapshotIterator
& iter
) const override
;
908 class RCreateArgumentsObject final
: public RInstruction
{
910 RINSTRUCTION_HEADER_NUM_OP_(CreateArgumentsObject
, 1)
912 [[nodiscard
]] bool recover(JSContext
* cx
,
913 SnapshotIterator
& iter
) const override
;
916 class RCreateInlinedArgumentsObject final
: public RInstruction
{
918 uint32_t numActuals_
;
921 RINSTRUCTION_HEADER_(CreateInlinedArgumentsObject
)
923 uint32_t numActuals() const { return numActuals_
; }
924 uint32_t numOperands() const override
{
925 // +1 for the callObj.
926 // +1 for the callee.
927 return numActuals() + 2;
930 [[nodiscard
]] bool recover(JSContext
* cx
,
931 SnapshotIterator
& iter
) const override
;
934 class RRest final
: public RInstruction
{
935 uint32_t numFormals_
;
938 RINSTRUCTION_HEADER_NUM_OP_(Rest
, 1)
940 [[nodiscard
]] bool recover(JSContext
* cx
,
941 SnapshotIterator
& iter
) const override
;
944 class RAssertRecoveredOnBailout final
: public RInstruction
{
946 RINSTRUCTION_HEADER_NUM_OP_(AssertRecoveredOnBailout
, 1)
948 [[nodiscard
]] bool recover(JSContext
* cx
,
949 SnapshotIterator
& iter
) const override
;
952 #undef RINSTRUCTION_HEADER_
953 #undef RINSTRUCTION_HEADER_NUM_OP_
954 #undef RINSTRUCTION_HEADER_NUM_OP_MAIN
956 const RResumePoint
* RInstruction::toResumePoint() const {
957 MOZ_ASSERT(isResumePoint());
958 return static_cast<const RResumePoint
*>(this);
964 #endif /* jit_Recover_h */