Tests + fixes
This commit is contained in:
parent
4c6dff3c3b
commit
57ee82d083
5 changed files with 153 additions and 48 deletions
3
TODO.md
3
TODO.md
|
@ -1,3 +1,6 @@
|
|||
tmp:
|
||||
- fix realloc
|
||||
|
||||
- Benchmarks
|
||||
- Tests
|
||||
- Rework assign/call to work better
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
54
src/tests.c
54
src/tests.c
|
@ -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",
|
||||
|
|
Loading…
Add table
Reference in a new issue