changed calling convention for memlib to stack
This commit is contained in:
parent
e9b91f2152
commit
9baff2d080
|
@ -1,5 +1,5 @@
|
|||
fst_ptr <- 28
|
||||
slot1 <- 32
|
||||
fst_ptr <- 0
|
||||
slot1 <- 4
|
||||
header <- 8
|
||||
off_oref <- -8
|
||||
off_osize <- -4
|
||||
|
@ -14,8 +14,8 @@ off_size <- 4
|
|||
// pointer to the first free slot at `#fst_ptr` and one free slot at `#slot1` of size
|
||||
// `brk-slot1-header`. When a piece of memory is requested for allocation, a tuple
|
||||
// `(reference count, size)` followed by `size` bytes for the object is formed. The calling
|
||||
// convention of the functions in this library consists of storing the return address at #0,
|
||||
// arguments at #4, #8 and #12 and return values (if any) at #16, #20 and #24.
|
||||
// convention of the functions in this library consists of pushing the return address followed by
|
||||
// any arguments (in order) to the stack. Any return values will be pushed to the stack likewise.
|
||||
//
|
||||
// Requires a register `brk` for the highest address available for heap allocation.
|
||||
// Requires an instruction `halt` when memory runs out
|
||||
|
@ -38,7 +38,7 @@ memlib_: loadI 0 => m_0
|
|||
// least #4+16
|
||||
// memory: [return address, object size] -> [object address]
|
||||
memalloc: loadI 0 => m_0
|
||||
loadAI m_0,4 => m_s // load size from #4
|
||||
pop => m_s // load size
|
||||
loadI @fst_ptr => m_p // load previous address (base pointer)
|
||||
loadAI m_p,@off_next => m_c // load current address (first slot)
|
||||
|
||||
|
@ -70,30 +70,31 @@ ma_final: storeAI m_n => m_p,@off_next // link previous free slot to n
|
|||
loadI 1 => m_1
|
||||
storeAI m_1 => m_c,@off_oref // set reference count to 1
|
||||
storeAI m_s => m_c,@off_osize // set object size
|
||||
ma_null: storeAI m_c => m_0,16 // store object address at #16
|
||||
loadAI m_0,0 => m_r // load return address from #0
|
||||
jump -> m_r
|
||||
ma_null: pop => m_1 // load return address
|
||||
push m_c // store object address
|
||||
jump -> m_1
|
||||
|
||||
|
||||
|
||||
// increase reference count of object
|
||||
// memory: [return address, object address] -> []
|
||||
memaddref: loadI 0 => m_0
|
||||
loadAI m_0,4 => m_n // load object address from #4
|
||||
pop => m_n // load object address
|
||||
cmp_EQ m_0,m_n => m_1
|
||||
cbr m_1 -> mr_ynul,mr_nnul // check if null pointer
|
||||
mr_ynul: haltI 1865445997
|
||||
mr_nnul: loadAI m_n,@off_oref => m_1
|
||||
addI m_1,1 => m_1
|
||||
storeAI m_1 => m_n,@off_oref
|
||||
loadAI m_0,0 => m_r // load return address from #0
|
||||
jump -> m_r
|
||||
pop => m_1 // load return address
|
||||
jump -> m_1
|
||||
|
||||
|
||||
// decrease reference count of object
|
||||
// frees memory if count goes to zero
|
||||
// memory: [return address, object address] -> []
|
||||
memfree: loadI 0 => m_0
|
||||
loadAI m_0,4 => m_n // load object from #4
|
||||
pop => m_n // load object address
|
||||
cmp_EQ m_0,m_n => m_1
|
||||
cbr m_1 -> mf_ynul,mf_nnul // check if null pointer
|
||||
mf_ynul: haltI 1865442925
|
||||
|
@ -103,8 +104,8 @@ mf_nnul: loadAI m_n,@off_oref => m_1
|
|||
cbr m_1 -> mf_exit,mf_free
|
||||
|
||||
mf_exit: storeAI m_1 => m_n,@off_oref
|
||||
loadAI m_0,0 => m_r // load return address from #0
|
||||
jump -> m_r
|
||||
pop => m_1 // load return address
|
||||
jump -> m_1
|
||||
|
||||
mf_free: subI m_n,@header => m_n
|
||||
loadI @fst_ptr => m_p
|
||||
|
@ -143,18 +144,19 @@ mf_ynxt: loadAI m_c,@off_size => m_2 // merge with next free slot
|
|||
storeAI m_1 => m_n,@off_size
|
||||
loadAI m_c,@off_next => m_1
|
||||
storeAI m_1 => m_n,@off_next // move link of next's next to new free slot
|
||||
jumpI -> mf_exit
|
||||
pop => m_1 // load return address
|
||||
jump -> m_1
|
||||
mf_nnxt: storeAI m_c => m_n,@off_next // link new free slot with next
|
||||
loadAI m_0,0 => m_r // load return address from #0
|
||||
jump -> m_r
|
||||
pop => m_1 // load return address
|
||||
jump -> m_1
|
||||
|
||||
|
||||
// copy object to location
|
||||
// memory: [return address, object address, destination] -> []
|
||||
memcopy: loadI 0 => m_0
|
||||
haltI 1835626101 // unimplemented
|
||||
loadAI m_0,0 => m_r // load return address from #0
|
||||
jump -> m_r
|
||||
pop => m_1 // load return address
|
||||
jump -> m_1
|
||||
|
||||
|
||||
ememlib_: nop
|
||||
|
|
|
@ -22,8 +22,8 @@ public class ILOCAllocatorTest {
|
|||
*/
|
||||
private static final int FREEMEM = 0XFF;
|
||||
private static final int HEADER = 8;
|
||||
private static final int FIRSTPTR = 28;
|
||||
private static final int FIRSTSLOT = 32;
|
||||
private static final int FIRSTPTR = 0;
|
||||
private static final int FIRSTSLOT = 4;
|
||||
private static final int SIZEOFFSET = 4;
|
||||
private static final int REFOFFSET = -8;
|
||||
|
||||
|
@ -35,13 +35,12 @@ public class ILOCAllocatorTest {
|
|||
private String malloc(int size, String reg) {
|
||||
returnAddress++;
|
||||
String s = "";
|
||||
s += "loadI 0 => r0\n";
|
||||
s += "loadI " + size + " => r1\n";
|
||||
s += "storeAI r1 => r0, 4\n";
|
||||
s += "loadI #end" + returnAddress + " => r2\n";
|
||||
s += "storeAI r2 => r0, 0\n";
|
||||
s += "push r2\n";
|
||||
s += "loadI " + size + " => r1\n";
|
||||
s += "push r1\n";
|
||||
s += "jumpI -> memalloc\n";
|
||||
s += "end" + returnAddress + ": loadAI r0,16 => " + reg + "\n";
|
||||
s += "end" + returnAddress + ": pop => " + reg + "\n";
|
||||
if (size >= 4) {
|
||||
s += "loadI " + 0xDADACAFE + " => r2\n";
|
||||
s += "storeAI r2 => " + reg + ",0\n";
|
||||
|
@ -53,10 +52,9 @@ public class ILOCAllocatorTest {
|
|||
private String incRef(String reg) {
|
||||
returnAddress++;
|
||||
String s = "";
|
||||
s += "loadI 0 => r0\n";
|
||||
s += "storeAI " + reg + " => r0, 4\n";
|
||||
s += "loadI #end" + returnAddress + " => r2\n";
|
||||
s += "storeAI r2 => r0, 0\n";
|
||||
s += "push r2\n";
|
||||
s += "push " + reg + "\n";
|
||||
s += "jumpI -> memaddref\n";
|
||||
s += "end" + returnAddress + ": nop\n";
|
||||
s += "\n";
|
||||
|
@ -66,10 +64,9 @@ public class ILOCAllocatorTest {
|
|||
private String free(String reg) {
|
||||
returnAddress++;
|
||||
String s = "";
|
||||
s += "loadI 0 => r0\n";
|
||||
s += "storeAI " + reg + " => r0, 4\n";
|
||||
s += "loadI #end" + returnAddress + " => r2\n";
|
||||
s += "storeAI r2 => r0, 0\n";
|
||||
s += "push r2\n";
|
||||
s += "push " + reg + "\n";
|
||||
s += "jumpI -> memfree\n";
|
||||
s += "end" + returnAddress + ": nop\n";
|
||||
s += "\n";
|
||||
|
@ -109,6 +106,7 @@ public class ILOCAllocatorTest {
|
|||
*/
|
||||
@Test
|
||||
public void simpleMallocFree() {
|
||||
// Simulator.DEBUG = true;
|
||||
sim(malloc(11, obj1));
|
||||
assertThat(vm.getInterrupt(), is(0));
|
||||
assertThat(vm.load(FIRSTPTR), is(not(FIRSTSLOT)));
|
||||
|
@ -144,10 +142,10 @@ public class ILOCAllocatorTest {
|
|||
sim(malloc(11, obj1) + free(obj1) + free(obj1));
|
||||
assertThat(vm.getInterrupt(), is(not(0)));
|
||||
|
||||
sim(malloc(11, obj1) + incRef("r0"));
|
||||
sim(malloc(11, obj1) + incRef("m_0"));
|
||||
assertThat(vm.getInterrupt(), is(not(0)));
|
||||
|
||||
sim(malloc(11, obj1) + free("r0"));
|
||||
sim(malloc(11, obj1) + free("m_0"));
|
||||
assertThat(vm.getInterrupt(), is(not(0)));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue