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

Unified Diff: Source/platform/heap/Heap.cpp

Issue 383743002: Oilpan: GC profiling. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: TracedValue contexts Created 6 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: Source/platform/heap/Heap.cpp
diff --git a/Source/platform/heap/Heap.cpp b/Source/platform/heap/Heap.cpp
index 3f1948e6cdd9fa8424962f288b751c04f063cfbe..6545b5f0914f6a6776a47860fd8c3698d21da050 100644
--- a/Source/platform/heap/Heap.cpp
+++ b/Source/platform/heap/Heap.cpp
@@ -39,7 +39,7 @@
#include "wtf/Assertions.h"
#include "wtf/LeakAnnotations.h"
#include "wtf/PassOwnPtr.h"
-#if ENABLE(GC_TRACING)
+#if GC_PROFILE_MARKING
#include "wtf/HashMap.h"
#include "wtf/HashSet.h"
#include "wtf/text/StringBuilder.h"
@@ -47,6 +47,9 @@
#include <stdio.h>
#include <utility>
#endif
+#if GC_PROFILE_HEAP
+#include "platform/TracedValue.h"
+#endif
#if OS(POSIX)
#include <sys/mman.h>
@@ -57,7 +60,7 @@
namespace WebCore {
-#if ENABLE(GC_TRACING)
+#if GC_PROFILE_MARKING
static String classOf(const void* object)
{
const GCInfo* gcInfo = Heap::findGCInfo(reinterpret_cast<Address>(const_cast<void*>(object)));
@@ -369,10 +372,10 @@ public:
, m_safePointScope(stackState)
, m_parkedAllThreads(false)
{
- TRACE_EVENT0("blink", "Heap::GCScope");
+ TRACE_EVENT0(GC_PROFILE_GROUP, "Heap::GCScope");
const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE();
if (m_state->isMainThread())
- TRACE_EVENT_SET_SAMPLING_STATE("blink", "BlinkGCWaiting");
+ TRACE_EVENT_SET_SAMPLING_STATE(GC_PROFILE_GROUP, "BlinkGCWaiting");
m_state->checkThread();
@@ -505,7 +508,7 @@ void LargeHeapObject<Header>::checkAndMarkPointer(Visitor* visitor, Address addr
ASSERT(contains(address));
if (!objectContains(address))
return;
-#if ENABLE(GC_TRACING)
+#if GC_PROFILE_MARKING
visitor->setHostInfo(&address, "stack");
#endif
mark(visitor);
@@ -641,7 +644,7 @@ BaseHeapPage* ThreadHeap<Header>::heapPageFromAddress(Address address)
return 0;
}
-#if ENABLE(GC_TRACING)
+#if GC_PROFILE_MARKING
template<typename Header>
const GCInfo* ThreadHeap<Header>::findGCInfoOfLargeHeapObject(Address address)
{
@@ -653,6 +656,43 @@ const GCInfo* ThreadHeap<Header>::findGCInfoOfLargeHeapObject(Address address)
}
#endif
+#if GC_PROFILE_HEAP
+template<typename Header>
+void ThreadHeap<Header>::snapshot(TracedDictionaryBase* json, ThreadState::SnapshotInfo* info)
+{
+ size_t previousPageCount = info->pageCount;
+
+ TracedArray<TracedDictionaryBase>& pages = json->beginArray("pages");
+ for (HeapPage<Header>* page = m_firstPage; page; page = page->next(), ++info->pageCount) {
+ // FIXME: To limit the size of the snapshot we only output "threshold" many page snapshots.
+ TracedArray<TracedArray<TracedDictionaryBase> >* jsonPage = 0;
+ if (info->pageCount < GC_PROFILE_HEAP_PAGE_DUMP_THRESHOLD) {
+ jsonPage = &pages.beginArray();
+ jsonPage->pushInteger(reinterpret_cast<intptr_t>(page));
+ }
+ page->snapshot(jsonPage, info);
+ if (jsonPage)
+ jsonPage->endArray();
+ }
+ pages.endArray();
+
+ TracedArray<TracedDictionaryBase>& largeObjects = json->beginArray("largeObjects");
+ for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; current = current->next()) {
+ TracedDictionary<TracedArray<TracedDictionaryBase> >& jsonCurrent = largeObjects.beginDictionary();
+ current->snapshot(&jsonCurrent, info);
+ jsonCurrent.endDictionary();
+ }
+ largeObjects.endArray();
+
+ size_t pagePoolSize = 0;
+ for (PagePoolEntry* page = m_pagePool; page; page = page->next())
+ ++pagePoolSize;
+
+ json->setInteger("pagePoolSize", pagePoolSize)
+ .setInteger("pageCount", info->pageCount - previousPageCount);
+}
+#endif
+
template<typename Header>
void ThreadHeap<Header>::addToFreeList(Address address, size_t size)
{
@@ -1201,7 +1241,7 @@ void HeapPage<Header>::checkAndMarkPointer(Visitor* visitor, Address address)
if (!header)
return;
-#if ENABLE(GC_TRACING)
+#if GC_PROFILE_MARKING
visitor->setHostInfo(&address, "stack");
#endif
if (hasVTable(header) && !vTableInitialized(header->payload()))
@@ -1210,7 +1250,7 @@ void HeapPage<Header>::checkAndMarkPointer(Visitor* visitor, Address address)
visitor->mark(header, traceCallback(header));
}
-#if ENABLE(GC_TRACING)
+#if GC_PROFILE_MARKING
template<typename Header>
const GCInfo* HeapPage<Header>::findGCInfo(Address address)
{
@@ -1228,6 +1268,42 @@ const GCInfo* HeapPage<Header>::findGCInfo(Address address)
}
#endif
+#if GC_PROFILE_HEAP
+template<typename Header>
+void HeapPage<Header>::snapshot(TracedArrayBase* json, ThreadState::SnapshotInfo* info)
+{
+ Header* header = 0;
+ for (Address addr = payload(); addr < end(); addr += header->size()) {
+ header = reinterpret_cast<Header*>(addr);
+ if (json)
+ json->pushInteger(header->encodedSize());
+ if (header->isFree()) {
+ info->freeSize += header->size();
+ continue;
+ }
+
+ size_t tag = info->getClassTag(header->gcInfo());
+ size_t age = header->age();
+ if (json)
+ json->pushInteger(tag);
+ if (header->isMarked()) {
+ info->liveCount[tag] += 1;
+ info->liveSize += header->size();
+ // Count objects that are live when promoted to the final generation.
+ if (age == maxHeapObjectAge - 1)
+ info->generations[tag][maxHeapObjectAge] += 1;
+ header->incAge();
haraken 2014/07/14 02:26:14 Do we want to increase the age when age == maxHeap
zerny-chromium 2014/07/28 11:54:41 No, the increment check against maxHeapObjectAge i
zerny-chromium 2014/07/28 11:57:59 (Too quick there) We do want to increment when it
+ } else {
+ info->deadCount[tag] += 1;
+ info->deadSize += header->size();
+ // Count objects that are dead before the final generation.
+ if (age < maxHeapObjectAge)
+ info->generations[tag][age] += 1;
+ }
+ }
+}
+#endif
+
#if defined(ADDRESS_SANITIZER)
template<typename Header>
void HeapPage<Header>::poisonUnmarkedObjects()
@@ -1289,6 +1365,37 @@ void LargeHeapObject<Header>::getStats(HeapStats& stats)
stats.increaseObjectSpace(payloadSize());
}
+#if GC_PROFILE_HEAP
+template<typename Header>
+void LargeHeapObject<Header>::snapshot(TracedDictionaryBase* json, ThreadState::SnapshotInfo* info)
+{
+ Header* header = heapObjectHeader();
+ size_t tag = info->getClassTag(header->gcInfo());
+ size_t age = header->age();
+ if (isMarked()) {
+ info->liveCount[tag] += 1;
+ info->liveSize += header->size();
+ // Count objects that are live when promoted to the final generation.
+ if (age == maxHeapObjectAge - 1)
+ info->generations[tag][maxHeapObjectAge] += 1;
+ header->incAge();
haraken 2014/07/14 02:26:14 Do we want to increase the age when age == maxHeap
zerny-chromium 2014/07/28 11:54:41 Ditto.
+ } else {
+ info->deadCount[tag] += 1;
+ info->deadSize += header->size();
+ // Count objects that are live when promoted to the final generation.
+ if (age == maxHeapObjectAge - 1)
+ info->generations[tag][maxHeapObjectAge] += 1;
+ header->incAge();
haraken 2014/07/14 02:26:14 Factor out the line 1378 - 1381 and the line 1385
zerny-chromium 2014/07/28 11:54:41 This is a copy-paste error. The dead-branch should
+ }
+
+ if (json) {
+ json->setInteger("class", tag)
+ .setInteger("size", header->size())
+ .setInteger("isMarked", isMarked());
+ }
+}
+#endif
+
template<typename Entry>
void HeapExtentCache<Entry>::flush()
{
@@ -1403,7 +1510,7 @@ bool CallbackStack::popAndInvokeCallback(CallbackStack** first, Visitor* visitor
Item* item = --m_current;
VisitorCallback callback = item->callback();
-#if ENABLE(GC_TRACING)
+#if GC_PROFILE_MARKING
if (ThreadState::isAnyThreadInGC()) // weak-processing will also use popAndInvokeCallback
visitor->setHostInfo(item->object(), classOf(item->object()));
#endif
@@ -1461,7 +1568,7 @@ bool CallbackStack::hasCallbackForObject(const void* object)
class MarkingVisitor : public Visitor {
public:
-#if ENABLE(GC_TRACING)
+#if GC_PROFILE_MARKING
typedef HashSet<uintptr_t> LiveObjectSet;
typedef HashMap<String, LiveObjectSet> LiveObjectMap;
typedef HashMap<uintptr_t, std::pair<uintptr_t, String> > ObjectGraph;
@@ -1474,7 +1581,7 @@ public:
if (header->isMarked())
return;
header->mark();
-#if ENABLE(GC_TRACING)
+#if GC_PROFILE_MARKING
MutexLocker locker(objectGraphMutex());
String className(classOf(objectPointer));
{
@@ -1580,7 +1687,7 @@ public:
FOR_EACH_TYPED_HEAP(DEFINE_VISITOR_METHODS)
#undef DEFINE_VISITOR_METHODS
-#if ENABLE(GC_TRACING)
+#if GC_PROFILE_MARKING
void reportStats()
{
fprintf(stderr, "\n---------- AFTER MARKING -------------------\n");
@@ -1758,12 +1865,14 @@ Address Heap::checkAndMarkPointer(Visitor* visitor, Address address)
return 0;
}
-#if ENABLE(GC_TRACING)
+#if GC_PROFILE_MARKING
const GCInfo* Heap::findGCInfo(Address address)
{
return ThreadState::findGCInfoFromAllThreads(address);
}
+#endif
+#if GC_PROFILE_MARKING
void Heap::dumpPathToObjectOnNextGC(void* p)
{
static_cast<MarkingVisitor*>(s_markingVisitor)->dumpPathToObjectOnNextGC(p);
@@ -1880,10 +1989,10 @@ void Heap::collectGarbage(ThreadState::StackState stackState)
ScriptForbiddenScope forbiddenScope;
s_lastGCWasConservative = false;
- TRACE_EVENT0("blink", "Heap::collectGarbage");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "BlinkGC");
+ TRACE_EVENT0(GC_PROFILE_GROUP, "Heap::collectGarbage");
+ TRACE_EVENT_SCOPED_SAMPLING_STATE(GC_PROFILE_GROUP, "BlinkGC");
double timeStamp = WTF::currentTimeMS();
-#if ENABLE(GC_TRACING)
+#if GC_PROFILE_MARKING
static_cast<MarkingVisitor*>(s_markingVisitor)->objectGraph().clear();
#endif
@@ -1920,7 +2029,7 @@ void Heap::collectGarbage(ThreadState::StackState stackState)
// callback phase, so the marking stack should still be empty here.
ASSERT(s_markingStack->isEmpty());
-#if ENABLE(GC_TRACING)
+#if GC_PROFILE_MARKING
static_cast<MarkingVisitor*>(s_markingVisitor)->reportStats();
#endif

Powered by Google App Engine
This is Rietveld 408576698