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

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

Powered by Google App Engine
This is Rietveld 408576698