Commit Graph
4722 Commits
Author SHA1 Message Date
Chris Tate 9336188d16 Merge perf/shape-overlay-cost 2026-10-26 12:40:45 -05:00
Chris Tate 53896238c4 Regenerate the IR field readers and fix the shard tests 2026-10-26 12:18:56 -05:00
Chris Tate 06f7b8631f Merge perf/shape-overlay-cost 2026-10-26 11:53:34 -05:00
Chris Tate d163df4674 Merge perf/shape-table-dispatch 2026-10-26 11:18:17 -05:00
Chris Tate 6622ae4e22 Merge perf/static-objects 2026-10-26 11:10:12 -05:00
Chris Tate 37131030ff Merge perf/shape-overlay-core 2026-10-26 11:01:59 -05:00
Chris Tate d5dc896576 Merge main 2026-10-26 10:53:46 -05:00
Chris Tate 26b2fdcc67 Read IR nodes' fields by name in three llvm-emit passes (#2336) 2026-10-26 10:17:48 -05:00
Chris Tate 1947bf66c7 Release a substitution's operands when it returns (#2337) 2026-10-26 10:17:28 -05:00
Chris Tate b1614d6e75 Release a substitution's operands when it returns
The temps a regex replace or replaceAll consumed (the subject that a
previous substitution in a chain produced, a computed replacement) were
released at the end of the statement. A chain of substitutions over a
large string therefore held every intermediate result until the last one
returned. The operands now live in a frame of their own that is released
right after the call, so a chain holds at most its current subject and
result.
2026-10-26 08:30:42 -05:00
Chris Tate f9b5533ee6 Read IR nodes' fields by name in three llvm-emit passes 2026-10-26 08:13:15 -05:00
Chris Tate f1298287d6 Resolve each shipped declaration path once
isFallbackDtsPath runs for every type lowering maps (isStdlibFile), and
since the fallback declarations moved into per-module files (#2256) it
asked declarationPath for the fallback module directory each time. Without
an installed declaration root, each answer resolved
@scriptc/compiler/scriptc-node-fallback.d.ts through Node's module
resolver. Lowering three.js's buffers-animation fixture went from 6.3 s to
43 s. declarationPath now keeps its answers by name until the declaration
root changes.
2026-10-26 07:58:58 -05:00
Chris Tate 7e6327740b Merge perf/static-objects 2026-10-26 07:53:16 -05:00
Chris Tate 52a228d0f5 Keep declarations a removed branch shares with another 2026-10-26 07:50:59 -05:00
Chris Tate 641f779fa3 Store identical runtime artifacts once and strip the copied CLI executables (#2301) 2026-10-26 07:06:31 -05:00
Chris Tate b221a13369 Reuse the completion callback a stream passes to its option callbacks (#2323) 2026-10-26 07:00:49 -05:00
Chris Tate de17158254 Merge main 2026-10-26 06:51:26 -05:00
Chris Tate 636c7631b3 Keep program partitions local to the code an edit changes (#2328) 2026-10-26 06:35:05 -05:00
Chris Tate 067f146e87 Read builtin globals through the global object, and support Node's navigator (#2242) 2026-10-26 06:16:08 -05:00
Chris Tate a758ff1b4e Select sanitized runtime variants by unit, and skip stripping without llvm-strip
The native sanitizer build chose the variants to compile by artifact path.
Since the runtime pack stores identical objects once, two variants of a
unit can share a path, so it compiled such a unit for both variants and
linked it twice (duplicate symbols in the sanitized native bootstrap).
selectedRuntimeUnits now returns each selected unit with its variant;
selectRuntimePackArtifacts and the sanitizer both use it.

Staging the native CLI's assets ran llvm-strip unconditionally and failed
on hosts without it. Without llvm-strip on PATH, tsc-ts now keeps its
symbols and the build prints a warning; the release hosts install LLVM.
2026-10-26 06:02:01 -05:00
Chris Tate 7ae99f63bc Give stream option callbacks Node's callback identities
Node passes a stream's one onwrite function to every _write and _writev
call, and a new function to every _transform call. A write or writev
option callback now receives the same closure on every call
(scr_stream_write_closure), kept or not, so a Set, WeakSet or WeakMap
finds it again. A reused transform, flush, final, construct or destroy
callback is first forgotten by weak collections, as at its free, so a
WeakSet or WeakMap that recorded the previous call's callback does not
find it on the next call.
2026-10-26 05:52:57 -05:00
Chris Tate e559baacde Skip repeated probes in lowering (#2330) 2026-10-26 05:47:59 -05:00
Chris Tate a684543b58 Merge perf/shape-overlay-core 2026-10-26 05:42:45 -05:00
Chris Tate 66b6ca53ce Load a Node module's fallback declarations only when the program names it (#2256) 2026-10-26 05:37:36 -05:00
Chris Tate b8aaa5985a Merge main 2026-10-26 05:23:00 -05:00
Chris Tate addecf6a02 Skip repeated probes in lowering 2026-10-26 05:17:10 -05:00
Chris Tate 2d2343e36f Keep program partitions local to the code an edit changes 2026-10-26 05:03:24 -05:00
Chris Tate 4553941d84 Merge main 2026-10-26 04:25:15 -05:00
Chris Tate ddf5b1f8e0 Keep the integers of typed-array reads in locals for indices and loop guards
A local that only holds exact integers or NaN, such as one assigned from
an integer typed-array read, now keeps whether it is NaN beside its
integer view. Its reads, and sums, differences and products of them,
carry an i64 that holds the integer whenever the number is not NaN, so
an index check or a counted loop's guard tests that integer and the
ordered bit instead of converting the double back and checking that it
is an exact integer.
2026-10-26 04:08:25 -05:00
Chris Tate 2ad699c98a Compile classes that extend Array (#2059) 2026-10-26 03:57:16 -05:00
Chris Tate ae3d388869 Merge main 2026-10-26 03:53:02 -05:00
Chris Tate e289b03ddc Keep int32 fields in programs with adopting casts (#2324) 2026-10-26 03:27:40 -05:00
Chris Tate 0ba138b57e Merge main 2026-10-26 03:25:54 -05:00
Chris Tate eec525dc6a Fix eight compiler and type bug reports (#2319) 2026-10-26 03:10:55 -05:00
Chris Tate 6c1ddbf390 Keep int32 fields in programs with adopting casts 2026-10-26 02:57:52 -05:00
Chris Tate acf19e2652 Merge main 2026-10-26 02:53:26 -05:00
Chris Tate 7a8ec3f3d2 Hold locals and module globals whose declared type does not compile as checked dynamic slots (#2292) 2026-10-26 02:49:06 -05:00
Chris Tate ca3217fe99 Reuse the completion callback a stream passes to its option callbacks
Each call of a typed or untyped write, writev, transform, flush, final,
construct or destroy option callback allocated a closure and a box holding
the stream for its `callback` argument. The emitted thunks now take it
from scr_stream_done_closure, which keeps the last one on the stream state and
hands it out again while the stream holds its only reference and it has
no own properties. A callback the user kept (stored, or passed to
setImmediate or a promise) is not reused: the next call gets a new
closure, and the kept one keeps its own stream reference.

The cached closure holds the stream, so the stream drops it when it
emits 'close' and traces it, which lets the cycle collector reclaim a
stream dropped before it closes.

RUNTIME_ABI_VERSION goes from 46 to 47 for scr_stream_done_closure.
2026-10-26 02:48:03 -05:00
Chris Tate 7183a76422 Address review: missing strings in bindings and calls, evaluated recursive flags
- A string held in a binding or returned by a call can be a missing element
  read (undefined), so `head + PAD[j]` and `at(i) + PAD[j]` still add to NaN
  when both are missing. Only string literals, templates and sums with such
  an operand now count as always a string.
- `readdirSync(path, { recursive })` folds only the `true` and `false`
  keywords. Any other flag expression, including one typed as a literal,
  evaluates at run time for its effects and exceptions.
2026-10-26 02:42:04 -05:00
Chris Tate f52806988d Read typed-array header fields once at a speculative loop's entry (#2321) 2026-10-26 02:33:23 -05:00
Chris Tate 3512b288ad Order the native compiler's cold functions by how many builds run them (#2320) 2026-10-26 02:33:05 -05:00
Chris Tate 035d618517 Store a table entry for if/else chains that store literals to one element (#2317) 2026-10-26 02:21:51 -05:00
Chris Tate eaa8a44cdf Read typed-array header fields once at a speculative loop's entry
A speculative integer loop's fast copy exits to a copy that resumes the
failed iteration, and both read the header fields of the views they
access. GVN's load PRE moved the fast copy's read of a view's data
pointer ahead of the exit branch, to make the resume copy's read
redundant, and put a copy on the exit edge. The loop then kept its first
iteration in the loop, so the overflow checks of a value whose range is
known after one iteration stayed in every iteration, with a reload of the
data pointer.

A view held by a const local or a parameter that the loop does not rebind
is the same view in every iteration, and its length, data pointer and
shared storage never change. The loop's entry now reads them once, and the
element accesses of every copy use those values.
2026-10-26 02:02:46 -05:00
Chris Tate 71de76b813 Order the native compiler's cold functions by how many builds run them 2026-10-26 02:02:18 -05:00
Chris Tate 055d1f9682 Fix eight compiler and type bug reports
Co-authored-by: dolphin278 <1130473+dolphin278@users.noreply.github.com>
Fixes #2139
Fixes #2131
Fixes #2132
Fixes #2133
Fixes #2140
Fixes #2141
Fixes #2159
2026-10-26 01:50:59 -05:00
Chris Tate 5d62d5a5f1 Read a constant choice's index as on every path when it is the compared local
The store a constant choice emits for its arms used the first arm's
index expression, with the ranges proven inside that arm. When the index
is the compared local, `j === 0` narrows it to [0, 0] there, so the one
store, which also runs on the final else's path, converted the index to
an int32 from that range. For `j` = 4294967297 that conversion has no
defined result, and the bounds check that follows could accept it: an
out-of-bounds write could reach a valid element.

The store now reads such an index through the first comparison's
operand: the same local, read before the chain branches, so its range
holds on every path. An index that is another local is not narrowed by
the comparisons and is unchanged.
2026-10-26 01:47:16 -05:00
Chris Tate 70eac263f7 Merge lf/l1-whole-slot 2026-10-26 01:43:44 -05:00
Chris Tate a28afa0261 Find bridgePlainUnwindCalls' calls and mentions with indexOf (#2316) 2026-10-26 01:08:35 -05:00
Chris Tate 33be2a80ee Store a table entry for if/else chains that store literals to one element
An if/else-if chain that compares one number local with integer literals
and stores a number literal to the same typed-array element in every arm,
including a final else, such as

    if (x === 97) a[i] = 0;
    else if (x === 116) a[i] = 1;
    else if (x === 99) a[i] = 2;
    else a[i] = 3;

is now emitted as one store of an entry of a constant table indexed by
the local's value (constant-choices.ts). On input whose cases do not
repeat in a pattern, such as the bases of a DNA sequence, the branches
mispredict; LLVM keeps them, because cases this far apart are too sparse
for its own switch tables.

The chain needs at least three distinct values within 256 of each other.
The table covers the cases' span, or the local's proven integer range
when that range has at most 256 values, in which case no test is
emitted. Otherwise a value that is not an exact integer in the table's
span (NaN, a fraction, or a value outside it) stores the final else's
literal, chosen with a select. The first arm wins for a repeated
value, and -0 selects the arm for 0, as strict equality does. The store
is the arms' own (the same receiver and index), converted to the
element's type as each arm's would be. Debug builds keep the arms.

k-nucleotide's transform of the input sequence uses this form: its
median wall time drops from 2.71 s to 2.21 s.
2026-10-26 01:04:42 -05:00
Chris Tate 2a0d115629 Keep a candidate's generation when a limited cycle pass reaches it (#2315) 2026-10-26 00:55:26 -05:00