Add dynamic buffers and reduce memory usage

This commit is contained in:
XOR 2023-09-19 22:32:26 +02:00
parent b7802a6b83
commit 1cf8f9cae2
4 changed files with 88 additions and 21 deletions

View file

@ -11,11 +11,18 @@ Here, common macros are specified
#define MAX_MEMORY 268435456 #define MAX_MEMORY 268435456
// Size of the label_table // Size of the label_table
#define LABEL_TABLE_SIZE 268435456 #define LABEL_TABLE_SIZE 100000
// Maximum size (charachters) of one token // Maximum size (charachters) of one token
#define MAX_TOKEN_SIZE 10 #define MAX_TOKEN_SIZE 10
// Intitial size and grow size for dynamic buffers
#define TABLE_INIT_SIZE 50
#define TABLE_GROW_SIZE 30
#define TARGET_CODE_INIT 50
#define TARGET_CODE_GROW 30
#define VER_MAJOR "0" #define VER_MAJOR "0"
#define VER_MINOR "1" #define VER_MINOR "1"
#define VER_PATCH "0" #define VER_PATCH "0"

19
header/dyn_buf.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef _DYN_BUF_H_
#define _DYN_BUF_H_
typedef struct
{
void *buffer;
unsigned int init_size;
unsigned int grow_size;
unsigned long int size;
unsigned long int used;
} dynamic_buffer_t;
//Intitialize an empty dynamic buffer *buffer. Returns 0 on success.
int init_dynamic_buffer(dynamic_buffer_t *buffer, unsigned int init_size, unsigned int grow_size);
// Resize a dynamic buffer. Returns 0 on sucess
int resize_dynamic_buffer(dynamic_buffer_t *buffer);
#endif

35
src/dyn_buf.c Normal file
View file

@ -0,0 +1,35 @@
#include "../header/dyn_buf.h"
#include <stdlib.h>
#include <string.h>
int init_dynamic_buffer(dynamic_buffer_t *buffer, unsigned int init_size, unsigned int grow_size)
{
buffer->init_size = init_size;
buffer->size = (unsigned long int) init_size;
buffer->grow_size = grow_size;
buffer->used = 0;
buffer->buffer = malloc(init_size);
memset(buffer->buffer, 0, buffer->size);
if(buffer->buffer == NULL) return 1;
return 0;
}
int resize_dynamic_buffer(dynamic_buffer_t *buffer)
{
// Maintain a copy of the buffers adress in case realloc returns NULL
void *buffer_cpy = buffer->buffer;
buffer->buffer = realloc(buffer->buffer, buffer->size + buffer->grow_size);
buffer->size = buffer->size + buffer->grow_size;
if(buffer->buffer == NULL){
free(buffer_cpy);
return 1;
}
unsigned int old_buffer_size = buffer->size - buffer->grow_size;
memset(buffer->buffer + old_buffer_size, 0 , buffer->grow_size);
return 0;
}

View file

@ -18,6 +18,7 @@ It also is responsible for Argument Parsing
#include "../header/labels.h" #include "../header/labels.h"
#include "../header/lexer.h" #include "../header/lexer.h"
#include "../header/target_code_generator.h" #include "../header/target_code_generator.h"
#include "../header/dyn_buf.h"
const char *argp_program_version = const char *argp_program_version =
VER_MAJOR "." VER_MINOR "." VER_PATCH " || " TAG; VER_MAJOR "." VER_MINOR "." VER_PATCH " || " TAG;
@ -127,57 +128,62 @@ int main(int argc, char **argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
char(*label_tokens)[MAX_TOKEN_SIZE] = calloc(MAX_MEMORY, sizeof(*label_tokens)); dynamic_buffer_t label_tokens;
if (label_tokens == NULL) init_dynamic_buffer(&label_tokens, TABLE_INIT_SIZE * MAX_TOKEN_SIZE, TABLE_GROW_SIZE * MAX_TOKEN_SIZE);
if (label_tokens.buffer == NULL)
{ {
printf("Error: Could not allocate memory for the label_tokens array\n"); printf("Error: Could not create the label_tokens array\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
lexer(assembly_file, label_tokens); lexer(assembly_file, (char (*)[MAX_TOKEN_SIZE]) label_tokens.buffer);
fclose(assembly_file); fclose(assembly_file);
// Part I of processing labels // Part I of processing labels
shash_hashtable_t label_table; shash_hashtable_t label_table;
shash_init_hashtable(&label_table, LABEL_TABLE_SIZE); shash_init_hashtable(&label_table, LABEL_TABLE_SIZE);
build_label_table(label_tokens, &label_table); build_label_table((char (*)[MAX_TOKEN_SIZE]) label_tokens.buffer, &label_table);
printf("Built label table\n"); printf("Built label table\n");
char(*no_label_definition_tokens)[MAX_TOKEN_SIZE] = calloc(MAX_MEMORY, sizeof(*no_label_definition_tokens));
if (no_label_definition_tokens == NULL) dynamic_buffer_t no_label_definition_tokens;
init_dynamic_buffer(&no_label_definition_tokens, TABLE_INIT_SIZE * MAX_TOKEN_SIZE, TABLE_GROW_SIZE * MAX_TOKEN_SIZE);
if (no_label_definition_tokens.buffer == NULL)
{ {
printf("Error: Could not allocate memory for the no_label_defintion_tokens array\n"); printf("Error: Could not allocate memory for the no_label_defintion_tokens array\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
remove_label_definition_tokens(label_tokens, no_label_definition_tokens); remove_label_definition_tokens((char (*)[MAX_TOKEN_SIZE]) label_tokens.buffer, (char (*)[MAX_TOKEN_SIZE]) no_label_definition_tokens.buffer);
printf("Removed label defintions\n"); printf("Removed label defintions\n");
free(label_tokens); free(label_tokens.buffer);
// Check if the EIPA Assembly contains errors with the no_label_definition_tokens array // Check if the EIPA Assembly contains errors with the no_label_definition_tokens array
shash_hashtable_t instruction_informations = create_instruction_information_hastable(); shash_hashtable_t instruction_informations = create_instruction_information_hastable();
printf("Found %d errors\n", check_token_errors(no_label_definition_tokens, instruction_informations, label_table)); printf("Found %d errors\n", check_token_errors((char (*)[MAX_TOKEN_SIZE]) no_label_definition_tokens.buffer, instruction_informations, label_table));
// Part II of processing labels // Part II of processing labels
char(*tokens)[MAX_TOKEN_SIZE] = calloc(MAX_MEMORY, sizeof(*tokens)); dynamic_buffer_t tokens;
if (tokens == NULL) init_dynamic_buffer(&tokens, TABLE_INIT_SIZE * MAX_TOKEN_SIZE, TABLE_GROW_SIZE * MAX_TOKEN_SIZE);
if (tokens.buffer == NULL)
{ {
printf("Error: Could not allocate memory for the tokens array\n"); printf("Error: Could not allocate memory for the tokens array\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
replace_labels_with_adresses(no_label_definition_tokens, tokens, label_table, instruction_informations); replace_labels_with_adresses((char (*)[MAX_TOKEN_SIZE]) no_label_definition_tokens.buffer, (char (*)[MAX_TOKEN_SIZE])tokens.buffer, label_table, instruction_informations);
printf("Removed labels\n"); printf("Removed labels\n");
free(no_label_definition_tokens); free(no_label_definition_tokens.buffer);
// Generate the target code // Generate the target code
__uint32_t *target_code = calloc(MAX_MEMORY, sizeof(target_code)); dynamic_buffer_t target_code;
if (target_code == NULL) init_dynamic_buffer(&target_code, TARGET_CODE_INIT * sizeof(__uint32_t), TARGET_CODE_GROW * sizeof(__uint32_t));
if (target_code.buffer == NULL)
{ {
printf("Error: Could not allocate memory for the target code\n"); printf("Error: Could not allocate memory for the target code\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
int error = gen_target_code(tokens, target_code); int error = gen_target_code((char (*)[MAX_TOKEN_SIZE])tokens.buffer, (__uint32_t *)target_code.buffer);
if (error != 0) if (error != 0)
{ {
printf("Error: Could not generate target code - Error %s\n", strerror(error)); printf("Error: Could not generate target code - Error %s\n", strerror(error));
@ -185,7 +191,7 @@ int main(int argc, char **argv)
} }
// Save the target code to a file // Save the target code to a file
if (save_img(arguments.output_file, target_code) != 0) if (save_img(arguments.output_file, (__uint32_t *)target_code.buffer) != 0)
{ {
printf("Couldn't save the output file\n"); printf("Couldn't save the output file\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -193,9 +199,9 @@ int main(int argc, char **argv)
// If the requested, we print the tokens and/or the target code // If the requested, we print the tokens and/or the target code
if (arguments.print_tokens) if (arguments.print_tokens)
print_tokens(tokens); print_tokens((char (*)[MAX_TOKEN_SIZE])tokens.buffer);
if (arguments.print_target_code) if (arguments.print_target_code)
print_target_code(target_code); print_target_code((__uint32_t *)target_code.buffer);
// Cleanup // Cleanup
destroy_instruction_information_hashtable(&instruction_informations); destroy_instruction_information_hashtable(&instruction_informations);