@sproutboat/toolchain 0.4.14 → 0.4.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/package.json +1 -1
- package/src/acquire.test.ts +2 -1
- package/src/patch.test.ts +7 -0
- package/src/patch.ts +19 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @sproutboat/toolchain
|
|
2
2
|
|
|
3
|
+
## 0.4.15
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c9f84ac: Raise Porffor's per-coroutine fiber stack from 256 KiB to 8 MiB. A large async handler compiled at -O0 (`sproutboat dev`) overflowed it within a few nested awaits and died with SIGBUS on its first request (baronunread/sproutboat#178). Only touched pages cost memory.
|
|
8
|
+
|
|
3
9
|
## 0.4.14
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/package.json
CHANGED
package/src/acquire.test.ts
CHANGED
|
@@ -27,7 +27,8 @@ async function fixture(): Promise<{ archive: string; sha256: string }> {
|
|
|
27
27
|
" return 0;\n" +
|
|
28
28
|
" }\n" +
|
|
29
29
|
" return -1;\n" +
|
|
30
|
-
"}\n"
|
|
30
|
+
"}\n" +
|
|
31
|
+
"#define PORF_CORO_STACK_SIZE (256u * 1024u)\n",
|
|
31
32
|
"compiler/index.js": " ...darwinReleaseCompileArgs,\n uSocketsArchive,\n '-lm'\n",
|
|
32
33
|
"compiler/precompile.js":
|
|
33
34
|
"const fs = require('node:fs');\n" +
|
package/src/patch.test.ts
CHANGED
|
@@ -35,6 +35,9 @@ int porf_native_fetch_read_value(jsval value, const char** out_buf, size_t* out_
|
|
|
35
35
|
|
|
36
36
|
return -1;
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
#define PORF_CORO_STACK_SIZE (256u * 1024u)
|
|
40
|
+
#define PORF_CORO_MAX 16384
|
|
38
41
|
`;
|
|
39
42
|
|
|
40
43
|
// Porffor's compiler/uwebsockets.js, trimmed to the parts the patch touches:
|
|
@@ -289,6 +292,10 @@ test("#165: render.js routes console output to stderr, unbuffered, idempotently"
|
|
|
289
292
|
"int porf_native_fetch_read_value(jsval value, const char** out_buf, size_t* out_len, char** out_owned) {",
|
|
290
293
|
);
|
|
291
294
|
|
|
295
|
+
// #178: fiber stacks big enough for -O0 frames in a few nested awaits.
|
|
296
|
+
expect(once).toContain("#define PORF_CORO_STACK_SIZE (8u * 1024u * 1024u)");
|
|
297
|
+
expect(once).not.toContain("(256u * 1024u)");
|
|
298
|
+
|
|
292
299
|
await patchRenderJs(root);
|
|
293
300
|
expect(await readFile(join(root, "compiler/render.js"), "utf8")).toBe(once);
|
|
294
301
|
} finally {
|
package/src/patch.ts
CHANGED
|
@@ -131,6 +131,24 @@ const READ_RAW_INJECT =
|
|
|
131
131
|
READ_RAW_ANCHOR;
|
|
132
132
|
const READ_RAW_MARKER = "porf_native_fetch_read_raw_bytes(jsval value";
|
|
133
133
|
|
|
134
|
+
/**
|
|
135
|
+
* baronunread/sproutboat#178: every async function runs on its own fiber
|
|
136
|
+
* stack, and alpha-10 fixes those at 256 KiB. A large handler compiled at -O0
|
|
137
|
+
* (what `sproutboat dev` builds) spends ~40 KiB of stack per call into the
|
|
138
|
+
* biggest generated functions, so a few nested awaits run off the end into
|
|
139
|
+
* the guard page and the sprout dies with SIGBUS on its first request, no log.
|
|
140
|
+
* -O3 frames are smaller, which only raises the threshold: a deep enough
|
|
141
|
+
* async chain hits it in a release build too.
|
|
142
|
+
*
|
|
143
|
+
* Match a thread's usual 8 MiB. The reservation is MAP_NORESERVE with a guard
|
|
144
|
+
* page, so only touched pages cost memory and a shallow handler pays nothing.
|
|
145
|
+
*/
|
|
146
|
+
const CORO_STACK_ANCHOR = "#define PORF_CORO_STACK_SIZE (256u * 1024u)";
|
|
147
|
+
const CORO_STACK_INJECT =
|
|
148
|
+
"// sproutboat #178: 256 KiB overflows -O0 frames in a few nested awaits.\n" +
|
|
149
|
+
"#define PORF_CORO_STACK_SIZE (8u * 1024u * 1024u)";
|
|
150
|
+
const CORO_STACK_MARKER = "sproutboat #178";
|
|
151
|
+
|
|
134
152
|
/**
|
|
135
153
|
* render.js full-block replacements: `[marker, anchor, inject, what]`, each a
|
|
136
154
|
* complete swap of the matched region (unlike `RENDER_EDITS`, which only ever
|
|
@@ -139,6 +157,7 @@ const READ_RAW_MARKER = "porf_native_fetch_read_raw_bytes(jsval value";
|
|
|
139
157
|
const RENDER_REPLACEMENTS = [
|
|
140
158
|
[BYTESTRING_MARKER, BYTESTRING_ANCHOR, BYTESTRING_INJECT, "bytestring UTF-8 encoding (#172)"],
|
|
141
159
|
[READ_RAW_MARKER, READ_RAW_ANCHOR, READ_RAW_INJECT, "raw bytestring passthrough function (#176)"],
|
|
160
|
+
[CORO_STACK_MARKER, CORO_STACK_ANCHOR, CORO_STACK_INJECT, "coroutine stack size (#178)"],
|
|
142
161
|
] as const;
|
|
143
162
|
|
|
144
163
|
// #15 — no `--port` flag: Porffor's native-fetch entry point calls
|