Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: third_party/WebKit/Source/platform/heap/Heap.cpp

Issue 1919773002: Revert of Prepare for multiple ThreadHeaps (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 #include "wtf/allocator/Partitions.h" 51 #include "wtf/allocator/Partitions.h"
52 52
53 namespace blink { 53 namespace blink {
54 54
55 HeapAllocHooks::AllocationHook* HeapAllocHooks::m_allocationHook = nullptr; 55 HeapAllocHooks::AllocationHook* HeapAllocHooks::m_allocationHook = nullptr;
56 HeapAllocHooks::FreeHook* HeapAllocHooks::m_freeHook = nullptr; 56 HeapAllocHooks::FreeHook* HeapAllocHooks::m_freeHook = nullptr;
57 57
58 class ParkThreadsScope final { 58 class ParkThreadsScope final {
59 STACK_ALLOCATED(); 59 STACK_ALLOCATED();
60 public: 60 public:
61 explicit ParkThreadsScope(ThreadState* state) 61 ParkThreadsScope()
62 : m_state(state) 62 : m_shouldResumeThreads(false)
63 , m_shouldResumeThreads(false)
64 { 63 {
65 } 64 }
66 65
67 bool parkThreads() 66 bool parkThreads(ThreadState* state)
68 { 67 {
69 TRACE_EVENT0("blink_gc", "ThreadHeap::ParkThreadsScope"); 68 TRACE_EVENT0("blink_gc", "ThreadHeap::ParkThreadsScope");
70 const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE(); 69 const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE();
71 if (m_state->isMainThread()) 70 if (state->isMainThread())
72 TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting"); 71 TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting");
73 72
74 // TODO(haraken): In an unlikely coincidence that two threads decide 73 // TODO(haraken): In an unlikely coincidence that two threads decide
75 // to collect garbage at the same time, avoid doing two GCs in 74 // to collect garbage at the same time, avoid doing two GCs in
76 // a row and return false. 75 // a row and return false.
77 double startTime = WTF::currentTimeMS(); 76 double startTime = WTF::currentTimeMS();
78 77
79 m_shouldResumeThreads = m_state->heap().park(); 78 m_shouldResumeThreads = ThreadState::stopThreads();
80 79
81 double timeForStoppingThreads = WTF::currentTimeMS() - startTime; 80 double timeForStoppingThreads = WTF::currentTimeMS() - startTime;
82 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, timeToStopThreadsH istogram, new CustomCountHistogram("BlinkGC.TimeForStoppingThreads", 1, 1000, 50 )); 81 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, timeToStopThreadsH istogram, new CustomCountHistogram("BlinkGC.TimeForStoppingThreads", 1, 1000, 50 ));
83 timeToStopThreadsHistogram.count(timeForStoppingThreads); 82 timeToStopThreadsHistogram.count(timeForStoppingThreads);
84 83
85 if (m_state->isMainThread()) 84 if (state->isMainThread())
86 TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState); 85 TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState);
87 return m_shouldResumeThreads; 86 return m_shouldResumeThreads;
88 } 87 }
89 88
90 ~ParkThreadsScope() 89 ~ParkThreadsScope()
91 { 90 {
92 // Only cleanup if we parked all threads in which case the GC happened 91 // Only cleanup if we parked all threads in which case the GC happened
93 // and we need to resume the other threads. 92 // and we need to resume the other threads.
94 if (m_shouldResumeThreads) 93 if (m_shouldResumeThreads)
95 m_state->heap().resume(); 94 ThreadState::resumeThreads();
96 } 95 }
97 96
98 private: 97 private:
99 ThreadState* m_state;
100 bool m_shouldResumeThreads; 98 bool m_shouldResumeThreads;
101 }; 99 };
102 100
103 void ThreadHeap::flushHeapDoesNotContainCache() 101 void ThreadHeap::flushHeapDoesNotContainCache()
104 { 102 {
105 m_heapDoesNotContainCache->flush(); 103 s_heapDoesNotContainCache->flush();
106 } 104 }
107 105
108 void ProcessHeap::init() 106 void ProcessHeap::init()
109 { 107 {
110 s_shutdownComplete = false;
111 s_totalAllocatedSpace = 0; 108 s_totalAllocatedSpace = 0;
112 s_totalAllocatedObjectSize = 0; 109 s_totalAllocatedObjectSize = 0;
113 s_totalMarkedObjectSize = 0; 110 s_totalMarkedObjectSize = 0;
114 s_isLowEndDevice = base::SysInfo::IsLowEndDevice(); 111 s_isLowEndDevice = base::SysInfo::IsLowEndDevice();
115
116 GCInfoTable::init();
117
118 if (Platform::current() && Platform::current()->currentThread())
119 Platform::current()->registerMemoryDumpProvider(BlinkGCMemoryDumpProvide r::instance(), "BlinkGC");
120 } 112 }
121 113
122 void ProcessHeap::resetHeapCounters() 114 void ProcessHeap::resetHeapCounters()
123 { 115 {
124 s_totalAllocatedObjectSize = 0; 116 s_totalAllocatedObjectSize = 0;
125 s_totalMarkedObjectSize = 0; 117 s_totalMarkedObjectSize = 0;
126 } 118 }
127 119
128 void ProcessHeap::shutdown() 120 void ThreadHeap::init()
129 { 121 {
130 ASSERT(!s_shutdownComplete); 122 ThreadState::init();
123 ProcessHeap::init();
124 s_markingStack = new CallbackStack();
125 s_postMarkingCallbackStack = new CallbackStack();
126 s_globalWeakCallbackStack = new CallbackStack();
127 // Use smallest supported block size for ephemerons.
128 s_ephemeronStack = new CallbackStack(CallbackStack::kMinimalBlockSize);
129 s_heapDoesNotContainCache = new HeapDoesNotContainCache();
130 s_freePagePool = new FreePagePool();
131 s_orphanedPagePool = new OrphanedPagePool();
132 s_lastGCReason = BlinkGC::NumberOfGCReason;
133
134 GCInfoTable::init();
135
136 if (Platform::current() && Platform::current()->currentThread())
137 Platform::current()->registerMemoryDumpProvider(BlinkGCMemoryDumpProvide r::instance(), "BlinkGC");
138 }
139
140 void ThreadHeap::shutdown()
141 {
142 ASSERT(s_markingStack);
131 143
132 if (Platform::current() && Platform::current()->currentThread()) 144 if (Platform::current() && Platform::current()->currentThread())
133 Platform::current()->unregisterMemoryDumpProvider(BlinkGCMemoryDumpProvi der::instance()); 145 Platform::current()->unregisterMemoryDumpProvider(BlinkGCMemoryDumpProvi der::instance());
134 146
135 { 147 // The main thread must be the last thread that gets detached.
136 // The main thread must be the last thread that gets detached. 148 RELEASE_ASSERT(ThreadState::attachedThreads().size() == 0);
137 MutexLocker locker(ThreadHeap::allHeapsMutex());
138 RELEASE_ASSERT(ThreadHeap::allHeaps().isEmpty());
139 }
140 149
150 delete s_heapDoesNotContainCache;
151 s_heapDoesNotContainCache = nullptr;
152 delete s_freePagePool;
153 s_freePagePool = nullptr;
154 delete s_orphanedPagePool;
155 s_orphanedPagePool = nullptr;
156 delete s_globalWeakCallbackStack;
157 s_globalWeakCallbackStack = nullptr;
158 delete s_postMarkingCallbackStack;
159 s_postMarkingCallbackStack = nullptr;
160 delete s_markingStack;
161 s_markingStack = nullptr;
162 delete s_ephemeronStack;
163 s_ephemeronStack = nullptr;
141 GCInfoTable::shutdown(); 164 GCInfoTable::shutdown();
142 ASSERT(ProcessHeap::totalAllocatedSpace() == 0); 165 ThreadState::shutdown();
143 s_shutdownComplete = true; 166 ASSERT(ThreadHeap::heapStats().allocatedSpace() == 0);
144 } 167 }
145 168
146 CrossThreadPersistentRegion& ProcessHeap::crossThreadPersistentRegion() 169 CrossThreadPersistentRegion& ProcessHeap::crossThreadPersistentRegion()
147 { 170 {
148 DEFINE_THREAD_SAFE_STATIC_LOCAL(CrossThreadPersistentRegion, persistentRegio n, new CrossThreadPersistentRegion()); 171 DEFINE_THREAD_SAFE_STATIC_LOCAL(CrossThreadPersistentRegion, persistentRegio n, new CrossThreadPersistentRegion());
149 return persistentRegion; 172 return persistentRegion;
150 } 173 }
151 174
152 bool ProcessHeap::s_shutdownComplete = false;
153 bool ProcessHeap::s_isLowEndDevice = false; 175 bool ProcessHeap::s_isLowEndDevice = false;
154 size_t ProcessHeap::s_totalAllocatedSpace = 0; 176 size_t ProcessHeap::s_totalAllocatedSpace = 0;
155 size_t ProcessHeap::s_totalAllocatedObjectSize = 0; 177 size_t ProcessHeap::s_totalAllocatedObjectSize = 0;
156 size_t ProcessHeap::s_totalMarkedObjectSize = 0; 178 size_t ProcessHeap::s_totalMarkedObjectSize = 0;
157 179
158 ThreadHeapStats::ThreadHeapStats() 180 ThreadHeapStats::ThreadHeapStats()
159 : m_allocatedSpace(0) 181 : m_allocatedSpace(0)
160 , m_allocatedObjectSize(0) 182 , m_allocatedObjectSize(0)
161 , m_objectSizeAtLastGC(0) 183 , m_objectSizeAtLastGC(0)
162 , m_markedObjectSize(0) 184 , m_markedObjectSize(0)
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 atomicAdd(&m_allocatedSpace, static_cast<long>(delta)); 237 atomicAdd(&m_allocatedSpace, static_cast<long>(delta));
216 ProcessHeap::increaseTotalAllocatedSpace(delta); 238 ProcessHeap::increaseTotalAllocatedSpace(delta);
217 } 239 }
218 240
219 void ThreadHeapStats::decreaseAllocatedSpace(size_t delta) 241 void ThreadHeapStats::decreaseAllocatedSpace(size_t delta)
220 { 242 {
221 atomicSubtract(&m_allocatedSpace, static_cast<long>(delta)); 243 atomicSubtract(&m_allocatedSpace, static_cast<long>(delta));
222 ProcessHeap::decreaseTotalAllocatedSpace(delta); 244 ProcessHeap::decreaseTotalAllocatedSpace(delta);
223 } 245 }
224 246
225 ThreadHeap::ThreadHeap()
226 : m_regionTree(adoptPtr(new RegionTree()))
227 , m_heapDoesNotContainCache(adoptPtr(new HeapDoesNotContainCache))
228 , m_safePointBarrier(adoptPtr(new SafePointBarrier()))
229 , m_freePagePool(adoptPtr(new FreePagePool))
230 , m_orphanedPagePool(adoptPtr(new OrphanedPagePool))
231 , m_markingStack(adoptPtr(new CallbackStack()))
232 , m_postMarkingCallbackStack(adoptPtr(new CallbackStack()))
233 , m_globalWeakCallbackStack(adoptPtr(new CallbackStack()))
234 , m_ephemeronStack(adoptPtr(new CallbackStack(CallbackStack::kMinimalBlockSi ze)))
235 {
236 if (ThreadState::current()->isMainThread())
237 s_mainThreadHeap = this;
238
239 MutexLocker locker(ThreadHeap::allHeapsMutex());
240 allHeaps().add(this);
241 }
242
243 ThreadHeap::~ThreadHeap()
244 {
245 MutexLocker locker(ThreadHeap::allHeapsMutex());
246 allHeaps().remove(this);
247 }
248
249 RecursiveMutex& ThreadHeap::allHeapsMutex()
250 {
251 DEFINE_THREAD_SAFE_STATIC_LOCAL(RecursiveMutex, mutex, (new RecursiveMutex)) ;
252 return mutex;
253 }
254
255 HashSet<ThreadHeap*>& ThreadHeap::allHeaps()
256 {
257 DEFINE_STATIC_LOCAL(HashSet<ThreadHeap*>, heaps, ());
258 return heaps;
259 }
260
261 void ThreadHeap::attach(ThreadState* thread)
262 {
263 MutexLocker locker(m_threadAttachMutex);
264 m_threads.add(thread);
265 }
266
267 void ThreadHeap::detach(ThreadState* thread)
268 {
269 ASSERT(ThreadState::current() == thread);
270 {
271 // Grab the threadAttachMutex to ensure only one thread can shutdown at
272 // a time and that no other thread can do a global GC. It also allows
273 // safe iteration of the m_threads set which happens as part of
274 // thread local GC asserts. We enter a safepoint while waiting for the
275 // lock to avoid a dead-lock where another thread has already requested
276 // GC.
277 SafePointAwareMutexLocker locker(m_threadAttachMutex, BlinkGC::NoHeapPoi ntersOnStack);
278 thread->runTerminationGC();
279 ASSERT(m_threads.contains(thread));
280 m_threads.remove(thread);
281 }
282 // The main thread must be the last thread that gets detached.
283 ASSERT(!thread->isMainThread() || m_threads.isEmpty());
284 if (thread->isMainThread()) {
285 ASSERT(heapStats().allocatedSpace() == 0);
286 delete this;
287 }
288 }
289
290 bool ThreadHeap::park()
291 {
292 return m_safePointBarrier->parkOthers();
293 }
294
295 void ThreadHeap::resume()
296 {
297 m_safePointBarrier->resumeOthers();
298 }
299
300 #if ENABLE(ASSERT) 247 #if ENABLE(ASSERT)
301 BasePage* ThreadHeap::findPageFromAddress(Address address) 248 BasePage* ThreadHeap::findPageFromAddress(Address address)
302 { 249 {
303 MutexLocker locker(m_threadAttachMutex); 250 MutexLocker lock(ThreadState::threadAttachMutex());
304 for (ThreadState* state : m_threads) { 251 for (ThreadState* state : ThreadState::attachedThreads()) {
305 if (BasePage* page = state->findPageFromAddress(address)) 252 if (BasePage* page = state->findPageFromAddress(address))
306 return page; 253 return page;
307 } 254 }
308 return nullptr; 255 return nullptr;
309 } 256 }
310
311 bool ThreadHeap::isAtSafePoint()
312 {
313 MutexLocker locker(m_threadAttachMutex);
314 for (ThreadState* state : m_threads) {
315 if (!state->isAtSafePoint())
316 return false;
317 }
318 return true;
319 }
320 #endif 257 #endif
321 258
322 Address ThreadHeap::checkAndMarkPointer(Visitor* visitor, Address address) 259 Address ThreadHeap::checkAndMarkPointer(Visitor* visitor, Address address)
323 { 260 {
324 ASSERT(ThreadState::current()->isInGC()); 261 ASSERT(ThreadState::current()->isInGC());
325 262
326 #if !ENABLE(ASSERT) 263 #if !ENABLE(ASSERT)
327 if (m_heapDoesNotContainCache->lookup(address)) 264 if (s_heapDoesNotContainCache->lookup(address))
328 return nullptr; 265 return nullptr;
329 #endif 266 #endif
330 267
331 if (BasePage* page = lookupPageForAddress(address)) { 268 if (BasePage* page = lookup(address)) {
332 ASSERT(page->contains(address)); 269 ASSERT(page->contains(address));
333 ASSERT(!page->orphaned()); 270 ASSERT(!page->orphaned());
334 ASSERT(!m_heapDoesNotContainCache->lookup(address)); 271 ASSERT(!s_heapDoesNotContainCache->lookup(address));
335 page->checkAndMarkPointer(visitor, address); 272 page->checkAndMarkPointer(visitor, address);
336 return address; 273 return address;
337 } 274 }
338 275
339 #if !ENABLE(ASSERT) 276 #if !ENABLE(ASSERT)
340 m_heapDoesNotContainCache->addEntry(address); 277 s_heapDoesNotContainCache->addEntry(address);
341 #else 278 #else
342 if (!m_heapDoesNotContainCache->lookup(address)) 279 if (!s_heapDoesNotContainCache->lookup(address))
343 m_heapDoesNotContainCache->addEntry(address); 280 s_heapDoesNotContainCache->addEntry(address);
344 #endif 281 #endif
345 return nullptr; 282 return nullptr;
346 } 283 }
347 284
348 void ThreadHeap::pushTraceCallback(void* object, TraceCallback callback) 285 void ThreadHeap::pushTraceCallback(void* object, TraceCallback callback)
349 { 286 {
350 ASSERT(ThreadState::current()->isInGC()); 287 ASSERT(ThreadState::current()->isInGC());
351 288
352 // Trace should never reach an orphaned page. 289 // Trace should never reach an orphaned page.
353 ASSERT(!getOrphanedPagePool()->contains(object)); 290 ASSERT(!ThreadHeap::getOrphanedPagePool()->contains(object));
354 CallbackStack::Item* slot = m_markingStack->allocateEntry(); 291 CallbackStack::Item* slot = s_markingStack->allocateEntry();
355 *slot = CallbackStack::Item(object, callback); 292 *slot = CallbackStack::Item(object, callback);
356 } 293 }
357 294
358 bool ThreadHeap::popAndInvokeTraceCallback(Visitor* visitor) 295 bool ThreadHeap::popAndInvokeTraceCallback(Visitor* visitor)
359 { 296 {
360 CallbackStack::Item* item = m_markingStack->pop(); 297 CallbackStack::Item* item = s_markingStack->pop();
361 if (!item) 298 if (!item)
362 return false; 299 return false;
363 item->call(visitor); 300 item->call(visitor);
364 return true; 301 return true;
365 } 302 }
366 303
367 void ThreadHeap::pushPostMarkingCallback(void* object, TraceCallback callback) 304 void ThreadHeap::pushPostMarkingCallback(void* object, TraceCallback callback)
368 { 305 {
369 ASSERT(ThreadState::current()->isInGC()); 306 ASSERT(ThreadState::current()->isInGC());
370 307
371 // Trace should never reach an orphaned page. 308 // Trace should never reach an orphaned page.
372 ASSERT(!getOrphanedPagePool()->contains(object)); 309 ASSERT(!ThreadHeap::getOrphanedPagePool()->contains(object));
373 CallbackStack::Item* slot = m_postMarkingCallbackStack->allocateEntry(); 310 CallbackStack::Item* slot = s_postMarkingCallbackStack->allocateEntry();
374 *slot = CallbackStack::Item(object, callback); 311 *slot = CallbackStack::Item(object, callback);
375 } 312 }
376 313
377 bool ThreadHeap::popAndInvokePostMarkingCallback(Visitor* visitor) 314 bool ThreadHeap::popAndInvokePostMarkingCallback(Visitor* visitor)
378 { 315 {
379 if (CallbackStack::Item* item = m_postMarkingCallbackStack->pop()) { 316 if (CallbackStack::Item* item = s_postMarkingCallbackStack->pop()) {
380 item->call(visitor); 317 item->call(visitor);
381 return true; 318 return true;
382 } 319 }
383 return false; 320 return false;
384 } 321 }
385 322
386 void ThreadHeap::pushGlobalWeakCallback(void** cell, WeakCallback callback) 323 void ThreadHeap::pushGlobalWeakCallback(void** cell, WeakCallback callback)
387 { 324 {
388 ASSERT(ThreadState::current()->isInGC()); 325 ASSERT(ThreadState::current()->isInGC());
389 326
390 // Trace should never reach an orphaned page. 327 // Trace should never reach an orphaned page.
391 ASSERT(!getOrphanedPagePool()->contains(cell)); 328 ASSERT(!ThreadHeap::getOrphanedPagePool()->contains(cell));
392 CallbackStack::Item* slot = m_globalWeakCallbackStack->allocateEntry(); 329 CallbackStack::Item* slot = s_globalWeakCallbackStack->allocateEntry();
393 *slot = CallbackStack::Item(cell, callback); 330 *slot = CallbackStack::Item(cell, callback);
394 } 331 }
395 332
396 void ThreadHeap::pushThreadLocalWeakCallback(void* closure, void* object, WeakCa llback callback) 333 void ThreadHeap::pushThreadLocalWeakCallback(void* closure, void* object, WeakCa llback callback)
397 { 334 {
398 ASSERT(ThreadState::current()->isInGC()); 335 ASSERT(ThreadState::current()->isInGC());
399 336
400 // Trace should never reach an orphaned page. 337 // Trace should never reach an orphaned page.
401 ASSERT(!getOrphanedPagePool()->contains(object)); 338 ASSERT(!ThreadHeap::getOrphanedPagePool()->contains(object));
402 ThreadState* state = pageFromObject(object)->arena()->getThreadState(); 339 ThreadState* state = pageFromObject(object)->arena()->getThreadState();
403 state->pushThreadLocalWeakCallback(closure, callback); 340 state->pushThreadLocalWeakCallback(closure, callback);
404 } 341 }
405 342
406 bool ThreadHeap::popAndInvokeGlobalWeakCallback(Visitor* visitor) 343 bool ThreadHeap::popAndInvokeGlobalWeakCallback(Visitor* visitor)
407 { 344 {
408 if (CallbackStack::Item* item = m_globalWeakCallbackStack->pop()) { 345 if (CallbackStack::Item* item = s_globalWeakCallbackStack->pop()) {
409 item->call(visitor); 346 item->call(visitor);
410 return true; 347 return true;
411 } 348 }
412 return false; 349 return false;
413 } 350 }
414 351
415 void ThreadHeap::registerWeakTable(void* table, EphemeronCallback iterationCallb ack, EphemeronCallback iterationDoneCallback) 352 void ThreadHeap::registerWeakTable(void* table, EphemeronCallback iterationCallb ack, EphemeronCallback iterationDoneCallback)
416 { 353 {
417 ASSERT(ThreadState::current()->isInGC()); 354 ASSERT(ThreadState::current()->isInGC());
418 355
419 // Trace should never reach an orphaned page. 356 // Trace should never reach an orphaned page.
420 ASSERT(!getOrphanedPagePool()->contains(table)); 357 ASSERT(!ThreadHeap::getOrphanedPagePool()->contains(table));
421 CallbackStack::Item* slot = m_ephemeronStack->allocateEntry(); 358 CallbackStack::Item* slot = s_ephemeronStack->allocateEntry();
422 *slot = CallbackStack::Item(table, iterationCallback); 359 *slot = CallbackStack::Item(table, iterationCallback);
423 360
424 // Register a post-marking callback to tell the tables that 361 // Register a post-marking callback to tell the tables that
425 // ephemeron iteration is complete. 362 // ephemeron iteration is complete.
426 pushPostMarkingCallback(table, iterationDoneCallback); 363 pushPostMarkingCallback(table, iterationDoneCallback);
427 } 364 }
428 365
429 #if ENABLE(ASSERT) 366 #if ENABLE(ASSERT)
430 bool ThreadHeap::weakTableRegistered(const void* table) 367 bool ThreadHeap::weakTableRegistered(const void* table)
431 { 368 {
432 ASSERT(m_ephemeronStack); 369 ASSERT(s_ephemeronStack);
433 return m_ephemeronStack->hasCallbackForObject(table); 370 return s_ephemeronStack->hasCallbackForObject(table);
434 } 371 }
435 #endif 372 #endif
436 373
437 void ThreadHeap::decommitCallbackStacks() 374 void ThreadHeap::decommitCallbackStacks()
438 { 375 {
439 m_markingStack->decommit(); 376 s_markingStack->decommit();
440 m_postMarkingCallbackStack->decommit(); 377 s_postMarkingCallbackStack->decommit();
441 m_globalWeakCallbackStack->decommit(); 378 s_globalWeakCallbackStack->decommit();
442 m_ephemeronStack->decommit(); 379 s_ephemeronStack->decommit();
443 } 380 }
444 381
445 void ThreadHeap::preGC() 382 void ThreadHeap::preGC()
446 { 383 {
447 ASSERT(!ThreadState::current()->isInGC()); 384 ASSERT(!ThreadState::current()->isInGC());
448 for (ThreadState* state : m_threads) { 385 for (ThreadState* state : ThreadState::attachedThreads())
449 state->preGC(); 386 state->preGC();
450 }
451 } 387 }
452 388
453 void ThreadHeap::postGC(BlinkGC::GCType gcType) 389 void ThreadHeap::postGC(BlinkGC::GCType gcType)
454 { 390 {
455 ASSERT(ThreadState::current()->isInGC()); 391 ASSERT(ThreadState::current()->isInGC());
456 for (ThreadState* state : m_threads) { 392 for (ThreadState* state : ThreadState::attachedThreads())
457 state->postGC(gcType); 393 state->postGC(gcType);
458 }
459 } 394 }
460 395
461 const char* ThreadHeap::gcReasonString(BlinkGC::GCReason reason) 396 const char* ThreadHeap::gcReasonString(BlinkGC::GCReason reason)
462 { 397 {
463 switch (reason) { 398 switch (reason) {
464 case BlinkGC::IdleGC: 399 case BlinkGC::IdleGC:
465 return "IdleGC"; 400 return "IdleGC";
466 case BlinkGC::PreciseGC: 401 case BlinkGC::PreciseGC:
467 return "PreciseGC"; 402 return "PreciseGC";
468 case BlinkGC::ConservativeGC: 403 case BlinkGC::ConservativeGC:
(...skipping 17 matching lines...) Expand all
486 ThreadState* state = ThreadState::current(); 421 ThreadState* state = ThreadState::current();
487 // Nested collectGarbage() invocations aren't supported. 422 // Nested collectGarbage() invocations aren't supported.
488 RELEASE_ASSERT(!state->isGCForbidden()); 423 RELEASE_ASSERT(!state->isGCForbidden());
489 state->completeSweep(); 424 state->completeSweep();
490 425
491 OwnPtr<Visitor> visitor = Visitor::create(state, gcType); 426 OwnPtr<Visitor> visitor = Visitor::create(state, gcType);
492 427
493 SafePointScope safePointScope(stackState, state); 428 SafePointScope safePointScope(stackState, state);
494 429
495 // Resume all parked threads upon leaving this scope. 430 // Resume all parked threads upon leaving this scope.
496 ParkThreadsScope parkThreadsScope(state); 431 ParkThreadsScope parkThreadsScope;
497 432
498 // Try to park the other threads. If we're unable to, bail out of the GC. 433 // Try to park the other threads. If we're unable to, bail out of the GC.
499 if (!parkThreadsScope.parkThreads()) 434 if (!parkThreadsScope.parkThreads(state))
500 return; 435 return;
501 436
502 ScriptForbiddenIfMainThreadScope scriptForbidden; 437 ScriptForbiddenIfMainThreadScope scriptForbidden;
503 438
504 TRACE_EVENT2("blink_gc,devtools.timeline", "BlinkGCMarking", 439 TRACE_EVENT2("blink_gc,devtools.timeline", "BlinkGCMarking",
505 "lazySweeping", gcType == BlinkGC::GCWithoutSweep, 440 "lazySweeping", gcType == BlinkGC::GCWithoutSweep,
506 "gcReason", gcReasonString(reason)); 441 "gcReason", gcReasonString(reason));
507 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC"); 442 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC");
508 double startTime = WTF::currentTimeMS(); 443 double startTime = WTF::currentTimeMS();
509 444
510 if (gcType == BlinkGC::TakeSnapshot) 445 if (gcType == BlinkGC::TakeSnapshot)
511 BlinkGCMemoryDumpProvider::instance()->clearProcessDumpForCurrentGC(); 446 BlinkGCMemoryDumpProvider::instance()->clearProcessDumpForCurrentGC();
512 447
513 // Disallow allocation during garbage collection (but not during the 448 // Disallow allocation during garbage collection (but not during the
514 // finalization that happens when the visitorScope is torn down). 449 // finalization that happens when the visitorScope is torn down).
515 ThreadState::NoAllocationScope noAllocationScope(state); 450 ThreadState::NoAllocationScope noAllocationScope(state);
516 451
517 state->heap().preGC(); 452 preGC();
518 453
519 StackFrameDepthScope stackDepthScope; 454 StackFrameDepthScope stackDepthScope;
520 455
521 size_t totalObjectSize = state->heap().heapStats().allocatedObjectSize() + s tate->heap().heapStats().markedObjectSize(); 456 size_t totalObjectSize = ThreadHeap::heapStats().allocatedObjectSize() + Thr eadHeap::heapStats().markedObjectSize();
522 if (gcType != BlinkGC::TakeSnapshot) 457 if (gcType != BlinkGC::TakeSnapshot)
523 state->heap().resetHeapCounters(); 458 ThreadHeap::resetHeapCounters();
524 459
525 // 1. Trace persistent roots. 460 // 1. Trace persistent roots.
526 state->heap().visitPersistentRoots(visitor.get()); 461 ThreadState::visitPersistentRoots(visitor.get());
527 462
528 // 2. Trace objects reachable from the stack. We do this independent of the 463 // 2. Trace objects reachable from the stack. We do this independent of the
529 // given stackState since other threads might have a different stack state. 464 // given stackState since other threads might have a different stack state.
530 state->heap().visitStackRoots(visitor.get()); 465 ThreadState::visitStackRoots(visitor.get());
531 466
532 // 3. Transitive closure to trace objects including ephemerons. 467 // 3. Transitive closure to trace objects including ephemerons.
533 state->heap().processMarkingStack(visitor.get()); 468 processMarkingStack(visitor.get());
534 469
535 state->heap().postMarkingProcessing(visitor.get()); 470 postMarkingProcessing(visitor.get());
536 state->heap().globalWeakProcessing(visitor.get()); 471 globalWeakProcessing(visitor.get());
537 472
538 // Now we can delete all orphaned pages because there are no dangling 473 // Now we can delete all orphaned pages because there are no dangling
539 // pointers to the orphaned pages. (If we have such dangling pointers, 474 // pointers to the orphaned pages. (If we have such dangling pointers,
540 // we should have crashed during marking before getting here.) 475 // we should have crashed during marking before getting here.)
541 state->heap().getOrphanedPagePool()->decommitOrphanedPages(); 476 getOrphanedPagePool()->decommitOrphanedPages();
542 477
543 double markingTimeInMilliseconds = WTF::currentTimeMS() - startTime; 478 double markingTimeInMilliseconds = WTF::currentTimeMS() - startTime;
544 state->heap().heapStats().setEstimatedMarkingTimePerByte(totalObjectSize ? ( markingTimeInMilliseconds / 1000 / totalObjectSize) : 0); 479 ThreadHeap::heapStats().setEstimatedMarkingTimePerByte(totalObjectSize ? (ma rkingTimeInMilliseconds / 1000 / totalObjectSize) : 0);
545 480
546 #if PRINT_HEAP_STATS 481 #if PRINT_HEAP_STATS
547 dataLogF("ThreadHeap::collectGarbage (gcReason=%s, lazySweeping=%d, time=%.1 lfms)\n", gcReasonString(reason), gcType == BlinkGC::GCWithoutSweep, markingTime InMilliseconds); 482 dataLogF("ThreadHeap::collectGarbage (gcReason=%s, lazySweeping=%d, time=%.1 lfms)\n", gcReasonString(reason), gcType == BlinkGC::GCWithoutSweep, markingTime InMilliseconds);
548 #endif 483 #endif
549 484
550 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, markingTimeHistogram, new CustomCountHistogram("BlinkGC.CollectGarbage", 0, 10 * 1000, 50)); 485 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, markingTimeHistogram, new CustomCountHistogram("BlinkGC.CollectGarbage", 0, 10 * 1000, 50));
551 markingTimeHistogram.count(markingTimeInMilliseconds); 486 markingTimeHistogram.count(markingTimeInMilliseconds);
552 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, totalObjectSpaceHistog ram, new CustomCountHistogram("BlinkGC.TotalObjectSpace", 0, 4 * 1024 * 1024, 50 )); 487 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, totalObjectSpaceHistog ram, new CustomCountHistogram("BlinkGC.TotalObjectSpace", 0, 4 * 1024 * 1024, 50 ));
553 totalObjectSpaceHistogram.count(ProcessHeap::totalAllocatedObjectSize() / 10 24); 488 totalObjectSpaceHistogram.count(ProcessHeap::totalAllocatedObjectSize() / 10 24);
554 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, totalAllocatedSpaceHis togram, new CustomCountHistogram("BlinkGC.TotalAllocatedSpace", 0, 4 * 1024 * 10 24, 50)); 489 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, totalAllocatedSpaceHis togram, new CustomCountHistogram("BlinkGC.TotalAllocatedSpace", 0, 4 * 1024 * 10 24, 50));
555 totalAllocatedSpaceHistogram.count(ProcessHeap::totalAllocatedSpace() / 1024 ); 490 totalAllocatedSpaceHistogram.count(ProcessHeap::totalAllocatedSpace() / 1024 );
556 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, gcReasonHistogram, new EnumerationHistogram("BlinkGC.GCReason", BlinkGC::NumberOfGCReason)); 491 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, gcReasonHistogram, new EnumerationHistogram("BlinkGC.GCReason", BlinkGC::NumberOfGCReason));
557 gcReasonHistogram.count(reason); 492 gcReasonHistogram.count(reason);
558 493
559 state->heap().m_lastGCReason = reason; 494 s_lastGCReason = reason;
560 495
561 ThreadHeap::reportMemoryUsageHistogram(); 496 ThreadHeap::reportMemoryUsageHistogram();
562 WTF::Partitions::reportMemoryUsageHistogram(); 497 WTF::Partitions::reportMemoryUsageHistogram();
563 498
564 state->heap().postGC(gcType); 499 postGC(gcType);
565 state->heap().decommitCallbackStacks(); 500 ThreadHeap::decommitCallbackStacks();
566 } 501 }
567 502
568 void ThreadHeap::collectGarbageForTerminatingThread(ThreadState* state) 503 void ThreadHeap::collectGarbageForTerminatingThread(ThreadState* state)
569 { 504 {
570 { 505 {
571 // A thread-specific termination GC must not allow other global GCs to g o 506 // A thread-specific termination GC must not allow other global GCs to g o
572 // ahead while it is running, hence the termination GC does not enter a 507 // ahead while it is running, hence the termination GC does not enter a
573 // safepoint. VisitorScope will not enter also a safepoint scope for 508 // safepoint. VisitorScope will not enter also a safepoint scope for
574 // ThreadTerminationGC. 509 // ThreadTerminationGC.
575 OwnPtr<Visitor> visitor = Visitor::create(state, BlinkGC::ThreadTerminat ionGC); 510 OwnPtr<Visitor> visitor = Visitor::create(state, BlinkGC::ThreadTerminat ionGC);
576 511
577 ThreadState::NoAllocationScope noAllocationScope(state); 512 ThreadState::NoAllocationScope noAllocationScope(state);
578 513
579 state->preGC(); 514 state->preGC();
580 515
581 // 1. Trace the thread local persistent roots. For thread local GCs we 516 // 1. Trace the thread local persistent roots. For thread local GCs we
582 // don't trace the stack (ie. no conservative scanning) since this is 517 // don't trace the stack (ie. no conservative scanning) since this is
583 // only called during thread shutdown where there should be no objects 518 // only called during thread shutdown where there should be no objects
584 // on the stack. 519 // on the stack.
585 // We also assume that orphaned pages have no objects reachable from 520 // We also assume that orphaned pages have no objects reachable from
586 // persistent handles on other threads or CrossThreadPersistents. The 521 // persistent handles on other threads or CrossThreadPersistents. The
587 // only cases where this could happen is if a subsequent conservative 522 // only cases where this could happen is if a subsequent conservative
588 // global GC finds a "pointer" on the stack or due to a programming 523 // global GC finds a "pointer" on the stack or due to a programming
589 // error where an object has a dangling cross-thread pointer to an 524 // error where an object has a dangling cross-thread pointer to an
590 // object on this heap. 525 // object on this heap.
591 state->visitPersistents(visitor.get()); 526 state->visitPersistents(visitor.get());
592 527
593 // 2. Trace objects reachable from the thread's persistent roots 528 // 2. Trace objects reachable from the thread's persistent roots
594 // including ephemerons. 529 // including ephemerons.
595 state->heap().processMarkingStack(visitor.get()); 530 processMarkingStack(visitor.get());
596 531
597 state->heap().postMarkingProcessing(visitor.get()); 532 postMarkingProcessing(visitor.get());
598 state->heap().globalWeakProcessing(visitor.get()); 533 globalWeakProcessing(visitor.get());
599 534
600 state->postGC(BlinkGC::GCWithSweep); 535 state->postGC(BlinkGC::GCWithSweep);
601 state->heap().decommitCallbackStacks(); 536 ThreadHeap::decommitCallbackStacks();
602 } 537 }
603 state->preSweep(); 538 state->preSweep();
604 } 539 }
605 540
606 void ThreadHeap::processMarkingStack(Visitor* visitor) 541 void ThreadHeap::processMarkingStack(Visitor* visitor)
607 { 542 {
608 // Ephemeron fixed point loop. 543 // Ephemeron fixed point loop.
609 do { 544 do {
610 { 545 {
611 // Iteratively mark all objects that are reachable from the objects 546 // Iteratively mark all objects that are reachable from the objects
612 // currently pushed onto the marking stack. 547 // currently pushed onto the marking stack.
613 TRACE_EVENT0("blink_gc", "ThreadHeap::processMarkingStackSingleThrea ded"); 548 TRACE_EVENT0("blink_gc", "ThreadHeap::processMarkingStackSingleThrea ded");
614 while (popAndInvokeTraceCallback(visitor)) { } 549 while (popAndInvokeTraceCallback(visitor)) { }
615 } 550 }
616 551
617 { 552 {
618 // Mark any strong pointers that have now become reachable in 553 // Mark any strong pointers that have now become reachable in
619 // ephemeron maps. 554 // ephemeron maps.
620 TRACE_EVENT0("blink_gc", "ThreadHeap::processEphemeronStack"); 555 TRACE_EVENT0("blink_gc", "ThreadHeap::processEphemeronStack");
621 m_ephemeronStack->invokeEphemeronCallbacks(visitor); 556 s_ephemeronStack->invokeEphemeronCallbacks(visitor);
622 } 557 }
623 558
624 // Rerun loop if ephemeron processing queued more objects for tracing. 559 // Rerun loop if ephemeron processing queued more objects for tracing.
625 } while (!m_markingStack->isEmpty()); 560 } while (!s_markingStack->isEmpty());
626 } 561 }
627 562
628 void ThreadHeap::postMarkingProcessing(Visitor* visitor) 563 void ThreadHeap::postMarkingProcessing(Visitor* visitor)
629 { 564 {
630 TRACE_EVENT0("blink_gc", "ThreadHeap::postMarkingProcessing"); 565 TRACE_EVENT0("blink_gc", "ThreadHeap::postMarkingProcessing");
631 // Call post-marking callbacks including: 566 // Call post-marking callbacks including:
632 // 1. the ephemeronIterationDone callbacks on weak tables to do cleanup 567 // 1. the ephemeronIterationDone callbacks on weak tables to do cleanup
633 // (specifically to clear the queued bits for weak hash tables), and 568 // (specifically to clear the queued bits for weak hash tables), and
634 // 2. the markNoTracing callbacks on collection backings to mark them 569 // 2. the markNoTracing callbacks on collection backings to mark them
635 // if they are only reachable from their front objects. 570 // if they are only reachable from their front objects.
636 while (popAndInvokePostMarkingCallback(visitor)) { } 571 while (popAndInvokePostMarkingCallback(visitor)) { }
637 572
638 // Post-marking callbacks should not trace any objects and 573 // Post-marking callbacks should not trace any objects and
639 // therefore the marking stack should be empty after the 574 // therefore the marking stack should be empty after the
640 // post-marking callbacks. 575 // post-marking callbacks.
641 ASSERT(m_markingStack->isEmpty()); 576 ASSERT(s_markingStack->isEmpty());
642 } 577 }
643 578
644 void ThreadHeap::globalWeakProcessing(Visitor* visitor) 579 void ThreadHeap::globalWeakProcessing(Visitor* visitor)
645 { 580 {
646 TRACE_EVENT0("blink_gc", "ThreadHeap::globalWeakProcessing"); 581 TRACE_EVENT0("blink_gc", "ThreadHeap::globalWeakProcessing");
647 double startTime = WTF::currentTimeMS(); 582 double startTime = WTF::currentTimeMS();
648 583
649 // Call weak callbacks on objects that may now be pointing to dead objects. 584 // Call weak callbacks on objects that may now be pointing to dead objects.
650 while (popAndInvokeGlobalWeakCallback(visitor)) { } 585 while (popAndInvokeGlobalWeakCallback(visitor)) { }
651 586
652 // It is not permitted to trace pointers of live objects in the weak 587 // It is not permitted to trace pointers of live objects in the weak
653 // callback phase, so the marking stack should still be empty here. 588 // callback phase, so the marking stack should still be empty here.
654 ASSERT(m_markingStack->isEmpty()); 589 ASSERT(s_markingStack->isEmpty());
655 590
656 double timeForGlobalWeakProcessing = WTF::currentTimeMS() - startTime; 591 double timeForGlobalWeakProcessing = WTF::currentTimeMS() - startTime;
657 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, globalWeakTimeHistogra m, new CustomCountHistogram("BlinkGC.TimeForGlobalWeakProcessing", 1, 10 * 1000, 50)); 592 DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, globalWeakTimeHistogra m, new CustomCountHistogram("BlinkGC.TimeForGlobalWeakProcessing", 1, 10 * 1000, 50));
658 globalWeakTimeHistogram.count(timeForGlobalWeakProcessing); 593 globalWeakTimeHistogram.count(timeForGlobalWeakProcessing);
659 } 594 }
660 595
661 void ThreadHeap::collectAllGarbage() 596 void ThreadHeap::collectAllGarbage()
662 { 597 {
663 // We need to run multiple GCs to collect a chain of persistent handles. 598 // We need to run multiple GCs to collect a chain of persistent handles.
664 size_t previousLiveObjects = 0; 599 size_t previousLiveObjects = 0;
665 ThreadState* state = ThreadState::current();
666 for (int i = 0; i < 5; ++i) { 600 for (int i = 0; i < 5; ++i) {
667 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, Bli nkGC::ForcedGC); 601 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, Bli nkGC::ForcedGC);
668 size_t liveObjects = state->heap().heapStats().markedObjectSize(); 602 size_t liveObjects = ThreadHeap::heapStats().markedObjectSize();
669 if (liveObjects == previousLiveObjects) 603 if (liveObjects == previousLiveObjects)
670 break; 604 break;
671 previousLiveObjects = liveObjects; 605 previousLiveObjects = liveObjects;
672 } 606 }
673 } 607 }
674 608
675 void ThreadHeap::reportMemoryUsageHistogram() 609 void ThreadHeap::reportMemoryUsageHistogram()
676 { 610 {
677 static size_t supportedMaxSizeInMB = 4 * 1024; 611 static size_t supportedMaxSizeInMB = 4 * 1024;
678 static size_t observedMaxSizeInMB = 0; 612 static size_t observedMaxSizeInMB = 0;
679 613
680 // We only report the memory in the main thread. 614 // We only report the memory in the main thread.
681 if (!isMainThread()) 615 if (!isMainThread())
682 return; 616 return;
683 // +1 is for rounding up the sizeInMB. 617 // +1 is for rounding up the sizeInMB.
684 size_t sizeInMB = ThreadState::current()->heap().heapStats().allocatedSpace( ) / 1024 / 1024 + 1; 618 size_t sizeInMB = ThreadHeap::heapStats().allocatedSpace() / 1024 / 1024 + 1 ;
685 if (sizeInMB >= supportedMaxSizeInMB) 619 if (sizeInMB >= supportedMaxSizeInMB)
686 sizeInMB = supportedMaxSizeInMB - 1; 620 sizeInMB = supportedMaxSizeInMB - 1;
687 if (sizeInMB > observedMaxSizeInMB) { 621 if (sizeInMB > observedMaxSizeInMB) {
688 // Send a UseCounter only when we see the highest memory usage 622 // Send a UseCounter only when we see the highest memory usage
689 // we've ever seen. 623 // we've ever seen.
690 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, commitedSizeHistog ram, new EnumerationHistogram("BlinkGC.CommittedSize", supportedMaxSizeInMB)); 624 DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, commitedSizeHistog ram, new EnumerationHistogram("BlinkGC.CommittedSize", supportedMaxSizeInMB));
691 commitedSizeHistogram.count(sizeInMB); 625 commitedSizeHistogram.count(sizeInMB);
692 observedMaxSizeInMB = sizeInMB; 626 observedMaxSizeInMB = sizeInMB;
693 } 627 }
694 } 628 }
695 629
696 void ThreadHeap::reportMemoryUsageForTracing() 630 void ThreadHeap::reportMemoryUsageForTracing()
697 { 631 {
698 #if PRINT_HEAP_STATS 632 #if PRINT_HEAP_STATS
699 // dataLogF("allocatedSpace=%ldMB, allocatedObjectSize=%ldMB, markedObjectSi ze=%ldMB, partitionAllocSize=%ldMB, wrapperCount=%ld, collectedWrapperCount=%ld\ n", ThreadHeap::allocatedSpace() / 1024 / 1024, ThreadHeap::allocatedObjectSize( ) / 1024 / 1024, ThreadHeap::markedObjectSize() / 1024 / 1024, WTF::Partitions:: totalSizeOfCommittedPages() / 1024 / 1024, ThreadHeap::wrapperCount(), ThreadHea p::collectedWrapperCount()); 633 // dataLogF("allocatedSpace=%ldMB, allocatedObjectSize=%ldMB, markedObjectSi ze=%ldMB, partitionAllocSize=%ldMB, wrapperCount=%ld, collectedWrapperCount=%ld\ n", ThreadHeap::allocatedSpace() / 1024 / 1024, ThreadHeap::allocatedObjectSize( ) / 1024 / 1024, ThreadHeap::markedObjectSize() / 1024 / 1024, WTF::Partitions:: totalSizeOfCommittedPages() / 1024 / 1024, ThreadHeap::wrapperCount(), ThreadHea p::collectedWrapperCount());
700 #endif 634 #endif
701 635
702 bool gcTracingEnabled; 636 bool gcTracingEnabled;
703 TRACE_EVENT_CATEGORY_GROUP_ENABLED("blink_gc", &gcTracingEnabled); 637 TRACE_EVENT_CATEGORY_GROUP_ENABLED("blink_gc", &gcTracingEnabled);
704 if (!gcTracingEnabled) 638 if (!gcTracingEnabled)
705 return; 639 return;
706 640
707 ThreadHeap& heap = ThreadState::current()->heap();
708 // These values are divided by 1024 to avoid overflow in practical cases (TR ACE_COUNTER values are 32-bit ints). 641 // These values are divided by 1024 to avoid overflow in practical cases (TR ACE_COUNTER values are 32-bit ints).
709 // They are capped to INT_MAX just in case. 642 // They are capped to INT_MAX just in case.
710 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::allocated ObjectSizeKB", std::min(heap.heapStats().allocatedObjectSize() / 1024, static_ca st<size_t>(INT_MAX))); 643 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::allocated ObjectSizeKB", std::min(ThreadHeap::heapStats().allocatedObjectSize() / 1024, st atic_cast<size_t>(INT_MAX)));
711 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::markedObj ectSizeKB", std::min(heap.heapStats().markedObjectSize() / 1024, static_cast<siz e_t>(INT_MAX))); 644 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::markedObj ectSizeKB", std::min(ThreadHeap::heapStats().markedObjectSize() / 1024, static_c ast<size_t>(INT_MAX)));
712 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::markedObj ectSizeAtLastCompleteSweepKB", std::min(heap.heapStats().markedObjectSizeAtLastC ompleteSweep() / 1024, static_cast<size_t>(INT_MAX))); 645 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::markedObj ectSizeAtLastCompleteSweepKB", std::min(ThreadHeap::heapStats().markedObjectSize AtLastCompleteSweep() / 1024, static_cast<size_t>(INT_MAX)));
713 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::allocated SpaceKB", std::min(heap.heapStats().allocatedSpace() / 1024, static_cast<size_t> (INT_MAX))); 646 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::allocated SpaceKB", std::min(ThreadHeap::heapStats().allocatedSpace() / 1024, static_cast< size_t>(INT_MAX)));
714 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::objectSiz eAtLastGCKB", std::min(heap.heapStats().objectSizeAtLastGC() / 1024, static_cast <size_t>(INT_MAX))); 647 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::objectSiz eAtLastGCKB", std::min(ThreadHeap::heapStats().objectSizeAtLastGC() / 1024, stat ic_cast<size_t>(INT_MAX)));
715 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::wrapperCo unt", std::min(heap.heapStats().wrapperCount(), static_cast<size_t>(INT_MAX))); 648 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::wrapperCo unt", std::min(ThreadHeap::heapStats().wrapperCount(), static_cast<size_t>(INT_M AX)));
716 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::wrapperCo untAtLastGC", std::min(heap.heapStats().wrapperCountAtLastGC(), static_cast<size _t>(INT_MAX))); 649 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::heapStats ().wrapperCountAtLastGC", std::min(ThreadHeap::heapStats().wrapperCountAtLastGC( ), static_cast<size_t>(INT_MAX)));
717 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::collected WrapperCount", std::min(heap.heapStats().collectedWrapperCount(), static_cast<si ze_t>(INT_MAX))); 650 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::collected WrapperCount", std::min(ThreadHeap::heapStats().collectedWrapperCount(), static_ cast<size_t>(INT_MAX)));
718 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::partition AllocSizeAtLastGCKB", std::min(heap.heapStats().partitionAllocSizeAtLastGC() / 1 024, static_cast<size_t>(INT_MAX))); 651 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadHeap::partition AllocSizeAtLastGCKB", std::min(ThreadHeap::heapStats().partitionAllocSizeAtLastG C() / 1024, static_cast<size_t>(INT_MAX)));
719 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "Partitions::totalSize OfCommittedPagesKB", std::min(WTF::Partitions::totalSizeOfCommittedPages() / 102 4, static_cast<size_t>(INT_MAX))); 652 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "Partitions::totalSize OfCommittedPagesKB", std::min(WTF::Partitions::totalSizeOfCommittedPages() / 102 4, static_cast<size_t>(INT_MAX)));
720 } 653 }
721 654
722 size_t ThreadHeap::objectPayloadSizeForTesting() 655 size_t ThreadHeap::objectPayloadSizeForTesting()
723 { 656 {
724 // MEMO: is threadAttachMutex locked?
725 size_t objectPayloadSize = 0; 657 size_t objectPayloadSize = 0;
726 for (ThreadState* state : m_threads) { 658 for (ThreadState* state : ThreadState::attachedThreads()) {
727 state->setGCState(ThreadState::GCRunning); 659 state->setGCState(ThreadState::GCRunning);
728 state->makeConsistentForGC(); 660 state->makeConsistentForGC();
729 objectPayloadSize += state->objectPayloadSizeForTesting(); 661 objectPayloadSize += state->objectPayloadSizeForTesting();
730 state->setGCState(ThreadState::EagerSweepScheduled); 662 state->setGCState(ThreadState::EagerSweepScheduled);
731 state->setGCState(ThreadState::Sweeping); 663 state->setGCState(ThreadState::Sweeping);
732 state->setGCState(ThreadState::NoGCScheduled); 664 state->setGCState(ThreadState::NoGCScheduled);
733 } 665 }
734 return objectPayloadSize; 666 return objectPayloadSize;
735 } 667 }
736 668
737 void ThreadHeap::visitPersistentRoots(Visitor* visitor) 669 RegionTree* ThreadHeap::getRegionTree()
670 {
671 DEFINE_THREAD_SAFE_STATIC_LOCAL(RegionTree, tree, new RegionTree);
672 return &tree;
673 }
674
675 BasePage* ThreadHeap::lookup(Address address)
738 { 676 {
739 ASSERT(ThreadState::current()->isInGC()); 677 ASSERT(ThreadState::current()->isInGC());
740 TRACE_EVENT0("blink_gc", "ThreadHeap::visitPersistentRoots"); 678 if (PageMemoryRegion* region = ThreadHeap::getRegionTree()->lookup(address)) {
741 ProcessHeap::crossThreadPersistentRegion().tracePersistentNodes(visitor);
742
743 for (ThreadState* state : m_threads) {
744 state->visitPersistents(visitor);
745 }
746 }
747
748 void ThreadHeap::visitStackRoots(Visitor* visitor)
749 {
750 ASSERT(ThreadState::current()->isInGC());
751 TRACE_EVENT0("blink_gc", "ThreadHeap::visitStackRoots");
752 for (ThreadState* state : m_threads) {
753 state->visitStack(visitor);
754 }
755 }
756
757 void ThreadHeap::checkAndPark(ThreadState* threadState, SafePointAwareMutexLocke r* locker)
758 {
759 m_safePointBarrier->checkAndPark(threadState, locker);
760 }
761
762 void ThreadHeap::enterSafePoint(ThreadState* threadState)
763 {
764 m_safePointBarrier->enterSafePoint(threadState);
765 }
766
767 void ThreadHeap::leaveSafePoint(ThreadState* threadState, SafePointAwareMutexLoc ker* locker)
768 {
769 m_safePointBarrier->leaveSafePoint(threadState, locker);
770 }
771
772 BasePage* ThreadHeap::lookupPageForAddress(Address address)
773 {
774 ASSERT(ThreadState::current()->isInGC());
775 if (PageMemoryRegion* region = m_regionTree->lookup(address)) {
776 BasePage* page = region->pageFromAddress(address); 679 BasePage* page = region->pageFromAddress(address);
777 return page && !page->orphaned() ? page : nullptr; 680 return page && !page->orphaned() ? page : nullptr;
778 } 681 }
779 return nullptr; 682 return nullptr;
780 } 683 }
781 684
782 void ThreadHeap::resetHeapCounters() 685 void ThreadHeap::resetHeapCounters()
783 { 686 {
784 ASSERT(ThreadState::current()->isInGC()); 687 ASSERT(ThreadState::current()->isInGC());
785 688
786 ThreadHeap::reportMemoryUsageForTracing(); 689 ThreadHeap::reportMemoryUsageForTracing();
787 690
788 ProcessHeap::decreaseTotalAllocatedObjectSize(m_stats.allocatedObjectSize()) ; 691 ProcessHeap::resetHeapCounters();
789 ProcessHeap::decreaseTotalMarkedObjectSize(m_stats.markedObjectSize()); 692 ThreadHeap::heapStats().reset();
790 693 for (ThreadState* state : ThreadState::attachedThreads())
791 m_stats.reset();
792 for (ThreadState* state : m_threads)
793 state->resetHeapCounters(); 694 state->resetHeapCounters();
794 } 695 }
795 696
796 ThreadHeap* ThreadHeap::s_mainThreadHeap = nullptr; 697 ThreadHeapStats& ThreadHeap::heapStats()
698 {
699 DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadHeapStats, stats, new ThreadHeapStats( ));
700 return stats;
701 }
702
703 CallbackStack* ThreadHeap::s_markingStack;
704 CallbackStack* ThreadHeap::s_postMarkingCallbackStack;
705 CallbackStack* ThreadHeap::s_globalWeakCallbackStack;
706 CallbackStack* ThreadHeap::s_ephemeronStack;
707 HeapDoesNotContainCache* ThreadHeap::s_heapDoesNotContainCache;
708 FreePagePool* ThreadHeap::s_freePagePool;
709 OrphanedPagePool* ThreadHeap::s_orphanedPagePool;
710
711 BlinkGC::GCReason ThreadHeap::s_lastGCReason = BlinkGC::NumberOfGCReason;
797 712
798 } // namespace blink 713 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/heap/Heap.h ('k') | third_party/WebKit/Source/platform/heap/HeapPage.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698