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