ref: 701bbb29718ee1c392466181d8db95103547ee81
parent: b456108b4fbfb9fb9c8de1c86910e64a45d0d290
	author: Lennart Augustsson <lennart.augustsson@epicgames.com>
	date: Sun Dec 17 07:46:12 EST 2023
	
Temp
--- a/src/runtime/eval.c
+++ b/src/runtime/eval.c
@@ -100,7 +100,8 @@
#endif /* WANT_STDIO */
#endif /* !define(ERR) */
-enum node_tag { T_FREE, T_IND, T_AP, T_INT, T_DBL, T_PTR, T_BADDYN, T_S, T_K, T_I, T_B, T_C,+enum node_tag { T_FREE, T_IND, T_AP, T_INT, T_DBL, T_PTR, T_BADDYN, T_IOARR,+ T_S, T_K, T_I, T_B, T_C,
T_A, T_Y, T_SS, T_BB, T_CC, T_P, T_R, T_O, T_U, T_Z,
T_K2, T_K3, T_K4,
T_ADD, T_SUB, T_MUL, T_QUOT, T_REM, T_SUBR, T_UQUOT, T_UREM, T_NEG,
@@ -144,6 +145,8 @@
"LAST_TAG",
};
+struct ioarray;
+
 typedef struct node {   union {struct node *uufun;
@@ -150,11 +153,12 @@
tag_t uutag; /* LSB=1 indicates that this is a tag, LSB=0 that this is a T_AP node */
} ufun;
   union {- struct node *uuarg;
- value_t uuvalue;
- flt_t uufloatvalue;
- const char *uustring;
- void *uuptr;
+ struct node *uuarg;
+ value_t uuvalue;
+ flt_t uufloatvalue;
+ const char *uustring;
+ void *uuptr;
+ struct ioarray *uuarray;
} uarg;
} node;
typedef struct node* NODEPTR;
@@ -170,6 +174,7 @@
#define ARG(p) (p)->uarg.uuarg
#define STR(p) (p)->uarg.uustring
#define PTR(p) (p)->uarg.uuptr
+#define ARR(p) (p)->uarg.uuarray
#define INDIR(p) ARG(p)
#define NODE_SIZE sizeof(node)
 #define ALLOC_HEAP(n) do { cells = malloc(n * sizeof(node)); memset(cells, 0x55, n * sizeof(node)); } while(0)@@ -176,6 +181,14 @@
#define LABEL(n) ((heapoffs_t)((n) - cells))
node *cells; /* All cells */
+struct ioarray {+ struct ioarray *next; /* all ioarrays are linked together */
+ int marked; /* marked during GC */
+ size_t size; /* number of elements in the array */
+ NODEPTR array[1]; /* actual size may be bigger */
+};
+struct ioarray *array_root = 0;
+
counter_t num_reductions = 0;
counter_t num_alloc;
counter_t num_gc = 0;
@@ -775,6 +788,7 @@
#if GCRED
value_t i;
#endif
+ enum node_tag tag;
// mark_depth++;
// if (mark_depth % 10000 == 0)
@@ -781,11 +795,12 @@
   //    printf("mark depth %"PRIcounter"\n", mark_depth);top:
n = *np;
-  if (GETTAG(n) == T_IND) {+ tag = GETTAG(n);
+  if (tag == T_IND) {#if SANITY
int loop = 0;
/* Skip indirections, and redirect start pointer */
-    while (GETTAG(n) == T_IND) {+    while ((tag = GETTAG(n)) == T_IND) {       //      printf("*"); fflush(stdout);n = INDIR(n);
       if (loop++ > 10000000) {@@ -796,7 +811,7 @@
// if (loop)
     //      printf("\n");#else /* SANITY */
-    while (GETTAG(n) == T_IND) {+    while ((tag = GETTAG(n)) == T_IND) {n = INDIR(n);
}
#endif /* SANITY */
@@ -811,7 +826,7 @@
#if GCRED
   if (want_gc_red) {/* This is really only fruitful just after parsing. It can be removed. */
-    if (GETTAG(n) == T_AP && GETTAG(FUN(n)) == T_AP && GETTAG(FUN(FUN(n))) == T_A) {+    if (tag == T_AP && GETTAG(FUN(n)) == T_AP && GETTAG(FUN(FUN(n))) == T_A) {/* Do the A x y --> y reduction */
NODEPTR y = ARG(n);
SETTAG(n, T_IND);
@@ -821,7 +836,7 @@
}
#if 0
/* This never seems to happen */
-    if (GETTAG(n) == T_AP && GETTAG(FUN(n)) == T_AP && GETTAG(FUN(FUN(n))) == T_K) {+    if (tag == T_AP && GETTAG(FUN(n)) == T_AP && GETTAG(FUN(FUN(n))) == T_K) {/* Do the K x y --> x reduction */
NODEPTR x = ARG(FUN(n));
SETTAG(n, T_IND);
@@ -830,7 +845,7 @@
goto top;
}
#endif /* 0 */
-    if (GETTAG(n) == T_AP && GETTAG(FUN(n)) == T_I) {+    if (tag == T_AP && GETTAG(FUN(n)) == T_I) {/* Do the I x --> x reduction */
NODEPTR x = ARG(n);
SETTAG(n, T_IND);
@@ -842,7 +857,7 @@
/* This is broken.
* Probably because it can happen in the middle of the C node.
*/
-    if (GETTAG(n) == T_AP && GETTAG(FUN(n)) == T_C) {+    if (tag == T_AP && GETTAG(FUN(n)) == T_C) {NODEPTR q = ARG(n);
enum node_tag tt, tf;
while ((tt = GETTAG(q)) == T_IND)
@@ -860,7 +875,7 @@
}
#endif
#if INTTABLE
-  if (GETTAG(n) == T_INT && LOW_INT <= (i = GETVALUE(n)) && i < HIGH_INT) {+  if (tag == T_INT && LOW_INT <= (i = GETVALUE(n)) && i < HIGH_INT) {SETTAG(n, T_IND);
INDIR(n) = intTable[i - LOW_INT];
red_int++;
@@ -868,7 +883,7 @@
}
#endif /* INTTABLE */
#endif /* GCRED */
-  if (GETTAG(n) == T_AP) {+  if (tag == T_AP) {#if 1
mark(&FUN(n));
//mark(&ARG(n));
@@ -879,6 +894,10 @@
np = &FUN(n);
goto top; /* Avoid tail recursion */
#endif
+  } else if (tag == T_IOARR) {+ struct ioarray *arr = ARR(n);
+ for(size_t i = 0; i < arr->size; i++)
+ mark(&arr->array[i]);
}
}
@@ -906,6 +925,12 @@
num_free = heap_size - heap_start - num_marked;
if (num_free < heap_size / 50)
     ERR("heap exhausted");+
+ struct ioarray **arrp;
+  for (arrp = &array_root; *arrp; arrp = &(*arrp)->next) {+
+ }
+
#if WANT_STDIO
   if (verbose > 1) {fprintf(stderr, "gc done, %"PRIcounter" free\n", num_free);
--
⑨