Skip to content

Commit 53beee0

Browse files
committed
Replace the runtime allocator
The old pool can't return freed memory to the operating system, reuse a cross-thread free, or re-carve memory from one size class for another. The arena does all three. Design: #5735
1 parent 89d5910 commit 53beee0

83 files changed

Lines changed: 9843 additions & 1608 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.ci-scripts/freebsd-valgrind-smoke.sh

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
# invoked from .github/workflows/ponyc-tier3.yml. POSIX sh, not bash: FreeBSD's
44
# base system has no bash. Expects to run from the ponyc source root.
55
#
6-
# use=valgrind annotates the Pony runtime so Valgrind can understand its custom
7-
# allocator. FreeBSD ships a modern Valgrind port, so this is the one BSD where
8-
# running a Pony program under Valgrind actually works — unlike DragonFly, whose
9-
# Valgrind 3.15 is too old and hangs on the runtime's memory arena
10-
# (https://github.com/ponylang/ponyc/issues/5435). This smoke guards two things:
11-
# 1. use=valgrind still builds — `cmake --build` compiles the annotated runtime
12-
# into ponyc; a build that can't compile or link is caught here.
6+
# use=valgrind annotates the classic pool so Valgrind can understand its
7+
# custom allocation; the arena allocator (the default) carries no
8+
# annotations and rejects the combination, so the smoke builds
9+
# pool_classic,valgrind. FreeBSD ships a modern Valgrind port, so this is the
10+
# one BSD where running a Pony program under Valgrind actually works — unlike
11+
# DragonFly, whose Valgrind 3.15 is too old and hangs on the runtime's memory
12+
# arena (https://github.com/ponylang/ponyc/issues/5435). This smoke guards two
13+
# things:
14+
# 1. the combination still builds — `cmake --build` compiles the annotated
15+
# runtime into ponyc; a build that can't compile or link is caught here.
1316
# 2. a Pony program compiled with it runs to completion *under Valgrind*
1417
# without hanging — the DragonFly failure mode.
1518
# It deliberately does NOT assert that Memcheck comes back clean: Pony's custom
@@ -26,16 +29,16 @@ set -eu
2629
# leave their own). This script is self-contained: it rebuilds from scratch, so
2730
# it can run as its own CI step regardless of what came before.
2831
rm -rf build/build_debug
29-
cmake --preset debug -DPONY_USES=valgrind
32+
cmake --preset debug -DPONY_USES=pool_classic,valgrind
3033
# The `cmake --build` below is itself the first assertion: it compiles ponyc with
3134
# the Valgrind-annotated runtime. A use=valgrind build that can't compile or
3235
# link fails here, at build time.
3336
cmake --build --preset debug
3437

35-
# use=valgrind sets PONY_OUTPUT_SUFFIX to -valgrind, so the build output lands in
36-
# build/debug-valgrind. Derive it rather than hardcoding (the suffix is
37-
# CMake-determined and could grow more segments in a combined build).
38-
out=$(find build -maxdepth 1 -type d -name 'debug-valgrind' | head -1)
38+
# The use options set PONY_OUTPUT_SUFFIX, so the build output lands in
39+
# build/debug-valgrind-pool_classic. Derive it rather than hardcoding (the
40+
# suffix order is CMake-determined and could grow more segments).
41+
out=$(find build -maxdepth 1 -type d -name 'debug-valgrind*' | head -1)
3942
if [ -z "$out" ] || [ ! -x "$out/ponyc" ]; then
4043
echo "FAIL: valgrind build output directory not found"
4144
exit 1

.ci-scripts/systematic-testing/determinism_smoke.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
build/libs:
1515
1616
1. Builds a systematic-testing ponyc
17-
(`use=scheduler_scaling_pthreads,systematic_testing`). The build itself is
17+
(`use=systematic_testing`). The build itself is
1818
the first assertion -- it is the only thing in CI that compiles that code
1919
path.
2020
2. Compiles the test/rt-systematic fixtures with it. Each folds the message
@@ -133,11 +133,11 @@
133133
("test/rt-systematic/cycle-collection-order-signature",
134134
"cycle-collection-order-signature", ["--ponycdinterval", "10"]),
135135
]
136-
# The output suffix order (scheduler_scaling_pthreads then systematic_testing)
137-
# comes from the block order of the PONY_USE_* `if()`s in the top-level
138-
# CMakeLists.txt, NOT from the order passed to `use=`. If those blocks are
139-
# reordered this path goes stale; the os.access check below then fails loudly.
140-
PONYC_REL = "build/debug-scheduler_scaling_pthreads-systematic_testing/ponyc"
136+
# The output suffix comes from the PONY_USE_* `if()` block in the
137+
# top-level CMakeLists.txt, not from the order passed to `use=`. If that
138+
# block is renamed this path goes stale; the os.access check below then
139+
# fails loudly.
140+
PONYC_REL = "build/debug-systematic_testing/ponyc"
141141

142142

143143
def parse_order_sig(output):
@@ -175,7 +175,7 @@ def build_systematic_ponyc(root):
175175
# self-consistent, and staying on the native preset keeps the script usable
176176
# as-is if the job grows to other architectures.
177177
if run(["cmake", "--preset", "debug",
178-
"-DPONY_USES=scheduler_scaling_pthreads,systematic_testing"],
178+
"-DPONY_USES=systematic_testing"],
179179
cwd=root).returncode != 0:
180180
fail("`cmake --preset debug` for the systematic-testing build failed")
181181
if run(["cmake", "--build", "--preset", "debug"],

.ci-scripts/test-debugger.sh

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
# is on the list even though the runtime sets it to SIG_IGN: a debugger stops on
1616
# an ignored signal too, seeing it before the process's disposition applies.
1717
#
18-
# SIGTERM is on the list for a different reason: nothing in the runtime raises
19-
# it, the tests do. CI exports PONY_TEST_DEBUGGER and runs `ctest -L ci-core`,
20-
# which puts both the stdlib suite and every full-program test under the
21-
# debugger. A test that raises a signal missing from these lists does not fail
22-
# outright — the debugger stops on the first delivery and exits, killing the
23-
# whole leg — so a test that raises a new signal must add it here.
18+
# SIGTERM and SIGUSR2 are on the list for a different reason: nothing in the
19+
# runtime raises them, the tests do. CI exports PONY_TEST_DEBUGGER and runs
20+
# `ctest -L ci-core`, which puts both the stdlib suite and every full-program
21+
# test under the debugger. A test that raises a signal missing from these
22+
# lists does not fail outright — the debugger stops on the first delivery and
23+
# exits, killing the whole leg — so a test that raises a new signal must add
24+
# it here.
2425
#
2526
# The Windows counterpart, test-debugger.ps1, forwards no signals: Windows
2627
# raise() calls the handler directly instead of raising an OS signal the

.github/workflows/build-release-image.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ jobs:
217217
path: 'stdlib-docs/site/'
218218
- name: Deploy to GitHub Pages
219219
id: deployment
220-
uses: actions/deploy-pages@v5
220+
uses: actions/deploy-pages@v4
221221

222222
trigger-release-announcement:
223223
needs:

.github/workflows/changelog-bot.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
name: Update CHANGELOG.md
2121
steps:
2222
- name: Update Changelog
23-
uses: docker://ghcr.io/ponylang/changelog-bot-action:0.3.10
23+
uses: docker://ghcr.io/ponylang/changelog-bot-action:0.3.9
2424
with:
2525
GIT_USER_NAME: "Ponylang Main Bot"
2626
GIT_USER_EMAIL: "ponylang.main@gmail.com"

.github/workflows/generate-documentation.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ jobs:
3535
path: 'stdlib-docs/site/'
3636
- name: Deploy to GitHub Pages
3737
id: deployment
38-
uses: actions/deploy-pages@v5
38+
uses: actions/deploy-pages@v4

.github/workflows/ponyc-tier3.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ jobs:
387387
set -e
388388
cd /build/ponyc
389389
df -h
390+
export PONY_FULL_PROGRAM_TIMEOUT=120
390391
cmake --preset debug
391392
cmake --build --preset debug
392393
cmake --build --preset debug --target pony-doc-tests pony-lint-tests pony-lsp-tests

.github/workflows/ponyc-weekly-checks.yml

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ jobs:
6060
directives: pool_memalign
6161
- image: ghcr.io/ponylang/ponyc-ci-ubuntu26.04-builder:20260425
6262
debugger: lldb
63-
directives: pool_retain
63+
directives: pool_classic
64+
- image: ghcr.io/ponylang/ponyc-ci-ubuntu26.04-builder:20260425
65+
debugger: lldb
66+
directives: pool_classic,pool_retain
6467
- image: ghcr.io/ponylang/ponyc-ci-ubuntu26.04-builder:20260425
6568
debugger: lldb
6669
directives: runtimestats
@@ -130,10 +133,8 @@ jobs:
130133
# the Linux directive checks pass -- the slower Windows runner isn't spent on a
131134
# directive that's already broken on Linux. That dependency also carries the
132135
# no-changes gate for free: when there are no changes use_directives is skipped,
133-
# which skips this job too, so it needs no check-for-changes `if` of its own. The
134-
# matrix has one entry today (runtime_tracing, the only use= option with
135-
# Windows-specific runtime code); add rows as more Windows-supported options
136-
# become worth checking here.
136+
# which skips this job too, so it needs no check-for-changes `if` of its own. Add
137+
# rows as more Windows-supported options become worth checking here.
137138
use_directives_windows:
138139
needs: use_directives
139140
runs-on: windows-2025-vs2026
@@ -148,6 +149,10 @@ jobs:
148149
# runtime_tracing's format specifiers for the runtimestats-gated fields
149150
# only compile in this combined build, so cover it explicitly.
150151
- directives: runtime_tracing,runtimestats
152+
# Windows defaults to the arena allocator, so this row builds the
153+
# classic pool there, as PonyUses.cmake requires for every entry in
154+
# its Windows allowlist.
155+
- directives: pool_classic
151156
name: 'use ${{ matrix.directives }} (Windows)'
152157
steps:
153158
- name: Checkout
@@ -288,6 +293,61 @@ jobs:
288293
topic: ${{ github.repository }} scheduled job failure
289294
content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed.
290295

296+
always_assert:
297+
needs: check-for-changes
298+
if: needs.check-for-changes.outputs.has-changes == 'true'
299+
runs-on: ubuntu-latest
300+
301+
# Builds the runtime optimized (release) with its asserts and the arena
302+
# allocator's integrity checks kept in, via -DPONY_ALWAYS_ASSERT=ON. A plain
303+
# release compiles those checks out; the debug suites run them but
304+
# unoptimized. This is the only lane that runs them against optimized code,
305+
# where the compiler can expose ordering or undefined behavior the checks
306+
# then catch.
307+
strategy:
308+
fail-fast: false
309+
matrix:
310+
include:
311+
- image: ghcr.io/ponylang/ponyc-ci-ubuntu26.04-builder:20260425
312+
debugger: lldb
313+
314+
name: release with always-assert
315+
container:
316+
image: ${{ matrix.image }}
317+
options: --user pony --cap-add=SYS_PTRACE --security-opt seccomp=unconfined
318+
steps:
319+
- name: Checkout
320+
uses: actions/checkout@v6.0.2
321+
with:
322+
ref: ${{ inputs.ref || github.sha }}
323+
- name: Build libs
324+
env:
325+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
326+
LIBS_IMAGE: ${{ matrix.image }}
327+
LIBS_TAG: ${{ hashFiles('lib/CMakePresets.json', 'CMakeLists.txt', 'lib/CMakeLists.txt', 'lib/build-libs.cmake', 'lib/llvm/patches/*') }}
328+
run: python3 .ci-scripts/libs-cache/resolve_libs_cache.py --branch-cache --image "$LIBS_IMAGE" --tag "$LIBS_TAG" -- cmake -DJOBS=4 -P lib/build-libs.cmake
329+
- name: Build Release Runtime with always-assert
330+
run: |
331+
cmake --preset x86-64-release -DPONY_ALWAYS_ASSERT=ON
332+
cmake --build --preset x86-64-release
333+
- name: Test with Release Runtime
334+
run: |
335+
PONY_TEST_DEBUGGER="$(.ci-scripts/test-debugger.sh ${{ matrix.debugger }})"
336+
export PONY_TEST_DEBUGGER
337+
export PONY_FULL_PROGRAM_TIMEOUT=120
338+
ctest --preset x86-64-release -L ci-core
339+
- name: Send alert on failure
340+
if: ${{ failure() }}
341+
uses: zulip/github-actions-zulip/send-message@bd8ec52de371d139ae8313661b7d8318c19266aa
342+
with:
343+
api-key: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_API_KEY }}
344+
email: ${{ secrets.ZULIP_SCHEDULED_JOB_FAILURE_EMAIL }}
345+
organization-url: 'https://ponylang.zulipchat.com/'
346+
to: notifications
347+
type: stream
348+
topic: ${{ github.repository }} scheduled job failure
349+
content: ${{ github.server_url}}/${{ github.repository }}/actions/runs/${{ github.run_id }} failed.
350+
291351
with_sanitizers:
292352
needs: check-for-changes
293353
if: needs.check-for-changes.outputs.has-changes == 'true'

.github/workflows/release-notes.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
name: Update release notes
2222
steps:
2323
- name: Update
24-
uses: docker://ghcr.io/ponylang/release-notes-bot-action:0.3.13
24+
uses: docker://ghcr.io/ponylang/release-notes-bot-action:0.3.12
2525
with:
2626
GIT_USER_NAME: "Ponylang Main Bot"
2727
GIT_USER_EMAIL: "ponylang.main@gmail.com"

.github/workflows/stress-test-generative-systematic-linux.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@ jobs:
5656
- name: Build Debug Systematic Runtime
5757
if: ${{ hashFiles('.libs-cache-miss') == '' }}
5858
run: |
59-
cmake --preset debug -DPONY_USES=scheduler_scaling_pthreads,systematic_testing
59+
cmake --preset debug -DPONY_USES=systematic_testing
6060
cmake --build --preset debug
6161
- name: Run Generative Stress Test
6262
if: ${{ hashFiles('.libs-cache-miss') == '' }}
6363
run: |
6464
python3 test/rt-stress/generative/orchestrate_systematic.py \
65-
--ponyc build/debug-scheduler_scaling_pthreads-systematic_testing/ponyc \
66-
--use-flags scheduler_scaling_pthreads,systematic_testing \
65+
--ponyc build/debug-systematic_testing/ponyc \
66+
--use-flags systematic_testing \
6767
--start ${{ github.run_id }} --count 250 \
6868
--out rt-stress-out
6969
# cancelled() too: keep bundles from seeds that ran before a cancel.

0 commit comments

Comments
 (0)