From 506f4bca1bdb14fcf745128b7e6681ba62b89fd7 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Mon, 9 Apr 2012 23:12:42 -0400 Subject: [PATCH] Implemented memory tracker --- Makefile | 3 ++- alloc.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gmqcc.h | 13 ++++++++--- parse.c | 11 ++++++++++ 4 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 alloc.c diff --git a/Makefile b/Makefile index 7a016b3..b1b4863 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,8 @@ OBJ = main.o \ lex.o \ error.o \ parse.o \ - typedef.o + typedef.o \ + alloc.o %.o: %.c $(CC) -c $< -o $@ $(CFLAGS) diff --git a/alloc.c b/alloc.c new file mode 100644 index 0000000..807936a --- /dev/null +++ b/alloc.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2012 + * Dale Weiler + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include +#include +#include "gmqcc.h" + +/* + * The compiler has it's own memory tracker / allocator for debugging + * reasons. It will help find things like buggy CSE or OOMs (if this + * compiler ever grows to that point.) + */ +struct memblock_t { + const char *file; + unsigned int line; + unsigned int byte; +}; + +void *memory_a(unsigned int byte, unsigned int line, const char *file) { + struct memblock_t *data = malloc(sizeof(struct memblock_t) + byte); + if (!data) return NULL; + data->line = line; + data->byte = byte; + data->file = file; + printf("[MEM] allocation: %08u (bytes) at %s:%u\n", byte, file, line); + return (void*)((uintptr_t)data+sizeof(struct memblock_t)); +} + +void memory_d(void *ptrn, unsigned int line, const char *file) { + if (!ptrn) return; + void *data = (void*)((uintptr_t)ptrn-sizeof(struct memblock_t)); + struct memblock_t *info = (struct memblock_t*)data; + printf("[MEM] released: %08u (bytes) at %s:%u\n", info->byte, file, line); + free(data); +} + +/* + * Ensure the macros are not already defined otherwise the memory + * tracker will fail. I hate trying to fix macro bugs, this should + * help stop any of that from occuring. + */ +#ifdef mem_a +#undef mem_a +#endif +#ifdef mem_d +#undef mem_d +#endif diff --git a/gmqcc.h b/gmqcc.h index 5f599db..43d90df 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -121,9 +121,6 @@ #define INSTR_BITAND 59 #define INSTR_BITOR 60 -#define mem_a(x) malloc(x) -#define mem_d(x) free (x) - /* * This is the smallest lexer I've ever wrote: and I must say, it's quite * more nicer than those large bulky complex parsers that most people write @@ -204,4 +201,14 @@ void typedef_init(); typedef_node *typedef_find(const char *); int typedef_add (const char *, const char *); +/* alloc.c */ +void *memory_a(unsigned int, unsigned int, const char *); +void memory_d(void *, unsigned int, const char *); +#ifdef NOTRACK +# define mem_a(x) malloc(x) +# define mem_d(x) free (x) +#else +# define mem_a(x) memory_a((x), __LINE__, __FILE__) +# define mem_d(x) memory_d((x), __LINE__, __FILE__) +#endif #endif diff --git a/parse.c b/parse.c index b46df13..4e820c7 100644 --- a/parse.c +++ b/parse.c @@ -168,6 +168,16 @@ void parse_debug(struct parsenode *tree) { break; \ } +void parse_clear(struct parsenode *tree) { + if (!tree) return; + struct parsenode *temp = NULL; + while (tree != NULL) { + temp = tree; + tree = tree->next; + mem_d (temp); + } +} + int parse(struct lex_file *file) { struct parsenode *parsetree = NULL; struct parsenode *parseroot = NULL; @@ -369,6 +379,7 @@ int parse(struct lex_file *file) { } parse_debug(parseroot); lex_reset(file); + parse_clear(parseroot); return 1; } -- 2.39.2