Skip to content

Commit 1399788

Browse files
committed
First attempt at realloc, may be buggy
1 parent ddda9cd commit 1399788

File tree

2 files changed

+185
-2
lines changed

2 files changed

+185
-2
lines changed

src/00/jumptable.config

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Do NOT modify entries that belong to an older version
33
# All listed entries must have accompanying documentation before tagging a new version change
44

5-
### Version 1.0.0 (not released - modification permitted)
5+
### Version 0.6.3 - DO NOT MODIFY
66

77
# System
88
boot
@@ -13,7 +13,6 @@
1313
calloc
1414
memset
1515
memcheck
16-
memoryAvailable
1716
memSeekToStart
1817
memSeekToEnd
1918
reassignMemory
@@ -181,3 +180,9 @@
181180
condWait
182181
condNotifyAll
183182
condNotifyOne
183+
184+
### Version 0.6.4 - OK to modify
185+
186+
# Memory
187+
realloc
188+
memoryAvailable

src/00/memory.asm

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ malloc:
359359
ld (hl), e \ inc hl
360360
ld (hl), d ; Pointer to footer
361361
.finish:
362+
; Note: Don't change this unless you also change realloc
362363
pop bc
363364
pop de
364365
pop hl
@@ -505,3 +506,180 @@ _: pop af
505506
ld (hl), d
506507
; Forward merge complete!
507508
jr .check_previous_block
509+
510+
;; realloc [System]
511+
;; Reallocates a block of memory at a different size and returns a new pointer.
512+
;; Inputs:
513+
;; IX: Block to resize
514+
;; BC: New size
515+
;; Outputs:
516+
;; IX: New memory
517+
;; Z: Reset on failure, set on success
518+
;; A: Preserved if success, error code if failure
519+
;; Notes:
520+
;; This function may have to move the memory that you've allocated. Consider the old pointer invalid and use
521+
;; the one returned from realloc instead.
522+
realloc:
523+
push af
524+
ld a, i
525+
push af
526+
di
527+
push hl
528+
push de
529+
push bc
530+
xor a \ cp b \ jr nz, _
531+
cp c \ jp z, .just_free_it ; Free if zero
532+
_: ld l, (ix + -2)
533+
ld h, (ix + -1)
534+
; Check for what case we're handling
535+
or a
536+
sbc hl, bc
537+
jr z, .dont_resize
538+
jr c, .resize_grow
539+
.resize_shrink:
540+
; BC is the leftover amount after we make it smaller
541+
; If it's less than 5, don't bother because we'll get a dead spot
542+
xor a \ cp b
543+
jr nz, _
544+
ld a, 5 \ cp c
545+
jr z, .dont_resize
546+
; Okay, we're fine. Continue.
547+
push ix
548+
add ix, bc
549+
pop hl \ push hl
550+
dec hl \ dec hl \ dec hl
551+
ld (ix), l
552+
ld (ix + 1), h
553+
ld a, 0xFE
554+
ld (ix + 2), a ; Create to-be-freed block
555+
dec bc \ dec bc \ dec bc \ dec bc \ dec bc
556+
ld (ix + 3), c ; Size of free block
557+
ld (ix + 4), b
558+
; Write free block footer
559+
push ix \ pop hl
560+
inc hl \ inc hl
561+
add ix, bc
562+
; IX is now at footer-5
563+
ld (ix + 5), l
564+
ld (ix + 6), h
565+
push hl \ pop ix
566+
ld bc, 3 \ add ix, bc
567+
; Join newly created free block with adjacent blocks if possible
568+
; NOTE: This calls free while the state of memory is _invalid_!
569+
call free
570+
pop ix
571+
pop bc
572+
ld (ix + -2), c
573+
ld (ix + -1), b ; Write new size of original block
574+
jr _
575+
.dont_resize:
576+
; Note: Don't change this unless you also change malloc
577+
pop bc
578+
_: pop de
579+
pop hl
580+
pop af
581+
jp po, _
582+
ei
583+
_: pop af
584+
ret
585+
.just_free_it:
586+
pop bc
587+
pop de
588+
pop hl
589+
pop af
590+
jp po, _
591+
ei
592+
_: pop af
593+
jp free
594+
.resize_grow:
595+
#define prev_block_ptr kernelGarbage
596+
#define next_block_ptr kernelGarbage + 2
597+
; First, we check to see if we can fit it by expanding into a free block
598+
; to the left of this one, and potentially including the block to the right
599+
; If so, we do just that. If not, we just malloc it elsewhere and copy it
600+
; over, then free the original block.
601+
602+
ld (prev_block_ptr), ix
603+
ld (next_block_ptr), ix ; In case can can't use them
604+
ld c, (ix + -2)
605+
ld b, (ix + -1) ; Set BC to current size
606+
call .add_next_block
607+
call .add_prev_block
608+
pop de \ push de
609+
; BC is now the maximum potential size, DE is the desired size, see if it'll fit
610+
call cpBCDE
611+
jr c, .manual_realloc
612+
; We can expand!
613+
; The procedure is to use the previous block as the new one
614+
; We'll change its size to the desired one, and move the contents of memory over
615+
; But we'll leave it marked as "free" and then hand it over to malloc, and that's it!
616+
ld c, (ix + -2)
617+
ld b, (ix + -1) ; Set BC to current size
618+
push de
619+
ld hl, (prev_block_ptr)
620+
ex de, hl
621+
push ix \ pop hl
622+
call cpHLDE
623+
jr z, _ ; Skip memory move if we can't move backwards
624+
ldir
625+
jr ++_
626+
_: pop de
627+
_: ld hl, (prev_block_ptr)
628+
jp do_allocate@malloc ; Hand it over to malloc to finish the job
629+
.manual_realloc:
630+
; We can't expand into neighboring sections so we have to do a manual realloc/copy/free
631+
push ix \ pop hl
632+
ld c, (ix + -2)
633+
ld b, (ix + -1) ; Set BC to current size
634+
push ix
635+
push bc
636+
ld b, d \ ld c, e
637+
call malloc
638+
pop bc
639+
ldir
640+
push ix \ pop de
641+
pop ix
642+
call free
643+
push de \ pop ix
644+
jp .dont_resize ; (we're done)
645+
.add_next_block:
646+
push ix \ pop hl
647+
add hl, bc
648+
inc hl \ inc hl
649+
ld a, 0x80
650+
cp h
651+
ret nc ; We went past the end of memory
652+
ld (next_block_ptr), hl
653+
ld a, (hl)
654+
cp 0xFF
655+
ret nz ; Not free
656+
inc hl
657+
; HL points to size of next block
658+
ld e, (hl) \ inc hl
659+
ld d, (hl) \ ex de, hl
660+
add hl, bc
661+
ld b, h \ ld c, l
662+
inc bc \ inc bc \ inc bc \ inc bc \ inc bc ; Factor in removed headers
663+
ret
664+
.add_prev_block:
665+
push ix \ pop hl
666+
dec hl \ ld d, (hl)
667+
dec hl \ ld e, (hl)
668+
; DE points to header of previous block
669+
ld a, 0x80
670+
cp d
671+
ret nc ; We went past the start of memory
672+
ex de, hl
673+
ld (prev_block_ptr), hl
674+
ld a, (hl)
675+
cp 0xFF
676+
ret nz ; Not free
677+
inc hl
678+
ld e, (hl) \ inc hl
679+
ld d, (hl) \ ex de, hl
680+
add hl, de
681+
ld c, h \ ld b, l
682+
inc bc \ inc bc \ inc bc \ inc bc \ inc bc ; Factor in removed headers
683+
ret
684+
#undefine prev_block_ptr
685+
#undefine next_block_ptr

0 commit comments

Comments
 (0)