Skip to content

Commit ed30549

Browse files
jbower-fbfacebook-github-bot
authored andcommitted
Plumb through memory allocation profiler feature to Chrome Inspector
Summary: Changelog: Make allocation profiler feature of Chome Inspector work Reviewed By: dulinriley Differential Revision: D20383003 fbshipit-source-id: 8a10c310d5a639a6644763adb53f2f0017057587
1 parent 8454975 commit ed30549

File tree

7 files changed

+174
-9
lines changed

7 files changed

+174
-9
lines changed

ReactCommon/hermes/inspector/chrome/Connection.cpp

+57-7
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ class Connection::Impl : public inspector::InspectorObserver,
8282
void handle(const m::debugger::StepOutRequest &req) override;
8383
void handle(const m::debugger::StepOverRequest &req) override;
8484
void handle(const m::heapProfiler::TakeHeapSnapshotRequest &req) override;
85+
void handle(
86+
const m::heapProfiler::StartTrackingHeapObjectsRequest &req) override;
87+
void handle(
88+
const m::heapProfiler::StopTrackingHeapObjectsRequest &req) override;
8589
void handle(const m::runtime::EvaluateRequest &req) override;
8690
void handle(const m::runtime::GetPropertiesRequest &req) override;
8791

@@ -95,6 +99,11 @@ class Connection::Impl : public inspector::InspectorObserver,
9599
const std::string &objectGroup,
96100
bool onlyOwnProperties);
97101

102+
void sendSnapshot(
103+
int reqId,
104+
std::string message,
105+
bool reportProgress,
106+
bool stopStackTraceCapture);
98107
void sendToClient(const std::string &str);
99108
void sendResponseToClient(const m::Response &resp);
100109
void sendNotificationToClient(const m::Notification &resp);
@@ -389,15 +398,16 @@ void Connection::Impl::handle(
389398
.thenError<std::exception>(sendErrorToClient(req.id));
390399
}
391400

392-
void Connection::Impl::handle(
393-
const m::heapProfiler::TakeHeapSnapshotRequest &req) {
394-
const auto id = req.id;
395-
const bool reportProgress = req.reportProgress && *req.reportProgress;
396-
401+
void Connection::Impl::sendSnapshot(
402+
int reqId,
403+
std::string message,
404+
bool reportProgress,
405+
bool stopStackTraceCapture) {
397406
inspector_
398407
->executeIfEnabled(
399-
"HeapProfiler.takeHeapSnapshot",
400-
[this, reportProgress](const debugger::ProgramState &) {
408+
message,
409+
[this, reportProgress, stopStackTraceCapture](
410+
const debugger::ProgramState &) {
401411
if (reportProgress) {
402412
// A progress notification with finished = true indicates the
403413
// snapshot has been captured and is ready to be sent. Our
@@ -421,13 +431,53 @@ void Connection::Impl::handle(
421431
});
422432

423433
getRuntime().instrumentation().createSnapshotToStream(cos);
434+
if (stopStackTraceCapture) {
435+
getRuntime()
436+
.instrumentation()
437+
.stopTrackingHeapObjectStackTraces();
438+
}
439+
})
440+
.via(executor_.get())
441+
.thenValue([this, reqId](auto &&) {
442+
sendResponseToClient(m::makeOkResponse(reqId));
443+
})
444+
.thenError<std::exception>(sendErrorToClient(reqId));
445+
}
446+
447+
void Connection::Impl::handle(
448+
const m::heapProfiler::TakeHeapSnapshotRequest &req) {
449+
sendSnapshot(
450+
req.id,
451+
"HeapSnapshot.takeHeapSnapshot",
452+
req.reportProgress && *req.reportProgress,
453+
/* stopStackTraceCapture */ false);
454+
}
455+
456+
void Connection::Impl::handle(
457+
const m::heapProfiler::StartTrackingHeapObjectsRequest &req) {
458+
const auto id = req.id;
459+
460+
inspector_
461+
->executeIfEnabled(
462+
"HeapProfiler.startTrackingHeapObjects",
463+
[this](const debugger::ProgramState &) {
464+
getRuntime().instrumentation().startTrackingHeapObjectStackTraces();
424465
})
425466
.via(executor_.get())
426467
.thenValue(
427468
[this, id](auto &&) { sendResponseToClient(m::makeOkResponse(id)); })
428469
.thenError<std::exception>(sendErrorToClient(req.id));
429470
}
430471

472+
void Connection::Impl::handle(
473+
const m::heapProfiler::StopTrackingHeapObjectsRequest &req) {
474+
sendSnapshot(
475+
req.id,
476+
"HeapSnapshot.takeHeapSnapshot",
477+
req.reportProgress && *req.reportProgress,
478+
/* stopStackTraceCapture */ true);
479+
}
480+
431481
void Connection::Impl::handle(const m::runtime::EvaluateRequest &req) {
432482
auto remoteObjPtr = std::make_shared<m::runtime::RemoteObject>();
433483

ReactCommon/hermes/inspector/chrome/MessageTypes.cpp

+65-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright 2004-present Facebook. All Rights Reserved.
2-
// @generated SignedSource<<633984dcfe87d2822ef0e80c1aab93ef>>
2+
// @generated SignedSource<<4ab81efd6f767bd583d00c806b7d1d9b>>
33

44
#include "MessageTypes.h"
55

@@ -40,6 +40,10 @@ std::unique_ptr<Request> Request::fromJsonThrowOnError(const std::string &str) {
4040
{"Debugger.stepInto", makeUnique<debugger::StepIntoRequest>},
4141
{"Debugger.stepOut", makeUnique<debugger::StepOutRequest>},
4242
{"Debugger.stepOver", makeUnique<debugger::StepOverRequest>},
43+
{"HeapProfiler.startTrackingHeapObjects",
44+
makeUnique<heapProfiler::StartTrackingHeapObjectsRequest>},
45+
{"HeapProfiler.stopTrackingHeapObjects",
46+
makeUnique<heapProfiler::StopTrackingHeapObjectsRequest>},
4347
{"HeapProfiler.takeHeapSnapshot",
4448
makeUnique<heapProfiler::TakeHeapSnapshotRequest>},
4549
{"Runtime.evaluate", makeUnique<runtime::EvaluateRequest>},
@@ -587,6 +591,66 @@ void debugger::StepOverRequest::accept(RequestHandler &handler) const {
587591
handler.handle(*this);
588592
}
589593

594+
heapProfiler::StartTrackingHeapObjectsRequest::StartTrackingHeapObjectsRequest()
595+
: Request("HeapProfiler.startTrackingHeapObjects") {}
596+
597+
heapProfiler::StartTrackingHeapObjectsRequest::StartTrackingHeapObjectsRequest(
598+
const dynamic &obj)
599+
: Request("HeapProfiler.startTrackingHeapObjects") {
600+
assign(id, obj, "id");
601+
assign(method, obj, "method");
602+
603+
dynamic params = obj.at("params");
604+
assign(trackAllocations, params, "trackAllocations");
605+
}
606+
607+
dynamic heapProfiler::StartTrackingHeapObjectsRequest::toDynamic() const {
608+
dynamic params = dynamic::object;
609+
put(params, "trackAllocations", trackAllocations);
610+
611+
dynamic obj = dynamic::object;
612+
put(obj, "id", id);
613+
put(obj, "method", method);
614+
put(obj, "params", std::move(params));
615+
return obj;
616+
}
617+
618+
void heapProfiler::StartTrackingHeapObjectsRequest::accept(
619+
RequestHandler &handler) const {
620+
handler.handle(*this);
621+
}
622+
623+
heapProfiler::StopTrackingHeapObjectsRequest::StopTrackingHeapObjectsRequest()
624+
: Request("HeapProfiler.stopTrackingHeapObjects") {}
625+
626+
heapProfiler::StopTrackingHeapObjectsRequest::StopTrackingHeapObjectsRequest(
627+
const dynamic &obj)
628+
: Request("HeapProfiler.stopTrackingHeapObjects") {
629+
assign(id, obj, "id");
630+
assign(method, obj, "method");
631+
632+
dynamic params = obj.at("params");
633+
assign(reportProgress, params, "reportProgress");
634+
assign(treatGlobalObjectsAsRoots, params, "treatGlobalObjectsAsRoots");
635+
}
636+
637+
dynamic heapProfiler::StopTrackingHeapObjectsRequest::toDynamic() const {
638+
dynamic params = dynamic::object;
639+
put(params, "reportProgress", reportProgress);
640+
put(params, "treatGlobalObjectsAsRoots", treatGlobalObjectsAsRoots);
641+
642+
dynamic obj = dynamic::object;
643+
put(obj, "id", id);
644+
put(obj, "method", method);
645+
put(obj, "params", std::move(params));
646+
return obj;
647+
}
648+
649+
void heapProfiler::StopTrackingHeapObjectsRequest::accept(
650+
RequestHandler &handler) const {
651+
handler.handle(*this);
652+
}
653+
590654
heapProfiler::TakeHeapSnapshotRequest::TakeHeapSnapshotRequest()
591655
: Request("HeapProfiler.takeHeapSnapshot") {}
592656

ReactCommon/hermes/inspector/chrome/MessageTypes.h

+32-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright 2004-present Facebook. All Rights Reserved.
2-
// @generated SignedSource<<16a6754d1896fef0cbab2a05800f6885>>
2+
// @generated SignedSource<<0a1a011902fd18d4eebd2fe12fafb8b1>>
33

44
#pragma once
55

@@ -68,6 +68,8 @@ using UnserializableValue = std::string;
6868
namespace heapProfiler {
6969
struct AddHeapSnapshotChunkNotification;
7070
struct ReportHeapSnapshotProgressNotification;
71+
struct StartTrackingHeapObjectsRequest;
72+
struct StopTrackingHeapObjectsRequest;
7173
struct TakeHeapSnapshotRequest;
7274
} // namespace heapProfiler
7375

@@ -88,6 +90,10 @@ struct RequestHandler {
8890
virtual void handle(const debugger::StepIntoRequest &req) = 0;
8991
virtual void handle(const debugger::StepOutRequest &req) = 0;
9092
virtual void handle(const debugger::StepOverRequest &req) = 0;
93+
virtual void handle(
94+
const heapProfiler::StartTrackingHeapObjectsRequest &req) = 0;
95+
virtual void handle(
96+
const heapProfiler::StopTrackingHeapObjectsRequest &req) = 0;
9197
virtual void handle(const heapProfiler::TakeHeapSnapshotRequest &req) = 0;
9298
virtual void handle(const runtime::EvaluateRequest &req) = 0;
9399
virtual void handle(const runtime::GetPropertiesRequest &req) = 0;
@@ -108,6 +114,10 @@ struct NoopRequestHandler : public RequestHandler {
108114
void handle(const debugger::StepIntoRequest &req) override {}
109115
void handle(const debugger::StepOutRequest &req) override {}
110116
void handle(const debugger::StepOverRequest &req) override {}
117+
void handle(
118+
const heapProfiler::StartTrackingHeapObjectsRequest &req) override {}
119+
void handle(
120+
const heapProfiler::StopTrackingHeapObjectsRequest &req) override {}
111121
void handle(const heapProfiler::TakeHeapSnapshotRequest &req) override {}
112122
void handle(const runtime::EvaluateRequest &req) override {}
113123
void handle(const runtime::GetPropertiesRequest &req) override {}
@@ -369,6 +379,27 @@ struct debugger::StepOverRequest : public Request {
369379
void accept(RequestHandler &handler) const override;
370380
};
371381

382+
struct heapProfiler::StartTrackingHeapObjectsRequest : public Request {
383+
StartTrackingHeapObjectsRequest();
384+
explicit StartTrackingHeapObjectsRequest(const folly::dynamic &obj);
385+
386+
folly::dynamic toDynamic() const override;
387+
void accept(RequestHandler &handler) const override;
388+
389+
folly::Optional<bool> trackAllocations;
390+
};
391+
392+
struct heapProfiler::StopTrackingHeapObjectsRequest : public Request {
393+
StopTrackingHeapObjectsRequest();
394+
explicit StopTrackingHeapObjectsRequest(const folly::dynamic &obj);
395+
396+
folly::dynamic toDynamic() const override;
397+
void accept(RequestHandler &handler) const override;
398+
399+
folly::Optional<bool> reportProgress;
400+
folly::Optional<bool> treatGlobalObjectsAsRoots;
401+
};
402+
372403
struct heapProfiler::TakeHeapSnapshotRequest : public Request {
373404
TakeHeapSnapshotRequest();
374405
explicit TakeHeapSnapshotRequest(const folly::dynamic &obj);

ReactCommon/hermes/inspector/tools/message_types.txt

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Debugger.stepOver
1717
HeapProfiler.addHeapSnapshotChunk
1818
HeapProfiler.reportHeapSnapshotProgress
1919
HeapProfiler.takeHeapSnapshot
20+
HeapProfiler.startTrackingHeapObjects
21+
HeapProfiler.stopTrackingHeapObjects
2022
Runtime.consoleAPICalled
2123
Runtime.evaluate
2224
Runtime.executionContextCreated

ReactCommon/jsi/jsi/decorator.h

+8
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,14 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation {
335335
plain().instrumentation().collectGarbage();
336336
}
337337

338+
void startTrackingHeapObjectStackTraces() override {
339+
plain().instrumentation().startTrackingHeapObjectStackTraces();
340+
}
341+
342+
void stopTrackingHeapObjectStackTraces() override {
343+
plain().instrumentation().stopTrackingHeapObjectStackTraces();
344+
}
345+
338346
void createSnapshotToFile(const std::string& path) override {
339347
plain().instrumentation().createSnapshotToFile(path);
340348
}

ReactCommon/jsi/jsi/instrumentation.h

+7
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ class Instrumentation {
5252
/// perform a full garbage collection
5353
virtual void collectGarbage() = 0;
5454

55+
/// Start capturing JS stack-traces for all JS heap allocated objects. These
56+
/// can be accessed via \c ::createSnapshotToFile().
57+
virtual void startTrackingHeapObjectStackTraces() = 0;
58+
59+
/// Stop capture JS stack-traces for JS heap allocated objects.
60+
virtual void stopTrackingHeapObjectStackTraces() = 0;
61+
5562
/// Captures the heap to a file
5663
///
5764
/// \param path to save the heap capture

ReactCommon/jsi/jsi/jsi.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ Instrumentation& Runtime::instrumentation() {
9999

100100
void collectGarbage() override {}
101101

102+
void startTrackingHeapObjectStackTraces() override {}
103+
void stopTrackingHeapObjectStackTraces() override {}
104+
102105
void createSnapshotToFile(const std::string&) override {
103106
throw JSINativeException(
104107
"Default instrumentation cannot create a heap snapshot");

0 commit comments

Comments
 (0)