Skip to content

Commit 22134ca

Browse files
authored
Adding support for MMTk (non-moving immix) (#56288)
This PR adds the possibility of building/running Julia using MMTk, running non-moving immix. The binding code (Rust) associated with it is in https://github.com/mmtk/mmtk-julia/tree/upstream-ready/immix. Instructions on how to build/run Julia with MMTk are described in the [`README`](https://github.com/mmtk/mmtk-julia/tree/upstream-ready/immix?tab=readme-ov-file#an-mmtk-binding-for-the-julia-programming-language) file inside the binding repo.
1 parent 0d6bd8c commit 22134ca

27 files changed

+1751
-210
lines changed

Make.inc

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ HAVE_SSP := 0
8080
WITH_GC_VERIFY := 0
8181
WITH_GC_DEBUG_ENV := 0
8282

83+
# Use stock if MMTK_PLAN hasn't been defined
84+
MMTK_PLAN ?= None
85+
8386
# Enable DTrace support
8487
WITH_DTRACE := 0
8588

@@ -833,6 +836,31 @@ JCXXFLAGS += -DGC_DEBUG_ENV
833836
JCFLAGS += -DGC_DEBUG_ENV
834837
endif
835838

839+
ifneq (${MMTK_PLAN},None)
840+
JCXXFLAGS += -DMMTK_GC
841+
JCFLAGS += -DMMTK_GC
842+
# Do a release build on the binding by default
843+
MMTK_BUILD ?= release
844+
ifeq (${MMTK_PLAN},Immix)
845+
JCXXFLAGS += -DMMTK_PLAN_IMMIX
846+
JCFLAGS += -DMMTK_PLAN_IMMIX
847+
else
848+
$(error "Unsupported MMTk plan: $(MMTK_PLAN)")
849+
endif
850+
851+
# Location of mmtk-julia binding
852+
# (needed for api/*.h and .so file)
853+
MMTK_JULIA_DIR ?= $(BUILDROOT)/usr/lib/mmtk_julia
854+
855+
MMTK_DIR = ${MMTK_JULIA_DIR}/mmtk
856+
MMTK_API_INC = ${MMTK_DIR}/api
857+
858+
MMTK_LIB := -lmmtk_julia
859+
else
860+
MMTK_JULIA_INC :=
861+
MMTK_LIB :=
862+
endif
863+
836864
ifeq ($(WITH_DTRACE), 1)
837865
JCXXFLAGS += -DUSE_DTRACE
838866
JCFLAGS += -DUSE_DTRACE
@@ -933,6 +961,21 @@ ARCH := $(BUILD_OS)
933961
endif
934962
endif
935963

964+
# MMTk is only available on x86_64 Linux for now
965+
ifneq (${MMTK_PLAN},None)
966+
967+
ifeq ($(OS),Linux)
968+
MMTK_LIB_NAME := libmmtk_julia.so
969+
else
970+
$(error "Unsupported OS for MMTk")
971+
endif
972+
973+
ifneq ($(ARCH),x86_64)
974+
$(error "Unsupported build architecture for MMTk")
975+
endif
976+
977+
endif
978+
936979
# Detect common pre-SSE2 JULIA_CPU_TARGET values known not to work (#7185)
937980
ifeq ($(MARCH),)
938981
ifneq ($(findstring $(ARCH),i386 i486 i586 i686),)

base/timing.jl

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,14 @@ function gc_page_utilization_data()
106106
return Base.unsafe_wrap(Array, page_utilization_raw, JL_GC_N_MAX_POOLS, own=false)
107107
end
108108

109+
110+
const USING_STOCK_GC = occursin("stock", unsafe_string(ccall(:jl_gc_active_impl, Ptr{UInt8}, ())))
111+
# Full sweep reasons are currently only available for the stock GC
112+
@static if USING_STOCK_GC
109113
# must be kept in sync with `src/gc-stock.h``
110114
const FULL_SWEEP_REASONS = [:FULL_SWEEP_REASON_SWEEP_ALWAYS_FULL, :FULL_SWEEP_REASON_FORCED_FULL_SWEEP,
111115
:FULL_SWEEP_REASON_USER_MAX_EXCEEDED, :FULL_SWEEP_REASON_LARGE_PROMOTION_RATE]
116+
end
112117

113118
"""
114119
Base.full_sweep_reasons()
@@ -124,11 +129,15 @@ The reasons are:
124129
Note that the set of reasons is not guaranteed to be stable across minor versions of Julia.
125130
"""
126131
function full_sweep_reasons()
127-
reason = cglobal(:jl_full_sweep_reasons, UInt64)
128-
reasons_as_array = Base.unsafe_wrap(Vector{UInt64}, reason, length(FULL_SWEEP_REASONS), own=false)
129132
d = Dict{Symbol, Int64}()
130-
for (i, r) in enumerate(FULL_SWEEP_REASONS)
131-
d[r] = reasons_as_array[i]
133+
# populate the dictionary according to the reasons above for the stock GC
134+
# otherwise return an empty dictionary for now
135+
@static if USING_STOCK_GC
136+
reason = cglobal(:jl_full_sweep_reasons, UInt64)
137+
reasons_as_array = Base.unsafe_wrap(Vector{UInt64}, reason, length(FULL_SWEEP_REASONS), own=false)
138+
for (i, r) in enumerate(FULL_SWEEP_REASONS)
139+
d[r] = reasons_as_array[i]
140+
end
132141
end
133142
return d
134143
end

deps/Makefile

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ BUILDDIR := $(BUILDDIR)$(MAYBE_HOST)
2626
# custom Makefile rules: openlibm dsfmt libsuitesparse lapack blastrampoline openblas utf8proc objconv libwhich
2727
# CMake libs: llvm llvmunwind libgit2 libssh2 libtracyclient
2828
#
29-
# downloadable via git: llvm-svn, libuv, libopenlibm, utf8proc, libgit2, libssh2, libtracyclient
29+
# downloadable via git: llvm-svn, libuv, libopenlibm, utf8proc, libgit2, libssh2, libtracyclient, mmtk_julia
3030
#
3131
# to debug 'define' rules, replace eval at the usage site with info or error
3232

@@ -195,14 +195,18 @@ DEP_LIBS += libwhich
195195
endif
196196
endif
197197

198+
ifneq (${MMTK_PLAN},None)
199+
DEP_LIBS += mmtk_julia
200+
endif
201+
198202
DEP_LIBS_STAGED := $(DEP_LIBS)
199203

200204
# list all targets
201205
DEP_LIBS_STAGED_ALL := llvm llvm-tools clang llvmunwind unwind libuv pcre \
202206
openlibm dsfmt blastrampoline openblas lapack gmp mpfr patchelf utf8proc \
203207
objconv openssl libssh2 nghttp2 curl libgit2 libwhich zlib p7zip csl \
204208
sanitizers libsuitesparse lld libtracyclient ittapi nvtx JuliaSyntax \
205-
terminfo
209+
terminfo mmtk_julia
206210
DEP_LIBS_ALL := $(DEP_LIBS_STAGED_ALL)
207211

208212
ifneq ($(USE_BINARYBUILDER_OPENBLAS),0)
@@ -266,6 +270,9 @@ include $(SRCDIR)/p7zip.mk
266270
include $(SRCDIR)/libtracyclient.mk
267271
include $(SRCDIR)/terminfo.mk
268272

273+
# MMTk
274+
include $(SRCDIR)/mmtk_julia.mk
275+
269276
# vendored Julia libs
270277
include $(SRCDIR)/JuliaSyntax.mk
271278

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1911cf084d26c48e2ed58af3d268b4b6
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
75beab54398989c46b62e714b242cf6705d88d220f40c21e494e0f29161437f5fbe9ba05b543d2353a1ad76f4239ac4025b476be0be864649f310f14935289fe

deps/mmtk_julia.mk

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
## MMTK ##
2+
3+
# Both MMTK_MOVING and MMTK_PLAN should be specified in the Make.user file.
4+
# At this point, since we only support non-moving this is always set to 0
5+
# FIXME: change it to `?:` when introducing moving plans
6+
MMTK_MOVING := 0
7+
MMTK_VARS := MMTK_PLAN=$(MMTK_PLAN) MMTK_MOVING=$(MMTK_MOVING)
8+
9+
# Download the binding, build it from source
10+
ifeq (${MMTK_JULIA_DIR},$(BUILDROOT)/usr/lib/mmtk_julia)
11+
$(eval $(call git-external,mmtk_julia,MMTK_JULIA,,,$(BUILDDIR)))
12+
13+
MMTK_JULIA_DIR=$(BUILDROOT)/deps/$(BUILDDIR)/$(MMTK_JULIA_SRC_DIR)
14+
MMTK_JULIA_LIB_PATH=$(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD)
15+
PROJECT_DIRS := JULIA_PATH=$(JULIAHOME) JULIA_BUILDROOT=$(BUILDROOT) MMTK_JULIA_DIR=$(MMTK_JULIA_DIR)
16+
17+
$(BUILDDIR)/$(MMTK_JULIA_SRC_DIR)/build-compiled: $(BUILDROOT)/usr/lib/libmmtk_julia.so
18+
@echo 1 > $@
19+
20+
# NB: use the absolute dir when creating the symlink
21+
$(BUILDROOT)/usr/lib/libmmtk_julia.so: $(MMTK_JULIA_LIB_PATH)/libmmtk_julia.so
22+
@ln -sf $(MMTK_JULIA_LIB_PATH)/libmmtk_julia.so $@
23+
24+
$(MMTK_JULIA_LIB_PATH)/libmmtk_julia.so: $(BUILDDIR)/$(MMTK_JULIA_SRC_DIR)/source-extracted
25+
@$(PROJECT_DIRS) $(MMTK_VARS) $(MAKE) -C $(MMTK_JULIA_DIR) $(MMTK_BUILD)
26+
27+
get-mmtk_julia: $(MMTK_JULIA_SRC_FILE)
28+
extract-mmtk_julia: $(BUILDDIR)/$(MMTK_JULIA_SRC_DIR)/source-extracted
29+
configure-mmtk_julia: extract-mmtk_julia
30+
compile-mmtk_julia: $(BUILDROOT)/usr/lib/libmmtk_julia.so
31+
fastcheck-mmtk_julia: #none
32+
check-mmtk_julia: compile-mmtk_julia
33+
34+
$(eval $(call symlink_install,mmtk_julia,$$(MMTK_JULIA_SRC_DIR),$$(BUILDROOT)/usr/lib))
35+
36+
# In this case, there is a custom version of the binding in MMTK_JULIA_DIR
37+
# Build it and symlink libmmtk_julia.so file into $(BUILDROOT)/usr/lib
38+
else
39+
40+
PROJECT_DIRS := JULIA_PATH=$(JULIAHOME) JULIA_BUILDROOT=$(BUILDROOT) MMTK_JULIA_DIR=$(MMTK_JULIA_DIR)
41+
MMTK_JULIA_LIB_PATH=$(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD)
42+
43+
install-mmtk_julia: compile-mmtk_julia $(build_prefix)/manifest/mmtk_julia
44+
45+
compile-mmtk_julia: $(BUILDROOT)/usr/lib/libmmtk_julia.so
46+
47+
version-check-mmtk_julia: $(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD)/libmmtk_julia.so
48+
49+
# NB: This will NOT run `cargo build` if there are changes in the Rust source files
50+
# inside the binding repo. However the target below should remake the symlink if there
51+
# are changes in the libmmtk_julia.so from the custom MMTK_JULIA_DIR folder
52+
$(BUILDROOT)/usr/lib/libmmtk_julia.so: $(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD)/libmmtk_julia.so
53+
@ln -sf $(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD)/libmmtk_julia.so $@
54+
55+
$(MMTK_JULIA_DIR)/mmtk/target/$(MMTK_BUILD)/libmmtk_julia.so:
56+
@$(PROJECT_DIRS) $(MMTK_VARS) $(MAKE) -C $(MMTK_JULIA_DIR) $(MMTK_BUILD)
57+
58+
MMTK_JULIA_VER := mmtk_julia_custom
59+
60+
UNINSTALL_mmtk_julia := $(MMTK_JULIA_VER) manual_mmtk_julia
61+
62+
define manual_mmtk_julia
63+
uninstall-mmtk_julia:
64+
-rm -f $(build_prefix)/manifest/mmtk_julia
65+
-rm -f $(BUILDROOT)/usr/lib/libmmtk_julia.so
66+
endef
67+
68+
$(build_prefix)/manifest/mmtk_julia: $(BUILDROOT)/usr/lib/libmmtk_julia.so
69+
@echo $(UNINSTALL_mmtk_julia) > $@
70+
71+
endif # MMTK_JULIA_DIR

deps/mmtk_julia.version

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
MMTK_JULIA_BRANCH = master
2+
MMTK_JULIA_SHA1 = b69acf5af7a7dd97c1cc6fd99f7c2d51b477f214
3+
MMTK_JULIA_GIT_URL := https://github.com/mmtk/mmtk-julia.git
4+
MMTK_JULIA_TAR_URL = https://github.com/mmtk/mmtk-julia/archive/refs/tags/v0.30.2.tar.gz

src/Makefile

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ ifeq ($(USECLANG),1)
2929
FLAGS += -Wno-return-type-c-linkage -Wno-atomic-alignment
3030
endif
3131

32+
ifneq (${MMTK_PLAN},None)
33+
FLAGS += -I$(MMTK_API_INC)
34+
endif
35+
3236
FLAGS += -DJL_BUILD_ARCH='"$(ARCH)"'
3337
ifeq ($(OS),WINNT)
3438
FLAGS += -DJL_BUILD_UNAME='"NT"'
@@ -40,23 +44,41 @@ ifeq ($(OS),FreeBSD)
4044
FLAGS += -I$(LOCALBASE)/include
4145
endif
4246

47+
# GC source code. It depends on which GC implementation to use.
48+
GC_SRCS := gc-common gc-stacks gc-alloc-profiler gc-heap-snapshot
49+
ifneq (${MMTK_PLAN},None)
50+
GC_SRCS += gc-mmtk
51+
else
52+
GC_SRCS += gc-stock gc-debug gc-pages gc-page-profiler
53+
endif
54+
4355
SRCS := \
4456
jltypes gf typemap smallintset ast builtins module interpreter symbol \
4557
dlload sys init task array genericmemory staticdata toplevel jl_uv datatype \
4658
simplevector runtime_intrinsics precompile jloptions mtarraylist \
47-
threading scheduler stackwalk gc-common gc-stock gc-debug gc-pages gc-stacks gc-alloc-profiler gc-page-profiler method \
48-
jlapi signal-handling safepoint timing subtype rtutils gc-heap-snapshot \
49-
crc32c APInt-C processor ircode opaque_closure codegen-stubs coverage runtime_ccall engine
59+
threading scheduler stackwalk \
60+
method jlapi signal-handling safepoint timing subtype rtutils \
61+
crc32c APInt-C processor ircode opaque_closure codegen-stubs coverage runtime_ccall engine \
62+
$(GC_SRCS)
5063

5164
RT_LLVMLINK :=
5265
CG_LLVMLINK :=
5366

5467
ifeq ($(JULIACODEGEN),LLVM)
68+
# Currently these files are used by both GCs. But we should make the list specific to stock, and MMTk should have its own implementation.
69+
GC_CODEGEN_SRCS := llvm-final-gc-lowering llvm-late-gc-lowering llvm-gc-invariant-verifier
70+
ifneq (${MMTK_PLAN},None)
71+
FLAGS += -I$(MMTK_API_INC)
72+
GC_CODEGEN_SRCS += llvm-late-gc-lowering-mmtk
73+
else
74+
GC_CODEGEN_SRCS += llvm-late-gc-lowering-stock
75+
endif
5576
CODEGEN_SRCS := codegen jitlayers aotcompile debuginfo disasm llvm-simdloop \
56-
llvm-final-gc-lowering llvm-pass-helpers llvm-late-gc-lowering llvm-ptls \
57-
llvm-lower-handlers llvm-gc-invariant-verifier llvm-propagate-addrspaces \
77+
llvm-pass-helpers llvm-ptls \
78+
llvm-lower-handlers llvm-propagate-addrspaces \
5879
llvm-multiversioning llvm-alloc-opt llvm-alloc-helpers cgmemmgr llvm-remove-addrspaces \
59-
llvm-remove-ni llvm-julia-licm llvm-demote-float16 llvm-cpufeatures pipeline llvm_api
80+
llvm-remove-ni llvm-julia-licm llvm-demote-float16 llvm-cpufeatures pipeline llvm_api \
81+
$(GC_CODEGEN_SRCS)
6082
FLAGS += -I$(shell $(LLVM_CONFIG_HOST) --includedir)
6183
CG_LLVM_LIBS := all
6284
ifeq ($(USE_POLLY),1)
@@ -99,7 +121,12 @@ ifeq ($(USE_SYSTEM_LIBUV),0)
99121
UV_HEADERS += uv.h
100122
UV_HEADERS += uv/*.h
101123
endif
102-
PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,work-stealing-queue.h gc-interface.h gc-tls.h gc-tls-common.h julia.h julia_assert.h julia_threads.h julia_fasttls.h julia_locks.h julia_atomics.h jloptions.h)
124+
PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,work-stealing-queue.h gc-interface.h gc-tls-common.h julia.h julia_assert.h julia_threads.h julia_fasttls.h julia_locks.h julia_atomics.h jloptions.h)
125+
ifneq (${MMTK_PLAN},None)
126+
PUBLIC_HEADERS += $(addprefix $(SRCDIR)/,gc-tls-mmtk.h)
127+
else
128+
PUBLIC_HEADERS += $(addprefix $(SRCDIR)/,gc-tls-stock.h)
129+
endif
103130
ifeq ($(OS),WINNT)
104131
PUBLIC_HEADERS += $(addprefix $(SRCDIR)/,win32_ucontext.h)
105132
endif
@@ -164,8 +191,8 @@ LIBJULIA_PATH_REL := libjulia
164191
endif
165192

166193
COMMON_LIBPATHS := -L$(build_libdir) -L$(build_shlibdir)
167-
RT_LIBS := $(WHOLE_ARCHIVE) $(LIBUV) $(WHOLE_ARCHIVE) $(LIBUTF8PROC) $(NO_WHOLE_ARCHIVE) $(LIBUNWIND) $(RT_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI)
168-
CG_LIBS := $(LIBUNWIND) $(CG_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI)
194+
RT_LIBS := $(WHOLE_ARCHIVE) $(LIBUV) $(WHOLE_ARCHIVE) $(LIBUTF8PROC) $(NO_WHOLE_ARCHIVE) $(LIBUNWIND) $(RT_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI) $(MMTK_LIB)
195+
CG_LIBS := $(LIBUNWIND) $(CG_LLVMLINK) $(OSLIBS) $(LIBTRACYCLIENT) $(LIBITTAPI) $(MMTK_LIB)
169196
RT_DEBUG_LIBS := $(COMMON_LIBPATHS) $(WHOLE_ARCHIVE) $(BUILDDIR)/flisp/libflisp-debug.a $(WHOLE_ARCHIVE) $(BUILDDIR)/support/libsupport-debug.a -ljulia-debug $(RT_LIBS)
170197
CG_DEBUG_LIBS := $(COMMON_LIBPATHS) $(CG_LIBS) -ljulia-debug -ljulia-internal-debug
171198
RT_RELEASE_LIBS := $(COMMON_LIBPATHS) $(WHOLE_ARCHIVE) $(BUILDDIR)/flisp/libflisp.a $(WHOLE_ARCHIVE) $(BUILDDIR)/support/libsupport.a -ljulia $(RT_LIBS)
@@ -314,6 +341,7 @@ $(BUILDDIR)/debuginfo.o $(BUILDDIR)/debuginfo.dbg.obj: $(addprefix $(SRCDIR)/,de
314341
$(BUILDDIR)/disasm.o $(BUILDDIR)/disasm.dbg.obj: $(SRCDIR)/debuginfo.h $(SRCDIR)/processor.h
315342
$(BUILDDIR)/gc-debug.o $(BUILDDIR)/gc-debug.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h
316343
$(BUILDDIR)/gc-pages.o $(BUILDDIR)/gc-pages.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h
344+
$(BUILDDIR)/gc-mmtk.o $(BUILDDIR)/gc-mmtk.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-heap-snapshot.h $(SRCDIR)/gc-alloc-profiler.h
317345
$(BUILDDIR)/gc-stacks.o $(BUILDDIR)/gc-stacks.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h
318346
$(BUILDDIR)/gc-stock.o $(BUILDDIR)/gc.dbg.obj: $(SRCDIR)/gc-common.h $(SRCDIR)/gc-stock.h $(SRCDIR)/gc-heap-snapshot.h $(SRCDIR)/gc-alloc-profiler.h $(SRCDIR)/gc-page-profiler.h
319347
$(BUILDDIR)/gc-heap-snapshot.o $(BUILDDIR)/gc-heap-snapshot.dbg.obj: $(SRCDIR)/gc-heap-snapshot.h

src/gc-common.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,38 @@ JL_DLLEXPORT jl_value_t *(jl_gc_alloc)(jl_ptls_t ptls, size_t sz, void *ty)
540540
return jl_gc_alloc_(ptls, sz, ty);
541541
}
542542

543+
JL_DLLEXPORT void *jl_malloc(size_t sz)
544+
{
545+
return jl_gc_counted_malloc(sz);
546+
}
547+
548+
//_unchecked_calloc does not check for potential overflow of nm*sz
549+
STATIC_INLINE void *_unchecked_calloc(size_t nm, size_t sz) {
550+
size_t nmsz = nm*sz;
551+
return jl_gc_counted_calloc(nmsz, 1);
552+
}
553+
554+
JL_DLLEXPORT void *jl_calloc(size_t nm, size_t sz)
555+
{
556+
if (nm > SSIZE_MAX/sz)
557+
return NULL;
558+
return _unchecked_calloc(nm, sz);
559+
}
560+
561+
JL_DLLEXPORT void jl_free(void *p)
562+
{
563+
if (p != NULL) {
564+
size_t sz = memory_block_usable_size(p, 0);
565+
return jl_gc_counted_free_with_size(p, sz);
566+
}
567+
}
568+
569+
JL_DLLEXPORT void *jl_realloc(void *p, size_t sz)
570+
{
571+
size_t old = p ? memory_block_usable_size(p, 0) : 0;
572+
return jl_gc_counted_realloc_with_old_size(p, old, sz);
573+
}
574+
543575
// =========================================================================== //
544576
// Generic Memory
545577
// =========================================================================== //
@@ -668,6 +700,24 @@ JL_DLLEXPORT void jl_throw_out_of_memory_error(void)
668700
jl_throw(jl_memory_exception);
669701
}
670702

703+
// Sweeping mtarraylist_buffers:
704+
// These buffers are made unreachable via `mtarraylist_resizeto` from mtarraylist.c
705+
// and are freed at the end of GC via jl_gc_sweep_stack_pools_and_mtarraylist_buffers
706+
void sweep_mtarraylist_buffers(void) JL_NOTSAFEPOINT
707+
{
708+
for (int i = 0; i < gc_n_threads; i++) {
709+
jl_ptls_t ptls = gc_all_tls_states[i];
710+
if (ptls == NULL) {
711+
continue;
712+
}
713+
small_arraylist_t *buffers = &ptls->lazily_freed_mtarraylist_buffers;
714+
void *buf;
715+
while ((buf = small_arraylist_pop(buffers)) != NULL) {
716+
free(buf);
717+
}
718+
}
719+
}
720+
671721
#ifdef __cplusplus
672722
}
673723
#endif

0 commit comments

Comments
 (0)