Skip to content

Commit 3568a72

Browse files
janicduplessisfacebook-github-bot
authored andcommitted
Implement Runtime.getHeapUsage for hermes chrome inspector (#32895)
Summary: I was looking at the hermes chrome devtools integration and noticed requests to `Runtime.getHeapUsage` which was not implemented. When implemented it will show a summary of memory usage of the javascript instance in devtools. <img width="325" alt="image" src="https://user-images.githubusercontent.com/2677334/149637113-e1d95d26-9e26-46c2-9be6-47d22284f15f.png"> ## Changelog [General] [Added] - Implement Runtime.getHeapUsage for hermes chrome inspector Pull Request resolved: #32895 Test Plan: Before <img width="912" alt="image" src="https://user-images.githubusercontent.com/2677334/149637073-15f4e1fa-8183-42dc-8673-d4371731415c.png"> After <img width="1076" alt="image" src="https://user-images.githubusercontent.com/2677334/149637085-579dee8f-5efb-4658-b0a8-2400bd119924.png"> Reviewed By: christophpurrer Differential Revision: D33616658 Pulled By: ShikaSD fbshipit-source-id: 49d863e6a58d4a92d4c86f9a288ac33ed8d2cb0d
1 parent a86cae7 commit 3568a72

File tree

8 files changed

+123
-12
lines changed

8 files changed

+123
-12
lines changed

ReactCommon/hermes/inspector/chrome/Connection.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class Connection::Impl : public inspector::InspectorObserver,
103103
void handle(const m::heapProfiler::GetHeapObjectIdRequest &req) override;
104104
void handle(const m::runtime::CallFunctionOnRequest &req) override;
105105
void handle(const m::runtime::EvaluateRequest &req) override;
106+
void handle(const m::runtime::GetHeapUsageRequest &req) override;
106107
void handle(const m::runtime::GetPropertiesRequest &req) override;
107108
void handle(const m::runtime::RunIfWaitingForDebuggerRequest &req) override;
108109

@@ -1348,6 +1349,23 @@ Connection::Impl::makePropsFromValue(
13481349
return result;
13491350
}
13501351

1352+
void Connection::Impl::handle(const m::runtime::GetHeapUsageRequest &req) {
1353+
auto resp = std::make_shared<m::runtime::GetHeapUsageResponse>();
1354+
resp->id = req.id;
1355+
1356+
inspector_
1357+
->executeIfEnabled(
1358+
"Runtime.getHeapUsage",
1359+
[this, req, resp](const debugger::ProgramState &state) {
1360+
auto heapInfo = getRuntime().instrumentation().getHeapInfo(false);
1361+
resp->usedSize = heapInfo["hermes_allocatedBytes"];
1362+
resp->totalSize = heapInfo["hermes_heapSize"];
1363+
})
1364+
.via(executor_.get())
1365+
.thenValue([this, resp](auto &&) { sendResponseToClient(*resp); })
1366+
.thenError<std::exception>(sendErrorToClient(req.id));
1367+
}
1368+
13511369
void Connection::Impl::handle(const m::runtime::GetPropertiesRequest &req) {
13521370
auto resp = std::make_shared<m::runtime::GetPropertiesResponse>();
13531371
resp->id = req.id;

ReactCommon/hermes/inspector/chrome/MessageTypes.cpp

+51
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ std::unique_ptr<Request> Request::fromJsonThrowOnError(const std::string &str) {
6262
makeUnique<heapProfiler::TakeHeapSnapshotRequest>},
6363
{"Runtime.callFunctionOn", makeUnique<runtime::CallFunctionOnRequest>},
6464
{"Runtime.evaluate", makeUnique<runtime::EvaluateRequest>},
65+
{"Runtime.getHeapUsage", makeUnique<runtime::GetHeapUsageRequest>},
6566
{"Runtime.getProperties", makeUnique<runtime::GetPropertiesRequest>},
6667
{"Runtime.runIfWaitingForDebugger",
6768
makeUnique<runtime::RunIfWaitingForDebuggerRequest>},
@@ -503,12 +504,19 @@ debugger::ResumeRequest::ResumeRequest(const dynamic &obj)
503504
: Request("Debugger.resume") {
504505
assign(id, obj, "id");
505506
assign(method, obj, "method");
507+
508+
dynamic params = obj.at("params");
509+
assign(terminateOnResume, params, "terminateOnResume");
506510
}
507511

508512
dynamic debugger::ResumeRequest::toDynamic() const {
513+
dynamic params = dynamic::object;
514+
put(params, "terminateOnResume", terminateOnResume);
515+
509516
dynamic obj = dynamic::object;
510517
put(obj, "id", id);
511518
put(obj, "method", method);
519+
put(obj, "params", std::move(params));
512520
return obj;
513521
}
514522

@@ -897,12 +905,14 @@ heapProfiler::StopTrackingHeapObjectsRequest::StopTrackingHeapObjectsRequest(
897905
dynamic params = obj.at("params");
898906
assign(reportProgress, params, "reportProgress");
899907
assign(treatGlobalObjectsAsRoots, params, "treatGlobalObjectsAsRoots");
908+
assign(captureNumericValue, params, "captureNumericValue");
900909
}
901910

902911
dynamic heapProfiler::StopTrackingHeapObjectsRequest::toDynamic() const {
903912
dynamic params = dynamic::object;
904913
put(params, "reportProgress", reportProgress);
905914
put(params, "treatGlobalObjectsAsRoots", treatGlobalObjectsAsRoots);
915+
put(params, "captureNumericValue", captureNumericValue);
906916

907917
dynamic obj = dynamic::object;
908918
put(obj, "id", id);
@@ -928,12 +938,14 @@ heapProfiler::TakeHeapSnapshotRequest::TakeHeapSnapshotRequest(
928938
dynamic params = obj.at("params");
929939
assign(reportProgress, params, "reportProgress");
930940
assign(treatGlobalObjectsAsRoots, params, "treatGlobalObjectsAsRoots");
941+
assign(captureNumericValue, params, "captureNumericValue");
931942
}
932943

933944
dynamic heapProfiler::TakeHeapSnapshotRequest::toDynamic() const {
934945
dynamic params = dynamic::object;
935946
put(params, "reportProgress", reportProgress);
936947
put(params, "treatGlobalObjectsAsRoots", treatGlobalObjectsAsRoots);
948+
put(params, "captureNumericValue", captureNumericValue);
937949

938950
dynamic obj = dynamic::object;
939951
put(obj, "id", id);
@@ -1030,6 +1042,26 @@ void runtime::EvaluateRequest::accept(RequestHandler &handler) const {
10301042
handler.handle(*this);
10311043
}
10321044

1045+
runtime::GetHeapUsageRequest::GetHeapUsageRequest()
1046+
: Request("Runtime.getHeapUsage") {}
1047+
1048+
runtime::GetHeapUsageRequest::GetHeapUsageRequest(const dynamic &obj)
1049+
: Request("Runtime.getHeapUsage") {
1050+
assign(id, obj, "id");
1051+
assign(method, obj, "method");
1052+
}
1053+
1054+
dynamic runtime::GetHeapUsageRequest::toDynamic() const {
1055+
dynamic obj = dynamic::object;
1056+
put(obj, "id", id);
1057+
put(obj, "method", method);
1058+
return obj;
1059+
}
1060+
1061+
void runtime::GetHeapUsageRequest::accept(RequestHandler &handler) const {
1062+
handler.handle(*this);
1063+
}
1064+
10331065
runtime::GetPropertiesRequest::GetPropertiesRequest()
10341066
: Request("Runtime.getProperties") {}
10351067

@@ -1284,6 +1316,25 @@ dynamic runtime::EvaluateResponse::toDynamic() const {
12841316
return obj;
12851317
}
12861318

1319+
runtime::GetHeapUsageResponse::GetHeapUsageResponse(const dynamic &obj) {
1320+
assign(id, obj, "id");
1321+
1322+
dynamic res = obj.at("result");
1323+
assign(usedSize, res, "usedSize");
1324+
assign(totalSize, res, "totalSize");
1325+
}
1326+
1327+
dynamic runtime::GetHeapUsageResponse::toDynamic() const {
1328+
dynamic res = dynamic::object;
1329+
put(res, "usedSize", usedSize);
1330+
put(res, "totalSize", totalSize);
1331+
1332+
dynamic obj = dynamic::object;
1333+
put(obj, "id", id);
1334+
put(obj, "result", std::move(res));
1335+
return obj;
1336+
}
1337+
12871338
runtime::GetPropertiesResponse::GetPropertiesResponse(const dynamic &obj) {
12881339
assign(id, obj, "id");
12891340

ReactCommon/hermes/inspector/chrome/MessageTypes.h

+25
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ struct ExceptionDetails;
5959
struct ExecutionContextCreatedNotification;
6060
struct ExecutionContextDescription;
6161
using ExecutionContextId = int;
62+
struct GetHeapUsageRequest;
63+
struct GetHeapUsageResponse;
6264
struct GetPropertiesRequest;
6365
struct GetPropertiesResponse;
6466
struct InternalPropertyDescriptor;
@@ -127,6 +129,7 @@ struct RequestHandler {
127129
virtual void handle(const heapProfiler::TakeHeapSnapshotRequest &req) = 0;
128130
virtual void handle(const runtime::CallFunctionOnRequest &req) = 0;
129131
virtual void handle(const runtime::EvaluateRequest &req) = 0;
132+
virtual void handle(const runtime::GetHeapUsageRequest &req) = 0;
130133
virtual void handle(const runtime::GetPropertiesRequest &req) = 0;
131134
virtual void handle(const runtime::RunIfWaitingForDebuggerRequest &req) = 0;
132135
};
@@ -162,6 +165,7 @@ struct NoopRequestHandler : public RequestHandler {
162165
void handle(const heapProfiler::TakeHeapSnapshotRequest &req) override {}
163166
void handle(const runtime::CallFunctionOnRequest &req) override {}
164167
void handle(const runtime::EvaluateRequest &req) override {}
168+
void handle(const runtime::GetHeapUsageRequest &req) override {}
165169
void handle(const runtime::GetPropertiesRequest &req) override {}
166170
void handle(const runtime::RunIfWaitingForDebuggerRequest &req) override {}
167171
};
@@ -400,6 +404,8 @@ struct debugger::ResumeRequest : public Request {
400404

401405
folly::dynamic toDynamic() const override;
402406
void accept(RequestHandler &handler) const override;
407+
408+
folly::Optional<bool> terminateOnResume;
403409
};
404410

405411
struct debugger::SetBreakpointRequest : public Request {
@@ -548,6 +554,7 @@ struct heapProfiler::StopTrackingHeapObjectsRequest : public Request {
548554

549555
folly::Optional<bool> reportProgress;
550556
folly::Optional<bool> treatGlobalObjectsAsRoots;
557+
folly::Optional<bool> captureNumericValue;
551558
};
552559

553560
struct heapProfiler::TakeHeapSnapshotRequest : public Request {
@@ -559,6 +566,7 @@ struct heapProfiler::TakeHeapSnapshotRequest : public Request {
559566

560567
folly::Optional<bool> reportProgress;
561568
folly::Optional<bool> treatGlobalObjectsAsRoots;
569+
folly::Optional<bool> captureNumericValue;
562570
};
563571

564572
struct runtime::CallFunctionOnRequest : public Request {
@@ -596,6 +604,14 @@ struct runtime::EvaluateRequest : public Request {
596604
folly::Optional<bool> awaitPromise;
597605
};
598606

607+
struct runtime::GetHeapUsageRequest : public Request {
608+
GetHeapUsageRequest();
609+
explicit GetHeapUsageRequest(const folly::dynamic &obj);
610+
611+
folly::dynamic toDynamic() const override;
612+
void accept(RequestHandler &handler) const override;
613+
};
614+
599615
struct runtime::GetPropertiesRequest : public Request {
600616
GetPropertiesRequest();
601617
explicit GetPropertiesRequest(const folly::dynamic &obj);
@@ -709,6 +725,15 @@ struct runtime::EvaluateResponse : public Response {
709725
folly::Optional<runtime::ExceptionDetails> exceptionDetails;
710726
};
711727

728+
struct runtime::GetHeapUsageResponse : public Response {
729+
GetHeapUsageResponse() = default;
730+
explicit GetHeapUsageResponse(const folly::dynamic &obj);
731+
folly::dynamic toDynamic() const override;
732+
733+
double usedSize{};
734+
double totalSize{};
735+
};
736+
712737
struct runtime::GetPropertiesResponse : public Response {
713738
GetPropertiesResponse() = default;
714739
explicit GetPropertiesResponse(const folly::dynamic &obj);

ReactCommon/hermes/inspector/tools/message_types.txt

+1
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ Runtime.callFunctionOn
3232
Runtime.consoleAPICalled
3333
Runtime.evaluate
3434
Runtime.executionContextCreated
35+
Runtime.getHeapUsage
3536
Runtime.getProperties
3637
Runtime.runIfWaitingForDebugger

ReactCommon/hermes/inspector/tools/msggen/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"test": "jest"
1313
},
1414
"dependencies": {
15-
"devtools-protocol": "0.0.730699",
15+
"devtools-protocol": "0.0.959523",
1616
"yargs": "^14.2.0"
1717
},
1818
"devDependencies": {

ReactCommon/hermes/inspector/tools/msggen/src/index.js

+17-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const proto = mergeDomains(standard, custom);
4141
function parseDomains(
4242
domainObjs: Array<any>,
4343
ignoreExperimental: boolean,
44+
includeExperimental: Set<string>,
4445
): Descriptor {
4546
const desc = {
4647
types: [],
@@ -59,7 +60,12 @@ function parseDomains(
5960
}
6061

6162
for (const commandObj of obj.commands || []) {
62-
const command = Command.create(domain, commandObj, ignoreExperimental);
63+
const command = Command.create(
64+
domain,
65+
commandObj,
66+
!includeExperimental.has(`${domain}.${commandObj.name}`) &&
67+
ignoreExperimental,
68+
);
6369
if (command) {
6470
desc.commands.push(command);
6571
}
@@ -199,18 +205,27 @@ function main() {
199205
.boolean('e')
200206
.alias('e', 'ignore-experimental')
201207
.describe('e', 'ignore experimental commands, props, and types')
208+
.alias('i', 'include-experimental')
209+
.describe('i', 'experimental commands to include')
202210
.alias('r', 'roots')
203211
.describe('r', 'path to a file listing root types, events, and commands')
204212
.nargs('r', 1)
205213
.demandCommand(2, 2).argv;
206214

207215
const ignoreExperimental = !!args.e;
216+
const includeExperimental = new Set(
217+
typeof args.i === 'string' ? args.i.split(',') : [],
218+
);
208219
const [headerPath, implPath] = args._;
209220

210221
const headerStream = fs.createWriteStream(headerPath);
211222
const implStream = fs.createWriteStream(implPath);
212223

213-
const desc = parseDomains(proto.domains, ignoreExperimental);
224+
const desc = parseDomains(
225+
proto.domains,
226+
ignoreExperimental,
227+
includeExperimental,
228+
);
214229
const graph = buildGraph(desc);
215230
const roots = parseRoots(desc, String(args.roots));
216231

ReactCommon/hermes/inspector/tools/msggen/yarn.lock

+4-4
Original file line numberDiff line numberDiff line change
@@ -2434,10 +2434,10 @@ detect-newline@^3.0.0:
24342434
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
24352435
integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==
24362436

2437-
2438-
version "0.0.730699"
2439-
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.730699.tgz#4d18f6a9b7fb7cf3f1ffe73bfe14aad66cf3b2ef"
2440-
integrity sha512-dprBpuPzVIIXXL6GevzhvWe2wg836h3d5hY+n6IzzHbKLsUh6QlVmcIy15za0J3MhDFbmEH60s6uYsrw/tgBbw==
2437+
2438+
version "0.0.959523"
2439+
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.959523.tgz#a7ce62c6b88876081fe5bec866f70e467bc021ba"
2440+
integrity sha512-taOcAND/oJA5FhJD2I3RA+I8RPdrpPJWwvMBPzTq7Sugev1xTOG3lgtlSfkh5xkjTYw0Ti2CRQq016goFHMoPQ==
24412441

24422442
diff-sequences@^26.6.2:
24432443
version "26.6.2"

ReactCommon/hermes/inspector/tools/run_msggen

+6-5
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,25 @@
22

33
set -e
44

5-
DIR=$(dirname "${BASH_SOURCE[0]}")
5+
DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
66
cd "${DIR}/msggen"
77

88
yarn install
99
yarn build
1010

11-
FBSOURCE=$(hg root)
12-
MSGTYPES_PATH="${FBSOURCE}/xplat/js/react-native-github/ReactCommon/hermes/inspector/tools/message_types.txt"
13-
HEADER_PATH="${FBSOURCE}/xplat/js/react-native-github/ReactCommon/hermes/inspector/chrome/MessageTypes.h"
14-
CPP_PATH="${FBSOURCE}/xplat/js/react-native-github/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp"
11+
MSGTYPES_PATH="${DIR}/message_types.txt"
12+
HEADER_PATH="${DIR}/../chrome/MessageTypes.h"
13+
CPP_PATH="${DIR}/../chrome/MessageTypes.cpp"
1514

1615
node bin/index.js \
1716
--ignore-experimental \
17+
--include-experimental=Runtime.getHeapUsage \
1818
--roots "$MSGTYPES_PATH" \
1919
"$HEADER_PATH" "$CPP_PATH"
2020

2121
clang-format -i --style=file "$HEADER_PATH"
2222
clang-format -i --style=file "$CPP_PATH"
2323

24+
FBSOURCE=$(hg root)
2425
"${FBSOURCE}/tools/signedsource" sign "$HEADER_PATH"
2526
"${FBSOURCE}/tools/signedsource" sign "$CPP_PATH"

0 commit comments

Comments
 (0)