cleanup stack shifting when inserting holes (growglobal).

This commit is contained in:
Vitor Santos Costa 2009-03-16 17:30:13 +00:00
parent 6a45dbc98a
commit 77eaff31b8
3 changed files with 86 additions and 91 deletions

140
C/grow.c
View File

@ -131,18 +131,18 @@ SetHeapRegs(void)
/* Adjust stack addresses */ /* Adjust stack addresses */
Yap_TrailBase = TrailAddrAdjust(Yap_TrailBase); Yap_TrailBase = TrailAddrAdjust(Yap_TrailBase);
Yap_TrailTop = TrailAddrAdjust(Yap_TrailTop); Yap_TrailTop = TrailAddrAdjust(Yap_TrailTop);
if (!(GDiff==0 && DelayDiff < 0)) { if (GDiff) {
/* make sure we are not just expanding the delay stack */ /* make sure we are not just expanding the delay stack */
Yap_GlobalBase = DelayAddrAdjust(Yap_GlobalBase); Yap_GlobalBase = BaseAddrAdjust(Yap_GlobalBase);
} }
Yap_LocalBase = LocalAddrAdjust(Yap_LocalBase); Yap_LocalBase = LocalAddrAdjust(Yap_LocalBase);
#if !USE_SYSTEM_MALLOC && !USE_DL_MALLOC #if !USE_SYSTEM_MALLOC && !USE_DL_MALLOC
AuxSp = PtoDelayAdjust(AuxSp); AuxSp = PtoBaseAdjust(AuxSp);
AuxTop = (ADDR)PtoDelayAdjust((CELL *)AuxTop); AuxTop = (ADDR)PtoBaseAdjust((CELL *)AuxTop);
#endif #endif
#if !USE_SYSTEM_MALLOC #if !USE_SYSTEM_MALLOC
if (HeapLim) if (HeapLim)
HeapLim = DelayAddrAdjust(HeapLim); HeapLim = BaseAddrAdjust(HeapLim);
#endif #endif
/* The registers pointing to one of the stacks */ /* The registers pointing to one of the stacks */
if (ENV) if (ENV)
@ -206,7 +206,7 @@ MoveLocalAndTrail(void)
{ {
/* cpcellsd(To,From,NOfCells) - copy the cells downwards */ /* cpcellsd(To,From,NOfCells) - copy the cells downwards */
#if USE_SYSTEM_MALLOC #if USE_SYSTEM_MALLOC
cpcellsd(ASP, (CELL *)((char *)OldASP+DelayDiff), (CELL *)OldTR - OldASP); cpcellsd(ASP, (CELL *)((char *)OldASP+BaseDiff), (CELL *)OldTR - OldASP);
#else #else
cpcellsd(ASP, OldASP, (CELL *)OldTR - OldASP); cpcellsd(ASP, OldASP, (CELL *)OldTR - OldASP);
#endif #endif
@ -229,7 +229,7 @@ MoveExpandedGlobal(void)
* cpcellsd(To,From,NOfCells) - copy the cells downwards - in * cpcellsd(To,From,NOfCells) - copy the cells downwards - in
* absmi.asm * absmi.asm
*/ */
cpcellsd((CELL *)(Yap_GlobalBase+(GDiff-DelayDiff)), (CELL *)Yap_GlobalBase, OldH - (CELL *)OldGlobalBase); cpcellsd((CELL *)(Yap_GlobalBase+(GDiff-BaseDiff)), (CELL *)Yap_GlobalBase, OldH - (CELL *)OldGlobalBase);
} }
static void static void
@ -240,7 +240,7 @@ MoveGlobalWithHole(void)
* absmi.asm * absmi.asm
*/ */
#if USE_SYSTEM_MALLOC #if USE_SYSTEM_MALLOC
cpcellsd((CELL *)((char *)Yap_GlobalBase+(GDiff0-DelayDiff)), (CELL *)Yap_GlobalBase, OldH - (CELL *)OldGlobalBase); cpcellsd((CELL *)((char *)Yap_GlobalBase+(GDiff0-BaseDiff)), (CELL *)Yap_GlobalBase, OldH - (CELL *)OldGlobalBase);
#else #else
cpcellsd((CELL *)((char *)OldGlobalBase+GDiff0), (CELL *)OldGlobalBase, OldH - (CELL *)OldGlobalBase); cpcellsd((CELL *)((char *)OldGlobalBase+GDiff0), (CELL *)OldGlobalBase, OldH - (CELL *)OldGlobalBase);
#endif #endif
@ -259,18 +259,6 @@ MoveHalfGlobal(CELL *OldPt)
cpcellsd(NewPt, IntPt, diff); cpcellsd(NewPt, IntPt, diff);
} }
static void
MoveHalfAttrs(CELL *DTop, CELL *OldPt)
{
/*
* cpcellsd(To,From,NOfCells) - copy the cells downwards - in
* absmi.asm
*/
UInt sz = sizeof(CELL)*(OldPt-DTop);
char *base = (char *)DTop+DelayDiff;
cpcellsd((CELL *)base, DTop, sz);
}
static inline CELL static inline CELL
AdjustAppl(register CELL t0) AdjustAppl(register CELL t0)
{ {
@ -682,8 +670,8 @@ static_growheap(long size, int fix_code, struct intermediates *cip, tr_fr_ptr *o
} }
ASP -= 256; ASP -= 256;
YAPEnterCriticalSection(); YAPEnterCriticalSection();
TrDiff = LDiff = GDiff = DelayDiff = size; TrDiff = LDiff = GDiff = GDiff0 = DelayDiff = BaseDiff = size;
XDiff = HDiff = GDiff0 = 0; XDiff = HDiff = 0;
GSplit = NULL; GSplit = NULL;
SetHeapRegs(); SetHeapRegs();
MoveLocalAndTrail(); MoveLocalAndTrail();
@ -724,25 +712,34 @@ static_growheap(long size, int fix_code, struct intermediates *cip, tr_fr_ptr *o
/* Used when we're short of heap, usually because of an overflow in /* Used when we're short of heap, usually because of an overflow in
the attributed stack, but also because we allocated a zone */ the attributed stack, but also because we allocated a zone */
static int static int
static_growglobal(long size, CELL **ptr, CELL *hsplit) static_growglobal(long request, CELL **ptr, CELL *hsplit)
{ {
UInt start_growth_time, growth_time; UInt start_growth_time, growth_time;
int gc_verbose; int gc_verbose;
char *omax = (ADDR)DelayTop(); char *omax = (ADDR)DelayTop();
ADDR old_GlobalBase = Yap_GlobalBase; ADDR old_GlobalBase = Yap_GlobalBase;
UInt minimal_request = 0L; UInt minimal_request = 0L;
long size0, sz = size; long size = request;
char vb_msg1 = '\0', *vb_msg2; char vb_msg1 = '\0', *vb_msg2;
int do_grow = TRUE; int do_grow = TRUE;
int insert_in_delays = FALSE;
/*
request is the amount of memory we requested, in bytes;
base_move is the shift in global stacks we had to do
size is how much space we allocate: it's negative if we just expand
the delay stack.
do_grow is whether we expand stacks
*/
CurrentDelayTop = (CELL *)omax; CurrentDelayTop = (CELL *)omax;
size0 = size;
if (hsplit) { if (hsplit) {
/* just a little bit of sanity checking */ /* just a little bit of sanity checking */
if (hsplit < H0 && hsplit > (CELL *)Yap_GlobalBase) { if (hsplit < H0 && hsplit > (CELL *)Yap_GlobalBase) {
insert_in_delays = TRUE;
/* expanding attributed variables */ /* expanding attributed variables */
if (omax - size > Yap_GlobalBase+4096*sizeof(CELL)) { if (omax - size > Yap_GlobalBase+4096*sizeof(CELL)) {
size = -size; /* we can just ask for more room */
size = 0;
do_grow = FALSE; do_grow = FALSE;
} }
} else if (hsplit < (CELL*)omax || } else if (hsplit < (CELL*)omax ||
@ -754,6 +751,7 @@ static_growglobal(long size, CELL **ptr, CELL *hsplit)
(size+H < ASP-4096 && (size+H < ASP-4096 &&
hsplit > H0)) { hsplit > H0)) {
/* don't need to expand stacks */ /* don't need to expand stacks */
insert_in_delays = TRUE;
do_grow = FALSE; do_grow = FALSE;
} }
} }
@ -803,76 +801,43 @@ static_growglobal(long size, CELL **ptr, CELL *hsplit)
} }
ASP -= 256; ASP -= 256;
YAPEnterCriticalSection(); YAPEnterCriticalSection();
#if USE_SYSTEM_MALLOC /* we always shift the local and the stack by the same amount */
/* we always run the risk of shifting memory */
size0 = Yap_GlobalBase-old_GlobalBase;
if (do_grow) { if (do_grow) {
DelayDiff = size0; /* if we grow, we need to move the stacks */
TrDiff = LDiff = GDiff = size+size0; LDiff = TrDiff = size;
GDiff0 = DelayDiff; /* This is what happens to the base of the stack */
BaseDiff = Yap_GlobalBase-old_GlobalBase;
} else { } else {
TrDiff = LDiff = 0; /* stay still */
if (size > 0) { LDiff = TrDiff = 0;
DelayDiff = 0; BaseDiff = 0;
GDiff = size;
GDiff0 = DelayDiff;
} else {
DelayDiff = size;
GDiff = 0;
GDiff0 = 0;
}
} }
if (hsplit) { /* now, remember we have delay -- global with a hole in delay or a
if (size > 0) { hole in global */
GDiff = GDiff0+sz; if (insert_in_delays) {
} /* we want to expand a hole for the delay stack */
GSplit = hsplit; DelayDiff = size-request;
GDiff = GDiff0 = size;
} else { } else {
GSplit = NULL; /* we want to expand a hole for the delay stack */
GDiff0 = DelayDiff = BaseDiff;
GDiff = BaseDiff+request;
} }
#else GSplit = hsplit;
if (!do_grow) {
TrDiff = DelayDiff = LDiff = 0;
/* don't grow more than what we asked for */
if (size > 0) {
GDiff = size-(size0-sz);
} else {
GDiff = 0;
}
} else if (minimal_request) {
DelayDiff = size-size0;
TrDiff = LDiff = GDiff = size;
} else {
TrDiff = LDiff = GDiff = size;
DelayDiff = 0;
}
if (hsplit) {
if (size > 0) {
GDiff0 = GDiff-size0;
} else {
DelayDiff = size;
GDiff0 = 0;
}
GSplit = hsplit;
} else {
GDiff0 = DelayDiff;
GSplit = NULL;
}
#endif
XDiff = HDiff = 0; XDiff = HDiff = 0;
Yap_GlobalBase = old_GlobalBase; Yap_GlobalBase = old_GlobalBase;
SetHeapRegs(); SetHeapRegs();
if (do_grow) { if (do_grow) {
MoveLocalAndTrail(); MoveLocalAndTrail();
if (hsplit) { if (hsplit) {
MoveGlobalWithHole(); MoveGlobalWithHole();
} else { } else {
MoveExpandedGlobal(); MoveExpandedGlobal();
} }
} }
/* don't run through garbage */ /* don't run through garbage */
if (hsplit && (OldH != hsplit)) { if (hsplit && (OldH != hsplit)) {
AdjustStacksAndTrail(sz); AdjustStacksAndTrail(request);
} else { } else {
AdjustStacksAndTrail(0); AdjustStacksAndTrail(0);
} }
@ -881,8 +846,9 @@ static_growglobal(long size, CELL **ptr, CELL *hsplit)
*ptr = PtoLocAdjust(*ptr); *ptr = PtoLocAdjust(*ptr);
} }
if (hsplit) { if (hsplit) {
if (!do_grow && size < 0) { if (insert_in_delays) {
MoveHalfAttrs(CurrentDelayTop,hsplit); /* we have things not quite where we want to have them */
cpcellsd((CELL *)(omax+DelayDiff), (CELL *)(omax+GDiff0), (ADDR)hsplit-omax);
} else { } else {
MoveHalfGlobal(hsplit); MoveHalfGlobal(hsplit);
} }
@ -900,9 +866,9 @@ static_growglobal(long size, CELL **ptr, CELL *hsplit)
} }
LeaveGrowMode(GrowStackMode); LeaveGrowMode(GrowStackMode);
if (hsplit) { if (hsplit) {
return size0; return request;
} else } else
return GDiff-DelayDiff; return GDiff-BaseDiff;
} }
static void static void
@ -1368,14 +1334,14 @@ execute_growstack(long size0, int from_trail, int in_parser, tr_fr_ptr *old_trp,
return FALSE; return FALSE;
} }
YAPEnterCriticalSection(); YAPEnterCriticalSection();
GDiff = DelayDiff = size-size0; GDiff = DelayDiff = BaseDiff = size-size0;
} else { } else {
YAPEnterCriticalSection(); YAPEnterCriticalSection();
if (Yap_GlobalBase != old_Yap_GlobalBase) { if (Yap_GlobalBase != old_Yap_GlobalBase) {
GDiff = DelayDiff = Yap_GlobalBase-old_Yap_GlobalBase; GDiff = BaseDiff = DelayDiff = Yap_GlobalBase-old_Yap_GlobalBase;
Yap_GlobalBase=old_Yap_GlobalBase; Yap_GlobalBase=old_Yap_GlobalBase;
} else { } else {
GDiff = DelayDiff = 0; GDiff = BaseDiff = DelayDiff = 0;
} }
} }
XDiff = HDiff = 0; XDiff = HDiff = 0;
@ -1572,7 +1538,7 @@ static int do_growtrail(long size, int contiguous_only, int in_parser, tr_fr_ptr
} else { } else {
YAPEnterCriticalSection(); YAPEnterCriticalSection();
if (in_parser) { if (in_parser) {
TrDiff = LDiff = GDiff = DelayDiff = XDiff = HDiff = GDiff0 = 0; TrDiff = LDiff = GDiff = BaseDiff = DelayDiff = XDiff = HDiff = GDiff0 = 0;
AdjustScannerStacks(tksp, vep); AdjustScannerStacks(tksp, vep);
} }
Yap_TrailTop += size; Yap_TrailTop += size;

View File

@ -80,7 +80,9 @@ typedef struct scratch_block_struct {
} scratch_block; } scratch_block;
typedef struct restore_info { typedef struct restore_info {
Int cl_diff, Int
base_diff,
cl_diff,
g_diff, g_diff,
g_diff0, g_diff0,
h_diff, h_diff,
@ -680,6 +682,7 @@ extern struct various_codes *Yap_heap_regs;
#define TrDiff RINFO.tr_diff #define TrDiff RINFO.tr_diff
#define XDiff RINFO.x_diff #define XDiff RINFO.x_diff
#define DelayDiff RINFO.delay_diff #define DelayDiff RINFO.delay_diff
#define BaseDiff RINFO.base_diff
/* current consult stack */ /* current consult stack */
#define ConsultSp Yap_heap_regs->WL.consultsp #define ConsultSp Yap_heap_regs->WL.consultsp
/* top of consult stack */ /* top of consult stack */

View File

@ -49,7 +49,10 @@ inline EXTERN CELL *
PtoGloAdjust (CELL * ptr) PtoGloAdjust (CELL * ptr)
{ {
if (ptr < GSplit) { if (ptr < GSplit) {
return (CELL *) (((CELL *) (CharP (ptr) + GDiff0))); if (ptr < H0)
return (CELL *) (((CELL *) (CharP (ptr) + DelayDiff)));
else
return (CELL *) (((CELL *) (CharP (ptr) + GDiff0)));
} else { } else {
return (CELL *) (((CELL *) (CharP (ptr) + GDiff))); return (CELL *) (((CELL *) (CharP (ptr) + GDiff)));
} }
@ -68,6 +71,14 @@ PtoDelayAdjust (CELL * ptr)
return (CELL *) (((CELL *) (CharP (ptr) + GDiff0))); return (CELL *) (((CELL *) (CharP (ptr) + GDiff0)));
} }
inline EXTERN CELL *PtoBaseAdjust (CELL *);
inline EXTERN CELL *
PtoBaseAdjust (CELL * ptr)
{
return (CELL *) (((CELL *) (CharP (ptr) + BaseDiff)));
}
inline EXTERN tr_fr_ptr PtoTRAdjust (tr_fr_ptr); inline EXTERN tr_fr_ptr PtoTRAdjust (tr_fr_ptr);
@ -139,7 +150,10 @@ inline EXTERN CELL
GlobalAdjust (CELL val) GlobalAdjust (CELL val)
{ {
if ((CELL *)val < GSplit) { if ((CELL *)val < GSplit) {
return (CELL) (val + GDiff0); if ((CELL *)val < H0)
return (CELL) (val + DelayDiff);
else
return (CELL) (val + GDiff0);
} else { } else {
return (CELL) (val + GDiff); return (CELL) (val + GDiff);
} }
@ -165,7 +179,10 @@ inline EXTERN ADDR
GlobalAddrAdjust (ADDR ptr) GlobalAddrAdjust (ADDR ptr)
{ {
if ((CELL *)ptr < GSplit) { if ((CELL *)ptr < GSplit) {
return (ADDR) ((ptr + GDiff0)); if ((CELL *)ptr < H0)
return (ADDR) (ptr + DelayDiff);
else
return (ADDR) ((ptr + GDiff0));
} else { } else {
return (ADDR) ((ptr + GDiff)); return (ADDR) ((ptr + GDiff));
} }
@ -186,6 +203,15 @@ DelayAddrAdjust (ADDR ptr)
} }
inline EXTERN ADDR BaseAddrAdjust (ADDR);
inline EXTERN ADDR
BaseAddrAdjust (ADDR ptr)
{
return (ADDR) ((ptr + BaseDiff));
}
inline EXTERN CELL LocalAdjust (CELL); inline EXTERN CELL LocalAdjust (CELL);