Chromium Code Reviews| Index: Source/platform/heap/ThreadState.cpp |
| diff --git a/Source/platform/heap/ThreadState.cpp b/Source/platform/heap/ThreadState.cpp |
| index 581aee1e7d67f5ce58f9d21cf8f695c6468224eb..946aab0604a62ce254b4556647aba83f10a70e06 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> |
| @@ -567,7 +570,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); |
| @@ -578,6 +581,67 @@ 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); |
| + TracedValue json; |
| + |
| +#define SNAPSHOT_HEAP(HeapType) \ |
| + { \ |
| + TracedDictionary<TracedArray<TracedValue> >& jsonHeap = heaps.beginDictionary(); \ |
| + jsonHeap.setString("name", #HeapType); \ |
| + m_heaps[HeapType##Heap]->snapshot(&jsonHeap, &info); \ |
| + jsonHeap.endDictionary(); \ |
| + } |
| + TracedArray<TracedValue>& heaps = json.beginArray("heaps"); |
| + SNAPSHOT_HEAP(General); |
| + FOR_EACH_TYPED_HEAP(SNAPSHOT_HEAP); |
| + heaps.endArray(); |
| +#undef SNAPSHOT_HEAP |
| + |
| + json.setInteger("allocatedSpace", m_stats.totalAllocatedSpace()) |
| + .setInteger("objectSpace", m_stats.totalObjectSpace()) |
| + .setInteger("liveSize", info.liveSize) |
| + .setInteger("deadSize", info.deadSize) |
| + .setInteger("freeSize", info.freeSize) |
| + .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; |
| + |
| + TracedArray<TracedValue>& jsonClasses = json.beginArray("classes"); |
| + for (size_t i = 0; i < classNameVector.size(); ++i) { |
| + TracedDictionary<TracedArray<TracedValue> >& jsonClass = jsonClasses.beginDictionary(); |
| + jsonClass |
| + .setString("name", classNameVector[i]) |
| + .setInteger("liveCount", info.liveCount[i]) |
| + .setInteger("deadCount", info.deadCount[i]); |
| + TracedArray<TracedDictionary<TracedArray<TracedValue> > >& jsonGens = jsonClass.beginArray("generations"); |
| + for (size_t j = 0; j < heapObjectGenerations; ++j) |
| + jsonGens.pushInteger(info.generations[i][j]); |
| + jsonGens.endArray(); |
| + jsonClass.endDictionary(); |
| + } |
| + jsonClasses.endArray(); |
| + |
| + TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID("blinkGC", "ThreadState", this, json.finish()); |
| +} |
| +#endif |
| + |
| void ThreadState::pushWeakObjectPointerCallback(void* object, WeakPointerCallback callback) |
| { |
| CallbackStack::Item* slot = m_weakCallbackStack->allocateEntry(&m_weakCallbackStack); |
| @@ -882,13 +946,23 @@ 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("blinkGC", &gcTracingEnabled); |
|
tkent
2014/08/05 00:38:10
Ditto.
|
| + if (gcTracingEnabled && m_stats.totalObjectSpace() > 0) |
| + snapshot(); |
| +#endif |
| + |
| + TRACE_EVENT0("blinkGC", "ThreadState::performPendingSweep"); |
| ScriptForbiddenScope forbiddenScope; |
| double timeStamp = WTF::currentTimeMS(); |
| const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE(); |
| if (isMainThread()) |
| - TRACE_EVENT_SET_SAMPLING_STATE("blink", "BlinkGCSweeping"); |
| + TRACE_EVENT_SET_SAMPLING_STATE("blinkGC", "BlinkGCSweeping"); |
| m_sweepInProgress = true; |
| // Disallow allocation during weak processing. |
| @@ -949,7 +1023,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(); |
| @@ -969,4 +1043,5 @@ const GCInfo* ThreadState::findGCInfoFromAllThreads(Address address) |
| return 0; |
| } |
| #endif |
| + |
| } |