shithub: MicroHs

Download patch

ref: 6c47eba740757adbe3cbdcd61645cadeb125c47d
parent: 36500620d51ebbb7eda5b00edc642b50c02e0ae0
author: Lennart Augustsson <lennart.augustsson@epicgames.com>
date: Sat Aug 17 16:25:58 EDT 2024

Avoid global variables for mark bits used in serialization.

--- a/src/runtime/eval.c
+++ b/src/runtime/eval.c
@@ -1758,8 +1758,10 @@
  * 1, 1   -- visited more than once
  * 0, 1   -- printed
  */
-bits_t *marked_bits;
-bits_t *shared_bits;
+struct print_bits {
+  bits_t *marked_bits;
+  bits_t *shared_bits;
+};
 static INLINE void set_bit(bits_t *bits, NODEPTR n)
 {
   heapoffs_t i = LABEL(n);
@@ -1815,11 +1817,11 @@
   putsb(str, p);
 }
 
-void printrec(BFILE *f, NODEPTR n, int prefix);
+void printrec(BFILE *f, struct print_bits *pb, NODEPTR n, int prefix);
 
 /* Mark all reachable nodes, when a marked node is reached, mark it as shared. */
 void
-find_sharing(NODEPTR n)
+find_sharing(struct print_bits *pb, NODEPTR n)
 {
  top:
   while (GETTAG(n) == T_IND) {
@@ -1829,26 +1831,26 @@
   //PRINT("find_sharing %p %llu ", n, LABEL(n));
   tag_t tag = GETTAG(n);
   if (tag == T_AP || tag == T_ARR) {
-    if (test_bit(shared_bits, n)) {
+    if (test_bit(pb->shared_bits, n)) {
       /* Alread marked as shared */
       //PRINT("shared\n");
       ;
-    } else if (test_bit(marked_bits, n)) {
+    } else if (test_bit(pb->marked_bits, n)) {
       /* Already marked, so now mark as shared */
       //PRINT("marked\n");
-      set_bit(shared_bits, n);
+      set_bit(pb->shared_bits, n);
       num_shared++;
     } else {
       /* Mark as visited, and recurse */
       //PRINT("unmarked\n");
-      set_bit(marked_bits, n);
+      set_bit(pb->marked_bits, n);
       if (tag == T_AP) {
-        find_sharing(FUN(n));
+        find_sharing(pb, FUN(n));
         n = ARG(n);
         goto top;
       } else {
         for(size_t i = 0; i < ARR(n)->size; i++) {
-          find_sharing(ARR(n)->array[i]);
+          find_sharing(pb, ARR(n)->array[i]);
         }
       }
     }
@@ -1882,7 +1884,7 @@
  * The prefix flag is used to get a readable dump.
  */
 void
-printrec(BFILE *f, NODEPTR n, int prefix)
+printrec(BFILE *f, struct print_bits *pb, NODEPTR n, int prefix)
 {
   int share = 0;
 
@@ -1891,9 +1893,9 @@
     n = INDIR(n);
   }
 
-  if (test_bit(shared_bits, n)) {
+  if (test_bit(pb->shared_bits, n)) {
     /* The node is shared */
-    if (test_bit(marked_bits, n)) {
+    if (test_bit(pb->marked_bits, n)) {
       /* Not yet printed, so emit a label */
       if (prefix) {
         putb(':', f);
@@ -1902,7 +1904,7 @@
       } else {
         share = 1;
       }
-      clear_bit(marked_bits, n);  /* mark as printed */
+      clear_bit(pb->marked_bits, n);  /* mark as printed */
     } else {
       /* This node has already been printed, so just use a reference. */
       putb('_', f);
@@ -1918,13 +1920,13 @@
   case T_AP:
     if (prefix) {
       putb('(', f);
-      printrec(f, FUN(n), prefix);
+      printrec(f, pb, FUN(n), prefix);
       putb(' ', f);
-      printrec(f, ARG(n), prefix);
+      printrec(f, pb, ARG(n), prefix);
       putb(')', f);
     } else {
-      printrec(f, FUN(n), prefix);
-      printrec(f, ARG(n), prefix);
+      printrec(f, pb, FUN(n), prefix);
+      printrec(f, pb, ARG(n), prefix);
       putb('@', f);
     }
     break;
@@ -1938,12 +1940,12 @@
       putb(']', f);
       for(size_t i = 0; i < ARR(n)->size; i++) {
         putb(' ', f);
-        printrec(f, ARR(n)->array[i], prefix);
+        printrec(f, pb, ARR(n)->array[i], prefix);
       }
     } else {
       /* Arrays serialize as 'e_1 ... e_sz [sz]' */
       for(size_t i = 0; i < ARR(n)->size; i++) {
-        printrec(f, ARR(n)->array[i], prefix);
+        printrec(f, pb, ARR(n)->array[i], prefix);
       }
       putb('[', f);
       putdecb((value_t)ARR(n)->size, f);
@@ -2094,25 +2096,26 @@
 void
 printb(BFILE *f, NODEPTR n, int header)
 {
+  struct print_bits pb;
   num_shared = 0;
-  marked_bits = calloc(free_map_nwords, sizeof(bits_t));
-  if (!marked_bits)
+  pb.marked_bits = calloc(free_map_nwords, sizeof(bits_t));
+  if (!pb.marked_bits)
     memerr();
-  shared_bits = calloc(free_map_nwords, sizeof(bits_t));
-  if (!shared_bits)
+  pb.shared_bits = calloc(free_map_nwords, sizeof(bits_t));
+  if (!pb.shared_bits)
     memerr();
-  find_sharing(n);
+  find_sharing(&pb, n);
   if (header) {
     putsb(VERSION, f);
     putdecb(num_shared, f);
     putb('\n', f);
   }
-  printrec(f, n, !header);
+  printrec(f, &pb, n, !header);
   if (header) {
     putb('}', f);
   }
-  FREE(marked_bits);
-  FREE(shared_bits);
+  FREE(pb.marked_bits);
+  FREE(pb.shared_bits);
 }
 
 /* Show a graph. */
--