Skip to content

Commit 558dc02

Browse files
committed
scheduled commit
1 parent 46bc69c commit 558dc02

File tree

1 file changed

+37
-45
lines changed

1 file changed

+37
-45
lines changed

algo/freelist.inc

+37-45
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
;
77
; requirements:
88
; g_sysinf SYSTEM_INFO ; populated global structure
9-
;
10-
; TODO: reuse handler code for initialization
119

1210
virtual DATA.64
1311
FreeList__block_bytes dq 64 ; 64, freelist item size
@@ -25,7 +23,7 @@ namespace FreeList
2523

2624
REGISTER equ r15 ; default global get/set register (or state explicitly)
2725

28-
; these two function are why freelist
26+
; this is why freelists are used - these two macros
2927
macro get reg0*, reg1:FreeList.REGISTER
3028
mov reg0, reg1
3129
mov reg1, [reg1]
@@ -35,6 +33,40 @@ macro put reg0*, reg1:FreeList.REGISTER
3533
mov reg1, reg0
3634
end macro
3735

36+
; The default is to configure through global variables, and let the OS
37+
; select a base address.
38+
macro initialize total_bytes:[FreeList__total_bytes],\
39+
start_address:0
40+
local fail
41+
; setup exception handler as first in hierarchy
42+
AddVectoredExceptionHandler 1, & FreeList.Handler
43+
mov [FreeList__hVector], rax
44+
xchg rcx, rax
45+
jrcxz fail
46+
47+
; set region start/size here
48+
mov rdx, total_bytes
49+
mov [FreeList__end_address], rdx
50+
VirtualAlloc start_address, rdx, MEM_RESERVE, PAGE_NOACCESS
51+
xchg rcx, rax
52+
jrcxz fail
53+
mov [FreeList__base_address], rcx
54+
add [FreeList__end_address], rcx
55+
call FreeList.Handler.extend
56+
mov FreeList.REGISTER, [FreeList__base_address]
57+
xchg ecx, eax
58+
fail:
59+
purge FreeList.initialize
60+
end macro ; RCX zero on error
61+
62+
macro destroy
63+
RemoveVectoredExceptionHandler [FreeList__hVector]
64+
VirtualFree [FreeList__base_address], 0, MEM_RELEASE
65+
purge FreeList.destroy
66+
end macro
67+
68+
69+
; Chaining is only used by the Handler.
3870
; NOTE: `base` is advanced to address after `bytes`
3971
macro chain base*, reg0*, reg1*, bytes:[g_sysinf.dwAllocationGranularity]
4072
local more
@@ -47,7 +79,6 @@ more: mov reg0, base
4779
jnz more
4880
end macro
4981

50-
5182
; TODO: test if just handling EXCEPTION_ACCESS_VIOLATION is the same?
5283
; NOTE: Cannot be used during a system service.
5384
;
@@ -78,7 +109,7 @@ Handler:
78109
; system removes the `PAGE_GUARD` status, commit next granule, set next guard page
79110
; invalidate guard address, no guard page set
80111
and [FreeList__guard_address], 0
81-
112+
.extend:
82113
virtual at rbp - .frame
83114
rq 4
84115
.frame := $ - $$
@@ -92,7 +123,7 @@ Handler:
92123
; create free blocks
93124
chain rcx, rdx, rax, [g_sysinf.dwAllocationGranularity]
94125

95-
; no guard page possible for large allocation unit
126+
; no guard page possible for last allocation unit
96127
cmp rcx, [FreeList__end_address]
97128
jz .execute
98129
VirtualAlloc rcx, dword [g_sysinf.dwPageSize],\
@@ -101,7 +132,6 @@ Handler:
101132
jrcxz .commit_fail
102133
mov [FreeList__guard_address], rcx
103134
.execute:
104-
; moved guard page, okay to continue
105135
assert (EXCEPTION_CONTINUE_EXECUTION and 0xFFFF_FFFF) = 0xFFFF_FFFF
106136
or eax, EXCEPTION_CONTINUE_EXECUTION
107137
leave
@@ -111,42 +141,4 @@ Handler:
111141
leave
112142
jmp .search
113143

114-
115-
; The default is to configure through global variables, and let the OS
116-
; select a base address.
117-
macro initialize total_bytes:[FreeList__total_bytes],\
118-
start_bytes:dword [g_sysinf.dwAllocationGranularity],\
119-
start_address:0
120-
local fail0,fail
121-
; setup exception handler as first in hierarchy
122-
AddVectoredExceptionHandler 1, & FreeList.Handler
123-
mov [FreeList__hVector], rax
124-
xchg rcx, rax
125-
jrcxz fail0
126-
127-
; set region start/size here
128-
mov rdx, total_bytes
129-
mov [FreeList__end_address], rdx
130-
VirtualAlloc start_address, rdx, MEM_RESERVE, PAGE_NOACCESS
131-
xchg rcx, rax
132-
fail0:
133-
jrcxz fail
134-
VirtualAlloc rcx, start_bytes, MEM_COMMIT, PAGE_READWRITE
135-
xchg rcx, rax
136-
jrcxz fail
137-
; update start/end addresses
138-
mov [FreeList__base_address], rcx
139-
add [FreeList__end_address], rcx
140-
141-
; create free blocks
142-
FreeList.chain rcx, rdx, rax, [g_sysinf.dwAllocationGranularity]
143-
144-
VirtualAlloc rcx, dword [g_sysinf.dwPageSize],\
145-
MEM_COMMIT, PAGE_READWRITE or PAGE_GUARD
146-
xchg rcx, rax
147-
mov [FreeList__guard_address], rcx
148-
mov FreeList.REGISTER, [FreeList__base_address]
149-
fail:
150-
end macro ; RCX zero on error
151-
152144
end namespace ; FreeList

0 commit comments

Comments
 (0)