Skip to content

Commit

Permalink
🐣 Define the LoadBarrier
Browse files Browse the repository at this point in the history
  • Loading branch information
oovm committed Mar 26, 2019
1 parent a6b98e2 commit 816dca0
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 5 deletions.
1 change: 1 addition & 0 deletions projects/zero-gc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ edition = "2021"
exclude = ["package.json", "tests/**"]

[dependencies]
bitflags = "2.3.1"

[dev-dependencies]

Expand Down
115 changes: 115 additions & 0 deletions projects/zero-gc/src/barrier/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// bitflags! {
// #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
// pub struct LoadBarrier: u8 {
// const Finalizable = 0b00000001;
// const Remapped = 0b00000010;
// const Marked1 = 0b00000100;
// const Marked0 = 0b00001000;
// }
// }

use std::fmt::{Debug, Formatter, Pointer};

pub struct LoadBarrier {
raw: usize,
}

impl Debug for LoadBarrier {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("GcPointer")
.field("raw", &format_args!("0x{:0x}", self.raw))
.field("pointer", &format_args!("{:p}", self.as_pointer()))
.field("finalize", &self.is_finalizable())
.field("remapped", &self.is_remapped())
.field("marked1", &self.is_marked1())
.field("marked0", &self.is_marked0())
.finish()
}
}

impl Pointer for LoadBarrier {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "0x{:0x}", self.raw)
}
}

impl LoadBarrier {
/// Create a new pointer from a usize.
pub unsafe fn new(address: *const usize) -> Self {
Self {
raw: address as usize,
}
}
pub fn make<T>(value: T) -> Self {
Self {
raw: &value as *const T as usize,
}
}
/// Get the pointer as a usize.
pub fn as_pointer(&self) -> *const usize {
let masked = self.raw & 0x0000_0000_ffff_ffff;
masked as *const usize
}
/// Cast the pointer to a specific type.
pub unsafe fn cast<T>(&self) -> &mut T {
&mut *(self.as_pointer() as *mut T)
}
/// The 19th bit of the pointer is used to indicate whether the object is finalizable.
pub fn is_finalizable(&self) -> bool {
self.raw & 0x80000 != 0
}
pub fn set_finalize(&mut self, finalize: bool) {
if finalize {
self.raw |= 0x80000;
} else {
self.raw &= !0x80000;
}
}
/// The 20th bit of the pointer is used to indicate whether the object is remapped.
pub fn is_remapped(&self) -> bool {
self.raw & 0x40000 != 0
}
pub fn set_remapped(&mut self, remapped: bool) {
if remapped {
self.raw |= 0x40000;
} else {
self.raw &= !0x40000;
}
}
/// The 21th bit of the pointer is used to indicate whether the object is marked.
pub fn is_marked1(&self) -> bool {
self.raw & 0x20000 != 0
}
pub fn set_marked1(&mut self, marked: bool) {
if marked {
self.raw |= 0x20000;
} else {
self.raw &= !0x20000;
}
}
/// The 22th bit of the pointer is used to indicate whether the object is marked.
pub fn is_marked0(&self) -> bool {
self.raw & 0x10000 != 0
}
pub fn set_marked0(&mut self, marked0: bool) {
if marked0 {
self.raw |= 0x10000;
} else {
self.raw &= !0x10000;
}
}
}

#[test]
pub fn test() {
let a: i64 = -2333;
println!("{:p}", &a);
let mut ptr = LoadBarrier::make(a);
ptr.set_marked0(true);
ptr.set_marked1(true);
ptr.set_remapped(true);
ptr.set_finalize(true);
println!("{:#?}", ptr);
let d = unsafe { ptr.cast::<i64>() };
println!("{:?}", d)
}
23 changes: 18 additions & 5 deletions projects/zero-gc/src/gc_head/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use std::ptr::NonNull;
/// Gc pointer
pub struct Gc<T> {
/// Pointer to the head
ptr: usize,
ptr: *mut u64,
/// Pointer to the data
data: *mut u8,
bytes: *mut u8,
/// Phantom data
typing: PhantomData<T>,
}
Expand All @@ -30,6 +30,7 @@ impl Region for SmallRegion {

pub struct TheWorld {}

#[derive(Copy, Clone)]
pub union TheRegion {
small: SmallRegion,
medium: MediumRegion,
Expand All @@ -44,14 +45,26 @@ unsafe impl Allocator for TheWorld {
todo!()
}
}

// 小型Region(Small Region):容量固定为2MB,用于放置小于256KB的小对象。
// 中型Region(Medium Region):容量固定为32MB,用于放置大于等于256KB但小于4MB的对象。
// 大型Region(Large Region):容量不固定,可以动态变化,但必须为2MB的整数倍,用于放置4MB或以上的大对象。每个大型Region中只会存放一个大对象,这也预示着虽然名字叫作“大型Region”,但它的实际容量完全有可能小于中型Region,最小容量可低至4MB。大型Region在ZGC的实现中是不会被重分配的,因为复制一个大对象的代价非常高昂。

/// 容量固定为1MB,用于放置小于128KB的小对象。
#[derive(Copy, Clone)]
pub struct SmallRegion {
bytes: [u8; 1 * 1024 * 1024],
}

/// 容量固定为16MB,用于放置小于4MB的中等对象。
/// 容量固定为 32MB,用于放置小于4MB的中等对象。
#[derive(Copy, Clone)]
pub struct MediumRegion {
bytes: [u8; 16 * 1024 * 1024],
bytes: [u8; 32 * 1024 * 1024],
}

pub struct OwnedRegion {
bytes: Vec<u8>,
}

pub struct WorldControl {
initiating_heap_occupancy_percent: u8,
}
1 change: 1 addition & 0 deletions projects/zero-gc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@

mod errors;
mod gc_head;
mod barrier;

pub use crate::errors::{Error, Result};

0 comments on commit 816dca0

Please sign in to comment.