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 * (c) The GHC Team, 1998-1999
* *
...@@ -32,6 +32,13 @@ typedef struct StgSparkPool_ { ...@@ -32,6 +32,13 @@ typedef struct StgSparkPool_ {
StgClosure **tl; StgClosure **tl;
} StgSparkPool; } StgSparkPool;
typedef struct {
StgFunPtr stgChk0;
StgFunPtr stgChk1;
StgFunPtr stgGCEnter1;
StgFunPtr stgUpdatePAP;
} StgFunTable;
typedef struct StgRegTable_ { typedef struct StgRegTable_ {
StgUnion rR1; StgUnion rR1;
StgUnion rR2; StgUnion rR2;
...@@ -41,8 +48,8 @@ typedef struct StgRegTable_ { ...@@ -41,8 +48,8 @@ typedef struct StgRegTable_ {
StgUnion rR6; StgUnion rR6;
StgUnion rR7; StgUnion rR7;
StgUnion rR8; StgUnion rR8;
StgUnion rR9; /* used occasionally by heap/stack checks */ StgUnion rR9; // used occasionally by heap/stack checks
StgUnion rR10; /* used occasionally by heap/stack checks */ StgUnion rR10; // used occasionally by heap/stack checks
StgFloat rF1; StgFloat rF1;
StgFloat rF2; StgFloat rF2;
StgFloat rF3; StgFloat rF3;
...@@ -58,19 +65,31 @@ typedef struct StgRegTable_ { ...@@ -58,19 +65,31 @@ typedef struct StgRegTable_ {
StgTSO *rCurrentTSO; StgTSO *rCurrentTSO;
struct _bdescr *rNursery; struct _bdescr *rNursery;
struct _bdescr *rCurrentNursery; struct _bdescr *rCurrentNursery;
StgWord rHpAlloc; // number of words being allocated in heap
#if defined(SMP) || defined(PAR) #if defined(SMP) || defined(PAR)
StgSparkPool rSparks; /* per-task spark pool */ StgSparkPool rSparks; // per-task spark pool
#endif #endif
#if defined(SMP) #if defined(SMP)
struct StgRegTable_ *link; /* per-task register tables are linked together */ struct StgRegTable_ *link; // per-task register tables are linked together
#endif #endif
} StgRegTable; } 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 /* No such thing as a MainRegTable under SMP - each thread must
* have its own MainRegTable. * have its own MainRegTable.
*/ */
#ifndef SMP #ifndef SMP
extern DLL_IMPORT_RTS StgRegTable MainRegTable; extern DLL_IMPORT_RTS Capability MainCapability;
#endif #endif
#if IN_STG_CODE #if IN_STG_CODE
...@@ -113,6 +132,7 @@ extern DLL_IMPORT_RTS StgRegTable MainRegTable; ...@@ -113,6 +132,7 @@ extern DLL_IMPORT_RTS StgRegTable MainRegTable;
#define SAVE_CurrentTSO (BaseReg->rCurrentTSO) #define SAVE_CurrentTSO (BaseReg->rCurrentTSO)
#define SAVE_CurrentNursery (BaseReg->rCurrentNursery) #define SAVE_CurrentNursery (BaseReg->rCurrentNursery)
#define SAVE_HpAlloc (BaseReg->rHpAlloc)
#if defined(SMP) || defined(PAR) #if defined(SMP) || defined(PAR)
#define SAVE_SparkHd (BaseReg->rSparks.hd) #define SAVE_SparkHd (BaseReg->rSparks.hd)
#define SAVE_SparkTl (BaseReg->rSparks.tl) #define SAVE_SparkTl (BaseReg->rSparks.tl)
...@@ -275,7 +295,7 @@ GLOBAL_REG_DECL(StgRegTable *,BaseReg,REG_Base) ...@@ -275,7 +295,7 @@ GLOBAL_REG_DECL(StgRegTable *,BaseReg,REG_Base)
#ifdef SMP #ifdef SMP
#error BaseReg must be in a register for SMP #error BaseReg must be in a register for SMP
#endif #endif
#define BaseReg (&MainRegTable) #define BaseReg (&MainCapability.r)
#endif #endif
#ifdef REG_Sp #ifdef REG_Sp
...@@ -320,6 +340,12 @@ GLOBAL_REG_DECL(bdescr *,CurrentNursery,REG_CurrentNursery) ...@@ -320,6 +340,12 @@ GLOBAL_REG_DECL(bdescr *,CurrentNursery,REG_CurrentNursery)
#define CurrentNursery (BaseReg->rCurrentNursery) #define CurrentNursery (BaseReg->rCurrentNursery)
#endif #endif
#ifdef REG_HpAlloc
GLOBAL_REG_DECL(bdescr *,HpAlloc,REG_HpAlloc)
#else
#define HpAlloc (BaseReg->rHpAlloc)
#endif
#ifdef REG_SparkHd #ifdef REG_SparkHd
GLOBAL_REG_DECL(bdescr *,SparkHd,REG_SparkHd) GLOBAL_REG_DECL(bdescr *,SparkHd,REG_SparkHd)
#else #else
...@@ -344,6 +370,39 @@ GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim) ...@@ -344,6 +370,39 @@ GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim)
#define SparkLim (BaseReg->rSparks.lim) #define SparkLim (BaseReg->rSparks.lim)
#endif #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 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 convention, we have to emit code to save and restore them across C
...@@ -553,6 +612,14 @@ GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim) ...@@ -553,6 +612,14 @@ GLOBAL_REG_DECL(bdescr *,SparkLim,REG_SparkLim)
#define CALLER_RESTORE_CurrentNursery /* nothing */ #define CALLER_RESTORE_CurrentNursery /* nothing */
#endif #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 #ifdef CALLER_SAVES_SparkHd
#define CALLER_SAVE_SparkHd SAVE_SparkHd = SparkHd; #define CALLER_SAVE_SparkHd SAVE_SparkHd = SparkHd;
#define CALLER_RESTORE_SparkHd SparkHd = SAVE_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 * (c) The GHC Team, 1998-1999
* *
...@@ -132,7 +132,6 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; } ...@@ -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) \ #define STK_CHK(headroom,ret,r,layout,tag_assts) \
if (Sp - headroom < SpLim) { \ if (Sp - headroom < SpLim) { \
EXTFUN_RTS(stg_chk_##layout); \
tag_assts \ tag_assts \
(r) = (P_)ret; \ (r) = (P_)ret; \
JMP_(stg_chk_##layout); \ JMP_(stg_chk_##layout); \
...@@ -141,7 +140,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; } ...@@ -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) \ #define HP_CHK(headroom,ret,r,layout,tag_assts) \
DO_GRAN_ALLOCATE(headroom) \ DO_GRAN_ALLOCATE(headroom) \
if ((Hp += headroom) > HpLim) { \ if ((Hp += headroom) > HpLim) { \
EXTFUN_RTS(stg_chk_##layout); \ HpAlloc = (headroom); \
tag_assts \ tag_assts \
(r) = (P_)ret; \ (r) = (P_)ret; \
JMP_(stg_chk_##layout); \ JMP_(stg_chk_##layout); \
...@@ -150,7 +149,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; } ...@@ -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) \ #define HP_STK_CHK(stk_headroom,hp_headroom,ret,r,layout,tag_assts) \
DO_GRAN_ALLOCATE(hp_headroom) \ DO_GRAN_ALLOCATE(hp_headroom) \
if (Sp - stk_headroom < SpLim || (Hp += hp_headroom) > HpLim) { \ if (Sp - stk_headroom < SpLim || (Hp += hp_headroom) > HpLim) { \
EXTFUN_RTS(stg_chk_##layout); \ HpAlloc = (hp_headroom); \
tag_assts \ tag_assts \
(r) = (P_)ret; \ (r) = (P_)ret; \
JMP_(stg_chk_##layout); \ JMP_(stg_chk_##layout); \
...@@ -177,7 +176,6 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; } ...@@ -177,7 +176,6 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
#define STK_CHK_NP(headroom,ptrs,tag_assts) \ #define STK_CHK_NP(headroom,ptrs,tag_assts) \
if ((Sp - (headroom)) < SpLim) { \ if ((Sp - (headroom)) < SpLim) { \
EXTFUN_RTS(stg_gc_enter_##ptrs); \
tag_assts \ tag_assts \
JMP_(stg_gc_enter_##ptrs); \ JMP_(stg_gc_enter_##ptrs); \
} }
...@@ -185,7 +183,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; } ...@@ -185,7 +183,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
#define HP_CHK_NP(headroom,ptrs,tag_assts) \ #define HP_CHK_NP(headroom,ptrs,tag_assts) \
DO_GRAN_ALLOCATE(headroom) \ DO_GRAN_ALLOCATE(headroom) \
if ((Hp += (headroom)) > HpLim) { \ if ((Hp += (headroom)) > HpLim) { \
EXTFUN_RTS(stg_gc_enter_##ptrs); \ HpAlloc = (headroom); \
tag_assts \ tag_assts \
JMP_(stg_gc_enter_##ptrs); \ JMP_(stg_gc_enter_##ptrs); \
} }
...@@ -193,7 +191,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; } ...@@ -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) \ #define HP_CHK_SEQ_NP(headroom,ptrs,tag_assts) \
DO_GRAN_ALLOCATE(headroom) \ DO_GRAN_ALLOCATE(headroom) \
if ((Hp += (headroom)) > HpLim) { \ if ((Hp += (headroom)) > HpLim) { \
EXTFUN_RTS(stg_gc_seq_##ptrs); \ HpAlloc = (headroom); \
tag_assts \ tag_assts \
JMP_(stg_gc_seq_##ptrs); \ JMP_(stg_gc_seq_##ptrs); \
} }
...@@ -201,7 +199,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; } ...@@ -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) \ #define HP_STK_CHK_NP(stk_headroom, hp_headroom, ptrs, tag_assts) \
DO_GRAN_ALLOCATE(hp_headroom) \ DO_GRAN_ALLOCATE(hp_headroom) \
if ((Sp - (stk_headroom)) < SpLim || (Hp += (hp_headroom)) > HpLim) { \ if ((Sp - (stk_headroom)) < SpLim || (Hp += (hp_headroom)) > HpLim) { \
EXTFUN_RTS(stg_gc_enter_##ptrs); \ HpAlloc = (hp_headroom); \
tag_assts \ tag_assts \
JMP_(stg_gc_enter_##ptrs); \ JMP_(stg_gc_enter_##ptrs); \
} }
...@@ -213,6 +211,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; } ...@@ -213,6 +211,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
DO_GRAN_ALLOCATE(headroom) \ DO_GRAN_ALLOCATE(headroom) \
if ((Hp += (headroom)) > HpLim) { \ if ((Hp += (headroom)) > HpLim) { \
EXTFUN_RTS(lbl); \ EXTFUN_RTS(lbl); \
HpAlloc = (headroom); \
tag_assts \ tag_assts \
JMP_(lbl); \ JMP_(lbl); \
} }
...@@ -294,7 +293,7 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; } ...@@ -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) \ #define HP_CHK_GEN(headroom,liveness,reentry,tag_assts) \
if ((Hp += (headroom)) > HpLim ) { \ if ((Hp += (headroom)) > HpLim ) { \
EXTFUN_RTS(stg_gen_chk); \ HpAlloc = (headroom); \
tag_assts \ tag_assts \
R9.w = (W_)LIVENESS_MASK(liveness); \ R9.w = (W_)LIVENESS_MASK(liveness); \
R10.w = (W_)reentry; \ R10.w = (W_)reentry; \
...@@ -307,7 +306,6 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; } ...@@ -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) \ #define STK_CHK_GEN(headroom,liveness,reentry,tag_assts) \
if ((Sp - (headroom)) < SpLim) { \ if ((Sp - (headroom)) < SpLim) { \
EXTFUN_RTS(stg_gen_chk); \
tag_assts \ tag_assts \
R9.w = (W_)LIVENESS_MASK(liveness); \ R9.w = (W_)LIVENESS_MASK(liveness); \
R10.w = (W_)reentry; \ R10.w = (W_)reentry; \
...@@ -316,7 +314,6 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; } ...@@ -316,7 +314,6 @@ static inline int IS_ARG_TAG( StgWord p ) { return p <= ARGTAG_MAX; }
#define MAYBE_GC(liveness,reentry) \ #define MAYBE_GC(liveness,reentry) \
if (doYouWantToGC()) { \ if (doYouWantToGC()) { \
EXTFUN_RTS(stg_gen_hp); \
R9.w = (W_)LIVENESS_MASK(liveness); \ R9.w = (W_)LIVENESS_MASK(liveness); \
R10.w = (W_)reentry; \ R10.w = (W_)reentry; \
JMP_(stg_gen_hp); \ JMP_(stg_gen_hp); \
...@@ -787,17 +784,20 @@ LoadThreadState (void) ...@@ -787,17 +784,20 @@ LoadThreadState (void)
* Suspending/resuming threads for doing external C-calls (_ccall_GC). * Suspending/resuming threads for doing external C-calls (_ccall_GC).
* These functions are defined in rts/Schedule.c. * These functions are defined in rts/Schedule.c.
*/ */
StgInt suspendThread ( StgRegTable *cap ); StgInt suspendThread ( Capability *cap );
StgRegTable * resumeThread ( StgInt ); Capability * resumeThread ( StgInt );
#define SUSPEND_THREAD(token) \ #define SUSPEND_THREAD(token) \
SaveThreadState(); \ SaveThreadState(); \
token = suspendThread(BaseReg); token = suspendThread((Capability *)((void *)BaseReg - sizeof(StgFunTable)));
#ifdef SMP #ifdef SMP
#define RESUME_THREAD(token) \ #define RESUME_THREAD(token) \
BaseReg = resumeThread(token); \ { Capability c; \
LoadThreadState(); c = resumeThread(token); \
BaseReg = &c.r; \
LoadThreadState(); \
}
#else #else
#define RESUME_THREAD(token) \ #define RESUME_THREAD(token) \
(void)resumeThread(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 * (c) The GHC Team, 1998-1999
* *
...@@ -238,3 +238,60 @@ EXTINFO_RTS stg_ap_6_upd_info; ...@@ -238,3 +238,60 @@ EXTINFO_RTS stg_ap_6_upd_info;
EXTINFO_RTS stg_ap_7_upd_info; EXTINFO_RTS stg_ap_7_upd_info;
EXTINFO_RTS stg_ap_8_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 * (c) The GHC Team, 1998-1999
* *
...@@ -104,7 +104,7 @@ typedef struct _generation { ...@@ -104,7 +104,7 @@ typedef struct _generation {
#define OpenNursery(hp,hplim) \ #define OpenNursery(hp,hplim) \
(hp = CurrentNursery->free-1, \ (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) #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 * (c) The GHC Team, 1998-1999
* *
...@@ -239,13 +239,13 @@ extern void newCAF(StgClosure*); ...@@ -239,13 +239,13 @@ extern void newCAF(StgClosure*);
Update-related prototypes Update-related prototypes
-------------------------------------------------------------------------- */ -------------------------------------------------------------------------- */
EXTFUN_RTS(__stg_update_PAP);
DLL_IMPORT_RTS extern STGFUN(stg_upd_frame_entry); DLL_IMPORT_RTS extern STGFUN(stg_upd_frame_entry);
extern DLL_IMPORT_RTS const StgInfoTable stg_PAP_info; extern DLL_IMPORT_RTS const StgInfoTable stg_PAP_info;
DLL_IMPORT_RTS STGFUN(stg_PAP_entry); DLL_IMPORT_RTS STGFUN(stg_PAP_entry);
EXTFUN_RTS(stg_update_PAP);
extern DLL_IMPORT_RTS const StgInfoTable stg_AP_UPD_info; extern DLL_IMPORT_RTS const StgInfoTable stg_AP_UPD_info;
DLL_IMPORT_RTS STGFUN(stg_AP_UPD_entry); 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 * (c) The GHC Team, 1992-1998
* *
...@@ -35,6 +35,14 @@ ...@@ -35,6 +35,14 @@
#define OFFSET_HpLim OFFSET(RegTable, RegTable.rHpLim) #define OFFSET_HpLim OFFSET(RegTable, RegTable.rHpLim)
#define OFFSET_CurrentTSO OFFSET(RegTable, RegTable.rCurrentTSO) #define OFFSET_CurrentTSO OFFSET(RegTable, RegTable.rCurrentTSO)
#define OFFSET_CurrentNursery OFFSET(RegTable, RegTable.rCurrentNursery) #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_SP OFFSET(tso, tso.sp)
#define TSO_SU OFFSET(tso, tso.su) #define TSO_SU OFFSET(tso, tso.su)
...@@ -44,6 +52,9 @@ ...@@ -44,6 +52,9 @@
#define BDESCR_FREE OFFSET(bd, bd.free) #define BDESCR_FREE OFFSET(bd, bd.free)
StgRegTable RegTable; StgRegTable RegTable;
Capability cap;
StgTSO tso; StgTSO tso;
bdescr bd; bdescr bd;
...@@ -80,6 +91,12 @@ main() ...@@ -80,6 +91,12 @@ main()
printf("#define OFFSET_HpLim %d\n", OFFSET_HpLim); printf("#define OFFSET_HpLim %d\n", OFFSET_HpLim);
printf("#define OFFSET_CurrentTSO %d\n", OFFSET_CurrentTSO); printf("#define OFFSET_CurrentTSO %d\n", OFFSET_CurrentTSO);
printf("#define OFFSET_CurrentNursery %d\n", OFFSET_CurrentNursery); 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"); 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 * (c) The GHC Team 1998-1999
* *
...@@ -920,6 +920,11 @@ GarbageCollect ( void (*get_roots)(evac_fn), rtsBool force_major_gc ) ...@@ -920,6 +920,11 @@ GarbageCollect ( void (*get_roots)(evac_fn), rtsBool force_major_gc )
} }
resizeNursery((nat)blocks); 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: ...@@ -1467,6 +1472,9 @@ loop:
if (HEAP_ALLOCED(q)) { if (HEAP_ALLOCED(q)) {
bd = Bdescr((P_)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) { if (bd->gen_no > N) {
/* Can't evacuate this object, because it's in a generation /* Can't evacuate this object, because it's in a generation
* older than the ones we're collecting. Let's hope that it's * 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);