diff options
author | Joyee Cheung <joyeec9h3@gmail.com> | 2020-06-09 16:18:25 +0300 |
---|---|---|
committer | gengjiawen <technicalcute@gmail.com> | 2020-10-22 13:53:36 +0300 |
commit | 7945a2cdc34623234037dfaccef56c257da68d13 (patch) | |
tree | 8030f573c3e83f0da49e0a00e36763c1f7aa2d18 | |
parent | fc5636e1eb45949e764f3b1ffbd63e39b2ca30a9 (diff) |
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
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 acdc122ed6a..72556365291 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 @@ -526,7 +537,7 @@ A subclass of [`Deserializer`][] corresponding to the format written by [`Deserializer`]: #v8_class_v8_deserializer [`Error`]: errors.md#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 @@ -536,5 +547,6 @@ 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.md#vm_new_vm_script_code_options [worker threads]: worker_threads.md diff --git a/lib/v8.js b/lib/v8.js index 0442cce4083..15fe57e63e3 100644 --- a/lib/v8.js +++ b/lib/v8.js @@ -282,6 +282,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 3444a9b9895..092b263ada2 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, @@ -489,6 +493,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, @@ -497,6 +516,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 5e861dd0ea0..be74153b0c3 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 00000000000..dadfd1900bd --- /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 00000000000..020e18d8747 --- /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); +} |