GetById list caching should use something object-oriented rather than PolymorphicAcce...
[WebKit-https.git] / Source / JavaScriptCore / 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     bool visitWeakReferences();
171         
172     bool seenOnce()
173     {
174         return seen;
175     }
176
177     void setSeen()
178     {
179         seen = true;
180     }
181         
182     StructureStubClearingWatchpoint* addWatchpoint(CodeBlock* codeBlock)
183     {
184         return WatchpointsOnStructureStubInfo::ensureReferenceAndAddWatchpoint(
185             watchpoints, codeBlock, this);
186     }
187     
188     int8_t accessType;
189     bool seen : 1;
190     bool resetByGC : 1;
191
192     CodeOrigin codeOrigin;
193
194     struct {
195         SpillRegistersMode spillMode : 8;
196         int8_t baseGPR;
197 #if USE(JSVALUE32_64)
198         int8_t valueTagGPR;
199 #endif
200         int8_t valueGPR;
201         RegisterSet usedRegisters;
202         int32_t deltaCallToDone;
203         int32_t deltaCallToStorageLoad;
204         int32_t deltaCallToJump;
205         int32_t deltaCallToSlowCase;
206         int32_t deltaCheckImmToCall;
207 #if USE(JSVALUE64)
208         int32_t deltaCallToLoadOrStore;
209 #else
210         int32_t deltaCallToTagLoadOrStore;
211         int32_t deltaCallToPayloadLoadOrStore;
212 #endif
213     } patch;
214
215     union {
216         struct {
217             // It would be unwise to put anything here, as it will surely be overwritten.
218         } unset;
219         struct {
220             WriteBarrierBase<Structure> baseObjectStructure;
221         } getByIdSelf;
222         struct {
223             WriteBarrierBase<Structure> baseObjectStructure;
224             WriteBarrierBase<Structure> prototypeStructure;
225             bool isDirect;
226         } getByIdProto;
227         struct {
228             WriteBarrierBase<Structure> baseObjectStructure;
229             WriteBarrierBase<StructureChain> chain;
230             unsigned count : 31;
231             bool isDirect : 1;
232         } getByIdChain;
233         struct {
234             PolymorphicGetByIdList* list;
235         } getByIdList;
236         struct {
237             WriteBarrierBase<Structure> previousStructure;
238             WriteBarrierBase<Structure> structure;
239             WriteBarrierBase<StructureChain> chain;
240         } putByIdTransition;
241         struct {
242             WriteBarrierBase<Structure> baseObjectStructure;
243         } putByIdReplace;
244         struct {
245             PolymorphicPutByIdList* list;
246         } putByIdList;
247         struct {
248             PolymorphicAccessStructureList* structureList;
249             int listSize;
250         } inList;
251     } u;
252
253     RefPtr<JITStubRoutine> stubRoutine;
254     CodeLocationCall callReturnLocation;
255     RefPtr<WatchpointsOnStructureStubInfo> watchpoints;
256 };
257
258 inline CodeOrigin getStructureStubInfoCodeOrigin(StructureStubInfo& structureStubInfo)
259 {
260     return structureStubInfo.codeOrigin;
261 }
262
263 typedef HashMap<CodeOrigin, StructureStubInfo*, CodeOriginApproximateHash> StubInfoMap;
264
265 #else
266
267 typedef HashMap<int, void*> StubInfoMap;
268
269 #endif // ENABLE(JIT)
270
271 } // namespace JSC
272
273 #endif // StructureStubInfo_h