Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
675b744
(feat): compile-time warning for container dot-access escape
mgyoo86 Mar 26, 2026
12c3dc5
(improve): add dims and size info to wrapper mutation warnings
mgyoo86 Mar 26, 2026
704426a
(fix): skip invalidated wrappers in mutation check (false positive)
mgyoo86 Mar 26, 2026
7620196
(improve): structured container escape warning matching PoolEscapeErr…
mgyoo86 Mar 26, 2026
5b6689b
(improve): use printstyled for container escape warning (colored output)
mgyoo86 Mar 26, 2026
42f3385
(improve): numbered entries, softer tone for container escape warning
mgyoo86 Mar 26, 2026
660e5a7
(improve): add Preferences.jl one-liner to container escape warning
mgyoo86 Mar 26, 2026
e20e65e
(improve): add restart note to RUNTIME_CHECK instruction
mgyoo86 Mar 26, 2026
ca38d1b
(fix): order-aware compile-time escape detection + reassignment warning
mgyoo86 Mar 26, 2026
8ad55cc
(fix): scope-aware recursion in escape detector — prevent false posit…
mgyoo86 Mar 26, 2026
bc0ea9e
(improve): address code review — remove dead code, add tests, improve…
mgyoo86 Mar 26, 2026
d068b66
(improve): pluralize "Escaping return(s):" in reassignment warning
mgyoo86 Mar 26, 2026
0e2ca1e
(fix): order-aware container taint tracking — prevent false positive …
mgyoo86 Mar 26, 2026
345e5b5
(fix): distinguish stale wrappers from legitimately zero-sized arrays
mgyoo86 Mar 26, 2026
585cdd9
Revert "(fix): distinguish stale wrappers from legitimately zero-size…
mgyoo86 Mar 26, 2026
f02ae4e
(fix): address copilot review — let scope, safe functions, dedup helper
mgyoo86 Mar 26, 2026
1f30e9f
(chore): update Runic workflow to include paths and permissions for p…
mgyoo86 Mar 26, 2026
c881807
Update src/macros.jl
mgyoo86 Mar 26, 2026
f80e969
(refactor): update safety checks for copy calls — remove Array/Vector…
mgyoo86 Mar 26, 2026
62fe02e
(test): add positive test for PoolContainerEscapeWarning — cover warn…
mgyoo86 Mar 26, 2026
afff7f3
(fix): add missing container/reassignment warnings to backend block form
mgyoo86 Mar 27, 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
16 changes: 16 additions & 0 deletions .github/workflows/Runic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ on:
push:
branches: [master]
pull_request:
paths:
- "**/*.jl"
- ".github/workflows/Runic.yml"

permissions:
contents: read
pull-requests: write

jobs:
runic:
name: Runic
Expand All @@ -13,3 +21,11 @@ jobs:
with:
version: "1"
- uses: fredrikekre/runic-action@v1
with:
format_files: true
continue-on-error: ${{ github.event_name == 'pull_request' }}
- uses: reviewdog/action-suggester@v1
if: github.event_name == 'pull_request'
with:
tool_name: Runic
fail_level: error
23 changes: 14 additions & 9 deletions src/debug.jl
Original file line number Diff line number Diff line change
Expand Up @@ -447,26 +447,31 @@ _check_wrapper_mutation!(::AbstractTypedPool, ::Int, ::Int) = nothing
wrapper === nothing && continue
wrapper::Array # safety: ensure wrapper is Array before ccall (TypeError vs segfault)

# Skip already-invalidated wrappers (dims zeroed by previous rewind).
# When a slot is reused with a different dimensionality, the old wrapper
# retains a stale MemoryRef — checking it would be a false positive.
_wrapper_prod_size(wrapper) == 0 && continue

# Check 1: Data pointer identity — detects reallocation from resize!/push! beyond capacity
# ccall avoids boxing MemoryRef when wrapper's Array type is erased (from Vector{Any})
wrapper_ptr = ccall(:jl_array_ptr, Ptr{Cvoid}, (Any,), wrapper)
if wrapper_ptr != vec_ptr
@warn "Pool-backed Array{$T}: resize!/push! caused memory reallocation " *
"(slot $i). Pooling benefits (zero-alloc reuse) may be lost; " *
"temporary extra memory retention may occur. " *
"Consider requesting the exact size via acquire!(pool, T, n) if known in advance." maxlog = 1
dims = getfield(wrapper, :size)
@warn "Pool-backed Array{$T,$N_idx} wrapper reallocation detected" *
" (slot $i, $(N_idx)D $(dims), backing vec length $vec_len)." *
" resize!/push! changed the wrapper's backing memory." *
" Pooling benefits (zero-alloc reuse) may be lost." maxlog = 1
return
end
# Check 2: wrapper length exceeds backing vector — detects growth beyond backing
# Function barrier avoids NTuple{N,Int} boxing from prod(getfield(:size))
# (length() is not used because it may not reflect setfield!(:size) on Julia 1.11)
wrapper_len = _wrapper_prod_size(wrapper)
if wrapper_len > vec_len
@warn "Pool-backed Array{$T}: wrapper grew beyond backing vector " *
"(slot $i, wrapper: $wrapper_len, backing: $vec_len). " *
"Pooling benefits (zero-alloc reuse) may be lost; " *
"temporary extra memory retention may occur. " *
"Consider requesting the exact size via acquire!(pool, T, n) if known in advance." maxlog = 1
dims = getfield(wrapper, :size)
@warn "Pool-backed Array{$T,$N_idx} wrapper grew beyond backing" *
" (slot $i, $(N_idx)D $(dims) = $wrapper_len elements, backing vec length $vec_len)." *
" Pooling benefits (zero-alloc reuse) may be lost." maxlog = 1
return
end
end
Expand Down
Loading
Loading