]> git.saurik.com Git - apple/javascriptcore.git/blame - bytecode/ValueRecovery.h
JavaScriptCore-1218.tar.gz
[apple/javascriptcore.git] / bytecode / ValueRecovery.h
CommitLineData
6fe7ccc8
A
1/*
2 * Copyright (C) 2011 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 ValueRecovery_h
27#define ValueRecovery_h
28
29#include "DataFormat.h"
93a37866 30#include "JSCJSValue.h"
6fe7ccc8
A
31#include "MacroAssembler.h"
32#include "VirtualRegister.h"
33#include <stdio.h>
34#include <wtf/Platform.h>
35
36namespace JSC {
37
38// Describes how to recover a given bytecode virtual register at a given
39// code point.
40enum ValueRecoveryTechnique {
93a37866
A
41 // It's already in the stack at the right location.
42 AlreadyInJSStack,
43 // It's already in the stack but unboxed.
44 AlreadyInJSStackAsUnboxedInt32,
45 AlreadyInJSStackAsUnboxedCell,
46 AlreadyInJSStackAsUnboxedBoolean,
47 AlreadyInJSStackAsUnboxedDouble,
6fe7ccc8
A
48 // It's in a register.
49 InGPR,
50 UnboxedInt32InGPR,
51 UnboxedBooleanInGPR,
52#if USE(JSVALUE32_64)
53 InPair,
54#endif
55 InFPR,
56 UInt32InGPR,
93a37866
A
57 // It's in the stack, but at a different location.
58 DisplacedInJSStack,
59 // It's in the stack, at a different location, and it's unboxed.
60 Int32DisplacedInJSStack,
61 DoubleDisplacedInJSStack,
62 CellDisplacedInJSStack,
63 BooleanDisplacedInJSStack,
64 // It's an Arguments object.
65 ArgumentsThatWereNotCreated,
6fe7ccc8
A
66 // It's a constant.
67 Constant,
68 // Don't know how to recover it.
69 DontKnow
70};
71
72class ValueRecovery {
73public:
74 ValueRecovery()
75 : m_technique(DontKnow)
76 {
77 }
78
93a37866
A
79 bool isSet() const { return m_technique != DontKnow; }
80 bool operator!() const { return !isSet(); }
81
82 static ValueRecovery alreadyInJSStack()
6fe7ccc8
A
83 {
84 ValueRecovery result;
93a37866 85 result.m_technique = AlreadyInJSStack;
6fe7ccc8
A
86 return result;
87 }
88
93a37866 89 static ValueRecovery alreadyInJSStackAsUnboxedInt32()
6fe7ccc8
A
90 {
91 ValueRecovery result;
93a37866 92 result.m_technique = AlreadyInJSStackAsUnboxedInt32;
6fe7ccc8
A
93 return result;
94 }
95
93a37866 96 static ValueRecovery alreadyInJSStackAsUnboxedCell()
6fe7ccc8
A
97 {
98 ValueRecovery result;
93a37866 99 result.m_technique = AlreadyInJSStackAsUnboxedCell;
6fe7ccc8
A
100 return result;
101 }
102
93a37866 103 static ValueRecovery alreadyInJSStackAsUnboxedBoolean()
6fe7ccc8
A
104 {
105 ValueRecovery result;
93a37866 106 result.m_technique = AlreadyInJSStackAsUnboxedBoolean;
6fe7ccc8
A
107 return result;
108 }
109
93a37866 110 static ValueRecovery alreadyInJSStackAsUnboxedDouble()
6fe7ccc8
A
111 {
112 ValueRecovery result;
93a37866 113 result.m_technique = AlreadyInJSStackAsUnboxedDouble;
6fe7ccc8
A
114 return result;
115 }
116
117 static ValueRecovery inGPR(MacroAssembler::RegisterID gpr, DataFormat dataFormat)
118 {
119 ASSERT(dataFormat != DataFormatNone);
120#if USE(JSVALUE32_64)
121 ASSERT(dataFormat == DataFormatInteger || dataFormat == DataFormatCell || dataFormat == DataFormatBoolean);
122#endif
123 ValueRecovery result;
124 if (dataFormat == DataFormatInteger)
125 result.m_technique = UnboxedInt32InGPR;
126 else if (dataFormat == DataFormatBoolean)
127 result.m_technique = UnboxedBooleanInGPR;
128 else
129 result.m_technique = InGPR;
130 result.m_source.gpr = gpr;
131 return result;
132 }
133
134 static ValueRecovery uint32InGPR(MacroAssembler::RegisterID gpr)
135 {
136 ValueRecovery result;
137 result.m_technique = UInt32InGPR;
138 result.m_source.gpr = gpr;
139 return result;
140 }
141
142#if USE(JSVALUE32_64)
143 static ValueRecovery inPair(MacroAssembler::RegisterID tagGPR, MacroAssembler::RegisterID payloadGPR)
144 {
145 ValueRecovery result;
146 result.m_technique = InPair;
147 result.m_source.pair.tagGPR = tagGPR;
148 result.m_source.pair.payloadGPR = payloadGPR;
149 return result;
150 }
151#endif
152
153 static ValueRecovery inFPR(MacroAssembler::FPRegisterID fpr)
154 {
155 ValueRecovery result;
156 result.m_technique = InFPR;
157 result.m_source.fpr = fpr;
158 return result;
159 }
160
93a37866 161 static ValueRecovery displacedInJSStack(VirtualRegister virtualReg, DataFormat dataFormat)
6fe7ccc8
A
162 {
163 ValueRecovery result;
164 switch (dataFormat) {
165 case DataFormatInteger:
93a37866 166 result.m_technique = Int32DisplacedInJSStack;
6fe7ccc8
A
167 break;
168
169 case DataFormatDouble:
93a37866 170 result.m_technique = DoubleDisplacedInJSStack;
6fe7ccc8
A
171 break;
172
173 case DataFormatCell:
93a37866 174 result.m_technique = CellDisplacedInJSStack;
6fe7ccc8
A
175 break;
176
177 case DataFormatBoolean:
93a37866 178 result.m_technique = BooleanDisplacedInJSStack;
6fe7ccc8
A
179 break;
180
181 default:
182 ASSERT(dataFormat != DataFormatNone && dataFormat != DataFormatStorage);
93a37866 183 result.m_technique = DisplacedInJSStack;
6fe7ccc8
A
184 break;
185 }
186 result.m_source.virtualReg = virtualReg;
187 return result;
188 }
189
190 static ValueRecovery constant(JSValue value)
191 {
192 ValueRecovery result;
193 result.m_technique = Constant;
194 result.m_source.constant = JSValue::encode(value);
195 return result;
196 }
197
93a37866
A
198 static ValueRecovery argumentsThatWereNotCreated()
199 {
200 ValueRecovery result;
201 result.m_technique = ArgumentsThatWereNotCreated;
202 return result;
203 }
204
6fe7ccc8
A
205 ValueRecoveryTechnique technique() const { return m_technique; }
206
207 bool isConstant() const { return m_technique == Constant; }
208
209 bool isInRegisters() const
210 {
211 switch (m_technique) {
212 case InGPR:
213 case UnboxedInt32InGPR:
214 case UnboxedBooleanInGPR:
215#if USE(JSVALUE32_64)
216 case InPair:
217#endif
218 case InFPR:
219 return true;
220 default:
221 return false;
222 }
223 }
224
93a37866 225 bool isAlreadyInJSStack() const
6fe7ccc8
A
226 {
227 switch (technique()) {
93a37866
A
228 case AlreadyInJSStack:
229 case AlreadyInJSStackAsUnboxedInt32:
230 case AlreadyInJSStackAsUnboxedCell:
231 case AlreadyInJSStackAsUnboxedBoolean:
232 case AlreadyInJSStackAsUnboxedDouble:
6fe7ccc8
A
233 return true;
234 default:
235 return false;
236 }
237 }
238
239 MacroAssembler::RegisterID gpr() const
240 {
241 ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UInt32InGPR);
242 return m_source.gpr;
243 }
244
245#if USE(JSVALUE32_64)
246 MacroAssembler::RegisterID tagGPR() const
247 {
248 ASSERT(m_technique == InPair);
249 return m_source.pair.tagGPR;
250 }
251
252 MacroAssembler::RegisterID payloadGPR() const
253 {
254 ASSERT(m_technique == InPair);
255 return m_source.pair.payloadGPR;
256 }
257#endif
258
259 MacroAssembler::FPRegisterID fpr() const
260 {
261 ASSERT(m_technique == InFPR);
262 return m_source.fpr;
263 }
264
265 VirtualRegister virtualRegister() const
266 {
93a37866 267 ASSERT(m_technique == DisplacedInJSStack || m_technique == Int32DisplacedInJSStack || m_technique == DoubleDisplacedInJSStack || m_technique == CellDisplacedInJSStack || m_technique == BooleanDisplacedInJSStack);
6fe7ccc8
A
268 return m_source.virtualReg;
269 }
270
271 JSValue constant() const
272 {
273 ASSERT(m_technique == Constant);
274 return JSValue::decode(m_source.constant);
275 }
276
93a37866 277 void dump(PrintStream& out) const
6fe7ccc8
A
278 {
279 switch (technique()) {
93a37866
A
280 case AlreadyInJSStack:
281 out.printf("-");
6fe7ccc8 282 break;
93a37866
A
283 case AlreadyInJSStackAsUnboxedInt32:
284 out.printf("(int32)");
6fe7ccc8 285 break;
93a37866
A
286 case AlreadyInJSStackAsUnboxedCell:
287 out.printf("(cell)");
6fe7ccc8 288 break;
93a37866
A
289 case AlreadyInJSStackAsUnboxedBoolean:
290 out.printf("(bool)");
6fe7ccc8 291 break;
93a37866
A
292 case AlreadyInJSStackAsUnboxedDouble:
293 out.printf("(double)");
6fe7ccc8
A
294 break;
295 case InGPR:
93a37866 296 out.printf("%%r%d", gpr());
6fe7ccc8
A
297 break;
298 case UnboxedInt32InGPR:
93a37866 299 out.printf("int32(%%r%d)", gpr());
6fe7ccc8
A
300 break;
301 case UnboxedBooleanInGPR:
93a37866 302 out.printf("bool(%%r%d)", gpr());
6fe7ccc8
A
303 break;
304 case UInt32InGPR:
93a37866 305 out.printf("uint32(%%r%d)", gpr());
6fe7ccc8
A
306 break;
307 case InFPR:
93a37866 308 out.printf("%%fr%d", fpr());
6fe7ccc8
A
309 break;
310#if USE(JSVALUE32_64)
311 case InPair:
93a37866 312 out.printf("pair(%%r%d, %%r%d)", tagGPR(), payloadGPR());
6fe7ccc8
A
313 break;
314#endif
93a37866
A
315 case DisplacedInJSStack:
316 out.printf("*%d", virtualRegister());
317 break;
318 case Int32DisplacedInJSStack:
319 out.printf("*int32(%d)", virtualRegister());
6fe7ccc8 320 break;
93a37866
A
321 case DoubleDisplacedInJSStack:
322 out.printf("*double(%d)", virtualRegister());
6fe7ccc8 323 break;
93a37866
A
324 case CellDisplacedInJSStack:
325 out.printf("*cell(%d)", virtualRegister());
6fe7ccc8 326 break;
93a37866
A
327 case BooleanDisplacedInJSStack:
328 out.printf("*bool(%d)", virtualRegister());
6fe7ccc8 329 break;
93a37866
A
330 case ArgumentsThatWereNotCreated:
331 out.printf("arguments");
6fe7ccc8
A
332 break;
333 case Constant:
93a37866 334 out.print("[", constant(), "]");
6fe7ccc8
A
335 break;
336 case DontKnow:
93a37866 337 out.printf("!");
6fe7ccc8
A
338 break;
339 default:
93a37866 340 out.printf("?%d", technique());
6fe7ccc8
A
341 break;
342 }
343 }
344
345private:
346 ValueRecoveryTechnique m_technique;
347 union {
348 MacroAssembler::RegisterID gpr;
349 MacroAssembler::FPRegisterID fpr;
350#if USE(JSVALUE32_64)
351 struct {
352 MacroAssembler::RegisterID tagGPR;
353 MacroAssembler::RegisterID payloadGPR;
354 } pair;
355#endif
356 VirtualRegister virtualReg;
357 EncodedJSValue constant;
358 } m_source;
359};
360
361} // namespace JSC
362
363#endif // ValueRecovery_h