diff options
author | Joyee Cheung <joyeec9h3@gmail.com> | 2020-06-09 21:18:25 +0800 |
---|---|---|
committer | Richard Lau <rlau@redhat.com> | 2021-03-17 20:36:04 +0000 |
commit | 86f34ee18c36e2fcd3c057abc86704523ec940c8 (patch) | |
tree | 733a7150fb8cb0885d2e6822c02425b727aa2a9c | |
parent | 8ddea3f16d643cb745e8ce75362d9be233bb42e1 (diff) | |
download | node-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.md | 16 | ||||
-rw-r--r-- | lib/v8.js | 1 | ||||
-rw-r--r-- | src/inspector_profiler.cc | 20 | ||||
-rw-r--r-- | src/inspector_profiler.h | 1 | ||||
-rw-r--r-- | test/fixtures/v8-coverage/stop-coverage.js | 3 | ||||
-rw-r--r-- | test/parallel/test-v8-stop-coverage.js | 34 |
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/ @@ -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); +} |