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