Skip to content

Commit 84fcdc3

Browse files
joyeecheungMylesBorins
authored andcommittedAug 31, 2021
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 <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Ben Coe <bencoe@gmail.com>
1 parent b238b6b commit 84fcdc3

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
@@ -236,7 +236,18 @@ be reset and a new coverage report will be written to the directory specified
236236
by [`NODE_V8_COVERAGE`][].
237237

238238
When the process is about to exit, one last coverage will still be written to
239-
disk.
239+
disk, unless [`v8.stopCoverage()`][] is invoked before the process exits.
240+
241+
## `v8.stopCoverage()`
242+
243+
<!-- YAML
244+
added: REPLACEME
245+
-->
246+
247+
The `v8.stopCoverage()` method allows the user to stop the coverage collection
248+
started by [`NODE_V8_COVERAGE`][], so that V8 can release the execution count
249+
records and optimize code. This can be used in conjunction with
250+
`v8.takeCoverage()` if the user wants to collect the coverage on demand.
240251

241252
## `v8.writeHeapSnapshot([filename])`
242253
<!-- YAML
@@ -535,7 +546,7 @@ A subclass of [`Deserializer`][] corresponding to the format written by
535546
[`Deserializer`]: #v8_class_v8_deserializer
536547
[`Error`]: errors.md#errors_class_error
537548
[`GetHeapSpaceStatistics`]: https://v8docs.nodesource.com/node-13.2/d5/dda/classv8_1_1_isolate.html#ac673576f24fdc7a33378f8f57e1d13a4
538-
[`NODE_V8_COVERAGE`]: cli.html#cli_node_v8_coverage_dir
549+
[`NODE_V8_COVERAGE`]: cli.md#cli_node_v8_coverage_dir
539550
[`Serializer`]: #v8_class_v8_serializer
540551
[`deserializer._readHostObject()`]: #v8_deserializer_readhostobject
541552
[`deserializer.transferArrayBuffer()`]: #v8_deserializer_transferarraybuffer_id_arraybuffer
@@ -545,5 +556,6 @@ A subclass of [`Deserializer`][] corresponding to the format written by
545556
[`serializer.releaseBuffer()`]: #v8_serializer_releasebuffer
546557
[`serializer.transferArrayBuffer()`]: #v8_serializer_transferarraybuffer_id_arraybuffer
547558
[`serializer.writeRawBytes()`]: #v8_serializer_writerawbytes_buffer
559+
[`v8.stopCoverage()`]: #v8_v8_stopcoverage
548560
[`vm.Script`]: vm.md#vm_new_vm_script_code_options
549561
[worker threads]: worker_threads.md

‎lib/v8.js

+1
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ module.exports = {
279279
DefaultDeserializer,
280280
deserialize,
281281
takeCoverage: profiler.takeCoverage,
282+
stopCoverage: profiler.stopCoverage,
282283
serialize,
283284
writeHeapSnapshot,
284285
};

‎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,
@@ -505,6 +509,21 @@ static void TakeCoverage(const FunctionCallbackInfo<Value>& args) {
505509
}
506510
}
507511

512+
static void StopCoverage(const FunctionCallbackInfo<Value>& args) {
513+
Environment* env = Environment::GetCurrent(args);
514+
V8CoverageConnection* connection = env->coverage_connection();
515+
516+
Debug(env,
517+
DebugCategory::INSPECTOR_PROFILER,
518+
"StopCoverage, connection %s nullptr\n",
519+
connection == nullptr ? "==" : "!=");
520+
521+
if (connection != nullptr) {
522+
Debug(env, DebugCategory::INSPECTOR_PROFILER, "Stopping coverage\n");
523+
connection->StopCoverage();
524+
}
525+
}
526+
508527
static void Initialize(Local<Object> target,
509528
Local<Value> unused,
510529
Local<Context> context,
@@ -513,6 +532,7 @@ static void Initialize(Local<Object> target,
513532
env->SetMethod(target, "setCoverageDirectory", SetCoverageDirectory);
514533
env->SetMethod(target, "setSourceMapCacheGetter", SetSourceMapCacheGetter);
515534
env->SetMethod(target, "takeCoverage", TakeCoverage);
535+
env->SetMethod(target, "stopCoverage", StopCoverage);
516536
}
517537

518538
} // 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)
Please sign in to comment.