Change heap layout for vector delete
This commit is contained in:
parent
7858c2135b
commit
291ff890e6
280
include/crt.c
280
include/crt.c
|
@ -4118,26 +4118,21 @@ void HeapStart, HeapEnd;
|
||||||
bool HeapInit;
|
bool HeapInit;
|
||||||
|
|
||||||
struct Heap {
|
struct Heap {
|
||||||
Heap * next;
|
Heap * next, * end;
|
||||||
unsigned size;
|
|
||||||
} HeapNode;
|
} HeapNode;
|
||||||
|
|
||||||
#pragma section(heap, 0x0000, HeapStart, HeapEnd)
|
#pragma section(heap, 0x0000, HeapStart, HeapEnd)
|
||||||
|
|
||||||
__asm malloc
|
__asm malloc
|
||||||
{
|
{
|
||||||
// round size to be a multiple of four
|
// make room for two additional bytes
|
||||||
// and make room for two additional bytes
|
// to store pointer to end of used memory
|
||||||
// to store size of memory node
|
|
||||||
|
|
||||||
clc
|
clc
|
||||||
lda accu + 0
|
lda accu + 0
|
||||||
sta tmp + 4
|
adc #2
|
||||||
adc #$05
|
|
||||||
and #$fc
|
|
||||||
sta tmp
|
sta tmp
|
||||||
lda accu + 1
|
lda accu + 1
|
||||||
sta tmp + 5
|
|
||||||
adc #$00
|
adc #$00
|
||||||
sta tmp + 1
|
sta tmp + 1
|
||||||
|
|
||||||
|
@ -4166,13 +4161,10 @@ __asm malloc
|
||||||
lda #>HeapStart
|
lda #>HeapStart
|
||||||
sta HeapNode + 1
|
sta HeapNode + 1
|
||||||
|
|
||||||
// set size to size of heap
|
// set end of memory block to end of heap
|
||||||
sec
|
|
||||||
lda #<HeapEnd
|
lda #<HeapEnd
|
||||||
sbc #<HeapStart
|
|
||||||
sta HeapStart + 2
|
sta HeapStart + 2
|
||||||
lda #>HeapEnd
|
lda #>HeapEnd
|
||||||
sbc #>HeapStart
|
|
||||||
sta HeapStart + 3
|
sta HeapStart + 3
|
||||||
|
|
||||||
hasHeap:
|
hasHeap:
|
||||||
|
@ -4181,57 +4173,79 @@ hasHeap:
|
||||||
// perfect fit
|
// perfect fit
|
||||||
|
|
||||||
lda #<HeapNode
|
lda #<HeapNode
|
||||||
sta accu + 2
|
ldx #>HeapNode
|
||||||
lda #>HeapNode
|
|
||||||
sta accu + 3
|
|
||||||
|
|
||||||
// Now loop over free nodes, until we find a match
|
// Now loop over free nodes, until we find a match
|
||||||
loop:
|
loop:
|
||||||
|
sta accu + 2
|
||||||
|
stx accu + 3
|
||||||
|
|
||||||
// next heap block
|
// next heap block
|
||||||
|
|
||||||
|
// calculate potential end of block
|
||||||
|
|
||||||
|
clc
|
||||||
ldy #0
|
ldy #0
|
||||||
lda (accu + 2), y
|
lda (accu + 2), y
|
||||||
sta accu
|
sta accu + 0
|
||||||
|
adc tmp
|
||||||
|
sta tmp + 2
|
||||||
iny
|
iny
|
||||||
lda (accu + 2), y
|
lda (accu + 2), y
|
||||||
sta accu + 1
|
sta accu + 1
|
||||||
|
|
||||||
// exit if out of blocks
|
// exit if out of blocks
|
||||||
|
beq done
|
||||||
beq done
|
adc tmp + 1
|
||||||
// calculate remaining size of heap block
|
|
||||||
|
|
||||||
ldy #2
|
|
||||||
sec
|
|
||||||
lda (accu), y
|
|
||||||
sbc tmp
|
|
||||||
sta tmp + 2
|
|
||||||
iny
|
|
||||||
lda (accu), y
|
|
||||||
sbc tmp + 1
|
|
||||||
sta tmp + 3
|
sta tmp + 3
|
||||||
|
|
||||||
// will fit
|
|
||||||
|
// Check if in range of current free block
|
||||||
|
|
||||||
|
ldy #2
|
||||||
|
lda (accu), y
|
||||||
|
cmp tmp + 2
|
||||||
|
iny
|
||||||
|
lda (accu), y
|
||||||
|
sbc tmp + 3
|
||||||
bcs avail
|
bcs avail
|
||||||
|
|
||||||
// prev
|
// move current block pointer to prev pointer
|
||||||
|
|
||||||
lda accu
|
lda accu
|
||||||
sta accu + 2
|
ldx accu + 1
|
||||||
lda accu + 1
|
|
||||||
sta accu + 3
|
|
||||||
jmp loop
|
jmp loop
|
||||||
|
|
||||||
done:
|
done:
|
||||||
// no more heap blocks
|
// no more heap blocks
|
||||||
rts
|
rts
|
||||||
|
|
||||||
avail:
|
avail:
|
||||||
// is it a perfect fit?
|
// calculate new end of block
|
||||||
|
|
||||||
|
clc
|
||||||
lda tmp + 2
|
lda tmp + 2
|
||||||
ora tmp + 3
|
adc #3
|
||||||
|
and #$fc
|
||||||
|
sta tmp + 4
|
||||||
|
lda tmp + 3
|
||||||
|
adc #0
|
||||||
|
sta tmp + 5
|
||||||
|
|
||||||
|
// compare with end of free block
|
||||||
|
|
||||||
|
ldy #2
|
||||||
|
lda tmp + 4
|
||||||
|
cmp (accu), y
|
||||||
|
bne nofit
|
||||||
|
iny
|
||||||
|
lda tmp + 5
|
||||||
|
cmp (accu), y
|
||||||
bne nofit
|
bne nofit
|
||||||
|
|
||||||
// so adjust previous pointer to point to
|
// perfect fit, so have previous block point to
|
||||||
// next heap block
|
// next free block
|
||||||
|
|
||||||
ldy #0
|
ldy #0
|
||||||
lda (accu), y
|
lda (accu), y
|
||||||
sta (accu + 2), y
|
sta (accu + 2), y
|
||||||
|
@ -4241,42 +4255,42 @@ avail:
|
||||||
jmp found
|
jmp found
|
||||||
|
|
||||||
nofit:
|
nofit:
|
||||||
// adjust size of remaining heapblock
|
// set next link in new link block
|
||||||
ldy #2
|
|
||||||
|
ldy #0
|
||||||
|
lda (accu), y
|
||||||
|
sta (tmp + 4), y
|
||||||
|
lda tmp + 4
|
||||||
|
sta (accu + 2), y
|
||||||
|
iny
|
||||||
|
lda (accu), y
|
||||||
|
sta (tmp + 4), y
|
||||||
|
lda tmp + 5
|
||||||
|
sta (accu + 2), y
|
||||||
|
|
||||||
|
// set new end of remaining block
|
||||||
|
iny
|
||||||
|
lda (accu), y
|
||||||
|
sta (tmp + 4), y
|
||||||
|
iny
|
||||||
|
lda (accu), y
|
||||||
|
sta (tmp + 4), y
|
||||||
|
|
||||||
|
found:
|
||||||
|
// remember end of allocated block
|
||||||
|
|
||||||
|
ldy #0
|
||||||
lda tmp + 2
|
lda tmp + 2
|
||||||
sta (accu), y
|
sta (accu), y
|
||||||
iny
|
iny
|
||||||
lda tmp + 3
|
lda tmp + 3
|
||||||
sta (accu), y
|
sta (accu), y
|
||||||
|
|
||||||
// advance address to start of next heap block
|
|
||||||
|
|
||||||
clc
|
|
||||||
lda accu
|
|
||||||
adc tmp + 2
|
|
||||||
sta accu
|
|
||||||
lda accu + 1
|
|
||||||
adc tmp + 3
|
|
||||||
sta accu + 1
|
|
||||||
|
|
||||||
found:
|
|
||||||
// remember size of heap block for free without size
|
|
||||||
|
|
||||||
ldy #0
|
|
||||||
lda tmp + 4
|
|
||||||
sta (accu), y
|
|
||||||
iny
|
|
||||||
lda tmp + 5
|
|
||||||
sta (accu), y
|
|
||||||
|
|
||||||
// advanve by two bytes to skip size
|
// advanve by two bytes to skip size
|
||||||
clc
|
|
||||||
lda accu
|
lda accu
|
||||||
adc #2
|
ora #2
|
||||||
sta accu
|
sta accu
|
||||||
bcc page
|
|
||||||
inc accu + 1
|
|
||||||
page:
|
|
||||||
rts
|
rts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4292,91 +4306,68 @@ __asm inp_malloc
|
||||||
|
|
||||||
__asm free
|
__asm free
|
||||||
{
|
{
|
||||||
// check nullptr free
|
|
||||||
|
// two bytes back to fix remembered end of block
|
||||||
|
|
||||||
lda accu
|
lda accu
|
||||||
|
and #$fc
|
||||||
|
sta accu
|
||||||
|
|
||||||
|
// check nullptr free
|
||||||
|
|
||||||
ora accu + 1
|
ora accu + 1
|
||||||
bne notnull
|
bne notnull
|
||||||
rts
|
rts
|
||||||
notnull:
|
notnull:
|
||||||
// two bytes back to fix size
|
|
||||||
sec
|
|
||||||
lda accu
|
|
||||||
sbc #2
|
|
||||||
sta accu
|
|
||||||
bcs page
|
|
||||||
dec accu + 1
|
|
||||||
page:
|
|
||||||
|
|
||||||
// cache size and end of block
|
// cache end of block, rounding to next four byte
|
||||||
|
// address
|
||||||
|
|
||||||
clc
|
clc
|
||||||
ldy #0
|
ldy #0
|
||||||
lda (accu), y
|
lda (accu), y
|
||||||
adc #5
|
adc #3
|
||||||
and #$fc
|
and #$fc
|
||||||
sta tmp
|
sta accu + 2
|
||||||
iny
|
iny
|
||||||
lda (accu), y
|
lda (accu), y
|
||||||
adc #0
|
adc #0
|
||||||
sta tmp + 1
|
|
||||||
|
|
||||||
clc
|
|
||||||
lda tmp + 0
|
|
||||||
adc accu
|
|
||||||
sta accu + 2
|
|
||||||
lda tmp + 1
|
|
||||||
adc accu + 1
|
|
||||||
sta accu + 3
|
sta accu + 3
|
||||||
|
|
||||||
// pointer to heap block, starting with
|
// pointer to heap block, starting with
|
||||||
// dummy block
|
// dummy block
|
||||||
|
|
||||||
lda #<HeapNode
|
lda #<HeapNode
|
||||||
sta tmp + 2
|
ldx #>HeapNode
|
||||||
lda #>HeapNode
|
|
||||||
sta tmp + 3
|
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
|
sta tmp + 2
|
||||||
|
stx tmp + 3
|
||||||
|
|
||||||
// check if end of heap
|
// check if end of heap
|
||||||
|
|
||||||
ldy #1
|
ldy #1
|
||||||
lda (tmp + 2), y
|
lda (tmp + 2), y
|
||||||
beq noend
|
beq noend
|
||||||
|
|
||||||
// Check if behind this block
|
|
||||||
|
|
||||||
cmp accu + 1
|
|
||||||
bcc before
|
|
||||||
bne after
|
|
||||||
|
|
||||||
dey
|
|
||||||
lda (tmp + 2), y
|
|
||||||
cmp accu + 0
|
|
||||||
bcs after
|
|
||||||
|
|
||||||
before:
|
|
||||||
ldy # 1
|
|
||||||
lda (tmp + 2), y
|
|
||||||
tax
|
tax
|
||||||
dey
|
dey
|
||||||
lda (tmp + 2), y
|
lda (tmp + 2), y
|
||||||
sta tmp + 2
|
|
||||||
stx tmp + 3
|
|
||||||
jmp loop
|
|
||||||
after:
|
|
||||||
|
|
||||||
// Merge with next block
|
// Check if next block is behind the block to free
|
||||||
|
|
||||||
ldy #1
|
cpx accu + 3
|
||||||
lda accu + 3
|
bcc loop
|
||||||
cmp (tmp + 2), y
|
|
||||||
bne noend
|
bne noend
|
||||||
dey
|
|
||||||
lda accu + 2
|
cmp accu + 2
|
||||||
cmp (tmp + 2), y
|
bcc loop
|
||||||
bne noend
|
bne noend
|
||||||
|
|
||||||
|
// The end of the block to free matches the
|
||||||
|
// start of the next free block
|
||||||
|
|
||||||
// Pointer to next next block
|
// Pointer to next next block
|
||||||
|
|
||||||
ldy #0
|
ldy #0
|
||||||
lda (accu + 2), y
|
lda (accu + 2), y
|
||||||
sta (accu), y
|
sta (accu), y
|
||||||
|
@ -4384,18 +4375,16 @@ after:
|
||||||
lda (accu + 2), y
|
lda (accu + 2), y
|
||||||
sta (accu), y
|
sta (accu), y
|
||||||
|
|
||||||
// Add size of next block to this
|
// Append free space to new block
|
||||||
iny
|
|
||||||
clc
|
|
||||||
lda tmp
|
|
||||||
adc (accu + 2), y
|
|
||||||
sta tmp
|
|
||||||
iny
|
|
||||||
lda tmp + 1
|
|
||||||
adc (accu + 2), y
|
|
||||||
sta tmp + 1
|
|
||||||
|
|
||||||
|
iny
|
||||||
|
lda (accu + 2), y
|
||||||
|
sta (accu), y
|
||||||
|
iny
|
||||||
|
lda (accu + 2), y
|
||||||
|
sta (accu), y
|
||||||
jmp start
|
jmp start
|
||||||
|
|
||||||
noend:
|
noend:
|
||||||
// Link to next block
|
// Link to next block
|
||||||
ldy #0
|
ldy #0
|
||||||
|
@ -4405,24 +4394,27 @@ noend:
|
||||||
lda (tmp + 2), y
|
lda (tmp + 2), y
|
||||||
sta (accu), y
|
sta (accu), y
|
||||||
|
|
||||||
start:
|
// End of new free block
|
||||||
// Calculate end of free block
|
|
||||||
ldy #2
|
|
||||||
clc
|
|
||||||
lda tmp + 2
|
|
||||||
adc (tmp + 2), y
|
|
||||||
iny
|
iny
|
||||||
tax
|
lda accu + 2
|
||||||
lda tmp + 3
|
sta (accu), y
|
||||||
adc (tmp + 2), y
|
iny
|
||||||
|
lda accu + 3
|
||||||
|
sta (accu), y
|
||||||
|
|
||||||
// Matches start of new block
|
start:
|
||||||
|
// Check if new block matches end of previous block
|
||||||
|
|
||||||
|
ldy #2
|
||||||
|
lda (tmp + 2), y
|
||||||
|
cmp accu
|
||||||
|
bne nostart
|
||||||
|
iny
|
||||||
|
lda (tmp + 2), y
|
||||||
cmp accu + 1
|
cmp accu + 1
|
||||||
bne nostart
|
bne nostart
|
||||||
cpx accu
|
|
||||||
bne nostart
|
|
||||||
|
|
||||||
// If so, increase the size and link
|
// If so, increase the size of previous block and link
|
||||||
// to free block after
|
// to free block after
|
||||||
|
|
||||||
ldy #0
|
ldy #0
|
||||||
|
@ -4433,13 +4425,10 @@ start:
|
||||||
sta (tmp + 2), y
|
sta (tmp + 2), y
|
||||||
|
|
||||||
iny
|
iny
|
||||||
clc
|
lda (accu), y
|
||||||
lda (tmp + 2), y
|
|
||||||
adc tmp
|
|
||||||
sta (tmp + 2), y
|
sta (tmp + 2), y
|
||||||
iny
|
iny
|
||||||
lda (tmp + 2), y
|
lda (accu), y
|
||||||
adc tmp + 1
|
|
||||||
sta (tmp + 2), y
|
sta (tmp + 2), y
|
||||||
|
|
||||||
rts
|
rts
|
||||||
|
@ -4453,14 +4442,7 @@ nostart:
|
||||||
iny
|
iny
|
||||||
lda accu + 1
|
lda accu + 1
|
||||||
sta (tmp + 2), y
|
sta (tmp + 2), y
|
||||||
iny
|
|
||||||
|
|
||||||
// Set size of free block
|
|
||||||
lda tmp
|
|
||||||
sta (accu), y
|
|
||||||
iny
|
|
||||||
lda tmp + 1
|
|
||||||
sta (accu), y
|
|
||||||
rts
|
rts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1609,9 +1609,13 @@ void ByteCodeBasicBlock::CallMalloc(InterCodeProcedure* proc, const InterInstruc
|
||||||
}
|
}
|
||||||
ByteCodeInstruction cins(BC_MALLOC);
|
ByteCodeInstruction cins(BC_MALLOC);
|
||||||
mIns.Push(cins);
|
mIns.Push(cins);
|
||||||
ByteCodeInstruction bins(BC_STORE_REG_16);
|
|
||||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
|
if (ins->mDst.mTemp >= 0)
|
||||||
mIns.Push(bins);
|
{
|
||||||
|
ByteCodeInstruction bins(BC_STORE_REG_16);
|
||||||
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
|
||||||
|
mIns.Push(bins);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ByteCodeBasicBlock::CallFree(InterCodeProcedure* proc, const InterInstruction* ins)
|
void ByteCodeBasicBlock::CallFree(InterCodeProcedure* proc, const InterInstruction* ins)
|
||||||
|
|
|
@ -7366,10 +7366,13 @@ void NativeCodeBasicBlock::CallMalloc(InterCodeProcedure* proc, const InterInstr
|
||||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("malloc")));
|
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("malloc")));
|
||||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_LOWER | NCIF_UPPER));
|
mIns.Push(NativeCodeInstruction(ins, ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_LOWER | NCIF_UPPER));
|
||||||
|
|
||||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
if (ins->mDst.mTemp >= 0)
|
||||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 0));
|
{
|
||||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
|
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||||
|
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeCodeBasicBlock::CallFree(InterCodeProcedure* proc, const InterInstruction* ins, NativeCodeProcedure* nproc)
|
void NativeCodeBasicBlock::CallFree(InterCodeProcedure* proc, const InterInstruction* ins, NativeCodeProcedure* nproc)
|
||||||
|
|
Loading…
Reference in New Issue