Git Product home page Git Product logo

mmtk-julia's Introduction

An MMTk binding for the Julia programming language.

Checking out and Building Julia with MMTk

Besides checking out the binding, it is also necessary to checkout a fork containing a modified version of the Julia repository (https://github.com/mmtk/julia). For example, we check out the fork as a sibling of mmtk-julia. For step-by-step instructions, read the section "Quick Building Guide".

The directory structure should look like the diagram below:

Your working directory/
├─ mmtk-julia/
│  ├─ julia/
│  └─ mmtk/
├─ julia/ (should be cloned manually)
└─ mmtk-core/ (optional)

Build Julia binding in Rust

Before building Julia, build the binding in mmtk-julia/mmtk. Note that we currently support either immix or stickyimmix implementations in mmtk-core (build it with cargo build --features immix or cargo build --features stickyimmix). Add --release at the end if you would like to have a release build, otherwise it is a debug build.

Build Julia with MMTk

To build Julia with MMTk, create a Make.user file in the top-level directory of the Julia repository and add an entry WITH_MMTK=1. Finally, set the following environment variables:

export MMTK_BUILD=release # or debug depending on how you build the Julia binding in Rust
export MMTK_JULIA_DIR=<path-to-mmtk-julia>

Then run make with the environment variables mentioned above. Please also make sure to install any dependency considering any particular requirement from both Julia and MMTk.

Heap Size

Currently MMTk supports a fixed heap limit or variable heap within an interval. The default is a variable heap with the minimum heap size set to Julia's default_collection_interval and the maximum size set to 70% of the free memory available. To change these values set the environment variables MMTK_MIN_HSIZE and MMTK_MAX_HSIZE to set the mininum and maximum size in megabytes, or MMTK_MIN_HSIZE_G and MMTK_MAX_HSIZE_G to set the size in gigabytes. If both environment variables are set, MMTk will use the size in megabytes. To set a fixed heap size, simply set only the variables MMTK_MAX_HSIZE or MMTK_MAX_HSIZE_G, or set MMTK_MIN_HSIZE or MMTK_MIN_HSIZE_G to 0. Note that these values can be decimal numbers, e.g. MMTK_MAX_HSIZE_G=1.5.

These environment variables are set during julia initialization time, so they can be set per-julia process.

Quick Building Guide

(1) Clone this repo: https://github.com/mmtk/mmtk-julia (run git clone https://github.com/mmtk/mmtk-julia)

(2) Clone this repo: https://github.com/mmtk/julia (run git clone https://github.com/mmtk/julia.git)

(3) In mmtk-julia/mmtk, run cargo build --features immix --release

(4) In julia, create a file Make.user, and add WITH_MMTK=1.

(5) In julia, run MMTK_PLAN=Immix MMTK_BUILD=release MMTK_JULIA_DIR=/absolute/path/mmtk-julia make (or with MMTK_PLAN=StickyImmix).

If you would like to have a debug build, remove --release from Step (3) and use MMTK_BUILD=debug in Step (5)

Further information

More about MMTk: https://github.com/mmtk/mmtk-core

More about Julia: https://github.com/JuliaLang/julia

mmtk-julia's People

Contributors

k-sareen avatar kpamnany avatar nhdaly avatar qinsoon avatar udesou avatar wks avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

mmtk-julia's Issues

Immix failed in Profile tests for v1.9.2+RAI

Run stdlib tests: Profile
Whitespace check found no issues.
    JULIA test/Profile
Running parallel tests with:
  nworkers() = 1
  nthreads() = 4
  Sys.CPU_THREADS = 2
  Sys.total_memory() = 15.607 GiB
  Sys.free_memory() = 14.162 GiB

Test  (Worker) | Time (s) | GC (s) | GC % | Alloc (MB) | RSS (MB)
Profile    (1) |        started at 2024-01-23T04:11:26.550
Profile    (1) |         failed at 2024-01-23T04:12:43.455
Test Failed at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.9/Profile/test/runtests.jl:230
  Expression: process_running(p)

Test Failed at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.9/Profile/test/runtests.jl:231
  Expression: occursin("Overhead ╎", s)
   Evaluated: occursin("Overhead ╎", "\n\n======================================================================================\nInformation request received. A stacktrace will print followed by a 1.0 second profile\n======================================================================================\n\ncmd: /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/bin/julia 44745 running 2 of 5\n\nsignal (10): User defined signal 1\n\n[44745] signal (11.1): Segmentation fault\nin expression starting at none:3\nAllocations: 3000 (Pool: 2987; Big: 13); GC: 0\n")

Test Failed at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.9/Profile/test/runtests.jl:230
  Expression: process_running(p)

Test Failed at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.9/Profile/test/runtests.jl:231
  Expression: occursin("Overhead ╎", s)
   Evaluated: occursin("Overhead ╎", "")

Test Failed at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.9/Profile/test/allocs.jl:141
  Expression: length(prof.allocs) >= 1
   Evaluated: 0 >= 1

Test Failed at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.9/Profile/test/allocs.jl:142
  Expression: length([a for a = prof.allocs if a.type == MyType]) >= 1
   Evaluated: 0 >= 1



Test Summary: | Pass  Fail  Total     Time
  Overall     |  114     6    120  1m18.3s
    Profile   |  114     6    120  1m17.6s
    FAILURE

The global RNG seed was 0x472dcce3a7713f6facb22d4222793[206](https://github.com/mmtk/mmtk-julia/actions/runs/7620777184/job/20756057161?pr=116#step:5:207).

Error in testset Profile:
Test Failed at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.9/Profile/test/runtests.jl:230
  Expression: process_running(p)

Error in testset Profile:
Test Failed at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.9/Profile/test/runtests.jl:231
  Expression: occursin("Overhead ╎", s)
   Evaluated: occursin("Overhead ╎", "\n\n======================================================================================\nInformation request received. A stacktrace will print followed by a 1.0 second profile\n======================================================================================\n\ncmd: /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/bin/julia 44745 running 2 of 5\n\nsignal (10): User defined signal 1\n\n[44745] signal (11.1): Segmentation fault\nin expression starting at none:3\nAllocations: 3000 (Pool: 2987; Big: 13); GC: 0\n")

Error in testset Profile:
Test Failed at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.9/Profile/test/runtests.jl:230
  Expression: process_running(p)

Error in testset Profile:
Test Failed at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.9/Profile/test/runtests.jl:231
  Expression: occursin("Overhead ╎", s)
   Evaluated: occursin("Overhead ╎", "")

Error in testset Profile:
Test Failed at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.9/Profile/test/allocs.jl:141
  Expression: length(prof.allocs) >= 1
   Evaluated: 0 >= 1

Error in testset Profile:
Test Failed at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.9/Profile/test/allocs.jl:142
  Expression: length([a for a = prof.allocs if a.type == MyType]) >= 1
   Evaluated: 0 >= 1

ERROR: LoadError: Test run finished with errors
in expression starting at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/test/runtests.jl:93
make[1]: *** [Makefile:25: Profile] Error 1
make: *** [Makefile:611: test-Profile] Error 2

Make -j doesn't work for the binding

Using make -j will result in an error:

make[1]: *** No rule to make target '../mmtk-julia/julia/mmtk_julia.o', needed by '/home/ubuntu/mmtk/julia/usr/lib/libjulia-internal.so.1.10.0'.  Stop.
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:91: julia-src-release] Error 2

Global counter for malloc has measurable overhead

We have a global variable that counts malloc'd bytes and gets updated for every malloc call. If there are multiple threads that are doing malloc, there will be contention and will have measurable overhead.

The following is measured with Julia GCBenchmarks, using the multithreaded benchmarks (using 8 mutator threads). The two builds both return 0 in vm_live_bytes() for a fair comparison, and the build with no-malloc-counter does not have the malloc counter update. The results showed that there is measurable overhead for some benchmarks, e.g. 2% slowdown for mergesort_parallel.

MMTK_MIN_HSIZE=31650 MMTK_MAX_HSIZE=31650 /home/yilin/Code/julia_workspace/julia/julia-mmtk-immix-release-no-malloc-counter/usr/bin/julia --project=/home/yilin/Code/julia_workspace/GCBenchmarks /home/yilin/Code/julia_workspace/GCBenchmarks/run_benchmarks.jl multithreaded mergesort_parallel mergesort_parallel -n 1 --threads=8
total time gc time mutator time total time error
('multithreaded-big_arrays-issue-52937', 'julia-mmtk-immix(6.0x minheap,.multithreaded-8)') 7328.7 0 7328.7 3.26144
('multithreaded-big_arrays-issue-52937', 'julia-mmtk-immix-no-malloc-counter(6.0x minheap,.multithreaded-8)') 7345.78 0 7345.78 2.8509
('multithreaded-big_arrays-objarray', 'julia-mmtk-immix(6.0x minheap,.multithreaded-8)') 7279.05 0 7279.05 7.97443
('multithreaded-big_arrays-objarray', 'julia-mmtk-immix-no-malloc-counter(6.0x minheap,.multithreaded-8)') 7288.47 0 7288.47 6.95254
('multithreaded-binary_tree-tree_immutable', 'julia-mmtk-immix(6.0x minheap,.multithreaded-8)') 2233.35 360.83 1872.52 3.61634
('multithreaded-binary_tree-tree_immutable', 'julia-mmtk-immix-no-malloc-counter(6.0x minheap,.multithreaded-8)') 2231.79 360.56 1871.23 3.18454
('multithreaded-binary_tree-tree_mutable', 'julia-mmtk-immix(6.0x minheap,.multithreaded-8)') 3130.31 640.23 2490.08 6.81284
('multithreaded-binary_tree-tree_mutable', 'julia-mmtk-immix-no-malloc-counter(6.0x minheap,.multithreaded-8)') 3132.71 641.74 2490.97 6.62351
('multithreaded-mergesort_parallel-mergesort_parallel', 'julia-mmtk-immix(6.0x minheap,.multithreaded-8)') 20202.5 0 20202.5 811.654
('multithreaded-mergesort_parallel-mergesort_parallel', 'julia-mmtk-immix-no-malloc-counter(6.0x minheap,.multithreaded-8)') 20648 0 20648 608.926
('multithreaded-mm_divide_and_conquer-mm_divide_and_conquer', 'julia-mmtk-immix(6.0x minheap,.multithreaded-8)') 791.47 0 791.47 1.83954
('multithreaded-mm_divide_and_conquer-mm_divide_and_conquer', 'julia-mmtk-immix-no-malloc-counter(6.0x minheap,.multithreaded-8)') 797.59 0 797.59 1.93677

One way to mitigate this issue is to reduce the frequency of global counter update. We could have a local counter for malloc'd bytes, and only update the global counter for every X bytes allocated (X could be 16K or something).

Fix fastpath allocation

Currently the binding only has the implementation for fastpath allocation using immix (using a bump pointer allocator). We need to implement the fastpath for all supported GCs and also be able to select which implementation to use at compile time depending on the GC strategy chosen.

Issues with sweep_stack_pool/gc_sweep_foreign_objs/etc

There are some sweeping tasks that update data structures in Julia. It can be found here: https://github.com/JuliaLang/julia/blob/c6ed7d7c54a501090019e2f509935f6f21bdf9af/src/gc.c#L3129

Some seems irrelevant for the MMTk binding. But some are relevant. Basically if we push those objects to the runtime data structure, we should do the same routine as the stock Julia GC: basically check if the object is alive, and if not, we should clear the object from the list. Otherwise, we may leave dangling pointers.

We have implemented some of these. Like SweepMallocedArray.

pub struct SweepMallocedArrays {
swept: bool,
}

But I think we still missed some, like sweep_stack_pools, gc_sweep_foreign_objs. We should do a thorough check.

malloc from `jl_gc_managed_malloc` is not counted in the heap size.

The bytes allocated by jl_gc_managed_malloc() in gc-common.c is counted in gc_num.malloc and gc_num.allocd, but it is not counted into MMTk heap.

https://github.com/mmtk/julia/blob/861f151c7fbec1d8431a804795bd3d3598b77e3b/src/gc-common.c#L760

We use JULIA_MALLOC_BYTES to count malloc bytes in functions like jl_gc_counted_malloc (in mmtk-gc.c, https://github.com/mmtk/julia/blob/861f151c7fbec1d8431a804795bd3d3598b77e3b/src/mmtk-gc.c#L380).

Use subsuming write barrier

Julia's jl_gc_wb is post write barrier. It works fine for us on sticky immix (which only uses post write barriers). When we try to support LXR, we will need to refactor the barrier code and use subsuming barrier.

Upstream Julia repo interface changes

This issue tracks our progress about upstreaming changes in Julia repo. We plan to submit two PRs to Julia: 1. introduce changes about GC interface (changes to gc.h and the new gc-common.c, etc), 2. introduce MMTk and allow people to use MMTk. Currently we focus on the first PR.

For the first PR, there are a bunch of things we need to do.

1. Clean up our fork

Essentially we would like to reduce or eliminate #ifdef MMTK_GC and #ifndef MMTK_GC outside the normal GC interface. We currently have such checks in array.c, julia_threads.c, partr.c, symbol.c, code gen, etc. We should try clean them up as much as we can.

2. Move MMTk code to the binding

We currently have a bunch of MMTk code in Julia, such as mmtk-gc.c. Those code are included in the Julia repo, as in the beginning we thought about upstreaming the binding as a part of Julia. But now it is preferable to not have the binding code in the Julia repo (MMTk will be a binary dependency for Julia). @NHDaly @d-netto Please correct me if I misunderstood anything.

3. Merge with upstream and get ready for opening a PR

The last step before we can open a PR. We do not want to merge too early, as we have many changes that easily conflicts with any upstream change.

`ci-test.sh` may timeout in 6h

We have a script .github/scripts/ci-test.sh that allows mmtk-core to run. As Github runner has a limit of 6h timeout, the script needs to finish in 6h. However, our ci-test.sh is always close to the 6h limit, and sometimes just times out.

What we could do:

  • Split the script into multiple scripts, and call them in mmtk-core's binding tests.
  • Try use workflow_dispatch, and allow mmtk-core to dispatch to a workflow in mmtk-julia, and we can use our normal test workflow (running multiple tests in parallel).

Big allocations

We insert LLVM calls to jl_mmtk_gc_alloc_big which uses alloc_large. But the library interface jl_gc_big_alloc calls mmtk_malloc_aligned. We should use alloc_large in both cases, correct?

MMTk core PR #1094 slowdown Julia

mmtk/mmtk-core#1094 changed the SFT map implementation to SFTDenseMap when vm_space is enabled for correctness reasons. As we know SFTDenseMap performs worse, and this change affects Julia + MMTk performance negatively. We see slowdown up to 15% in GC time for some benchmarks.

Normalized results

total time gc time mutator time
('multithreaded-big_arrays-issue-52937', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 0 1
('multithreaded-big_arrays-issue-52937', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 0.997136 0 0.997136
('multithreaded-big_arrays-objarray', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 1 1
('multithreaded-big_arrays-objarray', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 1.01231 1.03808 1.00693
('multithreaded-binary_tree-tree_immutable', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 1 1
('multithreaded-binary_tree-tree_immutable', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 1.03907 1.07512 1.00402
('multithreaded-binary_tree-tree_mutable', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 1 1
('multithreaded-binary_tree-tree_mutable', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 1.04052 1.08186 1.00477
('multithreaded-mergesort_parallel-mergesort_parallel', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 0 1
('multithreaded-mergesort_parallel-mergesort_parallel', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 1.00196 0 1.00196
('multithreaded-mm_divide_and_conquer-mm_divide_and_conquer', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 0 1
('multithreaded-mm_divide_and_conquer-mm_divide_and_conquer', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 1.0079 0 1.0079
('serial-TimeZones-TimeZones', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 0 1
('serial-TimeZones-TimeZones', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 1.04728 0 1.04728
('serial-append-append', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 1 1
('serial-append-append', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 1.09984 1.12163 0.999188
('serial-big_arrays-many_refs', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 1 1
('serial-big_arrays-many_refs', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 0.989741 0.990786 0.986718
('serial-big_arrays-single_ref', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 1 1
('serial-big_arrays-single_ref', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 0.989843 0.989805 0.990089
('serial-bigint-pollard', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 1 1
('serial-bigint-pollard', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 1.10983 1.16513 1.0113
('serial-linked-list', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 0 1
('serial-linked-list', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 1.00937 0 1.00937
('serial-linked-tree', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 0 1
('serial-linked-tree', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 1.00088 0 1.00088
('serial-strings-strings', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 0 1
('serial-strings-strings', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 0.993816 0 0.993816
('slow-bigint-pidigits', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 1 1
('slow-bigint-pidigits', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 1.14245 1.149 1.01848
('slow-rb_tree-rb_tree', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1 1 1
('slow-rb_tree-rb_tree', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 0.999169 0.97978 0.999665

Without normalization

total time gc time mutator time
('multithreaded-big_arrays-issue-52937', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 105672 0 105672
('multithreaded-big_arrays-issue-52937', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 105370 0 105370
('multithreaded-big_arrays-objarray', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 39175.8 6770 32405.8
('multithreaded-big_arrays-objarray', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 39658.1 7027.8 32630.3
('multithreaded-binary_tree-tree_immutable', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 29514.4 14547.3 14967.1
('multithreaded-binary_tree-tree_immutable', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 30667.4 15640.1 15027.3
('multithreaded-binary_tree-tree_mutable', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 42100.3 19521.8 22578.5
('multithreaded-binary_tree-tree_mutable', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 43806 21119.8 22686.2
('multithreaded-mergesort_parallel-mergesort_parallel', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 18882.6 0 18882.6
('multithreaded-mergesort_parallel-mergesort_parallel', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 18919.6 0 18919.6
('multithreaded-mm_divide_and_conquer-mm_divide_and_conquer', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 7177.4 0 7177.4
('multithreaded-mm_divide_and_conquer-mm_divide_and_conquer', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 7234.1 0 7234.1
('serial-TimeZones-TimeZones', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 9200.7 0 9200.7
('serial-TimeZones-TimeZones', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 9635.7 0 9635.7
('serial-append-append', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 40132.6 32991.6 7141
('serial-append-append', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 44139.6 37004.4 7135.2
('serial-big_arrays-many_refs', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 3460.5 2572.1 888.4
('serial-big_arrays-many_refs', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 3425 2548.4 876.6
('serial-big_arrays-single_ref', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 6449 5581.3 867.7
('serial-big_arrays-single_ref', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 6383.5 5524.4 859.1
('serial-bigint-pollard', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 5365.6 3436.6 1929
('serial-bigint-pollard', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 5954.9 4004.1 1950.8
('serial-linked-list', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 4281.3 0 4281.3
('serial-linked-list', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 4321.4 0 4321.4
('serial-linked-tree', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 113775 0 113775
('serial-linked-tree', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 113876 0 113876
('serial-strings-strings', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 39696.9 0 39696.9
('serial-strings-strings', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 39451.4 0 39451.4
('slow-bigint-pidigits', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 6.46475e+06 6.14039e+06 324355
('slow-bigint-pidigits', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 7.38565e+06 7.0553e+06 330348
('slow-rb_tree-rb_tree', 'julia-mmtk-master(1.5x minheap,.mmtk_gc_threads-12)') 1.90513e+06 47542.9 1.85759e+06
('slow-rb_tree-rb_tree', 'julia-mmtk-pr(1.5x minheap,.mmtk_gc_threads-12)') 1.90354e+06 46581.6 1.85696e+06

Support allocation into a non-moving space

Some objects such as types, and type names, which are used as metadata when scanning objects, should be allocated into a non-moving space. While MMTk already provides an API for doing so, and there's already a PR to add this support to Julia, MMTk currently allocates these objects in the immortal space; For this reason, they never get collected and increase memory consumption leading to OOM errors in the CI (#101). This issue is to keep track of this problem, which should be solved after we are able to allocate such objects in a proper non-moving space, such as marksweep (which has a few issues in mmtk-core at the moment: mmtk/mmtk-core#688).

NB: In the moving immix version (#93) the non-moving characteristic has been achieved by pinning these objects indefinitely.

Scanning objects in Rust

The implementation for scanning objects is currently done in C here. There is an out-of-sync implementation in Rust here which needs to be updated and tested. This is also likely to improve performance, since we avoid a call from Rust to C for every object being scanned.

Useful GC metrics for MMTk to export

The struct jl_gc_num_t from src/gc.h (and its Julia version defined in base/timing.jl) defines the set of metrics currently exported by the Julia GC.

Among these metrics, it would be particularly useful for MMTk to export:

    total_time => total time spent in GC;
    total_allocd => total number of bytes ever allocated;
    full_sweep => number of full collections;
    max_pause => maximum GC pause;
    max_memory => max heap size;
    time_to_safepoint => time to safepoint (TTSP) in the most recent collection;
    max_time_to_safepoint => maximum TTSP;
    total_time_to_safepoint => sum of all TTSP;
    sweep_time => sweep time in the most recent collection;
    mark_time => mark time in the most recent collection;
    total_sweep_time => sum of all sweep times;
    total_mark_time => sum of all mark times;

Some of them might need some massaging/reinterpretation due to the fact that MMTk uses a different GC algorithm.

Besides that, it would be desirable to export the self-explanatory live_bytes.

CC: @kpamnany.

realloc in MMTk?

Currently we implement realloc by simply allocating a new array and copy the contents over. At some point, we probably would like to know how much overhead this would introduce. Alternatively, we may add a realloc method for MMTk allocators. The default implementation is the same allocation and mem copying, but for some allocators, they may provide a more efficient implementation.

Julia GC assumes `jl_task_t` is always in the remembered set.

Julia treats jl_task_t as a special case and assumes it will always reference young objects.
https://github.com/JuliaLang/julia/blob/f9792b4863230d638425b4f79ec5e109e12f77cc/src/gc.c#L2517-L2518

In this case, they may not have write barriers when updating references in jl_task_t. I encountered a case when I was debugging for #71, and described it here: #71 (comment). The missing write barrier was upstreamed in JuliaLang/julia#51096, and included in our fork in mmtk/julia#21. However, there might be more cases like this that we haven't found. We may encounter similar issues like this in the future.

We could consider treating jl_task_t as a special case.

Package compiler does not include libmmtk_julia.so in its library bundle

When running RAI workloads, more specifically when building binary.linux, we get an error /bin/rai-server: error while loading shared libraries: libmmtk_julia.so: cannot open shared object file: No such file or directory. It looks like Julia's package compiler does not include the libmmtk_julia.so file as one of the dependencies, and the file does not get copied over to rai-server/lib/julia.

Implement fixed heap size for Julia

The goal is to compare MMTk with Julia's stock GC, and we would need the GC to be triggered in the same way as MMTk. We would need to set a fixed heap size for Julia.

Improving the performance when querying object size

Julia's stock GC uses page metadata information to ask for the size of smaller objects (pool-allocated). Since MMTk does not have that information available, we perform a check on the object type to calculate its size, which is likely to cause performance problems.

Sticky immix build fail: Assertion `ma->a->flags.how == 2' failed.

In the run https://github.com/mmtk/mmtk-julia/actions/runs/7604776437/job/20708115425 for #112, I got this error during building a release build of sticky immix. It is non-deterministic, and I cannot reproduce the issue again (neither locally or in the CI).

Base  ───────────── 40.367250 seconds
ArgTools  ─────────  6.693130 seconds
Artifacts  ────────  0.253433 seconds
Base64  ───────────  0.112872 seconds
CRC32c  ───────────  0.008417 seconds
FileWatching  ─────  0.174248 seconds
Libdl  ────────────  0.001760 seconds
Logging  ──────────  0.039110 seconds
Mmap  ─────────────  0.089678 seconds
NetworkOptions  ───  0.062446 seconds
SHA  ──────────────  0.199247 seconds
Serialization  ────  0.263934 seconds
Sockets  ──────────  0.391623 seconds
Unicode  ──────────  0.080520 seconds
LinearAlgebra  ────  7.017694 seconds
Markdown  ─────────  0.802332 seconds
Printf  ───────────  0.160136 seconds
Random  ───────────  0.714685 seconds
Tar  ──────────────  0.265033 seconds
Dates  ────────────  1.720099 seconds
Future  ───────────  0.006633 seconds
InteractiveUtils  ─  0.641833 seconds
LibGit2  ──────────  1.499335 seconds
UUIDs  ────────────  0.016796 seconds
REPL  ───────────── 13.033354 seconds
TOML  ─────────────  0.067494 seconds
LibCURL  ──────────  0.349211 seconds
Downloads  ────────  0.384808 seconds
Pkg  ──────────────  4.977926 seconds
Stdlibs total  ──── 40.037469 seconds
Sysimage built. Summary:
Base ────────  40.367250 seconds 50.2035%
Stdlibs ─────  40.037469 seconds 49.7934%
Total ───────  80.407189 seconds
julia: /home/runner/work/mmtk-julia/mmtk-julia/.github/scripts/../../julia/mmtk_julia.c:121: mmtk_sweep_malloced_arrays: Assertion `ma->a->flags.how == 2' failed.

[16917] signal (6.-6): Aborted
in expression starting at none:0
Allocations: 1 (Pool: 1; Big: 0); GC: 0
Aborted (core dumped)
*** This error might be fixed by running `make clean`. If the error persists, try `make cleanall`. ***
make[1]: *** [sysimage.mk:67: /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/lib/julia/sys.ji] Error 1
make: *** [Makefile:97: julia-sysimg-ji] Error 2

Remove max heap size for Julia-style GC trigger

/// Is current heap full?
fn is_heap_full(&self, plan: &dyn Plan<VM = JuliaVM>) -> bool {
plan.get_reserved_pages()
>= conversions::bytes_to_pages_up(self.max_total_memory.load(Ordering::Relaxed))
}

/// Return the upper bound of heap size
fn get_max_heap_size_in_pages(&self) -> usize {
conversions::bytes_to_pages_up(self.max_total_memory.load(Ordering::Relaxed))
}

These lines still uses max_total_memory as a hard limit for MMTk, while Julia treats max_total_memory as a soft limit. So we may still see MMTk OOM. We should simply use usize::MAX in those lines.

Allocation size is larger than necessary

In order to allocate the same amount of memory as the Julia GC, we currently use their size classes to determine the allocation size. However, this is not necessary since MMTk uses a different allocator. It should only need to allocate the object size without any check for the size classes - this will likely improve performance due to better memory usage.

Sticky (Generational) Collector

All supported collectors (immix and marksweep) currently only perform full heap GCs. This will likely degrade the performance of long running programs when the heap grows larger and larger. Ideally we should implement a generational/sticky variation of the supported GCs so we have an "apples to apples" comparison against stock Julia.

Sticky immix does not build for v1.9.2+RAI

It failed during building

    CC src/llvm-ptls.o
    CC src/llvm-lower-handlers.o
    CC src/llvm-gc-invariant-verifier.o
    CC src/llvm-propagate-addrspaces.o
    CC src/llvm-multiversioning.o
    CC src/llvm-alloc-opt.o
    CC src/llvm-alloc-helpers.o
    CC src/cgmemmgr.o
    CC src/llvm-remove-addrspaces.o
    CC src/llvm-remove-ni.o
    CC src/llvm-julia-licm.o
    CC src/llvm-demote-float16.o
    CC src/llvm-cpufeatures.o
    CC src/pipeline.o
    LINK usr/lib/libjulia-codegen.so.1.9
    LINK usr/lib/libjulia-codegen.so.1
    LINK usr/lib/libjulia-codegen.so
    JULIA usr/lib/julia/corecompiler.ji
[2024-01-23T04:16:03Z INFO  mmtk::policy::immix::immixspace] Creating non-moving ImmixSpace: immix. Block size: 2^13
[2024-01-23T04:16:03Z INFO  mmtk::memory_manager] Initialized MMTk with StickyImmix (DynamicHeapSize(536870912, 4294967296))
[2024-01-23T04:16:03Z INFO  mmtk_julia::api] Binding mutator 0x563f532e7190 with tls = VMMutatorThread(VMThread(OpaquePointer(0x563f532478c0))) to thread id = 0
[2024-01-23T04:16:03Z INFO  mmtk_julia::api] Binding mutator 0x7faf4c0a0550 with tls = VMMutatorThread(VMThread(OpaquePointer(0x7faf4c000b70))) to thread id = 0
[2024-01-23T04:16:33Z INFO  mmtk::util::heap::gc_trigger] [POLL] immix: Triggering collection (131074/131072 pages)
[2024-01-23T04:16:33Z INFO  mmtk_julia::collection] Triggered GC!
[2024-01-23T04:16:33Z INFO  mmtk_julia::collection] Blocking for GC!
[2024-01-23T04:16:33Z INFO  mmtk::plan::sticky::immix::global] Nursery GC
[2024-01-23T04:16:33Z INFO  mmtk_julia::collection] stop_all_mutators: visiting VMMutatorThread(VMThread(OpaquePointer(0x563f532478c0)))
[2024-01-23T04:16:33Z INFO  mmtk_julia::collection] stop_all_mutators: visiting VMMutatorThread(VMThread(OpaquePointer(0x7faf4c000b70)))
[2024-01-23T04:16:34Z INFO  mmtk::scheduler::gc_work] End of GC (36380/131072 pages, took 163 ms)
[2024-01-23T04:16:34Z INFO  mmtk_julia::collection] Live bytes = 146219008, total bytes = 536870912
[2024-01-23T04:16:34Z INFO  mmtk_julia::collection] Finished blocking mutator for GC!
[2024-01-23T04:16:50Z INFO  mmtk::util::heap::gc_trigger] [POLL] immix: Triggering collection (131073/131072 pages)
[2024-01-23T04:16:50Z INFO  mmtk_julia::collection] Triggered GC!
[2024-01-23T04:16:50Z INFO  mmtk_julia::collection] Blocking for GC!
[2024-01-23T04:16:50Z INFO  mmtk::plan::sticky::immix::global] Nursery GC
[2024-01-23T04:16:50Z INFO  mmtk_julia::collection] stop_all_mutators: visiting VMMutatorThread(VMThread(OpaquePointer(0x563f532478c0)))
[2024-01-23T04:16:50Z INFO  mmtk_julia::collection] stop_all_mutators: visiting VMMutatorThread(VMThread(OpaquePointer(0x7faf4c000b70)))
[2024-01-23T04:16:51Z INFO  mmtk::scheduler::gc_work] End of GC (54634/131072 pages, took 99 ms)
[2024-01-23T04:16:51Z INFO  mmtk_julia::collection] Live bytes = 219582464, total bytes = 536870912
[2024-01-23T04:16:51Z INFO  mmtk_julia::collection] Finished blocking mutator for GC!
[2024-01-23T04:17:02Z INFO  mmtk::util::heap::gc_trigger] [POLL] immix: Triggering collection (131073/131072 pages)
[2024-01-23T04:17:02Z INFO  mmtk_julia::collection] Triggered GC!
[2024-01-23T04:17:02Z INFO  mmtk_julia::collection] Blocking for GC!
[2024-01-23T04:17:02Z INFO  mmtk::plan::sticky::immix::global] Nursery GC
[2024-01-23T04:17:02Z INFO  mmtk_julia::collection] stop_all_mutators: visiting VMMutatorThread(VMThread(OpaquePointer(0x563f532478c0)))
[2024-01-23T04:17:02Z INFO  mmtk_julia::collection] stop_all_mutators: visiting VMMutatorThread(VMThread(OpaquePointer(0x7faf4c000b70)))
[2024-01-23T04:17:03Z INFO  mmtk::scheduler::gc_work] End of GC (66516/131072 pages, took 91 ms)
[2024-01-23T04:17:03Z INFO  mmtk_julia::collection] Live bytes = 267333632, total bytes = 536870912
[2024-01-23T04:17:03Z INFO  mmtk_julia::collection] Finished blocking mutator for GC!
[2024-01-23T04:17:12Z INFO  mmtk::util::heap::gc_trigger] [POLL] immix: Triggering collection (131073/131072 pages)
[2024-01-23T04:17:12Z INFO  mmtk_julia::collection] Triggered GC!
[2024-01-23T04:17:12Z INFO  mmtk_julia::collection] Blocking for GC!
[2024-01-23T04:17:12Z INFO  mmtk::plan::sticky::immix::global] Nursery GC
[2024-01-23T04:17:12Z INFO  mmtk_julia::collection] stop_all_mutators: visiting VMMutatorThread(VMThread(OpaquePointer(0x563f532478c0)))
[2024-01-23T04:17:12Z INFO  mmtk_julia::collection] stop_all_mutators: visiting VMMutatorThread(VMThread(OpaquePointer(0x7faf4c000b70)))
[2024-01-23T04:17:12Z INFO  mmtk::scheduler::gc_work] End of GC (76602/131072 pages, took 129 ms)
[2024-01-23T04:17:12Z INFO  mmtk_julia::collection] Live bytes = 307871744, total bytes = 536870912
[2024-01-23T04:17:12Z INFO  mmtk_julia::collection] Finished blocking mutator for GC!
[2024-01-23T04:17:20Z INFO  mmtk::util::heap::gc_trigger] [POLL] immix: Triggering collection (131073/131072 pages)
[2024-01-23T04:17:20Z INFO  mmtk_julia::collection] Triggered GC!
[2024-01-23T04:17:20Z INFO  mmtk_julia::collection] Blocking for GC!
[2024-01-23T04:17:20Z INFO  mmtk::plan::sticky::immix::global] Nursery GC
[2024-01-23T04:17:20Z INFO  mmtk_julia::collection] stop_all_mutators: visiting VMMutatorThread(VMThread(OpaquePointer(0x563f532478c0)))
[2024-01-23T04:17:20Z INFO  mmtk_julia::collection] stop_all_mutators: visiting VMMutatorThread(VMThread(OpaquePointer(0x7faf4c000b70)))

[320617] signal (11.1): Segmentation fault
in expression starting at compiler/bootstrap.jl:10
Allocations: 47037164 (Pool: 47033601; Big: 3563); GC: 4
Segmentation fault (core dumped)
make[1]: *** [sysimage.mk:61: /home/yilin/Code/julia_workspace/julia/usr/lib/julia/corecompiler.ji] Error 139
make: *** [Makefile:84: julia-sysimg-ji] Error 2

It died after a few nursery GCs. No mature GC happened.

Duplicated edges in scanning jl_module_type

These can be reproduced if we run make test-Pkg with immix with extreme_assertions. The following issue will cause assertion fails for duplicated edges.

The binding vector is scanned multiple times.

A module is scanned. A module has a pointer to of a simple vector. The vector is scanned from index 1 (index 0 is skipped) when we scan the module.

} else if (vt == jl_module_type) { // inlining label `module_binding` from mark_loop
jl_module_t *m = (jl_module_t*)obj;
jl_svec_t *bindings = jl_atomic_load_relaxed(&m->bindings);
jl_binding_t **table = (jl_binding_t**)jl_svec_data(bindings);
size_t bsize = jl_svec_len(bindings);
jl_binding_t **begin = table + 1;
jl_binding_t **end = table + bsize;
for (; begin < end; begin++) {
jl_binding_t *b = *begin;
if (b == (jl_binding_t*)jl_nothing)
continue;
process_edge(closure, begin);
}

Later in the GC, the vector could be reachable from somewhere else, and is scanned again, from index 0.

This pushes the edges from index 1 twice to MMTk. MMTk has assertions to make sure we should not have an edge multiple times, as it usually indicates a bug and could cause performance degradation as we will have to load from the same edge multiple times.

The object scanning code in the binding is from the stock GC's gc_mark_outrefs, which does the same thing: https://github.com/mmtk/julia/blob/72a275233012a80dfd5c5ac1c83afdf9aff0a87a/src/gc.c#L1922.

I think a more sensible approach might be just pushing the simple vector object to the queue when we scan the module.

Object is treated as an edge

This seems to be a bug. objary_begin is the slot/edge. We should not load the object, and use the object reference as the edge.

for (; objary_begin < objary_end; objary_begin += 1) {
jl_value_t *pnew_obj = *objary_begin;
process_edge(closure, pnew_obj);
}

Use build script to run bindgen

Currently we generate a Rust version for mmtk_julia_types.h using rust-bindgen, and check in the generated code. This introduces an issue for portability, as the code generation depends on the host we run bindgen. It is not a problem for now, as we only develop and test on one platform x86_64 linux. When we start considering about portability for the binding, we should run bindgen using Rust build script (build.rs).

Sweeps

sweep_stack_pools needs to be called to sweep up the stacks of tasks that have completed.

Also, sweep_big should also be called if jl_gc_big_alloc is ever used because it adds the allocated pointer to ptls->heap.big_objects.

Object pretenuring

It seems Julia may pretenure objects. For example:
https://github.com/mmtk/julia/blob/54ca78ad9ca9e2795c6356588ed50039f2d1b23b/src/symbol.c#L43
https://github.com/mmtk/julia/blob/72a275233012a80dfd5c5ac1c83afdf9aff0a87a/src/jltypes.c#L2156
https://github.com/mmtk/julia/blob/72a275233012a80dfd5c5ac1c83afdf9aff0a87a/src/julia_internal.h#L538 (for all perm objs).

We need to figure out whether this is for performance or for correctness. We need to support pretenuring in MMTk, and replace their pretenuring code with MMTk's.

Note that we use one bit in the header to know whether it is in the image. I am not sure how we set the bit, and if it is related with the pretenuring code (which will set the bit for some objects).

Separate slowpath function for compiler generated allocation

Currently the compiler generated allocation will call jl_gc_pool_alloc() as the slowpath, which eventually calls to jl_mmtk_gc_alloc_default().

JL_DLLEXPORT jl_value_t *jl_mmtk_gc_alloc_default(jl_ptls_t ptls, int pool_offset,

As the function is also used by runtime allocation, it includes the fastpath as well. That means for the compiler generated allocation, we will run the fastpath with the generated code. If it fails, we jump to the slowpath, and we will run the fastpath again (which is guaranteed to fail in this case), then call to the actual slowpath.

Performance wise, this might be slightly slower. But the slowdown may not be measurable. However, this makes the code confusing. We should introduce another method specifically for the slowpath, and call that method from the generated code when fastpath fails.

GC algorithm-specific calls

There are a number of functions in Julia's GC interface that are specific to the GC algorithm used. The most prominent example is pool-related calls, e.g. jl_gc_classify_pools. These have no clear implementation when using a different GC algorithm that does not have pools (such as IMMIX) and should ideally be scrubbed from the interface.

This issue collects such functions for future work to remove them from the GC interface.

Support moving collectors

It would be a huge (performance) win to support (partially) moving objects. Even if it's not possible to always move objects, collectors such as immix or LXR can be used to implement opportunistic copying. This issue is to keep track of the issues and perhaps discuss any problems with the implementation.

Failing CI tests

Write barrier elision

I encountered these statistics in Julia's JIT code: RemovedWriteBarriers and HoistedWriteBarrier. It appears that they are doing some sort of write barrier elision. We need to understand about the JIT's behavior on this, and disable the optimization if necessary.

ci-test-gc-core failed: A "spawn and wait lots of tasks" test failed

In https://github.com/mmtk/mmtk-core/actions/runs/7603829506/job/20706033725?pr=1073, there is a random failure in the threads tests.

threads
-> Run
Whitespace check found no issues.
    JULIA test/threads
Running parallel tests with:
  nworkers() = 1
  nthreads() = 4
  Sys.CPU_THREADS = 2
  Sys.total_memory() = 15.607 GiB
  Sys.free_memory() = 14.190 GiB

Test  (Worker) | Time (s) | GC (s) | GC % | Alloc (MB) | RSS (MB)
threads    (1) |        started at 2024-01-21T21:25:57.844
Test Summary:                               |  Pass  Total   Time
threads_exec.jl with JULIA_NUM_THREADS == 1 | 40353  40353  37.4s
Test Summary:                               |  Pass  Total   Time
threads_exec.jl with JULIA_NUM_THREADS == 2 | 45713  45713  34.6s
Test Summary:                               |  Pass  Total   Time
threads_exec.jl with JULIA_NUM_THREADS == 4 | 43803  43803  35.1s
Test Summary:                               |  Pass  Total   Time
threads_exec.jl with JULIA_NUM_THREADS == 4 | 47103  47103  35.6s
┌ Error: A "spawn and wait lots of tasks" test failed
│   n = 2000000
│   proc.exitcode = 0
│   proc.termsignal = 0
│   success(proc) = true
│   timeout = true
└ @ Main.Test84Main_threads ~/work/mmtk-core/mmtk-core/mmtk-julia/vm/julia/test/threads.jl:313
threads    (1) |         failed at 2024-01-21T21:30:56.635
Test Failed at /home/runner/work/mmtk-core/mmtk-core/mmtk-julia/vm/julia/test/threads.jl:320
  Expression: !timeout



Test Summary: | Pass  Fail  Total  Time
  Overall     |   50     1     51  0.5s
    threads   |   50     1     51  4m59.5s
    FAILURE

The global RNG seed was 0x7cd3376b3527438d6fed6c7518c967bd.

Error in testset threads:
Test Failed at /home/runner/work/mmtk-core/mmtk-core/mmtk-julia/vm/julia/test/threads.jl:320
  Expression: !timeout

ERROR: LoadError: Test run finished with errors
in expression starting at /home/runner/work/mmtk-core/mmtk-core/mmtk-julia/vm/julia/test/runtests.jl:95
make[1]: *** [Makefile:30: threads] Error 1
make: *** [Makefile:633: test-threads] Error 2

Test Failed in distributed_exec.jl:245 Expression: testval == 1 Evaluated: 0 == 1

First seen in https://github.com/mmtk/mmtk-julia/actions/runs/6079623548/job/16492380079 for PR #97

JULIA test/Distributed
Running parallel tests with:
  nworkers() = 1
  nthreads() = 4
  Sys.CPU_THREADS = 2
  Sys.total_memory() = 6.769 GiB
  Sys.free_memory() = 5.545 GiB

Test  (Worker) | Time (s) | GC (s) | GC % | Alloc (MB) | RSS (MB)
Distributed(1) |        started at 2023-09-05T03:29:31.446
Test Failed at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.10/Distributed/test/distributed_exec.jl:245
  Expression: testval == 1
   Evaluated: 0 == 1

ERROR: LoadError: There was an error during testing
in expression starting at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.10/Distributed/test/distributed_exec.jl:245
Distributed(1) |         failed at 2023-09-05T03:30:14.115
Error During Test at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/test/testdefs.jl:21
  Got exception outside of a @test
  LoadError: Distributed test failed, cmd : `/home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/bin/julia -Cnative -J/home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/lib/julia/sys.so -g1 --startup-file=no --check-bounds=yes --startup-file=no --depwarn=error /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.10/Distributed/test/distributed_exec.jl`
  Stacktrace:
    [1] error(s::String)
      @ Base ./error.jl:35
    [2] top-level scope
      @ ~/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.10/Distributed/test/runtests.jl:11
    [3] include(mod::Module, _path::String)
      @ Base ./Base.jl:489 [inlined]
    [4] macro expansion
      @ Main ~/work/mmtk-julia/mmtk-julia/vm/julia/test/testdefs.jl:29 [inlined]
    [5] macro expansion
      @ Main ~/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.10/Test/src/Test.jl:1577 [inlined]
    [6] macro expansion
      @ Main ~/work/mmtk-julia/mmtk-julia/vm/julia/test/testdefs.jl:23 [inlined]
    [7] macro expansion
      @ Main ./timing.jl:503 [inlined]
    [8] runtests(name::String, path::String, isolate::Bool; seed::UInt128)
      @ Main ~/work/mmtk-julia/mmtk-julia/vm/julia/test/testdefs.jl:21
    [9] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{seed::UInt128})
      @ Base ./essentials.jl:869
   [10] (::var"#31#39")()
      @ Main ~/work/mmtk-julia/mmtk-julia/vm/julia/test/runtests.jl:318
   [11] cd(f::var"#31#39", dir::String)
      @ Base.Filesystem ./file.jl:112
   [12] top-level scope
      @ ~/work/mmtk-julia/mmtk-julia/vm/julia/test/runtests.jl:95
   [13] include(mod::Module, _path::String)
      @ Base ./Base.jl:489
   [14] exec_options(opts::Base.JLOptions)
      @ Base ./client.jl:318
   [15] _start()
      @ Base ./client.jl:552
  in expression starting at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.10/Distributed/test/runtests.jl:10


Test Summary: | Error  Total  Time
  Overall     |     1      1  0.8s
    Distributed |     1      1  43.9s
    FAILURE

The global RNG seed was 0x5fdc85e73162a5e361dd2a952c[194](https://github.com/mmtk/mmtk-julia/actions/runs/6079623548/job/16492380079#step:5:195)744.

Error in testset Distributed:
Error During Test at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/test/testdefs.jl:21
  Got exception outside of a @test
  LoadError: Distributed test failed, cmd : `/home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/bin/julia -Cnative -J/home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/lib/julia/sys.so -g1 --startup-file=no --check-bounds=yes --startup-file=no --depwarn=error /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.10/Distributed/test/distributed_exec.jl`
  Stacktrace:
    [1] error(s::String)
      @ Base ./error.jl:35
    [2] top-level scope
      @ ~/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.10/Distributed/test/runtests.jl:11
    [3] include(mod::Module, _path::String)
      @ Base ./Base.jl:489 [inlined]
    [4] macro expansion
      @ Main ~/work/mmtk-julia/mmtk-julia/vm/julia/test/testdefs.jl:29 [inlined]
    [5] macro expansion
      @ Main ~/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.10/Test/src/Test.jl:1577 [inlined]
    [6] macro expansion
      @ Main ~/work/mmtk-julia/mmtk-julia/vm/julia/test/testdefs.jl:23 [inlined]
    [7] macro expansion
      @ Main ./timing.jl:503 [inlined]
    [8] runtests(name::String, path::String, isolate::Bool; seed::UInt128)
      @ Main ~/work/mmtk-julia/mmtk-julia/vm/julia/test/testdefs.jl:21
    [9] invokelatest(::Any, ::Any, ::Vararg{Any}; kwargs::@Kwargs{seed::UInt128})
      @ Base ./essentials.jl:869
   [10] (::var"#31#39")()
      @ Main ~/work/mmtk-julia/mmtk-julia/vm/julia/test/runtests.jl:318
   [11] cd(f::var"#31#39", dir::String)
      @ Base.Filesystem ./file.jl:112
   [12] top-level scope
      @ ~/work/mmtk-julia/mmtk-julia/vm/julia/test/runtests.jl:95
   [13] include(mod::Module, _path::String)
      @ Base ./Base.jl:489
   [14] exec_options(opts::Base.JLOptions)
      @ Base ./client.jl:318
   [15] _start()
      @ Base ./client.jl:552
  in expression starting at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/usr/share/julia/stdlib/v1.10/Distributed/test/runtests.jl:10
ERROR: LoadError: Test run finished with errors
in expression starting at /home/runner/work/mmtk-julia/mmtk-julia/vm/julia/test/runtests.jl:95
make[1]: *** [Makefile:30: Distributed] Error 1
make: *** [Makefile:633: test-Distributed] Error 2

Remove runtime_gc_x64.c?

This file currently builds with the Rust project, and statically linked with the final libmmtk_julia.so binary. This file does not seem to do anything special that we have to do in C. We should be able to just remove it, and implement it in Rust.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.