+ int ret_dyn_size =
+ RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE
+ + sizeofW(StgRetDyn);
+
+#ifdef RTS_SUPPORTS_THREADS
+ // Threaded RTS:
+ // Arguments on the TSO stack are not good, because garbage
+ // collection might move the TSO as soon as we call
+ // suspendThread below.
+
+ W_ arguments[stk_offset];
+
+ memcpy(arguments, Sp, sizeof(W_) * stk_offset);
+#endif
+
+ // There are a bunch of non-ptr words on the stack (the
+ // ccall args, the ccall fun address and space for the
+ // result), which we need to cover with an info table
+ // since we might GC during this call.
+ //
+ // We know how many (non-ptr) words there are before the
+ // next valid stack frame: it is the stk_offset arg to the
+ // CCALL instruction. So we build a RET_DYN stack frame
+ // on the stack frame to describe this chunk of stack.
+ //
+ Sp -= ret_dyn_size;
+ ((StgRetDyn *)Sp)->liveness = ALL_NON_PTRS | N_NONPTRS(stk_offset);
+ ((StgRetDyn *)Sp)->info = (StgInfoTable *)&stg_gc_gen_info;