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