rts/Linker.c (loadArchive):
[ghc.git] / rts / Apply.cmm
index c9c7daa..9af9b11 100644 (file)
@@ -30,9 +30,7 @@ stg_ap_0_fast
        foreign "C" printClosure(R1 "ptr") [R1]);
 
     IF_DEBUG(sanity,
-       foreign "C" checkStackChunk(Sp "ptr",
-                                   CurrentTSO + TSO_OFFSET_StgTSO_stack +
-                                   WDS(TO_W_(StgTSO_stack_size(CurrentTSO))) "ptr") [R1]);
+       foreign "C" checkStackFrame(Sp "ptr") [R1]);
 
     ENTER();
 }
@@ -223,6 +221,76 @@ for:
 #endif
 }
 
+/* AP_NOUPD is exactly like AP, except that no update frame is pushed.
+   Use for thunks that are guaranteed to be entered once only, such as 
+   those generated by the byte-code compiler for inserting breakpoints. */
+
+INFO_TABLE(stg_AP_NOUPD,/*special layout*/0,0,AP,"AP_NOUPD","AP_NOUPD")
+{
+  W_ Words;
+  W_ ap;
+    
+  ap = R1;
+  
+  Words = TO_W_(StgAP_n_args(ap));
+
+  /* 
+   * Check for stack overflow.  IMPORTANT: use a _NP check here,
+   * because if the check fails, we might end up blackholing this very
+   * closure, in which case we must enter the blackhole on return rather
+   * than continuing to evaluate the now-defunct closure.
+   */
+  STK_CHK_NP(WDS(Words));
+  Sp = Sp - WDS(Words);
+
+  TICK_ENT_AP();
+  LDV_ENTER(ap);
+
+  // Enter PAP cost centre
+  ENTER_CCS_PAP_CL(ap);   // ToDo: ENTER_CC_AP_CL 
+
+  // Reload the stack 
+  W_ i;
+  W_ p;
+  p = ap + SIZEOF_StgHeader + OFFSET_StgAP_payload;
+  i = 0;
+for:
+  if (i < Words) {
+    Sp(i) = W_[p];
+    p = p + WDS(1);
+    i = i + 1;
+    goto for;
+  }
+
+  R1 = StgAP_fun(ap);
+
+  // Off we go! 
+  TICK_ENT_VIA_NODE();
+
+#ifdef NO_ARG_REGS
+  jump %GET_ENTRY(UNTAG(R1));
+#else
+      W_ info;
+      info = %GET_FUN_INFO(UNTAG(R1));
+      W_ type;
+      type = TO_W_(StgFunInfoExtra_fun_type(info));
+      if (type == ARG_GEN) {
+         jump StgFunInfoExtra_slow_apply(info);
+      }
+      if (type == ARG_GEN_BIG) {
+         jump StgFunInfoExtra_slow_apply(info);
+      }
+      if (type == ARG_BCO) {
+         Sp_adj(-2);
+         Sp(1) = R1;
+         Sp(0) = stg_apply_interp_info;
+         jump stg_yield_to_interpreter;
+      }
+      jump W_[stg_ap_stack_entries + 
+               WDS(TO_W_(StgFunInfoExtra_fun_type(info)))];
+#endif
+}
+
 /* -----------------------------------------------------------------------------
    Entry Code for an AP_STACK.
 
@@ -249,7 +317,9 @@ INFO_TABLE(stg_AP_STACK,/*special layout*/0,0,AP_STACK,"AP_STACK","AP_STACK")
    * closure, in which case we must enter the blackhole on return rather
    * than continuing to evaluate the now-defunct closure.
    */
-  STK_CHK_NP(WDS(Words) + SIZEOF_StgUpdateFrame);
+  STK_CHK_NP(WDS(Words) + SIZEOF_StgUpdateFrame + WDS(AP_STACK_SPLIM));
+  /* ensure there is at least AP_STACK_SPLIM words of headroom available
+   * after unpacking the AP_STACK. See bug #1466 */
 
   PUSH_UPD_FRAME(Sp - SIZEOF_StgUpdateFrame, R1);
   Sp = Sp - SIZEOF_StgUpdateFrame - WDS(Words);