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