2 * Copyright (C) 2012 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef DFGVariableEvent_h
27 #define DFGVariableEvent_h
31 #include "DFGCommon.h"
32 #include "DFGMinifiedID.h"
33 #include "DataFormat.h"
34 #include "MacroAssembler.h"
37 namespace JSC
{ namespace DFG
{
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.
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.
52 // Events related to how a node is represented.
56 // Death of a node - after this we no longer care about this node.
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.
63 // A SetLocalEvent means that a node's value has been stored into the stack.
66 // Used to indicate an uninitialized VariableEvent. Don't use for other
71 union VariableRepresentation
{
72 MacroAssembler::RegisterID gpr
;
73 MacroAssembler::FPRegisterID fpr
;
76 MacroAssembler::RegisterID tagGPR
;
77 MacroAssembler::RegisterID payloadGPR
;
86 : m_kind(InvalidEventKind
)
90 static VariableEvent
reset()
97 static VariableEvent
fillGPR(VariableEventKind kind
, MinifiedID id
, MacroAssembler::RegisterID gpr
, DataFormat dataFormat
)
99 ASSERT(kind
== BirthToFill
|| kind
== Fill
);
100 ASSERT(dataFormat
!= DataFormatDouble
);
101 #if USE(JSVALUE32_64)
102 ASSERT(!(dataFormat
& DataFormatJS
));
105 event
.m_which
.id
= id
.bits();
106 event
.m_representation
.gpr
= gpr
;
108 event
.m_dataFormat
= dataFormat
;
112 #if USE(JSVALUE32_64)
113 static VariableEvent
fillPair(VariableEventKind kind
, MinifiedID id
, MacroAssembler::RegisterID tagGPR
, MacroAssembler::RegisterID payloadGPR
)
115 ASSERT(kind
== BirthToFill
|| kind
== Fill
);
117 event
.m_which
.id
= id
.bits();
118 event
.m_representation
.pair
.tagGPR
= tagGPR
;
119 event
.m_representation
.pair
.payloadGPR
= payloadGPR
;
121 event
.m_dataFormat
= DataFormatJS
;
124 #endif // USE(JSVALUE32_64)
126 static VariableEvent
fillFPR(VariableEventKind kind
, MinifiedID id
, MacroAssembler::FPRegisterID fpr
)
128 ASSERT(kind
== BirthToFill
|| kind
== Fill
);
130 event
.m_which
.id
= id
.bits();
131 event
.m_representation
.fpr
= fpr
;
133 event
.m_dataFormat
= DataFormatDouble
;
137 static VariableEvent
birth(MinifiedID id
)
140 event
.m_which
.id
= id
.bits();
141 event
.m_kind
= Birth
;
145 static VariableEvent
spill(VariableEventKind kind
, MinifiedID id
, VirtualRegister virtualRegister
, DataFormat format
)
147 ASSERT(kind
== BirthToSpill
|| kind
== Spill
);
149 event
.m_which
.id
= id
.bits();
150 event
.m_representation
.virtualReg
= virtualRegister
.offset();
152 event
.m_dataFormat
= format
;
156 static VariableEvent
death(MinifiedID id
)
159 event
.m_which
.id
= id
.bits();
160 event
.m_kind
= Death
;
164 static VariableEvent
setLocal(
165 VirtualRegister bytecodeReg
, VirtualRegister machineReg
, DataFormat format
)
168 event
.m_which
.virtualReg
= machineReg
.offset();
169 event
.m_representation
.virtualReg
= bytecodeReg
.offset();
170 event
.m_kind
= SetLocalEvent
;
171 event
.m_dataFormat
= format
;
175 static VariableEvent
movHint(MinifiedID id
, VirtualRegister bytecodeReg
)
178 event
.m_which
.id
= id
.bits();
179 event
.m_representation
.virtualReg
= bytecodeReg
.offset();
180 event
.m_kind
= MovHintEvent
;
184 VariableEventKind
kind() const
186 return static_cast<VariableEventKind
>(m_kind
);
189 MinifiedID
id() const
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
);
197 DataFormat
dataFormat() const
200 m_kind
== BirthToFill
|| m_kind
== Fill
|| m_kind
== BirthToSpill
|| m_kind
== Spill
201 || m_kind
== SetLocalEvent
);
202 return static_cast<DataFormat
>(m_dataFormat
);
205 MacroAssembler::RegisterID
gpr() const
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
));
213 return m_representation
.gpr
;
216 #if USE(JSVALUE32_64)
217 MacroAssembler::RegisterID
tagGPR() const
219 ASSERT(m_kind
== BirthToFill
|| m_kind
== Fill
);
220 ASSERT(m_dataFormat
& DataFormatJS
);
221 return m_representation
.pair
.tagGPR
;
223 MacroAssembler::RegisterID
payloadGPR() const
225 ASSERT(m_kind
== BirthToFill
|| m_kind
== Fill
);
226 ASSERT(m_dataFormat
& DataFormatJS
);
227 return m_representation
.pair
.payloadGPR
;
229 #endif // USE(JSVALUE32_64)
231 MacroAssembler::FPRegisterID
fpr() const
233 ASSERT(m_kind
== BirthToFill
|| m_kind
== Fill
);
234 ASSERT(m_dataFormat
== DataFormatDouble
);
235 return m_representation
.fpr
;
238 VirtualRegister
spillRegister() const
240 ASSERT(m_kind
== BirthToSpill
|| m_kind
== Spill
);
241 return VirtualRegister(m_representation
.virtualReg
);
244 VirtualRegister
bytecodeRegister() const
246 ASSERT(m_kind
== SetLocalEvent
|| m_kind
== MovHintEvent
);
247 return VirtualRegister(m_representation
.virtualReg
);
250 VirtualRegister
machineRegister() const
252 ASSERT(m_kind
== SetLocalEvent
);
253 return VirtualRegister(m_which
.virtualReg
);
256 const VariableRepresentation
& variableRepresentation() const { return m_representation
; }
258 void dump(PrintStream
&) const;
261 void dumpFillInfo(const char* name
, PrintStream
&) const;
262 void dumpSpillInfo(const char* name
, PrintStream
&) const;
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.
277 VariableRepresentation m_representation
;
283 } } // namespace JSC::DFG
285 #endif // ENABLE(DFG_JIT)
287 #endif // DFGVariableEvent_h