8c4d643fc626f68527c637573b9a9785e95472d3
[WebKit-https.git] / Source / JavaScriptCore / bytecode / StructureStubInfo.h
1 /*
2  * Copyright (C) 2008, 2012-2016 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 "ObjectPropertyConditionSet.h"
34 #include "Opcode.h"
35 #include "Options.h"
36 #include "RegisterSet.h"
37 #include "Structure.h"
38 #include "StructureStubClearingWatchpoint.h"
39
40 namespace JSC {
41
42 #if ENABLE(JIT)
43
44 class AccessCase;
45 class AccessGenerationResult;
46 class PolymorphicAccess;
47
48 enum class AccessType : int8_t {
49     Get,
50     GetPure,
51     Put,
52     In
53 };
54
55 enum class CacheType : int8_t {
56     Unset,
57     GetByIdSelf,
58     PutByIdReplace,
59     Stub
60 };
61
62 class StructureStubInfo {
63     WTF_MAKE_NONCOPYABLE(StructureStubInfo);
64     WTF_MAKE_FAST_ALLOCATED;
65 public:
66     StructureStubInfo(AccessType);
67     ~StructureStubInfo();
68
69     void initGetByIdSelf(CodeBlock*, Structure* baseObjectStructure, PropertyOffset);
70     void initPutByIdReplace(CodeBlock*, Structure* baseObjectStructure, PropertyOffset);
71     void initStub(CodeBlock*, std::unique_ptr<PolymorphicAccess>);
72
73     AccessGenerationResult addAccessCase(CodeBlock*, const Identifier&, std::unique_ptr<AccessCase>);
74
75     void reset(CodeBlock*);
76
77     void deref();
78     void aboutToDie();
79
80     // Check if the stub has weak references that are dead. If it does, then it resets itself,
81     // either entirely or just enough to ensure that those dead pointers don't get used anymore.
82     void visitWeakReferences(CodeBlock*);
83         
84     ALWAYS_INLINE bool considerCaching()
85     {
86         everConsidered = true;
87         if (!countdown) {
88             // Check if we have been doing repatching too frequently. If so, then we should cool off
89             // for a while.
90             willRepatch();
91             if (repatchCount > Options::repatchCountForCoolDown()) {
92                 // We've been repatching too much, so don't do it now.
93                 repatchCount = 0;
94                 // The amount of time we require for cool-down depends on the number of times we've
95                 // had to cool down in the past. The relationship is exponential. The max value we
96                 // allow here is 2^256 - 2, since the slow paths may increment the count to indicate
97                 // that they'd like to temporarily skip patching just this once.
98                 countdown = WTF::leftShiftWithSaturation(
99                     static_cast<uint8_t>(Options::initialCoolDownCount()),
100                     numberOfCoolDowns,
101                     static_cast<uint8_t>(std::numeric_limits<uint8_t>::max() - 1));
102                 willCoolDown();
103                 return false;
104             }
105             return true;
106         }
107         countdown--;
108         return false;
109     }
110
111     ALWAYS_INLINE void willRepatch()
112     {
113         WTF::incrementWithSaturation(repatchCount);
114     }
115
116     ALWAYS_INLINE void willCoolDown()
117     {
118         WTF::incrementWithSaturation(numberOfCoolDowns);
119     }
120
121     CodeLocationCall callReturnLocation;
122
123     CodeOrigin codeOrigin;
124     CallSiteIndex callSiteIndex;
125
126     bool containsPC(void* pc) const;
127
128     union {
129         struct {
130             WriteBarrierBase<Structure> baseObjectStructure;
131             PropertyOffset offset;
132         } byIdSelf;
133         PolymorphicAccess* stub;
134     } u;
135
136     struct {
137         int8_t baseGPR;
138 #if USE(JSVALUE32_64)
139         int8_t valueTagGPR;
140         int8_t baseTagGPR;
141 #endif
142         int8_t valueGPR;
143         RegisterSet usedRegisters;
144         int32_t deltaCallToDone;
145         int32_t deltaCallToJump;
146         int32_t deltaCallToSlowCase;
147         int32_t deltaCheckImmToCall;
148 #if USE(JSVALUE64)
149         int32_t deltaCallToLoadOrStore;
150 #else
151         int32_t deltaCallToTagLoadOrStore;
152         int32_t deltaCallToPayloadLoadOrStore;
153 #endif
154     } patch;
155
156     AccessType accessType;
157     CacheType cacheType;
158     uint8_t countdown; // We repatch only when this is zero. If not zero, we decrement.
159     uint8_t repatchCount;
160     uint8_t numberOfCoolDowns;
161     bool resetByGC : 1;
162     bool tookSlowPath : 1;
163     bool everConsidered : 1;
164 };
165
166 inline CodeOrigin getStructureStubInfoCodeOrigin(StructureStubInfo& structureStubInfo)
167 {
168     return structureStubInfo.codeOrigin;
169 }
170
171 #else
172
173 class StructureStubInfo;
174
175 #endif // ENABLE(JIT)
176
177 typedef HashMap<CodeOrigin, StructureStubInfo*, CodeOriginApproximateHash> StubInfoMap;
178
179 } // namespace JSC
180
181 #endif // StructureStubInfo_h