Changeset 128084 in webkit for trunk/Source/JavaScriptCore/heap/MarkStack.h
- Timestamp:
- Sep 10, 2012, 11:41:05 AM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/heap/MarkStack.h
r126354 r128084 27 27 #define MarkStack_h 28 28 29 #include "CopiedSpace.h"30 #include "HandleTypes.h"31 #include "JSValue.h"32 #include "Options.h"33 #include "Register.h"34 #include "UnconditionalFinalizer.h"35 #include "VTableSpectrum.h"36 #include "WeakReferenceHarvester.h"37 #include <wtf/DataLog.h>38 #include <wtf/Forward.h>39 #include <wtf/HashMap.h>40 #include <wtf/HashSet.h>41 #include <wtf/Noncopyable.h>42 #include <wtf/OSAllocator.h>43 #include <wtf/PageBlock.h>44 #include <wtf/TCSpinLock.h>45 #include <wtf/text/StringHash.h>46 #include <wtf/Vector.h>47 48 29 #if ENABLE(OBJECT_MARK_LOGGING) 49 30 #define MARK_LOG_MESSAGE0(message) dataLog(message) … … 70 51 #endif 71 52 53 #include <wtf/StdLibExtras.h> 54 #include <wtf/TCSpinLock.h> 55 72 56 namespace JSC { 73 57 74 class ConservativeRoots; 75 class JSGlobalData; 76 class MarkStack; 77 class GCThreadSharedData; 78 class ParallelModeEnabler; 79 class Register; 80 class SlotVisitor; 81 template<typename T> class WriteBarrierBase; 82 template<typename T> class JITWriteBarrier; 83 84 struct MarkStackSegment { 85 MarkStackSegment* m_previous; 58 class JSCell; 59 60 struct MarkStackSegment { 61 MarkStackSegment* m_previous; 86 62 #if !ASSERT_DISABLED 87 63 size_t m_top; 88 64 #endif 89 65 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 66 const JSCell** data() 67 { 68 return bitwise_cast<const JSCell**>(this + 1); 69 } 70 71 static size_t capacityFromSize(size_t size) 72 { 73 return (size - sizeof(MarkStackSegment)) / sizeof(const JSCell*); 74 } 75 76 static size_t sizeFromCapacity(size_t capacity) 77 { 78 return sizeof(MarkStackSegment) + capacity * sizeof(const JSCell*); 79 } 80 }; 105 81 106 107 108 109 110 111 112 113 114 115 116 117 118 119 82 class MarkStackSegmentAllocator { 83 public: 84 MarkStackSegmentAllocator(); 85 ~MarkStackSegmentAllocator(); 86 87 MarkStackSegment* allocate(); 88 void release(MarkStackSegment*); 89 90 void shrinkReserve(); 91 92 private: 93 SpinLock m_lock; 94 MarkStackSegment* m_nextFreeSegment; 95 }; 120 96 121 122 123 124 97 class MarkStackArray { 98 public: 99 MarkStackArray(MarkStackSegmentAllocator&); 100 ~MarkStackArray(); 125 101 126 102 void append(const JSCell*); 127 103 128 bool canRemoveLast(); 129 const JSCell* removeLast(); 130 bool refill(); 131 132 bool isEmpty(); 133 134 void donateSomeCellsTo(MarkStackArray& other); 135 136 void stealSomeCellsFrom(MarkStackArray& other, size_t idleThreadCount); 104 bool canRemoveLast(); 105 const JSCell* removeLast(); 106 bool refill(); 107 108 void donateSomeCellsTo(MarkStackArray& other); 109 void stealSomeCellsFrom(MarkStackArray& other, size_t idleThreadCount); 137 110 138 size_t size(); 111 size_t size(); 112 bool isEmpty(); 139 113 140 private: 141 MarkStackSegment* m_topSegment; 142 143 JS_EXPORT_PRIVATE void expand(); 144 145 MarkStackSegmentAllocator& m_allocator; 114 private: 115 JS_EXPORT_PRIVATE void expand(); 116 117 size_t postIncTop(); 118 size_t preDecTop(); 119 void setTopForFullSegment(); 120 void setTopForEmptySegment(); 121 size_t top(); 122 123 void validatePrevious(); 146 124 147 size_t m_segmentCapacity; 148 size_t m_top; 149 size_t m_numberOfPreviousSegments; 150 151 size_t postIncTop() 152 { 153 size_t result = m_top++; 154 ASSERT(result == m_topSegment->m_top++); 155 return result; 156 } 157 158 size_t preDecTop() 159 { 160 size_t result = --m_top; 161 ASSERT(result == --m_topSegment->m_top); 162 return result; 163 } 164 165 void setTopForFullSegment() 166 { 167 ASSERT(m_topSegment->m_top == m_segmentCapacity); 168 m_top = m_segmentCapacity; 169 } 170 171 void setTopForEmptySegment() 172 { 173 ASSERT(!m_topSegment->m_top); 174 m_top = 0; 175 } 176 177 size_t top() 178 { 179 ASSERT(m_top == m_topSegment->m_top); 180 return m_top; 181 } 182 183 #if ASSERT_DISABLED 184 void validatePrevious() { } 185 #else 186 void validatePrevious() 187 { 188 unsigned count = 0; 189 for (MarkStackSegment* current = m_topSegment->m_previous; current; current = current->m_previous) 190 count++; 191 ASSERT(count == m_numberOfPreviousSegments); 192 } 193 #endif 194 }; 125 MarkStackSegment* m_topSegment; 126 MarkStackSegmentAllocator& m_allocator; 195 127 196 class MarkStack { 197 WTF_MAKE_NONCOPYABLE(MarkStack); 198 friend class HeapRootVisitor; // Allowed to mark a JSValue* or JSCell** directly. 199 200 public: 201 MarkStack(GCThreadSharedData&); 202 ~MarkStack(); 203 204 void append(ConservativeRoots&); 205 206 template<typename T> void append(JITWriteBarrier<T>*); 207 template<typename T> void append(WriteBarrierBase<T>*); 208 void appendValues(WriteBarrierBase<Unknown>*, size_t count); 209 210 template<typename T> 211 void appendUnbarrieredPointer(T**); 212 void appendUnbarrieredValue(JSValue*); 213 214 void addOpaqueRoot(void*); 215 bool containsOpaqueRoot(void*); 216 int opaqueRootCount(); 217 218 GCThreadSharedData& sharedData() { return m_shared; } 219 bool isEmpty() { return m_stack.isEmpty(); } 220 221 void setup(); 222 void reset(); 223 224 size_t visitCount() const { return m_visitCount; } 225 226 #if ENABLE(SIMPLE_HEAP_PROFILING) 227 VTableSpectrum m_visitedTypeCounts; 228 #endif 229 230 void addWeakReferenceHarvester(WeakReferenceHarvester*); 231 void addUnconditionalFinalizer(UnconditionalFinalizer*); 232 233 #if ENABLE(OBJECT_MARK_LOGGING) 234 inline void resetChildCount() { m_logChildCount = 0; } 235 inline unsigned childCount() { return m_logChildCount; } 236 inline void incrementChildCount() { m_logChildCount++; } 237 #endif 238 239 protected: 240 JS_EXPORT_PRIVATE static void validate(JSCell*); 241 242 void append(JSValue*); 243 void append(JSValue*, size_t count); 244 void append(JSCell**); 245 246 void internalAppend(JSCell*); 247 void internalAppend(JSValue); 248 void internalAppend(JSValue*); 249 250 JS_EXPORT_PRIVATE void mergeOpaqueRoots(); 251 252 void mergeOpaqueRootsIfNecessary() 253 { 254 if (m_opaqueRoots.isEmpty()) 255 return; 256 mergeOpaqueRoots(); 257 } 258 259 void mergeOpaqueRootsIfProfitable() 260 { 261 if (static_cast<unsigned>(m_opaqueRoots.size()) < Options::opaqueRootMergeThreshold()) 262 return; 263 mergeOpaqueRoots(); 264 } 265 266 MarkStackArray m_stack; 267 HashSet<void*> m_opaqueRoots; // Handle-owning data structures not visible to the garbage collector. 268 269 #if !ASSERT_DISABLED 270 public: 271 bool m_isCheckingForDefaultMarkViolation; 272 bool m_isDraining; 273 #endif 274 protected: 275 friend class ParallelModeEnabler; 276 277 size_t m_visitCount; 278 bool m_isInParallelMode; 279 280 GCThreadSharedData& m_shared; 281 282 bool m_shouldHashConst; // Local per-thread copy of shared flag for performance reasons 283 typedef HashMap<StringImpl*, JSValue> UniqueStringMap; 284 UniqueStringMap m_uniqueStrings; 285 286 #if ENABLE(OBJECT_MARK_LOGGING) 287 unsigned m_logChildCount; 288 #endif 289 }; 290 291 inline void MarkStackArray::append(const JSCell* cell) 292 { 293 if (m_top == m_segmentCapacity) 294 expand(); 295 m_topSegment->data()[postIncTop()] = cell; 296 } 297 298 inline bool MarkStackArray::canRemoveLast() 299 { 300 return !!m_top; 301 } 302 303 inline const JSCell* MarkStackArray::removeLast() 304 { 305 return m_topSegment->data()[preDecTop()]; 306 } 307 308 inline bool MarkStackArray::isEmpty() 309 { 310 if (m_top) 311 return false; 312 if (m_topSegment->m_previous) { 313 ASSERT(m_topSegment->m_previous->m_top == m_segmentCapacity); 314 return false; 315 } 316 return true; 317 } 318 319 inline size_t MarkStackArray::size() 320 { 321 return m_top + m_segmentCapacity * m_numberOfPreviousSegments; 322 } 323 324 class ParallelModeEnabler { 325 public: 326 ParallelModeEnabler(MarkStack& stack) 327 : m_stack(stack) 328 { 329 ASSERT(!m_stack.m_isInParallelMode); 330 m_stack.m_isInParallelMode = true; 331 } 332 333 ~ParallelModeEnabler() 334 { 335 ASSERT(m_stack.m_isInParallelMode); 336 m_stack.m_isInParallelMode = false; 337 } 338 339 private: 340 MarkStack& m_stack; 341 }; 128 size_t m_segmentCapacity; 129 size_t m_top; 130 size_t m_numberOfPreviousSegments; 131 132 }; 342 133 343 134 } // namespace JSC
Note:
See TracChangeset
for help on using the changeset viewer.