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

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

Issue 717923005: Profile FreeList Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years 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 | Annotate | Revision Log
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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 #include "wtf/LeakAnnotations.h" 42 #include "wtf/LeakAnnotations.h"
43 #include "wtf/PassOwnPtr.h" 43 #include "wtf/PassOwnPtr.h"
44 #if ENABLE(GC_PROFILE_MARKING) 44 #if ENABLE(GC_PROFILE_MARKING)
45 #include "wtf/HashMap.h" 45 #include "wtf/HashMap.h"
46 #include "wtf/HashSet.h" 46 #include "wtf/HashSet.h"
47 #include "wtf/text/StringBuilder.h" 47 #include "wtf/text/StringBuilder.h"
48 #include "wtf/text/StringHash.h" 48 #include "wtf/text/StringHash.h"
49 #include <stdio.h> 49 #include <stdio.h>
50 #include <utility> 50 #include <utility>
51 #endif 51 #endif
52 #if ENABLE(GC_PROFILE_HEAP) 52 #if ENABLE(GC_PROFILE_HEAP) || ENABLE(GC_PROFILE_FREE_LIST) || ENABLE(GC_PROFILE _MARKING)
53 #include "platform/TracedValue.h" 53 #include "platform/TracedValue.h"
54 #endif 54 #endif
55 55
56 #if OS(POSIX) 56 #if OS(POSIX)
57 #include <sys/mman.h> 57 #include <sys/mman.h>
58 #include <unistd.h> 58 #include <unistd.h>
59 #elif OS(WIN) 59 #elif OS(WIN)
60 #include <windows.h> 60 #include <windows.h>
61 #endif 61 #endif
62 62
63 namespace blink { 63 namespace blink {
64 64
65 struct AgeHistogram {
66 int data[8];
67 };
68
69 typedef HashMap<String, AgeHistogram> ObjectAgeMap;
70
71 static ObjectAgeMap& uom()
72 {
73 static ObjectAgeMap uomap;
74 return uomap;
75 }
76
77 static Mutex& uomMutex()
78 {
79 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
80 return mutex;
81 }
82
83 static ObjectAgeMap& mom()
84 {
85 static ObjectAgeMap momap;
86 return momap;
87 }
88
89 static Mutex& momMutex()
90 {
91 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
92 return mutex;
93 }
94
65 #if ENABLE(GC_PROFILE_MARKING) 95 #if ENABLE(GC_PROFILE_MARKING)
66 static String classOf(const void* object) 96 static String classOf(const void* object)
67 { 97 {
68 const GCInfo* gcInfo = Heap::findGCInfo(reinterpret_cast<Address>(const_cast <void*>(object))); 98 const GCInfo* gcInfo = Heap::findGCInfo(reinterpret_cast<Address>(const_cast <void*>(object)));
69 if (gcInfo) 99 if (gcInfo)
70 return gcInfo->m_className; 100 return gcInfo->m_className;
71 101
72 return "unknown"; 102 return "unknown";
73 } 103 }
74 #endif 104 #endif
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 FinalizedHeapObjectHeader* header = 664 FinalizedHeapObjectHeader* header =
635 reinterpret_cast<FinalizedHeapObjectHeader*>(addr - finalizedHeaderSize) ; 665 reinterpret_cast<FinalizedHeapObjectHeader*>(addr - finalizedHeaderSize) ;
636 return header; 666 return header;
637 } 667 }
638 668
639 template<typename Header> 669 template<typename Header>
640 ThreadHeap<Header>::ThreadHeap(ThreadState* state, int index) 670 ThreadHeap<Header>::ThreadHeap(ThreadState* state, int index)
641 : m_currentAllocationPoint(0) 671 : m_currentAllocationPoint(0)
642 , m_remainingAllocationSize(0) 672 , m_remainingAllocationSize(0)
643 , m_lastRemainingAllocationSize(0) 673 , m_lastRemainingAllocationSize(0)
674 #if ENABLE(GC_PROFILE_FREE_LIST)
675 , m_totalAllocationSize(0.0)
676 , m_allocationCount(0)
677 , m_inlineAllocationCount(0)
678 #endif
644 , m_firstPage(0) 679 , m_firstPage(0)
645 , m_firstLargeObject(0) 680 , m_firstLargeObject(0)
646 , m_firstPageAllocatedDuringSweeping(0) 681 , m_firstPageAllocatedDuringSweeping(0)
647 , m_lastPageAllocatedDuringSweeping(0) 682 , m_lastPageAllocatedDuringSweeping(0)
648 , m_firstLargeObjectAllocatedDuringSweeping(0) 683 , m_firstLargeObjectAllocatedDuringSweeping(0)
649 , m_lastLargeObjectAllocatedDuringSweeping(0) 684 , m_lastLargeObjectAllocatedDuringSweeping(0)
650 , m_threadState(state) 685 , m_threadState(state)
651 , m_index(index) 686 , m_index(index)
652 , m_numberOfNormalPages(0) 687 , m_numberOfNormalPages(0)
653 , m_promptlyFreedCount(0) 688 , m_promptlyFreedCount(0)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 if (m_lastRemainingAllocationSize > remainingAllocationSize()) { 728 if (m_lastRemainingAllocationSize > remainingAllocationSize()) {
694 Heap::increaseAllocatedObjectSize(m_lastRemainingAllocationSize - remain ingAllocationSize()); 729 Heap::increaseAllocatedObjectSize(m_lastRemainingAllocationSize - remain ingAllocationSize());
695 m_lastRemainingAllocationSize = remainingAllocationSize(); 730 m_lastRemainingAllocationSize = remainingAllocationSize();
696 } 731 }
697 ASSERT(m_lastRemainingAllocationSize == remainingAllocationSize()); 732 ASSERT(m_lastRemainingAllocationSize == remainingAllocationSize());
698 } 733 }
699 734
700 template<typename Header> 735 template<typename Header>
701 Address ThreadHeap<Header>::outOfLineAllocate(size_t payloadSize, size_t allocat ionSize, const GCInfo* gcInfo) 736 Address ThreadHeap<Header>::outOfLineAllocate(size_t payloadSize, size_t allocat ionSize, const GCInfo* gcInfo)
702 { 737 {
738 #if ENABLE(GC_PROFILE_FREE_LIST)
739 m_threadState->snapshotFreeListIfNecessary();
740 #endif
703 ASSERT(allocationSize > remainingAllocationSize()); 741 ASSERT(allocationSize > remainingAllocationSize());
704 if (allocationSize > blinkPageSize / 2) 742 if (allocationSize > blinkPageSize / 2)
705 return allocateLargeObject(allocationSize, gcInfo); 743 return allocateLargeObject(allocationSize, gcInfo);
706 744
707 updateRemainingAllocationSize(); 745 updateRemainingAllocationSize();
708 if (threadState()->shouldGC()) { 746 if (threadState()->shouldGC()) {
709 if (threadState()->shouldForceConservativeGC()) 747 if (threadState()->shouldForceConservativeGC())
710 Heap::collectGarbage(ThreadState::HeapPointersOnStack); 748 Heap::collectGarbage(ThreadState::HeapPointersOnStack);
711 else 749 else
712 threadState()->setGCRequested(); 750 threadState()->setGCRequested();
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 const GCInfo* ThreadHeap<Header>::findGCInfoOfLargeObject(Address address) 830 const GCInfo* ThreadHeap<Header>::findGCInfoOfLargeObject(Address address)
793 { 831 {
794 for (LargeObject<Header>* largeObject = m_firstLargeObject; largeObject; lar geObject = largeObject->next()) { 832 for (LargeObject<Header>* largeObject = m_firstLargeObject; largeObject; lar geObject = largeObject->next()) {
795 if (largeObject->contains(address)) 833 if (largeObject->contains(address))
796 return largeObject->gcInfo(); 834 return largeObject->gcInfo();
797 } 835 }
798 return 0; 836 return 0;
799 } 837 }
800 #endif 838 #endif
801 839
840 #if ENABLE(GC_PROFILE_FREE_LIST)
841 template<typename Header>
842 void ThreadHeap<Header>::snapshotFreeList(TracedValue* json)
843 {
844 json->setDouble("totalAllocationSize", m_totalAllocationSize);
845 json->setDouble("inlineAllocationRate", static_cast<double>(m_inlineAllocati onCount) / m_allocationCount);
846 json->setInteger("inlineAllocationCount", m_inlineAllocationCount);
847 json->setInteger("allocationCount", m_allocationCount);
848 if (m_setAllocationPointCount > 0) {
849 json->setDouble("averageAllocationPointSize", static_cast<double>(m_alloca tionPointSizeSum) / m_setAllocationPointCount);
850 }
851 m_allocationPointSizeSum = 0;
852 m_setAllocationPointCount = 0;
853 size_t pageCount = 0;
854 size_t totalPageSize = 0;
855 for (HeapPage<Header>* page = m_firstPage; page; page = page->next()) {
856 ++pageCount;
857 totalPageSize += page->payloadSize();
858 }
859 json->setInteger("pageCount", pageCount);
860 json->setInteger("totalPageSize", totalPageSize);
861 size_t bucketSizes[blinkPageSizeLog2];
862 size_t bucketTotalSizes[blinkPageSizeLog2];
863 size_t freeSize = 0;
864 m_freeList.countBucketSizes(bucketSizes, bucketTotalSizes, &freeSize);
865 json->setInteger("freeSize", freeSize);
866 json->beginArray("bucketSizes");
867 for (size_t i = 0; i < blinkPageSizeLog2; ++i) {
868 json->pushInteger(bucketSizes[i]);
869 }
870 json->endArray();
871 json->beginArray("bucketTotalSizes");
872 for (size_t i = 0; i < blinkPageSizeLog2; ++i) {
873 json->pushInteger(bucketTotalSizes[i]);
874 }
875 json->endArray();
876 }
877 #endif
878
802 #if ENABLE(GC_PROFILE_HEAP) 879 #if ENABLE(GC_PROFILE_HEAP)
803 #define GC_PROFILE_HEAP_PAGE_SNAPSHOT_THRESHOLD 0 880 #define GC_PROFILE_HEAP_PAGE_SNAPSHOT_THRESHOLD 0
804 template<typename Header> 881 template<typename Header>
805 void ThreadHeap<Header>::snapshot(TracedValue* json, ThreadState::SnapshotInfo* info) 882 void ThreadHeap<Header>::snapshot(TracedValue* json, ThreadState::SnapshotInfo* info)
806 { 883 {
807 size_t previousPageCount = info->pageCount; 884 size_t previousPageCount = info->pageCount;
808 885
809 json->beginArray("pages"); 886 json->beginArray("pages");
810 for (HeapPage<Header>* page = m_firstPage; page; page = page->next(), ++info ->pageCount) { 887 for (HeapPage<Header>* page = m_firstPage; page; page = page->next(), ++info ->pageCount) {
811 // FIXME: To limit the size of the snapshot we only output "threshold" m any page snapshots. 888 // FIXME: To limit the size of the snapshot we only output "threshold" m any page snapshots.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 return; 936 return;
860 #endif 937 #endif
861 int index = bucketIndexForSize(size); 938 int index = bucketIndexForSize(size);
862 entry->link(&m_freeLists[index]); 939 entry->link(&m_freeLists[index]);
863 if (!m_lastFreeListEntries[index]) 940 if (!m_lastFreeListEntries[index])
864 m_lastFreeListEntries[index] = entry; 941 m_lastFreeListEntries[index] = entry;
865 if (index > m_biggestFreeListIndex) 942 if (index > m_biggestFreeListIndex)
866 m_biggestFreeListIndex = index; 943 m_biggestFreeListIndex = index;
867 } 944 }
868 945
946 #if ENABLE(GC_PROFILE_FREE_LIST)
947 template<typename Header>
948 void FreeList<Header>::countBucketSizes(size_t sizes[], size_t totalSizes[], siz e_t* freeSize) const
949 {
950 *freeSize = 0;
951 for (size_t i = 0; i < blinkPageSizeLog2; i++) {
952 sizes[i] = 0;
953 totalSizes[i] = 0;
954 FreeListEntry* entry = m_freeLists[i];
955 while (entry) {
956 ++sizes[i];
957 *freeSize += entry->size();
958 totalSizes[i] += entry->size();
959 entry = entry->next();
960 }
961 }
962 }
963 #endif
964
869 template<typename Header> 965 template<typename Header>
870 bool ThreadHeap<Header>::expandObject(Header* header, size_t newSize) 966 bool ThreadHeap<Header>::expandObject(Header* header, size_t newSize)
871 { 967 {
872 ASSERT(header->payloadSize() < newSize); 968 ASSERT(header->payloadSize() < newSize);
873 size_t allocationSize = allocationSizeFromSize(newSize); 969 size_t allocationSize = allocationSizeFromSize(newSize);
874 ASSERT(allocationSize > header->size()); 970 ASSERT(allocationSize > header->size());
875 size_t expandSize = allocationSize - header->size(); 971 size_t expandSize = allocationSize - header->size();
876 if (header->payloadEnd() == m_currentAllocationPoint && expandSize <= m_rema iningAllocationSize) { 972 if (header->payloadEnd() == m_currentAllocationPoint && expandSize <= m_rema iningAllocationSize) {
877 m_currentAllocationPoint += expandSize; 973 m_currentAllocationPoint += expandSize;
878 m_remainingAllocationSize -= expandSize; 974 m_remainingAllocationSize -= expandSize;
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 // STRICT_ASAN_FINALIZATION_CHECKING turns on poisoning of all objects during 1533 // STRICT_ASAN_FINALIZATION_CHECKING turns on poisoning of all objects during
1438 // sweeping to catch cases where dead objects touch each other. This is not 1534 // sweeping to catch cases where dead objects touch each other. This is not
1439 // turned on by default because it also triggers for cases that are safe. 1535 // turned on by default because it also triggers for cases that are safe.
1440 // Examples of such safe cases are context life cycle observers and timers 1536 // Examples of such safe cases are context life cycle observers and timers
1441 // embedded in garbage collected objects. 1537 // embedded in garbage collected objects.
1442 #define STRICT_ASAN_FINALIZATION_CHECKING 0 1538 #define STRICT_ASAN_FINALIZATION_CHECKING 0
1443 1539
1444 template<typename Header> 1540 template<typename Header>
1445 void ThreadHeap<Header>::sweep() 1541 void ThreadHeap<Header>::sweep()
1446 { 1542 {
1543 for (HeapPage<Header>* page = m_firstPage; page; page = page->next()) {
1544 page->countUnmarkedObjects();
1545 }
1447 ASSERT(isConsistentForSweeping()); 1546 ASSERT(isConsistentForSweeping());
1448 #if defined(ADDRESS_SANITIZER) && STRICT_ASAN_FINALIZATION_CHECKING 1547 #if defined(ADDRESS_SANITIZER) && STRICT_ASAN_FINALIZATION_CHECKING
1449 // When using ASan do a pre-sweep where all unmarked objects are 1548 // When using ASan do a pre-sweep where all unmarked objects are
1450 // poisoned before calling their finalizer methods. This can catch 1549 // poisoned before calling their finalizer methods. This can catch
1451 // the case where the finalizer of an object tries to modify 1550 // the case where the finalizer of an object tries to modify
1452 // another object as part of finalization. 1551 // another object as part of finalization.
1453 for (HeapPage<Header>* page = m_firstPage; page; page = page->next()) 1552 for (HeapPage<Header>* page = m_firstPage; page; page = page->next())
1454 page->poisonUnmarkedObjects(); 1553 page->poisonUnmarkedObjects();
1455 #endif 1554 #endif
1456 sweepNormalPages(); 1555 sweepNormalPages();
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
1828 Header* header = reinterpret_cast<Header*>(headerAddress); 1927 Header* header = reinterpret_cast<Header*>(headerAddress);
1829 ASSERT(header->size() < blinkPagePayloadSize()); 1928 ASSERT(header->size() < blinkPagePayloadSize());
1830 1929
1831 if (!header->isFree() && !header->isMarked()) 1930 if (!header->isFree() && !header->isMarked())
1832 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize()); 1931 ASAN_POISON_MEMORY_REGION(header->payload(), header->payloadSize());
1833 headerAddress += header->size(); 1932 headerAddress += header->size();
1834 } 1933 }
1835 } 1934 }
1836 #endif 1935 #endif
1837 1936
1937 template<typename Header>
1938 void HeapPage<Header>::countUnmarkedObjects()
1939 {
1940 MutexLocker locker(uomMutex());
1941 for (Address headerAddress = payload(); headerAddress < end(); ) {
1942 Header* header = reinterpret_cast<Header*>(headerAddress);
1943 ASSERT(header->size() < blinkPagePayloadSize());
1944
1945 if (!header->isFree() && !header->isMarked()) {
1946 String className(classOf(header->payload()));
1947 ObjectAgeMap::AddResult result = uom().add(className, AgeHistogram() );
1948 result.storedValue->value.data[header->age()]++;
1949 }
1950 headerAddress += header->size();
1951 }
1952 }
1953
1838 template<> 1954 template<>
1839 inline void HeapPage<FinalizedHeapObjectHeader>::finalize(FinalizedHeapObjectHea der* header) 1955 inline void HeapPage<FinalizedHeapObjectHeader>::finalize(FinalizedHeapObjectHea der* header)
1840 { 1956 {
1841 header->finalize(); 1957 header->finalize();
1842 } 1958 }
1843 1959
1844 template<> 1960 template<>
1845 inline void HeapPage<HeapObjectHeader>::finalize(HeapObjectHeader* header) 1961 inline void HeapPage<HeapObjectHeader>::finalize(HeapObjectHeader* header)
1846 { 1962 {
1847 ASSERT(gcInfo()); 1963 ASSERT(gcInfo());
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1989 // when doing weakness for ephemerons. Hence we only check 2105 // when doing weakness for ephemerons. Hence we only check
1990 // when called within. 2106 // when called within.
1991 ASSERT(!ThreadState::isAnyThreadInGC() || Heap::containedInHeapOrOrp hanedPage(header)); 2107 ASSERT(!ThreadState::isAnyThreadInGC() || Heap::containedInHeapOrOrp hanedPage(header));
1992 } 2108 }
1993 #endif 2109 #endif
1994 ASSERT(objectPointer); 2110 ASSERT(objectPointer);
1995 if (header->isMarked()) 2111 if (header->isMarked())
1996 return; 2112 return;
1997 header->mark(); 2113 header->mark();
1998 #if ENABLE(GC_PROFILE_MARKING) 2114 #if ENABLE(GC_PROFILE_MARKING)
2115 header->incAge();
2116
1999 MutexLocker locker(objectGraphMutex()); 2117 MutexLocker locker(objectGraphMutex());
2000 String className(classOf(objectPointer)); 2118 String className(classOf(objectPointer));
2001 { 2119 {
2002 LiveObjectMap::AddResult result = currentlyLive().add(className, Liv eObjectSet()); 2120 LiveObjectMap::AddResult result = currentlyLive().add(className, Liv eObjectSet());
2003 result.storedValue->value.add(reinterpret_cast<uintptr_t>(objectPoin ter)); 2121 result.storedValue->value.add(reinterpret_cast<uintptr_t>(objectPoin ter));
2004 } 2122 }
2123 {
2124 MutexLocker locker(momMutex());
2125 ObjectAgeMap::AddResult result = mom().add(className, AgeHistogram() );
2126 result.storedValue->value.data[header->age()]++;
2127 }
2005 ObjectGraph::AddResult result = objectGraph().add(reinterpret_cast<uintp tr_t>(objectPointer), std::make_pair(reinterpret_cast<uintptr_t>(m_hostObject), m_hostName)); 2128 ObjectGraph::AddResult result = objectGraph().add(reinterpret_cast<uintp tr_t>(objectPointer), std::make_pair(reinterpret_cast<uintptr_t>(m_hostObject), m_hostName));
2006 ASSERT(result.isNewEntry); 2129 ASSERT(result.isNewEntry);
2007 // fprintf(stderr, "%s[%p] -> %s[%p]\n", m_hostName.ascii().data(), m_ho stObject, className.ascii().data(), objectPointer); 2130 // fprintf(stderr, "%s[%p] -> %s[%p]\n", m_hostName.ascii().data(), m_ho stObject, className.ascii().data(), objectPointer);
2008 #endif 2131 #endif
2009 if (callback) 2132 if (callback)
2010 Heap::pushTraceCallback(m_markingStack, const_cast<void*>(objectPoin ter), callback); 2133 Heap::pushTraceCallback(m_markingStack, const_cast<void*>(objectPoin ter), callback);
2011 } 2134 }
2012 2135
2013 virtual void mark(HeapObjectHeader* header, TraceCallback callback) override 2136 virtual void mark(HeapObjectHeader* header, TraceCallback callback) override
2014 { 2137 {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
2091 } 2214 }
2092 2215
2093 previouslyLive().swap(currentlyLive()); 2216 previouslyLive().swap(currentlyLive());
2094 currentlyLive().clear(); 2217 currentlyLive().clear();
2095 2218
2096 for (HashSet<uintptr_t>::iterator it = objectsToFindPath().begin(), end = objectsToFindPath().end(); it != end; ++it) { 2219 for (HashSet<uintptr_t>::iterator it = objectsToFindPath().begin(), end = objectsToFindPath().end(); it != end; ++it) {
2097 dumpPathToObjectFromObjectGraph(objectGraph(), *it); 2220 dumpPathToObjectFromObjectGraph(objectGraph(), *it);
2098 } 2221 }
2099 } 2222 }
2100 2223
2224 void reportMarkingStats()
2225 {
2226 MutexLocker locker(momMutex());
2227 RefPtr<TracedValue> json = TracedValue::create();
2228 for (ObjectAgeMap::iterator it = mom().begin(), end = mom().end(); it != end; ++it) {
2229 json->beginArray(it->key.ascii().data());
2230 for (size_t i = 0; i < 8; ++i) {
2231 json->pushInteger(it->value.data[i]);
2232 }
2233 json->endArray();
2234 }
2235 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID("blink_gc", "MarkingStats", (unsigne d long long)0, json.release());
2236 mom().clear();
2237 }
2238
2101 static void reportStillAlive(LiveObjectSet current, LiveObjectSet previous) 2239 static void reportStillAlive(LiveObjectSet current, LiveObjectSet previous)
2102 { 2240 {
2103 int count = 0; 2241 int count = 0;
2104 2242
2105 fprintf(stderr, " [previously %u]", previous.size()); 2243 fprintf(stderr, " [previously %u]", previous.size());
2106 for (LiveObjectSet::iterator it = current.begin(), end = current.end(); it != end; ++it) { 2244 for (LiveObjectSet::iterator it = current.begin(), end = current.end(); it != end; ++it) {
2107 if (previous.find(*it) == previous.end()) 2245 if (previous.find(*it) == previous.end())
2108 continue; 2246 continue;
2109 count++; 2247 count++;
2110 } 2248 }
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
2448 #endif 2586 #endif
2449 2587
2450 void Heap::prepareForGC() 2588 void Heap::prepareForGC()
2451 { 2589 {
2452 ASSERT(ThreadState::isAnyThreadInGC()); 2590 ASSERT(ThreadState::isAnyThreadInGC());
2453 ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads( ); 2591 ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads( );
2454 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it) 2592 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it)
2455 (*it)->prepareForGC(); 2593 (*it)->prepareForGC();
2456 } 2594 }
2457 2595
2596 void Heap::reportSweepingStats()
2597 {
2598 MutexLocker locker(uomMutex());
2599 RefPtr<TracedValue> json = TracedValue::create();
2600 for (ObjectAgeMap::iterator it = uom().begin(), end = uom().end(); it != end ; ++it) {
2601 json->beginArray(it->key.ascii().data());
2602 for (size_t i = 0; i < 8; ++i) {
2603 json->pushInteger(it->value.data[i]);
2604 }
2605 json->endArray();
2606 }
2607 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID("blink_gc", "SweepingStats", (unsigned l ong long)0, json.release());
2608 uom().clear();
2609 }
2610
2458 void Heap::collectGarbage(ThreadState::StackState stackState, ThreadState::Cause OfGC cause) 2611 void Heap::collectGarbage(ThreadState::StackState stackState, ThreadState::Cause OfGC cause)
2459 { 2612 {
2460 ThreadState* state = ThreadState::current(); 2613 ThreadState* state = ThreadState::current();
2461 state->clearGCRequested(); 2614 state->clearGCRequested();
2462 2615
2616 #if ENABLE(GC_PROFILE_FREE_LIST)
2617 state->snapshotFreeListIfNecessary();
2618 #endif
2619
2463 GCScope gcScope(stackState); 2620 GCScope gcScope(stackState);
2464 // Check if we successfully parked the other threads. If not we bail out of the GC. 2621 // Check if we successfully parked the other threads. If not we bail out of the GC.
2465 if (!gcScope.allThreadsParked()) { 2622 if (!gcScope.allThreadsParked()) {
2466 ThreadState::current()->setGCRequested(); 2623 ThreadState::current()->setGCRequested();
2467 return; 2624 return;
2468 } 2625 }
2469 2626
2470 if (state->isMainThread()) 2627 if (state->isMainThread())
2471 ScriptForbiddenScope::enter(); 2628 ScriptForbiddenScope::enter();
2472 2629
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2510 2667
2511 postMarkingProcessing(); 2668 postMarkingProcessing();
2512 globalWeakProcessing(); 2669 globalWeakProcessing();
2513 2670
2514 // Now we can delete all orphaned pages because there are no dangling 2671 // Now we can delete all orphaned pages because there are no dangling
2515 // pointers to the orphaned pages. (If we have such dangling pointers, 2672 // pointers to the orphaned pages. (If we have such dangling pointers,
2516 // we should have crashed during marking before getting here.) 2673 // we should have crashed during marking before getting here.)
2517 orphanedPagePool()->decommitOrphanedPages(); 2674 orphanedPagePool()->decommitOrphanedPages();
2518 2675
2519 #if ENABLE(GC_PROFILE_MARKING) 2676 #if ENABLE(GC_PROFILE_MARKING)
2520 static_cast<MarkingVisitor*>(s_markingVisitor)->reportStats(); 2677 //static_cast<MarkingVisitor*>(s_markingVisitor)->reportStats();
2678 static_cast<MarkingVisitor*>(s_markingVisitor)->reportMarkingStats();
2521 #endif 2679 #endif
2522 2680
2523 if (Platform::current()) { 2681 if (Platform::current()) {
2524 Platform::current()->histogramCustomCounts("BlinkGC.CollectGarbage", WTF ::currentTimeMS() - timeStamp, 0, 10 * 1000, 50); 2682 Platform::current()->histogramCustomCounts("BlinkGC.CollectGarbage", WTF ::currentTimeMS() - timeStamp, 0, 10 * 1000, 50);
2525 Platform::current()->histogramCustomCounts("BlinkGC.TotalObjectSpace", H eap::allocatedObjectSize() / 1024, 0, 4 * 1024 * 1024, 50); 2683 Platform::current()->histogramCustomCounts("BlinkGC.TotalObjectSpace", H eap::allocatedObjectSize() / 1024, 0, 4 * 1024 * 1024, 50);
2526 Platform::current()->histogramCustomCounts("BlinkGC.TotalAllocatedSpace" , Heap::allocatedSpace() / 1024, 0, 4 * 1024 * 1024, 50); 2684 Platform::current()->histogramCustomCounts("BlinkGC.TotalAllocatedSpace" , Heap::allocatedSpace() / 1024, 0, 4 * 1024 * 1024, 50);
2527 } 2685 }
2528 2686
2529 if (state->isMainThread()) 2687 if (state->isMainThread())
2530 ScriptForbiddenScope::exit(); 2688 ScriptForbiddenScope::exit();
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
2860 bool Heap::s_shutdownCalled = false; 3018 bool Heap::s_shutdownCalled = false;
2861 bool Heap::s_lastGCWasConservative = false; 3019 bool Heap::s_lastGCWasConservative = false;
2862 FreePagePool* Heap::s_freePagePool; 3020 FreePagePool* Heap::s_freePagePool;
2863 OrphanedPagePool* Heap::s_orphanedPagePool; 3021 OrphanedPagePool* Heap::s_orphanedPagePool;
2864 Heap::RegionTree* Heap::s_regionTree = 0; 3022 Heap::RegionTree* Heap::s_regionTree = 0;
2865 size_t Heap::s_allocatedObjectSize = 0; 3023 size_t Heap::s_allocatedObjectSize = 0;
2866 size_t Heap::s_allocatedSpace = 0; 3024 size_t Heap::s_allocatedSpace = 0;
2867 size_t Heap::s_markedObjectSize = 0; 3025 size_t Heap::s_markedObjectSize = 0;
2868 3026
2869 } // namespace blink 3027 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698