]> git.saurik.com Git - apple/javascriptcore.git/blame - dfg/DFGVariableEvent.h
JavaScriptCore-1218.33.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
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
39namespace JSC { namespace DFG {
40
41enum 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
73union 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
85class VariableEvent {
86public:
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
246private:
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