diff --git a/lib/gc.nelua b/lib/gc.nelua index 1a403321..3fe12d68 100644 --- a/lib/gc.nelua +++ b/lib/gc.nelua @@ -13,7 +13,7 @@ local function setjmp(env: jmp_buf) end local allocator = @generic_allocator -local GCFlags = @enum(usize) { +global GCFlags = @enum(usize) { MARK = 1, ROOT = 2, LEAF = 4 @@ -208,6 +208,12 @@ function GC:_resize_less(): boolean end end +function GC:_unmark_all() + for i:usize=0, self.maxptr then return @@ -243,21 +249,11 @@ function GC:_mark_stack() local stk: pointer local bot: usize = (@usize)(self.bottom) local top: usize = (@usize)(&stk) - - if bot == top then - return - end - if bot < top then - for pi:usize=top,>=bot,-#@pointer do - self:_mark_ptr($(@pointer*)(pi)) - end + bot, top = top, bot end - - if bot > top then - for pi:usize=top,<=bot,#@pointer do - self:_mark_ptr($(@pointer*)(pi)) - end + for pi:usize=top,<=bot,#@pointer do + self:_mark_ptr($(@pointer*)(pi)) end end @@ -266,6 +262,8 @@ function GC:_mark() return end + self:_unmark_all() + for i:usize=0, if self.items[i].flags & GCFlags.LEAF ~= 0 then continue end - for k:usize=0, end end - self.frees = allocator.spanrealloc0(self.frees, self.nfrees) + self.frees = allocator.spanrealloc(self.frees, self.nfrees) if self.frees.size == 0 then return end @@ -337,14 +334,7 @@ function GC:_sweep() self.nitems = self.nitems - 1 end - for j:usize=0, self.mitems then self:run() end - return ptr + return true else self.nitems = self.nitems - 1 - allocator.dealloc(ptr) - return nilptr + return false end end @@ -423,20 +412,24 @@ function GC:rem(ptr: pointer) self.mitems = self.nitems + self.nitems // 2 + 1 end -function GC:alloc_opt(size: usize, flags: usize, finalizer: FinalizerPtr): pointer - local ptr: pointer = allocator.alloc(size) +function GC:_alloc(ptr: pointer, size: usize, flags: usize, finalizer: FinalizerPtr): pointer if ptr then - ptr = self:add(ptr, size, flags, finalizer) + if not self:add(ptr, size, flags, finalizer) then + allocator.dealloc(ptr) + ptr = nilptr + end end return ptr end +function GC:alloc_opt(size: usize, flags: usize, finalizer: FinalizerPtr): pointer + local ptr: pointer = allocator.alloc(size) + return self:_alloc(ptr, size, flags, finalizer) +end + function GC:alloc0_opt(size: usize, flags: usize, finalizer: FinalizerPtr): pointer local ptr: pointer = allocator.alloc0(size) - if ptr then - ptr = self:add(ptr, size, flags, finalizer) - end - return ptr + return self:_alloc(ptr, size, flags, finalizer) end function GC:alloc(size: usize): pointer @@ -454,7 +447,10 @@ function GC:_realloc(qtr: pointer, ptr: pointer, size: usize): pointer end if not ptr then - self:add(qtr, size, 0, nilptr) + if not self:add(qtr, size, 0, nilptr) then + allocator.dealloc(qtr) + qtr = nilptr + end return qtr end @@ -536,6 +532,9 @@ global gc = GC{} local function nelua_main(): cint end +local static_top: pointer +local static_bottom: pointer + local function main(argc: cint, argv: cchar**): cint gc:start(&argc) local ret: cint = nelua_main() diff --git a/lib/myarraytable.nelua b/lib/myarraytable.nelua index 3c7a3b9e..24bb1db5 100644 --- a/lib/myarraytable.nelua +++ b/lib/myarraytable.nelua @@ -11,21 +11,29 @@ local allocator = @gc_allocator ## local memoize = require 'nelua.utils.memoize' ## myarraytable = hygienize(memoize(function(T) local T = @#[T]# - local ArrayTableImpl = @record { + local ArrayTableImplT = @record { size: usize, data: span(T) } - local ArrayTable = @record{ - impl: ArrayTableImpl* + global ArrayTableT = @record{ + impl: ArrayTableImplT* } - function ArrayTable:_init() + function ArrayTableT:init() if unlikely(not self.impl) then - self.impl = (@ArrayTableImpl*)(allocator.alloc0(#ArrayTableImpl)) + self.impl = (@ArrayTableImplT*)(allocator.alloc0(#ArrayTableImplT)) end end - function ArrayTable:_grow() + function ArrayTableT:reset() + if likely(self.impl) then + allocator.spandealloc(self.impl.data) + allocator.dealloc(self.impl) + self.impl = nilptr + end + end + + function ArrayTableT:_grow() local cap: usize if self.impl.data.size ~= 0 then cap = self.impl.data.size * 2 @@ -35,16 +43,16 @@ local allocator = @gc_allocator self.impl.data = allocator.spanrealloc(self.impl.data, cap) end - function ArrayTable:reserve(n: usize ) - self:_init() + function ArrayTableT:reserve(n: usize ) + self:init() local cap = n + 1 if self.impl.data.size < cap then self.impl.data = allocator.spanrealloc(self.impl.data, cap) end end - function ArrayTable:resize(n: usize , v: T) - self:_init() + function ArrayTableT:resize(n: usize , v: T) + self:init() local addn = n - self.impl.size if addn > 0 then self:reserve(n) @@ -55,22 +63,17 @@ local allocator = @gc_allocator end end - function ArrayTable:clear() + function ArrayTableT:clear() if likely(self.impl) then self.impl.size = 0 + if likely(self.impl.data.size > 0) then + memory.zero(&self.impl.data[0], #T) + end end end - function ArrayTable:reset() - if likely(self.impl) then - allocator.spandealloc(self.impl.data) - allocator.dealloc(self.impl) - self.impl = nilptr - end - end - - function ArrayTable:push(v: T) - self:_init() + function ArrayTableT:push(v: T) + self:init() self.impl.size = self.impl.size + 1 if unlikely(self.impl.size + 1 >= self.impl.data.size) then self:_grow() @@ -78,15 +81,15 @@ local allocator = @gc_allocator self.impl.data[self.impl.size] = v end - function ArrayTable:pop(): T + function ArrayTableT:pop(): T check(self.impl and self.impl.size > 0, 'arraytable.pop: length is 0') local i = self.impl.size self.impl.size = self.impl.size - 1 return self.impl.data[i] end - function ArrayTable:at(i: usize ): T* - self:_init() + function ArrayTableT:at(i: usize ): T* + self:init() if unlikely(i > self.impl.size) then check(i == self.impl.size + 1, 'arraytable.at: index out of range') self.impl.size = self.impl.size + 1 @@ -98,8 +101,8 @@ local allocator = @gc_allocator return &self.impl.data[i] end - function ArrayTable:set(i: usize , v: T) - self:_init() + function ArrayTableT:set(i: usize , v: T) + self:init() if unlikely(i > self.impl.size) then check(i == self.impl.size + 1, 'arraytable.at: index out of range') self.impl.size = self.impl.size + 1 @@ -110,7 +113,7 @@ local allocator = @gc_allocator self.impl.data[i] = v end - function ArrayTable:get(i: usize ): T + function ArrayTableT:get(i: usize ): T if unlikely(i == 0 and (not self.impl or self.impl.data.size == 0)) then local v: T return v @@ -120,12 +123,12 @@ local allocator = @gc_allocator end end - function ArrayTable:len(): isize + function ArrayTableT:len(): isize if unlikely(not self.impl) then return 0 end return (@isize)(self.impl.size) end - ## return ArrayTable + ## return ArrayTableT ## end))