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