Commit 0671ef05 authored by simonmar's avatar simonmar

[project @ 2001-11-08 12:46:31 by simonmar]

Fix the large block allocation bug (Yay!)
-----------------------------------------

In order to do this, I had to

 1. in each heap-check failure branch, return the amount of heap
    actually requested, in a known location (I added another slot
    in StgRegTable called HpAlloc for this purpose).  This is
    useful for other reasons - in particular it makes it possible
    to get accurate allocation statistics.

 2. In the scheduler, if a heap check fails and we wanted more than
    BLOCK_SIZE_W words, then allocate a special large block and place
    it in the nursery.  The nursery now has to be double-linked so
    we can insert the new block in the middle.

 3. The garbage collector has to be able to deal with multiple objects
    in a large block.  It turns out that this isn't a problem as long as
    the large blocks only occur in the nursery, because we always copy
    objects from the nursery during GC.  One small change had to be
    made: in evacuate(), we may need to follow the link field from the
    block descriptor to get to the block descriptor for the head of a
    large block.

 4. Various other parts of the storage manager had to be modified
    to cope with a nursery containing a mixture of block sizes.

Point (3) causes a slight pessimization in the garbage collector.  I
don't see a way to avoid this.  Point (1) causes some code bloat (a
rough measurement is around 5%), so to offset this I made the
following change which I'd been meaning to do for some time:

  - Store the values of some commonly-used absolute addresses
    (eg. stg_update_PAP) in the register table.  This lets us use
    shorter instruction forms for some absolute jumps and saves some
    code space.

  - The type of Capability is no longer the same as an StgRegTable.
    MainRegTable renamed to MainCapability.  See Regs.h for details.

Other minor changes:

  - remove individual declarations for the heap-check-failure jump
    points, and declare them all in StgMiscClosures.h instead.  Remove
    HeapStackCheck.h.

Updates to the native code generator to follow.
parent d7dedcdb
/* -----------------------------------------------------------------------------
* $Id: Regs.h,v 1.9 2000/03/23 17:45:31 simonpj Exp $
* $Id: Regs.h,v 1.10 2001/11/08 12:46:31 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
......@@ -32,6 +32,13 @@ typedef struct StgSparkPool_ {
StgClosure **tl;
} StgSparkPool;
typedef struct {
StgFunPtr stgChk0;
StgFunPtr stgChk1;
StgFunPtr stgGCEnter1;
StgFunPtr stgUpdatePAP;
} StgFunTable;
typedef struct StgRegTable_ {
StgUnion rR1;
StgUnion rR2;
......@@ -41,8 +48,8 @@ typedef struct StgRegTable_ {
StgUnion rR6;
StgUnion rR7;
StgUnion rR8;
StgUnion rR9; /* used occasionally by heap/stack checks */
StgUnion rR10; /* used occasionally by heap/stack checks */
StgUnion rR9; // used occasionally by heap/stack checks
StgUnion rR10; // used occasionally by heap/stack checks
StgFloat rF1;
StgFloat rF2;
StgFloat rF3;
......@@ -58,19 +65,31 @@ typedef struct StgRegTable_ {
StgTSO *rCurrentTSO;
struct _bdescr *rNursery;
struct _bdescr *rCurrentNursery;
StgWord rHpAlloc; // number of words being allocated in heap
#if defined(SMP) || defined(PAR)
StgSparkPool rSparks; /* per-task spark pool */
StgSparkPool rSparks; // per-task spark pool
#endif
#if defined(SMP)
struct StgRegTable_ *link; /* per-task register tables are linked together */
struct StgRegTable_ *link; // per-task register tables are linked together
#endif
} StgRegTable;
/* A capability is a combination of a FunTable and a RegTable. In STG
* code, BaseReg normally points to the RegTable portion of this
* structure, so that we can index both forwards and backwards to take
* advantage of shorter instruction forms on some archs (eg. x86).
*/
typedef struct {
StgFunTable f;
StgRegTable r;
} Capability;
/* No such thing as a MainRegTable under SMP - each thread must
* have its own MainRegTable.
*/
#ifndef SMP
extern DLL_IMPORT_RTS StgRegTable MainRegTable;
extern DLL_IMPORT_RTS Capability MainCapability;
#endif
#if IN_STG_CODE
......@@ -113,6 +132,7 @@ extern DLL_IMPORT_RTS StgRegTable MainRegTable;
#define SAVE_CurrentTSO (BaseReg->rCurrentTSO)
#define SAVE_CurrentNursery (BaseReg->rCurrentNursery)
#define SAVE_HpAlloc (BaseReg->rHpAlloc)
#if defined(SMP) || defined(PAR)
#define SAVE_SparkHd (BaseReg->rSparks.hd)
#define SAVE_SparkTl (BaseReg->rSparks.tl)
......@@ -275,7 +295,7 @@ GLOBAL_REG_DECL(StgRegTable *,BaseReg,REG_Base)
#ifdef SMP
#error BaseReg must be in a register for SMP
#endif
#define BaseReg (&MainRegTable)
#define BaseReg (&MainCapability.r)
#endif
#ifdef REG_Sp
......@@ -320,6 +340,12 @@ GLOBAL_REG_DECL(bdescr *,CurrentNursery,REG_CurrentNursery)
#define CurrentNursery (BaseReg->rCurrentNursery)
#endif
#ifdef REG_HpAlloc
GLOBAL_REG_DECL(bdescr *,HpAlloc,REG_HpAlloc)
#else
#define HpAlloc (BaseReg->rHpAlloc)
#endif
#ifdef REG_SparkHd
GLOBAL_REG_DECL(bdescr *,SparkHd,REG_SparkHd)
#else
......@@ -344,6 +370,39 @@ GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim)
#define SparkLim (BaseReg->rSparks.lim)
#endif
/* -----------------------------------------------------------------------------
Get absolute function pointers from the register table, to save
code space. On x86,
jmp *-12(%ebx)
is shorter than
jmp absolute_address
as long as the offset is within the range of a signed byte
(-128..+127). So we pick some common absolute_addresses and put
them in the register table. As a bonus, linking time should also
be reduced.
Other possible candidates in order of importance:
stg_upd_frame_info
stg_CAF_BLACKHOLE_info
stg_IND_STATIC_info
anything else probably isn't worth the effort.
-------------------------------------------------------------------------- */
#define FunReg ((StgFunTable *)((void *)BaseReg - sizeof(StgFunTable)))
#define stg_chk_0 (FunReg->stgChk0)
#define stg_chk_1 (FunReg->stgChk1)
#define stg_gc_enter_1 (FunReg->stgGCEnter1)
#define stg_update_PAP (FunReg->stgUpdatePAP)
/* -----------------------------------------------------------------------------
For any registers which are denoted "caller-saves" by the C calling
convention, we have to emit code to save and restore them across C
......@@ -553,6 +612,14 @@ GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim)
#define CALLER_RESTORE_CurrentNursery /* nothing */
#endif
#ifdef CALLER_SAVES_HpAlloc
#define CALLER_SAVE_HpAlloc SAVE_HpAlloc = HpAlloc;
#define CALLER_RESTORE_HpAlloc HpAlloc = SAVE_HpAlloc;
#else
#define CALLER_SAVE_HpAlloc /* nothing */
#define CALLER_RESTORE_HpAlloc /* nothing */
#endif
#ifdef CALLER_SAVES_SparkHd
#define CALLER_SAVE_SparkHd SAVE_SparkHd = SparkHd;
#define CALLER_RESTORE_SparkHd SparkHd = SAVE_SparkHd;
......
/* -----------------------------------------------------------------------------
* $Id: StgMacros.h,v 1.38 2001/07/24 06:31:35 ken Exp $
* $Id: StgMacros.h,v 1.39 2001/11/08 12:46:31 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
......@@ -132,7 +132,6 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
#define STK_CHK(headroom,ret,r,layout,tag_assts) \
if (Sp - headroom < SpLim) { \
EXTFUN_RTS(stg_chk_##layout); \
tag_assts \
(r) = (P_)ret; \
JMP_(stg_chk_##layout); \
......@@ -141,7 +140,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
#define HP_CHK(headroom,ret,r,layout,tag_assts) \
DO_GRAN_ALLOCATE(headroom) \
if ((Hp += headroom) > HpLim) { \
EXTFUN_RTS(stg_chk_##layout); \
HpAlloc = (headroom); \
tag_assts \
(r) = (P_)ret; \
JMP_(stg_chk_##layout); \
......@@ -150,7 +149,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
#define HP_STK_CHK(stk_headroom,hp_headroom,ret,r,layout,tag_assts) \
DO_GRAN_ALLOCATE(hp_headroom) \
if (Sp - stk_headroom < SpLim || (Hp += hp_headroom) > HpLim) { \
EXTFUN_RTS(stg_chk_##layout); \
HpAlloc = (hp_headroom); \
tag_assts \
(r) = (P_)ret; \
JMP_(stg_chk_##layout); \
......@@ -177,7 +176,6 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
#define STK_CHK_NP(headroom,ptrs,tag_assts) \
if ((Sp - (headroom)) < SpLim) { \
EXTFUN_RTS(stg_gc_enter_##ptrs); \
tag_assts \
JMP_(stg_gc_enter_##ptrs); \
}
......@@ -185,7 +183,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
#define HP_CHK_NP(headroom,ptrs,tag_assts) \
DO_GRAN_ALLOCATE(headroom) \
if ((Hp += (headroom)) > HpLim) { \
EXTFUN_RTS(stg_gc_enter_##ptrs); \
HpAlloc = (headroom); \
tag_assts \
JMP_(stg_gc_enter_##ptrs); \
}
......@@ -193,7 +191,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
#define HP_CHK_SEQ_NP(headroom,ptrs,tag_assts) \
DO_GRAN_ALLOCATE(headroom) \
if ((Hp += (headroom)) > HpLim) { \
EXTFUN_RTS(stg_gc_seq_##ptrs); \
HpAlloc = (headroom); \
tag_assts \
JMP_(stg_gc_seq_##ptrs); \
}
......@@ -201,7 +199,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
#define HP_STK_CHK_NP(stk_headroom, hp_headroom, ptrs, tag_assts) \
DO_GRAN_ALLOCATE(hp_headroom) \
if ((Sp - (stk_headroom)) < SpLim || (Hp += (hp_headroom)) > HpLim) { \
EXTFUN_RTS(stg_gc_enter_##ptrs); \
HpAlloc = (hp_headroom); \
tag_assts \
JMP_(stg_gc_enter_##ptrs); \
}
......@@ -213,6 +211,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
DO_GRAN_ALLOCATE(headroom) \
if ((Hp += (headroom)) > HpLim) { \
EXTFUN_RTS(lbl); \
HpAlloc = (headroom); \
tag_assts \
JMP_(lbl); \
}
......@@ -294,7 +293,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
#define HP_CHK_GEN(headroom,liveness,reentry,tag_assts) \
if ((Hp += (headroom)) > HpLim ) { \
EXTFUN_RTS(stg_gen_chk); \
HpAlloc = (headroom); \
tag_assts \
R9.w = (W_)LIVENESS_MASK(liveness); \
R10.w = (W_)reentry; \
......@@ -307,7 +306,6 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
#define STK_CHK_GEN(headroom,liveness,reentry,tag_assts) \
if ((Sp - (headroom)) < SpLim) { \
EXTFUN_RTS(stg_gen_chk); \
tag_assts \
R9.w = (W_)LIVENESS_MASK(liveness); \
R10.w = (W_)reentry; \
......@@ -316,7 +314,6 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
#define MAYBE_GC(liveness,reentry) \
if (doYouWantToGC()) { \
EXTFUN_RTS(stg_gen_hp); \
R9.w = (W_)LIVENESS_MASK(liveness); \
R10.w = (W_)reentry; \
JMP_(stg_gen_hp); \
......@@ -787,17 +784,20 @@ LoadThreadState (void)
* Suspending/resuming threads for doing external C-calls (_ccall_GC).
* These functions are defined in rts/Schedule.c.
*/
StgInt suspendThread ( StgRegTable *cap );
StgRegTable * resumeThread ( StgInt );
StgInt suspendThread ( Capability *cap );
Capability * resumeThread ( StgInt );
#define SUSPEND_THREAD(token) \
SaveThreadState(); \
token = suspendThread(BaseReg);
token = suspendThread((Capability *)((void *)BaseReg - sizeof(StgFunTable)));
#ifdef SMP
#define RESUME_THREAD(token) \
BaseReg = resumeThread(token); \
LoadThreadState();
#define RESUME_THREAD(token) \
{ Capability c; \
c = resumeThread(token); \
BaseReg = &c.r; \
LoadThreadState(); \
}
#else
#define RESUME_THREAD(token) \
(void)resumeThread(token); \
......
/* -----------------------------------------------------------------------------
* $Id: StgMiscClosures.h,v 1.39 2001/07/09 19:45:16 sof Exp $
* $Id: StgMiscClosures.h,v 1.40 2001/11/08 12:46:31 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
......@@ -238,3 +238,60 @@ EXTINFO_RTS stg_ap_6_upd_info;
EXTINFO_RTS stg_ap_7_upd_info;
EXTINFO_RTS stg_ap_8_upd_info;
/* standard GC & stack check entry points */
EXTFUN(stg_gc_entertop);
EXTFUN(stg_gc_enter_1_hponly);
EXTFUN(__stg_gc_enter_1);
EXTFUN(stg_gc_enter_2);
EXTFUN(stg_gc_enter_3);
EXTFUN(stg_gc_enter_4);
EXTFUN(stg_gc_enter_5);
EXTFUN(stg_gc_enter_6);
EXTFUN(stg_gc_enter_7);
EXTFUN(stg_gc_enter_8);
EXTFUN(stg_gc_seq_1);
EI_(stg_gc_noregs_ret_info);
EF_(stg_gc_noregs);
EI_(stg_gc_unpt_r1_ret_info);
EF_(stg_gc_unpt_r1);
EI_(stg_gc_unbx_r1_ret_info);
EF_(stg_gc_unbx_r1);
EI_(stg_gc_f1_ret_info);
EF_(stg_gc_f1);
EI_(stg_gc_d1_ret_info);
EF_(stg_gc_d1);
EI_(stg_gc_ut_1_0_ret_info);
EF_(stg_gc_ut_1_0);
EI_(stg_gc_ut_0_1_ret_info);
EF_(stg_gc_ut_0_1);
EXTFUN(__stg_chk_0);
EXTFUN(__stg_chk_1);
EXTFUN(stg_chk_1n);
EXTFUN(stg_chk_2);
EXTFUN(stg_chk_3);
EXTFUN(stg_chk_4);
EXTFUN(stg_chk_5);
EXTFUN(stg_chk_6);
EXTFUN(stg_chk_7);
EXTFUN(stg_chk_8);
EXTFUN(stg_gen_chk_ret);
EXTFUN(stg_gen_chk);
EXTFUN(stg_gen_hp);
EXTFUN(stg_gen_yield);
EXTFUN(stg_yield_noregs);
EXTFUN(stg_yield_to_interpreter);
EXTFUN(stg_gen_block);
EXTFUN(stg_block_noregs);
EXTFUN(stg_block_1);
EXTFUN(stg_block_takemvar);
EXTFUN(stg_block_putmvar);
/* -----------------------------------------------------------------------------
* $Id: StgStorage.h,v 1.10 2001/07/24 16:36:44 simonmar Exp $
* $Id: StgStorage.h,v 1.11 2001/11/08 12:46:31 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
......@@ -104,7 +104,7 @@ typedef struct _generation {
#define OpenNursery(hp,hplim) \
(hp = CurrentNursery->free-1, \
hplim = CurrentNursery->start + BLOCK_SIZE_W - 1)
hplim = CurrentNursery->start + CurrentNursery->blocks*BLOCK_SIZE_W - 1)
#define CloseNursery(hp) (CurrentNursery->free = (P_)(hp)+1)
......
/* -----------------------------------------------------------------------------
* $Id: Updates.h,v 1.24 2001/03/22 03:51:09 hwloidl Exp $
* $Id: Updates.h,v 1.25 2001/11/08 12:46:31 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
......@@ -239,13 +239,13 @@ extern void newCAF(StgClosure*);
Update-related prototypes
-------------------------------------------------------------------------- */
EXTFUN_RTS(__stg_update_PAP);
DLL_IMPORT_RTS extern STGFUN(stg_upd_frame_entry);
extern DLL_IMPORT_RTS const StgInfoTable stg_PAP_info;
DLL_IMPORT_RTS STGFUN(stg_PAP_entry);
EXTFUN_RTS(stg_update_PAP);
extern DLL_IMPORT_RTS const StgInfoTable stg_AP_UPD_info;
DLL_IMPORT_RTS STGFUN(stg_AP_UPD_entry);
......
/* --------------------------------------------------------------------------
* $Id: mkNativeHdr.c,v 1.5 2000/08/17 14:30:26 simonmar Exp $
* $Id: mkNativeHdr.c,v 1.6 2001/11/08 12:46:31 simonmar Exp $
*
* (c) The GHC Team, 1992-1998
*
......@@ -35,6 +35,14 @@
#define OFFSET_HpLim OFFSET(RegTable, RegTable.rHpLim)
#define OFFSET_CurrentTSO OFFSET(RegTable, RegTable.rCurrentTSO)
#define OFFSET_CurrentNursery OFFSET(RegTable, RegTable.rCurrentNursery)
#define OFFSET_HpAlloc OFFSET(RegTable, RegTable.rHpAlloc)
#define FUN_OFFSET(sym) ((StgPtr)&cap.f.sym - (StgPtr)&cap.r)
#define OFFSET_stgChk0 FUN_OFFSET(stgChk0)
#define OFFSET_stgChk1 FUN_OFFSET(stgChk1)
#define OFFSET_stgGCEnter1 FUN_OFFSET(stgGCEnter1)
#define OFFSET_stgUpdatePAP FUN_OFFSET(stgUpdatePAP)
#define TSO_SP OFFSET(tso, tso.sp)
#define TSO_SU OFFSET(tso, tso.su)
......@@ -44,6 +52,9 @@
#define BDESCR_FREE OFFSET(bd, bd.free)
StgRegTable RegTable;
Capability cap;
StgTSO tso;
bdescr bd;
......@@ -80,6 +91,12 @@ main()
printf("#define OFFSET_HpLim %d\n", OFFSET_HpLim);
printf("#define OFFSET_CurrentTSO %d\n", OFFSET_CurrentTSO);
printf("#define OFFSET_CurrentNursery %d\n", OFFSET_CurrentNursery);
printf("#define OFFSET_HpAlloc %d\n", OFFSET_HpAlloc);
printf("#define OFFSET_stgChk0 (%d)\n", OFFSET_stgChk0);
printf("#define OFFSET_stgChk1 (%d)\n", OFFSET_stgChk1);
printf("#define OFFSET_stgGCEnter1 (%d)\n", OFFSET_stgGCEnter1);
printf("#define OFFSET_stgUpdatePAP (%d)\n", OFFSET_stgUpdatePAP);
printf("\n-- Storage Manager offsets for the Native Code Generator\n");
......
/* -----------------------------------------------------------------------------
* $Id: GC.c,v 1.125 2001/10/19 09:41:11 sewardj Exp $
* $Id: GC.c,v 1.126 2001/11/08 12:46:31 simonmar Exp $
*
* (c) The GHC Team 1998-1999
*
......@@ -920,6 +920,11 @@ GarbageCollect ( void (*get_roots)(evac_fn), rtsBool force_major_gc )
}
resizeNursery((nat)blocks);
} else {
// we might have added extra large blocks to the nursery, so
// resize back to minAllocAreaSize again.
resizeNursery(RtsFlags.GcFlags.minAllocAreaSize);
}
}
......@@ -1467,6 +1472,9 @@ loop:
if (HEAP_ALLOCED(q)) {
bd = Bdescr((P_)q);
// not a group head: find the group head
if (bd->blocks == 0) { bd = bd->link; }
if (bd->gen_no > N) {
/* Can't evacuate this object, because it's in a generation
* older than the ones we're collecting. Let's hope that it's
......
/* -----------------------------------------------------------------------------
* $Id: HeapStackCheck.h,v 1.7 2001/07/06 14:11:38 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
* Prototypes for functions in HeapStackCheck.hc
*
* ---------------------------------------------------------------------------*/
EXTFUN(stg_gc_entertop);
EXTFUN(stg_gc_enter_1_hponly);
EXTFUN(stg_gc_enter_1);
EXTFUN(stg_gc_enter_2);
EXTFUN(stg_gc_enter_3);
EXTFUN(stg_gc_enter_4);
EXTFUN(stg_gc_enter_5);
EXTFUN(stg_gc_enter_6);
EXTFUN(stg_gc_enter_7);
EXTFUN(stg_gc_enter_8);
EXTFUN(stg_gc_seq_1);
EI_(stg_gc_noregs_ret_info);
EF_(stg_gc_noregs);
EI_(stg_gc_unpt_r1_ret_info);
EF_(stg_gc_unpt_r1);
EI_(stg_gc_unbx_r1_ret_info);
EF_(stg_gc_unbx_r1);
EI_(stg_gc_f1_ret_info);
EF_(stg_gc_f1);
EI_(stg_gc_d1_ret_info);
EF_(stg_gc_d1);
EI_(stg_gc_ut_1_0_ret_info);
EF_(stg_gc_ut_1_0);
EI_(stg_gc_ut_0_1_ret_info);
EF_(stg_gc_ut_0_1);
EXTFUN(stg_chk_0);
EXTFUN(stg_chk_1);
EXTFUN(stg_chk_1n);
EXTFUN(stg_chk_2);
EXTFUN(stg_chk_3);
EXTFUN(stg_chk_4);
EXTFUN(stg_chk_5);
EXTFUN(stg_chk_6);
EXTFUN(stg_chk_7);
EXTFUN(stg_chk_8);
EXTFUN(stg_gen_chk_ret);
EXTFUN(stg_gen_chk);
EXTFUN(stg_gen_hp);
EXTFUN(stg_gen_yield);
EXTFUN(stg_yield_noregs);
EXTFUN(stg_yield_to_interpreter);
EXTFUN(stg_gen_block);
EXTFUN(stg_block_noregs);
EXTFUN(stg_block_1);
EXTFUN(stg_block_takemvar);
EXTFUN(stg_block_putmvar);
/* -----------------------------------------------------------------------------
* $Id: HeapStackCheck.hc,v 1.17 2001/07/06 14:11:38 simonmar Exp $
* $Id: HeapStackCheck.hc,v 1.18 2001/11/08 12:46:31 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
......@@ -12,7 +12,6 @@
#include "Storage.h" /* for CurrentTSO */
#include "StgRun.h" /* for StgReturn and register saving */
#include "Schedule.h" /* for context_switch */
#include "HeapStackCheck.h"
/* Stack/Heap Check Failure
* ------------------------
......@@ -51,7 +50,8 @@
#define GC_GENERIC \
if (Hp > HpLim) { \
if (ExtendNursery(Hp,HpLim)) { \
Hp -= HpAlloc; \
if (HpAlloc <= BLOCK_SIZE_W && ExtendNursery(Hp,HpLim)) {\
if (context_switch) { \
R1.i = ThreadYielding; \
} else { \
......@@ -70,7 +70,8 @@
#define GC_ENTER \
if (Hp > HpLim) { \
if (ExtendNursery(Hp,HpLim)) { \
Hp -= HpAlloc; \
if (HpAlloc <= BLOCK_SIZE_W && ExtendNursery(Hp,HpLim)) {\
if (context_switch) { \
R1.i = ThreadYielding; \
} else { \
......@@ -151,7 +152,7 @@ EXTFUN(stg_gc_entertop)
There are canned sequences for 'n' pointer values in registers.
-------------------------------------------------------------------------- */
EXTFUN(stg_gc_enter_1)
EXTFUN(__stg_gc_enter_1)
{
FB_
Sp -= 1;
......@@ -880,7 +881,7 @@ EXTFUN(stg_gc_ut_0_1)
/*- 0 Regs -------------------------------------------------------------------*/
EXTFUN(stg_chk_0)
EXTFUN(__stg_chk_0)
{
FB_
Sp -= 1;
......@@ -891,7 +892,7 @@ EXTFUN(stg_chk_0)
/*- 1 Reg --------------------------------------------------------------------*/
EXTFUN(stg_chk_1)
EXTFUN(__stg_chk_1)
{
FB_
Sp -= 2;
......
......@@ -5,8 +5,8 @@
* Copyright (c) 1994-2000.
*
* $RCSfile: Interpreter.c,v $
* $Revision: 1.30 $
* $Date: 2001/08/14 13:40:09 $
* $Revision: 1.31 $
* $Date: 2001/11/08 12:46:31 $
* ---------------------------------------------------------------------------*/
#include "PosixSource.h"
......@@ -56,15 +56,15 @@
#define BCO_ITBL(n) itbls[n]
#define LOAD_STACK_POINTERS \
iSp = cap->rCurrentTSO->sp; \
iSu = cap->rCurrentTSO->su; \
iSp = cap->r.rCurrentTSO->sp; \
iSu = cap->r.rCurrentTSO->su; \
/* We don't change this ... */ \
iSpLim = cap->rCurrentTSO->stack + RESERVED_STACK_WORDS;
iSpLim = cap->r.rCurrentTSO->stack + RESERVED_STACK_WORDS;
#define SAVE_STACK_POINTERS \
cap->rCurrentTSO->sp = iSp; \
cap->rCurrentTSO->su = iSu;
cap->r.rCurrentTSO->sp = iSp; \
cap->r.rCurrentTSO->su = iSu;
#define RETURN(retcode) \
SAVE_STACK_POINTERS; return retcode;
......@@ -196,10 +196,10 @@ StgThreadReturnCode interpretBCO ( Capability* cap )
// checkSanity(1);
// iSp--; StackWord(0) = obj;
// checkStack(iSp,cap->rCurrentTSO->stack+cap->rCurrentTSO->stack_size,iSu);
// checkStack(iSp,cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size,iSu);
// iSp++;
printStack(iSp,cap->rCurrentTSO->stack+cap->rCurrentTSO->stack_size,iSu);
printStack(iSp,cap->r.rCurrentTSO->stack+cap->r.rCurrentTSO->stack_size,iSu);
fprintf(stderr, "\n\n");
);
......@@ -373,7 +373,7 @@ StgThreadReturnCode interpretBCO ( Capability* cap )
/* Heap check */
if (doYouWantToGC()) {
iSp--; StackWord(0) = (W_)bco;
cap->rCurrentTSO->what_next = ThreadEnterInterp;
cap->r.rCurrentTSO->what_next = ThreadEnterInterp;
RETURN(HeapOverflow);
}
......@@ -381,7 +381,7 @@ StgThreadReturnCode interpretBCO ( Capability* cap )
if (iSp - (INTERP_STACK_CHECK_THRESH+1) < iSpLim) {
iSp--;
StackWord(0) = (W_)obj;
cap->rCurrentTSO->what_next = ThreadEnterInterp;
cap->r.rCurrentTSO->what_next = ThreadEnterInterp;
RETURN(StackOverflow);
}
......@@ -389,7 +389,7 @@ StgThreadReturnCode interpretBCO ( Capability* cap )
if (context_switch) {
iSp--;
StackWord(0) = (W_)obj;
cap->rCurrentTSO->what_next = ThreadEnterInterp;
cap->r.rCurrentTSO->what_next = ThreadEnterInterp;
RETURN(ThreadYielding);
}
......@@ -404,7 +404,7 @@ StgThreadReturnCode interpretBCO ( Capability* cap )
IF_DEBUG(