multi-slurp protection
[ghc-hetmet.git] / includes / Cmm.h
index c0b2fe9..e3f46e1 100644 (file)
@@ -88,6 +88,7 @@
 #define I16 bits16
 #define I32 bits32
 #define I64 bits64
+#define P_  gcptr
 
 #if SIZEOF_VOID_P == 4
 #define W_ bits32
    Indirections can contain tagged pointers, so their tag is checked.
    -------------------------------------------------------------------------- */
 
+#ifdef PROFILING
+
+// When profiling, we cannot shortcut ENTER() by checking the tag,
+// because LDV profiling relies on entering closures to mark them as
+// "used".
+
+#define LOAD_INFO \
+    info = %INFO_PTR(UNTAG(P1));
+
+#define UNTAG_R1 \
+    P1 = UNTAG(P1);
+
+#else
+
+#define LOAD_INFO                               \
+  if (GETTAG(P1) != 0) {                        \
+      jump %ENTRY_CODE(Sp(0));                  \
+  }                                             \
+  info = %INFO_PTR(P1);
+
+#define UNTAG_R1 /* nothing */
+
+#endif
+
 #define ENTER()                                                \
  again:                                                        \
   W_ info;                                             \
-  if (GETTAG(R1) != 0) {                                \
-      jump %ENTRY_CODE(Sp(0));                         \
-  }                                                     \
-  info = %INFO_PTR(R1);                                        \
+  LOAD_INFO                                             \
   switch [INVALID_OBJECT .. N_CLOSURE_TYPES]           \
          (TO_W_( %INFO_TYPE(%STD_INFO(info)) )) {      \
   case                                                 \
     IND_OLDGEN_PERM,                                   \
     IND_STATIC:                                                \
    {                                                   \
-      R1 = StgInd_indirectee(R1);                      \
+      P1 = StgInd_indirectee(P1);                      \
       goto again;                                      \
    }                                                   \
   case                                                 \
     FUN_0_1,                                           \
     FUN_2_0,                                           \
     FUN_1_1,                                           \
+    FUN_0_2,                                           \
     FUN_STATIC,                                         \
     BCO,                                               \
     PAP:                                               \
    }                                                   \
   default:                                             \
    {                                                   \
+      UNTAG_R1                                          \
       jump %ENTRY_CODE(info);                          \
    }                                                   \
   }
   bdescr_free(__bd) = free + WDS(1);
 
 #define recordMutable(p, regs)                                  \
-      W_ __p;                                                   \
+      P_ __p;                                                   \
       W_ __bd;                                                  \
       W_ __gen;                                                 \
       __p = p;                                                  \