]> git.saurik.com Git - apple/javascriptcore.git/blob - dfg/DFGVariableEvent.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / dfg / DFGVariableEvent.h
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 #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,
50 Birth,
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
63 // A SetLocalEvent means that a node's value has been stored into the stack.
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;
105 event.m_which.id = id.bits();
106 event.m_representation.gpr = gpr;
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;
117 event.m_which.id = id.bits();
118 event.m_representation.pair.tagGPR = tagGPR;
119 event.m_representation.pair.payloadGPR = payloadGPR;
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;
130 event.m_which.id = id.bits();
131 event.m_representation.fpr = fpr;
132 event.m_kind = kind;
133 event.m_dataFormat = DataFormatDouble;
134 return event;
135 }
136
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
145 static VariableEvent spill(VariableEventKind kind, MinifiedID id, VirtualRegister virtualRegister, DataFormat format)
146 {
147 ASSERT(kind == BirthToSpill || kind == Spill);
148 VariableEvent event;
149 event.m_which.id = id.bits();
150 event.m_representation.virtualReg = virtualRegister.offset();
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;
159 event.m_which.id = id.bits();
160 event.m_kind = Death;
161 return event;
162 }
163
164 static VariableEvent setLocal(
165 VirtualRegister bytecodeReg, VirtualRegister machineReg, DataFormat format)
166 {
167 VariableEvent event;
168 event.m_which.virtualReg = machineReg.offset();
169 event.m_representation.virtualReg = bytecodeReg.offset();
170 event.m_kind = SetLocalEvent;
171 event.m_dataFormat = format;
172 return event;
173 }
174
175 static VariableEvent movHint(MinifiedID id, VirtualRegister bytecodeReg)
176 {
177 VariableEvent event;
178 event.m_which.id = id.bits();
179 event.m_representation.virtualReg = bytecodeReg.offset();
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 {
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);
194 return MinifiedID::fromBits(m_which.id);
195 }
196
197 DataFormat dataFormat() const
198 {
199 ASSERT(
200 m_kind == BirthToFill || m_kind == Fill || m_kind == BirthToSpill || m_kind == Spill
201 || m_kind == SetLocalEvent);
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
213 return m_representation.gpr;
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);
221 return m_representation.pair.tagGPR;
222 }
223 MacroAssembler::RegisterID payloadGPR() const
224 {
225 ASSERT(m_kind == BirthToFill || m_kind == Fill);
226 ASSERT(m_dataFormat & DataFormatJS);
227 return m_representation.pair.payloadGPR;
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);
235 return m_representation.fpr;
236 }
237
238 VirtualRegister spillRegister() const
239 {
240 ASSERT(m_kind == BirthToSpill || m_kind == Spill);
241 return VirtualRegister(m_representation.virtualReg);
242 }
243
244 VirtualRegister bytecodeRegister() const
245 {
246 ASSERT(m_kind == SetLocalEvent || m_kind == MovHintEvent);
247 return VirtualRegister(m_representation.virtualReg);
248 }
249
250 VirtualRegister machineRegister() const
251 {
252 ASSERT(m_kind == SetLocalEvent);
253 return VirtualRegister(m_which.virtualReg);
254 }
255
256 const VariableRepresentation& variableRepresentation() const { return m_representation; }
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
264 union {
265 int virtualReg;
266 uintptr_t id;
267 } m_which;
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.
277 VariableRepresentation m_representation;
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