Skip to content

Commit 7bfa872

Browse files
joyeecheungtargos
authored andcommitted
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: #33807 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Jiawen Geng <[email protected]> Reviewed-By: Ben Coe <[email protected]>
1 parent 15ffed5 commit 7bfa872

File tree

6 files changed

+73
-2
lines changed

6 files changed

+73
-2
lines changed

doc/api/v8.md

+14-2
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,18 @@ be reset and a new coverage report will be written to the directory specified
227227
by [`NODE_V8_COVERAGE`][].
228228

229229
When the process is about to exit, one last coverage will still be written to
230-
disk.
230+
disk, unless [`v8.stopCoverage()`][] is invoked before the process exits.
231+
232+
## `v8.stopCoverage()`
233+
234+
<!-- YAML
235+
added: REPLACEME
236+
-->
237+
238+
The `v8.stopCoverage()` method allows the user to stop the coverage collection
239+
started by [`NODE_V8_COVERAGE`][], so that V8 can release the execution count
240+
records and optimize code. This can be used in conjunction with
241+
`v8.takeCoverage()` if the user wants to collect the coverage on demand.
231242

232243
## `v8.writeHeapSnapshot([filename])`
233244
<!-- YAML
@@ -526,7 +537,7 @@ A subclass of [`Deserializer`][] corresponding to the format written by
526537
[`Deserializer`]: #v8_class_v8_deserializer
527538
[`Error`]: errors.md#errors_class_error
528539
[`GetHeapSpaceStatistics`]: https://v8docs.nodesource.com/node-13.2/d5/dda/classv8_1_1_isolate.html#ac673576f24fdc7a33378f8f57e1d13a4
529-
[`NODE_V8_COVERAGE`]: cli.html#cli_node_v8_coverage_dir
540+
[`NODE_V8_COVERAGE`]: cli.md#cli_node_v8_coverage_dir
530541
[`Serializer`]: #v8_class_v8_serializer
531542
[`deserializer._readHostObject()`]: #v8_deserializer_readhostobject
532543
[`deserializer.transferArrayBuffer()`]: #v8_deserializer_transferarraybuffer_id_arraybuffer
@@ -536,5 +547,6 @@ A subclass of [`Deserializer`][] corresponding to the format written by
536547
[`serializer.releaseBuffer()`]: #v8_serializer_releasebuffer
537548
[`serializer.transferArrayBuffer()`]: #v8_serializer_transferarraybuffer_id_arraybuffer
538549
[`serializer.writeRawBytes()`]: #v8_serializer_writerawbytes_buffer
550+
[`v8.stopCoverage()`]: #v8_v8_stopcoverage
539551
[`vm.Script`]: vm.md#vm_new_vm_script_code_options
540552
[worker threads]: worker_threads.md

lib/v8.js

+1
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ module.exports = {
282282
DefaultDeserializer,
283283
deserialize,
284284
takeCoverage: profiler.takeCoverage,
285+
stopCoverage: profiler.stopCoverage,
285286
serialize,
286287
writeHeapSnapshot,
287288
};

src/inspector_profiler.cc

+20
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,10 @@ void V8CoverageConnection::TakeCoverage() {
295295
DispatchMessage("Profiler.takePreciseCoverage", nullptr, true);
296296
}
297297

298+
void V8CoverageConnection::StopCoverage() {
299+
DispatchMessage("Profiler.stopPreciseCoverage");
300+
}
301+
298302
void V8CoverageConnection::End() {
299303
Debug(env_,
300304
DebugCategory::INSPECTOR_PROFILER,
@@ -489,6 +493,21 @@ static void TakeCoverage(const FunctionCallbackInfo<Value>& args) {
489493
}
490494
}
491495

496+
static void StopCoverage(const FunctionCallbackInfo<Value>& args) {
497+
Environment* env = Environment::GetCurrent(args);
498+
V8CoverageConnection* connection = env->coverage_connection();
499+
500+
Debug(env,
501+
DebugCategory::INSPECTOR_PROFILER,
502+
"StopCoverage, connection %s nullptr\n",
503+
connection == nullptr ? "==" : "!=");
504+
505+
if (connection != nullptr) {
506+
Debug(env, DebugCategory::INSPECTOR_PROFILER, "Stopping coverage\n");
507+
connection->StopCoverage();
508+
}
509+
}
510+
492511
static void Initialize(Local<Object> target,
493512
Local<Value> unused,
494513
Local<Context> context,
@@ -497,6 +516,7 @@ static void Initialize(Local<Object> target,
497516
env->SetMethod(target, "setCoverageDirectory", SetCoverageDirectory);
498517
env->SetMethod(target, "setSourceMapCacheGetter", SetSourceMapCacheGetter);
499518
env->SetMethod(target, "takeCoverage", TakeCoverage);
519+
env->SetMethod(target, "stopCoverage", StopCoverage);
500520
}
501521

502522
} // namespace profiler

src/inspector_profiler.h

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ class V8CoverageConnection : public V8ProfilerConnection {
9595
void WriteProfile(v8::Local<v8::Object> result) override;
9696
void WriteSourceMapCache();
9797
void TakeCoverage();
98+
void StopCoverage();
9899

99100
private:
100101
std::unique_ptr<inspector::InspectorSession> session_;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict';
2+
const v8 = require('v8');
3+
v8.stopCoverage();
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict';
2+
3+
if (!process.features.inspector) return;
4+
5+
require('../common');
6+
const fixtures = require('../common/fixtures');
7+
const tmpdir = require('../common/tmpdir');
8+
const assert = require('assert');
9+
const fs = require('fs');
10+
const { spawnSync } = require('child_process');
11+
12+
tmpdir.refresh();
13+
const intervals = 20;
14+
15+
{
16+
const output = spawnSync(process.execPath, [
17+
'-r',
18+
fixtures.path('v8-coverage', 'stop-coverage'),
19+
'-r',
20+
fixtures.path('v8-coverage', 'take-coverage'),
21+
fixtures.path('v8-coverage', 'interval'),
22+
], {
23+
env: {
24+
...process.env,
25+
NODE_V8_COVERAGE: tmpdir.path,
26+
NODE_DEBUG_NATIVE: 'INSPECTOR_PROFILER',
27+
TEST_INTERVALS: intervals
28+
},
29+
});
30+
console.log(output.stderr.toString());
31+
assert.strictEqual(output.status, 0);
32+
const coverageFiles = fs.readdirSync(tmpdir.path);
33+
assert.strictEqual(coverageFiles.length, 0);
34+
}

0 commit comments

Comments
 (0)