]> git.saurik.com Git - apple/javascriptcore.git/blame - bytecode/StructureStubInfo.h
JavaScriptCore-1218.35.tar.gz
[apple/javascriptcore.git] / bytecode / StructureStubInfo.h
CommitLineData
9dae56ea 1/*
93a37866 2 * Copyright (C) 2008, 2012 Apple Inc. All rights reserved.
9dae56ea
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 StructureStubInfo_h
27#define StructureStubInfo_h
28
6fe7ccc8
A
29#include <wtf/Platform.h>
30
ba379fdc
A
31#if ENABLE(JIT)
32
6fe7ccc8 33#include "CodeOrigin.h"
93a37866 34#include "DFGRegisterSet.h"
9dae56ea 35#include "Instruction.h"
93a37866 36#include "JITStubRoutine.h"
ba379fdc 37#include "MacroAssembler.h"
9dae56ea 38#include "Opcode.h"
93a37866 39#include "PolymorphicAccessStructureList.h"
9dae56ea 40#include "Structure.h"
93a37866
A
41#include "StructureStubClearingWatchpoint.h"
42#include <wtf/OwnPtr.h>
9dae56ea
A
43
44namespace JSC {
45
93a37866
A
46class PolymorphicPutByIdList;
47
48enum 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
65inline 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;
6fe7ccc8 79 }
93a37866 80}
6fe7ccc8 81
93a37866
A
82inline 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
96struct 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)
6fe7ccc8 149 {
93a37866
A
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);
6fe7ccc8
A
158 }
159
93a37866
A
160 void initPutByIdReplace(VM& vm, JSCell* owner, Structure* baseObjectStructure)
161 {
162 accessType = access_put_by_id_replace;
9dae56ea 163
93a37866
A
164 u.putByIdReplace.baseObjectStructure.set(vm, owner, baseObjectStructure);
165 }
6fe7ccc8 166
93a37866
A
167 void initPutByIdList(PolymorphicPutByIdList* list)
168 {
169 accessType = access_put_by_id_list;
170 u.putByIdList.list = list;
171 }
6fe7ccc8 172
93a37866
A
173 void reset()
174 {
175 deref();
176 accessType = access_unset;
177 stubRoutine.clear();
178 watchpoints.clear();
179 }
9dae56ea 180
93a37866 181 void deref();
9dae56ea 182
93a37866 183 bool visitWeakReferences();
6fe7ccc8 184
93a37866
A
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 }
6fe7ccc8 200
93a37866 201 unsigned bytecodeIndex;
6fe7ccc8 202
93a37866
A
203 int8_t accessType;
204 bool seen : 1;
205 bool resetByGC : 1;
f9bf01c6 206
6fe7ccc8 207#if ENABLE(DFG_JIT)
93a37866 208 CodeOrigin codeOrigin;
6fe7ccc8 209#endif // ENABLE(DFG_JIT)
f9bf01c6 210
93a37866
A
211 union {
212 struct {
213 int8_t registersFlushed;
214 int8_t baseGPR;
6fe7ccc8 215#if USE(JSVALUE32_64)
93a37866 216 int8_t valueTagGPR;
6fe7ccc8 217#endif
93a37866
A
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;
6fe7ccc8 225#if USE(JSVALUE64)
93a37866 226 int32_t deltaCallToLoadOrStore;
6fe7ccc8 227#else
93a37866
A
228 int32_t deltaCallToTagLoadOrStore;
229 int32_t deltaCallToPayloadLoadOrStore;
6fe7ccc8 230#endif
93a37866
A
231 } dfg;
232 struct {
233 union {
234 struct {
235 int16_t structureToCompare;
236 int16_t structureCheck;
237 int16_t propertyStorageLoad;
6fe7ccc8 238#if USE(JSVALUE64)
93a37866 239 int16_t displacementLabel;
6fe7ccc8 240#else
93a37866
A
241 int16_t displacementLabel1;
242 int16_t displacementLabel2;
6fe7ccc8 243#endif
93a37866
A
244 int16_t putResult;
245 int16_t coldPathBegin;
246 } get;
247 struct {
248 int16_t structureToCompare;
249 int16_t propertyStorageLoad;
6fe7ccc8 250#if USE(JSVALUE64)
93a37866 251 int16_t displacementLabel;
6fe7ccc8 252#else
93a37866
A
253 int16_t displacementLabel1;
254 int16_t displacementLabel2;
6fe7ccc8 255#endif
93a37866
A
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
309inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo)
310{
311 return structureStubInfo->callReturnLocation.executableAddress();
312}
313
314inline unsigned getStructureStubInfoBytecodeIndex(StructureStubInfo* structureStubInfo)
315{
316 return structureStubInfo->bytecodeIndex;
317}
6fe7ccc8 318
9dae56ea
A
319} // namespace JSC
320
6fe7ccc8 321#endif // ENABLE(JIT)
ba379fdc 322
9dae56ea 323#endif // StructureStubInfo_h