summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoyee Cheung <joyeec9h3@gmail.com>2020-06-09 21:18:25 +0800
committerRichard Lau <rlau@redhat.com>2021-03-17 20:36:04 +0000
commit86f34ee18c36e2fcd3c057abc86704523ec940c8 (patch)
tree733a7150fb8cb0885d2e6822c02425b727aa2a9c
parent8ddea3f16d643cb745e8ce75362d9be233bb42e1 (diff)
downloadnode-new-86f34ee18c36e2fcd3c057abc86704523ec940c8.tar.gz
v8: implement v8.stopCoverage()
Add a v8.stopCoverage() API to stop the coverage collection started by NODE_V8_COVERAGE - this would be useful in conjunction with v8.takeCoverage() if the user don't want to emit the coverage at the process exit but still want to collect it on demand at some point. PR-URL: https://github.com/nodejs/node/pull/33807 Backport-PR-URL: https://github.com/nodejs/node/pull/36352 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Ben Coe <bencoe@gmail.com>
-rw-r--r--doc/api/v8.md16
-rw-r--r--lib/v8.js1
-rw-r--r--src/inspector_profiler.cc20
-rw-r--r--src/inspector_profiler.h1
-rw-r--r--test/fixtures/v8-coverage/stop-coverage.js3
-rw-r--r--test/parallel/test-v8-stop-coverage.js34
6 files changed, 73 insertions, 2 deletions
diff --git a/doc/api/v8.md b/doc/api/v8.md
index de4b9a37bd..7af37fba94 100644
--- a/doc/api/v8.md
+++ b/doc/api/v8.md
@@ -227,7 +227,18 @@ be reset and a new coverage report will be written to the directory specified
by [`NODE_V8_COVERAGE`][].
When the process is about to exit, one last coverage will still be written to
-disk.
+disk, unless [`v8.stopCoverage()`][] is invoked before the process exits.
+
+## `v8.stopCoverage()`
+
+<!-- YAML
+added: REPLACEME
+-->
+
+The `v8.stopCoverage()` method allows the user to stop the coverage collection
+started by [`NODE_V8_COVERAGE`][], so that V8 can release the execution count
+records and optimize code. This can be used in conjunction with
+`v8.takeCoverage()` if the user wants to collect the coverage on demand.
## `v8.writeHeapSnapshot([filename])`
<!-- YAML
@@ -524,7 +535,7 @@ A subclass of [`Deserializer`][] corresponding to the format written by
[`Deserializer`]: #v8_class_v8_deserializer
[`Error`]: errors.html#errors_class_error
[`GetHeapSpaceStatistics`]: https://v8docs.nodesource.com/node-13.2/d5/dda/classv8_1_1_isolate.html#ac673576f24fdc7a33378f8f57e1d13a4
-[`NODE_V8_COVERAGE`]: cli.html#cli_node_v8_coverage_dir
+[`NODE_V8_COVERAGE`]: cli.md#cli_node_v8_coverage_dir
[`Serializer`]: #v8_class_v8_serializer
[`deserializer._readHostObject()`]: #v8_deserializer_readhostobject
[`deserializer.transferArrayBuffer()`]: #v8_deserializer_transferarraybuffer_id_arraybuffer
@@ -534,6 +545,7 @@ A subclass of [`Deserializer`][] corresponding to the format written by
[`serializer.releaseBuffer()`]: #v8_serializer_releasebuffer
[`serializer.transferArrayBuffer()`]: #v8_serializer_transferarraybuffer_id_arraybuffer
[`serializer.writeRawBytes()`]: #v8_serializer_writerawbytes_buffer
+[`v8.stopCoverage()`]: #v8_v8_stopcoverage
[`vm.Script`]: vm.html#vm_new_vm_script_code_options
[HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
[V8]: https://developers.google.com/v8/
diff --git a/lib/v8.js b/lib/v8.js
index 095af7212b..2143e07274 100644
--- a/lib/v8.js
+++ b/lib/v8.js
@@ -293,6 +293,7 @@ module.exports = {
DefaultDeserializer,
deserialize,
takeCoverage: profiler.takeCoverage,
+ stopCoverage: profiler.stopCoverage,
serialize,
writeHeapSnapshot,
};
diff --git a/src/inspector_profiler.cc b/src/inspector_profiler.cc
index 2e2fd2e3d8..7640a04078 100644
--- a/src/inspector_profiler.cc
+++ b/src/inspector_profiler.cc
@@ -295,6 +295,10 @@ void V8CoverageConnection::TakeCoverage() {
DispatchMessage("Profiler.takePreciseCoverage", nullptr, true);
}
+void V8CoverageConnection::StopCoverage() {
+ DispatchMessage("Profiler.stopPreciseCoverage");
+}
+
void V8CoverageConnection::End() {
Debug(env_,
DebugCategory::INSPECTOR_PROFILER,
@@ -505,6 +509,21 @@ static void TakeCoverage(const FunctionCallbackInfo<Value>& args) {
}
}
+static void StopCoverage(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ V8CoverageConnection* connection = env->coverage_connection();
+
+ Debug(env,
+ DebugCategory::INSPECTOR_PROFILER,
+ "StopCoverage, connection %s nullptr\n",
+ connection == nullptr ? "==" : "!=");
+
+ if (connection != nullptr) {
+ Debug(env, DebugCategory::INSPECTOR_PROFILER, "Stopping coverage\n");
+ connection->StopCoverage();
+ }
+}
+
static void Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
@@ -513,6 +532,7 @@ static void Initialize(Local<Object> target,
env->SetMethod(target, "setCoverageDirectory", SetCoverageDirectory);
env->SetMethod(target, "setSourceMapCacheGetter", SetSourceMapCacheGetter);
env->SetMethod(target, "takeCoverage", TakeCoverage);
+ env->SetMethod(target, "stopCoverage", StopCoverage);
}
} // namespace profiler
diff --git a/src/inspector_profiler.h b/src/inspector_profiler.h
index 5e861dd0ea..be74153b0c 100644
--- a/src/inspector_profiler.h
+++ b/src/inspector_profiler.h
@@ -95,6 +95,7 @@ class V8CoverageConnection : public V8ProfilerConnection {
void WriteProfile(v8::Local<v8::Object> result) override;
void WriteSourceMapCache();
void TakeCoverage();
+ void StopCoverage();
private:
std::unique_ptr<inspector::InspectorSession> session_;
diff --git a/test/fixtures/v8-coverage/stop-coverage.js b/test/fixtures/v8-coverage/stop-coverage.js
new file mode 100644
index 0000000000..dadfd1900b
--- /dev/null
+++ b/test/fixtures/v8-coverage/stop-coverage.js
@@ -0,0 +1,3 @@
+'use strict';
+const v8 = require('v8');
+v8.stopCoverage();
diff --git a/test/parallel/test-v8-stop-coverage.js b/test/parallel/test-v8-stop-coverage.js
new file mode 100644
index 0000000000..020e18d874
--- /dev/null
+++ b/test/parallel/test-v8-stop-coverage.js
@@ -0,0 +1,34 @@
+'use strict';
+
+if (!process.features.inspector) return;
+
+require('../common');
+const fixtures = require('../common/fixtures');
+const tmpdir = require('../common/tmpdir');
+const assert = require('assert');
+const fs = require('fs');
+const { spawnSync } = require('child_process');
+
+tmpdir.refresh();
+const intervals = 20;
+
+{
+ const output = spawnSync(process.execPath, [
+ '-r',
+ fixtures.path('v8-coverage', 'stop-coverage'),
+ '-r',
+ fixtures.path('v8-coverage', 'take-coverage'),
+ fixtures.path('v8-coverage', 'interval'),
+ ], {
+ env: {
+ ...process.env,
+ NODE_V8_COVERAGE: tmpdir.path,
+ NODE_DEBUG_NATIVE: 'INSPECTOR_PROFILER',
+ TEST_INTERVALS: intervals
+ },
+ });
+ console.log(output.stderr.toString());
+ assert.strictEqual(output.status, 0);
+ const coverageFiles = fs.readdirSync(tmpdir.path);
+ assert.strictEqual(coverageFiles.length, 0);
+}