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

Side by Side Diff: sky/engine/platform/heap/Heap.cpp

Issue 678003003: Begin to remove heap/* (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month 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
« no previous file with comments | « sky/engine/platform/heap/Heap.h ('k') | sky/engine/platform/heap/HeapTerminatedArray.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 // C++ objects can contain pointers to objects outside of the heap and 347 // C++ objects can contain pointers to objects outside of the heap and
348 // should therefore be part of the LSan root set. 348 // should therefore be part of the LSan root set.
349 __lsan_register_root_region(m_writable.base(), m_writable.size()); 349 __lsan_register_root_region(m_writable.base(), m_writable.size());
350 } 350 }
351 351
352 352
353 PageMemoryRegion* m_reserved; 353 PageMemoryRegion* m_reserved;
354 MemoryRegion m_writable; 354 MemoryRegion m_writable;
355 }; 355 };
356 356
357 class GCScope {
358 public:
359 explicit GCScope(ThreadState::StackState stackState)
360 : m_state(ThreadState::current())
361 , m_safePointScope(stackState)
362 , m_parkedAllThreads(false)
363 {
364 TRACE_EVENT0("blink_gc", "Heap::GCScope");
365 const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE();
366 if (m_state->isMainThread())
367 TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting");
368
369 m_state->checkThread();
370
371 // FIXME: in an unlikely coincidence that two threads decide
372 // to collect garbage at the same time, avoid doing two GCs in
373 // a row.
374 RELEASE_ASSERT(!m_state->isInGC());
375 RELEASE_ASSERT(!m_state->isSweepInProgress());
376 if (LIKELY(ThreadState::stopThreads())) {
377 m_parkedAllThreads = true;
378 m_state->enterGC();
379 }
380 if (m_state->isMainThread())
381 TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState);
382 }
383
384 bool allThreadsParked() { return m_parkedAllThreads; }
385
386 ~GCScope()
387 {
388 // Only cleanup if we parked all threads in which case the GC happened
389 // and we need to resume the other threads.
390 if (LIKELY(m_parkedAllThreads)) {
391 m_state->leaveGC();
392 ASSERT(!m_state->isInGC());
393 ThreadState::resumeThreads();
394 }
395 }
396
397 private:
398 ThreadState* m_state;
399 ThreadState::SafePointScope m_safePointScope;
400 bool m_parkedAllThreads; // False if we fail to park all threads
401 };
402
403 NO_SANITIZE_ADDRESS 357 NO_SANITIZE_ADDRESS
404 bool HeapObjectHeader::isMarked() const 358 bool HeapObjectHeader::isMarked() const
405 { 359 {
406 checkHeader(); 360 checkHeader();
407 unsigned size = acquireLoad(&m_size); 361 unsigned size = acquireLoad(&m_size);
408 return size & markBitMask; 362 return size & markBitMask;
409 } 363 }
410 364
411 NO_SANITIZE_ADDRESS 365 NO_SANITIZE_ADDRESS
412 void HeapObjectHeader::unmark() 366 void HeapObjectHeader::unmark()
(...skipping 1788 matching lines...) Expand 10 before | Expand all | Expand 10 after
2201 protected: 2155 protected:
2202 virtual void registerWeakCell(void** cell, WeakPointerCallback callback) ove rride 2156 virtual void registerWeakCell(void** cell, WeakPointerCallback callback) ove rride
2203 { 2157 {
2204 Heap::pushWeakCellPointerCallback(cell, callback); 2158 Heap::pushWeakCellPointerCallback(cell, callback);
2205 } 2159 }
2206 2160
2207 private: 2161 private:
2208 CallbackStack** m_markingStack; 2162 CallbackStack** m_markingStack;
2209 }; 2163 };
2210 2164
2211 void Heap::init()
2212 {
2213 ThreadState::init();
2214 CallbackStack::init(&s_markingStack);
2215 CallbackStack::init(&s_postMarkingCallbackStack);
2216 CallbackStack::init(&s_weakCallbackStack);
2217 CallbackStack::init(&s_ephemeronStack);
2218 s_heapDoesNotContainCache = new HeapDoesNotContainCache();
2219 s_markingVisitor = new MarkingVisitor(&s_markingStack);
2220 s_freePagePool = new FreePagePool();
2221 s_orphanedPagePool = new OrphanedPagePool();
2222 s_markingThreads = new Vector<OwnPtr<blink::WebThread> >();
2223 }
2224
2225 void Heap::shutdown()
2226 {
2227 s_shutdownCalled = true;
2228 ThreadState::shutdownHeapIfNecessary();
2229 }
2230
2231 void Heap::doShutdown()
2232 {
2233 // We don't want to call doShutdown() twice.
2234 if (!s_markingVisitor)
2235 return;
2236
2237 ASSERT(!ThreadState::isAnyThreadInGC());
2238 ASSERT(!ThreadState::attachedThreads().size());
2239 delete s_markingThreads;
2240 s_markingThreads = 0;
2241 delete s_markingVisitor;
2242 s_markingVisitor = 0;
2243 delete s_heapDoesNotContainCache;
2244 s_heapDoesNotContainCache = 0;
2245 delete s_freePagePool;
2246 s_freePagePool = 0;
2247 delete s_orphanedPagePool;
2248 s_orphanedPagePool = 0;
2249 CallbackStack::shutdown(&s_weakCallbackStack);
2250 CallbackStack::shutdown(&s_postMarkingCallbackStack);
2251 CallbackStack::shutdown(&s_markingStack);
2252 CallbackStack::shutdown(&s_ephemeronStack);
2253 ThreadState::shutdown();
2254 }
2255
2256 BaseHeapPage* Heap::contains(Address address) 2165 BaseHeapPage* Heap::contains(Address address)
2257 { 2166 {
2258 ASSERT(ThreadState::isAnyThreadInGC()); 2167 ASSERT(ThreadState::isAnyThreadInGC());
2259 ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads( ); 2168 ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads( );
2260 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it) { 2169 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it) {
2261 BaseHeapPage* page = (*it)->contains(address); 2170 BaseHeapPage* page = (*it)->contains(address);
2262 if (page) 2171 if (page)
2263 return page; 2172 return page;
2264 } 2173 }
2265 return 0; 2174 return 0;
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
2433 void Heap::prepareForGC() 2342 void Heap::prepareForGC()
2434 { 2343 {
2435 ASSERT(ThreadState::isAnyThreadInGC()); 2344 ASSERT(ThreadState::isAnyThreadInGC());
2436 ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads( ); 2345 ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads( );
2437 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it) 2346 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it)
2438 (*it)->prepareForGC(); 2347 (*it)->prepareForGC();
2439 } 2348 }
2440 2349
2441 void Heap::collectGarbage(ThreadState::StackState stackState) 2350 void Heap::collectGarbage(ThreadState::StackState stackState)
2442 { 2351 {
2443 ThreadState* state = ThreadState::current();
2444 state->clearGCRequested();
2445
2446 GCScope gcScope(stackState);
2447 // Check if we successfully parked the other threads. If not we bail out of the GC.
2448 if (!gcScope.allThreadsParked()) {
2449 ThreadState::current()->setGCRequested();
2450 return;
2451 }
2452
2453 if (state->isMainThread())
2454 ScriptForbiddenScope::enter();
2455
2456 s_lastGCWasConservative = false;
2457
2458 TRACE_EVENT0("blink_gc", "Heap::collectGarbage");
2459 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC");
2460 double timeStamp = WTF::currentTimeMS();
2461 #if ENABLE(GC_PROFILE_MARKING)
2462 static_cast<MarkingVisitor*>(s_markingVisitor)->objectGraph().clear();
2463 #endif
2464
2465 // Disallow allocation during garbage collection (but not
2466 // during the finalization that happens when the gcScope is
2467 // torn down).
2468 NoAllocationScope<AnyThread> noAllocationScope;
2469
2470 prepareForGC();
2471
2472 // 1. trace persistent roots.
2473 ThreadState::visitPersistentRoots(s_markingVisitor);
2474
2475 // 2. trace objects reachable from the persistent roots including ephemerons .
2476 processMarkingStackInParallel();
2477
2478 // 3. trace objects reachable from the stack. We do this independent of the
2479 // given stackState since other threads might have a different stack state.
2480 ThreadState::visitStackRoots(s_markingVisitor);
2481
2482 // 4. trace objects reachable from the stack "roots" including ephemerons.
2483 // Only do the processing if we found a pointer to an object on one of the
2484 // thread stacks.
2485 if (lastGCWasConservative())
2486 processMarkingStackInParallel();
2487
2488 postMarkingProcessing();
2489 globalWeakProcessing();
2490
2491 // After a global marking we know that any orphaned page that was not reache d
2492 // cannot be reached in a subsequent GC. This is due to a thread either havi ng
2493 // swept its heap or having done a "poor mans sweep" in prepareForGC which m arks
2494 // objects that are dead, but not swept in the previous GC as dead. In this GC's
2495 // marking we check that any object marked as dead is not traced. E.g. via a
2496 // conservatively found pointer or a programming error with an object contai ning
2497 // a dangling pointer.
2498 orphanedPagePool()->decommitOrphanedPages();
2499
2500 #if ENABLE(GC_PROFILE_MARKING)
2501 static_cast<MarkingVisitor*>(s_markingVisitor)->reportStats();
2502 #endif
2503
2504 if (blink::Platform::current()) {
2505 uint64_t objectSpaceSize;
2506 uint64_t allocatedSpaceSize;
2507 getHeapSpaceSize(&objectSpaceSize, &allocatedSpaceSize);
2508 blink::Platform::current()->histogramCustomCounts("BlinkGC.CollectGarbag e", WTF::currentTimeMS() - timeStamp, 0, 10 * 1000, 50);
2509 blink::Platform::current()->histogramCustomCounts("BlinkGC.TotalObjectSp ace", objectSpaceSize / 1024, 0, 4 * 1024 * 1024, 50);
2510 blink::Platform::current()->histogramCustomCounts("BlinkGC.TotalAllocate dSpace", allocatedSpaceSize / 1024, 0, 4 * 1024 * 1024, 50);
2511 }
2512
2513 if (state->isMainThread())
2514 ScriptForbiddenScope::exit();
2515 } 2352 }
2516 2353
2517 void Heap::collectGarbageForTerminatingThread(ThreadState* state) 2354 void Heap::collectGarbageForTerminatingThread(ThreadState* state)
2518 { 2355 {
2519 // We explicitly do not enter a safepoint while doing thread specific
2520 // garbage collection since we don't want to allow a global GC at the
2521 // same time as a thread local GC.
2522
2523 {
2524 NoAllocationScope<AnyThread> noAllocationScope;
2525
2526 state->enterGC();
2527 state->prepareForGC();
2528
2529 // 1. trace the thread local persistent roots. For thread local GCs we
2530 // don't trace the stack (ie. no conservative scanning) since this is
2531 // only called during thread shutdown where there should be no objects
2532 // on the stack.
2533 // We also assume that orphaned pages have no objects reachable from
2534 // persistent handles on other threads or CrossThreadPersistents. The
2535 // only cases where this could happen is if a subsequent conservative
2536 // global GC finds a "pointer" on the stack or due to a programming
2537 // error where an object has a dangling cross-thread pointer to an
2538 // object on this heap.
2539 state->visitPersistents(s_markingVisitor);
2540
2541 // 2. trace objects reachable from the thread's persistent roots
2542 // including ephemerons.
2543 processMarkingStack<ThreadLocalMarking>();
2544
2545 postMarkingProcessing();
2546 globalWeakProcessing();
2547
2548 state->leaveGC();
2549 }
2550 state->performPendingSweep();
2551 } 2356 }
2552 2357
2553 void Heap::processMarkingStackEntries(int* runningMarkingThreads) 2358 void Heap::processMarkingStackEntries(int* runningMarkingThreads)
2554 { 2359 {
2555 CallbackStack* stack = 0; 2360 CallbackStack* stack = 0;
2556 MarkingVisitor visitor(&stack); 2361 MarkingVisitor visitor(&stack);
2557 { 2362 {
2558 MutexLocker locker(markingMutex()); 2363 MutexLocker locker(markingMutex());
2559 stack = s_markingStack->takeCallbacks(&s_markingStack); 2364 stack = s_markingStack->takeCallbacks(&s_markingStack);
2560 } 2365 }
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
2811 CallbackStack* Heap::s_markingStack; 2616 CallbackStack* Heap::s_markingStack;
2812 CallbackStack* Heap::s_postMarkingCallbackStack; 2617 CallbackStack* Heap::s_postMarkingCallbackStack;
2813 CallbackStack* Heap::s_weakCallbackStack; 2618 CallbackStack* Heap::s_weakCallbackStack;
2814 CallbackStack* Heap::s_ephemeronStack; 2619 CallbackStack* Heap::s_ephemeronStack;
2815 HeapDoesNotContainCache* Heap::s_heapDoesNotContainCache; 2620 HeapDoesNotContainCache* Heap::s_heapDoesNotContainCache;
2816 bool Heap::s_shutdownCalled = false; 2621 bool Heap::s_shutdownCalled = false;
2817 bool Heap::s_lastGCWasConservative = false; 2622 bool Heap::s_lastGCWasConservative = false;
2818 FreePagePool* Heap::s_freePagePool; 2623 FreePagePool* Heap::s_freePagePool;
2819 OrphanedPagePool* Heap::s_orphanedPagePool; 2624 OrphanedPagePool* Heap::s_orphanedPagePool;
2820 } 2625 }
OLDNEW
« no previous file with comments | « sky/engine/platform/heap/Heap.h ('k') | sky/engine/platform/heap/HeapTerminatedArray.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698