diff options
-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); +} |