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