Fix histograms for ticky code
[ghc.git] / rts / AutoApply.h
index f64bc6d..4e441ca 100644 (file)
 // ret addr and m arguments taking up n words are on the stack.
 // NB. x is a dummy argument attached to the 'for' label so that
 // BUILD_PAP can be used multiple times in the same function.
-#define BUILD_PAP(m,n,f,x)                             \
-    W_ pap;                                            \
-    W_ size;                                           \
-    W_ i;                                              \
-    size = SIZEOF_StgPAP + WDS(n);                     \
-    HP_CHK_NP_ASSIGN_SP0(size,f);                      \
-    TICK_ALLOC_PAP(size, 0);                           \
-    CCCS_ALLOC(size);                                  \
-    pap = Hp + WDS(1) - size;                          \
+#define BUILD_PAP(m,n,f,x)                              \
+    W_ pap;                                             \
+    W_ size;                                            \
+    W_ i;                                               \
+    size = SIZEOF_StgPAP + WDS(n);                      \
+    HP_CHK_NP_ASSIGN_SP0(size,f);                       \
+    TICK_ALLOC_PAP(size, 0);                            \
+    CCCS_ALLOC(size);                                   \
+    pap = Hp + WDS(1) - size;                           \
     SET_HDR(pap, stg_PAP_info, CCCS);                   \
-    StgPAP_arity(pap) = HALF_W_(arity - m);            \
-    StgPAP_fun(pap)   = R1;                            \
-    StgPAP_n_args(pap) = HALF_W_(n);                   \
-    i = 0;                                             \
-  for##x:                                              \
-    if (i < n) {                                       \
-       StgPAP_payload(pap,i) = Sp(1+i);                \
-       i = i + 1;                                      \
-       goto for##x;                                    \
-    }                                                  \
-    R1 = pap;                                          \
-    Sp_adj(1 + n);                                     \
+    StgPAP_arity(pap) = HALF_W_(arity - m);             \
+    StgPAP_fun(pap)   = R1;                             \
+    StgPAP_n_args(pap) = HALF_W_(n);                    \
+    i = 0;                                              \
+  for##x:                                               \
+    if (i < n) {                                        \
+        StgPAP_payload(pap,i) = Sp(1+i);                \
+        i = i + 1;                                      \
+        goto for##x;                                    \
+    }                                                   \
+    R1 = pap;                                           \
+    Sp_adj(1 + n);                                      \
     jump %ENTRY_CODE(Sp(0)) [R1];
 
+// Just like when we enter a PAP, if we're building a new PAP by applying more
+// arguments to an existing PAP, we must construct the CCS for the new PAP as if
+// we had entered the existing PAP from the current CCS.  Otherwise, we lose any
+// stack information in the existing PAP.  See #5654, and the test T5654b-O0.
+#ifdef PROFILING
+#define ENTER_FUN_CCS_NEW_PAP(pap) \
+  ccall enterFunCCS(BaseReg "ptr", StgHeader_ccs(pap) "ptr");
+#else
+#define ENTER_FUN_CCS_NEW_PAP(pap) /* empty */
+#endif
+
 // Copy the old PAP, build a new one with the extra arg(s)
 // ret addr and m arguments taking up n words are on the stack.
 // NB. x is a dummy argument attached to the 'for' label so that
 // BUILD_PAP can be used multiple times in the same function.
-#define NEW_PAP(m,n,f,x)                                       \
-     W_ pap;                                                   \
-     W_ new_pap;                                               \
-     W_ size;                                                  \
-     W_ i;                                                     \
-     pap = R1;                                                 \
-     size = SIZEOF_StgPAP + WDS(TO_W_(StgPAP_n_args(pap))) + WDS(n);   \
-     HP_CHK_NP_ASSIGN_SP0(size,f);                             \
-     TICK_ALLOC_PAP(size, 0);                                  \
-     CCCS_ALLOC(size);                                         \
-     new_pap = Hp + WDS(1) - size;                             \
+#define NEW_PAP(m,n,f,x)                                        \
+     W_ pap;                                                    \
+     W_ new_pap;                                                \
+     W_ size;                                                   \
+     W_ i;                                                      \
+     pap = R1;                                                  \
+     size = SIZEOF_StgPAP + WDS(TO_W_(StgPAP_n_args(pap))) + WDS(n);    \
+     HP_CHK_NP_ASSIGN_SP0(size,f);                              \
+     TICK_ALLOC_PAP(size, 0);                                   \
+     CCCS_ALLOC(size);                                          \
+     ENTER_FUN_CCS_NEW_PAP(pap);                                \
+     new_pap = Hp + WDS(1) - size;                              \
      SET_HDR(new_pap, stg_PAP_info, CCCS);                      \
-     StgPAP_arity(new_pap) = HALF_W_(arity - m);               \
-     W_ n_args;                                                        \
-     n_args = TO_W_(StgPAP_n_args(pap));                       \
-     StgPAP_n_args(new_pap) = HALF_W_(n_args + n);             \
-     StgPAP_fun(new_pap) = StgPAP_fun(pap);                    \
-     i = 0;                                                    \
-   for1##x:                                                    \
-     if (i < n_args) {                                         \
-         StgPAP_payload(new_pap,i) = StgPAP_payload(pap,i);    \
-        i = i + 1;                                             \
-        goto for1##x;                                          \
-     }                                                         \
-     i = 0;                                                    \
-   for2##x:                                                    \
-     if (i < n) {                                              \
-        StgPAP_payload(new_pap,n_args+i) = Sp(1+i);            \
-         i = i + 1;                                            \
-         goto for2##x;                                         \
-     }                                                         \
-     R1 = new_pap;                                             \
-     Sp_adj(n+1);                                              \
+     StgPAP_arity(new_pap) = HALF_W_(arity - m);                \
+     W_ n_args;                                                 \
+     n_args = TO_W_(StgPAP_n_args(pap));                        \
+     StgPAP_n_args(new_pap) = HALF_W_(n_args + n);              \
+     StgPAP_fun(new_pap) = StgPAP_fun(pap);                     \
+     i = 0;                                                     \
+   for1##x:                                                     \
+     if (i < n_args) {                                          \
+         StgPAP_payload(new_pap,i) = StgPAP_payload(pap,i);     \
+         i = i + 1;                                             \
+         goto for1##x;                                          \
+     }                                                          \
+     i = 0;                                                     \
+   for2##x:                                                     \
+     if (i < n) {                                               \
+         StgPAP_payload(new_pap,n_args+i) = Sp(1+i);            \
+         i = i + 1;                                             \
+         goto for2##x;                                          \
+     }                                                          \
+     R1 = new_pap;                                              \
+     Sp_adj(n+1);                                               \
      jump %ENTRY_CODE(Sp(0)) [R1];
 
 // Jump to target, saving CCCS and restoring it on return
 #if defined(PROFILING)
-#define jump_SAVE_CCCS(target)                  \
+#define jump_SAVE_CCCS(target,...)              \
     Sp(-1) = CCCS;                              \
     Sp(-2) = stg_restore_cccs_info;             \
     Sp_adj(-2);                                 \
-    jump (target) [R1]
+    jump (target) [__VA_ARGS__]
 #else
-#define jump_SAVE_CCCS(target) jump (target) [R1]
+#define jump_SAVE_CCCS(target,...) jump (target) [__VA_ARGS__]
 #endif
 
 #endif /* APPLY_H */