commit c6ea791b9cac2e0e4486156b8751acd82da179dd
parent 7e46551105c8bc3b8b4b2b9bc02b36d494dce031
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 14 Nov 2014 13:35:02 -0500
Free expressions after using them
We were not freeing memory, so with big files this was a problem. This patch
adds a first solution to this problem, but something better must be done,
because in this moment one type is created by every function.
Diffstat:
3 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/cc1/cc1.h b/cc1/cc1.h
@@ -157,6 +157,7 @@ typedef struct node {
void (*code)(struct node *);
Type *type;
uint8_t typeop;
+ uint8_t nchilds;
struct {
bool lvalue : 1;
bool symbol: 1;
@@ -209,6 +210,8 @@ extern Node
*symcode(Symbol *sym),
*fieldcode(Node *child, struct field *fp);
+extern void freetree(Node *np);
+
#define NEGATE(n, v) ((n)->u.op ^= (v))
/* TODO: remove some of these ugly macros */
#define ISNODEBIN(n) ((n)->code == emitbin)
diff --git a/cc1/code.c b/cc1/code.c
@@ -1,6 +1,7 @@
#include <stdint.h>
#include <stdio.h>
+#include <stdlib.h>
#include <cc.h>
#include "cc1.h"
@@ -58,12 +59,26 @@ node(void (*code)(Node *), Type *tp, union unode u, uint8_t nchilds)
np->code = code;
np->type = tp;
np->typeop = tp->op;
+ np->nchilds = nchilds;
np->u = u;
np->b.symbol = np->b.lvalue = 0;
return np;
}
+void
+freetree(Node *np)
+{
+ Node **p;
+
+ if (!np)
+ return;
+
+ for (p = np->childs; np->nchilds--; ++p)
+ freetree(*p);
+ free(np);
+}
+
static void
emitsym2(Symbol *sym)
{
diff --git a/cc1/stmt.c b/cc1/stmt.c
@@ -46,9 +46,15 @@ label(char *s, char define)
static void
stmtexp(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
{
- if (yytoken != ';')
- emitexp(expr());
+ Node *np = NULL;;
+
+ if (yytoken != ';') {
+ np = expr();
+ emitexp(np);
+ }
+
expect(';');
+ freetree(np);
}
static Node *
@@ -82,6 +88,7 @@ While(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
emitjump(begin, np);
emiteloop();
emitlabel(end);
+ freetree(np);
}
static void
@@ -113,12 +120,16 @@ For(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
emitjump(begin, econd);
emiteloop();
emitlabel(end);
+ freetree(einit);
+ freetree(econd);
+ freetree(einc);
}
static void
Dowhile(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
{
Symbol *begin, *end;
+ Node *np;
begin = install("", NS_LABEL);
end = install("", NS_LABEL);
@@ -127,9 +138,11 @@ Dowhile(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
emitlabel(begin);
stmt(end, begin, lswitch);
expect(WHILE);
- emitjump(begin, condition());
+ np = condition();
+ emitjump(begin, np);
emiteloop();
emitlabel(end);
+ freetree(np);
}
static void
@@ -153,6 +166,7 @@ Return(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
}
emitret(tp);
emitexp(np);
+ freetree(np);
}
static void
@@ -229,11 +243,13 @@ Switch(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
for (p = lcase.head; p; p = next) {
emitcase(p->label, p->expr);
next = p->next;
+ freetree(p->expr);
free(p);
}
if (lcase.deflabel)
emitdefault(lcase.deflabel);
emitlabel(lbreak);
+ freetree(cond);
}
static void
@@ -289,6 +305,7 @@ If(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
} else {
emitlabel(lelse);
}
+ freetree(np);
}
void
@@ -318,6 +335,7 @@ static void
stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
{
void (*fun)(Symbol *lbreak, Symbol *lcont, Caselist *lswitch);
+ Node *np;
switch (yytoken) {
case '{': fun = context; break;
@@ -338,7 +356,9 @@ stmt(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
break;
case '@':
next();
- emitprint(expr());
+ np = expr();
+ emitprint(np);
+ freetree(np);
return;
}
(*fun)(lbreak, lcont, lswitch);