fixed segfault due to used blocks being smaller than free
This commit is contained in:
@@ -2,6 +2,32 @@
|
|||||||
# It's slow / unoptimized, and only for
|
# It's slow / unoptimized, and only for
|
||||||
# learning how to set up a basic heap
|
# learning how to set up a basic heap
|
||||||
|
|
||||||
|
# It's also very messy due to trying to
|
||||||
|
# avoiding the usage of s registers;
|
||||||
|
# the point is to improve performance,
|
||||||
|
# because you don't need extra read & writes,
|
||||||
|
# which is pretty pointless because this
|
||||||
|
# is not optimized to be scalable anyways.
|
||||||
|
# This makes debugging it very fun :)
|
||||||
|
|
||||||
|
# If I were to write this in a sane way,
|
||||||
|
# I would break up certain parts into functions.
|
||||||
|
# For example, free would create a new block
|
||||||
|
# from the old block first, then merge with
|
||||||
|
# either side using functions.
|
||||||
|
|
||||||
|
# Unfortunately, I am not sane.
|
||||||
|
|
||||||
|
# Also, I tried to allow for memory up to
|
||||||
|
# 0xffffffffffffffff at some points,
|
||||||
|
# which of course won't happen anyways
|
||||||
|
# because of the stack and the fact that
|
||||||
|
# that address probably won't even exist
|
||||||
|
# in virtual memory, but not at other points,
|
||||||
|
# so if you happen to not have a stack and
|
||||||
|
# the heap gets there, things are prolly
|
||||||
|
# gonna break due to unsigned comparisons :)
|
||||||
|
|
||||||
# mask and imask are used to floor & ceil
|
# mask and imask are used to floor & ceil
|
||||||
# to get correct bounds
|
# to get correct bounds
|
||||||
.equ align_imask, 0b111
|
.equ align_imask, 0b111
|
||||||
@@ -34,9 +60,14 @@ heap_oom:
|
|||||||
.string "Heap ran out of memory!\n"
|
.string "Heap ran out of memory!\n"
|
||||||
0:
|
0:
|
||||||
|
|
||||||
|
.word 0f - heap_neg_size
|
||||||
|
heap_neg_size:
|
||||||
|
.string "Negative size given to alloc!\n"
|
||||||
|
0:
|
||||||
|
|
||||||
.section .data
|
.section .data
|
||||||
|
|
||||||
.align 4
|
.align 3
|
||||||
.global heap_info # global for testing only
|
.global heap_info # global for testing only
|
||||||
.equ heap_last_used, 0 # is the last block used;
|
.equ heap_last_used, 0 # is the last block used;
|
||||||
# matches binfo
|
# matches binfo
|
||||||
@@ -78,9 +109,11 @@ heap_init:
|
|||||||
li a0, 0
|
li a0, 0
|
||||||
jal brk
|
jal brk
|
||||||
andi a0, a0, align_mask
|
andi a0, a0, align_mask
|
||||||
|
blt a0, t1, 1f
|
||||||
sub t2, a0, t1 # size = end - start (t2)
|
sub t2, a0, t1 # size = end - start (t2)
|
||||||
li t3, sizeof_fb
|
li t3, sizeof_fb
|
||||||
bgeu t2, t3, 0f # check if enough mem to start
|
bgeu t2, t3, 0f # check if enough mem to start
|
||||||
|
1:
|
||||||
|
|
||||||
move a1, a0
|
move a1, a0
|
||||||
add a0, t1, t3
|
add a0, t1, t3
|
||||||
@@ -104,6 +137,10 @@ heap_init:
|
|||||||
addi sp, sp, +8
|
addi sp, sp, +8
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
# TODO: this shouldn't panic if it fails;
|
||||||
|
# instead return null I guess
|
||||||
|
# or maybe return status in a1?
|
||||||
|
|
||||||
# args:
|
# args:
|
||||||
# a0 - size
|
# a0 - size
|
||||||
#
|
#
|
||||||
@@ -114,6 +151,12 @@ heap_alloc:
|
|||||||
addi sp, sp, -8
|
addi sp, sp, -8
|
||||||
sd ra, 0(sp)
|
sd ra, 0(sp)
|
||||||
|
|
||||||
|
bgez a0, 0f # panic if negative size
|
||||||
|
la a0, heap_neg_size
|
||||||
|
lw a1, -4(a0)
|
||||||
|
j panic
|
||||||
|
0:
|
||||||
|
|
||||||
# align size properly (t0)
|
# align size properly (t0)
|
||||||
|
|
||||||
move t0, a0
|
move t0, a0
|
||||||
@@ -121,6 +164,13 @@ heap_alloc:
|
|||||||
addi t0, t0, align_imask
|
addi t0, t0, align_imask
|
||||||
andi t0, t0, align_mask
|
andi t0, t0, align_mask
|
||||||
|
|
||||||
|
# increase size if smaller than free block
|
||||||
|
|
||||||
|
li t1, sizeof_fb
|
||||||
|
bge t0, t1, 0f
|
||||||
|
move t0, t1
|
||||||
|
0:
|
||||||
|
|
||||||
# step 1:
|
# step 1:
|
||||||
# get a free block that will fit (t1)
|
# get a free block that will fit (t1)
|
||||||
# and its free space (t2)
|
# and its free space (t2)
|
||||||
@@ -252,11 +302,11 @@ heap_free:
|
|||||||
# merge with next if possible
|
# merge with next if possible
|
||||||
|
|
||||||
add t2, a0, t0 # t2 = next block
|
add t2, a0, t0 # t2 = next block
|
||||||
bge t2, t4, 0f # skip if end
|
bgeu t2, t4, 0f # skip if end
|
||||||
ld t1, binfo(t2)
|
ld t1, binfo(t2)
|
||||||
andi t1, t1, size_mask # t1 = next size
|
andi t1, t1, size_mask # t1 = next size
|
||||||
add t6, t2, t1 # t6 = next next block
|
add t6, t2, t1 # t6 = next next block
|
||||||
blt t6, t4, 1f # if end:
|
bltu t6, t4, 1f # if end:
|
||||||
ld t6, binfo(t3) # t6 = last block is used
|
ld t6, binfo(t3) # t6 = last block is used
|
||||||
bnez t6, 0f # skip if used
|
bnez t6, 0f # skip if used
|
||||||
j 2f # if end free, we can use
|
j 2f # if end free, we can use
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ hexstr:
|
|||||||
|
|
||||||
.global heap_test
|
.global heap_test
|
||||||
heap_test:
|
heap_test:
|
||||||
addi sp, sp, -(7*8)
|
addi sp, sp, -(8*8)
|
||||||
sd ra, 0(sp)
|
sd ra, 0(sp)
|
||||||
sd s0, 8(sp)
|
sd s0, 8(sp)
|
||||||
sd s1, 16(sp)
|
sd s1, 16(sp)
|
||||||
@@ -35,6 +35,7 @@ heap_test:
|
|||||||
sd s3, 32(sp)
|
sd s3, 32(sp)
|
||||||
sd s4, 40(sp)
|
sd s4, 40(sp)
|
||||||
sd s5, 48(sp)
|
sd s5, 48(sp)
|
||||||
|
sd s6, 56(sp)
|
||||||
|
|
||||||
# empty heap
|
# empty heap
|
||||||
|
|
||||||
@@ -43,7 +44,7 @@ heap_test:
|
|||||||
|
|
||||||
# put stuff on heap
|
# put stuff on heap
|
||||||
|
|
||||||
li a0, 8*9
|
li a0, 8*1
|
||||||
jal heap_alloc
|
jal heap_alloc
|
||||||
move s2, a0
|
move s2, a0
|
||||||
|
|
||||||
@@ -60,7 +61,7 @@ heap_test:
|
|||||||
|
|
||||||
# put array of stuff on heap
|
# put array of stuff on heap
|
||||||
|
|
||||||
li s0, 0x0a
|
li s0, 0x04
|
||||||
0:
|
0:
|
||||||
bltz s0, 0f
|
bltz s0, 0f
|
||||||
|
|
||||||
@@ -92,6 +93,8 @@ heap_test:
|
|||||||
|
|
||||||
move a0, s2
|
move a0, s2
|
||||||
jal heap_free
|
jal heap_free
|
||||||
|
jal print_heap
|
||||||
|
jal printnl
|
||||||
move a0, s3
|
move a0, s3
|
||||||
jal heap_free
|
jal heap_free
|
||||||
move a0, s4
|
move a0, s4
|
||||||
@@ -104,11 +107,12 @@ heap_test:
|
|||||||
ld ra, 0(sp)
|
ld ra, 0(sp)
|
||||||
ld s0, 8(sp)
|
ld s0, 8(sp)
|
||||||
ld s1, 16(sp)
|
ld s1, 16(sp)
|
||||||
sd s2, 24(sp)
|
ld s2, 24(sp)
|
||||||
sd s3, 32(sp)
|
ld s3, 32(sp)
|
||||||
sd s4, 40(sp)
|
ld s4, 40(sp)
|
||||||
sd s5, 48(sp)
|
ld s5, 48(sp)
|
||||||
addi sp, sp, +(7*8)
|
ld s6, 56(sp)
|
||||||
|
addi sp, sp, +(8*8)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
print_heap:
|
print_heap:
|
||||||
|
|||||||
Reference in New Issue
Block a user