Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Boa Gc implementation draft #2394

Closed
wants to merge 55 commits into from

Conversation

nekevss
Copy link
Member

@nekevss nekevss commented Oct 31, 2022

Not sure if anyone else may be working on something more substantial/in-depth, but I thought I'd post this. 😄

The basic rundown is that this is more of an untested (and in some ways naïve) draft than anything else. It builds rather heavily on rust-gc, and tries to keep plenty of the core aspects so as to not break anything too much, and also to minimize overarching changes were it to actually be merged at some point.

This implementation does add a generational divide (although a little unoptimized) to the heap, a GcAlloc/Collector struct with methods, and an ephemeron implementation that allows for the WeakPair and WeakGc pointers.

@codecov
Copy link

codecov bot commented Nov 5, 2022

Codecov Report

Merging #2394 (7b477b6) into main (70f73b4) will increase coverage by 13.52%.
The diff coverage is 71.34%.

@@             Coverage Diff             @@
##             main    #2394       +/-   ##
===========================================
+ Coverage   38.81%   52.34%   +13.52%     
===========================================
  Files         315      329       +14     
  Lines       24085    34982    +10897     
===========================================
+ Hits         9348    18310     +8962     
- Misses      14737    16672     +1935     
Impacted Files Coverage Δ
boa_engine/src/builtins/async_generator/mod.rs 8.08% <ø> (+1.83%) ⬆️
boa_engine/src/builtins/generator/mod.rs 15.16% <ø> (+4.58%) ⬆️
boa_engine/src/environments/runtime.rs 47.71% <ø> (+21.63%) ⬆️
boa_engine/src/job.rs 100.00% <ø> (+40.00%) ⬆️
boa_engine/src/string/mod.rs 82.37% <ø> (+22.91%) ⬆️
boa_engine/src/symbol.rs 85.88% <ø> (+55.00%) ⬆️
boa_engine/src/vm/code_block.rs 33.42% <0.00%> (+<0.01%) ⬆️
boa_macros/src/lib.rs 0.00% <0.00%> (ø)
boa_tester/src/exec/mod.rs 0.00% <0.00%> (ø)
boa_gc/src/cell.rs 63.84% <63.84%> (ø)
... and 326 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@nekevss
Copy link
Member Author

nekevss commented Nov 5, 2022

I decided to just go ahead and fully integrate it into the engine. Commits are a bit of a monstrosity, but the above appears to be roughly working. Looks like there's some EcmaScript tests that I may have to take a look at, but let me know what you think 😄

@nekevss nekevss marked this pull request as ready for review November 5, 2022 05:26
@jedel1043
Copy link
Member

Just a small suggestion. Could you remove the merged commits from main, then rebase? It would make reviewing the code a bit easier, since right now it's grouping your changes with all the merged commits from the main branch.

@jedel1043 jedel1043 added enhancement New feature or request performance Performance related changes and issues technical debt execution Issues or PRs related to code execution labels Nov 5, 2022
@jedel1043 jedel1043 added this to the v0.17.0 milestone Nov 5, 2022
@nekevss
Copy link
Member Author

nekevss commented Nov 5, 2022

Okay, I believe it's just about all cleaned up

Comment on lines 33 to 43
// TODO: Determine if thread local variables are the correct approach vs an initialized structure
thread_local!(pub static EPHEMERON_QUEUE: StdCell<Option<Vec<GcPointer>>> = StdCell::new(None));
thread_local!(pub static GC_DROPPING: StdCell<bool> = StdCell::new(false));
thread_local!(static BOA_GC: StdRefCell<BoaGc> = StdRefCell::new( BoaGc {
config: GcConfig::default(),
runtime: GcRuntimeData::default(),
adult_start: StdCell::new(None),
youth_start: StdCell::new(None),
}));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by "initialized structure"? Like, putting everything on a single thread_local!?

Copy link
Member Author

@nekevss nekevss Nov 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, probably not the right way to word what I was thinking. I meant a non-thread local struct. Basically, I was thinking something that would have to be initialized by context when I wrote that comment.

Edit: to expand on the above. When working on this, I was mostly thinking of it as a stepping stone away from using rust-gc to an independent garbage collector. I'm not sure how well using thread_local variables play with concurrent collection and I think there was also a question about no_std on an issue, so I was mostly just notating it as something to consider. Maybe it would be better to have left the comment as NOTE: vs. TODO:

Copy link
Member

@jedel1043 jedel1043 Nov 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can use thread locals for our std implementation, since they should be more performant on multi-threaded contexts (multiple Gcs can be run at the same time, because JS engines must always run on a single thread). On the other hand, we can use other mechanisms for no_std builds, since a system without an OS has no notion of threads.

@jedel1043
Copy link
Member

So, I experimented with this PR a bit and it seems like it has a memory leak somewhere?

For example, if I run:

systemd-run --scope -p MemoryMax=2G --user cargo run --release --bin boa_tester -- run

The memory of the boa_tester process peaks at 1.9 GB:

image

Compare that to the main branch, which uses 300 MB of memory at max:

image

I'll try to run this build with Miri, maybe I can find the leak.

@raskad
Copy link
Member

raskad commented Nov 5, 2022

So, I experimented with this PR a bit and it seems like it has a memory leak somewhere?

Yeah I think so too. The 262 ci currently exists with code 137 which is probably the job being OOM'd.

@nekevss
Copy link
Member Author

nekevss commented Nov 5, 2022

Yeah, there's definitely something. I've been looking at it all afternoon. Thought it might have to do with either GcCellRef or BoaGc's dropping.

@jedel1043
Copy link
Member

Just for the record. I ran systemd-run --scope -p MemoryMax=2G --user cargo +nightly miri test -p boa_engine after cherry-picking #2412 (since Miri was detecting UB on JsStrings instead of the garbage collector) and this printed:

test builtins::array::tests::array_entries_simple ... error: Undefined Behavior: pointer to alloc1059445 was dereferenced after this allocation got freed
    --> /home/jedel/SDK/src/Rust/boa/boa_gc/src/pointers/gc_ptr.rs:84:18
     |
84   |         unsafe { &*self.inner_ptr() }
     |                  ^^^^^^^^^^^^^^^^^^ pointer to alloc1059445 was dereferenced after this allocation got freed
     |
     = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
     = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
     = note: BACKTRACE:
     = note: inside `boa_gc::Gc::<boa_gc::Cell<object::Object>>::inner` at /home/jedel/SDK/src/Rust/boa/boa_gc/src/pointers/gc_ptr.rs:84:18
note: inside `<boa_gc::Gc<boa_gc::Cell<object::Object>> as boa_gc::Trace>::root` at /home/jedel/SDK/src/Rust/boa/boa_gc/src/pointers/gc_ptr.rs:113:9
    --> /home/jedel/SDK/src/Rust/boa/boa_gc/src/pointers/gc_ptr.rs:113:9
     |
113  |         self.inner().root_inner();
     |         ^^^^^^^^^^^^
note: inside `object::jsobject::_DERIVE_boa_gc_Trace_FOR_JsObject::<impl boa_gc::Trace for object::jsobject::JsObject>::root::mark::<boa_gc::Gc<boa_gc::Cell<object::Object>>>` at boa_engine/src/object/jsobject.rs:30:10
    --> boa_engine/src/object/jsobject.rs:30:10

I'll try to come up with a minimized script that replicates the UB.

@jedel1043
Copy link
Member

Ok, I found a pretty good minimization of the problem. A simple script as:

use boa_engine::{
    object::ObjectData,
    prelude::JsObject,
    property::PropertyDescriptor,
};

fn main() {
    let object = JsObject::from_proto_and_data(None, ObjectData::ordinary());

    for i in 0..29 {
        let function = JsObject::from_proto_and_data(None, ObjectData::ordinary());
        object.borrow_mut().insert(
            i,
            PropertyDescriptor::builder()
                .value(function)
                .writable(true)
                .enumerable(false)
                .configurable(true),
        );
    }
}

Throws a malloc(): unsorted double linked list corrupted error every time. You only have to expose the Object::insert method because it is crate only.

It is very interesting, because the program runs fine if you only insert 27 newly created objects. It is after you try to insert the 28th object when the gc corrupts the memory.

@jedel1043
Copy link
Member

Minimized the problem even further:

use boa_gc::BoaAlloc;

fn main() {
    let v = BoaAlloc::new_cell(Vec::new());

    for _ in 1..=259 {
        let cell = BoaAlloc::new_cell([0u8;10]);
        v.borrow_mut().push(cell);
    }
}

This throws with double free or corruption (out).

@addisoncrump
Copy link
Contributor

addisoncrump commented Nov 6, 2022

I actually see a different error here. I can't read, this is the same issue. Try using MSAN:

$ RUSTFLAGS="-Zsanitizer=memory" cargo -Zbuild-std run --target=x86_64-unknown-linux-gnu --bin gc_error
MSAN crash
   Compiling boa_examples v0.16.0 (/home/addisoncrump/git/boa/boa_examples)
    Finished dev [unoptimized + debuginfo] target(s) in 0.95s
     Running `/home/addisoncrump/git/boa/target/x86_64-unknown-linux-gnu/debug/gc_error`
==50838==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x55af7298c4a4 in boa_gc::gc_box::GcBoxHeader::inc_roots::hc5225928b6f33fbe /home/addisoncrump/git/boa/boa_gc/src/gc_box.rs:56:12
    #1 0x55af729820d1 in boa_gc::gc_box::GcBox$LT$T$GT$::root_inner::hbde44432d819337a /home/addisoncrump/git/boa/boa_gc/src/gc_box.rs:161:9
    #2 0x55af7298952f in _$LT$boa_gc..pointers..gc_ptr..Gc$LT$T$GT$$u20$as$u20$boa_gc..trace..Trace$GT$::root::h5f98dc2014fabd3d /home/addisoncrump/git/boa/boa_gc/src/pointers/gc_ptr.rs:113:9
    #3 0x55af72979351 in _$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$boa_gc..trace..Trace$GT$::root::mark::hb682d001a0056c52 /home/addisoncrump/git/boa/boa_gc/src/trace.rs:105:17
    #4 0x55af72977cbd in _$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$boa_gc..trace..Trace$GT$::root::h7e0e978d6450e227 /home/addisoncrump/git/boa/boa_gc/src/trace.rs:303:13
    #5 0x55af729853fd in boa_gc::internals::cell::GcCell$LT$T$GT$::try_borrow_mut::h7d83c0d1cefa6ac4 /home/addisoncrump/git/boa/boa_gc/src/internals/cell.rs:114:17
    #6 0x55af72984fa9 in boa_gc::internals::cell::GcCell$LT$T$GT$::borrow_mut::h4fa16a01de33d44d /home/addisoncrump/git/boa/boa_gc/src/internals/cell.rs:66:15
    #7 0x55af729769d2 in gc_error::main::he780f4a299b7f5e4 /home/addisoncrump/git/boa/boa_examples/src/bin/gc_error.rs:8:9
    #8 0x55af72974c8c in core::ops::function::FnOnce::call_once::hdd5a7ec9297d7f13 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:251:5
    #9 0x55af729842c1 in std::sys_common::backtrace::__rust_begin_short_backtrace::h908c572d2cbdd6fb /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys_common/backtrace.rs:121:18
    #10 0x55af7298bb3a in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::hacdcc69328a4b425 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:166:18
    #11 0x55af72afd044 in core::ops::function::impls::_$LT$impl$u20$core..ops..function..FnOnce$LT$A$GT$$u20$for$u20$$RF$F$GT$::call_once::h5e1c5deb26d62cbe /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:286:13
    #12 0x55af72c5d2fc in std::panicking::try::do_call::h4898d48b772e7a9f /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:483:40
    #13 0x55af72c6d249 in __rust_try std.e3c8d372-cgu.7
    #14 0x55af72c5cb8d in std::panicking::try::ha46d4cc94db5d020 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:447:19
    #15 0x55af72a6790d in std::panic::catch_unwind::he21fc66129e84a2e /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:137:14
    #16 0x55af72bbb8fe in std::rt::lang_start_internal::_$u7b$$u7b$closure$u7d$$u7d$::h242c210078bd3b3f /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:148:48
    #17 0x55af72c5d681 in std::panicking::try::do_call::heb0987c2d82e69c1 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:483:40
    #18 0x55af72c6d249 in __rust_try std.e3c8d372-cgu.7
    #19 0x55af72c5c426 in std::panicking::try::h5a4f8aa5684fbb01 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:447:19
    #20 0x55af72a6786d in std::panic::catch_unwind::h83016bfb06c049ae /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:137:14
    #21 0x55af72bbb34b in std::rt::lang_start_internal::h031a9b51ee0a41ea /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:148:20
    #22 0x55af7298ba55 in std::rt::lang_start::h58633f62c16f3df2 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:165:17
    #23 0x55af72976c16 in main (/home/addisoncrump/git/boa/target/x86_64-unknown-linux-gnu/debug/gc_error+0x91c16) (BuildId: ca2732652103c4c8458a358058d11d9f34908a3d)
    #24 0x7f94ffbf0d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #25 0x7f94ffbf0e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #26 0x55af7290e214 in _start (/home/addisoncrump/git/boa/target/x86_64-unknown-linux-gnu/debug/gc_error+0x29214) (BuildId: ca2732652103c4c8458a358058d11d9f34908a3d)

SUMMARY: MemorySanitizer: use-of-uninitialized-value /home/addisoncrump/git/boa/boa_gc/src/gc_box.rs:56:12 in boa_gc::gc_box::GcBoxHeader::inc_roots::hc5225928b6f33fbe
Exiting

ASAN shows the error you got as well, but I think this is caused by a previous memory error.

$ RUSTFLAGS="-Zsanitizer=address" cargo -Zbuild-std run --target=x86_64-unknown-linux-gnu --bin gc_error
ASAN crash
    Finished dev [unoptimized + debuginfo] target(s) in 0.09s
     Running `/home/addisoncrump/git/boa/target/x86_64-unknown-linux-gnu/debug/gc_error`
=================================================================
==52541==ERROR: AddressSanitizer: heap-use-after-free on address 0x606000001d00 at pc 0x55eef5c0f48c bp 0x7ffd9613c870 sp 0x7ffd9613c868
READ of size 8 at 0x606000001d00 thread T0
    #0 0x55eef5c0f48b in core::cell::Cell$LT$T$GT$::get::h965d71cd2284f59e /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/cell.rs:452:18
    #1 0x55eef5980d40 in boa_gc::gc_box::GcBoxHeader::inc_roots::hc5225928b6f33fbe /home/addisoncrump/git/boa/boa_gc/src/gc_box.rs:54:21
    #2 0x55eef59775e9 in boa_gc::gc_box::GcBox$LT$T$GT$::root_inner::hbde44432d819337a /home/addisoncrump/git/boa/boa_gc/src/gc_box.rs:161:9
    #3 0x55eef597df65 in _$LT$boa_gc..pointers..gc_ptr..Gc$LT$T$GT$$u20$as$u20$boa_gc..trace..Trace$GT$::root::h5f98dc2014fabd3d /home/addisoncrump/git/boa/boa_gc/src/pointers/gc_ptr.rs:113:9
    #4 0x55eef59706e9 in _$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$boa_gc..trace..Trace$GT$::root::mark::hb682d001a0056c52 /home/addisoncrump/git/boa/boa_gc/src/trace.rs:105:17
    #5 0x55eef596f9c8 in _$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$boa_gc..trace..Trace$GT$::root::h7e0e978d6450e227 /home/addisoncrump/git/boa/boa_gc/src/trace.rs:303:13
    #6 0x55eef597b1ac in boa_gc::internals::cell::GcCell$LT$T$GT$::try_borrow_mut::h7d83c0d1cefa6ac4 /home/addisoncrump/git/boa/boa_gc/src/internals/cell.rs:114:17
    #7 0x55eef597aca2 in boa_gc::internals::cell::GcCell$LT$T$GT$::borrow_mut::h4fa16a01de33d44d /home/addisoncrump/git/boa/boa_gc/src/internals/cell.rs:66:15
    #8 0x55eef596ead1 in gc_error::main::he780f4a299b7f5e4 /home/addisoncrump/git/boa/boa_examples/src/bin/gc_error.rs:8:9
    #9 0x55eef596ce1a in core::ops::function::FnOnce::call_once::hdd5a7ec9297d7f13 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:251:5
    #10 0x55eef597a6e4 in std::sys_common::backtrace::__rust_begin_short_backtrace::h908c572d2cbdd6fb /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys_common/backtrace.rs:121:18
    #11 0x55eef5980653 in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::hacdcc69328a4b425 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:166:18
    #12 0x55eef5ae833d in core::ops::function::impls::_$LT$impl$u20$core..ops..function..FnOnce$LT$A$GT$$u20$for$u20$$RF$F$GT$::call_once::h5e1c5deb26d62cbe /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:286:13
    #13 0x55eef5c824d2 in std::panicking::try::do_call::h4898d48b772e7a9f /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:483:40
    #14 0x55eef5c956aa in __rust_try std.e3c8d372-cgu.7
    #15 0x55eef5c81b23 in std::panicking::try::ha46d4cc94db5d020 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:447:19
    #16 0x55eef5a5bf89 in std::panic::catch_unwind::he21fc66129e84a2e /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:137:14
    #17 0x55eef5bc0850 in std::rt::lang_start_internal::_$u7b$$u7b$closure$u7d$$u7d$::h242c210078bd3b3f /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:148:48
    #18 0x55eef5c8287a in std::panicking::try::do_call::heb0987c2d82e69c1 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:483:40
    #19 0x55eef5c956aa in __rust_try std.e3c8d372-cgu.7
    #20 0x55eef5c81055 in std::panicking::try::h5a4f8aa5684fbb01 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:447:19
    #21 0x55eef5a5be19 in std::panic::catch_unwind::h83016bfb06c049ae /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:137:14
    #22 0x55eef5bc0278 in std::rt::lang_start_internal::h031a9b51ee0a41ea /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:148:20
    #23 0x55eef59805af in std::rt::lang_start::h58633f62c16f3df2 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:165:17
    #24 0x55eef596edfd in main (/home/addisoncrump/git/boa/target/x86_64-unknown-linux-gnu/debug/gc_error+0x199dfd) (BuildId: 6fb65983dcaaab5e74d215aa39ffed87184c77d2)
    #25 0x7f96c99c2d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #26 0x7f96c99c2e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #27 0x55eef58d0254 in _start (/home/addisoncrump/git/boa/target/x86_64-unknown-linux-gnu/debug/gc_error+0xfb254) (BuildId: 6fb65983dcaaab5e74d215aa39ffed87184c77d2)

0x606000001d00 is located 0 bytes inside of 56-byte region [0x606000001d00,0x606000001d38)
freed by thread T0 here:
    #0 0x55eef5944b82 in __interceptor_free /rustc/llvm/src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:52:3
    #1 0x55eef5b7d0cc in std::sys::unix::alloc::_$LT$impl$u20$core..alloc..global..GlobalAlloc$u20$for$u20$std..alloc..System$GT$::dealloc::h509003d75cfda122 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/unix/alloc.rs:42:9
    #2 0x55eef5c27069 in __rdl_dealloc /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/alloc.rs:389:18
    #3 0x55eef5992a2c in alloc::alloc::dealloc::h9f472da056ebc39a /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/alloc.rs:117:14
    #4 0x55eef5992c26 in _$LT$alloc..alloc..Global$u20$as$u20$core..alloc..Allocator$GT$::deallocate::h4794cdd7647f829c /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/alloc.rs:254:22
    #5 0x55eef599a5f8 in alloc::alloc::box_free::hde8e718b5be33e0a /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/alloc.rs:352:9
    #6 0x55eef598ef19 in core::ptr::drop_in_place$LT$alloc..boxed..Box$LT$boa_gc..gc_box..GcBox$LT$dyn$u20$boa_gc..trace..Trace$GT$$GT$$GT$::hf0678fa49d4665ab /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:490:1
    #7 0x55eef5987b20 in boa_gc::Collector::sweep_with_promotions::hd7c54cf581233e4d /home/addisoncrump/git/boa/boa_gc/src/lib.rs:438:13
    #8 0x55eef59842eb in boa_gc::Collector::run_youth_collection::h8be24bc9c66d10b2 /home/addisoncrump/git/boa/boa_gc/src/lib.rs:279:36
    #9 0x55eef5983ec0 in boa_gc::BoaAlloc::manage_state::he379656e2021954c /home/addisoncrump/git/boa/boa_gc/src/lib.rs:250:13
    #10 0x55eef5974941 in std::thread::local::LocalKey$LT$T$GT$::try_with::h135a363016c6abdf /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:446:16
    #11 0x55eef5974470 in std::thread::local::LocalKey$LT$T$GT$::with::hb4c2932391aff73b /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:422:9
    #12 0x55eef597e82d in boa_gc::BoaAlloc::new_cell::h02d2f812351c5496 /home/addisoncrump/git/boa/boa_gc/src/lib.rs:144:9
    #13 0x55eef596e9c2 in gc_error::main::he780f4a299b7f5e4 /home/addisoncrump/git/boa/boa_examples/src/bin/gc_error.rs:7:20
    #14 0x55eef596ce1a in core::ops::function::FnOnce::call_once::hdd5a7ec9297d7f13 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:251:5
    #15 0x55eef5980653 in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::hacdcc69328a4b425 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:166:18
    #16 0x55eef5c824d2 in std::panicking::try::do_call::h4898d48b772e7a9f /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:483:40
    #17 0x55eef5c956aa in __rust_try std.e3c8d372-cgu.7
    #18 0x55eef5a5bf89 in std::panic::catch_unwind::he21fc66129e84a2e /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:137:14
    #19 0x55eef5bc0850 in std::rt::lang_start_internal::_$u7b$$u7b$closure$u7d$$u7d$::h242c210078bd3b3f /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:148:48
    #20 0x55eef5c8287a in std::panicking::try::do_call::heb0987c2d82e69c1 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:483:40
    #21 0x55eef5c956aa in __rust_try std.e3c8d372-cgu.7
    #22 0x55eef5a5be19 in std::panic::catch_unwind::h83016bfb06c049ae /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:137:14
    #23 0x55eef5bc0278 in std::rt::lang_start_internal::h031a9b51ee0a41ea /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:148:20
    #24 0x55eef59805af in std::rt::lang_start::h58633f62c16f3df2 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:165:17
    #25 0x55eef596edfd in main (/home/addisoncrump/git/boa/target/x86_64-unknown-linux-gnu/debug/gc_error+0x199dfd) (BuildId: 6fb65983dcaaab5e74d215aa39ffed87184c77d2)

previously allocated by thread T0 here:
    #0 0x55eef5944cae in malloc /rustc/llvm/src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:69:3
    #1 0x55eef5b7cc47 in std::sys::unix::alloc::_$LT$impl$u20$core..alloc..global..GlobalAlloc$u20$for$u20$std..alloc..System$GT$::alloc::hc59e61b4dc141d80 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/unix/alloc.rs:14:13
    #2 0x55eef5c26e5f in __rdl_alloc /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/alloc.rs:381:13
    #3 0x55eef597680b in alloc::alloc::alloc::hb0cbb77b1568ad08 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/alloc.rs:99:14
    #4 0x55eef5976aa0 in alloc::alloc::Global::alloc_impl::h5c841aaae0c73eb1 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/alloc.rs:181:73
    #5 0x55eef5977230 in _$LT$alloc..alloc..Global$u20$as$u20$core..alloc..Allocator$GT$::allocate::hec12b08007082c78 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/alloc.rs:241:9
    #6 0x55eef5976525 in alloc::alloc::exchange_malloc::h721e3c7382153daa /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/alloc.rs:330:11
    #7 0x55eef597a40c in alloc::boxed::Box$LT$T$GT$::new::h126ebf71f4e279b2 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:218:9
    #8 0x55eef597a40c in _$LT$alloc..boxed..Box$LT$T$GT$$u20$as$u20$core..convert..From$LT$T$GT$$GT$::from::hdb9f51dce3ab3f57 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1454:9
    #9 0x55eef597f2ab in boa_gc::BoaAlloc::new_cell::_$u7b$$u7b$closure$u7d$$u7d$::h493b48f5386b2549 /home/addisoncrump/git/boa/boa_gc/src/lib.rs:156:53
    #10 0x55eef5974941 in std::thread::local::LocalKey$LT$T$GT$::try_with::h135a363016c6abdf /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:446:16
    #11 0x55eef5974470 in std::thread::local::LocalKey$LT$T$GT$::with::hb4c2932391aff73b /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:422:9
    #12 0x55eef597e82d in boa_gc::BoaAlloc::new_cell::h02d2f812351c5496 /home/addisoncrump/git/boa/boa_gc/src/lib.rs:144:9
    #13 0x55eef596e9c2 in gc_error::main::he780f4a299b7f5e4 /home/addisoncrump/git/boa/boa_examples/src/bin/gc_error.rs:7:20
    #14 0x55eef596ce1a in core::ops::function::FnOnce::call_once::hdd5a7ec9297d7f13 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:251:5
    #15 0x55eef5980653 in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::hacdcc69328a4b425 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:166:18
    #16 0x55eef5c824d2 in std::panicking::try::do_call::h4898d48b772e7a9f /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:483:40
    #17 0x55eef5c956aa in __rust_try std.e3c8d372-cgu.7
    #18 0x55eef5a5bf89 in std::panic::catch_unwind::he21fc66129e84a2e /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:137:14
    #19 0x55eef5bc0850 in std::rt::lang_start_internal::_$u7b$$u7b$closure$u7d$$u7d$::h242c210078bd3b3f /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:148:48
    #20 0x55eef5c8287a in std::panicking::try::do_call::heb0987c2d82e69c1 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panicking.rs:483:40
    #21 0x55eef5c956aa in __rust_try std.e3c8d372-cgu.7
    #22 0x55eef5a5be19 in std::panic::catch_unwind::h83016bfb06c049ae /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/panic.rs:137:14
    #23 0x55eef5bc0278 in std::rt::lang_start_internal::h031a9b51ee0a41ea /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:148:20
    #24 0x55eef59805af in std::rt::lang_start::h58633f62c16f3df2 /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:165:17
    #25 0x55eef596edfd in main (/home/addisoncrump/git/boa/target/x86_64-unknown-linux-gnu/debug/gc_error+0x199dfd) (BuildId: 6fb65983dcaaab5e74d215aa39ffed87184c77d2)

SUMMARY: AddressSanitizer: heap-use-after-free /home/addisoncrump/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/cell.rs:452:18 in core::cell::Cell$LT$T$GT$::get::h965d71cd2284f59e
Shadow bytes around the buggy address:
  0x0c0c7fff8350: 00 00 00 fa fa fa fa fa 00 00 00 00 00 00 00 fa
  0x0c0c7fff8360: fa fa fa fa 00 00 00 00 00 00 00 fa fa fa fa fa
  0x0c0c7fff8370: 00 00 00 00 00 00 00 fa fa fa fa fa 00 00 00 00
  0x0c0c7fff8380: 00 00 00 fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c0c7fff8390: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
=>0x0c0c7fff83a0:[fd]fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
  0x0c0c7fff83b0: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c0c7fff83c0: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
  0x0c0c7fff83d0: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
  0x0c0c7fff83e0: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c0c7fff83f0: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==52541==ABORTING

@nekevss nekevss force-pushed the implement-boa-gc branch 2 times, most recently from 3cca25a to 1b04319 Compare November 7, 2022 02:46
Copy link
Member

@Razican Razican left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only had the chance to review it lightly, and it's looking great :) I added some comments, mostly related to documentation.

Impressive work!

Comment on lines 80 to 82
// NOTE: [repr(C)] is most likely unneeded here, but will keep it for now
/// A garbage collected allocation.
#[repr(C)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we try this out without the #[repr(C)]?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we should be fine. There wasn't anything implemented with layout that would need it.

boa_gc/src/internals/gc_box.rs Show resolved Hide resolved

impl<T: Trace> GcBox<T> {
pub(crate) fn new(value: T) -> Self {
GcBox {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
GcBox {
Self {

This can in fact be done in many places, and can make renames easier at some point.

}

/// Increases the root count on this `GcBox`.
/// Roots prevent the `GcBox` from being destroyed by the garbage collector.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Roots prevent the `GcBox` from being destroyed by the garbage collector.
///
/// Roots prevent the `GcBox` from being destroyed by the garbage collector.

&self.value
}

pub(crate) fn is_marked(&self) -> bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is missing some documentation, and probably an #[inline] hint. I'm marking this one, since it's the only one missing the documentation in this file, but many other functions / structures / enums are missing documentation. Also, we should probably add the #[inline] hint to one-liners here and elsewhere.

boa_gc/src/lib.rs Show resolved Hide resolved
boa_gc/src/trace.rs Show resolved Hide resolved
@raskad
Copy link
Member

raskad commented Nov 11, 2022

The gc dependency is still in the Cargo.toml in boa_examples. If we drop it from there it will be gone from the Cargo.lock.

Copy link
Member

@Razican Razican left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! Some Debug implementations and docs missing :)

}

/// A garbage collected allocation.
pub(crate) struct GcBox<T: Trace + ?Sized + 'static> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can probably derive Debug :)

}
}

#[derive(Default)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can probably also derive Debug, Clone and Copy

bytes_allocated: usize,
}

struct BoaGc {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also implement Debug

Comment on lines 111 to 114
// Whether or not the thread is currently in the sweep phase of garbage collection.
// During this phase, attempts to dereference a `Gc<T>` pointer will trigger a panic.

struct DropGuard;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These comments seem to be together, right? Should they be doc comments related to the struct?

Also, the guard should derive / implement Debug, and maybe Clone/Copy.

struct DropGuard;

impl DropGuard {
fn new() -> DropGuard {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is missing some docs, with information on the default value. Also, it can return Self, to make it easier to rename.


/// Returns `true` if it is safe for a type to run [`Finalize::finalize`].
#[must_use]
pub fn finalizer_safe() -> bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should have an #[inline] hint.

/// The Allocator handles allocation of garbage collected values.
///
/// The allocator can trigger a garbage collection.
struct Allocator;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should at least derive/implement Debug, and maybe Clone/Copy.

Copy link
Member

@raskad raskad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a technical review and I think I understand most, if not all of the mechanics. Very impressive work!

I have some initial lint comments.

boa_gc/src/test/weak.rs Outdated Show resolved Hide resolved
boa_gc/src/test/weak.rs Outdated Show resolved Hide resolved
boa_gc/src/test/weak.rs Outdated Show resolved Hide resolved
boa_gc/src/test/weak.rs Outdated Show resolved Hide resolved
boa_gc/src/lib.rs Outdated Show resolved Hide resolved
Comment on lines 537 to 541
#[allow(clippy::use_self)]
fn cmp(&self, other: &GcCell<T>) -> Ordering {
(*self.borrow()).cmp(&*other.borrow())
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason against this?

Suggested change
#[allow(clippy::use_self)]
fn cmp(&self, other: &GcCell<T>) -> Ordering {
(*self.borrow()).cmp(&*other.borrow())
}
}
fn cmp(&self, other: &Self) -> Ordering {
(*self.borrow()).cmp(&*other.borrow())
}
}

Copy link
Member Author

@nekevss nekevss Nov 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just thought it might lack a little bit of clarity to be comparing &self vs &Self

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the documentation for Ord this is the normal signature, I think that is why clippy recommends this.

boa_gc/src/cell.rs Show resolved Hide resolved
Comment on lines +20 to +22
const ROOT: usize = 1;
const WRITING: usize = !1;
const UNUSED: usize = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about using bitflags!{} for this? it could add some useful methods.

const UNUSED: usize = 0;

/// The base borrowflag init is rooted, and has no outstanding borrows.
pub(crate) const BORROWFLAG_INIT: BorrowFlag = BorrowFlag(1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is the correct constant, right? We should use it here to avoid issues if we change values, and for clarity:

Suggested change
pub(crate) const BORROWFLAG_INIT: BorrowFlag = BorrowFlag(1);
pub(crate) const BORROWFLAG_INIT: BorrowFlag = BorrowFlag(ROOT);

/// The base borrowflag init is rooted, and has no outstanding borrows.
pub(crate) const BORROWFLAG_INIT: BorrowFlag = BorrowFlag(1);

impl BorrowFlag {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all functions in this impl would benefit from an #[inline] hint. I would also appreciate some documentation.

boa_gc/src/internals/gc_box.rs Show resolved Hide resolved
Copy link
Member

@HalidOdat HalidOdat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides some small nitpicks, this looks good to me :) Good work @nekevss

}

/// Calls [`Trace::weak_trace()`][crate::Trace] on value
///
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
///

@@ -0,0 +1,142 @@
use crate::trace::Trace;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its better to rename this file eph_box.rs => ephemeron_box.rs, since its clearer and matches the pointers/ephemeron.rs

@jedel1043
Copy link
Member

Gonna merge this then. Again, thank you, @nekevss for all the effort you put into this PR!

bors r+

bors bot pushed a commit that referenced this pull request Nov 14, 2022
<!---
Thank you for contributing to Boa! Please fill out the template below, and remove or add any
information as you feel necessary.
--->

Not sure if anyone else may be working on something more substantial/in-depth, but I thought I'd post this. 😄 

The basic rundown is that this is more of an untested (and in some ways naïve) draft than anything else. It builds rather heavily on `rust-gc`, and tries to keep plenty of the core aspects so as to not break anything too much, and also to minimize overarching changes were it to actually be merged at some point.

This implementation does add ~~a generational divide (although a little unoptimized) to the heap,~~ a GcAlloc/Collector struct with methods, and an ephemeron implementation that allows for the WeakPair and WeakGc pointers.
@bors
Copy link

bors bot commented Nov 14, 2022

Pull request successfully merged into main.

Build succeeded:

@bors bors bot changed the title Boa Gc implementation draft [Merged by Bors] - Boa Gc implementation draft Nov 14, 2022
@bors bors bot closed this Nov 14, 2022
@Manishearth
Copy link

FWIW, rust-gc is happy to accept more upstream PRs so that y'all can continue using it. It might be worth maintaining this as a fork that y'all can tailor that y'all occasionally contribute upstream when you think stuff is ready? I do hope the ephemeron stuff can be eventually upstreamed, i know you have a WIP pr)

The main thing is that rust-gc should be tailored in ways that ideally can be still flexibly picked up only if needed, but that shouldn't be too hard.

In the long run, I suspect boa will want a GC that doesn't need to reference count. I recommend checking out https://github.com/asajeffrey/josephine/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request execution Issues or PRs related to code execution performance Performance related changes and issues run-benchmark Label used to run banchmarks on PRs technical debt
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants