- GOARM3JIT needs to initialize the codelet "firstfree" pointer (coded)
- GOARM3JIT needs to initialize the first codelet heap entries (coded)
- CODELET macros need to scan for a free codelet block big enough for the requested codelet size (coded)
- Abort handlers need to free any codelets that are replaced by self-modifying code (coded)
- hv_reset_memory_block needs to free any codelets in the region being reset (coded)
- To check for a codelet, look for B <address> where jit_appspace_end < address < jit_code_start (coded)
- Remove code from embedded codelets (partially coded)
Pseudo code for codelet recycling:
Two codelets need to be initialised up front:
lastfree_codelet {lastfree_codelet, lastfree_codelet, <free space size>, 0}
first_codelet {first_codelet, first_codelet, codelet_struct_size, -1}
STRUCT codelet_struct {
.next DCD 0
.previous DCD 0
.size DCD 0
.source DCD 0
.var4 DCD 0
.var3 DCD 0
.var2 DCD 0
.var1 DCD 0
}.previous DCD 0
.size DCD 0
.source DCD 0
.var4 DCD 0
.var3 DCD 0
.var2 DCD 0
.var1 DCD 0
#set codelet_struct_size = 8 * 4
#set min_codelet_size = codelet_struct_size + (4 * 4)
Allocate
pointer allocate(required + heap_struct_size) {
codelet = lastfree_codelet.next
while codelet.size < required
codelet = codelet.next
endwhilefreesize = codelet.size - required
if freesize >= (codelet_struct_size + min_codelet_size) then
codelet.size = freesize
codelet = codelet + freesize
codelet.size = required
else
codelet = codelet + freesize
codelet.size = required
;update previous/next free
(codelet.previous).next = codelet.next
(codelet.next).previous = codelet.previous
endif(codelet.previous).next = codelet.next
(codelet.next).previous = codelet.previous
;update previous/next allocated
codelet.previous = codelet + codelet.size
codelet.next = (codelet.previous).next
(codelet.previous).next = codelet
(codelet.next).previous = codelet
codelet.source = <original instruction address>
return codelet + codelet_struct_size
}
Free
if codelet.code = hypervised_SWI then return
codelet.source = 0
;update previous/next allocated
(codelet.previous).next = codelet.next
(codelet.next).previous = codelet.previous
;find next free
next = lastfree_codelet
repeat
next = next.next
until next < codeletsize = codelet.size
previous = next
;defrag down
if next + next.size = codelet then
size += next.size
codelet = next
next = next.next
endifcodelet = next
next = next.next
;defrag up
previous = previous.previous
if codelet + codelet.size = previous then
size += previous.size
previous = previous.previous
endifprevious = previous.previous
codelet.size = size
;update previous/next free
codelet.next = next
codelet.previous = previous
next.previous = codelet
previous.next = codelet
}