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
|
||||
# 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
|
||||
# to get correct bounds
|
||||
.equ align_imask, 0b111
|
||||
@@ -34,9 +60,14 @@ heap_oom:
|
||||
.string "Heap ran out of memory!\n"
|
||||
0:
|
||||
|
||||
.word 0f - heap_neg_size
|
||||
heap_neg_size:
|
||||
.string "Negative size given to alloc!\n"
|
||||
0:
|
||||
|
||||
.section .data
|
||||
|
||||
.align 4
|
||||
.align 3
|
||||
.global heap_info # global for testing only
|
||||
.equ heap_last_used, 0 # is the last block used;
|
||||
# matches binfo
|
||||
@@ -78,9 +109,11 @@ heap_init:
|
||||
li a0, 0
|
||||
jal brk
|
||||
andi a0, a0, align_mask
|
||||
blt a0, t1, 1f
|
||||
sub t2, a0, t1 # size = end - start (t2)
|
||||
li t3, sizeof_fb
|
||||
bgeu t2, t3, 0f # check if enough mem to start
|
||||
1:
|
||||
|
||||
move a1, a0
|
||||
add a0, t1, t3
|
||||
@@ -104,6 +137,10 @@ heap_init:
|
||||
addi sp, sp, +8
|
||||
ret
|
||||
|
||||
# TODO: this shouldn't panic if it fails;
|
||||
# instead return null I guess
|
||||
# or maybe return status in a1?
|
||||
|
||||
# args:
|
||||
# a0 - size
|
||||
#
|
||||
@@ -114,6 +151,12 @@ heap_alloc:
|
||||
addi sp, sp, -8
|
||||
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)
|
||||
|
||||
move t0, a0
|
||||
@@ -121,6 +164,13 @@ heap_alloc:
|
||||
addi t0, t0, align_imask
|
||||
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:
|
||||
# get a free block that will fit (t1)
|
||||
# and its free space (t2)
|
||||
@@ -252,11 +302,11 @@ heap_free:
|
||||
# merge with next if possible
|
||||
|
||||
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)
|
||||
andi t1, t1, size_mask # t1 = next size
|
||||
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
|
||||
bnez t6, 0f # skip if used
|
||||
j 2f # if end free, we can use
|
||||
|
||||
@@ -27,7 +27,7 @@ hexstr:
|
||||
|
||||
.global heap_test
|
||||
heap_test:
|
||||
addi sp, sp, -(7*8)
|
||||
addi sp, sp, -(8*8)
|
||||
sd ra, 0(sp)
|
||||
sd s0, 8(sp)
|
||||
sd s1, 16(sp)
|
||||
@@ -35,6 +35,7 @@ heap_test:
|
||||
sd s3, 32(sp)
|
||||
sd s4, 40(sp)
|
||||
sd s5, 48(sp)
|
||||
sd s6, 56(sp)
|
||||
|
||||
# empty heap
|
||||
|
||||
@@ -43,7 +44,7 @@ heap_test:
|
||||
|
||||
# put stuff on heap
|
||||
|
||||
li a0, 8*9
|
||||
li a0, 8*1
|
||||
jal heap_alloc
|
||||
move s2, a0
|
||||
|
||||
@@ -60,7 +61,7 @@ heap_test:
|
||||
|
||||
# put array of stuff on heap
|
||||
|
||||
li s0, 0x0a
|
||||
li s0, 0x04
|
||||
0:
|
||||
bltz s0, 0f
|
||||
|
||||
@@ -92,6 +93,8 @@ heap_test:
|
||||
|
||||
move a0, s2
|
||||
jal heap_free
|
||||
jal print_heap
|
||||
jal printnl
|
||||
move a0, s3
|
||||
jal heap_free
|
||||
move a0, s4
|
||||
@@ -104,11 +107,12 @@ heap_test:
|
||||
ld ra, 0(sp)
|
||||
ld s0, 8(sp)
|
||||
ld s1, 16(sp)
|
||||
sd s2, 24(sp)
|
||||
sd s3, 32(sp)
|
||||
sd s4, 40(sp)
|
||||
sd s5, 48(sp)
|
||||
addi sp, sp, +(7*8)
|
||||
ld s2, 24(sp)
|
||||
ld s3, 32(sp)
|
||||
ld s4, 40(sp)
|
||||
ld s5, 48(sp)
|
||||
ld s6, 56(sp)
|
||||
addi sp, sp, +(8*8)
|
||||
ret
|
||||
|
||||
print_heap:
|
||||
|
||||
Reference in New Issue
Block a user