278 lines
4.8 KiB
PHP
278 lines
4.8 KiB
PHP
;; File: vmem.inc
|
||
;;
|
||
;; General purpose resource allocator.
|
||
;; Based on <tinyvmem at https://github.com/rdmsr/tinyvmem> and on <Bonwick's paper at https://www.usenix.org/legacy/event/usenix01/full_papers/bonwick/bonwick.pdf>
|
||
|
||
;;; MARK: macros and structs
|
||
|
||
VM_BESTFIT = (1 shl 0)
|
||
VM_INSTANTFIT = (1 shl 1)
|
||
VM_NEXTFIT = (1 shl 2)
|
||
VM_SLEEP = (1 shl 3)
|
||
VM_NOSLEEP = (1 shl 4)
|
||
VM_BOOTSTRAP = (1 shl 5)
|
||
|
||
STATIC_SEG_COUNT = 64
|
||
|
||
FREELISTS_N = 4 * 8
|
||
HASHTABLE_N = 16
|
||
|
||
SEGMENT_ALLOCATED = 0
|
||
SEGMENT_FREE = 1
|
||
SEGMENT_SPAN = 2
|
||
|
||
macro GET_LIST reg, N {
|
||
bsr reg, reg
|
||
xor reg, 31
|
||
add reg, -N
|
||
sub reg, 1
|
||
}
|
||
|
||
struc VmSegment {
|
||
.type db ?
|
||
.imported db ?
|
||
.base dd ?
|
||
.size dd ?
|
||
|
||
.spanlist ListEntry
|
||
.seglist ListEntry
|
||
}
|
||
DEFN VmSegment
|
||
|
||
;; Struc: Vmem
|
||
struc Vmem {
|
||
.name db 16 dup(0)
|
||
.base dd ?
|
||
.size dd ?
|
||
.quantum dd ?
|
||
.alloc dd ?
|
||
.free dd ?
|
||
.source dd ?
|
||
.vmflag dd ?
|
||
|
||
.freelist dd FREELISTS_N dup(0)
|
||
.hashtable dd HASHTABLE_N dup(0)
|
||
.spanlist ListHead 0
|
||
}
|
||
DEFN Vmem
|
||
|
||
;;; MARK: private functions
|
||
|
||
;; Function: _murmur32
|
||
;;
|
||
;; In:
|
||
;; EAX - Address
|
||
;;
|
||
;; Out:
|
||
;; EAX - Hash
|
||
;;
|
||
_murmur32:
|
||
; hash ← hash XOR (hash >> 16)
|
||
mov ecx, eax
|
||
shr ecx, 16
|
||
xor eax, ecx
|
||
; hash ← hash × 0x85ebca6b
|
||
mov ecx, 0x85ebca6b
|
||
mul ecx
|
||
; hash ← hash XOR (hash >> 13)
|
||
mov ecx, eax
|
||
shr ecx, 13
|
||
xor eax, ecx
|
||
; hash ← hash × 0xc2b2ae35
|
||
mov ecx, 0xc2b2ae35
|
||
mul ecx
|
||
; hash ← hash XOR (hash >> 16)
|
||
mov ecx, eax
|
||
shr ecx, 16
|
||
xor eax, ecx
|
||
ret
|
||
|
||
;; Function: _hash_table_addr
|
||
;;
|
||
;; In:
|
||
;; EAX - Vmem
|
||
;; EDX - ADDR
|
||
__hash_table_addr:
|
||
push ebp
|
||
mov ebp, esp
|
||
push esi
|
||
|
||
mov esi, eax
|
||
mov eax, edx
|
||
call _murmur32
|
||
and eax, HASHTABLE_N-1 ; x % y (y is a power of two)
|
||
shl eax, 2
|
||
|
||
mov edx, esi
|
||
add edx, Vmem.hashtable
|
||
add edx, eax
|
||
mov eax, [edx]
|
||
|
||
pop esi
|
||
leave
|
||
ret
|
||
|
||
;; Function: _vmm_segfree
|
||
;;
|
||
;; In:
|
||
;; EAX - Segment address
|
||
_vmm_segfree:
|
||
;mov ecx, eax
|
||
;add ecx, VmSegment.seglist.next
|
||
|
||
;mov edx, [pVmmFreeSegHead]
|
||
;or edx, edx
|
||
;jz @f
|
||
;mov [eax + VmSegment.seglist.next], edx
|
||
;mov [edx + VmSegment.seglist.prev], ecx
|
||
;@@:
|
||
; mov [pVmmFreeSegHead], eax
|
||
; mov [eax + VmSegment.seglist.prev], ecx
|
||
;
|
||
; inc [iVmmFreeSegCount]
|
||
ret
|
||
;
|
||
; ;; Function: _vmm_segalloc
|
||
;_vmm_segalloc:
|
||
; mov eax, [pVmmFreeSegHead]
|
||
; or eax, eax
|
||
; jz @f
|
||
;
|
||
; dec [iVmmFreeSegCount]
|
||
;@@:
|
||
; ret
|
||
|
||
|
||
;;; MARK: public functions
|
||
|
||
;; Function: vmem_create
|
||
;;
|
||
;; Creates a new <Vmem> arena whose initial span is [Base, Base + Size).
|
||
;;
|
||
;; In:
|
||
;; EAX - Pointer to a <Vmem> object.
|
||
;; EDX - String.
|
||
;; ECX - Base.
|
||
;; ESP[4] - Size in bytes.
|
||
;; ESP[8] - Quantum.
|
||
;; ESP[12] - Alloc function.
|
||
;; ESP[16] - Free function.
|
||
;; ESP[20] - Source.
|
||
;; ESP[24] - Flags. (<VM_SLEEP> or <VM_NOSLEEP>)
|
||
vmem_create:
|
||
push ebp
|
||
mov ebp, esp
|
||
|
||
mov [eax + Vmem.base], ecx
|
||
|
||
|
||
|
||
if CONFIG_TRACE_VMEM
|
||
push esi
|
||
push edi
|
||
push ebx
|
||
|
||
mov esi, eax
|
||
mov edi, edx
|
||
mov ebx, ecx
|
||
|
||
mov eax, esi
|
||
mov edx, edi
|
||
mov ecx, ebx
|
||
|
||
pop ebx
|
||
pop edi
|
||
pop esi
|
||
end if
|
||
|
||
leave
|
||
ret
|
||
|
||
;; Function: vmem_destroy
|
||
;;
|
||
;; Destroys an arena
|
||
;;
|
||
;; In:
|
||
;; EAX - Pointer to a <Vmem> object.
|
||
vmem_destroy:
|
||
ret
|
||
|
||
;; Function: vmem_alloc
|
||
;;
|
||
;; Allocates n-bytes from arena.
|
||
;;
|
||
;; In:
|
||
;; EAX - Pointer to a <Vmem> object.
|
||
;; EDX - Size in bytes.
|
||
;; ECX - Flags
|
||
;;
|
||
;; Out:
|
||
;; EAX - Allocated address on succes, 0 on failure.
|
||
vmem_alloc:
|
||
ret
|
||
|
||
;; Function: vmem_free
|
||
;;
|
||
;; Free n-bytes at address to arena
|
||
;;
|
||
;; In:
|
||
;; EAX - Pointer to a <Vmem> object.
|
||
;; EDX - Address.
|
||
;; ECX - Size in bytes.
|
||
vmem_free:
|
||
ret
|
||
|
||
;; Function: vmem_xalloc
|
||
;;
|
||
;; In:
|
||
;; EAX - Pointer to a <Vmem> object.
|
||
;; EDX - Size in bytes.
|
||
;; ECX - Alignment boundary.
|
||
;; ESP[4] - Phase.
|
||
;; ESP[8] - Nocross.
|
||
;; ESP[12] - Min address.
|
||
;; ESP[16] - Max address.
|
||
;; ESP[20] - Flags. (<VM_BESTFIT>, <VM_INSTANTFIT>, <VM_NEXTFIT>, <VM_SLEEP>, <VM_NOSLEEP>)
|
||
;;
|
||
;; Out:
|
||
;; EAX - Allocated address on succes, 0 on failure.
|
||
vmem_xalloc:
|
||
ret
|
||
|
||
;; Function: vmem_xfree
|
||
;;
|
||
;; Frees n-bytes at address.
|
||
;;
|
||
;; In:
|
||
;; EAX - Pointer to <Vmem> object.
|
||
;; EDX - Address.
|
||
;; ECX - Size in bytes.
|
||
vmem_xfree:
|
||
ret
|
||
|
||
;; Function: vmem_add
|
||
;;
|
||
;; Adds a span [Address, Address + Size) to an arena.
|
||
;;
|
||
;; In:
|
||
;; EAX - Pointer to <Vmem> object.
|
||
;; EDX - Address.
|
||
;; ECX - Size in bytes.
|
||
;; ESP[4] - Flags. (<VM_SLEEP> or <VM_NOSLEEP>)
|
||
;;
|
||
;; Out:
|
||
;; EAX - Return Address on success, 0 on failure.
|
||
vmem_add:
|
||
ret
|
||
|
||
;;; MARK: variables
|
||
|
||
aVmemStaticSegs db STATIC_SEG_COUNT*sizeof.VmSegment dup(0)
|
||
pVmemFreeSegHead dd 0
|
||
iVmemFreeSegCount dd 0
|
||
|
||
if CONFIG_TRACE_VMM
|
||
szTraceVmemCreate db "Trace(VMEM): Create %s [%x, %x)", 0
|
||
szTraceVmemAdd db "Trace(VMEM): %s: Add span [%x, %x)", 0
|
||
szTraceVmemDestroy db "Trace(VMEM): Destroy %s", 0
|
||
end if
|