shithub: scc

Download patch

ref: c6ea791b9cac2e0e4486156b8751acd82da179dd
parent: 7e46551105c8bc3b8b4b2b9bc02b36d494dce031
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Nov 14 08:35:02 EST 2014

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.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -157,6 +157,7 @@
 	void (*code)(struct node *);
 	Type *type;
 	uint8_t typeop;
+	uint8_t nchilds;
 	struct {
 		bool lvalue : 1;
 		bool symbol: 1;
@@ -208,6 +209,8 @@
 	*ternarycode(Node *cond, Node *ifyes, Node *ifno),
 	*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 */
--- 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,10 +59,24 @@
 	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
--- a/cc1/stmt.c
+++ b/cc1/stmt.c
@@ -46,9 +46,15 @@
 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 @@
 	emitjump(begin, np);
 	emiteloop();
 	emitlabel(end);
+	freetree(np);
 }
 
 static void
@@ -113,6 +120,9 @@
 	emitjump(begin, econd);
 	emiteloop();
 	emitlabel(end);
+	freetree(einit);
+	freetree(econd);
+	freetree(einc);
 }
 
 static void
@@ -119,6 +129,7 @@
 Dowhile(Symbol *lbreak, Symbol *lcont, Caselist *lswitch)
 {
 	Symbol *begin, *end;
+	Node *np;
 
 	begin = install("", NS_LABEL);
 	end = install("", NS_LABEL);
@@ -127,9 +138,11 @@
 	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 @@
 	}
 	emitret(tp);
 	emitexp(np);
+	freetree(np);
 }
 
 static void
@@ -229,11 +243,13 @@
 	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 @@
 	} else {
 		emitlabel(lelse);
 	}
+	freetree(np);
 }
 
 void
@@ -318,6 +335,7 @@
 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 @@
 		break;
 	case '@':
 		next();
-		emitprint(expr());
+		np = expr();
+		emitprint(np);
+		freetree(np);
 		return;
 	}
 	(*fun)(lbreak, lcont, lswitch);
--