Commit 1da232fc authored by simonmar's avatar simonmar

[project @ 2003-04-22 16:25:08 by simonmar]

Fix an obscure bug: the most general kind of heap check,
HEAP_CHECK_GEN(), is supposed to save the contents of *every* register
known to the STG machine (used in cases where we either can't figure
out which ones are live, or doing so would be too much hassle).  The
problem is that it wasn't saving the L1 register.

A slight complication arose in that saving the L1 register pushed the
size of the frame over the 16 words allowed for the size of the bitmap
stored in the frame, so I changed the layout of the frame a bit.
Describing all the registers using a single bitmap is overkill when
only 8 of them can actually be pointers, so now the bitmap is only 8
bits long and we always skip over a fixed number of non-ptr words to
account for all the non-ptr regs.  This is all described in StgMacros.h.
parent 3c85beaf
/* -----------------------------------------------------------------------------
* $Id: StgMacros.h,v 1.50 2002/12/11 15:36:39 simonmar Exp $
* $Id: StgMacros.h,v 1.51 2003/04/22 16:25:08 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
......@@ -230,14 +230,18 @@ typedef StgWord StgWordArray[];
The stack frame layout for a RET_DYN is like this:
some pointers
some nonpointers
DblReg1-2
FltReg1-4
R1-8
return address
liveness mask
stg_gen_chk_info
some pointers |-- GET_PTRS(liveness) words
some nonpointers |-- GET_NONPTRS(liveness) words
L1 \
D1-2 |-- RET_DYN_NONPTR_REGS_SIZE words
F1-4 /
R1-8 |-- RET_DYN_BITMAP_SIZE words
return address \
liveness mask |-- StgRetDyn structure
stg_gen_chk_info /
we assume that the size of a double is always 2 pointers (wasting a
word when it is only one pointer, but avoiding lots of #ifdefs).
......@@ -247,8 +251,9 @@ typedef StgWord StgWordArray[];
// VERY MAGIC CONSTANTS!
// must agree with code in HeapStackCheck.c, stg_gen_chk
//
#define ALL_NON_PTRS 0xffff
#define RET_DYN_SIZE 16
#define RET_DYN_BITMAP_SIZE 8
#define RET_DYN_NONPTR_REGS_SIZE 10
#define ALL_NON_PTRS 0xff
#define LIVENESS_MASK(ptr_regs) (ALL_NON_PTRS ^ (ptr_regs))
......
/* -----------------------------------------------------------------------------
* $Id: GC.c,v 1.153 2003/04/01 15:05:13 sof Exp $
* $Id: GC.c,v 1.154 2003/04/22 16:25:09 simonmar Exp $
*
* (c) The GHC Team 1998-2003
*
......@@ -3689,11 +3689,11 @@ scavenge_stack(StgPtr p, StgPtr stack_end)
// traverse the bitmap first
bitmap = GET_LIVENESS(dyn);
p = (P_)&((StgRetDyn *)p)->payload[0];
size = RET_DYN_SIZE;
size = RET_DYN_BITMAP_SIZE;
p = scavenge_small_bitmap(p, size, bitmap);
// skip over the non-ptr words
p += GET_NONPTRS(dyn);
p += GET_NONPTRS(dyn) + RET_DYN_NONPTR_REGS_SIZE;
// follow the ptr words
for (size = GET_PTRS(dyn); size > 0; size--) {
......
/* -----------------------------------------------------------------------------
* $Id: GCCompact.c,v 1.15 2003/03/24 16:18:26 simonmar Exp $
* $Id: GCCompact.c,v 1.16 2003/04/22 16:25:10 simonmar Exp $
*
* (c) The GHC Team 2001
*
......@@ -270,7 +270,7 @@ thread_stack(StgPtr p, StgPtr stack_end)
// traverse the bitmap first
bitmap = GET_LIVENESS(dyn);
p = (P_)&((StgRetDyn *)p)->payload[0];
size = RET_DYN_SIZE;
size = RET_DYN_BITMAP_SIZE;
while (size > 0) {
if ((bitmap & 1) == 0) {
thread(p);
......@@ -281,7 +281,7 @@ thread_stack(StgPtr p, StgPtr stack_end)
}
// skip over the non-ptr words
p += GET_NONPTRS(dyn);
p += GET_NONPTRS(dyn) + RET_DYN_NONPTR_REGS_SIZE;
// follow the ptr words
for (size = GET_PTRS(dyn); size > 0; size--) {
......
/* -----------------------------------------------------------------------------
* $Id: HeapStackCheck.hc,v 1.29 2003/03/19 18:56:14 sof Exp $
* $Id: HeapStackCheck.hc,v 1.30 2003/04/22 16:25:10 simonmar Exp $
*
* (c) The GHC Team, 1998-2002
*
......@@ -810,6 +810,7 @@ EXTFUN(stg_gc_fun_ret)
// it's not a big deal.
#define RESTORE_EVERYTHING \
L1 = PK_Word64(Sp+19); \
D2 = PK_DBL(Sp+17); \
D1 = PK_DBL(Sp+15); \
F4 = PK_FLT(Sp+14); \
......@@ -824,12 +825,13 @@ EXTFUN(stg_gc_fun_ret)
R3.w = Sp[5]; \
R2.w = Sp[4]; \
R1.w = Sp[3]; \
Sp += 19;
Sp += 21;
#define RET_OFFSET (-17)
#define RET_OFFSET (-19)
#define SAVE_EVERYTHING \
Sp -= 19; \
Sp -= 21; \
ASSIGN_Word64(Sp+19,L1); \
ASSIGN_DBL(Sp+17,D2); \
ASSIGN_DBL(Sp+15,D1); \
ASSIGN_FLT(Sp+14,F4); \
......
......@@ -1157,6 +1157,9 @@ run_BCO:
int stk_offset = BCO_NEXT;
int o_itbl = BCO_NEXT;
void(*marshall_fn)(void*) = (void (*)(void*))BCO_LIT(o_itbl);
int ret_dyn_size =
RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE
+ sizeofW(StgRetDyn);
#ifdef RTS_SUPPORTS_THREADS
// Threaded RTS:
......@@ -1168,7 +1171,7 @@ run_BCO:
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
......@@ -1179,7 +1182,7 @@ run_BCO:
// CCALL instruction. So we build a RET_DYN stack frame
// on the stack frame to describe this chunk of stack.
//
Sp -= RET_DYN_SIZE + sizeofW(StgRetDyn);
Sp -= ret_dyn_size;
((StgRetDyn *)Sp)->liveness = ALL_NON_PTRS | N_NONPTRS(stk_offset);
((StgRetDyn *)Sp)->info = (StgInfoTable *)&stg_gc_gen_info;
......@@ -1192,7 +1195,7 @@ run_BCO:
// around (stack squeezing), so we have to grab the real
// Sp out of the TSO to find the ccall args again.
marshall_fn ( (void*)(cap->r.rCurrentTSO->sp + RET_DYN_SIZE + sizeofW(StgRetDyn)) );
marshall_fn ( (void*)(cap->r.rCurrentTSO->sp + ret_dyn_size) );
#else
// Threaded RTS:
// We already made a malloced copy of the arguments above.
......@@ -1203,8 +1206,7 @@ run_BCO:
// And restart the thread again, popping the RET_DYN frame.
cap = (Capability *)((void *)resumeThread(tok,rtsFalse) - sizeof(StgFunTable));
LOAD_STACK_POINTERS;
Sp += RET_DYN_SIZE + sizeofW(StgRetDyn);
Sp += ret_dyn_size;
#ifdef RTS_SUPPORTS_THREADS
// Threaded RTS:
......
/* -----------------------------------------------------------------------------
* $Id: Printer.c,v 1.58 2003/04/01 17:09:40 sof Exp $
* $Id: Printer.c,v 1.59 2003/04/22 16:25:12 simonmar Exp $
*
* (c) The GHC Team, 1994-2000.
*
......@@ -558,8 +558,8 @@ printStackChunk( StgPtr sp, StgPtr spBottom )
p = (P_)(r->payload);
printSmallBitmap(spBottom, sp,
GET_LIVENESS(r->liveness), RET_DYN_SIZE);
p += RET_DYN_SIZE;
GET_LIVENESS(r->liveness), RET_DYN_BITMAP_SIZE);
p += RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE;
for (size = GET_NONPTRS(dyn); size > 0; size--) {
fprintf(stderr," stk[%ld] (%p) = ", (long)(spBottom-p), p);
......
/* -----------------------------------------------------------------------------
* $Id: Sanity.c,v 1.32 2003/03/24 14:46:56 simonmar Exp $
* $Id: Sanity.c,v 1.33 2003/04/22 16:25:12 simonmar Exp $
*
* (c) The GHC Team, 1998-2001
*
......@@ -113,8 +113,8 @@ checkStackFrame( StgPtr c )
dyn = r->liveness;
p = (P_)(r->payload);
checkSmallBitmap(p,GET_LIVENESS(r->liveness),RET_DYN_SIZE);
p += RET_DYN_SIZE;
checkSmallBitmap(p,GET_LIVENESS(r->liveness),RET_DYN_BITMAP_SIZE);
p += RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE;
// skip over the non-pointers
p += GET_NONPTRS(dyn);
......@@ -125,7 +125,8 @@ checkStackFrame( StgPtr c )
p++;
}
return sizeofW(StgRetDyn) + RET_DYN_SIZE +
return sizeofW(StgRetDyn) + RET_DYN_BITMAP_SIZE +
RET_DYN_NONPTR_REGS_SIZE +
GET_NONPTRS(dyn) + GET_PTRS(dyn);
}
......
/* -----------------------------------------------------------------------------
* $Id: Storage.h,v 1.51 2003/03/27 13:54:32 simonmar Exp $
* $Id: Storage.h,v 1.52 2003/04/22 16:25:12 simonmar Exp $
*
* (c) The GHC Team, 1998-2002
*
......@@ -419,7 +419,8 @@ static inline StgWord stack_frame_sizeW( StgClosure *frame )
case RET_DYN:
{
StgRetDyn *dyn = (StgRetDyn *)frame;
return sizeofW(StgRetDyn) + RET_DYN_SIZE +
return sizeofW(StgRetDyn) + RET_DYN_BITMAP_SIZE +
RET_DYN_NONPTR_REGS_SIZE +
GET_PTRS(dyn->liveness) + GET_NONPTRS(dyn->liveness);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment