]>
Commit | Line | Data |
---|---|---|
93a37866 A |
1 | /* |
2 | * Copyright (C) 2012 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 | #ifndef DFGVariableEvent_h | |
27 | #define DFGVariableEvent_h | |
28 | ||
29 | #include <wtf/Platform.h> | |
30 | ||
31 | #if ENABLE(DFG_JIT) | |
32 | ||
33 | #include "DFGCommon.h" | |
34 | #include "DFGMinifiedID.h" | |
35 | #include "DataFormat.h" | |
36 | #include "MacroAssembler.h" | |
37 | #include <stdio.h> | |
38 | ||
39 | namespace JSC { namespace DFG { | |
40 | ||
41 | enum VariableEventKind { | |
42 | // Marks the beginning of a checkpoint. If you interpret the variable | |
43 | // events starting at a Reset point then you'll get everything you need. | |
44 | Reset, | |
45 | ||
46 | // Node births. Points in the code where a node becomes relevant for OSR. | |
47 | // It may be the point where it is actually born (i.e. assigned) or it may | |
48 | // be a later point, if it's only later in the sequence of instructions | |
49 | // that we start to care about this node. | |
50 | BirthToFill, | |
51 | BirthToSpill, | |
52 | ||
53 | // Events related to how a node is represented. | |
54 | Fill, | |
55 | Spill, | |
56 | ||
57 | // Death of a node - after this we no longer care about this node. | |
58 | Death, | |
59 | ||
60 | // A MovHintEvent means that a node is being associated with a bytecode operand, | |
61 | // but that it has not been stored into that operand. | |
62 | MovHintEvent, | |
63 | ||
64 | // A SetLocalEvent means that a node's value has actually been stored into the | |
65 | // bytecode operand that it's associated with. | |
66 | SetLocalEvent, | |
67 | ||
68 | // Used to indicate an uninitialized VariableEvent. Don't use for other | |
69 | // purposes. | |
70 | InvalidEventKind | |
71 | }; | |
72 | ||
73 | union VariableRepresentation { | |
74 | MacroAssembler::RegisterID gpr; | |
75 | MacroAssembler::FPRegisterID fpr; | |
76 | #if USE(JSVALUE32_64) | |
77 | struct { | |
78 | MacroAssembler::RegisterID tagGPR; | |
79 | MacroAssembler::RegisterID payloadGPR; | |
80 | } pair; | |
81 | #endif | |
82 | int32_t virtualReg; | |
83 | }; | |
84 | ||
85 | class VariableEvent { | |
86 | public: | |
87 | VariableEvent() | |
88 | : m_kind(InvalidEventKind) | |
89 | { | |
90 | } | |
91 | ||
92 | static VariableEvent reset() | |
93 | { | |
94 | VariableEvent event; | |
95 | event.m_kind = Reset; | |
96 | return event; | |
97 | } | |
98 | ||
99 | static VariableEvent fillGPR(VariableEventKind kind, MinifiedID id, MacroAssembler::RegisterID gpr, DataFormat dataFormat) | |
100 | { | |
101 | ASSERT(kind == BirthToFill || kind == Fill); | |
102 | ASSERT(dataFormat != DataFormatDouble); | |
103 | #if USE(JSVALUE32_64) | |
104 | ASSERT(!(dataFormat & DataFormatJS)); | |
105 | #endif | |
106 | VariableEvent event; | |
107 | event.m_id = id; | |
108 | event.u.gpr = gpr; | |
109 | event.m_kind = kind; | |
110 | event.m_dataFormat = dataFormat; | |
111 | return event; | |
112 | } | |
113 | ||
114 | #if USE(JSVALUE32_64) | |
115 | static VariableEvent fillPair(VariableEventKind kind, MinifiedID id, MacroAssembler::RegisterID tagGPR, MacroAssembler::RegisterID payloadGPR) | |
116 | { | |
117 | ASSERT(kind == BirthToFill || kind == Fill); | |
118 | VariableEvent event; | |
119 | event.m_id = id; | |
120 | event.u.pair.tagGPR = tagGPR; | |
121 | event.u.pair.payloadGPR = payloadGPR; | |
122 | event.m_kind = kind; | |
123 | event.m_dataFormat = DataFormatJS; | |
124 | return event; | |
125 | } | |
126 | #endif // USE(JSVALUE32_64) | |
127 | ||
128 | static VariableEvent fillFPR(VariableEventKind kind, MinifiedID id, MacroAssembler::FPRegisterID fpr) | |
129 | { | |
130 | ASSERT(kind == BirthToFill || kind == Fill); | |
131 | VariableEvent event; | |
132 | event.m_id = id; | |
133 | event.u.fpr = fpr; | |
134 | event.m_kind = kind; | |
135 | event.m_dataFormat = DataFormatDouble; | |
136 | return event; | |
137 | } | |
138 | ||
139 | static VariableEvent spill(VariableEventKind kind, MinifiedID id, VirtualRegister virtualRegister, DataFormat format) | |
140 | { | |
141 | ASSERT(kind == BirthToSpill || kind == Spill); | |
142 | VariableEvent event; | |
143 | event.m_id = id; | |
144 | event.u.virtualReg = virtualRegister; | |
145 | event.m_kind = kind; | |
146 | event.m_dataFormat = format; | |
147 | return event; | |
148 | } | |
149 | ||
150 | static VariableEvent death(MinifiedID id) | |
151 | { | |
152 | VariableEvent event; | |
153 | event.m_id = id; | |
154 | event.m_kind = Death; | |
155 | return event; | |
156 | } | |
157 | ||
158 | static VariableEvent setLocal(int operand, DataFormat format) | |
159 | { | |
160 | VariableEvent event; | |
161 | event.u.virtualReg = operand; | |
162 | event.m_kind = SetLocalEvent; | |
163 | event.m_dataFormat = format; | |
164 | return event; | |
165 | } | |
166 | ||
167 | static VariableEvent movHint(MinifiedID id, int operand) | |
168 | { | |
169 | VariableEvent event; | |
170 | event.m_id = id; | |
171 | event.u.virtualReg = operand; | |
172 | event.m_kind = MovHintEvent; | |
173 | return event; | |
174 | } | |
175 | ||
176 | VariableEventKind kind() const | |
177 | { | |
178 | return static_cast<VariableEventKind>(m_kind); | |
179 | } | |
180 | ||
181 | MinifiedID id() const | |
182 | { | |
183 | ASSERT(m_kind == BirthToFill || m_kind == Fill | |
184 | || m_kind == BirthToSpill || m_kind == Spill | |
185 | || m_kind == Death || m_kind == MovHintEvent); | |
186 | return m_id; | |
187 | } | |
188 | ||
189 | DataFormat dataFormat() const | |
190 | { | |
191 | ASSERT(m_kind == BirthToFill || m_kind == Fill | |
192 | || m_kind == BirthToSpill || m_kind == Spill | |
193 | || m_kind == SetLocalEvent); | |
194 | return static_cast<DataFormat>(m_dataFormat); | |
195 | } | |
196 | ||
197 | MacroAssembler::RegisterID gpr() const | |
198 | { | |
199 | ASSERT(m_kind == BirthToFill || m_kind == Fill); | |
200 | ASSERT(m_dataFormat); | |
201 | ASSERT(m_dataFormat != DataFormatDouble); | |
202 | #if USE(JSVALUE32_64) | |
203 | ASSERT(!(m_dataFormat & DataFormatJS)); | |
204 | #endif | |
205 | return u.gpr; | |
206 | } | |
207 | ||
208 | #if USE(JSVALUE32_64) | |
209 | MacroAssembler::RegisterID tagGPR() const | |
210 | { | |
211 | ASSERT(m_kind == BirthToFill || m_kind == Fill); | |
212 | ASSERT(m_dataFormat & DataFormatJS); | |
213 | return u.pair.tagGPR; | |
214 | } | |
215 | MacroAssembler::RegisterID payloadGPR() const | |
216 | { | |
217 | ASSERT(m_kind == BirthToFill || m_kind == Fill); | |
218 | ASSERT(m_dataFormat & DataFormatJS); | |
219 | return u.pair.payloadGPR; | |
220 | } | |
221 | #endif // USE(JSVALUE32_64) | |
222 | ||
223 | MacroAssembler::FPRegisterID fpr() const | |
224 | { | |
225 | ASSERT(m_kind == BirthToFill || m_kind == Fill); | |
226 | ASSERT(m_dataFormat == DataFormatDouble); | |
227 | return u.fpr; | |
228 | } | |
229 | ||
230 | VirtualRegister virtualRegister() const | |
231 | { | |
232 | ASSERT(m_kind == BirthToSpill || m_kind == Spill); | |
233 | return static_cast<VirtualRegister>(u.virtualReg); | |
234 | } | |
235 | ||
236 | int operand() const | |
237 | { | |
238 | ASSERT(m_kind == SetLocalEvent || m_kind == MovHintEvent); | |
239 | return u.virtualReg; | |
240 | } | |
241 | ||
242 | const VariableRepresentation& variableRepresentation() const { return u; } | |
243 | ||
244 | void dump(PrintStream&) const; | |
245 | ||
246 | private: | |
247 | void dumpFillInfo(const char* name, PrintStream&) const; | |
248 | void dumpSpillInfo(const char* name, PrintStream&) const; | |
249 | ||
250 | MinifiedID m_id; | |
251 | ||
252 | // For BirthToFill, Fill: | |
253 | // - The GPR or FPR, or a GPR pair. | |
254 | // For BirthToSpill, Spill: | |
255 | // - The virtual register. | |
256 | // For MovHintEvent, SetLocalEvent: | |
257 | // - The bytecode operand. | |
258 | // For Death: | |
259 | // - Unused. | |
260 | VariableRepresentation u; | |
261 | ||
262 | int8_t m_kind; | |
263 | int8_t m_dataFormat; | |
264 | }; | |
265 | ||
266 | } } // namespace JSC::DFG | |
267 | ||
268 | #endif // ENABLE(DFG_JIT) | |
269 | ||
270 | #endif // DFGVariableEvent_h | |
271 |