fixed segfault due to used blocks being smaller than free

This commit is contained in:
Bryan McShea
2022-10-21 01:27:51 -04:00
parent de5c57ef9e
commit 6f0db493c2
2 changed files with 65 additions and 11 deletions

View File

@@ -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

View File

@@ -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: