2023-10-30 11:10:15 -04:00
|
|
|
// Copyright 2019-2021 the Deno authors. All rights reserved. MIT license.
|
|
|
|
//
|
|
|
|
// This sample program shows how to set up a stand-alone cppgc heap.
|
|
|
|
|
|
|
|
// Simple string rope to illustrate allocation and garbage collection below.
|
|
|
|
// The rope keeps the next parts alive via regular managed reference.
|
2024-06-27 11:29:46 -04:00
|
|
|
|
2023-10-30 11:10:15 -04:00
|
|
|
struct Rope {
|
|
|
|
part: String,
|
2024-06-27 11:29:46 -04:00
|
|
|
next: v8::cppgc::Member<Rope>,
|
2023-10-30 11:10:15 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl std::fmt::Display for Rope {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
write!(f, "{}", self.part)?;
|
2024-06-27 11:29:46 -04:00
|
|
|
if let Some(next) = self.next.borrow() {
|
|
|
|
write!(f, "{}", next)?;
|
2023-10-30 11:10:15 -04:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Rope {
|
2024-06-27 11:29:46 -04:00
|
|
|
pub fn new(part: String, next: v8::cppgc::Member<Rope>) -> Rope {
|
|
|
|
Self { part, next }
|
2023-10-30 11:10:15 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl v8::cppgc::GarbageCollected for Rope {
|
|
|
|
fn trace(&self, visitor: &v8::cppgc::Visitor) {
|
2024-06-27 11:29:46 -04:00
|
|
|
visitor.trace(&self.next);
|
2023-10-30 11:10:15 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for Rope {
|
|
|
|
fn drop(&mut self) {
|
2024-06-27 11:29:46 -04:00
|
|
|
println!("Dropping: {}", self.part);
|
2023-10-30 11:10:15 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
let platform = v8::new_default_platform(0, false).make_shared();
|
|
|
|
v8::V8::initialize_platform(platform.clone());
|
|
|
|
v8::V8::initialize();
|
|
|
|
v8::cppgc::initalize_process(platform.clone());
|
|
|
|
|
|
|
|
{
|
|
|
|
// Create a managed heap.
|
2024-06-27 11:29:46 -04:00
|
|
|
let heap =
|
|
|
|
v8::cppgc::Heap::create(platform, v8::cppgc::HeapCreateParams::default());
|
2023-10-30 11:10:15 -04:00
|
|
|
|
|
|
|
// Allocate a string rope on the managed heap.
|
2024-06-27 11:29:46 -04:00
|
|
|
let rope = unsafe {
|
|
|
|
v8::cppgc::make_garbage_collected(
|
|
|
|
&heap,
|
|
|
|
Rope::new(
|
|
|
|
String::from("Hello "),
|
|
|
|
v8::cppgc::make_garbage_collected(
|
|
|
|
&heap,
|
|
|
|
Rope::new(String::from("World!"), v8::cppgc::Member::empty()),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
};
|
|
|
|
|
|
|
|
println!("{}", rope.borrow().unwrap());
|
|
|
|
|
2023-10-30 11:10:15 -04:00
|
|
|
// Manually trigger garbage collection.
|
|
|
|
heap.enable_detached_garbage_collections_for_testing();
|
2024-06-27 11:29:46 -04:00
|
|
|
|
|
|
|
println!("Collect: MayContainHeapPointers");
|
|
|
|
unsafe {
|
|
|
|
heap.collect_garbage_for_testing(
|
|
|
|
v8::cppgc::EmbedderStackState::MayContainHeapPointers,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Should still be live here:
|
|
|
|
println!("{}", rope.borrow().unwrap());
|
|
|
|
|
|
|
|
println!("Collect: NoHeapPointers");
|
|
|
|
unsafe {
|
|
|
|
heap.collect_garbage_for_testing(
|
|
|
|
v8::cppgc::EmbedderStackState::NoHeapPointers,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Should be dead now.
|
2023-10-30 11:10:15 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Gracefully shutdown the process.
|
|
|
|
unsafe {
|
|
|
|
v8::cppgc::shutdown_process();
|
|
|
|
v8::V8::dispose();
|
|
|
|
}
|
|
|
|
v8::V8::dispose_platform();
|
|
|
|
}
|