]> git.saurik.com Git - apple/javascriptcore.git/blame_incremental - bytecode/ValueRecovery.h
JavaScriptCore-7600.1.4.9.tar.gz
[apple/javascriptcore.git] / bytecode / ValueRecovery.h
... / ...
CommitLineData
1/*
2 * Copyright (C) 2011, 2013 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"
30#if ENABLE(JIT)
31#include "GPRInfo.h"
32#include "FPRInfo.h"
33#endif
34#include "JSCJSValue.h"
35#include "MacroAssembler.h"
36#include "VirtualRegister.h"
37
38namespace JSC {
39
40struct DumpContext;
41
42// Describes how to recover a given bytecode virtual register at a given
43// code point.
44enum ValueRecoveryTechnique {
45 // It's in a register.
46 InGPR,
47 UnboxedInt32InGPR,
48 UnboxedInt52InGPR,
49 UnboxedStrictInt52InGPR,
50 UnboxedBooleanInGPR,
51 UnboxedCellInGPR,
52#if USE(JSVALUE32_64)
53 InPair,
54#endif
55 InFPR,
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,
60 Int52DisplacedInJSStack,
61 StrictInt52DisplacedInJSStack,
62 DoubleDisplacedInJSStack,
63 CellDisplacedInJSStack,
64 BooleanDisplacedInJSStack,
65 // It's an Arguments object.
66 ArgumentsThatWereNotCreated,
67 // It's a constant.
68 Constant,
69 // Don't know how to recover it.
70 DontKnow
71};
72
73class ValueRecovery {
74public:
75 ValueRecovery()
76 : m_technique(DontKnow)
77 {
78 }
79
80 bool isSet() const { return m_technique != DontKnow; }
81 bool operator!() const { return !isSet(); }
82
83 static ValueRecovery inGPR(MacroAssembler::RegisterID gpr, DataFormat dataFormat)
84 {
85 ASSERT(dataFormat != DataFormatNone);
86#if USE(JSVALUE32_64)
87 ASSERT(dataFormat == DataFormatInt32 || dataFormat == DataFormatCell || dataFormat == DataFormatBoolean);
88#endif
89 ValueRecovery result;
90 if (dataFormat == DataFormatInt32)
91 result.m_technique = UnboxedInt32InGPR;
92 else if (dataFormat == DataFormatInt52)
93 result.m_technique = UnboxedInt52InGPR;
94 else if (dataFormat == DataFormatStrictInt52)
95 result.m_technique = UnboxedStrictInt52InGPR;
96 else if (dataFormat == DataFormatBoolean)
97 result.m_technique = UnboxedBooleanInGPR;
98 else if (dataFormat == DataFormatCell)
99 result.m_technique = UnboxedCellInGPR;
100 else
101 result.m_technique = InGPR;
102 result.m_source.gpr = gpr;
103 return result;
104 }
105
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
125 static ValueRecovery displacedInJSStack(VirtualRegister virtualReg, DataFormat dataFormat)
126 {
127 ValueRecovery result;
128 switch (dataFormat) {
129 case DataFormatInt32:
130 result.m_technique = Int32DisplacedInJSStack;
131 break;
132
133 case DataFormatInt52:
134 result.m_technique = Int52DisplacedInJSStack;
135 break;
136
137 case DataFormatStrictInt52:
138 result.m_technique = StrictInt52DisplacedInJSStack;
139 break;
140
141 case DataFormatDouble:
142 result.m_technique = DoubleDisplacedInJSStack;
143 break;
144
145 case DataFormatCell:
146 result.m_technique = CellDisplacedInJSStack;
147 break;
148
149 case DataFormatBoolean:
150 result.m_technique = BooleanDisplacedInJSStack;
151 break;
152
153 default:
154 ASSERT(dataFormat != DataFormatNone && dataFormat != DataFormatStorage);
155 result.m_technique = DisplacedInJSStack;
156 break;
157 }
158 result.m_source.virtualReg = virtualReg.offset();
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
170 static ValueRecovery argumentsThatWereNotCreated()
171 {
172 ValueRecovery result;
173 result.m_technique = ArgumentsThatWereNotCreated;
174 return result;
175 }
176
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:
187 case UnboxedCellInGPR:
188 case UnboxedInt52InGPR:
189 case UnboxedStrictInt52InGPR:
190#if USE(JSVALUE32_64)
191 case InPair:
192#endif
193 case InFPR:
194 return true;
195 default:
196 return false;
197 }
198 }
199
200 MacroAssembler::RegisterID gpr() const
201 {
202 ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UnboxedInt52InGPR || m_technique == UnboxedStrictInt52InGPR || m_technique == UnboxedCellInGPR);
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 {
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);
230 }
231
232 ValueRecovery withLocalsOffset(int offset) const
233 {
234 switch (m_technique) {
235 case DisplacedInJSStack:
236 case Int32DisplacedInJSStack:
237 case DoubleDisplacedInJSStack:
238 case CellDisplacedInJSStack:
239 case BooleanDisplacedInJSStack:
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
248 default:
249 return *this;
250 }
251 }
252
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
266private:
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
277 int virtualReg;
278 EncodedJSValue constant;
279 } m_source;
280};
281
282} // namespace JSC
283
284#endif // ValueRecovery_h