#include "config.h"
#include "core/inspector/InspectorHeapProfilerAgent.h"
-#include "bindings/v8/ScriptProfiler.h"
-#include "bindings/v8/ScriptScope.h"
+#include "bindings/core/v8/ScriptProfiler.h"
#include "core/inspector/InjectedScript.h"
#include "core/inspector/InjectedScriptHost.h"
#include "core/inspector/InspectorState.h"
#include "platform/Timer.h"
#include "wtf/CurrentTime.h"
-namespace WebCore {
+namespace blink {
typedef uint32_t SnapshotObjectId;
namespace HeapProfilerAgentState {
static const char heapProfilerEnabled[] = "heapProfilerEnabled";
+static const char heapObjectsTrackingEnabled[] = "heapObjectsTrackingEnabled";
+static const char allocationTrackingEnabled[] = "allocationTrackingEnabled";
}
-class InspectorHeapProfilerAgent::HeapStatsUpdateTask {
+class InspectorHeapProfilerAgent::HeapStatsUpdateTask FINAL : public NoBaseWillBeGarbageCollectedFinalized<InspectorHeapProfilerAgent::HeapStatsUpdateTask> {
public:
- HeapStatsUpdateTask(InspectorHeapProfilerAgent*);
+ explicit HeapStatsUpdateTask(InspectorHeapProfilerAgent*);
void startTimer();
void resetTimer() { m_timer.stop(); }
void onTimer(Timer<HeapStatsUpdateTask>*);
+ void trace(Visitor*);
private:
- InspectorHeapProfilerAgent* m_heapProfilerAgent;
+ RawPtrWillBeMember<InspectorHeapProfilerAgent> m_heapProfilerAgent;
Timer<HeapStatsUpdateTask> m_timer;
};
-PassOwnPtr<InspectorHeapProfilerAgent> InspectorHeapProfilerAgent::create(InjectedScriptManager* injectedScriptManager)
+PassOwnPtrWillBeRawPtr<InspectorHeapProfilerAgent> InspectorHeapProfilerAgent::create(InjectedScriptManager* injectedScriptManager)
{
- return adoptPtr(new InspectorHeapProfilerAgent(injectedScriptManager));
+ return adoptPtrWillBeNoop(new InspectorHeapProfilerAgent(injectedScriptManager));
}
InspectorHeapProfilerAgent::InspectorHeapProfilerAgent(InjectedScriptManager* injectedScriptManager)
{
}
-void InspectorHeapProfilerAgent::clearProfiles(ErrorString*)
-{
- m_snapshots.clear();
- m_nextUserInitiatedHeapSnapshotNumber = 1;
- stopTrackingHeapObjectsInternal();
- resetFrontendProfiles();
- m_injectedScriptManager->injectedScriptHost()->clearInspectedObjects();
-}
-
-void InspectorHeapProfilerAgent::resetFrontendProfiles()
-{
- if (!m_frontend)
- return;
- if (!m_state->getBoolean(HeapProfilerAgentState::heapProfilerEnabled))
- return;
- if (m_snapshots.isEmpty())
- m_frontend->resetProfiles();
-}
-
void InspectorHeapProfilerAgent::setFrontend(InspectorFrontend* frontend)
{
m_frontend = frontend->heapprofiler();
void InspectorHeapProfilerAgent::clearFrontend()
{
m_frontend = 0;
+
+ m_nextUserInitiatedHeapSnapshotNumber = 1;
+ stopTrackingHeapObjectsInternal();
+ m_injectedScriptManager->injectedScriptHost()->clearInspectedObjects();
+
ErrorString error;
- clearProfiles(&error);
disable(&error);
}
void InspectorHeapProfilerAgent::restore()
{
- resetFrontendProfiles();
+ if (m_state->getBoolean(HeapProfilerAgentState::heapProfilerEnabled))
+ m_frontend->resetProfiles();
+ if (m_state->getBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled))
+ startTrackingHeapObjectsInternal(m_state->getBoolean(HeapProfilerAgentState::allocationTrackingEnabled));
}
-void InspectorHeapProfilerAgent::collectGarbage(WebCore::ErrorString*)
+void InspectorHeapProfilerAgent::collectGarbage(blink::ErrorString*)
{
ScriptProfiler::collectGarbage();
}
-PassRefPtr<TypeBuilder::HeapProfiler::ProfileHeader> InspectorHeapProfilerAgent::createSnapshotHeader(const ScriptHeapSnapshot& snapshot)
-{
- RefPtr<TypeBuilder::HeapProfiler::ProfileHeader> header = TypeBuilder::HeapProfiler::ProfileHeader::create()
- .setUid(snapshot.uid())
- .setTitle(snapshot.title());
- return header.release();
-}
-
InspectorHeapProfilerAgent::HeapStatsUpdateTask::HeapStatsUpdateTask(InspectorHeapProfilerAgent* heapProfilerAgent)
: m_heapProfilerAgent(heapProfilerAgent)
, m_timer(this, &HeapStatsUpdateTask::onTimer)
void InspectorHeapProfilerAgent::HeapStatsUpdateTask::startTimer()
{
ASSERT(!m_timer.isActive());
- m_timer.startRepeating(0.05);
+ m_timer.startRepeating(0.05, FROM_HERE);
+}
+
+void InspectorHeapProfilerAgent::HeapStatsUpdateTask::trace(Visitor* visitor)
+{
+ visitor->trace(m_heapProfilerAgent);
}
class InspectorHeapProfilerAgent::HeapStatsStream FINAL : public ScriptProfiler::OutputStream {
InspectorHeapProfilerAgent* m_heapProfilerAgent;
};
-void InspectorHeapProfilerAgent::startTrackingHeapObjects(ErrorString*)
+void InspectorHeapProfilerAgent::startTrackingHeapObjects(ErrorString*, const bool* trackAllocations)
{
- if (m_heapStatsUpdateTask)
- return;
- ScriptProfiler::startTrackingHeapObjects();
- m_heapStatsUpdateTask = adoptPtr(new HeapStatsUpdateTask(this));
- m_heapStatsUpdateTask->startTimer();
+ m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, true);
+ bool allocationTrackingEnabled = asBool(trackAllocations);
+ m_state->setBoolean(HeapProfilerAgentState::allocationTrackingEnabled, allocationTrackingEnabled);
+ startTrackingHeapObjectsInternal(allocationTrackingEnabled);
}
void InspectorHeapProfilerAgent::requestHeapStatsUpdate()
stopTrackingHeapObjectsInternal();
}
+void InspectorHeapProfilerAgent::startTrackingHeapObjectsInternal(bool trackAllocations)
+{
+ if (m_heapStatsUpdateTask)
+ return;
+ ScriptProfiler::startTrackingHeapObjects(trackAllocations);
+ m_heapStatsUpdateTask = adoptPtrWillBeNoop(new HeapStatsUpdateTask(this));
+ m_heapStatsUpdateTask->startTimer();
+}
+
void InspectorHeapProfilerAgent::stopTrackingHeapObjectsInternal()
{
if (!m_heapStatsUpdateTask)
ScriptProfiler::stopTrackingHeapObjects();
m_heapStatsUpdateTask->resetTimer();
m_heapStatsUpdateTask.clear();
+ m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, false);
+ m_state->setBoolean(HeapProfilerAgentState::allocationTrackingEnabled, false);
}
void InspectorHeapProfilerAgent::enable(ErrorString*)
m_state->setBoolean(HeapProfilerAgentState::heapProfilerEnabled, false);
}
-void InspectorHeapProfilerAgent::getHeapSnapshot(ErrorString* errorString, int rawUid)
-{
- class OutputStream FINAL : public ScriptHeapSnapshot::OutputStream {
- public:
- OutputStream(InspectorFrontend::HeapProfiler* frontend, unsigned uid)
- : m_frontend(frontend), m_uid(uid) { }
- virtual void Write(const String& chunk) OVERRIDE { m_frontend->addHeapSnapshotChunk(m_uid, chunk); }
- virtual void Close() OVERRIDE { }
- private:
- InspectorFrontend::HeapProfiler* m_frontend;
- int m_uid;
- };
-
- unsigned uid = static_cast<unsigned>(rawUid);
- IdToHeapSnapshotMap::iterator it = m_snapshots.find(uid);
- if (it == m_snapshots.end()) {
- *errorString = "Profile wasn't found";
- return;
- }
- RefPtr<ScriptHeapSnapshot> snapshot = it->value;
- if (m_frontend) {
- OutputStream stream(m_frontend, uid);
- snapshot->writeJSON(&stream);
- }
-}
-
-void InspectorHeapProfilerAgent::removeProfile(ErrorString*, int rawUid)
-{
- unsigned uid = static_cast<unsigned>(rawUid);
- if (m_snapshots.contains(uid))
- m_snapshots.remove(uid);
-}
-
-void InspectorHeapProfilerAgent::takeHeapSnapshot(ErrorString*, const bool* reportProgress)
+void InspectorHeapProfilerAgent::takeHeapSnapshot(ErrorString* errorString, const bool* reportProgress)
{
class HeapSnapshotProgress FINAL : public ScriptProfiler::HeapSnapshotProgress {
public:
}
virtual void Worked(int workDone) OVERRIDE
{
- if (m_frontend)
- m_frontend->reportHeapSnapshotProgress(workDone, m_totalWork);
+ if (m_frontend) {
+ m_frontend->reportHeapSnapshotProgress(workDone, m_totalWork, 0);
+ m_frontend->flush();
+ }
+ }
+ virtual void Done() OVERRIDE
+ {
+ const bool finished = true;
+ if (m_frontend) {
+ m_frontend->reportHeapSnapshotProgress(m_totalWork, m_totalWork, &finished);
+ m_frontend->flush();
+ }
}
- virtual void Done() OVERRIDE { }
virtual bool isCanceled() OVERRIDE { return false; }
private:
InspectorFrontend::HeapProfiler* m_frontend;
};
String title = "Snapshot " + String::number(m_nextUserInitiatedHeapSnapshotNumber++);
- HeapSnapshotProgress progress(reportProgress && *reportProgress ? m_frontend : 0);
+ HeapSnapshotProgress progress(asBool(reportProgress) ? m_frontend : 0);
RefPtr<ScriptHeapSnapshot> snapshot = ScriptProfiler::takeHeapSnapshot(title, &progress);
- if (snapshot) {
- m_snapshots.add(snapshot->uid(), snapshot);
- if (m_frontend)
- m_frontend->addProfileHeader(createSnapshotHeader(*snapshot));
+ if (!snapshot) {
+ *errorString = "Failed to take heap snapshot";
+ return;
+ }
+
+ class OutputStream : public ScriptHeapSnapshot::OutputStream {
+ public:
+ explicit OutputStream(InspectorFrontend::HeapProfiler* frontend)
+ : m_frontend(frontend) { }
+ void Write(const String& chunk)
+ {
+ m_frontend->addHeapSnapshotChunk(chunk);
+ m_frontend->flush();
+ }
+ void Close() { }
+ private:
+ InspectorFrontend::HeapProfiler* m_frontend;
+ };
+
+ if (m_frontend) {
+ OutputStream stream(m_frontend);
+ snapshot->writeJSON(&stream);
}
}
*error = "Invalid heap snapshot object id";
return;
}
- ScriptObject heapObject = ScriptProfiler::objectByHeapObjectId(id);
- if (heapObject.hasNoValue()) {
+ ScriptValue heapObject = ScriptProfiler::objectByHeapObjectId(id);
+ if (heapObject.isEmpty()) {
*error = "Object is not available";
return;
}
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(heapObject.scriptState());
- if (injectedScript.hasNoValue()) {
+ if (injectedScript.isEmpty()) {
*error = "Object is not available. Inspected context is gone";
return;
}
void InspectorHeapProfilerAgent::getHeapObjectId(ErrorString* errorString, const String& objectId, String* heapSnapshotObjectId)
{
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
- if (injectedScript.hasNoValue()) {
+ if (injectedScript.isEmpty()) {
*errorString = "Inspected context has gone";
return;
}
ScriptValue value = injectedScript.findObjectById(objectId);
- ScriptScope scope(injectedScript.scriptState());
- if (value.hasNoValue() || value.isUndefined()) {
+ ScriptState::Scope scope(injectedScript.scriptState());
+ if (value.isEmpty() || value.isUndefined()) {
*errorString = "Object with given id not found";
return;
}
*heapSnapshotObjectId = String::number(id);
}
-} // namespace WebCore
+void InspectorHeapProfilerAgent::trace(Visitor* visitor)
+{
+ visitor->trace(m_injectedScriptManager);
+ visitor->trace(m_heapStatsUpdateTask);
+ InspectorBaseAgent::trace(visitor);
+}
+
+} // namespace blink