📄 memory-allocator.zc
字号:
//[of]:description
//[c]Simple memory allocator
//[c]
//[c]Currently a simple wrapper to the libc malloc.
//[c]A very basic leak detector is implemented.
//[cf]
//[of]:imports
//[c]
import "libc/malloc"
import "base/types"
import "base/memory"
//[cf]
//[of]:globals
//[c]
//[c]Statistics
//[c]
public def total block : size
public def left block : size
public def left bytes : size
public def max bytes : size
//[cf]
//[c]
//[of]:module initialization
//[of]:initialize allocator
//[c]
public func initialize allocator
first block = nil
total block = 0
left block = 0
left bytes = 0
max bytes = 0
end
//[cf]
//[of]:release allocator
//[c]
public func release allocator
def block = first block
while not nil (block)
def next = next (block)
free (block - head size)
block = next
end
end
//[cf]
//[cf]
//[of]:allocating
//[of]:allocate memory (size)
//[c]Allocates memory
//[c]
public equ allocate memory (size: size) =
raw allocate memory (size)
//[cf]
//[of]:free memory (base)
//[c]Frees a memory block
//[c]
//[c]Deleting a null pointer does nothing but is valid
//[c]
public equ free memory (base: mem) =
raw free memory (base)
//[cf]
//[c]
//[c]For statistics, basic leak detections:
//[of]:stat allocate memory (size)
//[c]Allocates memory
//[c]
private func stat allocate memory (size: size)
def next block = first block
first block = malloc ((size + head size):malloc size):bytes + head size
next (first block) = next block
prev (first block) = nil
size (first block) = size
if not nil (next block)
prev (next block) = first block
end
// statistics
total block += 1
left block += 1
left bytes += size
if left bytes > max bytes
max bytes = left bytes
end
return first block
end
//[cf]
//[of]:stat free memory (base)
//[c]Frees a memory block
//[c]
//[c]Deleting a null pointer does nothing but is valid
//[c]
private func stat free memory (base: mem)
if is nil (base)
return
end
def p = prev (base:bytes)
def n = next (base:bytes)
if not nil (p)
next (p) = n
end
if not nil (n)
prev (n) = p
end
if first block == base
first block = n
end
// statistics
left bytes -= size (base:bytes)
left block -= 1
// now free memory
free (base:bytes - head size)
end
//[cf]
//[c]
//[c]For memory debugging:
//[of]:debug allocate memory (size)
//[c]Allocates memory
//[c]
equ extra = 32
equ uninit = 0xE4:byte
equ wall = 0xE6:byte
//[c]
private func debug allocate memory (size: size)
def next block = first block
first block = malloc ((size + head size + extra):malloc size):bytes + head size
next (first block) = next block
prev (first block) = nil
size (first block) = size
if not nil (next block)
prev (next block) = first block
end
// fill allocated memory with unitialized markers
// plus extra bytes
def p = first block
def limit = p+size
while p < limit
p++[] = uninit
end
limit = p+extra
while p < limit
p++[] = wall
end
// statistics
total block += 1
left block += 1
left bytes += size
if left bytes > max bytes
max bytes = left bytes
end
return first block
end
//[cf]
//[of]:debug free memory (base)
//[c]Frees a memory block
//[c]
//[c]Deleting a null pointer does nothing but is valid
//[c]
private func debug free memory (base: mem)
if is nil (base)
return
end
def p = prev (base:bytes)
def n = next (base:bytes)
def s = size (base:bytes)
if not nil (p)
next (p) = n
end
if not nil (n)
prev (n) = p
end
if first block == base
first block = n
end
// check this block
if s > 0x0fffffff
trap
end
def pp = base:bytes + s
def limit = pp+extra
while pp < limit
if pp++[] <> wall
trap
end
end
check memory
// statistics
left bytes -= size (base:bytes)
left block -= 1
// now free memory
def r = base:bytes
def i = size (base:bytes)
while i > 0
r++ [] = 0xE5:byte
i --
end
free (base:bytes - head size)
end
//[c]
public func check memory
def base = first block
while not nil (base)
def s = size (base:bytes)
def p = base:bytes + s
def limit = p + extra
while p < limit
if p++[] <> wall
trap
end
end
base = next (base)
end
end
//[cf]
//[c]
//[c]The libc allocation functions:
//[of]:raw allocate memory (size)
//[c]Allocates memory
//[c]
private equ raw allocate memory (size: size) =
malloc (size:malloc size):bytes
//[cf]
//[of]:raw free memory (base)
//[c]Frees a memory block
//[c]
private equ raw free memory (base: mem) =
free (base:bytes)
//[cf]
//[cf]
//[c]
//[of]:private
//[of]:types
//[c]
typedef bytes = []byte
//[cf]
//[of]:globals
//[c]
def first block: bytes
//[cf]
//[of]:macros & constants
//[c]
private struct mem head
next: bytes
prev: bytes
size: size
end
equ head size = sizeof (local mem head)
equ next(base:bytes) = next ((base-head size): mem head)
equ prev(base:bytes) = prev ((base-head size): mem head)
equ size(base:bytes) = size ((base-head size): mem head)
//[cf]
//[cf]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -