Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
5318870
Add copied-minor fallback evidence gates
andrewtdiz May 19, 2026
1fb3b6d
Add malloc object-kind allocation and retention telemetry
andrewtdiz May 20, 2026
a28ad73
Introduce old-generation page side metadata
andrewtdiz May 20, 2026
6c09378
Centralize heap child scanning through layout descriptors
andrewtdiz May 20, 2026
baeb0f7
Replace remaining copy-only root scanners with mutable visitors
andrewtdiz May 20, 2026
a10d7b7
Add explicit runtime handles for allocation-sensitive helpers
andrewtdiz May 20, 2026
76b3a8d
Make conservative scanning a debug or runtime-only fallback path
andrewtdiz May 20, 2026
ef6b06c
Populate old-page live and fragmentation accounting during GC
andrewtdiz May 20, 2026
48fd690
Route large or external-backed objects away from the copying nursery
andrewtdiz May 20, 2026
e995c29
Drive old-gen evacuation from page metadata
andrewtdiz May 20, 2026
9c3bf61
Move small and medium strings into GC-managed pages
andrewtdiz May 20, 2026
235648b
Move ordinary closures into GC-managed pages
andrewtdiz May 20, 2026
0ecec61
Make packed numeric arrays pointer-free for tracing
andrewtdiz May 20, 2026
6311f93
Attach stable shape pointer masks to typed object layouts
andrewtdiz May 20, 2026
715f7ef
Prototype raw numeric fields for one stable object shape
andrewtdiz May 20, 2026
b95ac6a
Add target-collector architecture gates to the stress matrix
andrewtdiz May 20, 2026
5f11dfb
Bring JSON churn memory stability back under the RSS gate
andrewtdiz May 20, 2026
d285ffc
Replace hard-coded GC type ranges with explicit type metadata
andrewtdiz May 20, 2026
ad18558
Preserve old-page accounting across copied-minor fast paths
andrewtdiz May 20, 2026
bff2752
Separate old-page accounting from actual reusable or returned memory
andrewtdiz May 20, 2026
9334002
Convert extension copy-only root scanners to mutable visitors
andrewtdiz May 20, 2026
95784de
Fail representative fallback evidence on known bad reasons
andrewtdiz May 20, 2026
756a1c7
Make target-collector workload gates validate results, not only labels
andrewtdiz May 20, 2026
b01f300
Add typed-shape and unboxed codegen checks to architecture gates
andrewtdiz May 20, 2026
371b479
Prove managed string and closure migration at workload level
andrewtdiz May 20, 2026
08c2821
Persist machine-readable GC evidence from verification runs
andrewtdiz May 20, 2026
e02085d
Convert remaining first-party extension copy-only root scanners to mu…
andrewtdiz May 20, 2026
953ae81
Make perry-ext-net copied-minor root rewrite verification stable
andrewtdiz May 20, 2026
e702239
Fix codegen test options after rebase
andrewtdiz May 20, 2026
e19442c
Add correctness gates to the benchmark matrix before trusting speed o…
andrewtdiz May 20, 2026
167cf3b
Remove per-push handle overhead from the array push fast path
andrewtdiz May 20, 2026
bc56b7a
Prove JSON roundtrip is correct and not retaining transient churn in …
andrewtdiz May 20, 2026
ca443b2
Split GC runtime by responsibility
andrewtdiz May 21, 2026
0326de1
Finalize GC checkpoint evidence cleanup
andrewtdiz May 21, 2026
1543782
Fix Linux GC module split compile
andrewtdiz May 21, 2026
6294f51
Fix Fastify mutable root scanner migration
andrewtdiz May 21, 2026
922fbfa
Write GC evidence to runner temp
andrewtdiz May 21, 2026
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
56 changes: 50 additions & 6 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,17 @@ jobs:
| tee .bench-results/output.txt

# Capture status for the summary job
if grep -q "REGRESSION" .bench-results/output.txt; then
if python3 - <<'PY'
import json
cur = json.load(open(".bench-results/current.json"))
raise SystemExit(0 if any(
entry.get("correctness", {}).get("status") == "fail"
for entry in cur.get("benchmarks", {}).values()
) else 1)
PY
then
echo "status=invalid" >> "$GITHUB_OUTPUT"
elif grep -q "REGRESSION" .bench-results/output.txt; then
echo "status=regression" >> "$GITHUB_OUTPUT"
elif grep -q "improvement" .bench-results/output.txt; then
echo "status=improved" >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -112,26 +122,60 @@ jobs:
print(f"- Current commit: `{cur.get('commit','?')}`")
print(f"- Runner: macos-14 / median of 3 runs")
print()
print("| Benchmark | Perry (ms) | Node (ms) | Ratio | Perry RAM (KB) | Node RAM (KB) | Δ Speed | Δ RAM |")
print("|-----------|-----------:|----------:|------:|---------------:|--------------:|--------:|------:|")
def md(value):
return str(value).replace("|", "\\|")

def evidence(correctness):
status = correctness.get("status", "unchecked")
if status == "fail":
parts = []
expected = correctness.get("expected_lines") or []
actual = correctness.get("actual_lines") or []
if expected:
parts.append("expected " + ", ".join(f"`{md(line)}`" for line in expected))
if actual:
parts.append("actual " + ", ".join(f"`{md(line)}`" for line in actual))
reason = correctness.get("reason")
if reason:
parts.append(md(reason))
return "<br>".join(parts)
lines = correctness.get("expected_lines") or correctness.get("actual_lines") or []
if lines:
return "<br>".join(f"`{md(line)}`" for line in lines)
return md(correctness.get("reason", ""))

print("| Benchmark | Correctness | Evidence | Perry (ms) | Node (ms) | Ratio | Perry RAM (KB) | Node RAM (KB) | Δ Speed | Δ RAM |")
print("|-----------|-------------|----------|-----------:|----------:|------:|---------------:|--------------:|--------:|------:|")
for name, c in cur["benchmarks"].items():
b = base.get("benchmarks", {}).get(name, {})
p_ms = c.get("perry_ms")
n_ms = c.get("node_ms", "-")
p_rss = c.get("perry_rss_kb", 0)
n_rss = c.get("node_rss_kb", 0)
ratio = c.get("speed_ratio", "-")
correctness = c.get("correctness", {
"status": "unchecked",
"reference": "none",
"actual_lines": [],
"expected_lines": [],
"reason": "no correctness report",
})
correctness_status = correctness.get("status", "unchecked")
correctness_evidence = evidence(correctness)
d_speed = "-"
d_ram = "-"
if b.get("perry_ms") and p_ms is not None and b["perry_ms"] > 0:
if correctness_status == "fail":
d_speed = "invalid"
d_ram = "invalid"
elif b.get("perry_ms") and p_ms is not None and b["perry_ms"] > 0:
pct = (p_ms - b["perry_ms"]) / b["perry_ms"] * 100
emoji = "🔴" if pct > 20 else ("🟡" if pct > 10 else ("🟢" if pct < -10 else ""))
d_speed = f"{emoji} {pct:+.1f}%"
if b.get("perry_rss_kb") and p_rss and b["perry_rss_kb"] > 0:
if correctness_status != "fail" and b.get("perry_rss_kb") and p_rss and b["perry_rss_kb"] > 0:
pct = (p_rss - b["perry_rss_kb"]) / b["perry_rss_kb"] * 100
emoji = "🔴" if pct > 30 else ("🟡" if pct > 15 else ("🟢" if pct < -15 else ""))
d_ram = f"{emoji} {pct:+.1f}%"
print(f"| `{name}` | {p_ms} | {n_ms} | {ratio} | {p_rss} | {n_rss} | {d_speed} | {d_ram} |")
print(f"| `{name}` | {correctness_status} | {correctness_evidence} | {p_ms} | {n_ms} | {ratio} | {p_rss} | {n_rss} | {d_speed} | {d_ram} |")
PY

- name: Upload benchmark results
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -655,8 +655,18 @@ jobs:
# availability + RSS reporting differs on Windows runners.
- name: Memory stability tests
if: runner.os == 'Linux' || runner.os == 'macOS'
env:
PERRY_GC_EVIDENCE_DIR: ${{ runner.temp }}/gc-evidence
run: ./scripts/run_memory_stability_tests.sh

- name: Upload GC evidence artifacts
if: always()
uses: actions/upload-artifact@v7
with:
name: gc-evidence-${{ runner.os }}
path: ${{ runner.temp }}/gc-evidence
if-no-files-found: ignore

# ---------------------------------------------------------------------------
# HarmonyOS ArkUI codegen smoke (Phase 2 v9).
#
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ tests/test-*
!tests/test-*.ts
!tests/test_*.sh
!tests/test-*.sh
!tests/test_copied_minor_fallback_report.py
!tests/*/
bench_*
!bench_*.ts
Expand Down
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading