]> git.saurik.com Git - apple/javascriptcore.git/blob - bytecode/StructureStubInfo.h
008996663c26784714e8250b224714c2edb3095c
[apple/javascriptcore.git] / bytecode / StructureStubInfo.h
1 /*
2 * Copyright (C) 2008, 2012, 2013, 2014 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 "CodeOrigin.h"
30 #include "Instruction.h"
31 #include "JITStubRoutine.h"
32 #include "MacroAssembler.h"
33 #include "Opcode.h"
34 #include "PolymorphicAccessStructureList.h"
35 #include "RegisterSet.h"
36 #include "SpillRegistersMode.h"
37 #include "Structure.h"
38 #include "StructureStubClearingWatchpoint.h"
39 #include <wtf/OwnPtr.h>
40
41 namespace JSC {
42
43 #if ENABLE(JIT)
44
45 class PolymorphicGetByIdList;
46 class PolymorphicPutByIdList;
47
48 enum AccessType {
49 access_get_by_id_self,
50 access_get_by_id_chain,
51 access_get_by_id_list,
52 access_put_by_id_transition_normal,
53 access_put_by_id_transition_direct,
54 access_put_by_id_replace,
55 access_put_by_id_list,
56 access_unset,
57 access_in_list
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_chain:
65 case access_get_by_id_list:
66 return true;
67 default:
68 return false;
69 }
70 }
71
72 inline bool isPutByIdAccess(AccessType accessType)
73 {
74 switch (accessType) {
75 case access_put_by_id_transition_normal:
76 case access_put_by_id_transition_direct:
77 case access_put_by_id_replace:
78 case access_put_by_id_list:
79 return true;
80 default:
81 return false;
82 }
83 }
84
85 inline bool isInAccess(AccessType accessType)
86 {
87 switch (accessType) {
88 case access_in_list:
89 return true;
90 default:
91 return false;
92 }
93 }
94
95 struct StructureStubInfo {
96 StructureStubInfo()
97 : accessType(access_unset)
98 , seen(false)
99 , resetByGC(false)
100 {
101 }
102
103 void initGetByIdSelf(VM& vm, JSCell* owner, Structure* baseObjectStructure)
104 {
105 accessType = access_get_by_id_self;
106
107 u.getByIdSelf.baseObjectStructure.set(vm, owner, baseObjectStructure);
108 }
109
110 void initGetByIdChain(VM& vm, JSCell* owner, Structure* baseObjectStructure, StructureChain* chain, unsigned count, bool isDirect)
111 {
112 accessType = access_get_by_id_chain;
113
114 u.getByIdChain.baseObjectStructure.set(vm, owner, baseObjectStructure);
115 u.getByIdChain.chain.set(vm, owner, chain);
116 u.getByIdChain.count = count;
117 u.getByIdChain.isDirect = isDirect;
118 }
119
120 void initGetByIdList(PolymorphicGetByIdList* list)
121 {
122 accessType = access_get_by_id_list;
123 u.getByIdList.list = list;
124 }
125
126 // PutById*
127
128 void initPutByIdTransition(VM& vm, JSCell* owner, Structure* previousStructure, Structure* structure, StructureChain* chain, bool isDirect)
129 {
130 if (isDirect)
131 accessType = access_put_by_id_transition_direct;
132 else
133 accessType = access_put_by_id_transition_normal;
134
135 u.putByIdTransition.previousStructure.set(vm, owner, previousStructure);
136 u.putByIdTransition.structure.set(vm, owner, structure);
137 u.putByIdTransition.chain.set(vm, owner, chain);
138 }
139
140 void initPutByIdReplace(VM& vm, JSCell* owner, Structure* baseObjectStructure)
141 {
142 accessType = access_put_by_id_replace;
143
144 u.putByIdReplace.baseObjectStructure.set(vm, owner, baseObjectStructure);
145 }
146
147 void initPutByIdList(PolymorphicPutByIdList* list)
148 {
149 accessType = access_put_by_id_list;
150 u.putByIdList.list = list;
151 }
152
153 void initInList(PolymorphicAccessStructureList* list, int listSize)
154 {
155 accessType = access_in_list;
156 u.inList.structureList = list;
157 u.inList.listSize = listSize;
158 }
159
160 void reset()
161 {
162 deref();
163 accessType = access_unset;
164 stubRoutine.clear();
165 watchpoints.clear();
166 }
167
168 void deref();
169
170 // Check if the stub has weak references that are dead. If there are dead ones that imply
171 // that the stub should be entirely reset, this should return false. If there are dead ones
172 // that can be handled internally by the stub and don't require a full reset, then this
173 // should reset them and return true. If there are no dead weak references, return true.
174 // If this method returns true it means that it has left the stub in a state where all
175 // outgoing GC pointers are known to point to currently marked objects; this method is
176 // allowed to accomplish this by either clearing those pointers somehow or by proving that
177 // they have already been marked. It is not allowed to mark new objects.
178 bool visitWeakReferences(RepatchBuffer&);
179
180 bool seenOnce()
181 {
182 return seen;
183 }
184
185 void setSeen()
186 {
187 seen = true;
188 }
189
190 StructureStubClearingWatchpoint* addWatchpoint(CodeBlock* codeBlock)
191 {
192 return WatchpointsOnStructureStubInfo::ensureReferenceAndAddWatchpoint(
193 watchpoints, codeBlock, this);
194 }
195
196 int8_t accessType;
197 bool seen : 1;
198 bool resetByGC : 1;
199
200 CodeOrigin codeOrigin;
201
202 struct {
203 unsigned spillMode : 8;
204 int8_t baseGPR;
205 #if USE(JSVALUE32_64)
206 int8_t valueTagGPR;
207 #endif
208 int8_t valueGPR;
209 RegisterSet usedRegisters;
210 int32_t deltaCallToDone;
211 int32_t deltaCallToStorageLoad;
212 int32_t deltaCallToJump;
213 int32_t deltaCallToSlowCase;
214 int32_t deltaCheckImmToCall;
215 #if USE(JSVALUE64)
216 int32_t deltaCallToLoadOrStore;
217 #else
218 int32_t deltaCallToTagLoadOrStore;
219 int32_t deltaCallToPayloadLoadOrStore;
220 #endif
221 } patch;
222
223 union {
224 struct {
225 // It would be unwise to put anything here, as it will surely be overwritten.
226 } unset;
227 struct {
228 WriteBarrierBase<Structure> baseObjectStructure;
229 } getByIdSelf;
230 struct {
231 WriteBarrierBase<Structure> baseObjectStructure;
232 WriteBarrierBase<Structure> prototypeStructure;
233 bool isDirect;
234 } getByIdProto;
235 struct {
236 WriteBarrierBase<Structure> baseObjectStructure;
237 WriteBarrierBase<StructureChain> chain;
238 unsigned count : 31;
239 bool isDirect : 1;
240 } getByIdChain;
241 struct {
242 PolymorphicGetByIdList* list;
243 } getByIdList;
244 struct {
245 WriteBarrierBase<Structure> previousStructure;
246 WriteBarrierBase<Structure> structure;
247 WriteBarrierBase<StructureChain> chain;
248 } putByIdTransition;
249 struct {
250 WriteBarrierBase<Structure> baseObjectStructure;
251 } putByIdReplace;
252 struct {
253 PolymorphicPutByIdList* list;
254 } putByIdList;
255 struct {
256 PolymorphicAccessStructureList* structureList;
257 int listSize;
258 } inList;
259 } u;
260
261 RefPtr<JITStubRoutine> stubRoutine;
262 CodeLocationCall callReturnLocation;
263 RefPtr<WatchpointsOnStructureStubInfo> watchpoints;
264 };
265
266 inline CodeOrigin getStructureStubInfoCodeOrigin(StructureStubInfo& structureStubInfo)
267 {
268 return structureStubInfo.codeOrigin;
269 }
270
271 typedef HashMap<CodeOrigin, StructureStubInfo*, CodeOriginApproximateHash> StubInfoMap;
272
273 #else
274
275 typedef HashMap<int, void*> StubInfoMap;
276
277 #endif // ENABLE(JIT)
278
279 } // namespace JSC
280
281 #endif // StructureStubInfo_h