[JSC] Pass CodeOrigin to FuzzerAgent
[WebKit-https.git] / Source / JavaScriptCore / jit / RegisterSet.h
1 /*
2  * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
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 #pragma once
27
28 #if !ENABLE(C_LOOP)
29
30 #include "GPRInfo.h"
31 #include "MacroAssembler.h"
32 #include "Reg.h"
33 #include "TempRegisterSet.h"
34 #include <wtf/Bitmap.h>
35
36 namespace JSC {
37
38 typedef Bitmap<MacroAssembler::numGPRs + MacroAssembler::numFPRs + 1> RegisterBitmap;
39 class RegisterAtOffsetList;
40
41 class RegisterSet {
42 public:
43     constexpr RegisterSet() { }
44
45     template<typename... Regs>
46     constexpr explicit RegisterSet(Regs... regs)
47     {
48         setMany(regs...);
49     }
50     
51     JS_EXPORT_PRIVATE static RegisterSet stackRegisters();
52     JS_EXPORT_PRIVATE static RegisterSet reservedHardwareRegisters();
53     static RegisterSet runtimeRegisters();
54     static RegisterSet specialRegisters(); // The union of stack, reserved hardware, and runtime registers.
55     JS_EXPORT_PRIVATE static RegisterSet calleeSaveRegisters();
56     static RegisterSet vmCalleeSaveRegisters(); // Callee save registers that might be saved and used by any tier.
57     static RegisterAtOffsetList* vmCalleeSaveRegisterOffsets();
58     static RegisterSet llintBaselineCalleeSaveRegisters(); // Registers saved and used by the LLInt.
59     static RegisterSet dfgCalleeSaveRegisters(); // Registers saved and used by the DFG JIT.
60     static RegisterSet ftlCalleeSaveRegisters(); // Registers that might be saved and used by the FTL JIT.
61 #if ENABLE(WEBASSEMBLY)
62     static RegisterSet webAssemblyCalleeSaveRegisters(); // Registers saved and used by the WebAssembly JIT.
63 #endif
64     static RegisterSet volatileRegistersForJSCall();
65     static RegisterSet stubUnavailableRegisters(); // The union of callee saves and special registers.
66     JS_EXPORT_PRIVATE static RegisterSet macroScratchRegisters();
67     JS_EXPORT_PRIVATE static RegisterSet allGPRs();
68     JS_EXPORT_PRIVATE static RegisterSet allFPRs();
69     static RegisterSet allRegisters();
70     JS_EXPORT_PRIVATE static RegisterSet argumentGPRS();
71
72     static RegisterSet registersToNotSaveForJSCall();
73     static RegisterSet registersToNotSaveForCCall();
74     
75     void set(Reg reg, bool value = true)
76     {
77         ASSERT(!!reg);
78         m_bits.set(reg.index(), value);
79     }
80     
81     void set(JSValueRegs regs, bool value = true)
82     {
83         if (regs.tagGPR() != InvalidGPRReg)
84             set(regs.tagGPR(), value);
85         set(regs.payloadGPR(), value);
86     }
87     
88     void clear(Reg reg)
89     {
90         ASSERT(!!reg);
91         set(reg, false);
92     }
93     
94     bool get(Reg reg) const
95     {
96         ASSERT(!!reg);
97         return m_bits.get(reg.index());
98     }
99     
100     template<typename Iterable>
101     void setAll(const Iterable& iterable)
102     {
103         for (Reg reg : iterable)
104             set(reg);
105     }
106     
107     // Also allow add/remove/contains terminology, which means the same thing as set/clear/get.
108     bool add(Reg reg)
109     {
110         ASSERT(!!reg);
111         return !m_bits.testAndSet(reg.index());
112     }
113     bool remove(Reg reg)
114     {
115         ASSERT(!!reg);
116         return m_bits.testAndClear(reg.index());
117     }
118     bool contains(Reg reg) const { return get(reg); }
119     
120     void merge(const RegisterSet& other) { m_bits.merge(other.m_bits); }
121     void filter(const RegisterSet& other) { m_bits.filter(other.m_bits); }
122     void exclude(const RegisterSet& other) { m_bits.exclude(other.m_bits); }
123     
124     bool subsumes(const RegisterSet& other) const { return m_bits.subsumes(other.m_bits); }
125     
126     size_t numberOfSetGPRs() const;
127     size_t numberOfSetFPRs() const;
128     size_t numberOfSetRegisters() const { return m_bits.count(); }
129     
130     bool isEmpty() const { return m_bits.isEmpty(); }
131     
132     JS_EXPORT_PRIVATE void dump(PrintStream&) const;
133     
134     enum EmptyValueTag { EmptyValue };
135     enum DeletedValueTag { DeletedValue };
136     
137     RegisterSet(EmptyValueTag)
138     {
139         m_bits.set(hashSpecialBitIndex);
140     }
141     
142     RegisterSet(DeletedValueTag)
143     {
144         m_bits.set(hashSpecialBitIndex);
145         m_bits.set(deletedBitIndex);
146     }
147     
148     bool isEmptyValue() const
149     {
150         return m_bits.get(hashSpecialBitIndex) && !m_bits.get(deletedBitIndex);
151     }
152     
153     bool isDeletedValue() const
154     {
155         return m_bits.get(hashSpecialBitIndex) && m_bits.get(deletedBitIndex);
156     }
157     
158     bool operator==(const RegisterSet& other) const { return m_bits == other.m_bits; }
159     bool operator!=(const RegisterSet& other) const { return m_bits != other.m_bits; }
160     
161     unsigned hash() const { return m_bits.hash(); }
162     
163     template<typename Func>
164     void forEach(const Func& func) const
165     {
166         m_bits.forEachSetBit(
167             [&] (size_t index) {
168                 func(Reg::fromIndex(index));
169             });
170     }
171     
172     class iterator {
173     public:
174         iterator()
175         {
176         }
177         
178         iterator(const RegisterBitmap::iterator& iter)
179             : m_iter(iter)
180         {
181         }
182         
183         Reg operator*() const { return Reg::fromIndex(*m_iter); }
184         
185         iterator& operator++()
186         {
187             ++m_iter;
188             return *this;
189         }
190         
191         bool operator==(const iterator& other)
192         {
193             return m_iter == other.m_iter;
194         }
195         
196         bool operator!=(const iterator& other)
197         {
198             return !(*this == other);
199         }
200         
201     private:
202         RegisterBitmap::iterator m_iter;
203     };
204     
205     iterator begin() const { return iterator(m_bits.begin()); }
206     iterator end() const { return iterator(m_bits.end()); }
207     
208 private:
209     void setAny(Reg reg) { set(reg); }
210     void setAny(JSValueRegs regs) { set(regs); }
211     void setAny(const RegisterSet& set) { merge(set); }
212     void setMany() { }
213     template<typename RegType, typename... Regs>
214     void setMany(RegType reg, Regs... regs)
215     {
216         setAny(reg);
217         setMany(regs...);
218     }
219
220     // These offsets mirror the logic in Reg.h.
221     static const unsigned gprOffset = 0;
222     static const unsigned fprOffset = gprOffset + MacroAssembler::numGPRs;
223     static const unsigned hashSpecialBitIndex = fprOffset + MacroAssembler::numFPRs;
224     static const unsigned deletedBitIndex = 0;
225     
226     RegisterBitmap m_bits;
227 };
228
229 struct RegisterSetHash {
230     static unsigned hash(const RegisterSet& set) { return set.hash(); }
231     static bool equal(const RegisterSet& a, const RegisterSet& b) { return a == b; }
232     static const bool safeToCompareToEmptyOrDeleted = false;
233 };
234
235 } // namespace JSC
236
237 namespace WTF {
238
239 template<typename T> struct DefaultHash;
240 template<> struct DefaultHash<JSC::RegisterSet> {
241     typedef JSC::RegisterSetHash Hash;
242 };
243
244 template<typename T> struct HashTraits;
245 template<> struct HashTraits<JSC::RegisterSet> : public CustomHashTraits<JSC::RegisterSet> { };
246
247 } // namespace WTF
248
249 #endif // !ENABLE(C_LOOP)