Skip to content
This repository was archived by the owner on Apr 3, 2020. It is now read-only.

Commit d79eb73

Browse files
amalysheRaphael Kubo da Costa
authored and
Raphael Kubo da Costa
committed
The Chrome DevTools protocol part of the XDK
in-depth allocation tracker There are three new commands are added by analogy with Chrome DevTools allocation tracker. Start/Stop and Event which is sent by timer. Command stopTrackingHeapXDK accepts three parameters: stack depth for unwinding, Sample After Value - period of timer and a flag to collect retention information or not. Event sends to the host currently collected data about symbols/callstack/objects. Command stopTrackingHeapXDK returns the final info witch is similar to Event passed format with one more parameter: duration of the collection. Basing on this info consumer can build allocation call tree for any period of time, annotate source by self and total allocation mertics and annotate allocation call tree by the objects, which retain other objects in the memory
1 parent 4d0ea51 commit d79eb73

7 files changed

+294
-1
lines changed

Source/bindings/core/v8/ScriptProfiler.cpp

+54
Original file line numberDiff line numberDiff line change
@@ -316,4 +316,58 @@ void ScriptProfiler::setIdle(bool isIdle)
316316
profiler->SetIdle(isIdle);
317317
}
318318

319+
namespace {
320+
321+
class HeapXDKStream : public v8::OutputStream {
322+
public:
323+
HeapXDKStream(ScriptProfiler::OutputStream* stream) : m_stream(stream) { }
324+
virtual void EndOfStream() override { }
325+
326+
virtual WriteResult WriteAsciiChunk(char* data, int size) override
327+
{
328+
ASSERT(false);
329+
return kAbort;
330+
}
331+
332+
virtual WriteResult WriteHeapXDKChunk(const char* symbols, int symbolsSize,
333+
const char* frames, int framesSize,
334+
const char* types, int typesSize,
335+
const char* chunks, int chunksSize,
336+
const char* retentions,
337+
int retentionSize) override
338+
{
339+
m_stream->write(symbols, symbolsSize, frames, framesSize,
340+
types, typesSize, chunks, chunksSize,
341+
retentions, retentionSize);
342+
return kContinue;
343+
}
344+
345+
private:
346+
ScriptProfiler::OutputStream* m_stream;
347+
};
348+
349+
}
350+
351+
void ScriptProfiler::requestHeapXDKUpdate(ScriptProfiler::OutputStream* stream)
352+
{
353+
HeapXDKStream heapXDKStream(stream);
354+
v8::Isolate::GetCurrent()->GetHeapProfiler()->GetHeapXDKStats(
355+
&heapXDKStream);
356+
}
357+
358+
void ScriptProfiler::startTrackingHeapObjectsXDK(int stackDepth,
359+
bool retentions)
360+
{
361+
v8::Isolate::GetCurrent()->GetHeapProfiler()->StartTrackingHeapObjectsXDK(
362+
stackDepth, retentions);
363+
}
364+
365+
PassRefPtr<HeapProfileXDK> ScriptProfiler::stopTrackingHeapObjectsXDK()
366+
{
367+
return HeapProfileXDK::create(
368+
v8::Isolate::GetCurrent()
369+
->GetHeapProfiler()->StopTrackingHeapObjectsXDK());
370+
}
371+
372+
319373
} // namespace blink

Source/bindings/core/v8/ScriptProfiler.h

+8
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ class ScriptProfiler {
5757
public:
5858
virtual ~OutputStream() { }
5959
virtual void write(const uint32_t* chunk, const int size) = 0;
60+
virtual void write(const char* symbols, int symbolsSize,
61+
const char* frames, int framesSize,
62+
const char* types, int typesSize,
63+
const char* chunks, int chunksSize,
64+
const char* retentions, int retentionsSize) { };
6065
};
6166

6267
static void collectGarbage();
@@ -70,6 +75,9 @@ class ScriptProfiler {
7075
static void startTrackingHeapObjects(bool trackAllocations);
7176
static void stopTrackingHeapObjects();
7277
static unsigned requestHeapStatsUpdate(OutputStream*);
78+
static void startTrackingHeapObjectsXDK(int stackDepth, bool retentions);
79+
static PassRefPtr<HeapProfileXDK> stopTrackingHeapObjectsXDK();
80+
static void requestHeapXDKUpdate(OutputStream*);
7381
static void initialize();
7482
static void visitNodeWrappers(WrappedNodeVisitor*);
7583
static HashMap<String, double>* currentProfileNameIdleTimeMap();

Source/core/inspector/InspectorHeapProfilerAgent.cpp

+127
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@ class InspectorHeapProfilerAgent::HeapStatsUpdateTask final : public NoBaseWillB
6161
Timer<HeapStatsUpdateTask> m_timer;
6262
};
6363

64+
65+
class InspectorHeapProfilerAgent::HeapXDKUpdateTask final : public NoBaseWillBeGarbageCollectedFinalized<InspectorHeapProfilerAgent::HeapXDKUpdateTask> {
66+
public:
67+
HeapXDKUpdateTask(InspectorHeapProfilerAgent*);
68+
void startTimer(float sav);
69+
void resetTimer() { m_timer.stop(); }
70+
void onTimer(Timer<HeapXDKUpdateTask>*);
71+
72+
private:
73+
InspectorHeapProfilerAgent* m_heapProfilerAgent;
74+
Timer<HeapXDKUpdateTask> m_timer;
75+
};
76+
77+
6478
PassOwnPtrWillBeRawPtr<InspectorHeapProfilerAgent> InspectorHeapProfilerAgent::create(InjectedScriptManager* injectedScriptManager)
6579
{
6680
return adoptPtrWillBeNoop(new InspectorHeapProfilerAgent(injectedScriptManager));
@@ -326,5 +340,118 @@ void InspectorHeapProfilerAgent::trace(Visitor* visitor)
326340
InspectorBaseAgent::trace(visitor);
327341
}
328342

343+
static PassRefPtr<TypeBuilder::HeapProfiler::HeapEventXDK> createHeapProfileXDK(const HeapProfileXDK& heapProfileXDK)
344+
{
345+
RefPtr<TypeBuilder::HeapProfiler::HeapEventXDK> profile = TypeBuilder::HeapProfiler::HeapEventXDK::create()
346+
.setDuration(heapProfileXDK.getDuration())
347+
.setSymbols(heapProfileXDK.getSymbols())
348+
.setFrames(heapProfileXDK.getFrames())
349+
.setTypes(heapProfileXDK.getTypes())
350+
.setChunks(heapProfileXDK.getChunks())
351+
.setRetentions(heapProfileXDK.getRetentions());
352+
return profile.release();
353+
}
354+
355+
InspectorHeapProfilerAgent::HeapXDKUpdateTask::HeapXDKUpdateTask(InspectorHeapProfilerAgent* heapProfilerAgent)
356+
: m_heapProfilerAgent(heapProfilerAgent)
357+
, m_timer(this, &HeapXDKUpdateTask::onTimer)
358+
{
359+
}
360+
361+
void InspectorHeapProfilerAgent::HeapXDKUpdateTask::onTimer(Timer<HeapXDKUpdateTask>*)
362+
{
363+
// The timer is stopped on m_heapProfilerAgent destruction,
364+
// so this method will never be called after m_heapProfilerAgent has been destroyed.
365+
m_heapProfilerAgent->requestHeapXDKUpdate();
366+
}
367+
368+
void InspectorHeapProfilerAgent::HeapXDKUpdateTask::startTimer(float sav)
369+
{
370+
ASSERT(!m_timer.isActive());
371+
m_timer.startRepeating(sav, FROM_HERE);
372+
}
373+
374+
void InspectorHeapProfilerAgent::startTrackingHeapXDK(ErrorString*,
375+
const int* stack_depth,
376+
const int* sav,
377+
const bool* retentions)
378+
{
379+
m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, true);
380+
381+
// inline of startTrackingHeapObjectsInternal(allocationTrackingEnabled);
382+
if (m_heapXDKUpdateTask)
383+
return;
384+
int stackDepth = 8;
385+
if (stack_depth) {
386+
stackDepth = *stack_depth;
387+
}
388+
float sav_timer = 1;
389+
if (sav) {
390+
sav_timer = (float)*sav / 1000.;
391+
}
392+
bool needRetentions = retentions && *retentions;
393+
ScriptProfiler::startTrackingHeapObjectsXDK(stackDepth, needRetentions );
394+
m_heapXDKUpdateTask = adoptPtr(new HeapXDKUpdateTask(this));
395+
m_heapXDKUpdateTask->startTimer(sav_timer);
396+
}
397+
398+
class InspectorHeapProfilerAgent::HeapXDKStream final : public ScriptProfiler::OutputStream {
399+
public:
400+
HeapXDKStream(InspectorHeapProfilerAgent* heapProfilerAgent)
401+
: m_heapProfilerAgent(heapProfilerAgent)
402+
{
403+
}
404+
405+
virtual void write(const uint32_t* chunk, const int size){}
406+
virtual void write(const char* symbols, int symbolsSize,
407+
const char* frames, int framesSize,
408+
const char* types, int typesSize,
409+
const char* chunks, int chunksSize,
410+
const char* retentions, int retentionsSize) override
411+
{
412+
m_heapProfilerAgent->pushHeapXDKUpdate(symbols, symbolsSize, frames, framesSize,
413+
types, typesSize, chunks, chunksSize,
414+
retentions, retentionsSize);
415+
}
416+
private:
417+
InspectorHeapProfilerAgent* m_heapProfilerAgent;
418+
};
419+
420+
void InspectorHeapProfilerAgent::requestHeapXDKUpdate()
421+
{
422+
if (!m_frontend)
423+
return;
424+
HeapXDKStream stream(this);
425+
ScriptProfiler::requestHeapXDKUpdate(&stream);
426+
}
427+
428+
void InspectorHeapProfilerAgent::stopTrackingHeapXDK(ErrorString* error, RefPtr<TypeBuilder::HeapProfiler::HeapEventXDK>& profile)
429+
{
430+
if (!m_heapXDKUpdateTask) {
431+
*error = "Heap object tracking is not started.";
432+
return;
433+
}
434+
435+
RefPtr<HeapProfileXDK> heapProfileXDK = ScriptProfiler::stopTrackingHeapObjectsXDK();
436+
profile = createHeapProfileXDK(*heapProfileXDK);
437+
438+
m_heapXDKUpdateTask->resetTimer();
439+
m_heapXDKUpdateTask.clear();
440+
m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, false);
441+
442+
}
443+
void InspectorHeapProfilerAgent::pushHeapXDKUpdate( const char* symbols, int symbolsSize,
444+
const char* frames, int framesSize,
445+
const char* types, int typesSize,
446+
const char* chunks, int chunksSize,
447+
const char* retentions, int retentionsSize)
448+
{
449+
if (!m_frontend)
450+
return;
451+
m_frontend->heapXDKUpdate(String(symbols, symbolsSize), String(frames, framesSize),
452+
String(types, typesSize), String(chunks, chunksSize),
453+
String(retentions, retentionsSize));
454+
}
455+
329456
} // namespace blink
330457

Source/core/inspector/InspectorHeapProfilerAgent.h

+13
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class InspectorHeapProfilerAgent final : public InspectorBaseAgent<InspectorHeap
6161
virtual void disable(ErrorString*) override;
6262
virtual void startTrackingHeapObjects(ErrorString*, const bool* trackAllocations) override;
6363
virtual void stopTrackingHeapObjects(ErrorString*, const bool* reportProgress) override;
64+
virtual void startTrackingHeapXDK(ErrorString*, const int* stack_depth, const int* sav, const bool* retentions) override;
65+
virtual void stopTrackingHeapXDK(ErrorString*, RefPtr<TypeBuilder::HeapProfiler::HeapEventXDK>&) override;
6466

6567
virtual void setFrontend(InspectorFrontend*) override;
6668
virtual void clearFrontend() override;
@@ -75,18 +77,29 @@ class InspectorHeapProfilerAgent final : public InspectorBaseAgent<InspectorHeap
7577
class HeapStatsStream;
7678
class HeapStatsUpdateTask;
7779

80+
class HeapXDKStream;
81+
class HeapXDKUpdateTask;
82+
7883
explicit InspectorHeapProfilerAgent(InjectedScriptManager*);
7984

8085
void requestHeapStatsUpdate();
8186
void pushHeapStatsUpdate(const uint32_t* const data, const int size);
8287

88+
void requestHeapXDKUpdate();
89+
void pushHeapXDKUpdate(const char* symbols, int symbolsSize,
90+
const char* frames, int framesSize,
91+
const char* types, int typesSize,
92+
const char* chunks, int chunksSize,
93+
const char* retentions, int retentionsSize);
94+
8395
void startTrackingHeapObjectsInternal(bool trackAllocations);
8496
void stopTrackingHeapObjectsInternal();
8597

8698
RawPtrWillBeMember<InjectedScriptManager> m_injectedScriptManager;
8799
InspectorFrontend::HeapProfiler* m_frontend;
88100
unsigned m_nextUserInitiatedHeapSnapshotNumber;
89101
OwnPtrWillBeMember<HeapStatsUpdateTask> m_heapStatsUpdateTask;
102+
OwnPtrWillBeMember<HeapXDKUpdateTask> m_heapXDKUpdateTask;
90103
};
91104

92105
} // namespace blink

Source/core/inspector/ScriptProfile.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,34 @@ PassRefPtr<TypeBuilder::Array<double> > ScriptProfile::buildInspectorObjectForTi
135135
return array.release();
136136
}
137137

138+
String HeapProfileXDK::getSymbols() const
139+
{
140+
return String(m_event->getSymbols());
141+
}
142+
143+
String HeapProfileXDK::getFrames() const
144+
{
145+
return String(m_event->getFrames());
146+
}
147+
148+
String HeapProfileXDK::getTypes() const
149+
{
150+
return String(m_event->getTypes());
151+
}
152+
153+
String HeapProfileXDK::getChunks() const
154+
{
155+
return String(m_event->getChunks());
156+
}
157+
158+
int HeapProfileXDK::getDuration() const
159+
{
160+
return (int)m_event->getDuration();
161+
}
162+
163+
String HeapProfileXDK::getRetentions() const
164+
{
165+
return String(m_event->getRetentions());
166+
}
167+
138168
} // namespace blink

Source/core/inspector/ScriptProfile.h

+24
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,30 @@ class ScriptProfile final : public RefCountedWillBeGarbageCollectedFinalized<Scr
6969
double m_idleTime;
7070
};
7171

72+
class HeapProfileXDK final : public RefCountedWillBeGarbageCollectedFinalized<HeapProfileXDK> {
73+
public:
74+
static PassRefPtrWillBeRawPtr<HeapProfileXDK> create(v8::HeapEventXDK* event)
75+
{
76+
return adoptRefWillBeNoop(new HeapProfileXDK(event));
77+
}
78+
79+
String getSymbols() const;
80+
String getFrames() const;
81+
String getTypes() const;
82+
String getChunks() const;
83+
String getRetentions() const;
84+
int getDuration() const;
85+
86+
private:
87+
HeapProfileXDK(v8::HeapEventXDK* event)
88+
: m_event(event)
89+
{
90+
}
91+
92+
v8::HeapEventXDK* m_event;
93+
94+
};
95+
7296
} // namespace blink
7397

7498
#endif // ScriptProfile_h

Source/devtools/protocol.json

+38-1
Original file line numberDiff line numberDiff line change
@@ -3918,6 +3918,19 @@
39183918
"id": "HeapSnapshotObjectId",
39193919
"type": "string",
39203920
"description": "Heap snapshot object id."
3921+
},
3922+
{
3923+
"id": "HeapEventXDK",
3924+
"type": "object",
3925+
"description": "",
3926+
"properties": [
3927+
{ "name": "duration", "type": "integer" },
3928+
{ "name": "symbols", "type": "string" },
3929+
{ "name": "frames", "type": "string" },
3930+
{ "name": "types", "type": "string" },
3931+
{ "name": "chunks", "type": "string" },
3932+
{ "name": "retentions", "type": "string" }
3933+
]
39213934
}
39223935
],
39233936
"commands": [
@@ -3940,6 +3953,20 @@
39403953
]
39413954

39423955
},
3956+
{
3957+
"name": "startTrackingHeapXDK",
3958+
"parameters": [
3959+
{ "name": "stack_depth", "type": "integer", "optional": true },
3960+
{ "name": "sav", "type": "integer", "optional": true },
3961+
{ "name": "retentions", "type": "boolean", "optional": true }
3962+
]
3963+
},
3964+
{
3965+
"name": "stopTrackingHeapXDK",
3966+
"returns": [
3967+
{ "name": "profileXDK", "$ref": "HeapEventXDK", "description": "Recorded profile." }
3968+
]
3969+
},
39433970
{
39443971
"name": "takeHeapSnapshot",
39453972
"parameters": [
@@ -4001,7 +4028,17 @@
40014028
"parameters": [
40024029
{ "name": "statsUpdate", "type": "array", "items": { "type": "integer" }, "description": "An array of triplets. Each triplet describes a fragment. The first integer is the fragment index, the second integer is a total count of objects for the fragment, the third integer is a total size of the objects for the fragment."}
40034030
]
4004-
}
4031+
},
4032+
{
4033+
"name": "heapXDKUpdate",
4034+
"parameters": [
4035+
{ "name": "symbols", "type": "string" },
4036+
{ "name": "frames", "type": "string" },
4037+
{ "name": "types", "type": "string" },
4038+
{ "name": "chunks", "type": "string" },
4039+
{ "name": "retentions", "type": "string" }
4040+
]
4041+
}
40054042
]
40064043
},
40074044
{

0 commit comments

Comments
 (0)