[move tagging from the heap to the pointer, allowing more interesting whnf representations and speeding things up
John Meacham <john@repetae.net>**20070225063043] hunk ./C/FromGrin2.hs 86
-        f n t = tshow (nodeTagName t) <> text " = " <> tshow (n * 4 + 2 :: Int)
+        f n t = tshow (nodeTagName t) <> text " = " <> tshow (n :: Int) -- (n * 4 + 2 :: Int)
hunk ./C/FromGrin2.hs 527
-    return (mconcat $ malloc:tagassign:ass, cast pnode_t tmp)
+        tmp'' = functionCall (name "EVALTAG") [tmp]
+    return (mconcat $ malloc:tagassign:ass, cast pnode_t tmp'')
hunk ./data/jhc_rts2.c 4
-#define PTAG(x)   (((uintptr_t)(x)) & 0x3)
-#define TAGP(x,t) ((x) | (t))
-#define NODEP(x)  ((node_t *)(x))
-#define EVALTAG(fn) ((tag_t)((uintptr_t)(fn) | P_EVAL))
+#define ISLAZY(x)   (((uintptr_t)(x)) & 0x1)
+#define DETAG(x)    ((uintptr_t)(x) & ~0x3)
hunk ./data/jhc_rts2.c 7
-#define P_VALUE    0x3
-#define P_INDIRECT 0x0
+#define GETHEAD(x)  (NODEP(x)->tag)
+#define NODEP(x)    ((node_t *)(x))
+#define EVALTAG(fn) ((tag_t)((uintptr_t)(fn) | P_LAZY))
hunk ./data/jhc_rts2.c 11
-#define P_EVAL 0x1
-#define P_WHNF 0x2
+#define P_VALUE 0x2
+#define P_WHNF  0x0
+#define P_LAZY  0x1
hunk ./data/jhc_rts2.c 17
-/* a pointer may be one of the following
+/* a value may be one of the following and is represented by a sptr_t
hunk ./data/jhc_rts2.c 20
- * |    raw value      | 11|
+ * |    raw value      | 10|
hunk ./data/jhc_rts2.c 23
+ * -------------------------
+ * |    whnf location  | 00|
+ * -------------------------
hunk ./data/jhc_rts2.c 28
- * |    heap location  | 00|
+ * |   lazy location   | u1|
hunk ./data/jhc_rts2.c 31
- *  a heap location is always at least a single word long, its header word may
- *  be the following,
+ * whnf and raw value field formats are completly determined by the data type
+ * and need not conform to any particular format.
+ *
+ *  a lazy location is always at least a single word long which is always one
+ *  of the following
hunk ./data/jhc_rts2.c 38
- * |    raw value      | 11|
+ * |    raw value      | 10|
hunk ./data/jhc_rts2.c 41
- *
hunk ./data/jhc_rts2.c 42
- * |    heap indirect  | 00|
+ * |    whnf location  | 00|
hunk ./data/jhc_rts2.c 45
- * note that these two values have the exact same format as a pointer, so you
- * may always overwrite the first word of a heap location with a pointer.
+ *  which are interpreted exactly as above or
hunk ./data/jhc_rts2.c 48
- * |    code pointer   | 01|
+ * |    code pointer   | u1|
hunk ./data/jhc_rts2.c 54
- * of updating the location if needed and it is assumed enough space is available
- * for whatever the location is updated with
- *
- *
- * -------------------------
- * |    data ...       | 10|
- * -------------------------
- * |     ...               |
- *
- * an object in WHNF. format is type specific
+ * of updating the location if needed.
hunk ./data/jhc_rts2.c 56
+ * note that it is invalid to have a lazy location point to another lazy
+ * location. there is only ever one level of indirection allowed, and only from
+ * lazy locations
hunk ./data/jhc_rts2.c 60
- * raw values are never pointers to the heap. data is filled in in a type
- * specific manner.
+ * note that a partial application is just like any other value in WHNF as far
+ * as the above is concered. It happens to possibly contain a code pointer.
hunk ./data/jhc_rts2.c 63
- * note that a partial application is just like any other value but it happens
- * to contain a code pointer, and may be represented by a 01 or a 11 if in
- * WHNF and depending on whether it has data attached.
+ * u bits are undefined.
hunk ./data/jhc_rts2.c 71
- * sptr_t - a tagged smart pointer, may be a value, may be a pointer to a node
- * node_t - definitely a pointer to a node
- * tag_t - the first value in a node, has a tag indicating what it is
- *
- * there are several things a sptr_t can represent, often, it can be determined
- * statically what the possibilities are at any given point in the program
- *
- *
- * a literal value in WHNF
- * a pointer to a whnf node
- * a pointer to a thunk
- *
- * a thunk is always either one of
- * an unevaluated closure, a pointer to a function and its arguments
- *
- * or if evaluated, the first word is one of:
- * a pointer to something in WHNF
- * a literal value in WHNF
+ * sptr_t - a tagged smart pointer, may be a value, may be a pointer to a whnf or lazy location
+ * node_t - definitely a pointer to a lazy location
+ * tag_t - the first value in a lazy location, has a tag indicating what it is
hunk ./data/jhc_rts2.c 93
-    assert(PTAG(s) == P_VALUE ||  PTAG((sptr_t)(NODEP(s)->tag)) == P_WHNF);
-    return s;
+        assert(!ISLAZY(s));
+        return s;
hunk ./data/jhc_rts2.c 100
-        if(PTAG(s) == P_INDIRECT) {
-                sptr_t h = (sptr_t)(NODEP(s)->tag);
-                switch(PTAG(h)) {
-                case P_INDIRECT:
-                        return eval(h);
-                case P_EVAL:
-                        return ((eval_fn)NODEP((uintptr_t)h & ~0x3))(NODEP(s));
-                case P_VALUE:
-                        return h;
-                default: // P_WHNF
-                        return s;
+        if(ISLAZY(s)) {
+                void *ds = (void *)DETAG(s);
+                sptr_t h = (sptr_t)(GETHEAD(ds));
+                if(ISLAZY(h)) {
+                        return ((eval_fn)DETAG(h))(NODEP(ds));
hunk ./data/jhc_rts2.c 106
-        } else {
-                assert(PTAG(s) == P_VALUE);
-                return s;
+                return h;
hunk ./data/jhc_rts2.c 108
+        return s;
hunk ./data/jhc_rts2.c 115
-        assert(PTAG(thunk) == P_INDIRECT);
-        assert(PTAG(NODEP(thunk)->tag) == P_EVAL);
-        NODEP(thunk)->tag = (tag_t)new;
+        update_inc();
+        assert(ISLAZY(GETHEAD(thunk)));
+        assert(!ISLAZY(new));
+        GETHEAD(thunk) = (tag_t)new;