78 lines
2.0 KiB
Rust
78 lines
2.0 KiB
Rust
use crate::*;
|
|
|
|
const MASK_WHITE0: u8 = 0b1;
|
|
const MASK_WHITE1: u8 = 0b10;
|
|
const MASK_WHITE: u8 = MASK_WHITE0 | MASK_WHITE1;
|
|
const MASK_BLACK: u8 = 0b100;
|
|
const MASK_FIXED: u8 = 0b1000;
|
|
|
|
/// Possible states of the Garbage Collector
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
#[repr(u8)]
|
|
enum GCState {
|
|
Pause = 0,
|
|
Propagate = 1,
|
|
PropagateAgain = 2,
|
|
Atomic = 3,
|
|
Sweep = 4,
|
|
}
|
|
|
|
#[inline(always)]
|
|
unsafe fn is_black(o: GCObjectPtr) -> bool {
|
|
(&*o.0).gch.marked & MASK_BLACK != 0
|
|
}
|
|
|
|
#[inline(always)]
|
|
unsafe fn is_white(o: GCObjectPtr) -> bool {
|
|
(&*o.0).gch.marked & MASK_WHITE != 0
|
|
}
|
|
|
|
/*#[inline(always)]
|
|
unsafe fn is_dead(g: *mut global_State, o: *mut GCObject) -> bool {
|
|
(&*o).gch.marked & (MASK_WHITE | MASK_FIXED) == otherwhite(g) & MASK_WHITE
|
|
}
|
|
|
|
#[inline(always)]
|
|
unsafe fn otherwhite(g: *mut global_State) -> u8 {
|
|
(&*g).currentwhite ^ MASK_WHITE
|
|
}
|
|
|
|
#[inline(always)]
|
|
fn black2gray(o: *mut GCObject) {
|
|
(&mut *o).gch.marked &= !MASK_BLACK;
|
|
}
|
|
|
|
pub unsafe fn luaC_barrierback(L: *mut lua_State, o: *mut GCObject, gclist: *mut *mut GCObject) {
|
|
let g = (&*L).global;
|
|
debug_assert!(is_black(o) && !is_dead(g, o) != 0);
|
|
debug_assert_ne!(g.gcstate, GCState::Pause);
|
|
|
|
black2gray(o); // make object gray (again)
|
|
*gclist = (&*g).grayagain;
|
|
(&mut *g).grayagain = o;
|
|
}*/
|
|
|
|
extern "C" {
|
|
pub fn luaC_barrierback(L: *mut lua_State, o: GCObjectPtr, gclist: *mut *mut GCObject);
|
|
|
|
pub fn luaC_barriertable(L: *mut lua_State, t: *mut Table, v: GCObjectPtr);
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub unsafe fn luaC_threadbarrier(L: *mut lua_State) {
|
|
if is_black(L.into()) {
|
|
luaC_barrierback(L, L.into(), &mut (&mut *L).gc_list as *mut _);
|
|
}
|
|
}
|
|
|
|
#[inline(always)]
|
|
pub unsafe fn luaC_barriert(L: *mut lua_State, t: *mut Table, v: *mut TValue) {
|
|
if (*v).is_collectable() {
|
|
debug_assert_eq!((*v).tt, (*(*v).value.gc).gch.tt.into(), "types do not match");
|
|
let v = (*v).value.gc.into();
|
|
if is_black(v) && is_white(v) {
|
|
luaC_barriertable(L, t, v);
|
|
}
|
|
}
|
|
}
|