]> git.saurik.com Git - apple/javascriptcore.git/blob - bytecode/StructureStubInfo.h
JavaScriptCore-1218.34.tar.gz
[apple/javascriptcore.git] / bytecode / StructureStubInfo.h
1 /*
2 * Copyright (C) 2008, 2012 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 StructureStubInfo_h
27 #define StructureStubInfo_h
28
29 #include <wtf/Platform.h>
30
31 #if ENABLE(JIT)
32
33 #include "CodeOrigin.h"
34 #include "DFGRegisterSet.h"
35 #include "Instruction.h"
36 #include "JITStubRoutine.h"
37 #include "MacroAssembler.h"
38 #include "Opcode.h"
39 #include "PolymorphicAccessStructureList.h"
40 #include "Structure.h"
41 #include "StructureStubClearingWatchpoint.h"
42 #include <wtf/OwnPtr.h>
43
44 namespace JSC {
45
46 class PolymorphicPutByIdList;
47
48 enum AccessType {
49 access_get_by_id_self,
50 access_get_by_id_proto,
51 access_get_by_id_chain,
52 access_get_by_id_self_list,
53 access_get_by_id_proto_list,
54 access_put_by_id_transition_normal,
55 access_put_by_id_transition_direct,
56 access_put_by_id_replace,
57 access_put_by_id_list,
58 access_unset,
59 access_get_by_id_generic,
60 access_put_by_id_generic,
61 access_get_array_length,
62 access_get_string_length,
63 };
64
65 inline bool isGetByIdAccess(AccessType accessType)
66 {
67 switch (accessType) {
68 case access_get_by_id_self:
69 case access_get_by_id_proto:
70 case access_get_by_id_chain:
71 case access_get_by_id_self_list:
72 case access_get_by_id_proto_list:
73 case access_get_by_id_generic:
74 case access_get_array_length:
75 case access_get_string_length:
76 return true;
77 default:
78 return false;
79 }
80 }
81
82 inline bool isPutByIdAccess(AccessType accessType)
83 {
84 switch (accessType) {
85 case access_put_by_id_transition_normal:
86 case access_put_by_id_transition_direct:
87 case access_put_by_id_replace:
88 case access_put_by_id_list:
89 case access_put_by_id_generic:
90 return true;
91 default:
92 return false;
93 }
94 }
95
96 struct StructureStubInfo {
97 StructureStubInfo()
98 : accessType(access_unset)
99 , seen(false)
100 , resetByGC(false)
101 {
102 }
103
104 void initGetByIdSelf(VM& vm, JSCell* owner, Structure* baseObjectStructure)
105 {
106 accessType = access_get_by_id_self;
107
108 u.getByIdSelf.baseObjectStructure.set(vm, owner, baseObjectStructure);
109 }
110
111 void initGetByIdProto(VM& vm, JSCell* owner, Structure* baseObjectStructure, Structure* prototypeStructure, bool isDirect)
112 {
113 accessType = access_get_by_id_proto;
114
115 u.getByIdProto.baseObjectStructure.set(vm, owner, baseObjectStructure);
116 u.getByIdProto.prototypeStructure.set(vm, owner, prototypeStructure);
117 u.getByIdProto.isDirect = isDirect;
118 }
119
120 void initGetByIdChain(VM& vm, JSCell* owner, Structure* baseObjectStructure, StructureChain* chain, unsigned count, bool isDirect)
121 {
122 accessType = access_get_by_id_chain;
123
124 u.getByIdChain.baseObjectStructure.set(vm, owner, baseObjectStructure);
125 u.getByIdChain.chain.set(vm, owner, chain);
126 u.getByIdChain.count = count;
127 u.getByIdChain.isDirect = isDirect;
128 }
129
130 void initGetByIdSelfList(PolymorphicAccessStructureList* structureList, int listSize)
131 {
132 accessType = access_get_by_id_self_list;
133
134 u.getByIdSelfList.structureList = structureList;
135 u.getByIdSelfList.listSize = listSize;
136 }
137
138 void initGetByIdProtoList(PolymorphicAccessStructureList* structureList, int listSize)
139 {
140 accessType = access_get_by_id_proto_list;
141
142 u.getByIdProtoList.structureList = structureList;
143 u.getByIdProtoList.listSize = listSize;
144 }
145
146 // PutById*
147
148 void initPutByIdTransition(VM& vm, JSCell* owner, Structure* previousStructure, Structure* structure, StructureChain* chain, bool isDirect)
149 {
150 if (isDirect)
151 accessType = access_put_by_id_transition_direct;
152 else
153 accessType = access_put_by_id_transition_normal;
154
155 u.putByIdTransition.previousStructure.set(vm, owner, previousStructure);
156 u.putByIdTransition.structure.set(vm, owner, structure);
157 u.putByIdTransition.chain.set(vm, owner, chain);
158 }
159
160 void initPutByIdReplace(VM& vm, JSCell* owner, Structure* baseObjectStructure)
161 {
162 accessType = access_put_by_id_replace;
163
164 u.putByIdReplace.baseObjectStructure.set(vm, owner, baseObjectStructure);
165 }
166
167 void initPutByIdList(PolymorphicPutByIdList* list)
168 {
169 accessType = access_put_by_id_list;
170 u.putByIdList.list = list;
171 }
172
173 void reset()
174 {
175 deref();
176 accessType = access_unset;
177 stubRoutine.clear();
178 watchpoints.clear();
179 }
180
181 void deref();
182
183 bool visitWeakReferences();
184
185 bool seenOnce()
186 {
187 return seen;
188 }
189
190 void setSeen()
191 {
192 seen = true;
193 }
194
195 StructureStubClearingWatchpoint* addWatchpoint(CodeBlock* codeBlock)
196 {
197 return WatchpointsOnStructureStubInfo::ensureReferenceAndAddWatchpoint(
198 watchpoints, codeBlock, this);
199 }
200
201 unsigned bytecodeIndex;
202
203 int8_t accessType;
204 bool seen : 1;
205 bool resetByGC : 1;
206
207 #if ENABLE(DFG_JIT)
208 CodeOrigin codeOrigin;
209 #endif // ENABLE(DFG_JIT)
210
211 union {
212 struct {
213 int8_t registersFlushed;
214 int8_t baseGPR;
215 #if USE(JSVALUE32_64)
216 int8_t valueTagGPR;
217 #endif
218 int8_t valueGPR;
219 DFG::RegisterSetPOD usedRegisters;
220 int32_t deltaCallToDone;
221 int32_t deltaCallToStorageLoad;
222 int32_t deltaCallToStructCheck;
223 int32_t deltaCallToSlowCase;
224 int32_t deltaCheckImmToCall;
225 #if USE(JSVALUE64)
226 int32_t deltaCallToLoadOrStore;
227 #else
228 int32_t deltaCallToTagLoadOrStore;
229 int32_t deltaCallToPayloadLoadOrStore;
230 #endif
231 } dfg;
232 struct {
233 union {
234 struct {
235 int16_t structureToCompare;
236 int16_t structureCheck;
237 int16_t propertyStorageLoad;
238 #if USE(JSVALUE64)
239 int16_t displacementLabel;
240 #else
241 int16_t displacementLabel1;
242 int16_t displacementLabel2;
243 #endif
244 int16_t putResult;
245 int16_t coldPathBegin;
246 } get;
247 struct {
248 int16_t structureToCompare;
249 int16_t propertyStorageLoad;
250 #if USE(JSVALUE64)
251 int16_t displacementLabel;
252 #else
253 int16_t displacementLabel1;
254 int16_t displacementLabel2;
255 #endif
256 } put;
257 } u;
258 int16_t methodCheckProtoObj;
259 int16_t methodCheckProtoStructureToCompare;
260 int16_t methodCheckPutFunction;
261 } baseline;
262 } patch;
263
264 union {
265 struct {
266 // It would be unwise to put anything here, as it will surely be overwritten.
267 } unset;
268 struct {
269 WriteBarrierBase<Structure> baseObjectStructure;
270 } getByIdSelf;
271 struct {
272 WriteBarrierBase<Structure> baseObjectStructure;
273 WriteBarrierBase<Structure> prototypeStructure;
274 bool isDirect;
275 } getByIdProto;
276 struct {
277 WriteBarrierBase<Structure> baseObjectStructure;
278 WriteBarrierBase<StructureChain> chain;
279 unsigned count : 31;
280 bool isDirect : 1;
281 } getByIdChain;
282 struct {
283 PolymorphicAccessStructureList* structureList;
284 int listSize;
285 } getByIdSelfList;
286 struct {
287 PolymorphicAccessStructureList* structureList;
288 int listSize;
289 } getByIdProtoList;
290 struct {
291 WriteBarrierBase<Structure> previousStructure;
292 WriteBarrierBase<Structure> structure;
293 WriteBarrierBase<StructureChain> chain;
294 } putByIdTransition;
295 struct {
296 WriteBarrierBase<Structure> baseObjectStructure;
297 } putByIdReplace;
298 struct {
299 PolymorphicPutByIdList* list;
300 } putByIdList;
301 } u;
302
303 RefPtr<JITStubRoutine> stubRoutine;
304 CodeLocationCall callReturnLocation;
305 CodeLocationLabel hotPathBegin;
306 RefPtr<WatchpointsOnStructureStubInfo> watchpoints;
307 };
308
309 inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo)
310 {
311 return structureStubInfo->callReturnLocation.executableAddress();
312 }
313
314 inline unsigned getStructureStubInfoBytecodeIndex(StructureStubInfo* structureStubInfo)
315 {
316 return structureStubInfo->bytecodeIndex;
317 }
318
319 } // namespace JSC
320
321 #endif // ENABLE(JIT)
322
323 #endif // StructureStubInfo_h