Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
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/. */
6 :
7 : #ifndef jit_Recover_h
8 : #define jit_Recover_h
9 :
10 : #include "mozilla/Attributes.h"
11 :
12 : #include "jsarray.h"
13 :
14 : #include "jit/MIR.h"
15 : #include "jit/Snapshots.h"
16 :
17 : struct JSContext;
18 :
19 : namespace js {
20 : namespace jit {
21 :
22 : // This file contains all recover instructions.
23 : //
24 : // A recover instruction is an equivalent of a MIR instruction which is executed
25 : // before the reconstruction of a baseline frame. Recover instructions are used
26 : // by resume points to fill the value which are not produced by the code
27 : // compiled by IonMonkey. For example, if a value is optimized away by
28 : // IonMonkey, but required by Baseline, then we should have a recover
29 : // instruction to fill the missing baseline frame slot.
30 : //
31 : // Recover instructions are executed either during a bailout, or under a call
32 : // when the stack frame is introspected. If the stack is introspected, then any
33 : // use of recover instruction must lead to an invalidation of the code.
34 : //
35 : // For each MIR instruction where |canRecoverOnBailout| might return true, we
36 : // have a RInstruction of the same name.
37 : //
38 : // Recover instructions are encoded by the code generator into a compact buffer
39 : // (RecoverWriter). The MIR instruction method |writeRecoverData| should write a
40 : // tag in the |CompactBufferWriter| which is used by
41 : // |RInstruction::readRecoverData| to dispatch to the right Recover
42 : // instruction. Then |writeRecoverData| writes any local fields which are
43 : // necessary for the execution of the |recover| method. These fields are decoded
44 : // by the Recover instruction constructor which has a |CompactBufferReader| as
45 : // argument. The constructor of the Recover instruction should follow the same
46 : // sequence as the |writeRecoverData| method of the MIR instruction.
47 : //
48 : // Recover instructions are decoded by the |SnapshotIterator| (RecoverReader),
49 : // which is given as argument of the |recover| methods, in order to read the
50 : // operands. The number of operands read should be the same as the result of
51 : // |numOperands|, which corresponds to the number of operands of the MIR
52 : // instruction. Operands should be decoded in the same order as the operands of
53 : // the MIR instruction.
54 : //
55 : // The result of the |recover| method should either be a failure, or a value
56 : // stored on the |SnapshotIterator|, by using the |storeInstructionResult|
57 : // method.
58 :
59 : #define RECOVER_OPCODE_LIST(_) \
60 : _(ResumePoint) \
61 : _(BitNot) \
62 : _(BitAnd) \
63 : _(BitOr) \
64 : _(BitXor) \
65 : _(Lsh) \
66 : _(Rsh) \
67 : _(Ursh) \
68 : _(SignExtend) \
69 : _(Add) \
70 : _(Sub) \
71 : _(Mul) \
72 : _(Div) \
73 : _(Mod) \
74 : _(Not) \
75 : _(Concat) \
76 : _(StringLength) \
77 : _(ArgumentsLength) \
78 : _(Floor) \
79 : _(Ceil) \
80 : _(Round) \
81 : _(CharCodeAt) \
82 : _(FromCharCode) \
83 : _(Pow) \
84 : _(PowHalf) \
85 : _(MinMax) \
86 : _(Abs) \
87 : _(Sqrt) \
88 : _(Atan2) \
89 : _(Hypot) \
90 : _(MathFunction) \
91 : _(Random) \
92 : _(StringSplit) \
93 : _(NaNToZero) \
94 : _(RegExpMatcher) \
95 : _(RegExpSearcher) \
96 : _(RegExpTester) \
97 : _(StringReplace) \
98 : _(TypeOf) \
99 : _(ToDouble) \
100 : _(ToFloat32) \
101 : _(TruncateToInt32) \
102 : _(NewObject) \
103 : _(NewTypedArray) \
104 : _(NewArray) \
105 : _(NewIterator) \
106 : _(NewDerivedTypedObject) \
107 : _(CreateThisWithTemplate) \
108 : _(Lambda) \
109 : _(LambdaArrow) \
110 : _(SimdBox) \
111 : _(ObjectState) \
112 : _(ArrayState) \
113 : _(AtomicIsLockFree) \
114 : _(AssertRecoveredOnBailout)
115 :
116 : class RResumePoint;
117 : class SnapshotIterator;
118 :
119 2520 : class MOZ_NON_PARAM RInstruction
120 : {
121 : public:
122 : enum Opcode
123 : {
124 : # define DEFINE_OPCODES_(op) Recover_##op,
125 : RECOVER_OPCODE_LIST(DEFINE_OPCODES_)
126 : # undef DEFINE_OPCODES_
127 : Recover_Invalid
128 : };
129 :
130 : virtual Opcode opcode() const = 0;
131 :
132 : // As opposed to the MIR, there is no need to add more methods as every
133 : // other instruction is well abstracted under the "recover" method.
134 1680 : bool isResumePoint() const {
135 1680 : return opcode() == Recover_ResumePoint;
136 : }
137 : inline const RResumePoint* toResumePoint() const;
138 :
139 : // Call the copy constructor of a specific RInstruction, to do a copy of the
140 : // RInstruction content.
141 : virtual void cloneInto(RInstructionStorage* raw) const = 0;
142 :
143 : // Number of allocations which are encoded in the Snapshot for recovering
144 : // the current instruction.
145 : virtual uint32_t numOperands() const = 0;
146 :
147 : // Function used to recover the value computed by this instruction. This
148 : // function reads its arguments from the allocations listed on the snapshot
149 : // iterator and stores its returned value on the snapshot iterator too.
150 : virtual MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const = 0;
151 :
152 : // Decode an RInstruction on top of the reserved storage space, based on the
153 : // tag written by the writeRecoverData function of the corresponding MIR
154 : // instruction.
155 : static void readRecoverData(CompactBufferReader& reader, RInstructionStorage* raw);
156 : };
157 :
158 : #define RINSTRUCTION_HEADER_(op) \
159 : private: \
160 : friend class RInstruction; \
161 : explicit R##op(CompactBufferReader& reader); \
162 : explicit R##op(const R##op& src) = default; \
163 : \
164 : public: \
165 : Opcode opcode() const override { \
166 : return RInstruction::Recover_##op; \
167 : } \
168 : void cloneInto(RInstructionStorage* raw) const override { \
169 : new (raw->addr()) R##op(*this); \
170 : }
171 :
172 : #define RINSTRUCTION_HEADER_NUM_OP_MAIN(op, numOp) \
173 : RINSTRUCTION_HEADER_(op) \
174 : uint32_t numOperands() const override { \
175 : return numOp; \
176 : }
177 :
178 : #ifdef DEBUG
179 : # define RINSTRUCTION_HEADER_NUM_OP_(op, numOp) \
180 : RINSTRUCTION_HEADER_NUM_OP_MAIN(op, numOp) \
181 : static_assert(M##op::staticNumOperands == numOp, "The recover instructions's numOperands should equal to the MIR's numOperands");
182 : #else
183 : # define RINSTRUCTION_HEADER_NUM_OP_(op, numOp) \
184 : RINSTRUCTION_HEADER_NUM_OP_MAIN(op, numOp)
185 : #endif
186 :
187 : class RResumePoint final : public RInstruction
188 : {
189 : private:
190 : uint32_t pcOffset_; // Offset from script->code.
191 : uint32_t numOperands_; // Number of slots.
192 :
193 : public:
194 5040 : RINSTRUCTION_HEADER_(ResumePoint)
195 :
196 840 : uint32_t pcOffset() const {
197 840 : return pcOffset_;
198 : }
199 0 : uint32_t numOperands() const override {
200 0 : return numOperands_;
201 : }
202 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
203 : };
204 :
205 : class RBitNot final : public RInstruction
206 : {
207 : public:
208 0 : RINSTRUCTION_HEADER_NUM_OP_(BitNot, 1)
209 :
210 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
211 : };
212 :
213 : class RBitAnd final : public RInstruction
214 : {
215 : public:
216 0 : RINSTRUCTION_HEADER_NUM_OP_(BitAnd, 2)
217 :
218 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
219 : };
220 :
221 : class RBitOr final : public RInstruction
222 : {
223 : public:
224 0 : RINSTRUCTION_HEADER_NUM_OP_(BitOr, 2)
225 :
226 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
227 : };
228 :
229 : class RBitXor final : public RInstruction
230 : {
231 : public:
232 0 : RINSTRUCTION_HEADER_NUM_OP_(BitXor, 2)
233 :
234 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
235 : };
236 :
237 : class RLsh final : public RInstruction
238 : {
239 : public:
240 0 : RINSTRUCTION_HEADER_NUM_OP_(Lsh, 2)
241 :
242 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
243 : };
244 :
245 : class RRsh final : public RInstruction
246 : {
247 : public:
248 0 : RINSTRUCTION_HEADER_NUM_OP_(Rsh, 2)
249 :
250 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
251 : };
252 :
253 : class RUrsh final : public RInstruction
254 : {
255 : public:
256 0 : RINSTRUCTION_HEADER_NUM_OP_(Ursh, 2)
257 :
258 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
259 : };
260 :
261 : class RSignExtend final : public RInstruction
262 : {
263 : private:
264 : uint8_t mode_;
265 :
266 : public:
267 0 : RINSTRUCTION_HEADER_NUM_OP_(SignExtend, 1)
268 :
269 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
270 : };
271 :
272 : class RAdd final : public RInstruction
273 : {
274 : private:
275 : bool isFloatOperation_;
276 :
277 : public:
278 0 : RINSTRUCTION_HEADER_NUM_OP_(Add, 2)
279 :
280 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
281 : };
282 :
283 : class RSub final : public RInstruction
284 : {
285 : private:
286 : bool isFloatOperation_;
287 :
288 : public:
289 0 : RINSTRUCTION_HEADER_NUM_OP_(Sub, 2)
290 :
291 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
292 : };
293 :
294 : class RMul final : public RInstruction
295 : {
296 : private:
297 : bool isFloatOperation_;
298 : uint8_t mode_;
299 :
300 : public:
301 0 : RINSTRUCTION_HEADER_NUM_OP_(Mul, 2)
302 :
303 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
304 : };
305 :
306 : class RDiv final : public RInstruction
307 : {
308 : private:
309 : bool isFloatOperation_;
310 :
311 : public:
312 0 : RINSTRUCTION_HEADER_NUM_OP_(Div, 2)
313 :
314 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
315 : };
316 :
317 : class RMod final : public RInstruction
318 : {
319 : public:
320 0 : RINSTRUCTION_HEADER_NUM_OP_(Mod, 2)
321 :
322 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
323 : };
324 :
325 : class RNot final : public RInstruction
326 : {
327 : public:
328 0 : RINSTRUCTION_HEADER_NUM_OP_(Not, 1)
329 :
330 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
331 : };
332 :
333 : class RConcat final : public RInstruction
334 : {
335 : public:
336 0 : RINSTRUCTION_HEADER_NUM_OP_(Concat, 2)
337 :
338 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
339 : };
340 :
341 : class RStringLength final : public RInstruction
342 : {
343 : public:
344 0 : RINSTRUCTION_HEADER_NUM_OP_(StringLength, 1)
345 :
346 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
347 : };
348 :
349 : class RArgumentsLength final : public RInstruction
350 : {
351 : public:
352 0 : RINSTRUCTION_HEADER_NUM_OP_(ArgumentsLength, 0)
353 :
354 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
355 : };
356 :
357 :
358 : class RFloor final : public RInstruction
359 : {
360 : public:
361 0 : RINSTRUCTION_HEADER_NUM_OP_(Floor, 1)
362 :
363 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
364 : };
365 :
366 : class RCeil final : public RInstruction
367 : {
368 : public:
369 0 : RINSTRUCTION_HEADER_NUM_OP_(Ceil, 1)
370 :
371 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
372 : };
373 :
374 : class RRound final : public RInstruction
375 : {
376 : public:
377 0 : RINSTRUCTION_HEADER_NUM_OP_(Round, 1)
378 :
379 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
380 : };
381 :
382 : class RCharCodeAt final : public RInstruction
383 : {
384 : public:
385 0 : RINSTRUCTION_HEADER_NUM_OP_(CharCodeAt, 2)
386 :
387 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
388 : };
389 :
390 : class RFromCharCode final : public RInstruction
391 : {
392 : public:
393 0 : RINSTRUCTION_HEADER_NUM_OP_(FromCharCode, 1)
394 :
395 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
396 : };
397 :
398 : class RPow final : public RInstruction
399 : {
400 : public:
401 0 : RINSTRUCTION_HEADER_NUM_OP_(Pow, 2)
402 :
403 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
404 : };
405 :
406 : class RPowHalf final : public RInstruction
407 : {
408 : public:
409 0 : RINSTRUCTION_HEADER_NUM_OP_(PowHalf, 1)
410 :
411 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
412 : };
413 :
414 : class RMinMax final : public RInstruction
415 : {
416 : private:
417 : bool isMax_;
418 :
419 : public:
420 0 : RINSTRUCTION_HEADER_NUM_OP_(MinMax, 2)
421 :
422 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
423 : };
424 :
425 : class RAbs final : public RInstruction
426 : {
427 : public:
428 0 : RINSTRUCTION_HEADER_NUM_OP_(Abs, 1)
429 :
430 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
431 : };
432 :
433 : class RSqrt final : public RInstruction
434 : {
435 : private:
436 : bool isFloatOperation_;
437 :
438 : public:
439 0 : RINSTRUCTION_HEADER_NUM_OP_(Sqrt, 1)
440 :
441 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
442 : };
443 :
444 : class RAtan2 final : public RInstruction
445 : {
446 : public:
447 0 : RINSTRUCTION_HEADER_NUM_OP_(Atan2, 2)
448 :
449 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
450 : };
451 :
452 : class RHypot final : public RInstruction
453 : {
454 : private:
455 : uint32_t numOperands_;
456 :
457 : public:
458 0 : RINSTRUCTION_HEADER_(Hypot)
459 :
460 0 : uint32_t numOperands() const override {
461 0 : return numOperands_;
462 : }
463 :
464 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
465 : };
466 :
467 : class RMathFunction final : public RInstruction
468 : {
469 : private:
470 : uint8_t function_;
471 :
472 : public:
473 0 : RINSTRUCTION_HEADER_NUM_OP_(MathFunction, 1)
474 :
475 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
476 : };
477 :
478 : class RRandom final : public RInstruction
479 : {
480 0 : RINSTRUCTION_HEADER_NUM_OP_(Random, 0)
481 : public:
482 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
483 : };
484 :
485 : class RStringSplit final : public RInstruction
486 : {
487 : public:
488 0 : RINSTRUCTION_HEADER_NUM_OP_(StringSplit, 2)
489 :
490 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
491 : };
492 :
493 : class RNaNToZero final : public RInstruction
494 : {
495 : public:
496 0 : RINSTRUCTION_HEADER_NUM_OP_(NaNToZero, 1);
497 :
498 : bool recover(JSContext* cx, SnapshotIterator& iter) const override;
499 : };
500 :
501 : class RRegExpMatcher final : public RInstruction
502 : {
503 : public:
504 0 : RINSTRUCTION_HEADER_NUM_OP_(RegExpMatcher, 3)
505 :
506 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
507 : };
508 :
509 : class RRegExpSearcher final : public RInstruction
510 : {
511 : public:
512 0 : RINSTRUCTION_HEADER_NUM_OP_(RegExpSearcher, 3)
513 :
514 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
515 : };
516 :
517 : class RRegExpTester final : public RInstruction
518 : {
519 : public:
520 0 : RINSTRUCTION_HEADER_NUM_OP_(RegExpTester, 3)
521 :
522 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
523 : };
524 :
525 : class RStringReplace final : public RInstruction
526 : {
527 : private:
528 : bool isFlatReplacement_;
529 :
530 : public:
531 0 : RINSTRUCTION_HEADER_NUM_OP_(StringReplace, 3)
532 :
533 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
534 : };
535 :
536 : class RTypeOf final : public RInstruction
537 : {
538 : public:
539 0 : RINSTRUCTION_HEADER_NUM_OP_(TypeOf, 1)
540 :
541 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
542 : };
543 :
544 : class RToDouble final : public RInstruction
545 : {
546 : public:
547 0 : RINSTRUCTION_HEADER_NUM_OP_(ToDouble, 1)
548 :
549 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
550 : };
551 :
552 : class RToFloat32 final : public RInstruction
553 : {
554 : public:
555 0 : RINSTRUCTION_HEADER_NUM_OP_(ToFloat32, 1)
556 :
557 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
558 : };
559 :
560 : class RTruncateToInt32 final : public RInstruction
561 : {
562 : public:
563 0 : RINSTRUCTION_HEADER_NUM_OP_(TruncateToInt32, 1)
564 :
565 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
566 : };
567 :
568 : class RNewObject final : public RInstruction
569 : {
570 : private:
571 : MNewObject::Mode mode_;
572 :
573 : public:
574 0 : RINSTRUCTION_HEADER_NUM_OP_(NewObject, 1)
575 :
576 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
577 : };
578 :
579 : class RNewTypedArray final : public RInstruction
580 : {
581 : public:
582 0 : RINSTRUCTION_HEADER_NUM_OP_(NewTypedArray, 1)
583 :
584 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
585 : };
586 :
587 : class RNewArray final : public RInstruction
588 : {
589 : private:
590 : uint32_t count_;
591 :
592 : public:
593 0 : RINSTRUCTION_HEADER_NUM_OP_(NewArray, 1)
594 :
595 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
596 : };
597 :
598 : class RNewIterator final : public RInstruction
599 : {
600 : private:
601 : uint8_t type_;
602 :
603 : public:
604 0 : RINSTRUCTION_HEADER_NUM_OP_(NewIterator, 1)
605 :
606 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
607 : };
608 :
609 : class RNewDerivedTypedObject final : public RInstruction
610 : {
611 : public:
612 0 : RINSTRUCTION_HEADER_NUM_OP_(NewDerivedTypedObject, 3)
613 :
614 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
615 : };
616 :
617 : class RCreateThisWithTemplate final : public RInstruction
618 : {
619 : public:
620 0 : RINSTRUCTION_HEADER_NUM_OP_(CreateThisWithTemplate, 1)
621 :
622 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
623 : };
624 :
625 : class RLambda final : public RInstruction
626 : {
627 : public:
628 0 : RINSTRUCTION_HEADER_NUM_OP_(Lambda, 2)
629 :
630 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
631 : };
632 :
633 : class RLambdaArrow final : public RInstruction
634 : {
635 : public:
636 0 : RINSTRUCTION_HEADER_NUM_OP_(LambdaArrow, 3)
637 :
638 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
639 : };
640 :
641 : class RSimdBox final : public RInstruction
642 : {
643 : private:
644 : uint8_t type_;
645 :
646 : public:
647 0 : RINSTRUCTION_HEADER_NUM_OP_(SimdBox, 1)
648 :
649 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
650 : };
651 :
652 : class RObjectState final : public RInstruction
653 : {
654 : private:
655 : uint32_t numSlots_; // Number of slots.
656 :
657 : public:
658 0 : RINSTRUCTION_HEADER_(ObjectState)
659 :
660 0 : uint32_t numSlots() const {
661 0 : return numSlots_;
662 : }
663 0 : uint32_t numOperands() const override {
664 : // +1 for the object.
665 0 : return numSlots() + 1;
666 : }
667 :
668 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
669 : };
670 :
671 : class RArrayState final : public RInstruction
672 : {
673 : private:
674 : uint32_t numElements_;
675 :
676 : public:
677 0 : RINSTRUCTION_HEADER_(ArrayState)
678 :
679 0 : uint32_t numElements() const {
680 0 : return numElements_;
681 : }
682 0 : uint32_t numOperands() const override {
683 : // +1 for the array.
684 : // +1 for the initalized length.
685 0 : return numElements() + 2;
686 : }
687 :
688 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
689 : };
690 :
691 : class RAtomicIsLockFree final : public RInstruction
692 : {
693 : public:
694 0 : RINSTRUCTION_HEADER_NUM_OP_(AtomicIsLockFree, 1)
695 :
696 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
697 : };
698 :
699 : class RAssertRecoveredOnBailout final : public RInstruction
700 : {
701 : public:
702 0 : RINSTRUCTION_HEADER_NUM_OP_(AssertRecoveredOnBailout, 1)
703 :
704 : MOZ_MUST_USE bool recover(JSContext* cx, SnapshotIterator& iter) const override;
705 : };
706 :
707 : #undef RINSTRUCTION_HEADER_
708 : #undef RINSTRUCTION_HEADER_NUM_OP_
709 : #undef RINSTRUCTION_HEADER_NUM_OP_MAIN
710 :
711 : const RResumePoint*
712 840 : RInstruction::toResumePoint() const
713 : {
714 840 : MOZ_ASSERT(isResumePoint());
715 840 : return static_cast<const RResumePoint*>(this);
716 : }
717 :
718 : } // namespace jit
719 : } // namespace js
720 :
721 : #endif /* jit_Recover_h */
|