summaryrefslogtreecommitdiff
path: root/memory.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <peter@pmikkelsen.com>2022-02-09 01:16:03 +0000
committerPeter Mikkelsen <peter@pmikkelsen.com>2022-02-09 01:16:03 +0000
commit6ed5b9f6d3fdeeed8ecd43b18bae642ec1ec24b1 (patch)
treecee3f787af7fb7e8b892fb661f63dc9248cd5f61 /memory.c
parent8fd005f6185ac76ed0ac2495bd97ee817b472040 (diff)
Add much better memory handling (We now track and free Datum * structs)
Diffstat (limited to 'memory.c')
-rw-r--r--memory.c223
1 files changed, 208 insertions, 15 deletions
diff --git a/memory.c b/memory.c
index 4606ef2..33c30d7 100644
--- a/memory.c
+++ b/memory.c
@@ -1,20 +1,44 @@
#include <u.h>
#include <libc.h>
+#include <thread.h>
#include <bio.h>
#include <pool.h>
#include "apl9.h"
-int alloccounts = 0;
+int arrayalloccounts = 0;
+int datumalloccounts = 0;
int debugmem;
void *
emalloc(ulong size)
{
void *res = malloc(size);
- if(res == nil){
+ if(res == nil && size > 0){
print("Out of memory! :(\n");
- exits("emalloc");
+ threadexitsall("emalloc");
+ }
+ return res;
+}
+
+void *
+emallocz(ulong size, int clr)
+{
+ void *res = mallocz(size, clr);
+ if(res == nil && size > 0){
+ print("Out of memory! :(\n");
+ threadexitsall("emallocz");
+ }
+ return res;
+}
+
+void *
+erealloc(void *ptr, ulong size)
+{
+ void *res = realloc(ptr, size);
+ if(res == nil && size > 0){
+ print("Out of memory! :(\n");
+ threadexitsall("erealloc");
}
return res;
}
@@ -36,19 +60,18 @@ freearray(Array *a)
a->refs--;
if(a->refs == 0){
- /* print("Freeing array: %S (%p)\n", pparray(a), a); */
if(a->type == AtypeArray)
for(int i = 0; i < a->size; i++)
freearray(a->arraydata[i]);
free(a->shape);
+ free(a->rawdata);
free(a);
- alloccounts--;
- }else if(a->refs > 0){
- /* print("Not freeing (refs=%d): %S (%p)\n", a->refs, pparray(a), a); */
- }else{
- print("NEGATIVE REF COUNT! %p\n", a);
- exits(nil);
+ arrayalloccounts--;
+ }else if(a->refs < 0){
+ print("NEGATIVE REF COUNT (array)! %p\n", a);
+ threadexitsall(nil);
}
+
}
Array *
@@ -63,16 +86,186 @@ allocarray(arrayDataType t, int rank, int size)
a->rawdata = emalloc(datasizes[t] * size);
a->type = t;
a->refs = 1;
- alloccounts++;
+ arrayalloccounts++;
return a;
}
void
incarrayref(Array *a)
{
- /* print("INCREF %d->%d %S\n", a->refs, a->refs+1, pparray(a)); */
a->refs++;
- if(a->type == AtypeArray)
- for(int i = 0; i < a->size; i++)
- incarrayref(a->arraydata[i]);
+}
+
+Datum *
+allocdatum(int tag, int shy)
+{
+ Datum *d = emallocz(sizeof(Datum), 1);
+ d->refs = 1;
+ d->tag = tag;
+ d->shy = shy;
+ datumalloccounts++;
+ return d;
+}
+
+void
+freedatum(Datum *d)
+{
+ if(d == nil)
+ return;
+
+ d->refs--;
+ if(d->refs == 0){
+ /* print("FREE DATUM: %S\n", ppdatum(d)); */
+ switch(d->tag){
+ case ArrayTag:
+ freearray(d->array);
+ break;
+ case FunctionTag:
+ case BoundFunctionTag:
+ freefunction(d->func);
+ break;
+ case HybridTag:
+ break;
+ case MonadicOpTag:
+ case DyadicOpTag:
+ freeoperator(d->operator);
+ break;
+ case LParTag:
+ freestatement(d->stmt);
+ break;
+ case RParTag:
+ break;
+ case ArrowTag:
+ break;
+ case AssignmentTag:
+ freestatement(d->names);
+ break;
+ case NameTag:
+ free(d->name);
+ break;
+ default:
+ print("Don't know how to free datum with tag: %d\n", d->tag);
+ threadexitsall("freedatum");
+ }
+ free(d);
+ datumalloccounts--;
+ }else if(d->refs < 0){
+ print("NEGATIVE REF COUNT (datum)! %p\n", d);
+ threadexitsall(nil);
+ }
+}
+
+void
+incdatumref(Datum *d)
+{
+ d->refs++;
+}
+
+void
+freefunction(Function f)
+{
+ freearray(f.left);
+ switch(f.type){
+ case FunctypeDfn:
+ free(f.dfn);
+ break;
+ case FunctypePrim:
+ break;
+ case FunctypeOp:
+ freeoperator(f.operator);
+ break;
+ case FunctypeQuad:
+ free(f.quad);
+ break;
+ case FunctypeHybrid:
+ break;
+ case FunctypeTrain:
+ for(int i = 0; i < f.train.nfuncs; i++)
+ freefunction(f.train.funcs[i]);
+ free(f.train.funcs);
+ break;
+ default:
+ print("Missing case in freefunction: %d\n", f.type);
+ threadexitsall("freefunction");
+ }
+}
+
+void
+freeoperator(Operator o)
+{
+ freedatum(o.left);
+ freedatum(o.right);
+ switch(o.type){
+ case OperatortypeDop:
+ free(o.dop);
+ break;
+ case OperatortypePrim:
+ case OperatortypeHybrid:
+ break;
+ default:
+ print("Missing case in freeoperator: %d\n", o.type);
+ threadexitsall("freeoperator");
+ }
+}
+
+void
+freestatement(Statement s)
+{
+ for(int i = 0; i < s.ntoks; i++)
+ freedatum(s.toks[i]);
+ free(s.toks);
+ if(s.guard)
+ freestatement(*s.guard);
+}
+
+Function
+dupfunction(Function f)
+{
+ Function g = f;
+ if(g.left)
+ incarrayref(g.left);
+
+ switch(f.type){
+ case FunctypeDfn:
+ g.dfn = runestrdup(f.dfn);
+ break;
+ case FunctypePrim:
+ break;
+ case FunctypeOp:
+ g.operator = dupoperator(f.operator);
+ break;
+ case FunctypeQuad:
+ g.quad = emalloc(sizeof(QuadnameDef));
+ *g.quad = *f.quad;
+ break;
+ case FunctypeHybrid:
+ break;
+ default:
+ print("Missing case in dupfunction: %d\n", f.type);
+ threadexitsall("dupfunction");
+ }
+ return g;
+
+}
+
+Operator
+dupoperator(Operator o)
+{
+ Operator p = o;
+ if(p.left)
+ incdatumref(p.left);
+ if(p.right)
+ incdatumref(p.right);
+ switch(o.type){
+ case OperatortypeDop:
+ p.dop = runestrdup(o.dop);
+ break;
+ case OperatortypePrim:
+ case OperatortypeHybrid:
+ break;
+ default:
+ print("Missing case in dupoperator: %d\n", o.type);
+ threadexitsall("dupoperator");
+ }
+ return p;
} \ No newline at end of file