Summary
Add $262.gc() to the bundled $262.js host hooks file, delegating to Goccia.gc() which calls TGarbageCollector.Instance.Collect. This unblocks 28 test262 tests that require host-gc-required. However, a pre-existing GC access violation must be fixed first — the collector crashes when triggered inside traditional for loops with repeated var allocations.
Why
28 test262 tests call $262.gc(). The wiring is trivial (Goccia.gc() is already available in the bare loader), but the GC bug causes access violations under certain allocation patterns, so landing the hook without the fix would turn honest FAILs into SIGSEGV infrastructure failures.
Current behavior
./build.pas loaderbare
cat > /tmp/gc_loop.js <<'JS'
for (var u = 0; u < 3; ++u) {
var y = [];
Object.create(y);
Goccia.gc();
y.t = 3;
Goccia.gc();
}
print("done");
JS
./build/GocciaScriptLoaderBare /tmp/gc_loop.js --asi --compat-all
# Error: Access violation
Simple GC calls outside loops work fine:
printf 'var x = {}; x = null; Goccia.gc(); print("ok");\n' | ./build/GocciaScriptLoaderBare --asi --compat-all
# ok
Expected behavior
Both cases should complete without crashing. $262.gc() should trigger a full collection cycle.
Scope notes
Two pieces of work:
-
Wire $262.gc — one-line addition to scripts/test262_harness/$262.js: gc() { Goccia.gc(); }. Trivial once the GC bug is fixed.
-
Fix GC access violation — the crash happens when Collect runs inside a traditional for loop with var redeclarations and Object.create. Likely a mark-sweep issue where objects allocated in the loop body are collected while still reachable from the loop scope. The GC itself is in source/units/Goccia.GarbageCollector.pas:496 (Collect); the crash is in the sweep phase. This is the blocking prerequisite.
Reproduction from test262: staging/sm/regress/regress-596103.js (the simplest test that triggers it).
Summary
Add
$262.gc()to the bundled$262.jshost hooks file, delegating toGoccia.gc()which callsTGarbageCollector.Instance.Collect. This unblocks 28 test262 tests that requirehost-gc-required. However, a pre-existing GC access violation must be fixed first — the collector crashes when triggered inside traditional for loops with repeatedvarallocations.Why
28 test262 tests call
$262.gc(). The wiring is trivial (Goccia.gc()is already available in the bare loader), but the GC bug causes access violations under certain allocation patterns, so landing the hook without the fix would turn honest FAILs into SIGSEGV infrastructure failures.Current behavior
Simple GC calls outside loops work fine:
Expected behavior
Both cases should complete without crashing.
$262.gc()should trigger a full collection cycle.Scope notes
Two pieces of work:
Wire
$262.gc— one-line addition toscripts/test262_harness/$262.js:gc() { Goccia.gc(); }. Trivial once the GC bug is fixed.Fix GC access violation — the crash happens when
Collectruns inside a traditional for loop withvarredeclarations andObject.create. Likely a mark-sweep issue where objects allocated in the loop body are collected while still reachable from the loop scope. The GC itself is insource/units/Goccia.GarbageCollector.pas:496(Collect); the crash is in the sweep phase. This is the blocking prerequisite.Reproduction from test262:
staging/sm/regress/regress-596103.js(the simplest test that triggers it).