2 * Copyright (C) 2008, 2012-2016 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef StructureStubInfo_h
27 #define StructureStubInfo_h
29 #include "CodeOrigin.h"
30 #include "Instruction.h"
31 #include "JITStubRoutine.h"
32 #include "MacroAssembler.h"
33 #include "ObjectPropertyConditionSet.h"
36 #include "RegisterSet.h"
37 #include "Structure.h"
38 #include "StructureSet.h"
39 #include "StructureStubClearingWatchpoint.h"
46 class AccessGenerationResult;
47 class PolymorphicAccess;
49 enum class AccessType : int8_t {
56 enum class CacheType : int8_t {
63 class StructureStubInfo {
64 WTF_MAKE_NONCOPYABLE(StructureStubInfo);
65 WTF_MAKE_FAST_ALLOCATED;
67 StructureStubInfo(AccessType);
70 void initGetByIdSelf(CodeBlock*, Structure* baseObjectStructure, PropertyOffset);
71 void initPutByIdReplace(CodeBlock*, Structure* baseObjectStructure, PropertyOffset);
72 void initStub(CodeBlock*, std::unique_ptr<PolymorphicAccess>);
74 AccessGenerationResult addAccessCase(CodeBlock*, const Identifier&, std::unique_ptr<AccessCase>);
76 void reset(CodeBlock*);
81 // Check if the stub has weak references that are dead. If it does, then it resets itself,
82 // either entirely or just enough to ensure that those dead pointers don't get used anymore.
83 void visitWeakReferences(CodeBlock*);
85 ALWAYS_INLINE bool considerCaching(Structure* structure)
87 // We never cache non-cells.
91 // This method is called from the Optimize variants of IC slow paths. The first part of this
92 // method tries to determine if the Optimize variant should really behave like the
93 // non-Optimize variant and leave the IC untouched.
95 // If we determine that we should do something to the IC then the next order of business is
96 // to determine if this Structure would impact the IC at all. We know that it won't, if we
97 // have already buffered something on its behalf. That's what the bufferedStructures set is
100 everConsidered = true;
102 // Check if we have been doing repatching too frequently. If so, then we should cool off
104 WTF::incrementWithSaturation(repatchCount);
105 if (repatchCount > Options::repatchCountForCoolDown()) {
106 // We've been repatching too much, so don't do it now.
108 // The amount of time we require for cool-down depends on the number of times we've
109 // had to cool down in the past. The relationship is exponential. The max value we
110 // allow here is 2^256 - 2, since the slow paths may increment the count to indicate
111 // that they'd like to temporarily skip patching just this once.
112 countdown = WTF::leftShiftWithSaturation(
113 static_cast<uint8_t>(Options::initialCoolDownCount()),
115 static_cast<uint8_t>(std::numeric_limits<uint8_t>::max() - 1));
116 WTF::incrementWithSaturation(numberOfCoolDowns);
118 // We may still have had something buffered. Trigger generation now.
119 bufferingCountdown = 0;
123 // We don't want to return false due to buffering indefinitely.
124 if (!bufferingCountdown) {
125 // Note that when this returns true, it's possible that we will not even get an
126 // AccessCase because this may cause Repatch.cpp to simply do an in-place
131 bufferingCountdown--;
133 // Now protect the IC buffering. We want to proceed only if this is a structure that
134 // we don't already have a case buffered for. Note that if this returns true but the
135 // bufferingCountdown is not zero then we will buffer the access case for later without
136 // immediately generating code for it.
137 return bufferedStructures.add(structure);
143 CodeLocationCall callReturnLocation;
145 CodeOrigin codeOrigin;
146 CallSiteIndex callSiteIndex;
148 bool containsPC(void* pc) const;
152 WriteBarrierBase<Structure> baseObjectStructure;
153 PropertyOffset offset;
155 PolymorphicAccess* stub;
158 // Represents those structures that already have buffered AccessCases in the PolymorphicAccess.
159 // Note that it's always safe to clear this. If we clear it prematurely, then if we see the same
160 // structure again during this buffering countdown, we will create an AccessCase object for it.
161 // That's not so bad - we'll get rid of the redundant ones once we regenerate.
162 StructureSet bufferedStructures;
166 #if USE(JSVALUE32_64)
171 RegisterSet usedRegisters;
172 int32_t deltaCallToDone;
173 int32_t deltaCallToJump;
174 int32_t deltaCallToSlowCase;
175 int32_t deltaCheckImmToCall;
177 int32_t deltaCallToLoadOrStore;
179 int32_t deltaCallToTagLoadOrStore;
180 int32_t deltaCallToPayloadLoadOrStore;
184 AccessType accessType;
186 uint8_t countdown; // We repatch only when this is zero. If not zero, we decrement.
187 uint8_t repatchCount;
188 uint8_t numberOfCoolDowns;
189 uint8_t bufferingCountdown;
191 bool tookSlowPath : 1;
192 bool everConsidered : 1;
195 inline CodeOrigin getStructureStubInfoCodeOrigin(StructureStubInfo& structureStubInfo)
197 return structureStubInfo.codeOrigin;
202 class StructureStubInfo;
204 #endif // ENABLE(JIT)
206 typedef HashMap<CodeOrigin, StructureStubInfo*, CodeOriginApproximateHash> StubInfoMap;
210 #endif // StructureStubInfo_h