Skip to content

Commit 592a494

Browse files
addaleaxcodebytere
authored andcommitted
worker: reset Isolate stack limit after entering Locker
It turns out that using `v8::Locker` undoes the effects of passing an explicit stack limit as part of the `Isolate`’s resource constraints. Therefore, reset the stack limit manually after entering a Locker. Refs: #26049 (comment) PR-URL: #31593 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Rich Trott <[email protected]>
1 parent 76991fb commit 592a494

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

src/node_worker.cc

+3
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ class WorkerThreadData {
159159
{
160160
Locker locker(isolate);
161161
Isolate::Scope isolate_scope(isolate);
162+
// V8 computes its stack limit the first time a `Locker` is used based on
163+
// --stack-size. Reset it to the correct value.
164+
isolate->SetStackLimit(w->stack_base_);
162165

163166
HandleScope handle_scope(isolate);
164167
isolate_data_.reset(CreateIsolateData(isolate,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const { once } = require('events');
5+
const v8 = require('v8');
6+
const { Worker } = require('worker_threads');
7+
8+
// Verify that Workers don't care about --stack-size, as they have their own
9+
// fixed and known stack sizes.
10+
11+
async function runWorker() {
12+
const empiricalStackDepth = new Uint32Array(new SharedArrayBuffer(4));
13+
const worker = new Worker(`
14+
const { workerData: { empiricalStackDepth } } = require('worker_threads');
15+
function f() {
16+
empiricalStackDepth[0]++;
17+
f();
18+
}
19+
f();`, {
20+
eval: true,
21+
workerData: { empiricalStackDepth }
22+
});
23+
24+
const [ error ] = await once(worker, 'error');
25+
26+
common.expectsError({
27+
constructor: RangeError,
28+
message: 'Maximum call stack size exceeded'
29+
})(error);
30+
31+
return empiricalStackDepth[0];
32+
}
33+
34+
(async function() {
35+
v8.setFlagsFromString('--stack-size=500');
36+
const w1stack = await runWorker();
37+
v8.setFlagsFromString('--stack-size=1000');
38+
const w2stack = await runWorker();
39+
// Make sure the two stack sizes are within 10 % of each other, i.e. not
40+
// affected by the different `--stack-size` settings.
41+
assert(Math.max(w1stack, w2stack) / Math.min(w1stack, w2stack) < 1.1,
42+
`w1stack = ${w1stack}, w2stack ${w2stack} are too far apart`);
43+
})().then(common.mustCall());

0 commit comments

Comments
 (0)