| Index: Source/platform/heap/ThreadState.cpp
|
| diff --git a/Source/platform/heap/ThreadState.cpp b/Source/platform/heap/ThreadState.cpp
|
| index 1d63ae03a8e385f9488fde3945a09f569e285277..8d48c23acdc8d33f2ad7d57b84f64e0d4312eec3 100644
|
| --- a/Source/platform/heap/ThreadState.cpp
|
| +++ b/Source/platform/heap/ThreadState.cpp
|
| @@ -38,6 +38,9 @@
|
| #include "platform/heap/Heap.h"
|
| #include "public/platform/Platform.h"
|
| #include "wtf/ThreadingPrimitives.h"
|
| +#if ENABLE(GC_PROFILE_HEAP)
|
| +#include "platform/TracedValue.h"
|
| +#endif
|
|
|
| #if OS(WIN)
|
| #include <stddef.h>
|
| @@ -568,7 +571,7 @@ bool ThreadState::checkAndMarkPointer(Visitor* visitor, Address address)
|
| return false;
|
| }
|
|
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILE_MARKING)
|
| const GCInfo* ThreadState::findGCInfo(Address address)
|
| {
|
| BaseHeapPage* page = heapPageFromAddress(address);
|
| @@ -579,6 +582,66 @@ const GCInfo* ThreadState::findGCInfo(Address address)
|
| }
|
| #endif
|
|
|
| +#if ENABLE(GC_PROFILE_HEAP)
|
| +size_t ThreadState::SnapshotInfo::getClassTag(const GCInfo* gcinfo)
|
| +{
|
| + HashMap<const GCInfo*, size_t>::AddResult result = classTags.add(gcinfo, classTags.size());
|
| + if (result.isNewEntry) {
|
| + liveCount.append(0);
|
| + deadCount.append(0);
|
| + generations.append(Vector<int, 8>());
|
| + generations.last().fill(0, 8);
|
| + }
|
| + return result.storedValue->value;
|
| +}
|
| +
|
| +void ThreadState::snapshot()
|
| +{
|
| + SnapshotInfo info(this);
|
| + RefPtr<TracedValue> json = TracedValue::create();
|
| +
|
| +#define SNAPSHOT_HEAP(HeapType) \
|
| + { \
|
| + json->beginDictionary(); \
|
| + json->setString("name", #HeapType); \
|
| + m_heaps[HeapType##Heap]->snapshot(json.get(), &info); \
|
| + json->endDictionary(); \
|
| + }
|
| + json->beginArray("heaps");
|
| + SNAPSHOT_HEAP(General);
|
| + FOR_EACH_TYPED_HEAP(SNAPSHOT_HEAP);
|
| + json->endArray();
|
| +#undef SNAPSHOT_HEAP
|
| +
|
| + json->setInteger("allocatedSpace", m_stats.totalAllocatedSpace());
|
| + json->setInteger("objectSpace", m_stats.totalObjectSpace());
|
| + json->setInteger("liveSize", info.liveSize);
|
| + json->setInteger("deadSize", info.deadSize);
|
| + json->setInteger("freeSize", info.freeSize);
|
| + json->setInteger("pageCount", info.freeSize);
|
| +
|
| + Vector<String> classNameVector(info.classTags.size());
|
| + for (HashMap<const GCInfo*, size_t>::iterator it = info.classTags.begin(); it != info.classTags.end(); ++it)
|
| + classNameVector[it->value] = it->key->m_className;
|
| +
|
| + json->beginArray("classes");
|
| + for (size_t i = 0; i < classNameVector.size(); ++i) {
|
| + json->beginDictionary();
|
| + json->setString("name", classNameVector[i]);
|
| + json->setInteger("liveCount", info.liveCount[i]);
|
| + json->setInteger("deadCount", info.deadCount[i]);
|
| + json->beginArray("generations");
|
| + for (size_t j = 0; j < heapObjectGenerations; ++j)
|
| + json->pushInteger(info.generations[i][j]);
|
| + json->endArray();
|
| + json->endDictionary();
|
| + }
|
| + json->endArray();
|
| +
|
| + TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID("blink_gc", "ThreadState", this, json);
|
| +}
|
| +#endif
|
| +
|
| void ThreadState::pushWeakObjectPointerCallback(void* object, WeakPointerCallback callback)
|
| {
|
| CallbackStack::Item* slot = m_weakCallbackStack->allocateEntry(&m_weakCallbackStack);
|
| @@ -886,7 +949,17 @@ void ThreadState::performPendingSweep()
|
| if (!sweepRequested())
|
| return;
|
|
|
| - TRACE_EVENT0("blink", "ThreadState::performPendingSweep");
|
| +#if ENABLE(GC_PROFILE_HEAP)
|
| + // We snapshot the heap prior to sweeping to get numbers for both resources
|
| + // that have been allocated since the last GC and for resources that are
|
| + // going to be freed.
|
| + bool gcTracingEnabled;
|
| + TRACE_EVENT_CATEGORY_GROUP_ENABLED("blink_gc", &gcTracingEnabled);
|
| + if (gcTracingEnabled && m_stats.totalObjectSpace() > 0)
|
| + snapshot();
|
| +#endif
|
| +
|
| + TRACE_EVENT0("blink_gc", "ThreadState::performPendingSweep");
|
|
|
| double timeStamp = WTF::currentTimeMS();
|
| const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE();
|
| @@ -961,7 +1034,7 @@ ThreadState::AttachedThreadStateSet& ThreadState::attachedThreads()
|
| return threads;
|
| }
|
|
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILE_MARKING)
|
| const GCInfo* ThreadState::findGCInfoFromAllThreads(Address address)
|
| {
|
| bool needLockForIteration = !isAnyThreadInGC();
|
| @@ -981,4 +1054,5 @@ const GCInfo* ThreadState::findGCInfoFromAllThreads(Address address)
|
| return 0;
|
| }
|
| #endif
|
| +
|
| }
|
|
|