]> git.rm.cloudns.org Git - xonotic/gmqcc.git/commitdiff
Implemented memory tracker
authorDale Weiler <killfieldengine@gmail.com>
Tue, 10 Apr 2012 03:12:42 +0000 (23:12 -0400)
committerDale Weiler <killfieldengine@gmail.com>
Tue, 10 Apr 2012 03:12:42 +0000 (23:12 -0400)
Makefile
alloc.c [new file with mode: 0644]
gmqcc.h
parse.c

index 7a016b322b9ecaa2dabb9b43da7fdb009d9f1e32..b1b4863b13841e14006db1570fea711a659aae19 100644 (file)
--- 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 (file)
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 <stdint.h>
+#include <stdlib.h>
+#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 5f599db3b7593c611ed1735c877082831092bc4e..43d90df396158d7d21fbba788138b64eef35bee2 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
 #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 b46df134b044004114d91d66deaf92cf85ab4d16..4e820c70d84c7219f80f1033df708018d824fb3c 100644 (file)
--- 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;
 }