]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGVariableEvent.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / dfg / DFGVariableEvent.h
CommitLineData
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
37namespace JSC { namespace DFG {
38
39enum 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
71union 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
83class VariableEvent {
84public:
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
260private:
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