Tests + fixes

This commit is contained in:
attilavs2 2025-03-16 21:56:51 +01:00
parent 4c6dff3c3b
commit 57ee82d083
5 changed files with 153 additions and 48 deletions

View file

@ -1,3 +1,6 @@
tmp:
- fix realloc
- Benchmarks
- Tests
- Rework assign/call to work better

View file

@ -36,6 +36,8 @@ typedef struct {
} AllocBlock;
#define EXT_BLOCK 4096
void *internal_buf;
AllocBlock *blocks;
u32 *usage; // bitmap for usage, by 8byte chunks
@ -70,48 +72,14 @@ int evaluate(Value val){
}
}
int alloc_init(){
internal_buf = malloc(4096);
blocks = malloc(sizeof(AllocBlock));
block_count = 0;
usage = malloc(sizeof(u32)*4096/32/8);
if(!internal_buf || !blocks || !usage)
int alloc_extend(u32 size){
size = (size/EXT_BLOCK+1)*EXT_BLOCK;
internal_buf = realloc(internal_buf, internal_size+size);
usage = realloc(usage, sizeof(u32)*(internal_size+size)/32/8);
if(!internal_buf || !usage)
return 1;
memset(usage, 0, sizeof(u32)*4096/32/8);
return 0;
}
u32 flisp_alloc(size_t size){
u32 pos = 32;
u32 curr_free = 0;
while(pos < internal_size){
if(usage[pos/32/8]){
for(int i = 0; i < 32; i++){
if((usage[pos/32/8]>>i) & 1)
curr_free = 0;
else
curr_free+=8;
}
}
else {
curr_free += 32*8;
}
if(curr_free >= size){
blocks = realloc(blocks, sizeof(AllocBlock)*(block_count+1));
if(!blocks)
return 0;
AllocBlock *block = &blocks[block_count++];
block->pos = pos - curr_free;
block->size = size;
for(u32 i = block->pos; i < block->pos+size; i++){
usage[i/32/8] |= 1<<(i%(32*8));
}
// Unvirtualize the memory
memset(get_addr(block->pos),0xB00B5069,size);
return block->pos;
}
pos++;
}
memset(usage+(internal_size/32/8), 0, sizeof(u32)*size/32/8);
internal_size += size;
return 0;
}
@ -121,10 +89,86 @@ int block_cmpfunc(const void *_a, const void *_b){
return b->pos - a->pos;
}
void flisp_free(u32 pos){
AllocBlock *get_block(u32 pos){
AllocBlock tmp = {.pos = pos};
AllocBlock *ret = bsearch(&tmp, blocks, block_count, sizeof(AllocBlock),
block_cmpfunc);
return ret;
}
int alloc_init(){
blocks = malloc(sizeof(AllocBlock));
block_count = 0;
internal_buf = NULL;
internal_size = 0;
usage = NULL;
if(!blocks || alloc_extend(EXT_BLOCK))
return 1;
return 0;
}
void alloc_clean(){
free(internal_buf);
free(blocks);
free(usage);
}
u32 flisp_alloc(u32 size){
u32 pos = 32;
u32 curr_free = 0;
while(pos < internal_size){
if(usage[pos/32/8]){
for(int i = 0; i < 32; i++){
if((usage[pos/32/8]>>i) & 1)
curr_free = 0;
else
curr_free+=8;
pos+=8;
if(curr_free >= size)
break;
}
}
else {
curr_free += 32*8;
pos+=32*8;
}
if(curr_free >= size){
blocks = realloc(blocks, sizeof(AllocBlock)*(block_count+1));
if(!blocks)
return 0;
AllocBlock *block = &blocks[block_count++];
block->pos = pos-curr_free;
block->size = size;
for(u32 i = block->pos; i < block->pos+size; i+=8){
usage[i/32/8] |= 1<<(i%32);
}
// Unvirtualize the memory
memset(get_addr(block->pos),0xB00B5069,size);
return block->pos;
}
}
if(alloc_extend(size))
return 0;
// Try again after extending the buffer
return flisp_alloc(size);
}
// TODO : make it efficient
u32 flisp_realloc(u32 pos, u32 size){
if(!pos)
return flisp_alloc(size);
u32 new = flisp_alloc(size);
if(!new)
return 0;
AllocBlock *block = get_block(pos);
memcpy(get_addr(new),get_addr(pos),block->size);
flisp_free(pos);
return new;
}
void flisp_free(u32 pos){
AllocBlock *ret = get_block(pos);
if(!ret)
return;
i32 bpos = (size_t)(ret-blocks)/sizeof(AllocBlock);

View file

@ -27,17 +27,21 @@ void runtime_err(char *s);
int evaluate(Value val);
int alloc_init();
// All internal allocator memory is guaranteed to be free range and 32bit
u32 flisp_alloc(size_t size);
void alloc_clean();
// All internal allocator memory is guaranteed to be free range
u32 flisp_alloc(u32 size);
u32 flisp_realloc(u32 pos, u32 size);
void flisp_free(u32 pos);
void *flisp_realloc(u32 pos, size_t size);
void *get_addr(u32 pos);
Value is(Tag tag, Value b);
Value cast(Tag tag, Value b);

View file

@ -144,8 +144,6 @@ void yyerror(char *s){
extern FILE *yyin;
int main(int argc, char *argv[]){
alloc_init();
i32 fpos = 1;
if(argc > 1){
@ -167,6 +165,8 @@ int main(int argc, char *argv[]){
yyin = stdin;
}
alloc_init();
make_stack();
yyparse();
free_stack();

View file

@ -19,12 +19,14 @@
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "types.h"
#include "parser.h"
#include "code_defs.h"
#include "byte_defs.h"
#include "exec_common.h"
typedef int (test_fun_t)(void);
@ -66,6 +68,50 @@ int t_free_hashmap(){
return 0;
}
int t_alloc_init(){
return alloc_init();
}
int t_flisp_alloc(){
int err = 0;
u32 pos0 = flisp_alloc(sizeof(u64));
u32 pos1 = flisp_alloc(sizeof(u64));
err += !pos0 || !pos1;
if(err)
return 1;
err += pos0 == pos1;
u64 *ptr0 = get_addr(pos0);
u64 *ptr1 = get_addr(pos1);
*ptr1 = 0;
*ptr0 = 0xFFFFFFFFFFFFFFFF;
err += !!*ptr1;
flisp_free(pos0);
flisp_free(pos1);
return err;
}
int t_flisp_realloc(){
int err = 0;
u8 ref[10] = {1,2,3,4,5,6,7,8,9,10};
u32 pos0 = flisp_alloc(5);
if(!pos0)
return 1;
u8 *ptr0 = get_addr(pos0);
memcpy(ptr0, ref, 5);
pos0 = flisp_realloc(pos0, 10);
if(!pos0)
return 1;
ptr0 = get_addr(pos0);
err += memcmp(ptr0, ref, 5);
return err;
}
int t_alloc_clean(){
alloc_clean();
return 0;
}
int t_get_type(){
int err = 0;
Tag ttag = get_type("int");
@ -118,6 +164,10 @@ test_fun_t *tests[] = {
t_hashmap_insert_get,
t_hashmap_remove,
t_free_hashmap,
t_alloc_init,
t_flisp_alloc,
t_flisp_realloc,
t_alloc_clean,
t_get_type,
t_make_stack,
t_make_iconst,
@ -132,6 +182,10 @@ char *names[] = {
"hashmap_insert_get",
"hashmap_remove",
"free_hashmap",
"alloc_init",
"flisp_alloc",
"flisp_realloc",
"alloc_clean",
"get_type",
"make_stack",
"make_iconst",