]>
Commit | Line | Data |
---|---|---|
6fe7ccc8 | 1 | /* |
81345200 | 2 | * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. |
6fe7ccc8 A |
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 ValueRecovery_h | |
27 | #define ValueRecovery_h | |
28 | ||
29 | #include "DataFormat.h" | |
81345200 A |
30 | #if ENABLE(JIT) |
31 | #include "GPRInfo.h" | |
32 | #include "FPRInfo.h" | |
33 | #endif | |
93a37866 | 34 | #include "JSCJSValue.h" |
6fe7ccc8 A |
35 | #include "MacroAssembler.h" |
36 | #include "VirtualRegister.h" | |
6fe7ccc8 A |
37 | |
38 | namespace JSC { | |
39 | ||
81345200 A |
40 | struct DumpContext; |
41 | ||
6fe7ccc8 A |
42 | // Describes how to recover a given bytecode virtual register at a given |
43 | // code point. | |
44 | enum ValueRecoveryTechnique { | |
6fe7ccc8 A |
45 | // It's in a register. |
46 | InGPR, | |
47 | UnboxedInt32InGPR, | |
81345200 A |
48 | UnboxedInt52InGPR, |
49 | UnboxedStrictInt52InGPR, | |
6fe7ccc8 | 50 | UnboxedBooleanInGPR, |
81345200 | 51 | UnboxedCellInGPR, |
6fe7ccc8 A |
52 | #if USE(JSVALUE32_64) |
53 | InPair, | |
54 | #endif | |
55 | InFPR, | |
93a37866 A |
56 | // It's in the stack, but at a different location. |
57 | DisplacedInJSStack, | |
58 | // It's in the stack, at a different location, and it's unboxed. | |
59 | Int32DisplacedInJSStack, | |
81345200 A |
60 | Int52DisplacedInJSStack, |
61 | StrictInt52DisplacedInJSStack, | |
93a37866 A |
62 | DoubleDisplacedInJSStack, |
63 | CellDisplacedInJSStack, | |
64 | BooleanDisplacedInJSStack, | |
65 | // It's an Arguments object. | |
66 | ArgumentsThatWereNotCreated, | |
6fe7ccc8 A |
67 | // It's a constant. |
68 | Constant, | |
69 | // Don't know how to recover it. | |
70 | DontKnow | |
71 | }; | |
72 | ||
73 | class ValueRecovery { | |
74 | public: | |
75 | ValueRecovery() | |
76 | : m_technique(DontKnow) | |
77 | { | |
78 | } | |
79 | ||
93a37866 A |
80 | bool isSet() const { return m_technique != DontKnow; } |
81 | bool operator!() const { return !isSet(); } | |
82 | ||
6fe7ccc8 A |
83 | static ValueRecovery inGPR(MacroAssembler::RegisterID gpr, DataFormat dataFormat) |
84 | { | |
85 | ASSERT(dataFormat != DataFormatNone); | |
86 | #if USE(JSVALUE32_64) | |
81345200 | 87 | ASSERT(dataFormat == DataFormatInt32 || dataFormat == DataFormatCell || dataFormat == DataFormatBoolean); |
6fe7ccc8 A |
88 | #endif |
89 | ValueRecovery result; | |
81345200 | 90 | if (dataFormat == DataFormatInt32) |
6fe7ccc8 | 91 | result.m_technique = UnboxedInt32InGPR; |
81345200 A |
92 | else if (dataFormat == DataFormatInt52) |
93 | result.m_technique = UnboxedInt52InGPR; | |
94 | else if (dataFormat == DataFormatStrictInt52) | |
95 | result.m_technique = UnboxedStrictInt52InGPR; | |
6fe7ccc8 A |
96 | else if (dataFormat == DataFormatBoolean) |
97 | result.m_technique = UnboxedBooleanInGPR; | |
81345200 A |
98 | else if (dataFormat == DataFormatCell) |
99 | result.m_technique = UnboxedCellInGPR; | |
6fe7ccc8 A |
100 | else |
101 | result.m_technique = InGPR; | |
102 | result.m_source.gpr = gpr; | |
103 | return result; | |
104 | } | |
105 | ||
6fe7ccc8 A |
106 | #if USE(JSVALUE32_64) |
107 | static ValueRecovery inPair(MacroAssembler::RegisterID tagGPR, MacroAssembler::RegisterID payloadGPR) | |
108 | { | |
109 | ValueRecovery result; | |
110 | result.m_technique = InPair; | |
111 | result.m_source.pair.tagGPR = tagGPR; | |
112 | result.m_source.pair.payloadGPR = payloadGPR; | |
113 | return result; | |
114 | } | |
115 | #endif | |
116 | ||
117 | static ValueRecovery inFPR(MacroAssembler::FPRegisterID fpr) | |
118 | { | |
119 | ValueRecovery result; | |
120 | result.m_technique = InFPR; | |
121 | result.m_source.fpr = fpr; | |
122 | return result; | |
123 | } | |
124 | ||
93a37866 | 125 | static ValueRecovery displacedInJSStack(VirtualRegister virtualReg, DataFormat dataFormat) |
6fe7ccc8 A |
126 | { |
127 | ValueRecovery result; | |
128 | switch (dataFormat) { | |
81345200 | 129 | case DataFormatInt32: |
93a37866 | 130 | result.m_technique = Int32DisplacedInJSStack; |
6fe7ccc8 A |
131 | break; |
132 | ||
81345200 A |
133 | case DataFormatInt52: |
134 | result.m_technique = Int52DisplacedInJSStack; | |
135 | break; | |
136 | ||
137 | case DataFormatStrictInt52: | |
138 | result.m_technique = StrictInt52DisplacedInJSStack; | |
139 | break; | |
140 | ||
6fe7ccc8 | 141 | case DataFormatDouble: |
93a37866 | 142 | result.m_technique = DoubleDisplacedInJSStack; |
6fe7ccc8 A |
143 | break; |
144 | ||
145 | case DataFormatCell: | |
93a37866 | 146 | result.m_technique = CellDisplacedInJSStack; |
6fe7ccc8 A |
147 | break; |
148 | ||
149 | case DataFormatBoolean: | |
93a37866 | 150 | result.m_technique = BooleanDisplacedInJSStack; |
6fe7ccc8 A |
151 | break; |
152 | ||
153 | default: | |
154 | ASSERT(dataFormat != DataFormatNone && dataFormat != DataFormatStorage); | |
93a37866 | 155 | result.m_technique = DisplacedInJSStack; |
6fe7ccc8 A |
156 | break; |
157 | } | |
81345200 | 158 | result.m_source.virtualReg = virtualReg.offset(); |
6fe7ccc8 A |
159 | return result; |
160 | } | |
161 | ||
162 | static ValueRecovery constant(JSValue value) | |
163 | { | |
164 | ValueRecovery result; | |
165 | result.m_technique = Constant; | |
166 | result.m_source.constant = JSValue::encode(value); | |
167 | return result; | |
168 | } | |
169 | ||
93a37866 A |
170 | static ValueRecovery argumentsThatWereNotCreated() |
171 | { | |
172 | ValueRecovery result; | |
173 | result.m_technique = ArgumentsThatWereNotCreated; | |
174 | return result; | |
175 | } | |
176 | ||
6fe7ccc8 A |
177 | ValueRecoveryTechnique technique() const { return m_technique; } |
178 | ||
179 | bool isConstant() const { return m_technique == Constant; } | |
180 | ||
181 | bool isInRegisters() const | |
182 | { | |
183 | switch (m_technique) { | |
184 | case InGPR: | |
185 | case UnboxedInt32InGPR: | |
186 | case UnboxedBooleanInGPR: | |
81345200 A |
187 | case UnboxedCellInGPR: |
188 | case UnboxedInt52InGPR: | |
189 | case UnboxedStrictInt52InGPR: | |
6fe7ccc8 A |
190 | #if USE(JSVALUE32_64) |
191 | case InPair: | |
192 | #endif | |
193 | case InFPR: | |
194 | return true; | |
195 | default: | |
196 | return false; | |
197 | } | |
198 | } | |
199 | ||
6fe7ccc8 A |
200 | MacroAssembler::RegisterID gpr() const |
201 | { | |
81345200 | 202 | ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UnboxedInt52InGPR || m_technique == UnboxedStrictInt52InGPR || m_technique == UnboxedCellInGPR); |
6fe7ccc8 A |
203 | return m_source.gpr; |
204 | } | |
205 | ||
206 | #if USE(JSVALUE32_64) | |
207 | MacroAssembler::RegisterID tagGPR() const | |
208 | { | |
209 | ASSERT(m_technique == InPair); | |
210 | return m_source.pair.tagGPR; | |
211 | } | |
212 | ||
213 | MacroAssembler::RegisterID payloadGPR() const | |
214 | { | |
215 | ASSERT(m_technique == InPair); | |
216 | return m_source.pair.payloadGPR; | |
217 | } | |
218 | #endif | |
219 | ||
220 | MacroAssembler::FPRegisterID fpr() const | |
221 | { | |
222 | ASSERT(m_technique == InFPR); | |
223 | return m_source.fpr; | |
224 | } | |
225 | ||
226 | VirtualRegister virtualRegister() const | |
227 | { | |
81345200 A |
228 | ASSERT(m_technique == DisplacedInJSStack || m_technique == Int32DisplacedInJSStack || m_technique == DoubleDisplacedInJSStack || m_technique == CellDisplacedInJSStack || m_technique == BooleanDisplacedInJSStack || m_technique == Int52DisplacedInJSStack || m_technique == StrictInt52DisplacedInJSStack); |
229 | return VirtualRegister(m_source.virtualReg); | |
6fe7ccc8 A |
230 | } |
231 | ||
81345200 | 232 | ValueRecovery withLocalsOffset(int offset) const |
6fe7ccc8 | 233 | { |
81345200 | 234 | switch (m_technique) { |
93a37866 | 235 | case DisplacedInJSStack: |
93a37866 | 236 | case Int32DisplacedInJSStack: |
93a37866 | 237 | case DoubleDisplacedInJSStack: |
93a37866 | 238 | case CellDisplacedInJSStack: |
93a37866 | 239 | case BooleanDisplacedInJSStack: |
81345200 A |
240 | case Int52DisplacedInJSStack: |
241 | case StrictInt52DisplacedInJSStack: { | |
242 | ValueRecovery result; | |
243 | result.m_technique = m_technique; | |
244 | result.m_source.virtualReg = m_source.virtualReg + offset; | |
245 | return result; | |
246 | } | |
247 | ||
6fe7ccc8 | 248 | default: |
81345200 | 249 | return *this; |
6fe7ccc8 A |
250 | } |
251 | } | |
252 | ||
81345200 A |
253 | JSValue constant() const |
254 | { | |
255 | ASSERT(m_technique == Constant); | |
256 | return JSValue::decode(m_source.constant); | |
257 | } | |
258 | ||
259 | JSValue recover(ExecState*) const; | |
260 | ||
261 | #if ENABLE(JIT) | |
262 | void dumpInContext(PrintStream& out, DumpContext* context) const; | |
263 | void dump(PrintStream& out) const; | |
264 | #endif | |
265 | ||
6fe7ccc8 A |
266 | private: |
267 | ValueRecoveryTechnique m_technique; | |
268 | union { | |
269 | MacroAssembler::RegisterID gpr; | |
270 | MacroAssembler::FPRegisterID fpr; | |
271 | #if USE(JSVALUE32_64) | |
272 | struct { | |
273 | MacroAssembler::RegisterID tagGPR; | |
274 | MacroAssembler::RegisterID payloadGPR; | |
275 | } pair; | |
276 | #endif | |
81345200 | 277 | int virtualReg; |
6fe7ccc8 A |
278 | EncodedJSValue constant; |
279 | } m_source; | |
280 | }; | |
281 | ||
282 | } // namespace JSC | |
283 | ||
284 | #endif // ValueRecovery_h |