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

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

Issue 1892713003: Prepare for multiple ThreadHeaps (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 #endif 65 #endif
66 66
67 #include <v8.h> 67 #include <v8.h>
68 68
69 namespace blink { 69 namespace blink {
70 70
71 WTF::ThreadSpecific<ThreadState*>* ThreadState::s_threadSpecific = nullptr; 71 WTF::ThreadSpecific<ThreadState*>* ThreadState::s_threadSpecific = nullptr;
72 uintptr_t ThreadState::s_mainThreadStackStart = 0; 72 uintptr_t ThreadState::s_mainThreadStackStart = 0;
73 uintptr_t ThreadState::s_mainThreadUnderestimatedStackSize = 0; 73 uintptr_t ThreadState::s_mainThreadUnderestimatedStackSize = 0;
74 uint8_t ThreadState::s_mainThreadStateStorage[sizeof(ThreadState)]; 74 uint8_t ThreadState::s_mainThreadStateStorage[sizeof(ThreadState)];
75 SafePointBarrier* ThreadState::s_safePointBarrier = nullptr;
76
77 RecursiveMutex& ThreadState::threadAttachMutex()
78 {
79 DEFINE_THREAD_SAFE_STATIC_LOCAL(RecursiveMutex, mutex, (new RecursiveMutex)) ;
80 return mutex;
81 }
82 75
83 ThreadState::ThreadState() 76 ThreadState::ThreadState()
84 : m_thread(currentThread()) 77 : m_thread(currentThread())
85 , m_persistentRegion(adoptPtr(new PersistentRegion())) 78 , m_persistentRegion(adoptPtr(new PersistentRegion()))
86 #if OS(WIN) && COMPILER(MSVC) 79 #if OS(WIN) && COMPILER(MSVC)
87 , m_threadStackSize(0) 80 , m_threadStackSize(0)
88 #endif 81 #endif
89 , m_startOfStack(reinterpret_cast<intptr_t*>(StackFrameDepth::getStackStart( ))) 82 , m_startOfStack(reinterpret_cast<intptr_t*>(StackFrameDepth::getStackStart( )))
90 , m_endOfStack(reinterpret_cast<intptr_t*>(StackFrameDepth::getStackStart()) ) 83 , m_endOfStack(reinterpret_cast<intptr_t*>(StackFrameDepth::getStackStart()) )
91 , m_safePointScopeMarker(nullptr) 84 , m_safePointScopeMarker(nullptr)
(...skipping 23 matching lines...) Expand all
115 { 108 {
116 ASSERT(checkThread()); 109 ASSERT(checkThread());
117 ASSERT(!**s_threadSpecific); 110 ASSERT(!**s_threadSpecific);
118 **s_threadSpecific = this; 111 **s_threadSpecific = this;
119 112
120 if (isMainThread()) { 113 if (isMainThread()) {
121 s_mainThreadStackStart = reinterpret_cast<uintptr_t>(m_startOfStack) - s izeof(void*); 114 s_mainThreadStackStart = reinterpret_cast<uintptr_t>(m_startOfStack) - s izeof(void*);
122 size_t underestimatedStackSize = StackFrameDepth::getUnderestimatedStack Size(); 115 size_t underestimatedStackSize = StackFrameDepth::getUnderestimatedStack Size();
123 if (underestimatedStackSize > sizeof(void*)) 116 if (underestimatedStackSize > sizeof(void*))
124 s_mainThreadUnderestimatedStackSize = underestimatedStackSize - size of(void*); 117 s_mainThreadUnderestimatedStackSize = underestimatedStackSize - size of(void*);
118 m_heap = new ThreadHeap();
119 } else {
120 m_heap = &ThreadState::mainThreadState()->heap();
125 } 121 }
122 ASSERT(m_heap);
123 m_heap->attach(this);
126 124
127 for (int arenaIndex = 0; arenaIndex < BlinkGC::LargeObjectArenaIndex; arenaI ndex++) 125 for (int arenaIndex = 0; arenaIndex < BlinkGC::LargeObjectArenaIndex; arenaI ndex++)
128 m_arenas[arenaIndex] = new NormalPageArena(this, arenaIndex); 126 m_arenas[arenaIndex] = new NormalPageArena(this, arenaIndex);
129 m_arenas[BlinkGC::LargeObjectArenaIndex] = new LargeObjectArena(this, BlinkG C::LargeObjectArenaIndex); 127 m_arenas[BlinkGC::LargeObjectArenaIndex] = new LargeObjectArena(this, BlinkG C::LargeObjectArenaIndex);
130 128
131 m_likelyToBePromptlyFreed = adoptArrayPtr(new int[likelyToBePromptlyFreedArr aySize]); 129 m_likelyToBePromptlyFreed = adoptArrayPtr(new int[likelyToBePromptlyFreedArr aySize]);
132 clearArenaAges(); 130 clearArenaAges();
133 131
134 // There is little use of weak references and collections off the main threa d; 132 // There is little use of weak references and collections off the main threa d;
135 // use a much lower initial block reservation. 133 // use a much lower initial block reservation.
(...skipping 11 matching lines...) Expand all
147 145
148 **s_threadSpecific = nullptr; 146 **s_threadSpecific = nullptr;
149 if (isMainThread()) { 147 if (isMainThread()) {
150 s_mainThreadStackStart = 0; 148 s_mainThreadStackStart = 0;
151 s_mainThreadUnderestimatedStackSize = 0; 149 s_mainThreadUnderestimatedStackSize = 0;
152 } 150 }
153 } 151 }
154 152
155 void ThreadState::init() 153 void ThreadState::init()
156 { 154 {
157 s_threadSpecific = new WTF::ThreadSpecific<ThreadState*>(); 155 s_threadSpecific = new WTF::ThreadSpecific<ThreadState*>();
haraken 2016/04/21 11:48:25 Can we move this to ThreadState::attachMainThread
keishi 2016/04/22 06:09:59 Done.
158 s_safePointBarrier = new SafePointBarrier;
159 }
160
161 void ThreadState::shutdown()
162 {
163 delete s_safePointBarrier;
164 s_safePointBarrier = nullptr;
165
166 // Thread-local storage shouldn't be disposed, so we don't call ~ThreadSpeci fic().
167 } 156 }
168 157
169 #if OS(WIN) && COMPILER(MSVC) 158 #if OS(WIN) && COMPILER(MSVC)
170 size_t ThreadState::threadStackSize() 159 size_t ThreadState::threadStackSize()
171 { 160 {
172 if (m_threadStackSize) 161 if (m_threadStackSize)
173 return m_threadStackSize; 162 return m_threadStackSize;
174 163
175 // Notice that we cannot use the TIB's StackLimit for the stack end, as it 164 // Notice that we cannot use the TIB's StackLimit for the stack end, as it
176 // tracks the end of the committed range. We're after the end of the reserve d 165 // tracks the end of the committed range. We're after the end of the reserve d
(...skipping 19 matching lines...) Expand all
196 // http://blogs.msdn.com/b/satyem/archive/2012/08/13/thread-s-stack-memory-m anagement.aspx 185 // http://blogs.msdn.com/b/satyem/archive/2012/08/13/thread-s-stack-memory-m anagement.aspx
197 // explains the details. 186 // explains the details.
198 RELEASE_ASSERT(m_threadStackSize > 4 * 0x1000); 187 RELEASE_ASSERT(m_threadStackSize > 4 * 0x1000);
199 m_threadStackSize -= 4 * 0x1000; 188 m_threadStackSize -= 4 * 0x1000;
200 return m_threadStackSize; 189 return m_threadStackSize;
201 } 190 }
202 #endif 191 #endif
203 192
204 void ThreadState::attachMainThread() 193 void ThreadState::attachMainThread()
205 { 194 {
206 MutexLocker locker(threadAttachMutex()); 195 RELEASE_ASSERT(!ProcessHeap::s_shutdownComplete);
207 ThreadState* state = new (s_mainThreadStateStorage) ThreadState(); 196 new(s_mainThreadStateStorage) ThreadState();
haraken 2016/04/21 11:48:26 Nit: Add a space after 'new'.
keishi 2016/04/22 06:09:59 Done.
208 attachedThreads().add(state);
209 } 197 }
210 198
199 void ThreadState::attach()
haraken 2016/04/21 11:48:25 attach => attachCurrentThread ? (for consistency w
keishi 2016/04/22 06:09:59 Done.
200 {
201 RELEASE_ASSERT(!ProcessHeap::s_shutdownComplete);
202 new ThreadState();
203 }
204
205 void ThreadState::cleanupPages()
206 {
207 ASSERT(checkThread());
208 for (int i = 0; i < BlinkGC::NumberOfArenas; ++i)
209 m_arenas[i]->cleanupPages();
210 }
211
212 void ThreadState::cleanup()
haraken 2016/04/21 11:48:26 cleanup => runTerminationGC
keishi 2016/04/22 06:09:59 Done.
213 {
214 if (isMainThread()) {
haraken 2016/04/21 11:48:25 This is okay at the moment, but you'll need to rep
215 cleanupPages();
216 return;
217 }
218 ASSERT(checkThread());
219
220 // Finish sweeping.
221 completeSweep();
222
223 // From here on ignore all conservatively discovered
224 // pointers into the heap owned by this thread.
225 m_isTerminating = true;
226
227 // Invoke the cleanup hooks. This gives an opportunity to release any
228 // persistent handles that may exist, e.g. in thread-specific static
229 // locals.
230 for (const OwnPtr<SameThreadClosure>& hook : m_threadShutdownHooks)
231 (*hook)();
232
233 // Set the terminate flag on all heap pages of this thread. This is used to
234 // ensure we don't trace pages on other threads that are not part of the
235 // thread local GC.
236 prepareForThreadStateTermination();
237
238 ProcessHeap::crossThreadPersistentRegion().prepareForThreadStateTermination( this);
239
240 // Do thread local GC's as long as the count of thread local Persistents
241 // changes and is above zero.
242 int oldCount = -1;
243 int currentCount = getPersistentRegion()->numberOfPersistents();
244 ASSERT(currentCount >= 0);
245 while (currentCount != oldCount) {
246 ThreadHeap::collectGarbageForTerminatingThread(this);
247 oldCount = currentCount;
248 currentCount = getPersistentRegion()->numberOfPersistents();
249 }
250 // We should not have any persistents left when getting to this point,
251 // if we have it is probably a bug so adding a debug ASSERT to catch this.
252 ASSERT(!currentCount);
253 // All of pre-finalizers should be consumed.
254 ASSERT(m_orderedPreFinalizers.isEmpty());
255 RELEASE_ASSERT(gcState() == NoGCScheduled);
256
257 // Add pages to the orphaned page pool to ensure any global GCs from this po int
258 // on will not trace objects on this thread's arenas.
259 cleanupPages();
260 }
211 261
212 void ThreadState::cleanupMainThread() 262 void ThreadState::cleanupMainThread()
213 { 263 {
214 ASSERT(isMainThread()); 264 ASSERT(isMainThread());
215 265
216 #if defined(LEAK_SANITIZER) 266 #if defined(LEAK_SANITIZER)
217 // If LSan is about to perform leak detection, release all the registered 267 // If LSan is about to perform leak detection, release all the registered
218 // static Persistent<> root references to global caches that Blink keeps, 268 // static Persistent<> root references to global caches that Blink keeps,
219 // followed by GCs to clear out all they referred to. 269 // followed by GCs to clear out all they referred to.
220 // 270 //
(...skipping 14 matching lines...) Expand all
235 enterGCForbiddenScope(); 285 enterGCForbiddenScope();
236 } 286 }
237 287
238 void ThreadState::detachMainThread() 288 void ThreadState::detachMainThread()
239 { 289 {
240 // Enter a safe point before trying to acquire threadAttachMutex 290 // Enter a safe point before trying to acquire threadAttachMutex
241 // to avoid dead lock if another thread is preparing for GC, has acquired 291 // to avoid dead lock if another thread is preparing for GC, has acquired
242 // threadAttachMutex and waiting for other threads to pause or reach a 292 // threadAttachMutex and waiting for other threads to pause or reach a
243 // safepoint. 293 // safepoint.
244 ThreadState* state = mainThreadState(); 294 ThreadState* state = mainThreadState();
245 ASSERT(state == ThreadState::current());
246 ASSERT(state->checkThread());
247 ASSERT(!state->isSweepingInProgress()); 295 ASSERT(!state->isSweepingInProgress());
248 296
249 // The main thread must be the last thread that gets detached. 297 state->heap().detach(state);
250 RELEASE_ASSERT(ThreadState::attachedThreads().size() == 1);
haraken 2016/04/21 11:48:25 Can we keep this assert somewhere?
keishi 2016/04/22 06:09:59 I moved this assert to ThreadHeap::detach()
251
252 // Add the main thread's heap pages to the orphaned pool.
253 state->cleanupPages();
254
255 // Detach the main thread. We don't need to grab a lock because
256 // the main thread should be the last thread that gets detached.
257 ASSERT(attachedThreads().contains(state));
258 attachedThreads().remove(state);
259 state->~ThreadState(); 298 state->~ThreadState();
260 } 299 }
261 300
262 void ThreadState::attach() 301 void ThreadState::detachCurrentThread()
263 {
264 MutexLocker locker(threadAttachMutex());
265 ThreadState* state = new ThreadState();
266 attachedThreads().add(state);
267 }
268
269 void ThreadState::cleanupPages()
270 {
271 ASSERT(checkThread());
272 for (int i = 0; i < BlinkGC::NumberOfArenas; ++i)
273 m_arenas[i]->cleanupPages();
274 }
275
276 void ThreadState::cleanup()
277 {
278 ASSERT(checkThread());
279 {
280 // Grab the threadAttachMutex to ensure only one thread can shutdown at
281 // a time and that no other thread can do a global GC. It also allows
282 // safe iteration of the attachedThreads set which happens as part of
283 // thread local GC asserts. We enter a safepoint while waiting for the
284 // lock to avoid a dead-lock where another thread has already requested
285 // GC.
286 SafePointAwareMutexLocker locker(threadAttachMutex(), BlinkGC::NoHeapPoi ntersOnStack);
287
288 // Finish sweeping.
289 completeSweep();
290
291 // From here on ignore all conservatively discovered
292 // pointers into the heap owned by this thread.
293 m_isTerminating = true;
294
295 // Invoke the cleanup hooks. This gives an opportunity to release any
296 // persistent handles that may exist, e.g. in thread-specific static
297 // locals.
298 for (const OwnPtr<SameThreadClosure>& hook : m_threadShutdownHooks)
299 (*hook)();
300
301 // Set the terminate flag on all heap pages of this thread. This is used to
302 // ensure we don't trace pages on other threads that are not part of the
303 // thread local GC.
304 prepareForThreadStateTermination();
305
306 ProcessHeap::crossThreadPersistentRegion().prepareForThreadStateTerminat ion(this);
307
308 // Do thread local GC's as long as the count of thread local Persistents
309 // changes and is above zero.
310 int oldCount = -1;
311 int currentCount = getPersistentRegion()->numberOfPersistents();
312 ASSERT(currentCount >= 0);
313 while (currentCount != oldCount) {
314 ThreadHeap::collectGarbageForTerminatingThread(this);
315 oldCount = currentCount;
316 currentCount = getPersistentRegion()->numberOfPersistents();
317 }
318 // We should not have any persistents left when getting to this point,
319 // if we have it is probably a bug so adding a debug ASSERT to catch thi s.
320 ASSERT(!currentCount);
321 // All of pre-finalizers should be consumed.
322 ASSERT(m_orderedPreFinalizers.isEmpty());
323 RELEASE_ASSERT(gcState() == NoGCScheduled);
324
325 // Add pages to the orphaned page pool to ensure any global GCs from thi s point
326 // on will not trace objects on this thread's arenas.
327 cleanupPages();
328
329 ASSERT(attachedThreads().contains(this));
330 attachedThreads().remove(this);
331 }
332 }
333
334 void ThreadState::detach()
335 { 302 {
336 ThreadState* state = current(); 303 ThreadState* state = current();
337 state->cleanup(); 304 state->heap().detach(state);
338 RELEASE_ASSERT(state->gcState() == ThreadState::NoGCScheduled);
haraken 2016/04/21 11:48:25 Can we keep this assert somewhere?
keishi 2016/04/22 06:09:59 Done. Added back to ThreadState::detachCurrentThre
339 delete state; 305 delete state;
340 } 306 }
341 307
342 void ThreadState::visitPersistentRoots(Visitor* visitor)
343 {
344 TRACE_EVENT0("blink_gc", "ThreadState::visitPersistentRoots");
345 ProcessHeap::crossThreadPersistentRegion().tracePersistentNodes(visitor);
346
347 for (ThreadState* state : attachedThreads())
348 state->visitPersistents(visitor);
349 }
350
351 void ThreadState::visitStackRoots(Visitor* visitor)
352 {
353 TRACE_EVENT0("blink_gc", "ThreadState::visitStackRoots");
354 for (ThreadState* state : attachedThreads())
355 state->visitStack(visitor);
356 }
357
358 NO_SANITIZE_ADDRESS 308 NO_SANITIZE_ADDRESS
359 void ThreadState::visitAsanFakeStackForPointer(Visitor* visitor, Address ptr) 309 void ThreadState::visitAsanFakeStackForPointer(Visitor* visitor, Address ptr)
360 { 310 {
361 #if defined(ADDRESS_SANITIZER) 311 #if defined(ADDRESS_SANITIZER)
362 Address* start = reinterpret_cast<Address*>(m_startOfStack); 312 Address* start = reinterpret_cast<Address*>(m_startOfStack);
363 Address* end = reinterpret_cast<Address*>(m_endOfStack); 313 Address* end = reinterpret_cast<Address*>(m_endOfStack);
364 Address* fakeFrameStart = nullptr; 314 Address* fakeFrameStart = nullptr;
365 Address* fakeFrameEnd = nullptr; 315 Address* fakeFrameEnd = nullptr;
366 Address* maybeFakeFrame = reinterpret_cast<Address*>(ptr); 316 Address* maybeFakeFrame = reinterpret_cast<Address*>(ptr);
367 Address* realFrameForFakeFrame = 317 Address* realFrameForFakeFrame =
368 reinterpret_cast<Address*>( 318 reinterpret_cast<Address*>(
369 __asan_addr_is_in_fake_stack( 319 __asan_addr_is_in_fake_stack(
370 m_asanFakeStack, maybeFakeFrame, 320 m_asanFakeStack, maybeFakeFrame,
371 reinterpret_cast<void**>(&fakeFrameStart), 321 reinterpret_cast<void**>(&fakeFrameStart),
372 reinterpret_cast<void**>(&fakeFrameEnd))); 322 reinterpret_cast<void**>(&fakeFrameEnd)));
373 if (realFrameForFakeFrame) { 323 if (realFrameForFakeFrame) {
374 // This is a fake frame from the asan fake stack. 324 // This is a fake frame from the asan fake stack.
375 if (realFrameForFakeFrame > end && start > realFrameForFakeFrame) { 325 if (realFrameForFakeFrame > end && start > realFrameForFakeFrame) {
376 // The real stack address for the asan fake frame is 326 // The real stack address for the asan fake frame is
377 // within the stack range that we need to scan so we need 327 // within the stack range that we need to scan so we need
378 // to visit the values in the fake frame. 328 // to visit the values in the fake frame.
379 for (Address* p = fakeFrameStart; p < fakeFrameEnd; ++p) 329 for (Address* p = fakeFrameStart; p < fakeFrameEnd; ++p)
380 ThreadHeap::checkAndMarkPointer(visitor, *p); 330 m_heap->checkAndMarkPointer(visitor, *p);
381 } 331 }
382 } 332 }
383 #endif 333 #endif
384 } 334 }
385 335
386 NO_SANITIZE_ADDRESS 336 NO_SANITIZE_ADDRESS
387 void ThreadState::visitStack(Visitor* visitor) 337 void ThreadState::visitStack(Visitor* visitor)
388 { 338 {
389 if (m_stackState == BlinkGC::NoHeapPointersOnStack) 339 if (m_stackState == BlinkGC::NoHeapPointersOnStack)
390 return; 340 return;
(...skipping 15 matching lines...) Expand all
406 for (; current < start; ++current) { 356 for (; current < start; ++current) {
407 Address ptr = *current; 357 Address ptr = *current;
408 #if defined(MEMORY_SANITIZER) 358 #if defined(MEMORY_SANITIZER)
409 // |ptr| may be uninitialized by design. Mark it as initialized to keep 359 // |ptr| may be uninitialized by design. Mark it as initialized to keep
410 // MSan from complaining. 360 // MSan from complaining.
411 // Note: it may be tempting to get rid of |ptr| and simply use |current| 361 // Note: it may be tempting to get rid of |ptr| and simply use |current|
412 // here, but that would be incorrect. We intentionally use a local 362 // here, but that would be incorrect. We intentionally use a local
413 // variable because we don't want to unpoison the original stack. 363 // variable because we don't want to unpoison the original stack.
414 __msan_unpoison(&ptr, sizeof(ptr)); 364 __msan_unpoison(&ptr, sizeof(ptr));
415 #endif 365 #endif
416 ThreadHeap::checkAndMarkPointer(visitor, ptr); 366 m_heap->checkAndMarkPointer(visitor, ptr);
417 visitAsanFakeStackForPointer(visitor, ptr); 367 visitAsanFakeStackForPointer(visitor, ptr);
418 } 368 }
419 369
420 for (Address ptr : m_safePointStackCopy) { 370 for (Address ptr : m_safePointStackCopy) {
421 #if defined(MEMORY_SANITIZER) 371 #if defined(MEMORY_SANITIZER)
422 // See the comment above. 372 // See the comment above.
423 __msan_unpoison(&ptr, sizeof(ptr)); 373 __msan_unpoison(&ptr, sizeof(ptr));
424 #endif 374 #endif
425 ThreadHeap::checkAndMarkPointer(visitor, ptr); 375 m_heap->checkAndMarkPointer(visitor, ptr);
426 visitAsanFakeStackForPointer(visitor, ptr); 376 visitAsanFakeStackForPointer(visitor, ptr);
427 } 377 }
428 } 378 }
429 379
430 void ThreadState::visitPersistents(Visitor* visitor) 380 void ThreadState::visitPersistents(Visitor* visitor)
431 { 381 {
432 m_persistentRegion->tracePersistentNodes(visitor); 382 m_persistentRegion->tracePersistentNodes(visitor);
433 if (m_traceDOMWrappers) { 383 if (m_traceDOMWrappers) {
434 TRACE_EVENT0("blink_gc", "V8GCController::traceDOMWrappers"); 384 TRACE_EVENT0("blink_gc", "V8GCController::traceDOMWrappers");
435 m_traceDOMWrappers(m_isolate, visitor); 385 m_traceDOMWrappers(m_isolate, visitor);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 466
517 if (isMainThread()) { 467 if (isMainThread()) {
518 double timeForThreadLocalWeakProcessing = WTF::currentTimeMS() - startTi me; 468 double timeForThreadLocalWeakProcessing = WTF::currentTimeMS() - startTi me;
519 DEFINE_STATIC_LOCAL(CustomCountHistogram, timeForWeakHistogram, ("BlinkG C.TimeForThreadLocalWeakProcessing", 1, 10 * 1000, 50)); 469 DEFINE_STATIC_LOCAL(CustomCountHistogram, timeForWeakHistogram, ("BlinkG C.TimeForThreadLocalWeakProcessing", 1, 10 * 1000, 50));
520 timeForWeakHistogram.count(timeForThreadLocalWeakProcessing); 470 timeForWeakHistogram.count(timeForThreadLocalWeakProcessing);
521 } 471 }
522 } 472 }
523 473
524 size_t ThreadState::totalMemorySize() 474 size_t ThreadState::totalMemorySize()
525 { 475 {
526 return ThreadHeap::heapStats().allocatedObjectSize() + ThreadHeap::heapStats ().markedObjectSize() + WTF::Partitions::totalSizeOfCommittedPages(); 476 return m_heap->heapStats().allocatedObjectSize() + m_heap->heapStats().marke dObjectSize() + WTF::Partitions::totalSizeOfCommittedPages();
527 } 477 }
528 478
529 size_t ThreadState::estimatedLiveSize(size_t estimationBaseSize, size_t sizeAtLa stGC) 479 size_t ThreadState::estimatedLiveSize(size_t estimationBaseSize, size_t sizeAtLa stGC)
530 { 480 {
531 if (ThreadHeap::heapStats().wrapperCountAtLastGC() == 0) { 481 if (m_heap->heapStats().wrapperCountAtLastGC() == 0) {
532 // We'll reach here only before hitting the first GC. 482 // We'll reach here only before hitting the first GC.
533 return 0; 483 return 0;
534 } 484 }
535 485
536 // (estimated size) = (estimation base size) - (heap size at the last GC) / (# of persistent handles at the last GC) * (# of persistent handles collected si nce the last GC); 486 // (estimated size) = (estimation base size) - (heap size at the last GC) / (# of persistent handles at the last GC) * (# of persistent handles collected si nce the last GC);
537 size_t sizeRetainedByCollectedPersistents = static_cast<size_t>(1.0 * sizeAt LastGC / ThreadHeap::heapStats().wrapperCountAtLastGC() * ThreadHeap::heapStats( ).collectedWrapperCount()); 487 size_t sizeRetainedByCollectedPersistents = static_cast<size_t>(1.0 * sizeAt LastGC / m_heap->heapStats().wrapperCountAtLastGC() * m_heap->heapStats().collec tedWrapperCount());
538 if (estimationBaseSize < sizeRetainedByCollectedPersistents) 488 if (estimationBaseSize < sizeRetainedByCollectedPersistents)
539 return 0; 489 return 0;
540 return estimationBaseSize - sizeRetainedByCollectedPersistents; 490 return estimationBaseSize - sizeRetainedByCollectedPersistents;
541 } 491 }
542 492
543 double ThreadState::heapGrowingRate() 493 double ThreadState::heapGrowingRate()
544 { 494 {
545 size_t currentSize = ThreadHeap::heapStats().allocatedObjectSize() + ThreadH eap::heapStats().markedObjectSize(); 495 size_t currentSize = m_heap->heapStats().allocatedObjectSize() + m_heap->hea pStats().markedObjectSize();
546 size_t estimatedSize = estimatedLiveSize(ThreadHeap::heapStats().markedObjec tSizeAtLastCompleteSweep(), ThreadHeap::heapStats().markedObjectSizeAtLastComple teSweep()); 496 size_t estimatedSize = estimatedLiveSize(m_heap->heapStats().markedObjectSiz eAtLastCompleteSweep(), m_heap->heapStats().markedObjectSizeAtLastCompleteSweep( ));
547 497
548 // If the estimatedSize is 0, we set a high growing rate to trigger a GC. 498 // If the estimatedSize is 0, we set a high growing rate to trigger a GC.
549 double growingRate = estimatedSize > 0 ? 1.0 * currentSize / estimatedSize : 100; 499 double growingRate = estimatedSize > 0 ? 1.0 * currentSize / estimatedSize : 100;
550 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadState::heapEsti matedSizeKB", std::min(estimatedSize / 1024, static_cast<size_t>(INT_MAX))); 500 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadState::heapEsti matedSizeKB", std::min(estimatedSize / 1024, static_cast<size_t>(INT_MAX)));
551 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadState::heapGrow ingRate", static_cast<int>(100 * growingRate)); 501 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadState::heapGrow ingRate", static_cast<int>(100 * growingRate));
552 return growingRate; 502 return growingRate;
553 } 503 }
554 504
555 double ThreadState::partitionAllocGrowingRate() 505 double ThreadState::partitionAllocGrowingRate()
556 { 506 {
557 size_t currentSize = WTF::Partitions::totalSizeOfCommittedPages(); 507 size_t currentSize = WTF::Partitions::totalSizeOfCommittedPages();
558 size_t estimatedSize = estimatedLiveSize(currentSize, ThreadHeap::heapStats( ).partitionAllocSizeAtLastGC()); 508 size_t estimatedSize = estimatedLiveSize(currentSize, m_heap->heapStats().pa rtitionAllocSizeAtLastGC());
559 509
560 // If the estimatedSize is 0, we set a high growing rate to trigger a GC. 510 // If the estimatedSize is 0, we set a high growing rate to trigger a GC.
561 double growingRate = estimatedSize > 0 ? 1.0 * currentSize / estimatedSize : 100; 511 double growingRate = estimatedSize > 0 ? 1.0 * currentSize / estimatedSize : 100;
562 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadState::partitio nAllocEstimatedSizeKB", std::min(estimatedSize / 1024, static_cast<size_t>(INT_M AX))); 512 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadState::partitio nAllocEstimatedSizeKB", std::min(estimatedSize / 1024, static_cast<size_t>(INT_M AX)));
563 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadState::partitio nAllocGrowingRate", static_cast<int>(100 * growingRate)); 513 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadState::partitio nAllocGrowingRate", static_cast<int>(100 * growingRate));
564 return growingRate; 514 return growingRate;
565 } 515 }
566 516
567 // TODO(haraken): We should improve the GC heuristics. The heuristics affect 517 // TODO(haraken): We should improve the GC heuristics. The heuristics affect
568 // performance significantly. 518 // performance significantly.
569 bool ThreadState::judgeGCThreshold(size_t totalMemorySizeThreshold, double heapG rowingRateThreshold) 519 bool ThreadState::judgeGCThreshold(size_t totalMemorySizeThreshold, double heapG rowingRateThreshold)
570 { 520 {
571 // If the allocated object size or the total memory size is small, don't tri gger a GC. 521 // If the allocated object size or the total memory size is small, don't tri gger a GC.
572 if (ThreadHeap::heapStats().allocatedObjectSize() < 100 * 1024 || totalMemor ySize() < totalMemorySizeThreshold) 522 if (m_heap->heapStats().allocatedObjectSize() < 100 * 1024 || totalMemorySiz e() < totalMemorySizeThreshold)
573 return false; 523 return false;
574 // If the growing rate of Oilpan's heap or PartitionAlloc is high enough, 524 // If the growing rate of Oilpan's heap or PartitionAlloc is high enough,
575 // trigger a GC. 525 // trigger a GC.
576 #if PRINT_HEAP_STATS 526 #if PRINT_HEAP_STATS
577 dataLogF("heapGrowingRate=%.1lf, partitionAllocGrowingRate=%.1lf\n", heapGro wingRate(), partitionAllocGrowingRate()); 527 dataLogF("heapGrowingRate=%.1lf, partitionAllocGrowingRate=%.1lf\n", heapGro wingRate(), partitionAllocGrowingRate());
578 #endif 528 #endif
579 return heapGrowingRate() >= heapGrowingRateThreshold || partitionAllocGrowin gRate() >= heapGrowingRateThreshold; 529 return heapGrowingRate() >= heapGrowingRateThreshold || partitionAllocGrowin gRate() >= heapGrowingRateThreshold;
580 } 530 }
581 531
582 bool ThreadState::shouldScheduleIdleGC() 532 bool ThreadState::shouldScheduleIdleGC()
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 } 696 }
747 if (shouldScheduleIdleGC()) { 697 if (shouldScheduleIdleGC()) {
748 #if PRINT_HEAP_STATS 698 #if PRINT_HEAP_STATS
749 dataLogF("Scheduled IdleGC\n"); 699 dataLogF("Scheduled IdleGC\n");
750 #endif 700 #endif
751 scheduleIdleGC(); 701 scheduleIdleGC();
752 return; 702 return;
753 } 703 }
754 } 704 }
755 705
706 ThreadState* ThreadState::fromObject(const void* object)
haraken 2016/04/21 11:48:25 Worth inlining this method?
keishi 2016/04/22 06:09:59 It's hard to avoid a circular include right now.
707 {
708 if (!object)
haraken 2016/04/21 11:48:25 I'd remove this check. Instead add ASSERT(object).
keishi 2016/04/22 06:09:59 Done.
709 return nullptr;
710 BasePage* page = pageFromObject(object);
711 ASSERT(page);
712 ASSERT(page->arena());
713 return page->arena()->getThreadState();
714 }
715
756 void ThreadState::performIdleGC(double deadlineSeconds) 716 void ThreadState::performIdleGC(double deadlineSeconds)
757 { 717 {
758 ASSERT(checkThread()); 718 ASSERT(checkThread());
759 ASSERT(isMainThread()); 719 ASSERT(isMainThread());
760 ASSERT(Platform::current()->currentThread()->scheduler()); 720 ASSERT(Platform::current()->currentThread()->scheduler());
761 721
762 if (gcState() != IdleGCScheduled) 722 if (gcState() != IdleGCScheduled)
763 return; 723 return;
764 724
765 double idleDeltaInSeconds = deadlineSeconds - monotonicallyIncreasingTime(); 725 double idleDeltaInSeconds = deadlineSeconds - monotonicallyIncreasingTime();
766 TRACE_EVENT2("blink_gc", "ThreadState::performIdleGC", "idleDeltaInSeconds", idleDeltaInSeconds, "estimatedMarkingTime", ThreadHeap::heapStats().estimatedMa rkingTime()); 726 TRACE_EVENT2("blink_gc", "ThreadState::performIdleGC", "idleDeltaInSeconds", idleDeltaInSeconds, "estimatedMarkingTime", m_heap->heapStats().estimatedMarkin gTime());
767 if (idleDeltaInSeconds <= ThreadHeap::heapStats().estimatedMarkingTime() && !Platform::current()->currentThread()->scheduler()->canExceedIdleDeadlineIfRequi red()) { 727 if (idleDeltaInSeconds <= m_heap->heapStats().estimatedMarkingTime() && !Pla tform::current()->currentThread()->scheduler()->canExceedIdleDeadlineIfRequired( )) {
768 // If marking is estimated to take longer than the deadline and we can't 728 // If marking is estimated to take longer than the deadline and we can't
769 // exceed the deadline, then reschedule for the next idle period. 729 // exceed the deadline, then reschedule for the next idle period.
770 scheduleIdleGC(); 730 scheduleIdleGC();
771 return; 731 return;
772 } 732 }
773 733
774 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithou tSweep, BlinkGC::IdleGC); 734 ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithou tSweep, BlinkGC::IdleGC);
775 } 735 }
776 736
777 void ThreadState::performIdleLazySweep(double deadlineSeconds) 737 void ThreadState::performIdleLazySweep(double deadlineSeconds)
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 // Idle time GC will be scheduled by Blink Scheduler. 919 // Idle time GC will be scheduled by Blink Scheduler.
960 break; 920 break;
961 default: 921 default:
962 break; 922 break;
963 } 923 }
964 } 924 }
965 925
966 void ThreadState::flushHeapDoesNotContainCacheIfNeeded() 926 void ThreadState::flushHeapDoesNotContainCacheIfNeeded()
967 { 927 {
968 if (m_shouldFlushHeapDoesNotContainCache) { 928 if (m_shouldFlushHeapDoesNotContainCache) {
969 ThreadHeap::flushHeapDoesNotContainCache(); 929 m_heap->flushHeapDoesNotContainCache();
970 m_shouldFlushHeapDoesNotContainCache = false; 930 m_shouldFlushHeapDoesNotContainCache = false;
971 } 931 }
972 } 932 }
973 933
974 void ThreadState::makeConsistentForGC() 934 void ThreadState::makeConsistentForGC()
975 { 935 {
976 ASSERT(isInGC()); 936 ASSERT(isInGC());
977 TRACE_EVENT0("blink_gc", "ThreadState::makeConsistentForGC"); 937 TRACE_EVENT0("blink_gc", "ThreadState::makeConsistentForGC");
978 for (int i = 0; i < BlinkGC::NumberOfArenas; ++i) 938 for (int i = 0; i < BlinkGC::NumberOfArenas; ++i)
979 m_arenas[i]->makeConsistentForGC(); 939 m_arenas[i]->makeConsistentForGC();
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 postSweep(); 1086 postSweep();
1127 } 1087 }
1128 1088
1129 void ThreadState::postSweep() 1089 void ThreadState::postSweep()
1130 { 1090 {
1131 ASSERT(checkThread()); 1091 ASSERT(checkThread());
1132 ThreadHeap::reportMemoryUsageForTracing(); 1092 ThreadHeap::reportMemoryUsageForTracing();
1133 1093
1134 if (isMainThread()) { 1094 if (isMainThread()) {
1135 double collectionRate = 0; 1095 double collectionRate = 0;
1136 if (ThreadHeap::heapStats().objectSizeAtLastGC() > 0) 1096 if (m_heap->heapStats().objectSizeAtLastGC() > 0)
1137 collectionRate = 1 - 1.0 * ThreadHeap::heapStats().markedObjectSize( ) / ThreadHeap::heapStats().objectSizeAtLastGC(); 1097 collectionRate = 1 - 1.0 * m_heap->heapStats().markedObjectSize() / m_heap->heapStats().objectSizeAtLastGC();
1138 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadState::coll ectionRate", static_cast<int>(100 * collectionRate)); 1098 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadState::coll ectionRate", static_cast<int>(100 * collectionRate));
1139 1099
1140 #if PRINT_HEAP_STATS 1100 #if PRINT_HEAP_STATS
1141 dataLogF("ThreadState::postSweep (collectionRate=%d%%)\n", static_cast<i nt>(100 * collectionRate)); 1101 dataLogF("ThreadState::postSweep (collectionRate=%d%%)\n", static_cast<i nt>(100 * collectionRate));
1142 #endif 1102 #endif
1143 1103
1144 // ThreadHeap::markedObjectSize() may be underestimated here if any othe r 1104 // ThreadHeap::markedObjectSize() may be underestimated here if any othe r
1145 // thread has not yet finished lazy sweeping. 1105 // thread has not yet finished lazy sweeping.
1146 ThreadHeap::heapStats().setMarkedObjectSizeAtLastCompleteSweep(ThreadHea p::heapStats().markedObjectSize()); 1106 m_heap->heapStats().setMarkedObjectSizeAtLastCompleteSweep(m_heap->heapS tats().markedObjectSize());
1147 1107
1148 DEFINE_STATIC_LOCAL(CustomCountHistogram, objectSizeBeforeGCHistogram, ( "BlinkGC.ObjectSizeBeforeGC", 1, 4 * 1024 * 1024, 50)); 1108 DEFINE_STATIC_LOCAL(CustomCountHistogram, objectSizeBeforeGCHistogram, ( "BlinkGC.ObjectSizeBeforeGC", 1, 4 * 1024 * 1024, 50));
1149 objectSizeBeforeGCHistogram.count(ThreadHeap::heapStats().objectSizeAtLa stGC() / 1024); 1109 objectSizeBeforeGCHistogram.count(m_heap->heapStats().objectSizeAtLastGC () / 1024);
1150 DEFINE_STATIC_LOCAL(CustomCountHistogram, objectSizeAfterGCHistogram, (" BlinkGC.ObjectSizeAfterGC", 1, 4 * 1024 * 1024, 50)); 1110 DEFINE_STATIC_LOCAL(CustomCountHistogram, objectSizeAfterGCHistogram, (" BlinkGC.ObjectSizeAfterGC", 1, 4 * 1024 * 1024, 50));
1151 objectSizeAfterGCHistogram.count(ThreadHeap::heapStats().markedObjectSiz e() / 1024); 1111 objectSizeAfterGCHistogram.count(m_heap->heapStats().markedObjectSize() / 1024);
1152 DEFINE_STATIC_LOCAL(CustomCountHistogram, collectionRateHistogram, ("Bli nkGC.CollectionRate", 1, 100, 20)); 1112 DEFINE_STATIC_LOCAL(CustomCountHistogram, collectionRateHistogram, ("Bli nkGC.CollectionRate", 1, 100, 20));
1153 collectionRateHistogram.count(static_cast<int>(100 * collectionRate)); 1113 collectionRateHistogram.count(static_cast<int>(100 * collectionRate));
1154 DEFINE_STATIC_LOCAL(CustomCountHistogram, timeForSweepHistogram, ("Blink GC.TimeForSweepingAllObjects", 1, 10 * 1000, 50)); 1114 DEFINE_STATIC_LOCAL(CustomCountHistogram, timeForSweepHistogram, ("Blink GC.TimeForSweepingAllObjects", 1, 10 * 1000, 50));
1155 timeForSweepHistogram.count(m_accumulatedSweepingTime); 1115 timeForSweepHistogram.count(m_accumulatedSweepingTime);
1156 1116
1157 1117
1158 #define COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(GCReason) \ 1118 #define COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(GCReason) \
1159 case BlinkGC::GCReason: { \ 1119 case BlinkGC::GCReason: { \
1160 DEFINE_STATIC_LOCAL(CustomCountHistogram, histogram, \ 1120 DEFINE_STATIC_LOCAL(CustomCountHistogram, histogram, \
1161 ("BlinkGC.CollectionRate_" #GCReason, 1, 100, 20)); \ 1121 ("BlinkGC.CollectionRate_" #GCReason, 1, 100, 20)); \
1162 histogram.count(static_cast<int>(100 * collectionRate)); \ 1122 histogram.count(static_cast<int>(100 * collectionRate)); \
1163 break; \ 1123 break; \
1164 } 1124 }
1165 1125
1166 switch (ThreadHeap::lastGCReason()) { 1126 switch (m_heap->lastGCReason()) {
1167 COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(IdleGC) 1127 COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(IdleGC)
1168 COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(PreciseGC) 1128 COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(PreciseGC)
1169 COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(ConservativeGC) 1129 COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(ConservativeGC)
1170 COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(ForcedGC) 1130 COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(ForcedGC)
1171 COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(MemoryPressureGC) 1131 COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(MemoryPressureGC)
1172 COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(PageNavigationGC) 1132 COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(PageNavigationGC)
1173 default: 1133 default:
1174 break; 1134 break;
1175 } 1135 }
1176 } 1136 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 #endif 1170 #endif
1211 1171
1212 size_t ThreadState::objectPayloadSizeForTesting() 1172 size_t ThreadState::objectPayloadSizeForTesting()
1213 { 1173 {
1214 size_t objectPayloadSize = 0; 1174 size_t objectPayloadSize = 0;
1215 for (int i = 0; i < BlinkGC::NumberOfArenas; ++i) 1175 for (int i = 0; i < BlinkGC::NumberOfArenas; ++i)
1216 objectPayloadSize += m_arenas[i]->objectPayloadSizeForTesting(); 1176 objectPayloadSize += m_arenas[i]->objectPayloadSizeForTesting();
1217 return objectPayloadSize; 1177 return objectPayloadSize;
1218 } 1178 }
1219 1179
1220 bool ThreadState::stopThreads()
1221 {
1222 return s_safePointBarrier->parkOthers();
1223 }
1224
1225 void ThreadState::resumeThreads()
1226 {
1227 s_safePointBarrier->resumeOthers();
1228 }
1229
1230 void ThreadState::safePoint(BlinkGC::StackState stackState) 1180 void ThreadState::safePoint(BlinkGC::StackState stackState)
1231 { 1181 {
1232 ASSERT(checkThread()); 1182 ASSERT(checkThread());
1233 ThreadHeap::reportMemoryUsageForTracing(); 1183 ThreadHeap::reportMemoryUsageForTracing();
1234 1184
1235 runScheduledGC(stackState); 1185 runScheduledGC(stackState);
1236 ASSERT(!m_atSafePoint); 1186 ASSERT(!m_atSafePoint);
1237 m_stackState = stackState; 1187 m_stackState = stackState;
1238 m_atSafePoint = true; 1188 m_atSafePoint = true;
1239 s_safePointBarrier->checkAndPark(this); 1189 m_heap->checkAndPark(this, nullptr);
1240 m_atSafePoint = false; 1190 m_atSafePoint = false;
1241 m_stackState = BlinkGC::HeapPointersOnStack; 1191 m_stackState = BlinkGC::HeapPointersOnStack;
1242 preSweep(); 1192 preSweep();
1243 } 1193 }
1244 1194
1245 #ifdef ADDRESS_SANITIZER 1195 #ifdef ADDRESS_SANITIZER
1246 // When we are running under AddressSanitizer with detect_stack_use_after_return =1 1196 // When we are running under AddressSanitizer with detect_stack_use_after_return =1
1247 // then stack marker obtained from SafePointScope will point into a fake stack. 1197 // then stack marker obtained from SafePointScope will point into a fake stack.
1248 // Detect this case by checking if it falls in between current stack frame 1198 // Detect this case by checking if it falls in between current stack frame
1249 // and stack start and use an arbitrary high enough value for it. 1199 // and stack start and use an arbitrary high enough value for it.
(...skipping 23 matching lines...) Expand all
1273 #ifdef ADDRESS_SANITIZER 1223 #ifdef ADDRESS_SANITIZER
1274 if (stackState == BlinkGC::HeapPointersOnStack) 1224 if (stackState == BlinkGC::HeapPointersOnStack)
1275 scopeMarker = adjustScopeMarkerForAdressSanitizer(scopeMarker); 1225 scopeMarker = adjustScopeMarkerForAdressSanitizer(scopeMarker);
1276 #endif 1226 #endif
1277 ASSERT(stackState == BlinkGC::NoHeapPointersOnStack || scopeMarker); 1227 ASSERT(stackState == BlinkGC::NoHeapPointersOnStack || scopeMarker);
1278 runScheduledGC(stackState); 1228 runScheduledGC(stackState);
1279 ASSERT(!m_atSafePoint); 1229 ASSERT(!m_atSafePoint);
1280 m_atSafePoint = true; 1230 m_atSafePoint = true;
1281 m_stackState = stackState; 1231 m_stackState = stackState;
1282 m_safePointScopeMarker = scopeMarker; 1232 m_safePointScopeMarker = scopeMarker;
1283 s_safePointBarrier->enterSafePoint(this); 1233 m_heap->enterSafePoint(this);
1284 } 1234 }
1285 1235
1286 void ThreadState::leaveSafePoint(SafePointAwareMutexLocker* locker) 1236 void ThreadState::leaveSafePoint(SafePointAwareMutexLocker* locker)
1287 { 1237 {
1288 ASSERT(checkThread()); 1238 ASSERT(checkThread());
1289 ASSERT(m_atSafePoint); 1239 ASSERT(m_atSafePoint);
1290 s_safePointBarrier->leaveSafePoint(this, locker); 1240 m_heap->leaveSafePoint(this, locker);
1291 m_atSafePoint = false; 1241 m_atSafePoint = false;
1292 m_stackState = BlinkGC::HeapPointersOnStack; 1242 m_stackState = BlinkGC::HeapPointersOnStack;
1293 clearSafePointScopeMarker(); 1243 clearSafePointScopeMarker();
1294 preSweep(); 1244 preSweep();
1295 } 1245 }
1296 1246
1297 void ThreadState::reportMemoryToV8() 1247 void ThreadState::reportMemoryToV8()
1298 { 1248 {
1299 if (!m_isolate) 1249 if (!m_isolate)
1300 return; 1250 return;
1301 1251
1302 size_t currentHeapSize = m_allocatedObjectSize + m_markedObjectSize; 1252 size_t currentHeapSize = m_allocatedObjectSize + m_markedObjectSize;
1303 int64_t diff = static_cast<int64_t>(currentHeapSize) - static_cast<int64_t>( m_reportedMemoryToV8); 1253 int64_t diff = static_cast<int64_t>(currentHeapSize) - static_cast<int64_t>( m_reportedMemoryToV8);
1304 m_isolate->AdjustAmountOfExternalAllocatedMemory(diff); 1254 m_isolate->AdjustAmountOfExternalAllocatedMemory(diff);
1305 m_reportedMemoryToV8 = currentHeapSize; 1255 m_reportedMemoryToV8 = currentHeapSize;
1306 } 1256 }
1307 1257
1308 void ThreadState::resetHeapCounters() 1258 void ThreadState::resetHeapCounters()
1309 { 1259 {
1310 m_allocatedObjectSize = 0; 1260 m_allocatedObjectSize = 0;
1311 m_markedObjectSize = 0; 1261 m_markedObjectSize = 0;
1312 } 1262 }
1313 1263
1314 void ThreadState::increaseAllocatedObjectSize(size_t delta) 1264 void ThreadState::increaseAllocatedObjectSize(size_t delta)
1315 { 1265 {
1316 m_allocatedObjectSize += delta; 1266 m_allocatedObjectSize += delta;
1317 ThreadHeap::heapStats().increaseAllocatedObjectSize(delta); 1267 m_heap->heapStats().increaseAllocatedObjectSize(delta);
1318 } 1268 }
1319 1269
1320 void ThreadState::decreaseAllocatedObjectSize(size_t delta) 1270 void ThreadState::decreaseAllocatedObjectSize(size_t delta)
1321 { 1271 {
1322 m_allocatedObjectSize -= delta; 1272 m_allocatedObjectSize -= delta;
1323 ThreadHeap::heapStats().decreaseAllocatedObjectSize(delta); 1273 m_heap->heapStats().decreaseAllocatedObjectSize(delta);
1324 } 1274 }
1325 1275
1326 void ThreadState::increaseMarkedObjectSize(size_t delta) 1276 void ThreadState::increaseMarkedObjectSize(size_t delta)
1327 { 1277 {
1328 m_markedObjectSize += delta; 1278 m_markedObjectSize += delta;
1329 ThreadHeap::heapStats().increaseMarkedObjectSize(delta); 1279 m_heap->heapStats().increaseMarkedObjectSize(delta);
1330 } 1280 }
1331 1281
1332 void ThreadState::copyStackUntilSafePointScope() 1282 void ThreadState::copyStackUntilSafePointScope()
1333 { 1283 {
1334 if (!m_safePointScopeMarker || m_stackState == BlinkGC::NoHeapPointersOnStac k) 1284 if (!m_safePointScopeMarker || m_stackState == BlinkGC::NoHeapPointersOnStac k)
1335 return; 1285 return;
1336 1286
1337 Address* to = reinterpret_cast<Address*>(m_safePointScopeMarker); 1287 Address* to = reinterpret_cast<Address*>(m_safePointScopeMarker);
1338 Address* from = reinterpret_cast<Address*>(m_endOfStack); 1288 Address* from = reinterpret_cast<Address*>(m_endOfStack);
1339 RELEASE_ASSERT(from < to); 1289 RELEASE_ASSERT(from < to);
(...skipping 13 matching lines...) Expand all
1353 for (size_t i = 0; i < slotCount; ++i) { 1303 for (size_t i = 0; i < slotCount; ++i) {
1354 m_safePointStackCopy[i] = from[i]; 1304 m_safePointStackCopy[i] = from[i];
1355 } 1305 }
1356 } 1306 }
1357 1307
1358 void ThreadState::addInterruptor(PassOwnPtr<BlinkGCInterruptor> interruptor) 1308 void ThreadState::addInterruptor(PassOwnPtr<BlinkGCInterruptor> interruptor)
1359 { 1309 {
1360 ASSERT(checkThread()); 1310 ASSERT(checkThread());
1361 SafePointScope scope(BlinkGC::HeapPointersOnStack); 1311 SafePointScope scope(BlinkGC::HeapPointersOnStack);
1362 { 1312 {
1363 MutexLocker locker(threadAttachMutex()); 1313 MutexLocker locker(m_heap->threadAttachMutex());
1364 m_interruptors.append(interruptor); 1314 m_interruptors.append(interruptor);
1365 } 1315 }
1366 } 1316 }
1367 1317
1368 void ThreadState::registerThreadShutdownHook(PassOwnPtr<SameThreadClosure> hook) 1318 void ThreadState::registerThreadShutdownHook(PassOwnPtr<SameThreadClosure> hook)
1369 { 1319 {
1370 ASSERT(checkThread()); 1320 ASSERT(checkThread());
1371 ASSERT(!isTerminating()); 1321 ASSERT(!isTerminating());
1372 m_threadShutdownHooks.append(hook); 1322 m_threadShutdownHooks.append(hook);
1373 } 1323 }
(...skipping 21 matching lines...) Expand all
1395 m_disabledStaticPersistentsRegistration++; 1345 m_disabledStaticPersistentsRegistration++;
1396 } 1346 }
1397 1347
1398 void ThreadState::leaveStaticReferenceRegistrationDisabledScope() 1348 void ThreadState::leaveStaticReferenceRegistrationDisabledScope()
1399 { 1349 {
1400 ASSERT(m_disabledStaticPersistentsRegistration); 1350 ASSERT(m_disabledStaticPersistentsRegistration);
1401 m_disabledStaticPersistentsRegistration--; 1351 m_disabledStaticPersistentsRegistration--;
1402 } 1352 }
1403 #endif 1353 #endif
1404 1354
1405 ThreadState::AttachedThreadStateSet& ThreadState::attachedThreads()
1406 {
1407 DEFINE_STATIC_LOCAL(AttachedThreadStateSet, threads, ());
1408 return threads;
1409 }
1410
1411 void ThreadState::lockThreadAttachMutex() 1355 void ThreadState::lockThreadAttachMutex()
1412 { 1356 {
1413 threadAttachMutex().lock(); 1357 m_heap->threadAttachMutex().lock();
1414 } 1358 }
1415 1359
1416 void ThreadState::unlockThreadAttachMutex() 1360 void ThreadState::unlockThreadAttachMutex()
1417 { 1361 {
1418 threadAttachMutex().unlock(); 1362 m_heap->threadAttachMutex().unlock();
1419 } 1363 }
1420 1364
1421 void ThreadState::invokePreFinalizers() 1365 void ThreadState::invokePreFinalizers()
1422 { 1366 {
1423 ASSERT(checkThread()); 1367 ASSERT(checkThread());
1424 ASSERT(!sweepForbidden()); 1368 ASSERT(!sweepForbidden());
1425 TRACE_EVENT0("blink_gc", "ThreadState::invokePreFinalizers"); 1369 TRACE_EVENT0("blink_gc", "ThreadState::invokePreFinalizers");
1426 1370
1427 double startTime = WTF::currentTimeMS(); 1371 double startTime = WTF::currentTimeMS();
1428 if (!m_orderedPreFinalizers.isEmpty()) { 1372 if (!m_orderedPreFinalizers.isEmpty()) {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1564 threadDump->addScalar("dead_count", "objects", totalDeadCount); 1508 threadDump->addScalar("dead_count", "objects", totalDeadCount);
1565 threadDump->addScalar("live_size", "bytes", totalLiveSize); 1509 threadDump->addScalar("live_size", "bytes", totalLiveSize);
1566 threadDump->addScalar("dead_size", "bytes", totalDeadSize); 1510 threadDump->addScalar("dead_size", "bytes", totalDeadSize);
1567 1511
1568 WebMemoryAllocatorDump* heapsDump = BlinkGCMemoryDumpProvider::instance()->c reateMemoryAllocatorDumpForCurrentGC(heapsDumpName); 1512 WebMemoryAllocatorDump* heapsDump = BlinkGCMemoryDumpProvider::instance()->c reateMemoryAllocatorDumpForCurrentGC(heapsDumpName);
1569 WebMemoryAllocatorDump* classesDump = BlinkGCMemoryDumpProvider::instance()- >createMemoryAllocatorDumpForCurrentGC(classesDumpName); 1513 WebMemoryAllocatorDump* classesDump = BlinkGCMemoryDumpProvider::instance()- >createMemoryAllocatorDumpForCurrentGC(classesDumpName);
1570 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->addOwners hipEdge(classesDump->guid(), heapsDump->guid()); 1514 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->addOwners hipEdge(classesDump->guid(), heapsDump->guid());
1571 } 1515 }
1572 1516
1573 } // namespace blink 1517 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698