mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-03-14 10:51:20 -07:00
Merge mmdevel_collect
Copied from Perforce Change: 18764 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
30140d54dc
commit
2ee45a68c4
17 changed files with 429 additions and 248 deletions
|
|
@ -1,13 +1,13 @@
|
|||
/* impl.c.action: STRATEGIC ACTION
|
||||
*
|
||||
* Copyright (C) 1997 Harlequin Group, all rights reserved.
|
||||
* $HopeName: MMsrc!action.c(trunk.4) $
|
||||
* $HopeName: MMsrc!action.c(trunk.5) $
|
||||
*/
|
||||
|
||||
#include "mpm.h"
|
||||
#include <float.h> /* @@@@ for DBL_MAX */
|
||||
|
||||
SRCID(action, "$HopeName: MMsrc!action.c(trunk.4) $");
|
||||
SRCID(action, "$HopeName: MMsrc!action.c(trunk.5) $");
|
||||
|
||||
|
||||
/* ActionCheck -- check consistency of an Action structure */
|
||||
|
|
@ -56,23 +56,6 @@ void ActionFinish(Action action)
|
|||
}
|
||||
|
||||
|
||||
/* Noddy collection policy -- condemn first pool found */
|
||||
|
||||
static Res ActionCollect(Action action)
|
||||
{
|
||||
Trace trace;
|
||||
Res res;
|
||||
Arena arena;
|
||||
|
||||
arena = PoolArena(action->pool);
|
||||
|
||||
res = TraceCreate(&trace, arena, action);
|
||||
if(res != ResOK) return res;
|
||||
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
|
||||
/* ActionPoll -- decide what to do next
|
||||
*
|
||||
* This is the brain of the system. The function weighs up the
|
||||
|
|
@ -111,6 +94,6 @@ void ActionPoll(Arena arena)
|
|||
/* @@@@ ignores failure */
|
||||
if(bestBenefit > 0) {
|
||||
AVER(bestAction != NULL);
|
||||
(void)ActionCollect(bestAction);
|
||||
(void)PoolAct(bestAction->pool, bestAction);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.arena: ARENA IMPLEMENTATION
|
||||
*
|
||||
* $HopeName: MMsrc!arena.c(trunk.5) $
|
||||
* $HopeName: MMsrc!arena.c(trunk.6) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* .readership: Any MPS developer
|
||||
|
|
@ -40,7 +40,7 @@
|
|||
/* finalization */
|
||||
#include "poolmrg.h"
|
||||
|
||||
SRCID(arena, "$HopeName: MMsrc!arena.c(trunk.5) $");
|
||||
SRCID(arena, "$HopeName: MMsrc!arena.c(trunk.6) $");
|
||||
|
||||
|
||||
/* All static data objects are declared here. See .static */
|
||||
|
|
@ -548,6 +548,98 @@ void ArenaPoll(Arena arena)
|
|||
#endif
|
||||
|
||||
|
||||
void ArenaClamp(Arena arena)
|
||||
{
|
||||
AVERT(Arena, arena);
|
||||
arena->clamped = TRUE;
|
||||
}
|
||||
|
||||
void ArenaRelease(Arena arena)
|
||||
{
|
||||
AVERT(Arena, arena);
|
||||
arena->clamped = FALSE;
|
||||
}
|
||||
|
||||
void ArenaPark(Arena arena)
|
||||
{
|
||||
TraceId ti;
|
||||
Res res;
|
||||
|
||||
AVERT(Arena, arena);
|
||||
|
||||
arena->clamped = TRUE;
|
||||
|
||||
while(arena->busyTraces != TraceSetEMPTY) {
|
||||
/* Poll active traces to make progress. */
|
||||
for(ti = 0; ti < TRACE_MAX; ++ti)
|
||||
if(TraceSetIsMember(arena->busyTraces, ti)) {
|
||||
Trace trace = ArenaTrace(arena, ti);
|
||||
|
||||
res = TracePoll(trace);
|
||||
AVER(res == ResOK); /* @@@@ */
|
||||
|
||||
/* @@@@ Pick up results and use for prediction. */
|
||||
if(trace->state == TraceFINISHED)
|
||||
TraceDestroy(trace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Res ArenaCollect(Arena arena)
|
||||
{
|
||||
Trace trace;
|
||||
Res res;
|
||||
Ring poolNode, nextPoolNode;
|
||||
|
||||
AVERT(Arena, arena);
|
||||
ArenaPark(arena);
|
||||
|
||||
res = TraceCreate(&trace, arena);
|
||||
/* should be a trace available -- we're parked */
|
||||
AVER(res != ResLIMIT);
|
||||
if(res != ResOK)
|
||||
goto failCreate;
|
||||
|
||||
/* Identify the condemned set and turn it white. */
|
||||
RING_FOR(poolNode, ArenaPoolRing(arena), nextPoolNode) {
|
||||
Pool pool = RING_ELT(Pool, arenaRing, poolNode);
|
||||
Ring segNode, nextSegNode;
|
||||
|
||||
if((pool->class->attr & AttrGC) != 0) {
|
||||
res = PoolTraceBegin(pool, trace);
|
||||
if(res != ResOK)
|
||||
goto failBegin;
|
||||
|
||||
RING_FOR(segNode, PoolSegRing(pool), nextSegNode) {
|
||||
Seg seg = SegOfPoolRing(segNode);
|
||||
|
||||
/* avoid buffered segments and non-auto pools? */
|
||||
res = TraceAddWhite(trace, seg);
|
||||
if(res != ResOK)
|
||||
goto failAddWhite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TraceStart(trace);
|
||||
if(res != ResOK)
|
||||
goto failStart;
|
||||
|
||||
ArenaPark(arena);
|
||||
|
||||
return ResOK;
|
||||
|
||||
failStart:
|
||||
NOTREACHED;
|
||||
failAddWhite:
|
||||
NOTREACHED; /* @@@@ Would leave white sets inconsistent. */
|
||||
failBegin:
|
||||
TraceDestroy(trace);
|
||||
failCreate:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* ArenaDescribe -- describe the arena
|
||||
*
|
||||
* See design.mps.describe.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# impl.gmk.comm: COMMON GNUMAKEFILE FRAGMENT
|
||||
#
|
||||
# $HopeName: MMsrc!comm.gmk(trunk.16) $
|
||||
# $HopeName: MMsrc!comm.gmk(trunk.17) $
|
||||
# Copyright (C) 1995,1996,1997 Harlequin Group, all rights reserved
|
||||
#
|
||||
# DSCRIPTION
|
||||
|
|
@ -215,7 +215,7 @@ endif
|
|||
# just a convenient set of targets to build.
|
||||
|
||||
all: mpmss amcss amsss awlut dwstress mpsicv lockcov poolncv mps.a \
|
||||
lo.a mrg.a locv qs weakcv mpmconft finalcv arenacv
|
||||
lo.a locv qs weakcv mpmconft finalcv arenacv
|
||||
|
||||
# These convenience targets allow one to type "make foo" to build target
|
||||
# foo in all varieties.
|
||||
|
|
@ -224,7 +224,7 @@ all: mpmss amcss amsss awlut dwstress mpsicv lockcov poolncv mps.a \
|
|||
|
||||
mpmss amcss amsss awlut dwstress mpsicv lockcov poolncv \
|
||||
locv qs weakcv mpmconft finalcv arenacv \
|
||||
mps.a lo.a mrg.a awl.a mmsw.a: phony
|
||||
mps.a lo.a awl.a mmsw.a: phony
|
||||
ifdef VARIETY
|
||||
$(MAKE) -f $(PFM).gmk TARGET=$@ variety
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.h.mpm: MEMORY POOL MANAGER DEFINITIONS
|
||||
*
|
||||
* $HopeName: MMsrc!mpm.h(trunk.46) $
|
||||
* $HopeName: MMsrc!mpm.h(trunk.47) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*/
|
||||
|
||||
|
|
@ -268,8 +268,8 @@ extern Res PoolCreateV(Pool *poolReturn, Arena arena,
|
|||
extern void PoolDestroy(Pool pool);
|
||||
extern Res PoolAlloc(Addr *pReturn, Pool pool, Size size);
|
||||
extern void PoolFree(Pool pool, Addr old, Size size);
|
||||
extern Res PoolTraceBegin(Pool pool, Trace trace, Action action);
|
||||
extern Res PoolCondemn(Pool pool, Trace trace, Seg seg, Action action);
|
||||
extern Res PoolTraceBegin(Pool pool, Trace trace);
|
||||
extern Res PoolWhiten(Pool pool, Trace trace, Seg seg);
|
||||
extern void PoolGrey(Pool pool, Trace trace, Seg seg);
|
||||
extern void PoolBlacken(Pool pool, TraceSet traceSet, Seg seg);
|
||||
extern Res PoolScan(ScanState ss, Pool pool, Seg seg);
|
||||
|
|
@ -277,8 +277,8 @@ extern Res (PoolFix)(Pool pool, ScanState ss, Seg seg, Addr *refIO);
|
|||
#define PoolFix(pool, ss, seg, refIO) \
|
||||
((*(pool)->class->fix)(pool, ss, seg, refIO))
|
||||
extern void PoolReclaim(Pool pool, Trace trace, Seg seg);
|
||||
extern void PoolTraceEnd(Pool pool, Trace trace, Action action);
|
||||
extern double PoolBenefit(Pool pool, Action action);
|
||||
extern Res PoolAct(Pool pool, Action action);
|
||||
|
||||
extern void PoolTrivFinish(Pool pool);
|
||||
extern Res PoolNoAlloc(Addr *pReturn, Pool pool, Size size);
|
||||
|
|
@ -297,9 +297,10 @@ extern void PoolNoBufferEmpty(Pool pool, Buffer buffer);
|
|||
extern void PoolTrivBufferEmpty(Pool pool, Buffer buffer);
|
||||
extern Res PoolNoDescribe(Pool pool, mps_lib_FILE *stream);
|
||||
extern Res PoolTrivDescribe(Pool pool, mps_lib_FILE *stream);
|
||||
extern Res PoolNoTraceBegin(Pool pool, Trace trace, Action action);
|
||||
extern Res PoolTrivTraceBegin(Pool pool, Trace trace, Action action);
|
||||
extern Res PoolNoCondemn(Pool pool, Trace trace, Seg seg, Action action);
|
||||
extern Res PoolNoTraceBegin(Pool pool, Trace trace);
|
||||
extern Res PoolTrivTraceBegin(Pool pool, Trace trace);
|
||||
extern Res PoolNoWhiten(Pool pool, Trace trace, Seg seg);
|
||||
extern Res PoolTrivWhiten(Pool pool, Trace trace, Seg seg);
|
||||
extern void PoolNoGrey(Pool pool, Trace trace, Seg seg);
|
||||
extern void PoolTrivGrey(Pool pool, Trace trace, Seg seg);
|
||||
extern void PoolNoBlacken(Pool pool, TraceSet traceSet, Seg seg);
|
||||
|
|
@ -307,8 +308,6 @@ extern void PoolTrivBlacken(Pool pool, TraceSet traceSet, Seg seg);
|
|||
extern Res PoolNoScan(ScanState ss, Pool pool, Seg seg);
|
||||
extern Res PoolNoFix(Pool pool, ScanState ss, Seg seg, Ref *refIO);
|
||||
extern void PoolNoReclaim(Pool pool, Trace trace, Seg seg);
|
||||
extern void PoolNoTraceEnd(Pool pool, Trace trace, Action action);
|
||||
extern void PoolTrivTraceEnd(Pool pool, Trace trace, Action action);
|
||||
extern double PoolNoBenefit(Pool pool, Action action);
|
||||
|
||||
|
||||
|
|
@ -337,6 +336,9 @@ extern void MessageFinalizationRef(Ref *refReturn,
|
|||
extern void MessageNoFinalizationRef(Ref *refReturn,
|
||||
Arena arena, Message message);
|
||||
|
||||
extern Res PoolNoAct(Pool pool, Action action);
|
||||
extern Res PoolCollectAct(Pool pool, Action action);
|
||||
|
||||
|
||||
/* Trace Interface -- see impl.c.trace */
|
||||
|
||||
|
|
@ -361,12 +363,16 @@ extern Bool TraceIdCheck(TraceId id);
|
|||
extern Bool TraceSetCheck(TraceSet ts);
|
||||
extern Bool TraceCheck(Trace trace);
|
||||
|
||||
extern Res TraceCreate(Trace *traceReturn, Arena arena, Action action);
|
||||
extern Res TraceCreate(Trace *traceReturn, Space space);
|
||||
extern Res TraceAddWhite(Trace trace, Seg seg);
|
||||
extern Res TraceStart(Trace trace);
|
||||
extern Res TraceFlip(Trace trace);
|
||||
extern void TraceDestroy(Trace trace);
|
||||
extern Res TracePoll(Trace trace);
|
||||
extern void TraceAccess(Arena arena, Seg seg, AccessSet mode);
|
||||
|
||||
extern Res TraceFix(ScanState ss, Ref *refIO);
|
||||
extern void TraceSegGreyen(Arena arena, Seg seg, TraceSet ts);
|
||||
extern Size TraceGreyEstimate(Arena arena, RefSet refSet);
|
||||
|
||||
/* Equivalent to impl.h.mps MPS_SCAN_BEGIN */
|
||||
|
|
@ -448,6 +454,11 @@ extern void (ArenaPoll)(Arena arena);
|
|||
/* @@@@ Doesn't this break a rule that macro and function forms */
|
||||
/* must have identical behaviour? GavinM 1997-09-12 */
|
||||
|
||||
extern void ArenaClamp(Arena arena);
|
||||
extern void ArenaRelease(Arena arena);
|
||||
extern void ArenaPark(Arena arena);
|
||||
extern Res ArenaCollect(Arena arena);
|
||||
|
||||
extern Res ArenaAlloc(void **baseReturn, Arena arena, Size size);
|
||||
extern void ArenaFree(Arena arena, void *base, Size size);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.h.mpmst: MEMORY POOL MANAGER DATA STRUCTURES
|
||||
*
|
||||
* $HopeName: MMsrc!mpmst.h(trunk.36) $
|
||||
* $HopeName: MMsrc!mpmst.h(trunk.37) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* .readership: MM developers.
|
||||
|
|
@ -86,14 +86,14 @@ typedef struct PoolClassStruct {
|
|||
PoolBufferEmptyMethod bufferEmpty; /* out-of-line commit */
|
||||
PoolBufferFinishMethod bufferFinish; /* additional buffer finish */
|
||||
PoolTraceBeginMethod traceBegin;
|
||||
PoolCondemnMethod condemn; /* condemn (some or all) objects */
|
||||
PoolWhitenMethod whiten; /* whiten objects in a segment */
|
||||
PoolGreyMethod grey; /* grey non-white objects */
|
||||
PoolBlackenMethod blacken; /* blacken grey objects without scanning */
|
||||
PoolScanMethod scan; /* find references during tracing */
|
||||
PoolFixMethod fix; /* referent reachable during tracing */
|
||||
PoolReclaimMethod reclaim; /* reclaim dead objects after tracing */
|
||||
PoolTraceEndMethod traceEnd;
|
||||
PoolBenefitMethod benefit;
|
||||
PoolBenefitMethod benefit; /* calculate benefit of action */
|
||||
PoolActMethod act; /* do an action */
|
||||
PoolDescribeMethod describe; /* describe the contents of the pool */
|
||||
Sig endSig; /* .class.end-sig */
|
||||
} PoolClassStruct;
|
||||
|
|
@ -478,11 +478,10 @@ typedef struct TraceStruct {
|
|||
Sig sig; /* design.mps.sig */
|
||||
TraceId ti; /* index into TraceSets */
|
||||
Arena arena; /* owning arena */
|
||||
Action action; /* the action that launched the trace */
|
||||
RefSet white; /* superset of refs in white set */
|
||||
RefSet mayMove; /* superset of refs in moving set */
|
||||
TraceState state; /* current state of trace */
|
||||
Size condemned; /* condemned set size */
|
||||
Size condemned; /* condemned bytes */
|
||||
Size foundation; /* initial grey set size */
|
||||
Size rate; /* bytes to scan per increment */
|
||||
} TraceStruct;
|
||||
|
|
@ -555,6 +554,7 @@ typedef struct ArenaStruct {
|
|||
LockStruct lockStruct; /* arena's lock */
|
||||
Size pollThreshold; /* design.mps.arena.poll */
|
||||
Bool insidePoll; /* design.mps.arena.poll */
|
||||
Bool clamped; /* prevent background activity */
|
||||
Size actionInterval; /* design.mps.arena.poll.interval */
|
||||
double allocTime; /* "time" in allocated bytes */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.h.mpmtypes: MEMORY POOL MANAGER TYPES
|
||||
*
|
||||
* $HopeName: MMsrc!mpmtypes.h(trunk.32) $
|
||||
* $HopeName: MMsrc!mpmtypes.h(trunk.33) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* .readership: MM developers.
|
||||
|
|
@ -110,18 +110,14 @@ typedef Res (*PoolBufferFillMethod)(Seg *segReturn,
|
|||
Pool pool, Buffer buffer, Size size);
|
||||
typedef void (*PoolBufferEmptyMethod)(Pool pool, Buffer buffer);
|
||||
typedef Res (*PoolDescribeMethod)(Pool pool, mps_lib_FILE *stream);
|
||||
typedef Res (*PoolTraceBeginMethod)(Pool pool, Trace trace,
|
||||
Action action);
|
||||
typedef Res (*PoolCondemnMethod)(Pool pool, Trace trace,
|
||||
Seg seg, Action action);
|
||||
typedef Res (*PoolTraceBeginMethod)(Pool pool, Trace trace);
|
||||
typedef Res (*PoolWhitenMethod)(Pool pool, Trace trace, Seg seg);
|
||||
typedef void (*PoolGreyMethod)(Pool pool, Trace trace, Seg seg);
|
||||
typedef void (*PoolBlackenMethod)(Pool pool, TraceSet traceSet, Seg seg);
|
||||
typedef Res (*PoolScanMethod)(ScanState ss, Pool pool, Seg seg);
|
||||
typedef Res (*PoolFixMethod)(Pool pool, ScanState ss, Seg seg,
|
||||
Ref *refIO);
|
||||
typedef void (*PoolReclaimMethod)(Pool pool, Trace trace, Seg seg);
|
||||
typedef void (*PoolTraceEndMethod)(Pool pool, Trace trace,
|
||||
Action action);
|
||||
typedef double (*PoolBenefitMethod)(Pool pool, Action action);
|
||||
|
||||
|
||||
|
|
@ -137,6 +133,9 @@ typedef void (*MessageFinalizationRefMethod)
|
|||
typedef struct MessageFinalizationStruct *MessageFinalization;
|
||||
|
||||
|
||||
typedef Res (*PoolActMethod)(Pool pool, Action action);
|
||||
|
||||
|
||||
/* Format*Method -- see design.mps.format-interface */
|
||||
/* .fmt-methods: These methods must match those defined in the */
|
||||
/* MPS C Interface. (See impl.h.mps.fmt-methods.) */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.h.mps: HARLEQUIN MEMORY POOL SYSTEM C INTERFACE
|
||||
*
|
||||
* $HopeName: MMsrc!mps.h(trunk.23) $
|
||||
* $HopeName: MMsrc!mps.h(trunk.24) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* .readership: customers, MPS developers.
|
||||
|
|
@ -169,6 +169,11 @@ extern mps_assert_t mps_assert_default(void);
|
|||
|
||||
/* arenas */
|
||||
|
||||
extern void mps_arena_clamp(mps_arena_t);
|
||||
extern void mps_arena_release(mps_arena_t);
|
||||
extern void mps_arena_park(mps_arena_t);
|
||||
extern mps_res_t mps_arena_collect(mps_arena_t);
|
||||
|
||||
extern mps_res_t mps_arena_create(mps_arena_t *, mps_arena_class_t, ...);
|
||||
extern mps_res_t mps_arena_create_v(mps_arena_t *, mps_arena_class_t, va_list);
|
||||
extern void mps_arena_destroy(mps_arena_t);
|
||||
|
|
@ -179,7 +184,7 @@ extern void mps_space_destroy(mps_space_t);
|
|||
|
||||
extern size_t mps_arena_reserved(mps_arena_t);
|
||||
extern size_t mps_arena_committed(mps_arena_t);
|
||||
|
||||
|
||||
extern size_t mps_space_reserved(mps_space_t);
|
||||
extern size_t mps_space_committed(mps_space_t);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.mpsi: MEMORY POOL SYSTEM C INTERFACE LAYER
|
||||
*
|
||||
* $HopeName: MMsrc!mpsi.c(trunk.28) $
|
||||
* $HopeName: MMsrc!mpsi.c(trunk.29) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* .purpose: This code bridges between the MPS interface to C,
|
||||
|
|
@ -52,7 +52,7 @@
|
|||
#include "mps.h"
|
||||
#include "mpsavm.h" /* only for mps_space_create */
|
||||
|
||||
SRCID(mpsi, "$HopeName: MMsrc!mpsi.c(trunk.28) $");
|
||||
SRCID(mpsi, "$HopeName: MMsrc!mpsi.c(trunk.29) $");
|
||||
|
||||
|
||||
/* mpsi_check -- check consistency of interface mappings
|
||||
|
|
@ -213,6 +213,40 @@ size_t mps_space_committed(mps_space_t mps_space)
|
|||
return mps_arena_committed(mps_space);
|
||||
}
|
||||
|
||||
void mps_arena_clamp(mps_arena_t mps_arena)
|
||||
{
|
||||
Arena arena = (Arena)mps_arena;
|
||||
ArenaEnter(arena);
|
||||
ArenaClamp(arena);
|
||||
ArenaLeave(arena);
|
||||
}
|
||||
|
||||
void mps_arena_release(mps_arena_t mps_arena)
|
||||
{
|
||||
Arena arena = (Arena)mps_arena;
|
||||
ArenaEnter(arena);
|
||||
ArenaRelease(arena);
|
||||
ArenaLeave(arena);
|
||||
}
|
||||
|
||||
void mps_arena_park(mps_space_t mps_space)
|
||||
{
|
||||
Arena arena = (Arena)mps_space;
|
||||
ArenaEnter(arena);
|
||||
ArenaPark(arena);
|
||||
ArenaLeave(arena);
|
||||
}
|
||||
|
||||
mps_res_t mps_arena_collect(mps_space_t mps_space)
|
||||
{
|
||||
Res res;
|
||||
Arena arena = (Arena)mps_space;
|
||||
ArenaEnter(arena);
|
||||
res = ArenaCollect(arena);
|
||||
ArenaLeave(arena);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* mps_arena_create -- create an arena object */
|
||||
|
||||
|
|
|
|||
156
mps/src/pool.c
156
mps/src/pool.c
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.pool: POOL IMPLEMENTATION
|
||||
*
|
||||
* $HopeName: MMsrc!pool.c(trunk.36) $
|
||||
* $HopeName: MMsrc!pool.c(trunk.37) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* This is the implementation of the generic pool interface. The
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include "mpm.h"
|
||||
|
||||
SRCID(pool, "$HopeName: MMsrc!pool.c(trunk.36) $");
|
||||
SRCID(pool, "$HopeName: MMsrc!pool.c(trunk.37) $");
|
||||
|
||||
|
||||
Bool PoolClassCheck(PoolClass class)
|
||||
|
|
@ -33,13 +33,13 @@ Bool PoolClassCheck(PoolClass class)
|
|||
CHECKL(FUNCHECK(class->bufferEmpty));
|
||||
CHECKL(FUNCHECK(class->bufferFinish));
|
||||
CHECKL(FUNCHECK(class->traceBegin));
|
||||
CHECKL(FUNCHECK(class->condemn));
|
||||
CHECKL(FUNCHECK(class->whiten));
|
||||
CHECKL(FUNCHECK(class->grey));
|
||||
CHECKL(FUNCHECK(class->scan));
|
||||
CHECKL(FUNCHECK(class->fix));
|
||||
CHECKL(FUNCHECK(class->reclaim));
|
||||
CHECKL(FUNCHECK(class->traceEnd));
|
||||
CHECKL(FUNCHECK(class->benefit));
|
||||
CHECKL(FUNCHECK(class->act));
|
||||
CHECKL(FUNCHECK(class->describe));
|
||||
CHECKL(class->endSig == PoolClassSig);
|
||||
return TRUE;
|
||||
|
|
@ -250,26 +250,22 @@ void PoolFree(Pool pool, Addr old, Size size)
|
|||
EVENT_PAW(PoolFree, pool, old, size);
|
||||
}
|
||||
|
||||
Res PoolTraceBegin(Pool pool, Trace trace, Action action)
|
||||
Res PoolTraceBegin(Pool pool, Trace trace)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Action, action);
|
||||
AVER(trace->action == action);
|
||||
AVER(action->pool == pool);
|
||||
AVER(pool->arena == trace->arena);
|
||||
return (*pool->class->traceBegin)(pool, trace, action);
|
||||
AVER(PoolArena(pool) == trace->arena);
|
||||
return (*pool->class->traceBegin)(pool, trace);
|
||||
}
|
||||
|
||||
Res PoolCondemn(Pool pool, Trace trace, Seg seg, Action action)
|
||||
Res PoolWhiten(Pool pool, Trace trace, Seg seg)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Seg, seg);
|
||||
AVERT(Action, action);
|
||||
AVER(pool->arena == trace->arena);
|
||||
AVER(PoolArena(pool) == trace->arena);
|
||||
AVER(SegPool(seg) == pool);
|
||||
return (*pool->class->condemn)(pool, trace, seg, action);
|
||||
return (*pool->class->whiten)(pool, trace, seg);
|
||||
}
|
||||
|
||||
void PoolGrey(Pool pool, Trace trace, Seg seg)
|
||||
|
|
@ -349,17 +345,6 @@ void PoolReclaim(Pool pool, Trace trace, Seg seg)
|
|||
(*pool->class->reclaim)(pool, trace, seg);
|
||||
}
|
||||
|
||||
void PoolTraceEnd(Pool pool, Trace trace, Action action)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Action, action);
|
||||
AVER(trace->action == action);
|
||||
AVER(action->pool == pool);
|
||||
AVER(pool->arena == trace->arena);
|
||||
(*pool->class->traceEnd)(pool, trace, action);
|
||||
}
|
||||
|
||||
|
||||
double PoolBenefit(Pool pool, Action action)
|
||||
{
|
||||
|
|
@ -370,6 +355,15 @@ double PoolBenefit(Pool pool, Action action)
|
|||
}
|
||||
|
||||
|
||||
Res PoolAct(Pool pool, Action action)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Action, action);
|
||||
AVER(action->pool == pool);
|
||||
return (*pool->class->act)(pool, action);
|
||||
}
|
||||
|
||||
|
||||
Res PoolDescribe(Pool pool, mps_lib_FILE *stream)
|
||||
{
|
||||
Res res;
|
||||
|
|
@ -606,35 +600,39 @@ Res PoolTrivDescribe(Pool pool, mps_lib_FILE *stream)
|
|||
return WriteF(stream, " No class-specific description available.\n", NULL);
|
||||
}
|
||||
|
||||
Res PoolNoTraceBegin(Pool pool, Trace trace, Action action)
|
||||
Res PoolNoTraceBegin(Pool pool, Trace trace)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Action, action);
|
||||
AVER(trace->action == action);
|
||||
AVER(action->pool == pool);
|
||||
AVER(pool->arena == trace->arena);
|
||||
AVER(PoolArena(pool) == trace->arena);
|
||||
NOTREACHED;
|
||||
return ResUNIMPL;
|
||||
}
|
||||
|
||||
Res PoolTrivTraceBegin(Pool pool, Trace trace, Action action)
|
||||
Res PoolTrivTraceBegin(Pool pool, Trace trace)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Action, action);
|
||||
AVER(trace->action == action);
|
||||
AVER(action->pool == pool);
|
||||
AVER(pool->arena == trace->arena);
|
||||
AVER(PoolArena(pool) == trace->arena);
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
Res PoolNoCondemn(Pool pool, Trace trace, Seg seg, Action action)
|
||||
Res PoolTrivWhiten(Pool pool, Trace trace, Seg seg)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Seg, seg);
|
||||
|
||||
SegSetWhite(seg, TraceSetAdd(SegWhite(seg), trace->ti));
|
||||
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
Res PoolNoWhiten(Pool pool, Trace trace, Seg seg)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Seg, seg);
|
||||
AVERT(Action, action);
|
||||
NOTREACHED;
|
||||
return ResUNIMPL;
|
||||
}
|
||||
|
|
@ -705,27 +703,6 @@ void PoolNoReclaim(Pool pool, Trace trace, Seg seg)
|
|||
NOTREACHED;
|
||||
}
|
||||
|
||||
void PoolNoTraceEnd(Pool pool, Trace trace, Action action)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Action, action);
|
||||
AVER(trace->action == action);
|
||||
AVER(action->pool == pool);
|
||||
AVER(pool->arena == trace->arena);
|
||||
NOTREACHED;
|
||||
}
|
||||
|
||||
void PoolTrivTraceEnd(Pool pool, Trace trace, Action action)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Action, action);
|
||||
AVER(trace->action == action);
|
||||
AVER(action->pool == pool);
|
||||
AVER(pool->arena == trace->arena);
|
||||
}
|
||||
|
||||
double PoolNoBenefit(Pool pool, Action action)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
|
|
@ -734,3 +711,66 @@ double PoolNoBenefit(Pool pool, Action action)
|
|||
NOTREACHED;
|
||||
return (double)0;
|
||||
}
|
||||
|
||||
Res PoolNoAct(Pool pool, Action action)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Action, action);
|
||||
AVER(action->pool == pool);
|
||||
NOTREACHED;
|
||||
return ResUNIMPL;
|
||||
}
|
||||
|
||||
|
||||
/* PoolCollectAct -- perform the action of collecting the entire pool
|
||||
*
|
||||
* @@@@ This should be in a module such as collect.c, but this is a
|
||||
* short term patch for change.dylan.sunflower.10.170440.
|
||||
*/
|
||||
|
||||
Res PoolCollectAct(Pool pool, Action action)
|
||||
{
|
||||
Trace trace;
|
||||
Res res;
|
||||
Arena arena;
|
||||
Ring ring, node, nextNode;
|
||||
Seg seg;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Action, action);
|
||||
|
||||
arena = PoolArena(pool);
|
||||
|
||||
res = TraceCreate(&trace, arena);
|
||||
if(res != ResOK)
|
||||
goto failCreate;
|
||||
|
||||
res = PoolTraceBegin(action->pool, trace);
|
||||
if(res != ResOK)
|
||||
goto failBegin;
|
||||
|
||||
/* Identify the condemned set and turn it white. */
|
||||
ring = PoolSegRing(pool);
|
||||
RING_FOR(node, ring, nextNode) {
|
||||
seg = SegOfPoolRing(node);
|
||||
|
||||
res = TraceAddWhite(trace, seg);
|
||||
if(res != ResOK)
|
||||
goto failAddWhite;
|
||||
}
|
||||
|
||||
TraceStart(trace);
|
||||
if(res != ResOK)
|
||||
goto failStart;
|
||||
|
||||
return ResOK;
|
||||
|
||||
failStart:
|
||||
NOTREACHED;
|
||||
failAddWhite:
|
||||
NOTREACHED; /* @@@@ Would leave white sets inconsistent. */
|
||||
failBegin:
|
||||
TraceDestroy(trace);
|
||||
failCreate:
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.poolams: AUTOMATIC MARK & SWEEP POOL CLASS
|
||||
*
|
||||
* $HopeName: MMsrc!poolams.c(trunk.9) $
|
||||
* $HopeName: MMsrc!poolams.c(trunk.10) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* NOTES
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
#include "mpm.h"
|
||||
#include "mpscams.h"
|
||||
|
||||
SRCID(poolams, "$HopeName: MMsrc!poolams.c(trunk.9) $");
|
||||
SRCID(poolams, "$HopeName: MMsrc!poolams.c(trunk.10) $");
|
||||
|
||||
|
||||
#define AMSSig ((Sig)0x519A3599) /* SIGnature AMS */
|
||||
|
|
@ -536,12 +536,12 @@ static void AMSBufferEmpty(Pool pool, Buffer buffer)
|
|||
}
|
||||
|
||||
|
||||
/* AMSRangeCondemn -- condemns a part of a group
|
||||
/* AMSRangeWhiten -- whitens a part of a group
|
||||
*
|
||||
* Split out of AMSCondemn because it's used in more than one place.
|
||||
* Split out of AMSWhiten because it's used in more than one place.
|
||||
*/
|
||||
|
||||
static void AMSRangeCondemn(AMSGroup group, Index base, Index limit)
|
||||
static void AMSRangeWhiten(AMSGroup group, Index base, Index limit)
|
||||
{
|
||||
if (base != limit) {
|
||||
AVER(base < limit);
|
||||
|
|
@ -559,12 +559,12 @@ static void AMSRangeCondemn(AMSGroup group, Index base, Index limit)
|
|||
}
|
||||
|
||||
|
||||
/* AMSCondemn -- the pool class segment condemning method
|
||||
/* AMSWhiten -- the pool class segment whitening method
|
||||
*
|
||||
* See design.mps.poolams.condemn
|
||||
* See design.mps.poolams.whiten
|
||||
*/
|
||||
|
||||
static Res AMSCondemn(Pool pool, Trace trace, Seg seg, Action action)
|
||||
static Res AMSWhiten(Pool pool, Trace trace, Seg seg)
|
||||
{
|
||||
AMS ams;
|
||||
AMSGroup group;
|
||||
|
|
@ -576,8 +576,6 @@ static Res AMSCondemn(Pool pool, Trace trace, Seg seg, Action action)
|
|||
|
||||
AVERT(Trace, trace);
|
||||
AVER(SegCheck(seg));
|
||||
AVERT(Action, action);
|
||||
AVER(ams == ActionAMS(action));
|
||||
|
||||
group = AMSSegGroup(seg);
|
||||
AVERT(AMSGroup, group);
|
||||
|
|
@ -588,20 +586,20 @@ static Res AMSCondemn(Pool pool, Trace trace, Seg seg, Action action)
|
|||
AVER(SegWhite(seg) == TraceSetEMPTY);
|
||||
|
||||
buffer = SegBuffer(seg);
|
||||
if (buffer != NULL) { /* design.mps.poolams.condemn.buffer */
|
||||
if (buffer != NULL) { /* design.mps.poolams.whiten.buffer */
|
||||
Index scanLimitIndex, limitIndex;
|
||||
scanLimitIndex = AMSAddrIndex(group, BufferScanLimit(buffer));
|
||||
limitIndex = AMSAddrIndex(group, BufferLimit(buffer));
|
||||
|
||||
AMSRangeCondemn(group, 0, scanLimitIndex);
|
||||
AMSRangeCondemn(group, limitIndex, group->grains);
|
||||
} else { /* condemn whole seg */
|
||||
AMSRangeCondemn(group, 0, group->grains);
|
||||
AMSRangeWhiten(group, 0, scanLimitIndex);
|
||||
AMSRangeWhiten(group, limitIndex, group->grains);
|
||||
} else { /* whiten whole seg */
|
||||
AMSRangeWhiten(group, 0, group->grains);
|
||||
}
|
||||
|
||||
group->marked = FALSE; /* design.mps.poolams.marked.condemn */
|
||||
|
||||
/* design.mps.poolams.condemn.white */
|
||||
/* design.mps.poolams.whiten.seg */
|
||||
SegSetWhite(seg, TraceSetAdd(SegWhite(seg), trace->ti));
|
||||
|
||||
return ResOK;
|
||||
|
|
@ -1206,14 +1204,14 @@ static PoolClassStruct PoolClassAMSStruct = {
|
|||
AMSBufferEmpty, /* bufferEmpty */
|
||||
PoolTrivBufferFinish, /* design.mps.poolams.triv-buffer-finish */
|
||||
PoolTrivTraceBegin, /* design.mps.poolams.triv-trace-begin */
|
||||
AMSCondemn, /* condemn */
|
||||
AMSWhiten, /* whiten */
|
||||
PoolTrivGrey, /* design.mps.poolams.triv-grey */
|
||||
AMSBlacken, /* blacken */
|
||||
AMSScan, /* scan */
|
||||
AMSFix, /* fix */
|
||||
AMSReclaim, /* reclaim */
|
||||
PoolTrivTraceEnd, /* design.mps.poolams.triv-trace-end */
|
||||
AMSBenefit, /* benefit */
|
||||
PoolCollectAct, /* act */
|
||||
AMSDescribe, /* describe */
|
||||
PoolClassSig /* impl.h.mpm.class.end-sig */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.poolawl: AUTOMATIC WEAK LINKED POOL CLASS
|
||||
*
|
||||
* $HopeName: MMsrc!poolawl.c(trunk.20) $
|
||||
* $HopeName: MMsrc!poolawl.c(trunk.21) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* READERSHIP
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
#include "mpm.h"
|
||||
#include "mpscawl.h"
|
||||
|
||||
SRCID(poolawl, "$HopeName: MMsrc!poolawl.c(trunk.20) $");
|
||||
SRCID(poolawl, "$HopeName: MMsrc!poolawl.c(trunk.21) $");
|
||||
|
||||
|
||||
#define AWLSig ((Sig)0x519b7a37) /* SIGPooLAWL */
|
||||
|
|
@ -334,14 +334,11 @@ static void AWLBufferEmpty(Pool pool, Buffer buffer)
|
|||
}
|
||||
|
||||
|
||||
static Res AWLCondemn(Pool pool, Trace trace, Seg seg, Action action)
|
||||
static Res AWLWhiten(Pool pool, Trace trace, Seg seg)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Seg, seg);
|
||||
AVERT(Action, action);
|
||||
/* all parameters checked by generic PoolWhiten */
|
||||
|
||||
/* can only condemn for a single trace, */
|
||||
/* can only whiten for a single trace, */
|
||||
/* see design.mps.poolawl.fun.condemn */
|
||||
AVER(SegWhite(seg) == TraceSetEMPTY);
|
||||
|
||||
|
|
@ -353,7 +350,6 @@ static Res AWLCondemn(Pool pool, Trace trace, Seg seg, Action action)
|
|||
|
||||
awl = PoolPoolAWL(pool);
|
||||
AVERT(AWL, awl);
|
||||
AVER(awl == ActionAWL(action));
|
||||
|
||||
group = (AWLGroup)SegP(seg);
|
||||
AVERT(AWLGroup, group);
|
||||
|
|
@ -707,7 +703,7 @@ static void AWLReclaim(Pool pool, Trace trace, Seg seg)
|
|||
SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace->ti));
|
||||
}
|
||||
|
||||
static Res AWLTraceBegin(Pool pool, Trace trace, Action action)
|
||||
static Res AWLTraceBegin(Pool pool, Trace trace)
|
||||
{
|
||||
AWL awl;
|
||||
|
||||
|
|
@ -715,8 +711,6 @@ static Res AWLTraceBegin(Pool pool, Trace trace, Action action)
|
|||
awl = PoolPoolAWL(pool);
|
||||
AVERT(AWL, awl);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Action, action);
|
||||
AVER(awl == ActionAWL(action));
|
||||
|
||||
awl->lastCollected = PoolArena(pool)->allocTime;
|
||||
return ResOK;
|
||||
|
|
@ -756,14 +750,14 @@ struct PoolClassStruct PoolClassAWLStruct = {
|
|||
AWLBufferEmpty,
|
||||
PoolTrivBufferFinish,
|
||||
AWLTraceBegin,
|
||||
AWLCondemn,
|
||||
AWLWhiten,
|
||||
AWLGrey,
|
||||
AWLBlacken,
|
||||
AWLScan,
|
||||
AWLFix,
|
||||
AWLReclaim,
|
||||
PoolTrivTraceEnd,
|
||||
AWLBenefit,
|
||||
PoolCollectAct,
|
||||
PoolTrivDescribe,
|
||||
PoolClassSig
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.poolmfs: MANUAL FIXED SMALL UNIT POOL
|
||||
*
|
||||
* $HopeName: MMsrc!poolmfs.c(trunk.23) $
|
||||
* $HopeName: MMsrc!poolmfs.c(trunk.24) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* This is the implementation of the MFS pool class.
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
#include "mpm.h"
|
||||
#include "poolmfs.h"
|
||||
|
||||
SRCID(poolmfs, "$HopeName: MMsrc!poolmfs.c(trunk.23) $");
|
||||
SRCID(poolmfs, "$HopeName: MMsrc!poolmfs.c(trunk.24) $");
|
||||
|
||||
|
||||
/* == Round up ==
|
||||
|
|
@ -273,14 +273,14 @@ static PoolClassStruct PoolClassMFSStruct = {
|
|||
PoolNoBufferEmpty, /* bufferEmpty */
|
||||
PoolNoBufferFinish, /* bufferFinish */
|
||||
PoolNoTraceBegin, /* traceBegin */
|
||||
PoolNoCondemn, /* condemn */
|
||||
PoolNoWhiten, /* whiten */
|
||||
PoolNoGrey, /* grey */
|
||||
PoolNoBlacken, /* blacken */
|
||||
PoolNoScan, /* scan */
|
||||
PoolNoFix, /* fix */
|
||||
PoolNoReclaim, /* reclaim */
|
||||
PoolNoTraceEnd, /* traceEnd */
|
||||
PoolNoBenefit, /* benefit */
|
||||
PoolNoAct, /* act */
|
||||
MFSDescribe, /* describe */
|
||||
PoolClassSig /* impl.h.mpmst.class.end-sig */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* MANUAL RANK GUARDIAN POOL
|
||||
*
|
||||
* $HopeName: MMsrc!poolmrg.c(trunk.15) $
|
||||
* $HopeName: MMsrc!poolmrg.c(trunk.16) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* READERSHIP
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
#include "mpm.h"
|
||||
#include "poolmrg.h"
|
||||
|
||||
SRCID(poolmrg, "$HopeName: MMsrc!poolmrg.c(trunk.15) $");
|
||||
SRCID(poolmrg, "$HopeName: MMsrc!poolmrg.c(trunk.16) $");
|
||||
|
||||
|
||||
/* Types */
|
||||
|
|
@ -680,15 +680,15 @@ static PoolClassStruct PoolClassMRGStruct = {
|
|||
PoolNoBufferFill, /* bufferFill */
|
||||
PoolNoBufferEmpty, /* bufferEmpty */
|
||||
PoolNoBufferFinish, /* bufferFinish */
|
||||
PoolNoTraceBegin, /* traceBegin */
|
||||
PoolNoCondemn, /* condemn */
|
||||
PoolNoTraceBegin, /* traceBegin */
|
||||
PoolNoWhiten, /* whiten */
|
||||
PoolTrivGrey, /* grey */
|
||||
PoolTrivBlacken, /* blacken */
|
||||
MRGScan, /* scan */
|
||||
PoolNoFix, /* fix */
|
||||
PoolNoReclaim, /* reclaim */
|
||||
PoolNoTraceEnd, /* traceEnd */
|
||||
PoolNoBenefit, /* benefit */
|
||||
PoolNoBenefit, /* benefit */
|
||||
PoolNoAct, /* act */
|
||||
MRGDescribe, /* describe */
|
||||
PoolClassSig /* impl.h.mpmst.class.end-sig */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.poolmv: MANUAL VARIABLE POOL
|
||||
*
|
||||
* $HopeName: MMsrc!poolmv.c(trunk.24) $
|
||||
* $HopeName: MMsrc!poolmv.c(trunk.25) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* **** RESTRICTION: This pool may not allocate from the arena control
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
#include "poolmfs.h"
|
||||
#include "mpscmv.h"
|
||||
|
||||
SRCID(poolmv, "$HopeName: MMsrc!poolmv.c(trunk.24) $");
|
||||
SRCID(poolmv, "$HopeName: MMsrc!poolmv.c(trunk.25) $");
|
||||
|
||||
|
||||
#define BLOCKPOOL(mv) (MFSPool(&(mv)->blockPoolStruct))
|
||||
|
|
@ -620,14 +620,14 @@ static PoolClassStruct PoolClassMVStruct = {
|
|||
PoolTrivBufferEmpty, /* bufferEmpty */
|
||||
PoolTrivBufferFinish, /* bufferFinish */
|
||||
PoolNoTraceBegin, /* traceBegin */
|
||||
PoolNoCondemn, /* condemn */
|
||||
PoolNoGrey, /* grey */
|
||||
PoolNoWhiten, /* whiten */
|
||||
PoolNoGrey, /* mark */
|
||||
PoolNoBlacken, /* blacken */
|
||||
PoolNoScan, /* scan */
|
||||
PoolNoFix, /* fix */
|
||||
PoolNoReclaim, /* relcaim */
|
||||
PoolNoTraceEnd, /* traceEnd */
|
||||
PoolNoBenefit, /* benefit */
|
||||
PoolNoAct, /* act */
|
||||
MVDescribe, /* describe */
|
||||
PoolClassSig /* impl.h.mpmst.class.end-sig */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.pooln: NULL POOL
|
||||
*
|
||||
* $HopeName: MMsrc!pooln.c(trunk.13) $
|
||||
* $HopeName: MMsrc!pooln.c(trunk.14) $
|
||||
* Copyright(C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* This is the implementation of the null pool class. Begin null it
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
#include "mpm.h"
|
||||
#include "pooln.h"
|
||||
|
||||
SRCID(pooln, "$HopeName: MMsrc!pooln.c(trunk.13) $");
|
||||
SRCID(pooln, "$HopeName: MMsrc!pooln.c(trunk.14) $");
|
||||
|
||||
|
||||
typedef struct PoolNStruct {
|
||||
|
|
@ -148,7 +148,7 @@ static Res NDescribe(Pool pool, mps_lib_FILE *stream)
|
|||
return ResOK;
|
||||
}
|
||||
|
||||
static Res NCondemn(Pool pool, Trace trace, Seg seg, Action action)
|
||||
static Res NWhiten(Pool pool, Trace trace, Seg seg)
|
||||
{
|
||||
PoolN poolN;
|
||||
|
||||
|
|
@ -158,7 +158,6 @@ static Res NCondemn(Pool pool, Trace trace, Seg seg, Action action)
|
|||
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Seg, seg);
|
||||
AVERT(Action, action);
|
||||
|
||||
NOTREACHED; /* pool doesn't have any actions */
|
||||
|
||||
|
|
@ -247,14 +246,14 @@ static PoolClassStruct PoolClassNStruct = {
|
|||
NBufferEmpty, /* bufferEmpty */
|
||||
NBufferFinish, /* bufferFinish */
|
||||
PoolNoTraceBegin, /* traceBegin */
|
||||
NCondemn, /* condemn */
|
||||
NWhiten, /* whiten */
|
||||
NGrey, /* grey */
|
||||
NBlacken, /* blacken */
|
||||
NScan, /* scan */
|
||||
NFix, /* fix */
|
||||
NReclaim, /* reclaim */
|
||||
PoolNoTraceEnd, /* traceEnd */
|
||||
PoolNoBenefit, /* benefit */
|
||||
PoolNoAct, /* act */
|
||||
NDescribe, /* describe */
|
||||
PoolClassSig /* impl.h.mpmst.class.end-sig */
|
||||
};
|
||||
|
|
|
|||
193
mps/src/trace.c
193
mps/src/trace.c
|
|
@ -1,12 +1,12 @@
|
|||
/* impl.c.trace: GENERIC TRACER IMPLEMENTATION
|
||||
*
|
||||
* $HopeName: MMsrc!trace.c(trunk.48) $
|
||||
* $HopeName: MMsrc!trace.c(trunk.49) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "mpm.h"
|
||||
|
||||
SRCID(trace, "$HopeName: MMsrc!trace.c(trunk.48) $");
|
||||
SRCID(trace, "$HopeName: MMsrc!trace.c(trunk.49) $");
|
||||
|
||||
|
||||
/* ScanStateCheck -- check consistency of a ScanState object */
|
||||
|
|
@ -94,6 +94,43 @@ Bool TraceCheck(Trace trace)
|
|||
}
|
||||
|
||||
|
||||
/* TraceAddWhite -- add a segment to the white set of a trace */
|
||||
|
||||
Res TraceAddWhite(Trace trace, Seg seg)
|
||||
{
|
||||
Res res;
|
||||
Pool pool;
|
||||
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Seg, seg);
|
||||
AVER(!TraceSetIsMember(SegWhite(seg), trace->ti)); /* .start.black */
|
||||
|
||||
pool = SegPool(seg);
|
||||
AVERT(Pool, pool);
|
||||
|
||||
/* Give the pool the opportunity to turn the segment white. */
|
||||
/* If it fails, unwind. */
|
||||
res = PoolWhiten(pool, trace, seg);
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
|
||||
/* Add the segment to the approximation of the white set the */
|
||||
/* pool made it white. */
|
||||
if(TraceSetIsMember(SegWhite(seg), trace->ti)) {
|
||||
trace->white = RefSetUnion(trace->white,
|
||||
RefSetOfSeg(trace->arena, seg));
|
||||
trace->condemned += SegSize(seg);
|
||||
/* if the pool is a moving GC, then condemned objects may move */
|
||||
if(pool->class->attr & AttrMOVINGGC) {
|
||||
trace->mayMove = RefSetUnion(trace->mayMove,
|
||||
RefSetOfSeg(PoolArena(pool), seg));
|
||||
}
|
||||
}
|
||||
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
|
||||
/* TraceStart -- condemn a set of objects and start collection
|
||||
*
|
||||
* TraceStart should be passed a trace with state TraceINIT, i.e.
|
||||
|
|
@ -105,62 +142,23 @@ Bool TraceCheck(Trace trace)
|
|||
* it easy to destroy traces half-way through.
|
||||
*/
|
||||
|
||||
static Res TraceStart(Trace trace, Action action)
|
||||
Res TraceStart(Trace trace)
|
||||
{
|
||||
Res res;
|
||||
Ring ring, node;
|
||||
Arena arena;
|
||||
Seg seg;
|
||||
Pool pool;
|
||||
Res res;
|
||||
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Action, action);
|
||||
AVER((action->pool->class->attr & AttrGC) != 0);
|
||||
AVER(trace->state == TraceINIT);
|
||||
AVER(trace->white == RefSetEMPTY);
|
||||
|
||||
/* Identify the condemned set and turn it white. */
|
||||
arena = trace->arena;
|
||||
pool = action->pool;
|
||||
|
||||
EVENT_PPP(TraceStart, trace, pool, action);
|
||||
ring = PoolSegRing(pool);
|
||||
node = RingNext(ring);
|
||||
while(node != ring) {
|
||||
Ring next = RingNext(node);
|
||||
seg = SegOfPoolRing(node);
|
||||
|
||||
AVER(!TraceSetIsMember(SegWhite(seg), trace->ti)); /* .start.black */
|
||||
|
||||
/* Give the pool the opportunity to turn the segment white. */
|
||||
/* If it fails, unwind. */
|
||||
res = PoolCondemn(pool, trace, seg, action);
|
||||
if(res != ResOK) goto failCondemn;
|
||||
|
||||
/* Add the segment to the approximation of the white set */
|
||||
/* if and only if the pool made it white. */
|
||||
if(TraceSetIsMember(SegWhite(seg), trace->ti)) {
|
||||
trace->white = RefSetUnion(trace->white, RefSetOfSeg(arena, seg));
|
||||
trace->condemned += SegSize(seg);
|
||||
/* if the pool is a moving GC, then condemned objects may move */
|
||||
if(pool->class->attr & AttrMOVINGGC) {
|
||||
trace->mayMove =
|
||||
RefSetUnion(trace->mayMove, RefSetOfSeg(arena, seg));
|
||||
}
|
||||
}
|
||||
|
||||
node = next;
|
||||
}
|
||||
|
||||
/* If there is nothing white then there can be nothing grey, */
|
||||
/* so everything is black and we can proceed straight to */
|
||||
/* reclaim. We have to reclaim because we want to guarantee */
|
||||
/* to the pool that for every condemn there will be a reclaim. */
|
||||
/* @@@@ We can also shortcut if there is nothing grey. */
|
||||
/* @@@@ This should be in design. */
|
||||
/* so everything is black and we can finish the trace immediately. */
|
||||
if(trace->white == RefSetEMPTY) {
|
||||
arena->flippedTraces = TraceSetAdd(arena->flippedTraces, trace->ti);
|
||||
trace->state = TraceRECLAIM;
|
||||
trace->state = TraceFINISHED;
|
||||
trace->rate = (Size)1;
|
||||
return ResOK;
|
||||
}
|
||||
|
|
@ -231,21 +229,12 @@ static Res TraceStart(Trace trace, Action action)
|
|||
|
||||
trace->state = TraceUNFLIPPED;
|
||||
|
||||
/* All traces must flip at beginning at the moment. */
|
||||
res = TraceFlip(trace);
|
||||
if(res != ResOK)
|
||||
return res;
|
||||
|
||||
return ResOK;
|
||||
|
||||
/* PoolCondemn failed, possibly half-way through whitening the condemned */
|
||||
/* set. This loop empties the white set again. */
|
||||
failCondemn:
|
||||
ring = PoolSegRing(pool);
|
||||
node = RingNext(ring);
|
||||
while(node != ring) {
|
||||
Ring next = RingNext(node);
|
||||
seg = SegOfPoolRing(node);
|
||||
SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace->ti));
|
||||
node = next;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -265,17 +254,15 @@ failCondemn:
|
|||
* objects dynamically.
|
||||
*/
|
||||
|
||||
Res TraceCreate(Trace *traceReturn, Arena arena, Action action)
|
||||
Res TraceCreate(Trace *traceReturn, Arena arena)
|
||||
{
|
||||
TraceId ti;
|
||||
Trace trace;
|
||||
Res res;
|
||||
|
||||
AVER(TRACE_MAX == 1); /* .single-collection */
|
||||
|
||||
AVER(traceReturn != NULL);
|
||||
AVERT(Arena, arena);
|
||||
AVERT(Action, action);
|
||||
|
||||
/* Find a free trace ID */
|
||||
for(ti = 0; ti < TRACE_MAX; ++ti)
|
||||
|
|
@ -290,7 +277,6 @@ found:
|
|||
arena->busyTraces = TraceSetAdd(arena->busyTraces, ti);
|
||||
|
||||
trace->arena = arena;
|
||||
trace->action = action;
|
||||
trace->white = RefSetEMPTY;
|
||||
trace->mayMove = RefSetEMPTY;
|
||||
trace->ti = ti;
|
||||
|
|
@ -302,22 +288,8 @@ found:
|
|||
trace->sig = TraceSig;
|
||||
AVERT(Trace, trace);
|
||||
|
||||
res = PoolTraceBegin(action->pool, trace, action);
|
||||
if(res != ResOK) goto failBegin;
|
||||
|
||||
res = TraceStart(trace, action);
|
||||
if(res != ResOK) goto failStart;
|
||||
|
||||
*traceReturn = trace;
|
||||
EVENT_PPPU(TraceCreate, arena, action, trace, ti);
|
||||
return ResOK;
|
||||
|
||||
failStart:
|
||||
PoolTraceEnd(action->pool, trace, action);
|
||||
failBegin:
|
||||
trace->sig = SigInvalid; /* design.mps.arena.trace.invalid */
|
||||
arena->busyTraces = TraceSetDel(arena->busyTraces, ti);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -333,11 +305,10 @@ failBegin:
|
|||
void TraceDestroy(Trace trace)
|
||||
{
|
||||
AVERT(Trace, trace);
|
||||
|
||||
AVER(trace->state == TraceFINISHED);
|
||||
|
||||
PoolTraceEnd(trace->action->pool, trace, trace->action);
|
||||
|
||||
trace->sig = SigInvalid; /* design.mps.arena.trace.invalid */
|
||||
trace->sig = SigInvalid;
|
||||
trace->arena->busyTraces =
|
||||
TraceSetDel(trace->arena->busyTraces, trace->ti);
|
||||
trace->arena->flippedTraces =
|
||||
|
|
@ -346,6 +317,60 @@ void TraceDestroy(Trace trace)
|
|||
}
|
||||
|
||||
|
||||
/* TraceSegGreyen -- turn a segment more grey
|
||||
*
|
||||
* Adds the trace set ts to the greyness of the segment and adjusts
|
||||
* the shielding on the segment appropriately. (If it causes the
|
||||
* segment to become grey for a flipped trace the shield is raised.)
|
||||
* @@@@ Why does it seem to be write and a read barrier?
|
||||
*/
|
||||
|
||||
void TraceSegGreyen(Arena arena, Seg seg, TraceSet ts)
|
||||
{
|
||||
TraceSet segGrey, newGrey;
|
||||
|
||||
AVERT(Arena, arena);
|
||||
AVERT(Seg, seg);
|
||||
AVER(TraceSetCheck(ts));
|
||||
|
||||
segGrey = SegGrey(seg);
|
||||
newGrey = TraceSetUnion(segGrey, ts);
|
||||
if(newGrey != segGrey) {
|
||||
/* The read barrier should only really be raised when the */
|
||||
/* segment is grey for some flipped trace, i.e. */
|
||||
/* if(TraceSetInter(grey, space->flippedTraces) != TraceSetEMPTY) */
|
||||
/* But this requires Flip to raise it when flippedTraces changes, */
|
||||
/* which it does not do at present. */
|
||||
ShieldRaise(arena, seg, AccessREAD);
|
||||
|
||||
/* Temporary hack to add to grey list for */
|
||||
/* change.dylan.sunflower.7.170421. */
|
||||
AVER(RankSetIsSingle(SegRankSet(seg)));
|
||||
if(segGrey == RefSetEMPTY) {
|
||||
switch(SegRankSet(seg)) {
|
||||
case RankSetSingle(RankAMBIG):
|
||||
RingInsert(&arena->greyRing[RankAMBIG], SegGreyRing(seg));
|
||||
break;
|
||||
case RankSetSingle(RankEXACT):
|
||||
RingInsert(&arena->greyRing[RankEXACT], SegGreyRing(seg));
|
||||
break;
|
||||
case RankSetSingle(RankFINAL):
|
||||
RingInsert(&arena->greyRing[RankFINAL], SegGreyRing(seg));
|
||||
break;
|
||||
case RankSetSingle(RankWEAK):
|
||||
RingInsert(&arena->greyRing[RankWEAK], SegGreyRing(seg));
|
||||
break;
|
||||
default:
|
||||
NOTREACHED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SegSetGrey(seg, newGrey);
|
||||
EVENT_PPU(TraceSegGreyen, arena, seg, ts);
|
||||
}
|
||||
|
||||
|
||||
/* TraceFlipBuffers -- flip all buffers in the arena */
|
||||
|
||||
static void TraceFlipBuffers(Arena arena)
|
||||
|
|
@ -382,7 +407,7 @@ static void TraceFlipBuffers(Arena arena)
|
|||
|
||||
/* TraceFlip -- blacken the mutator */
|
||||
|
||||
static Res TraceFlip(Trace trace)
|
||||
Res TraceFlip(Trace trace)
|
||||
{
|
||||
Ring ring;
|
||||
Ring node, nextNode;
|
||||
|
|
@ -888,7 +913,8 @@ Res TraceScanArea(ScanState ss, Addr *base, Addr *limit)
|
|||
ref = *p++;
|
||||
if(!TRACE_FIX1(ss, ref)) goto loop;
|
||||
res = TRACE_FIX2(ss, p-1);
|
||||
if(res == ResOK) goto loop;
|
||||
if(res == ResOK)
|
||||
goto loop;
|
||||
return res;
|
||||
out:
|
||||
AVER(p == limit);
|
||||
|
|
@ -937,7 +963,8 @@ Res TraceScanAreaMasked(ScanState ss, Addr *base, Addr *limit, Word mask)
|
|||
if(((Word)ref & mask) != 0) goto loop;
|
||||
if(!TRACE_FIX1(ss, ref)) goto loop;
|
||||
res = TRACE_FIX2(ss, p-1);
|
||||
if(res == ResOK) goto loop;
|
||||
if(res == ResOK)
|
||||
goto loop;
|
||||
return res;
|
||||
out:
|
||||
AVER(p == limit);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# ==== NTI3MV NMAKE FILE ====
|
||||
#
|
||||
# $HopeName: MMsrc!w3i3mv.nmk(trunk.41) $
|
||||
# $HopeName: MMsrc!w3i3mv.nmk(trunk.42) $
|
||||
#
|
||||
# Copyright (C) 1995,1996,1997 Harlequin Group, all rights reserved
|
||||
#
|
||||
|
|
@ -163,7 +163,6 @@ MPMOBJ0 = $(MPM:<=w3i3mv\wi\)
|
|||
MPMOBJ = $(MPMOBJ0:>=.obj)
|
||||
PLINTHOBJ0 = $(PLINTH:<=w3i3mv\wi\)
|
||||
PLINTHOBJ = $(PLINTHOBJ0:>=.obj)
|
||||
<<<<<<< /u/ldisk2/gavinm/mmtrunk/src/w3i3mv.nmk
|
||||
SWOBJ0 = $(SW:<=w3i3mv\wi\)
|
||||
SWOBJ = $(SWOBJ0:>=.obj)
|
||||
AMSOBJ0 = $(AMS:<=w3i3mv\wi\)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue