Remove excessive headers from JavaScriptCore
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGValueSource.h
1 /*
2  * Copyright (C) 2011, 2013-2015 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 "DFGFlushFormat.h"
31 #include "DFGMinifiedID.h"
32 #include "DataFormat.h"
33 #include "ValueRecovery.h"
34
35 namespace JSC { namespace DFG {
36
37 enum ValueSourceKind {
38     SourceNotSet,
39     ValueInJSStack,
40     Int32InJSStack,
41     Int52InJSStack,
42     CellInJSStack,
43     BooleanInJSStack,
44     DoubleInJSStack,
45     SourceIsDead,
46     HaveNode
47 };
48
49 static inline ValueSourceKind dataFormatToValueSourceKind(DataFormat dataFormat)
50 {
51     switch (dataFormat) {
52     case DataFormatInt32:
53         return Int32InJSStack;
54     case DataFormatInt52:
55         return Int52InJSStack;
56     case DataFormatDouble:
57         return DoubleInJSStack;
58     case DataFormatBoolean:
59         return BooleanInJSStack;
60     case DataFormatCell:
61         return CellInJSStack;
62     case DataFormatDead:
63         return SourceIsDead;
64     default:
65         RELEASE_ASSERT(dataFormat & DataFormatJS);
66         return ValueInJSStack;
67     }
68 }
69
70 static inline DataFormat valueSourceKindToDataFormat(ValueSourceKind kind)
71 {
72     switch (kind) {
73     case ValueInJSStack:
74         return DataFormatJS;
75     case Int32InJSStack:
76         return DataFormatInt32;
77     case Int52InJSStack:
78         return DataFormatInt52;
79     case CellInJSStack:
80         return DataFormatCell;
81     case BooleanInJSStack:
82         return DataFormatBoolean;
83     case DoubleInJSStack:
84         return DataFormatDouble;
85     case SourceIsDead:
86         return DataFormatDead;
87     default:
88         return DataFormatNone;
89     }
90 }
91
92 static inline bool isInJSStack(ValueSourceKind kind)
93 {
94     DataFormat format = valueSourceKindToDataFormat(kind);
95     return format != DataFormatNone && format < DataFormatOSRMarker;
96 }
97
98 // Can this value be recovered without having to look at register allocation state or
99 // DFG node liveness?
100 static inline bool isTriviallyRecoverable(ValueSourceKind kind)
101 {
102     return valueSourceKindToDataFormat(kind) != DataFormatNone;
103 }
104
105 class ValueSource {
106 public:
107     ValueSource()
108         : m_kind(SourceNotSet)
109     {
110     }
111     
112     explicit ValueSource(ValueSourceKind valueSourceKind)
113         : m_kind(valueSourceKind)
114     {
115         ASSERT(kind() == SourceIsDead);
116     }
117     
118     explicit ValueSource(MinifiedID id)
119         : m_kind(HaveNode)
120         , m_value(id.bits())
121     {
122         ASSERT(!!id);
123         ASSERT(kind() == HaveNode);
124     }
125     
126     ValueSource(ValueSourceKind valueSourceKind, VirtualRegister where)
127         : m_kind(valueSourceKind)
128         , m_value(static_cast<intptr_t>(where.offset()))
129     {
130         ASSERT(kind() != SourceNotSet);
131         ASSERT(kind() != HaveNode);
132     }
133     
134     static ValueSource forFlushFormat(VirtualRegister where, FlushFormat format)
135     {
136         switch (format) {
137         case DeadFlush:
138         case ConflictingFlush:
139             return ValueSource(SourceIsDead);
140         case FlushedJSValue:
141             return ValueSource(ValueInJSStack, where);
142         case FlushedDouble:
143             return ValueSource(DoubleInJSStack, where);
144         case FlushedInt32:
145             return ValueSource(Int32InJSStack, where);
146         case FlushedInt52:
147             return ValueSource(Int52InJSStack, where);
148         case FlushedCell:
149             return ValueSource(CellInJSStack, where);
150         case FlushedBoolean:
151             return ValueSource(BooleanInJSStack, where);
152         }
153         RELEASE_ASSERT_NOT_REACHED();
154         return ValueSource();
155     }
156     
157     static ValueSource forDataFormat(VirtualRegister where, DataFormat dataFormat)
158     {
159         return ValueSource(dataFormatToValueSourceKind(dataFormat), where);
160     }
161     
162     bool isSet() const
163     {
164         return kind() != SourceNotSet;
165     }
166     
167     bool operator!() const { return !isSet(); }
168     
169     ValueSourceKind kind() const
170     {
171         return m_kind;
172     }
173     
174     bool isInJSStack() const { return JSC::DFG::isInJSStack(kind()); }
175     bool isTriviallyRecoverable() const { return JSC::DFG::isTriviallyRecoverable(kind()); }
176     
177     DataFormat dataFormat() const
178     {
179         return valueSourceKindToDataFormat(kind());
180     }
181     
182     ValueRecovery valueRecovery() const
183     {
184         ASSERT(isTriviallyRecoverable());
185         switch (kind()) {
186         case SourceIsDead:
187             return ValueRecovery::constant(jsUndefined());
188             
189         default:
190             return ValueRecovery::displacedInJSStack(virtualRegister(), dataFormat());
191         }
192     }
193     
194     MinifiedID id() const
195     {
196         ASSERT(kind() == HaveNode);
197         return MinifiedID::fromBits(m_value);
198     }
199     
200     VirtualRegister virtualRegister() const
201     {
202         ASSERT(isInJSStack());
203         return VirtualRegister(m_value);
204     }
205     
206     void dump(PrintStream&) const;
207     void dumpInContext(PrintStream&, DumpContext*) const;
208     
209 private:
210     ValueSourceKind m_kind;
211     uintptr_t m_value;
212 };
213
214 } } // namespace JSC::DFG
215
216 #endif // ENABLE(DFG_JIT)