Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions doc/api/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -464,10 +464,12 @@ no-op, and the directory is not created if it is missing.

### Limitations of the compile cache

Currently when using the compile cache with [V8 JavaScript code coverage][], the
coverage being collected by V8 may be less precise in functions that are
deserialized from the code cache. It's recommended to turn this off when
running tests to generate precise coverage.
V8 cannot collect block-level [V8 JavaScript code coverage][] for functions that
are deserialized from the code cache. The compile cache is therefore disabled
when coverage collection starts with the process, through
[`NODE_V8_COVERAGE=dir`][] or [`--experimental-test-coverage`][]. Coverage that
is started later, for example through the inspector, may be less precise in
functions that were already deserialized from the code cache.

Compilation cache generated by one version of Node.js can not be reused by a different
version of Node.js. Cache generated by different versions of Node.js will be stored
Expand Down Expand Up @@ -525,7 +527,8 @@ The following constants are returned as the `status` field in the object returne
<td><code>DISABLED</code></td>
<td>
Node.js cannot enable the compile cache because the environment variable
<code>NODE_DISABLE_COMPILE_CACHE=1</code> has been set.
<code>NODE_DISABLE_COMPILE_CACHE=1</code> has been set, or because V8
coverage is being collected.
</td>
</tr>
</table>
Expand Down Expand Up @@ -2111,6 +2114,7 @@ returned object contains the following keys:
[V8 code cache]: https://v8.dev/blog/code-caching-for-devs
[`"exports"`]: packages.md#exports
[`--enable-source-maps`]: cli.md#--enable-source-maps
[`--experimental-test-coverage`]: cli.md#--experimental-test-coverage
[`--import`]: cli.md#--importmodule
[`--require`]: cli.md#-r---require-module
[`NODE_COMPILE_CACHE=dir`]: cli.md#node_compile_cachedir
Expand Down
2 changes: 1 addition & 1 deletion src/compile_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct CompileCacheEntry {
V(FAILED) /* Failed to enable the cache */ \
V(ENABLED) /* Was not enabled before, and now enabled. */ \
V(ALREADY_ENABLED) /* Was already enabled. */ \
V(DISABLED) /* Has been disabled by NODE_DISABLE_COMPILE_CACHE. */
V(DISABLED) /* Disabled by the environment or by V8 coverage. */

enum class CompileCacheEnableStatus : uint8_t {
#define V(status) status,
Expand Down
10 changes: 9 additions & 1 deletion src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1398,8 +1398,16 @@ CompileCacheEnableResult Environment::EnableCompileCache(
std::string disable_env;
if (credentials::SafeGetenv(
"NODE_DISABLE_COMPILE_CACHE", &disable_env, this)) {
result.status = CompileCacheEnableStatus::DISABLED;
result.message = "Disabled by NODE_DISABLE_COMPILE_CACHE";
}
#if HAVE_INSPECTOR
// V8 cannot collect block coverage for functions deserialized from the cache.
if (result.message.empty() && coverage_connection() != nullptr) {
result.message = "Disabled because V8 coverage is being collected";
}
#endif // HAVE_INSPECTOR
if (!result.message.empty()) {
result.status = CompileCacheEnableStatus::DISABLED;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No strong feelings, but setting message and status together like the code did before makes sense to me semantically

Debug(this,
DebugCategory::COMPILE_CACHE,
"[compile cache] %s.\n",
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-api-env.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const fixtures = require('../common/fixtures');
const tmpdir = require('../common/tmpdir');
const fs = require('fs');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

{
// Test that it works with non-existent directory.
tmpdir.refresh();
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-api-flush.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const assert = require('assert');
const tmpdir = require('../common/tmpdir');
const fixtures = require('../common/fixtures');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

{
// Test that it works with non-existent directory.
tmpdir.refresh();
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-api-options-portable-env.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const tmpdir = require('../common/tmpdir');
const fs = require('fs');
const path = require('path');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

const wrapper = fixtures.path('compile-cache-wrapper-options.js');
tmpdir.refresh();

Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-api-portable.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const tmpdir = require('../common/tmpdir');
const path = require('path');
const fixtures = require('../common/fixtures');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

tmpdir.refresh();
const workDir = path.join(tmpdir.path, 'work');
const cacheRel = '.compile_cache_dir';
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-api-readonly.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const path = require('path');
const tmpdir = require('../common/tmpdir');
const fixtures = require('../common/fixtures');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

tmpdir.refresh();
const wrapper = fixtures.path('compile-cache-wrapper-options.js');
const target = path.join(tmpdir.path, 'target.js');
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-api-success.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const tmpdir = require('../common/tmpdir');
const fs = require('fs');
const path = require('path');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

{
// Test that it works with non-existent directory.
tmpdir.refresh();
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-api-tmpdir.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const tmpdir = require('../common/tmpdir');
const fs = require('fs');
const path = require('path');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

{
// Test that it works with non-existent directory.
tmpdir.refresh();
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-bad-syntax.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const assert = require('assert');
const fs = require('fs');
const path = require('path');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

{
// Test that it throws if the script fails to parse, and no cache is created.
tmpdir.refresh();
Expand Down
45 changes: 45 additions & 0 deletions test/parallel/test-compile-cache-coverage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use strict';

const common = require('../common');
common.skipIfInspectorDisabled();

const { spawnSyncAndAssert } = require('../common/child_process');
const assert = require('assert');
const fixtures = require('../common/fixtures');
const fs = require('fs');
const tmpdir = require('../common/tmpdir');

tmpdir.refresh();
const cacheDir = tmpdir.resolve('compile_cache');
const env = {
...process.env,
NODE_DEBUG_NATIVE: 'COMPILE_CACHE',
NODE_V8_COVERAGE: tmpdir.resolve('coverage'),
};

spawnSyncAndAssert(
process.execPath,
[fixtures.path('empty.js')],
{ env: { ...env, NODE_COMPILE_CACHE: cacheDir }, cwd: tmpdir.path },
{ stderr: /Disabled because V8 coverage is being collected/ });
assert(!fs.existsSync(cacheDir));

spawnSyncAndAssert(
process.execPath,
['-r', fixtures.path('compile-cache-wrapper.js'), fixtures.path('empty.js')],
{
env: {
...env,
NODE_COMPILE_CACHE: undefined,
NODE_TEST_COMPILE_CACHE_DIR: cacheDir,
},
cwd: tmpdir.path,
},
{
stdout(output) {
assert.match(output, /Compile cache already disabled/);
assert.match(output, /dir after enableCompileCache: undefined/);
},
stderr: /Disabled because V8 coverage is being collected/,
});
assert(!fs.existsSync(cacheDir));
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-dynamic-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const assert = require('assert');
const tmpdir = require('../common/tmpdir');
const fixtures = require('../common/fixtures');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

{
tmpdir.refresh();
const dir = tmpdir.resolve('.compile_cache_dir');
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const assert = require('assert');
const tmpdir = require('../common/tmpdir');
const fixtures = require('../common/fixtures');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

{
tmpdir.refresh();
const dir = tmpdir.resolve('.compile_cache_dir');
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-existing-directory.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ const fs = require('fs');
const fixtures = require('../common/fixtures');
const tmpdir = require('../common/tmpdir');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

{
tmpdir.refresh();
const dir = tmpdir.resolve('.compile_cache_dir');
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-portable-esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ const tmpdir = require('../common/tmpdir');
const fs = require('fs');
const path = require('path');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

tmpdir.refresh();

const workDir = path.join(tmpdir.path, 'work');
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-portable.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const fs = require('fs');
const tmpdir = require('../common/tmpdir');
const path = require('path');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

tmpdir.refresh();
const workDir = path.join(tmpdir.path, 'work');
const cacheRel = '.compile_cache_dir';
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-success.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const tmpdir = require('../common/tmpdir');
const fs = require('fs');
const path = require('path');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

{
// Test that it works with non-existent directory.
tmpdir.refresh();
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-typescript-commonjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const assert = require('assert');
const tmpdir = require('../common/tmpdir');
const fixtures = require('../common/fixtures');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

// Check cache for .ts files that would be run as CommonJS.
{
tmpdir.refresh();
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-typescript-esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ const assert = require('assert');
const tmpdir = require('../common/tmpdir');
const fixtures = require('../common/fixtures');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

// Check cache for .ts files that would be run as ESM.
{
tmpdir.refresh();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ const assert = require('assert');
const tmpdir = require('../common/tmpdir');
const fixtures = require('../common/fixtures');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

tmpdir.refresh();
const dir = tmpdir.resolve('.compile_cache_dir');
const script = fixtures.path('typescript', 'ts', 'test-typescript.ts');
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-updated-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const assert = require('assert');
const fs = require('fs');
const tmpdir = require('../common/tmpdir');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

{
tmpdir.refresh();
const dir = tmpdir.resolve('.compile_cache_dir');
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-compile-cache-wasm.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const assert = require('assert');
const tmpdir = require('../common/tmpdir');
const fixtures = require('../common/fixtures');

// The compile cache is disabled while V8 coverage is being collected.
process.env.NODE_V8_COVERAGE = '';

const script = fixtures.path('es-modules', 'test-wasm-js-string-builtins.mjs');

// V8 only serializes optimized code, so a complete cache requires eager
Expand Down
Loading