1
Fork 0
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:
Gavin Matthews 1997-09-18 16:49:33 +01:00
parent 30140d54dc
commit 2ee45a68c4
17 changed files with 429 additions and 248 deletions

View file

@ -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);
}
}

View file

@ -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.

View file

@ -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

View file

@ -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);

View file

@ -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 */

View file

@ -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.) */

View file

@ -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);

View file

@ -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 */

View file

@ -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;
}

View file

@ -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 */
};

View file

@ -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
};

View file

@ -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 */
};

View file

@ -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 */
};

View file

@ -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 */
};

View file

@ -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 */
};

View file

@ -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);

View file

@ -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\)