From 1cf8f9cae28e9c672ab601568dae19367aebd2cd Mon Sep 17 00:00:00 2001 From: XOR Date: Tue, 19 Sep 2023 22:32:26 +0200 Subject: [PATCH] Add dynamic buffers and reduce memory usage --- header/common.h | 9 ++++++++- header/dyn_buf.h | 19 +++++++++++++++++++ src/dyn_buf.c | 35 +++++++++++++++++++++++++++++++++++ src/main.c | 46 ++++++++++++++++++++++++++-------------------- 4 files changed, 88 insertions(+), 21 deletions(-) create mode 100644 header/dyn_buf.h create mode 100644 src/dyn_buf.c diff --git a/header/common.h b/header/common.h index 8b3bf20..2588a61 100755 --- a/header/common.h +++ b/header/common.h @@ -11,11 +11,18 @@ Here, common macros are specified #define MAX_MEMORY 268435456 // Size of the label_table -#define LABEL_TABLE_SIZE 268435456 +#define LABEL_TABLE_SIZE 100000 // Maximum size (charachters) of one token #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_MINOR "1" #define VER_PATCH "0" diff --git a/header/dyn_buf.h b/header/dyn_buf.h new file mode 100644 index 0000000..6746221 --- /dev/null +++ b/header/dyn_buf.h @@ -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 diff --git a/src/dyn_buf.c b/src/dyn_buf.c new file mode 100644 index 0000000..416b4a6 --- /dev/null +++ b/src/dyn_buf.c @@ -0,0 +1,35 @@ +#include "../header/dyn_buf.h" +#include +#include + +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; +} diff --git a/src/main.c b/src/main.c index bde1a5f..249ba57 100755 --- a/src/main.c +++ b/src/main.c @@ -18,6 +18,7 @@ It also is responsible for Argument Parsing #include "../header/labels.h" #include "../header/lexer.h" #include "../header/target_code_generator.h" +#include "../header/dyn_buf.h" const char *argp_program_version = VER_MAJOR "." VER_MINOR "." VER_PATCH " || " TAG; @@ -127,57 +128,62 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - char(*label_tokens)[MAX_TOKEN_SIZE] = calloc(MAX_MEMORY, sizeof(*label_tokens)); - if (label_tokens == NULL) + dynamic_buffer_t label_tokens; + 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; } - lexer(assembly_file, label_tokens); + lexer(assembly_file, (char (*)[MAX_TOKEN_SIZE]) label_tokens.buffer); fclose(assembly_file); // Part I of processing labels shash_hashtable_t label_table; 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"); - 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"); 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"); - free(label_tokens); + free(label_tokens.buffer); // Check if the EIPA Assembly contains errors with the no_label_definition_tokens array 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 - char(*tokens)[MAX_TOKEN_SIZE] = calloc(MAX_MEMORY, sizeof(*tokens)); - if (tokens == NULL) + dynamic_buffer_t tokens; + 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"); 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"); - free(no_label_definition_tokens); + free(no_label_definition_tokens.buffer); // Generate the target code - __uint32_t *target_code = calloc(MAX_MEMORY, sizeof(target_code)); - if (target_code == NULL) + dynamic_buffer_t target_code; + 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"); 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) { 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 - 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"); 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 (arguments.print_tokens) - print_tokens(tokens); + print_tokens((char (*)[MAX_TOKEN_SIZE])tokens.buffer); if (arguments.print_target_code) - print_target_code(target_code); + print_target_code((__uint32_t *)target_code.buffer); // Cleanup destroy_instruction_information_hashtable(&instruction_informations);