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/. */
6 
7 #ifndef jit_Safepoints_h
8 #define jit_Safepoints_h
9 
10 #include "jit/BitSet.h"
11 #include "jit/CompactBuffer.h"
12 #include "jit/shared/Assembler-shared.h"
13 
14 namespace js {
15 namespace jit {
16 
17 struct SafepointSlotEntry;
18 
19 class LAllocation;
20 class LSafepoint;
21 
22 static const uint32_t INVALID_SAFEPOINT_OFFSET = uint32_t(-1);
23 
24 class SafepointWriter {
25   CompactBufferWriter stream_;
26   BitSet frameSlots_;
27   BitSet argumentSlots_;
28 
29  public:
30   explicit SafepointWriter(uint32_t slotCount, uint32_t argumentCount);
31   MOZ_MUST_USE bool init(TempAllocator& alloc);
32 
33  private:
34   // A safepoint entry is written in the order these functions appear.
35   uint32_t startEntry();
36 
37   void writeOsiCallPointOffset(uint32_t osiPointOffset);
38   void writeGcRegs(LSafepoint* safepoint);
39   void writeGcSlots(LSafepoint* safepoint);
40   void writeValueSlots(LSafepoint* safepoint);
41 
42   void writeSlotsOrElementsSlots(LSafepoint* safepoint);
43 
44 #ifdef JS_NUNBOX32
45   void writeNunboxParts(LSafepoint* safepoint);
46 #endif
47 
48   void endEntry();
49 
50  public:
51   void encode(LSafepoint* safepoint);
52 
size()53   size_t size() const { return stream_.length(); }
buffer()54   const uint8_t* buffer() const { return stream_.buffer(); }
oom()55   bool oom() const { return stream_.oom(); }
56 };
57 
58 class SafepointReader {
59   CompactBufferReader stream_;
60   uint32_t frameSlots_;
61   uint32_t argumentSlots_;
62   uint32_t currentSlotChunk_;
63   bool currentSlotsAreStack_;
64   uint32_t nextSlotChunkNumber_;
65   uint32_t osiCallPointOffset_;
66   GeneralRegisterSet gcSpills_;
67   GeneralRegisterSet valueSpills_;
68   GeneralRegisterSet slotsOrElementsSpills_;
69   GeneralRegisterSet allGprSpills_;
70   FloatRegisterSet allFloatSpills_;
71   uint32_t nunboxSlotsRemaining_;
72   uint32_t slotsOrElementsSlotsRemaining_;
73 
74  private:
75   void advanceFromGcRegs();
76   void advanceFromGcSlots();
77   void advanceFromValueSlots();
78   void advanceFromNunboxSlots();
79   MOZ_MUST_USE bool getSlotFromBitmap(SafepointSlotEntry* entry);
80 
81  public:
82   SafepointReader(IonScript* script, const SafepointIndex* si);
83 
84   static CodeLocationLabel InvalidationPatchPoint(IonScript* script,
85                                                   const SafepointIndex* si);
86 
osiCallPointOffset()87   uint32_t osiCallPointOffset() const { return osiCallPointOffset_; }
gcSpills()88   LiveGeneralRegisterSet gcSpills() const {
89     return LiveGeneralRegisterSet(gcSpills_);
90   }
slotsOrElementsSpills()91   LiveGeneralRegisterSet slotsOrElementsSpills() const {
92     return LiveGeneralRegisterSet(slotsOrElementsSpills_);
93   }
valueSpills()94   LiveGeneralRegisterSet valueSpills() const {
95     return LiveGeneralRegisterSet(valueSpills_);
96   }
allGprSpills()97   LiveGeneralRegisterSet allGprSpills() const {
98     return LiveGeneralRegisterSet(allGprSpills_);
99   }
allFloatSpills()100   LiveFloatRegisterSet allFloatSpills() const {
101     return LiveFloatRegisterSet(allFloatSpills_);
102   }
103   uint32_t osiReturnPointOffset() const;
104 
105   // Returns true if a slot was read, false if there are no more slots.
106   MOZ_MUST_USE bool getGcSlot(SafepointSlotEntry* entry);
107 
108   // Returns true if a slot was read, false if there are no more value slots.
109   MOZ_MUST_USE bool getValueSlot(SafepointSlotEntry* entry);
110 
111   // Returns true if a nunbox slot was read, false if there are no more
112   // nunbox slots.
113   MOZ_MUST_USE bool getNunboxSlot(LAllocation* type, LAllocation* payload);
114 
115   // Returns true if a slot was read, false if there are no more slots.
116   MOZ_MUST_USE bool getSlotsOrElementsSlot(SafepointSlotEntry* entry);
117 };
118 
119 }  // namespace jit
120 }  // namespace js
121 
122 #endif /* jit_Safepoints_h */
123