mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-04-27 08:43:40 -07:00
Merge changes from mmdevel_gens3
Copied from Perforce Change: 18374 ServerID: perforce.ravenbrook.com
This commit is contained in:
parent
6aa3dffe04
commit
c93ef229cf
15 changed files with 462 additions and 191 deletions
|
|
@ -1,12 +1,13 @@
|
|||
/* impl.c.action: STRATEGIC ACTION
|
||||
*
|
||||
* Copyright (C) 1997 Harlequin Group, all rights reserved.
|
||||
* $HopeName: MMsrc!action.c(MMdevel_action2.3) $
|
||||
* $HopeName: MMsrc!action.c(trunk.2) $
|
||||
*/
|
||||
|
||||
#include "mpm.h"
|
||||
#include <float.h> /* @@@@ for DBL_MAX */
|
||||
|
||||
SRCID(action, "$HopeName: MMsrc!action.c(MMdevel_action2.3) $");
|
||||
SRCID(action, "$HopeName: MMsrc!action.c(trunk.2) $");
|
||||
|
||||
|
||||
/* ActionCheck -- check consistency of an Action structure */
|
||||
|
|
@ -57,44 +58,18 @@ void ActionFinish(Action action)
|
|||
|
||||
/* Noddy collection policy -- condemn first pool found */
|
||||
|
||||
static Res ActionCollect(Space space)
|
||||
static Res ActionCollect(Action action)
|
||||
{
|
||||
Ring ring, node;
|
||||
Trace trace;
|
||||
Res res;
|
||||
Pool pool;
|
||||
Space space;
|
||||
|
||||
ring = SpacePoolRing(space);
|
||||
node = RingNext(ring);
|
||||
while(node != ring) {
|
||||
Ring next = RingNext(node);
|
||||
space = PoolSpace(action->pool);
|
||||
|
||||
pool = RING_ELT(Pool, spaceRing, node);
|
||||
if((pool->class->attr & AttrGC) != 0)
|
||||
goto found;
|
||||
|
||||
node = next;
|
||||
}
|
||||
|
||||
/* No GC-able pool found. */
|
||||
return ResOK;
|
||||
|
||||
found:
|
||||
res = TraceCreate(&trace, space);
|
||||
if(res != ResOK) goto failTraceCreate;
|
||||
|
||||
res = TraceStart(trace, pool);
|
||||
if(res != ResOK) goto failStart;
|
||||
res = TraceCreate(&trace, space, action);
|
||||
if(res != ResOK) return res;
|
||||
|
||||
return ResOK;
|
||||
|
||||
failStart:
|
||||
/* .improve.undo-condemn: This is unsatisfactory as pools which
|
||||
* successfully completed a condemn aren't given a chance to
|
||||
* release any resources they may have allocated. */
|
||||
TraceDestroy(trace);
|
||||
failTraceCreate:
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -103,15 +78,39 @@ failTraceCreate:
|
|||
* This is the brain of the system. The function weighs up the
|
||||
* costs and benefits of the various actions exhibited by the pools,
|
||||
* and takes those which are worthwhile.
|
||||
*
|
||||
* @@@@ At the moment, it just launches a collection whenever it
|
||||
* can.
|
||||
*/
|
||||
|
||||
void ActionPoll(Space space)
|
||||
{
|
||||
Ring poolNode;
|
||||
double bestBenefit;
|
||||
Action bestAction;
|
||||
|
||||
AVERT(Space, space);
|
||||
|
||||
bestBenefit = -DBL_MAX;
|
||||
bestAction = NULL;
|
||||
|
||||
if(space->busyTraces == TraceSetEMPTY)
|
||||
(void)ActionCollect(space);
|
||||
RING_FOR(poolNode, &space->poolRing) {
|
||||
Pool pool = RING_ELT(Pool, spaceRing, poolNode);
|
||||
Ring actionNode;
|
||||
|
||||
RING_FOR(actionNode, &pool->actionRing) {
|
||||
Action action = RING_ELT(Action, poolRing, actionNode);
|
||||
double benefit;
|
||||
AVERT(Action, action);
|
||||
|
||||
benefit = PoolBenefit(action->pool, action);
|
||||
if(benefit >= bestBenefit) {
|
||||
bestBenefit = benefit;
|
||||
bestAction = action;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* @@@@ ignores failure */
|
||||
if(bestBenefit > 0) {
|
||||
AVER(bestAction != NULL);
|
||||
(void)ActionCollect(bestAction);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.amcss: POOL CLASS AMC STRESS TEST
|
||||
*
|
||||
* $HopeName: MMsrc!amcss.c(trunk.13) $
|
||||
* $HopeName: MMsrc!amcss.c(trunk.14) $
|
||||
* Copyright (C) 1996 Harlequin Group, all rights reserved
|
||||
*/
|
||||
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
#define NR_EXACT_ROOTS 50
|
||||
#define NR_AMBIG_ROOTS 50
|
||||
#define FIELDS_MAX 2000
|
||||
#define OBJECTS 40000
|
||||
#define COLLECTIONS 10
|
||||
#define OBJNULL ((mps_addr_t)0xDECEA5ED)
|
||||
|
||||
static mps_pool_t pool;
|
||||
|
|
@ -80,7 +80,7 @@ static void *test(void *arg, size_t s)
|
|||
|
||||
collections = 0;
|
||||
|
||||
for(i=0; i<OBJECTS; ++i) {
|
||||
while(collections < COLLECTIONS) {
|
||||
unsigned c;
|
||||
size_t r;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# ==== SECOND COMMON FRAGMENT FOR PLATFORMS USING MV AND NMAKE
|
||||
#
|
||||
# $HopeName: MMsrc!commpost.nmk(trunk.3) $
|
||||
# $HopeName: MMsrc!commpost.nmk(trunk.4) $
|
||||
# Copyright(C) 1997 Harlequin Group, all rights reserved
|
||||
#
|
||||
# DESCRIPTION
|
||||
|
|
@ -15,14 +15,14 @@
|
|||
|
||||
all: mpmss.exe amcss.exe dwstress.exe lockutnt.exe lockcov.exe \
|
||||
mpsicv.exe poolncv.exe locv.exe qs.exe mpm.lib weakcv.exe \
|
||||
mpmconft.exe finalcv.exe
|
||||
mpmconft.exe finalcv.exe awlut.exe
|
||||
|
||||
# Convenience targets
|
||||
# %%TARGET: Add a pseudo-target for the new part
|
||||
|
||||
dwstress.exe amcss.exe lockutnt.exe lockcov.exe \
|
||||
mpmss.exe protcv.exe mpsicv.exe poolncv.exe locv.exe qs.exe \
|
||||
weakcv.exe mpmconft.exe finalcv.exe \
|
||||
weakcv.exe mpmconft.exe finalcv.exe awlut.exe \
|
||||
mpm.lib mmdw.lib mmsw.lib poolawl.lib:
|
||||
!IFDEF VARIETY
|
||||
$(MAKE) /nologo /f $(PFM).nmk TARGET=$@ variety
|
||||
|
|
@ -113,6 +113,10 @@ $(PFM)\$(VARIETY)\poolncv.exe: $(PFM)\$(VARIETY)\poolncv.obj \
|
|||
$(PFM)\$(VARIETY)\locv.exe: $(PFM)\$(VARIETY)\locv.obj \
|
||||
$(MPMOBJ) $(PLINTHOBJ) $(TESTLIBOBJ) $(LOOBJ)
|
||||
|
||||
$(PFM)\$(VARIETY)\awlut.exe: $(PFM)\$(VARIETY)\awlut.obj \
|
||||
$(PFM)/$(VARIETY)/fmtdy.obj \
|
||||
$(MPMOBJ) $(PLINTHOBJ) $(TESTLIBOBJ) $(LOOBJ) $(AWLOBJ)
|
||||
|
||||
$(PFM)\$(VARIETY)\mpm.lib: $(MPMOBJ)
|
||||
$(ECHO) $@
|
||||
$(LIBMAN) $(LIBFLAGS) /OUT:$@ $**
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* impl.h.config: MPS CONFIGURATION
|
||||
*
|
||||
* Copyright (C) 1997 Harlequin Group, all rights reserved.
|
||||
* $HopeName: MMsrc!config.h(trunk.8) $
|
||||
* $HopeName: MMsrc!config.h(trunk.9) $
|
||||
*/
|
||||
|
||||
#ifndef config_h
|
||||
|
|
@ -79,12 +79,15 @@
|
|||
#elif defined(CONFIG_PROD_DYLAN)
|
||||
#define MPS_PROD_DYLAN
|
||||
#define ARENA_SIZE ((Size)1<<30)
|
||||
#define AMC_SIZE_LIMIT ((Size)64<<20) /* experimentally reasonable limit */
|
||||
#elif defined(CONFIG_PROD_MPS)
|
||||
#define MPS_PROD_MPS
|
||||
#ifdef MPS_OS_S7
|
||||
#define ARENA_SIZE ((Size)2<<20)
|
||||
#define AMC_SIZE_LIMIT ARENA_SIZE
|
||||
#else
|
||||
#define ARENA_SIZE ((Size)64<<20)
|
||||
#define AMC_SIZE_LIMIT ARENA_SIZE
|
||||
#endif /* MPS_OS_S7 */
|
||||
#else
|
||||
#error "No target product configured."
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.h.mpm: MEMORY POOL MANAGER DEFINITIONS
|
||||
*
|
||||
* $HopeName: MMsrc!mpm.h(trunk.30) $
|
||||
* $HopeName: MMsrc!mpm.h(trunk.31) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*/
|
||||
|
||||
|
|
@ -261,13 +261,16 @@ extern Res PoolCreateV(Pool *poolReturn, Space space,
|
|||
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 PoolCondemn(Pool pool, Trace trace, Seg seg);
|
||||
extern Res PoolTraceBegin(Pool pool, Trace trace, Action action);
|
||||
extern Res PoolCondemn(Pool pool, Trace trace, Seg seg, Action action);
|
||||
extern void PoolGrey(Pool pool, Trace trace, Seg seg);
|
||||
extern Res PoolScan(ScanState ss, Pool pool, Seg seg);
|
||||
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 void PoolTrivFinish(Pool pool);
|
||||
extern Res PoolNoAlloc(Addr *pReturn, Pool pool, Size size);
|
||||
|
|
@ -286,12 +289,17 @@ 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 PoolNoCondemn(Pool pool, Trace trace, Seg seg);
|
||||
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 void PoolNoGrey(Pool pool, Trace trace, Seg seg);
|
||||
extern void PoolTrivGrey(Pool pool, Trace trace, 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);
|
||||
|
||||
|
||||
/* Trace Interface -- see impl.c.trace */
|
||||
|
|
@ -315,15 +323,15 @@ extern Bool TraceIdCheck(TraceId id);
|
|||
extern Bool TraceSetCheck(TraceSet ts);
|
||||
extern Bool TraceCheck(Trace trace);
|
||||
|
||||
extern Res TraceCreate(Trace *traceReturn, Space space);
|
||||
extern Res TraceCreate(Trace *traceReturn, Space space, Action action);
|
||||
extern void TraceDestroy(Trace trace);
|
||||
extern Res TraceStart(Trace trace, Pool pool);
|
||||
extern Res TracePoll(Trace trace);
|
||||
extern void TraceAccess(Space space, Seg seg, AccessSet mode);
|
||||
|
||||
extern Res TraceFix(ScanState ss, Ref *refIO);
|
||||
extern void TraceSegGreyen(Space space, Seg seg, TraceSet ts);
|
||||
extern void TraceSetSummary(Space space, Seg seg, RefSet summary);
|
||||
extern Size TraceGreyEstimate(Space space, RefSet refSet);
|
||||
|
||||
/* Equivalent to impl.h.mps MPS_SCAN_BEGIN */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.h.mpmst: MEMORY POOL MANAGER DATA STRUCTURES
|
||||
*
|
||||
* $HopeName: MMsrc!mpmst.h(trunk.24) $
|
||||
* $HopeName: MMsrc!mpmst.h(trunk.25) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* .readership: MM developers.
|
||||
|
|
@ -92,11 +92,14 @@ typedef struct PoolClassStruct {
|
|||
PoolBufferFillMethod bufferFill;
|
||||
PoolBufferEmptyMethod bufferEmpty;
|
||||
PoolBufferFinishMethod bufferFinish;
|
||||
PoolTraceBeginMethod traceBegin;
|
||||
PoolCondemnMethod condemn; /* condemn (some or all) objects */
|
||||
PoolGreyMethod grey; /* grey non-white objects */
|
||||
PoolScanMethod scan; /* find references during tracing */
|
||||
PoolFixMethod fix; /* referent reachable during tracing */
|
||||
PoolReclaimMethod reclaim; /* reclaim dead objects after tracing */
|
||||
PoolTraceEndMethod traceEnd;
|
||||
PoolBenefitMethod benefit;
|
||||
PoolDescribeMethod describe; /* describe the contents of the pool */
|
||||
Sig endSig; /* .class.end-sig */
|
||||
} PoolClassStruct;
|
||||
|
|
@ -577,6 +580,7 @@ typedef struct TraceStruct {
|
|||
Sig sig; /* design.mps.sig */
|
||||
TraceId ti; /* index into TraceSets */
|
||||
Space space; /* owning space */
|
||||
Action action; /* the action that launched the trace */
|
||||
RefSet white; /* superset of refs in white set */
|
||||
TraceState state; /* current state of trace */
|
||||
Size interval; /* polling interval */
|
||||
|
|
@ -621,6 +625,7 @@ typedef struct SpaceStruct {
|
|||
Size pollThreshold; /* see impl.c.mpsi.poll and SpacePoll */
|
||||
Bool insidePoll; /* prevent recursive polling, see SpacePoll */
|
||||
Size actionInterval; /* see SpacePoll */
|
||||
double allocTime; /* "time" in allocated bytes */
|
||||
|
||||
/* arena fields (impl.c.arena*) */
|
||||
ArenaStruct arenaStruct; /* the arena */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.h.mpmtypes: MEMORY POOL MANAGER TYPES
|
||||
*
|
||||
* $HopeName: MMsrc!mpmtypes.h(trunk.23) $
|
||||
* $HopeName: MMsrc!mpmtypes.h(trunk.24) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* .readership: MM developers.
|
||||
|
|
@ -76,30 +76,29 @@ typedef struct ActionStruct *Action; /* design.mps.action */
|
|||
|
||||
/* Pool*Method -- see design.mps.class-interface */
|
||||
|
||||
typedef Res (*PoolInitMethod) (Pool pool, va_list arg);
|
||||
typedef void (*PoolFinishMethod) (Pool pool);
|
||||
typedef Res (*PoolAllocMethod) (Addr *pReturn, Pool pool,
|
||||
Size size);
|
||||
typedef void (*PoolFreeMethod) (Pool pool, Addr old, Size size);
|
||||
typedef Res (*PoolBufferInitMethod) (Pool pool, Buffer buf);
|
||||
typedef void (*PoolBufferFinishMethod) (Pool pool, Buffer buf);
|
||||
typedef Res (*PoolBufferFillMethod) (Seg *segReturn,
|
||||
Addr *baseReturn, Addr *limitReturn,
|
||||
Pool pool, Buffer buffer, Size size);
|
||||
typedef void (*PoolBufferEmptyMethod) (Pool pool, Buffer buffer);
|
||||
typedef Res (*PoolDescribeMethod) (Pool pool, mps_lib_FILE
|
||||
*stream);
|
||||
typedef Res (*PoolCondemnMethod) (Pool pool, Trace trace,
|
||||
Seg seg);
|
||||
typedef void (*PoolGreyMethod) (Pool pool, Trace trace,
|
||||
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 Res (*PoolInitMethod)(Pool pool, va_list arg);
|
||||
typedef void (*PoolFinishMethod)(Pool pool);
|
||||
typedef Res (*PoolAllocMethod)(Addr *pReturn, Pool pool, Size size);
|
||||
typedef void (*PoolFreeMethod)(Pool pool, Addr old, Size size);
|
||||
typedef Res (*PoolBufferInitMethod)(Pool pool, Buffer buf);
|
||||
typedef void (*PoolBufferFinishMethod)(Pool pool, Buffer buf);
|
||||
typedef Res (*PoolBufferFillMethod)(Seg *segReturn,
|
||||
Addr *baseReturn, Addr *limitReturn,
|
||||
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 void (*PoolGreyMethod)(Pool pool, Trace trace, 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);
|
||||
|
||||
|
||||
/* Format*Method -- see design.mps.format-interface */
|
||||
|
|
@ -247,20 +246,51 @@ typedef int WriteFC; /* Promoted */
|
|||
*/
|
||||
|
||||
/* EVent ... */
|
||||
#define EventEventTime ((EventType)0xEF213E99) /* TIME */
|
||||
#define EventSpaceCreate ((EventType)0xEF5BCC6E) /* SPaCe CREate */
|
||||
#define EventSpaceDestroy ((EventType)0xEF5BCDE5) /* SPaCe DEStroy */
|
||||
#define EventPoolInit ((EventType)0xEFB07141) /* POoL INIt */
|
||||
#define EventPoolFinish ((EventType)0xEFB07F14) /* POoL FINish */
|
||||
#define EventPoolAlloc ((EventType)0xEFB07A77) /* POoL ALLoc */
|
||||
#define EventPoolFree ((EventType)0xEFB07F6E) /* POoL FREe */
|
||||
#define EventArenaCreate ((EventType)0xEFA64C6E) /* AReNa CREate */
|
||||
#define EventArenaDestroy ((EventType)0xEFA64DE5) /* AReNa DEStroy */
|
||||
#define EventSegAlloc ((EventType)0xEF5E9A77) /* SEG ALLoc */
|
||||
#define EventSegFree ((EventType)0xEF5E9F6E) /* SEG FREe */
|
||||
#define EventVMCreate ((EventType)0xEFF3C6EA) /* VM CREAte */
|
||||
#define EventVMDestroy ((EventType)0xEFF3DE52) /* VM DESTroy */
|
||||
#define EventVMMap ((EventType)0xEFF33AB9) /* VM MAP */
|
||||
#define EventVMUnmap ((EventType)0xEFF3043B) /* VM UNMaP */
|
||||
#define EventEventTime ((EventType)0xEF213E99) /* TIME */
|
||||
#define EventSpaceCreate ((EventType)0xEF5BCC6E) /* SPaCe CREate */
|
||||
#define EventSpaceDestroy ((EventType)0xEF5BCDE5) /* SPaCe DEStroy */
|
||||
#define EventPoolInit ((EventType)0xEFB07141) /* POoL INIt */
|
||||
#define EventPoolFinish ((EventType)0xEFB07F14) /* POoL FINish */
|
||||
#define EventPoolAlloc ((EventType)0xEFB07A77) /* POoL ALLoc */
|
||||
#define EventPoolFree ((EventType)0xEFB07F6E) /* POoL FREe */
|
||||
#define EventArenaCreate ((EventType)0xEFA64C6E) /* AReNa CREate */
|
||||
#define EventArenaDestroy ((EventType)0xEFA64DE5) /* AReNa DEStroy */
|
||||
#define EventSegAlloc ((EventType)0xEF5E9A77) /* SEG ALLoc */
|
||||
#define EventSegFree ((EventType)0xEF5E9F6E) /* SEG FREe */
|
||||
#define EventAMCGenCreate ((EventType)0xEFA3C94C) /* AMC GeN Create */
|
||||
#define EventAMCGenDestroy ((EventType)0xEFA3C94D) /* AMC GeN Destroy */
|
||||
#define EventAMCInit ((EventType)0xEFA3C141) /* AMC INIt */
|
||||
#define EventAMCFinish ((EventType)0xEFA3CF14) /* AMC FINish */
|
||||
#define EventAMCBufferInit ((EventType)0xEFA3CBF1) /* AMC BuFfer Init */
|
||||
#define EventAMCBufferFill ((EventType)0xEFA3CBFF) /* AMC BuFfer Fill */
|
||||
#define EventAMCBufferEmpty ((EventType)0xEFA3CBFE) /* AMC BuFfer Empty */
|
||||
#define EventAMCTraceBegin ((EventType)0xEFA3C26B) /* AMC TRace Begin */
|
||||
#define EventAMCCondemn ((EventType)0xEFA3CC04) /* AMC CONdemn */
|
||||
#define EventAMCScanBegin ((EventType)0xEFA3C5CB) /* AMC SCan Begin */
|
||||
#define EventAMCScanEnd ((EventType)0xEFA3C5CE) /* AMC SCan End */
|
||||
#define EventAMCFix ((EventType)0xEFA3CF18) /* AMC FIX */
|
||||
#define EventAMCFixAmbig ((EventType)0xEFA3CF8A) /* AMC FiX Ambig */
|
||||
#define EventAMCFixForward ((EventType)0xEFA3CF8F) /* AMC FiX Forward */
|
||||
#define EventAMCReclaim ((EventType)0xEFA3C6EC) /* AMC REClaim */
|
||||
#define EventAMCTraceEnd ((EventType)0xEFA3C26E) /* AMC TRace End */
|
||||
#define EventTraceStart ((EventType)0xEF26AC52) /* TRACe STart */
|
||||
#define EventTraceCreate ((EventType)0xEF26ACC6) /* TRACe CReate */
|
||||
#define EventTraceDestroy ((EventType)0xEF26ACDE) /* TRACe DEstroy */
|
||||
#define EventTraceSegGreyen ((EventType)0xEF26A599) /* TRAce SeG Greyen */
|
||||
#define EventTraceFlipBegin ((EventType)0xEF26AF7B) /* TRAce FLip Begin */
|
||||
#define EventTraceFlipEnd ((EventType)0xEF26AF7E) /* TRAce FLip End */
|
||||
#define EventTraceReclaim ((EventType)0xEF26A6EC) /* TRAce REClaim */
|
||||
#define EventTraceScan ((EventType)0xEF26AC5C) /* TRACe SCan */
|
||||
#define EventTraceAccess ((EventType)0xEF26AACC) /* TRAce ACCess */
|
||||
#define EventTracePoll ((EventType)0xEF26AB01) /* TRAce POLl */
|
||||
#define EventTraceFix ((EventType)0xEF26AF18) /* TRAce FIX */
|
||||
#define EventTraceFixSeg ((EventType)0xEF26AF85) /* TRAce FiX Seg */
|
||||
#define EventTraceFixWhite ((EventType)0xEF26AF83) /* TRAce FiX White */
|
||||
#define EventTraceScanArea ((EventType)0xEF26A5CA) /* TRAce SCan Area */
|
||||
#define EventTraceScanAreaTagged ((EventType)0xEF26A5C2) /* TRAce SCan area Tagged */
|
||||
#define EventVMCreate ((EventType)0xEFF3C6EA) /* VM CREAte */
|
||||
#define EventVMDestroy ((EventType)0xEFF3DE52) /* VM DESTroy */
|
||||
#define EventVMMap ((EventType)0xEFF33AB9) /* VM MAP */
|
||||
#define EventVMUnmap ((EventType)0xEFF3043B) /* VM UNMaP */
|
||||
|
||||
#endif /* mpmtypes_h */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.pool: POOL IMPLEMENTATION
|
||||
*
|
||||
* $HopeName: MMsrc!pool.c(trunk.28) $
|
||||
* $HopeName: MMsrc!pool.c(trunk.29) $
|
||||
* 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.28) $");
|
||||
SRCID(pool, "$HopeName: MMsrc!pool.c(trunk.29) $");
|
||||
|
||||
|
||||
Bool PoolClassCheck(PoolClass class)
|
||||
|
|
@ -32,11 +32,14 @@ Bool PoolClassCheck(PoolClass class)
|
|||
CHECKL(FUNCHECK(class->bufferFill));
|
||||
CHECKL(FUNCHECK(class->bufferEmpty));
|
||||
CHECKL(FUNCHECK(class->bufferFinish));
|
||||
CHECKL(FUNCHECK(class->traceBegin));
|
||||
CHECKL(FUNCHECK(class->condemn));
|
||||
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->describe));
|
||||
CHECKL(class->endSig == PoolClassSig);
|
||||
return TRUE;
|
||||
|
|
@ -247,14 +250,26 @@ void PoolFree(Pool pool, Addr old, Size size)
|
|||
EVENT3(PoolFree, (Word)pool, (Word)old, (Word)size);
|
||||
}
|
||||
|
||||
Res PoolCondemn(Pool pool, Trace trace, Seg seg)
|
||||
Res PoolTraceBegin(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->space == trace->space);
|
||||
return (*pool->class->traceBegin)(pool, trace, action);
|
||||
}
|
||||
|
||||
Res PoolCondemn(Pool pool, Trace trace, Seg seg, Action action)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Seg, seg);
|
||||
AVERT(Action, action);
|
||||
AVER(pool->space == trace->space);
|
||||
AVER(seg->pool == pool);
|
||||
return (*pool->class->condemn)(pool, trace, seg);
|
||||
return (*pool->class->condemn)(pool, trace, seg, action);
|
||||
}
|
||||
|
||||
void PoolGrey(Pool pool, Trace trace, Seg seg)
|
||||
|
|
@ -325,6 +340,26 @@ 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->space == trace->space);
|
||||
(*pool->class->traceEnd)(pool, trace, action);
|
||||
}
|
||||
|
||||
|
||||
double PoolBenefit(Pool pool, Action action)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Action, action);
|
||||
AVER(action->pool == pool);
|
||||
return (*pool->class->benefit)(pool, action);
|
||||
}
|
||||
|
||||
|
||||
Res PoolDescribe(Pool pool, mps_lib_FILE *stream)
|
||||
{
|
||||
|
|
@ -612,11 +647,35 @@ Res PoolTrivDescribe(Pool pool, mps_lib_FILE *stream)
|
|||
return WriteF(stream, " No class-specific description available.\n", NULL);
|
||||
}
|
||||
|
||||
Res PoolNoCondemn(Pool pool, Trace trace, Seg seg)
|
||||
Res PoolNoTraceBegin(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->space == trace->space);
|
||||
NOTREACHED;
|
||||
return ResUNIMPL;
|
||||
}
|
||||
|
||||
Res PoolTrivTraceBegin(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->space == trace->space);
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
Res PoolNoCondemn(Pool pool, Trace trace, Seg seg, Action action)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Seg, seg);
|
||||
AVERT(Action, action);
|
||||
NOTREACHED;
|
||||
return ResUNIMPL;
|
||||
}
|
||||
|
|
@ -675,3 +734,33 @@ void PoolNoReclaim(Pool pool, Trace trace, Seg seg)
|
|||
AVERT(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->space == trace->space);
|
||||
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->space == trace->space);
|
||||
}
|
||||
|
||||
double PoolNoBenefit(Pool pool, Action action)
|
||||
{
|
||||
AVERT(Pool, pool);
|
||||
AVERT(Action, action);
|
||||
AVER(action->pool == pool);
|
||||
NOTREACHED;
|
||||
return (double)0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.poolawl: AUTOMATIC WEAK LINKED POOL CLASS
|
||||
*
|
||||
* $HopeName: MMsrc!poolawl.c(trunk.3) $
|
||||
* $HopeName: MMsrc!poolawl.c(trunk.4) $
|
||||
* 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.3) $");
|
||||
SRCID(poolawl, "$HopeName: MMsrc!poolawl.c(trunk.4) $");
|
||||
|
||||
|
||||
#define AWLSig ((Sig)0x519b7a37) /* SIGPooLAWL */
|
||||
|
|
@ -26,6 +26,8 @@ typedef struct AWLStruct {
|
|||
PoolStruct poolStruct;
|
||||
Format format;
|
||||
Shift alignShift;
|
||||
ActionStruct actionStruct;
|
||||
double lastCollected;
|
||||
Sig sig;
|
||||
} AWLStruct, *AWL;
|
||||
|
||||
|
|
@ -50,6 +52,8 @@ static Bool AWLGroupCheck(AWLGroup group);
|
|||
#define PoolPoolAWL(pool) \
|
||||
PARENT(AWLStruct, poolStruct, (pool))
|
||||
|
||||
#define ActionAWL(action) PARENT(AWLStruct, actionStruct, action)
|
||||
|
||||
|
||||
static void AWLGroupDestroy(AWLGroup group)
|
||||
{
|
||||
|
|
@ -192,6 +196,8 @@ static Res AWLInit(Pool pool, va_list arg)
|
|||
AVERT(Format, format);
|
||||
awl->format = format;
|
||||
awl->alignShift = SizeLog2(pool->alignment);
|
||||
ActionInit(&awl->actionStruct, pool);
|
||||
awl->lastCollected = PoolSpace(pool)->allocTime;
|
||||
awl->sig = AWLSig;
|
||||
|
||||
AVERT(AWL, awl);
|
||||
|
|
@ -223,6 +229,7 @@ static void AWLFinish(Pool pool)
|
|||
AWLGroupDestroy(group);
|
||||
node = next;
|
||||
}
|
||||
ActionFinish(&awl->actionStruct);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -307,7 +314,7 @@ static void AWLBufferEmpty(Pool pool, Buffer buffer)
|
|||
}
|
||||
|
||||
|
||||
static Res AWLCondemn(Pool pool, Trace trace, Seg seg)
|
||||
static Res AWLCondemn(Pool pool, Trace trace, Seg seg, Action action)
|
||||
{
|
||||
Count bits;
|
||||
AWL awl;
|
||||
|
|
@ -322,13 +329,16 @@ static Res AWLCondemn(Pool pool, Trace trace, Seg seg)
|
|||
awl = PoolPoolAWL(pool);
|
||||
AVERT(AWL, awl);
|
||||
|
||||
AVERT(Action, action);
|
||||
AVER(awl == ActionAWL(action));
|
||||
|
||||
group = (AWLGroup)seg->p;
|
||||
AVERT(AWLGroup, group);
|
||||
bits = SegSize(PoolSpace(pool), seg) >> awl->alignShift;
|
||||
|
||||
|
||||
BTResRange(group->mark, 0, bits);
|
||||
seg->white = TraceSetAdd(seg->white, trace->ti);
|
||||
|
||||
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
|
|
@ -566,6 +576,40 @@ static void AWLReclaim(Pool pool, Trace trace, Seg seg)
|
|||
BTResRange(group->mark, 0, bits);
|
||||
}
|
||||
|
||||
static Res AWLTraceBegin(Pool pool, Trace trace, Action action)
|
||||
{
|
||||
AWL awl;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
awl = PoolPoolAWL(pool);
|
||||
AVERT(AWL, awl);
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Action, action);
|
||||
AVER(awl == ActionAWL(action));
|
||||
|
||||
awl->lastCollected = PoolSpace(pool)->allocTime;
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
/* @@@@ completely made-up benefit calculation: each AWL pool gradually
|
||||
* becomes a better candidate for collection as allocation goes
|
||||
* by. Starting a trace on a pool makes it a bad candidate. nickb
|
||||
* 1997-06-19 */
|
||||
|
||||
static double AWLBenefit(Pool pool, Action action)
|
||||
{
|
||||
AWL awl;
|
||||
|
||||
AVERT(Pool, pool);
|
||||
awl = PoolPoolAWL(pool);
|
||||
AVERT(AWL, awl);
|
||||
AVERT(Action, action);
|
||||
AVER(awl == ActionAWL(action));
|
||||
|
||||
return (PoolSpace(pool)->allocTime - awl->lastCollected) - 10*1024*1024.0;
|
||||
}
|
||||
|
||||
|
||||
struct PoolClassStruct PoolClassAWLStruct = {
|
||||
PoolClassSig,
|
||||
"AWL",
|
||||
|
|
@ -580,11 +624,14 @@ struct PoolClassStruct PoolClassAWLStruct = {
|
|||
AWLBufferFill,
|
||||
AWLBufferEmpty,
|
||||
PoolTrivBufferFinish,
|
||||
AWLTraceBegin,
|
||||
AWLCondemn,
|
||||
AWLGrey,
|
||||
AWLScan,
|
||||
AWLFix,
|
||||
AWLReclaim,
|
||||
PoolTrivTraceEnd,
|
||||
AWLBenefit,
|
||||
PoolTrivDescribe,
|
||||
PoolClassSig
|
||||
};
|
||||
|
|
@ -602,6 +649,8 @@ static Bool AWLCheck(AWL awl)
|
|||
CHECKD(Pool, &awl->poolStruct);
|
||||
CHECKL(awl->poolStruct.class == &PoolClassAWLStruct);
|
||||
CHECKL(1uL << awl->alignShift == awl->poolStruct.alignment);
|
||||
CHECKD(Action, &awl->actionStruct);
|
||||
CHECKL(awl->poolStruct.space->allocTime >= awl->lastCollected);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.poolmfs: MANUAL FIXED SMALL UNIT POOL
|
||||
*
|
||||
* $HopeName: MMsrc!poolmfs.c(MMdevel_bufferscan.2) $
|
||||
* $HopeName: MMsrc!poolmfs.c(trunk.18) $
|
||||
* 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(MMdevel_bufferscan.2) $");
|
||||
SRCID(poolmfs, "$HopeName: MMsrc!poolmfs.c(trunk.18) $");
|
||||
|
||||
|
||||
/* == Round up ==
|
||||
|
|
@ -275,11 +275,14 @@ static PoolClassStruct PoolClassMFSStruct = {
|
|||
PoolNoBufferFill, /* bufferFill */
|
||||
PoolNoBufferEmpty, /* bufferEmpty */
|
||||
PoolNoBufferFinish, /* bufferFinish */
|
||||
PoolNoTraceBegin, /* traceBegin */
|
||||
PoolNoCondemn, /* condemn */
|
||||
PoolNoGrey, /* grey */
|
||||
PoolNoScan, /* scan */
|
||||
PoolNoFix, /* fix */
|
||||
PoolNoReclaim, /* reclaim */
|
||||
PoolNoTraceEnd, /* traceEnd */
|
||||
PoolNoBenefit, /* benefit */
|
||||
MFSDescribe, /* describe */
|
||||
PoolClassSig /* impl.h.mpmst.class.end-sig */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* MANUAL RANK GUARDIAN POOL
|
||||
*
|
||||
* $HopeName: MMsrc!poolmrg.c(MMdevel_bufferscan.2) $
|
||||
* $HopeName: MMsrc!poolmrg.c(trunk.9) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*
|
||||
* READERSHIP
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
#include "mpm.h"
|
||||
#include "poolmrg.h"
|
||||
|
||||
SRCID(poolmrg, "$HopeName: MMsrc!poolmrg.c(MMdevel_bufferscan.2) $");
|
||||
SRCID(poolmrg, "$HopeName: MMsrc!poolmrg.c(trunk.9) $");
|
||||
|
||||
|
||||
#define MRGSig ((Sig)0x519369B0) /* SIGnature MRG POol */
|
||||
|
|
@ -415,11 +415,14 @@ static PoolClassStruct PoolClassMRGStruct = {
|
|||
PoolNoBufferFill, /* bufferFill */
|
||||
PoolNoBufferEmpty, /* bufferEmpty */
|
||||
PoolNoBufferFinish, /* bufferFinish */
|
||||
PoolNoTraceBegin, /* traceBegin */
|
||||
PoolNoCondemn, /* condemn */
|
||||
PoolTrivGrey, /* grey */
|
||||
MRGScan, /* scan */
|
||||
PoolNoFix, /* fix */
|
||||
PoolNoReclaim, /* reclaim */
|
||||
PoolNoTraceEnd, /* traceEnd */
|
||||
PoolNoBenefit, /* benefit */
|
||||
MRGDescribe, /* describe */
|
||||
PoolClassSig /* impl.h.mpmst.class.end-sig */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.poolmv: MANUAL VARIABLE POOL
|
||||
*
|
||||
* $HopeName: MMsrc!poolmv.c(MMdevel_bufferscan.2) $
|
||||
* $HopeName: MMsrc!poolmv.c(trunk.20) $
|
||||
* 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.19) $");
|
||||
SRCID(poolmv, "$HopeName: MMsrc!poolmv.c(trunk.20) $");
|
||||
|
||||
|
||||
#define BLOCKPOOL(mv) (MFSPool(&(mv)->blockPoolStruct))
|
||||
|
|
@ -619,11 +619,14 @@ static PoolClassStruct PoolClassMVStruct = {
|
|||
PoolTrivBufferFill, /* bufferFill */
|
||||
PoolTrivBufferEmpty, /* bufferEmpty */
|
||||
PoolTrivBufferFinish, /* bufferFinish */
|
||||
PoolNoTraceBegin, /* traceBegin */
|
||||
PoolNoCondemn, /* condemn */
|
||||
PoolNoGrey, /* mark */
|
||||
PoolNoScan, /* scan */
|
||||
PoolNoFix, /* fix */
|
||||
PoolNoReclaim, /* relcaim */
|
||||
PoolNoTraceEnd, /* traceEnd */
|
||||
PoolNoBenefit, /* benefit */
|
||||
MVDescribe, /* describe */
|
||||
PoolClassSig /* impl.h.mpmst.class.end-sig */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.pooln: NULL POOL
|
||||
*
|
||||
* $HopeName: MMsrc!pooln.c(MMdevel_bufferscan.2) $
|
||||
* $HopeName: MMsrc!pooln.c(trunk.12) $
|
||||
* 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(MMdevel_bufferscan.2) $");
|
||||
SRCID(pooln, "$HopeName: MMsrc!pooln.c(trunk.12) $");
|
||||
|
||||
|
||||
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)
|
||||
static Res NCondemn(Pool pool, Trace trace, Seg seg, Action action)
|
||||
{
|
||||
PoolN poolN;
|
||||
|
||||
|
|
@ -158,8 +158,11 @@ static Res NCondemn(Pool pool, Trace trace, Seg seg)
|
|||
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Seg, seg);
|
||||
AVERT(Action, action);
|
||||
|
||||
NOTREACHED; /* pool doesn't have any actions */
|
||||
|
||||
return ResOK;
|
||||
return ResUNIMPL;
|
||||
}
|
||||
|
||||
static void NGrey(Pool pool, Trace trace, Seg seg)
|
||||
|
|
@ -231,11 +234,14 @@ static PoolClassStruct PoolClassNStruct = {
|
|||
NBufferFill, /* bufferFill */
|
||||
NBufferEmpty, /* bufferEmpty */
|
||||
NBufferFinish, /* bufferFinish */
|
||||
PoolNoTraceBegin, /* traceBegin */
|
||||
NCondemn, /* condemn */
|
||||
NGrey, /* grey */
|
||||
NScan, /* scan */
|
||||
NFix, /* fix */
|
||||
NReclaim, /* reclaim */
|
||||
PoolNoTraceEnd, /* traceEnd */
|
||||
PoolNoBenefit, /* benefit */
|
||||
NDescribe, /* describe */
|
||||
PoolClassSig /* impl.h.mpmst.class.end-sig */
|
||||
};
|
||||
|
|
|
|||
218
mps/src/trace.c
218
mps/src/trace.c
|
|
@ -1,12 +1,12 @@
|
|||
/* impl.c.trace: GENERIC TRACER IMPLEMENTATION
|
||||
*
|
||||
* $HopeName: MMsrc!trace.c(trunk.25) $
|
||||
* $HopeName: MMsrc!trace.c(trunk.26) $
|
||||
* Copyright (C) 1997 The Harlequin Group Limited. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "mpm.h"
|
||||
|
||||
SRCID(trace, "$HopeName: MMsrc!trace.c(trunk.25) $");
|
||||
SRCID(trace, "$HopeName: MMsrc!trace.c(trunk.26) $");
|
||||
|
||||
|
||||
/* ScanStateCheck -- check consistency of a ScanState object */
|
||||
|
|
@ -94,78 +94,6 @@ Bool TraceCheck(Trace trace)
|
|||
}
|
||||
|
||||
|
||||
/* TraceCreate -- create a Trace object
|
||||
*
|
||||
* Allocates and initializes a new Trace object with a TraceId
|
||||
* which is not currently active.
|
||||
*
|
||||
* Returns ResLIMIT if there aren't any available trace IDs.
|
||||
*
|
||||
* Trace objects are allocated directly from a small array in the
|
||||
* space structure which is indexed by the TraceId. This is so
|
||||
* that it's always possible to start a trace (provided there's
|
||||
* a free TraceId) even if there's no available memory.
|
||||
*
|
||||
* This code is written to be adaptable to allocating Trace
|
||||
* objects dynamically.
|
||||
*/
|
||||
|
||||
Res TraceCreate(Trace *traceReturn, Space space)
|
||||
{
|
||||
TraceId ti;
|
||||
Trace trace;
|
||||
|
||||
AVER(TRACE_MAX == 1); /* .single-collection */
|
||||
|
||||
AVER(traceReturn != NULL);
|
||||
AVERT(Space, space);
|
||||
|
||||
/* Find a free trace ID */
|
||||
for(ti = 0; ti < TRACE_MAX; ++ti)
|
||||
if(!TraceSetIsMember(space->busyTraces, ti))
|
||||
goto found;
|
||||
|
||||
return ResLIMIT; /* no trace IDs available */
|
||||
|
||||
found:
|
||||
trace = SpaceTrace(space, ti);
|
||||
space->busyTraces = TraceSetAdd(space->busyTraces, ti);
|
||||
|
||||
trace->space = space;
|
||||
trace->white = RefSetEMPTY;
|
||||
trace->ti = ti;
|
||||
trace->state = TraceINIT;
|
||||
trace->interval = (Size)4096; /* @@@@ should be progress control */
|
||||
|
||||
trace->sig = TraceSig;
|
||||
AVERT(Trace, trace);
|
||||
|
||||
*traceReturn = trace;
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
|
||||
/* TraceDestroy -- destroy a trace object
|
||||
*
|
||||
* Finish and deallocate a Trace object, freeing up a TraceId.
|
||||
*
|
||||
* This code does not allow a Trace to be destroyed while it is
|
||||
* active. It would be possible to allow this, but the colours
|
||||
* of segments etc. would need to be reset to black.
|
||||
*/
|
||||
|
||||
void TraceDestroy(Trace trace)
|
||||
{
|
||||
AVERT(Trace, trace);
|
||||
AVER(trace->state == TraceFINISHED);
|
||||
trace->sig = SigInvalid;
|
||||
trace->space->busyTraces =
|
||||
TraceSetDel(trace->space->busyTraces, trace->ti);
|
||||
trace->space->flippedTraces =
|
||||
TraceSetDel(trace->space->flippedTraces, trace->ti);
|
||||
}
|
||||
|
||||
|
||||
/* TraceStart -- condemn a set of objects and start collection
|
||||
*
|
||||
* TraceStart should be passed a trace with state TraceINIT, i.e.
|
||||
|
|
@ -177,21 +105,25 @@ void TraceDestroy(Trace trace)
|
|||
* it easy to destroy traces half-way through.
|
||||
*/
|
||||
|
||||
Res TraceStart(Trace trace, Pool pool)
|
||||
static Res TraceStart(Trace trace, Action action)
|
||||
{
|
||||
Res res;
|
||||
Ring ring, node;
|
||||
Space space;
|
||||
Seg seg;
|
||||
Pool pool;
|
||||
|
||||
AVERT(Trace, trace);
|
||||
AVERT(Pool, pool);
|
||||
AVER((pool->class->attr & AttrGC) != 0);
|
||||
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. */
|
||||
space = trace->space;
|
||||
pool = action->pool;
|
||||
|
||||
EVENT3(TraceStart, trace, pool, action);
|
||||
ring = PoolSegRing(pool);
|
||||
node = RingNext(ring);
|
||||
while(node != ring) {
|
||||
|
|
@ -202,7 +134,7 @@ Res TraceStart(Trace trace, Pool pool)
|
|||
|
||||
/* Give the pool the opportunity to turn the segment white. */
|
||||
/* If it fails, unwind. */
|
||||
res = PoolCondemn(pool, trace, seg);
|
||||
res = PoolCondemn(pool, trace, seg, action);
|
||||
if(res != ResOK) goto failCondemn;
|
||||
|
||||
/* Add the segment to the approximation of the white set the */
|
||||
|
|
@ -289,6 +221,99 @@ failCondemn:
|
|||
}
|
||||
|
||||
|
||||
/* TraceCreate -- create a Trace object
|
||||
*
|
||||
* Allocates and initializes a new Trace object with a TraceId
|
||||
* which is not currently active.
|
||||
*
|
||||
* Returns ResLIMIT if there aren't any available trace IDs.
|
||||
*
|
||||
* Trace objects are allocated directly from a small array in the
|
||||
* space structure which is indexed by the TraceId. This is so
|
||||
* that it's always possible to start a trace (provided there's
|
||||
* a free TraceId) even if there's no available memory.
|
||||
*
|
||||
* This code is written to be adaptable to allocating Trace
|
||||
* objects dynamically.
|
||||
*/
|
||||
|
||||
Res TraceCreate(Trace *traceReturn, Space space, Action action)
|
||||
{
|
||||
TraceId ti;
|
||||
Trace trace;
|
||||
Res res;
|
||||
|
||||
AVER(TRACE_MAX == 1); /* .single-collection */
|
||||
|
||||
AVER(traceReturn != NULL);
|
||||
AVERT(Space, space);
|
||||
AVERT(Action, action);
|
||||
|
||||
/* Find a free trace ID */
|
||||
for(ti = 0; ti < TRACE_MAX; ++ti)
|
||||
if(!TraceSetIsMember(space->busyTraces, ti))
|
||||
goto found;
|
||||
|
||||
return ResLIMIT; /* no trace IDs available */
|
||||
|
||||
found:
|
||||
trace = SpaceTrace(space, ti);
|
||||
space->busyTraces = TraceSetAdd(space->busyTraces, ti);
|
||||
|
||||
trace->space = space;
|
||||
trace->action = action;
|
||||
trace->white = RefSetEMPTY;
|
||||
trace->ti = ti;
|
||||
trace->state = TraceINIT;
|
||||
trace->interval = (Size)4096; /* @@@@ should be progress control */
|
||||
|
||||
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;
|
||||
EVENT4(TraceCreate, space, action, trace, ti);
|
||||
return ResOK;
|
||||
|
||||
failStart:
|
||||
PoolTraceEnd(action->pool, trace, action);
|
||||
failBegin:
|
||||
trace->sig = SigInvalid;
|
||||
space->busyTraces = TraceSetDel(space->busyTraces, ti);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* TraceDestroy -- destroy a trace object
|
||||
*
|
||||
* Finish and deallocate a Trace object, freeing up a TraceId.
|
||||
*
|
||||
* This code does not allow a Trace to be destroyed while it is
|
||||
* active. It would be possible to allow this, but the colours
|
||||
* of segments etc. would need to be reset to black.
|
||||
*/
|
||||
|
||||
void TraceDestroy(Trace trace)
|
||||
{
|
||||
AVERT(Trace, trace);
|
||||
AVER(trace->state == TraceFINISHED);
|
||||
|
||||
PoolTraceEnd(trace->action->pool, trace, trace->action);
|
||||
|
||||
trace->sig = SigInvalid;
|
||||
trace->space->busyTraces =
|
||||
TraceSetDel(trace->space->busyTraces, trace->ti);
|
||||
trace->space->flippedTraces =
|
||||
TraceSetDel(trace->space->flippedTraces, trace->ti);
|
||||
EVENT1(TraceDestroy, trace);
|
||||
}
|
||||
|
||||
|
||||
/* TraceSetGreyen -- turn a segment more grey
|
||||
*
|
||||
* Adds the trace set ts to the greyness of the segment and adjusts
|
||||
|
|
@ -311,6 +336,7 @@ void TraceSegGreyen(Space space, Seg seg, TraceSet ts)
|
|||
TraceSetInter(grey, space->flippedTraces) != TraceSetEMPTY)
|
||||
ShieldRaise(space, seg, AccessREAD);
|
||||
seg->grey = grey;
|
||||
EVENT3(TraceSegGreyen, space, seg, ts);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -395,6 +421,8 @@ static Res TraceFlip(Trace trace)
|
|||
|
||||
AVER(trace->state == TraceUNFLIPPED);
|
||||
|
||||
EVENT2(TraceFlipBegin, trace, space);
|
||||
|
||||
TraceFlipBuffers(space);
|
||||
|
||||
/* Update location dependency structures. white is */
|
||||
|
|
@ -453,6 +481,8 @@ static Res TraceFlip(Trace trace)
|
|||
|
||||
ss.sig = SigInvalid; /* just in case */
|
||||
|
||||
EVENT2(TraceFlipEnd, trace, space);
|
||||
|
||||
ShieldResume(space);
|
||||
|
||||
return ResOK;
|
||||
|
|
@ -467,6 +497,8 @@ static void TraceReclaim(Trace trace)
|
|||
AVERT(Trace, trace);
|
||||
AVER(trace->state == TraceRECLAIM);
|
||||
|
||||
|
||||
EVENT1(TraceReclaim, trace);
|
||||
space = trace->space;
|
||||
if(SegFirst(&seg, space)) {
|
||||
Addr base;
|
||||
|
|
@ -552,6 +584,8 @@ static Res TraceScan(TraceSet ts, Rank rank,
|
|||
/* The reason for scanning a segment is that it's grey. */
|
||||
AVER(TraceSetInter(ts, seg->grey) != TraceSetEMPTY);
|
||||
|
||||
EVENT5(TraceScan, ts, rank, space, seg, &ss);
|
||||
|
||||
ss.rank = rank;
|
||||
ss.traces = ts;
|
||||
ss.fix = TraceFix;
|
||||
|
|
@ -608,6 +642,8 @@ void TraceAccess(Space space, Seg seg, AccessSet mode)
|
|||
AVERT(Seg, seg);
|
||||
UNUSED(mode);
|
||||
|
||||
EVENT3(TraceAccess, space, seg, mode);
|
||||
|
||||
if((mode & seg->sm & AccessREAD) != 0) { /* read barrier? */
|
||||
/* In this case, the segment must be grey for a trace which is */
|
||||
/* flipped. */
|
||||
|
|
@ -675,6 +711,8 @@ Res TracePoll(Trace trace)
|
|||
|
||||
space = trace->space;
|
||||
|
||||
EVENT2(TracePoll, trace, space);
|
||||
|
||||
switch(trace->state) {
|
||||
case TraceUNFLIPPED: {
|
||||
res = TraceFlip(trace);
|
||||
|
|
@ -704,6 +742,23 @@ Res TracePoll(Trace trace)
|
|||
}
|
||||
|
||||
|
||||
/* TraceGreyEstimate -- estimate amount of grey stuff
|
||||
*
|
||||
* This function returns an estimate of the total size (in bytes)
|
||||
* of objects which would need to be scanned in order to find
|
||||
* all references to a certain RefSet.
|
||||
*
|
||||
* @@@@ This currently assumes that it's everything in the world.
|
||||
* @@@@ Should factor in the size of the roots, especially if the stack
|
||||
* is currently very deep.
|
||||
*/
|
||||
|
||||
Size TraceGreyEstimate(Space space, RefSet refSet)
|
||||
{
|
||||
return ArenaCommitted(space);
|
||||
}
|
||||
|
||||
|
||||
Res TraceFix(ScanState ss, Ref *refIO)
|
||||
{
|
||||
Ref ref;
|
||||
|
|
@ -714,8 +769,11 @@ Res TraceFix(ScanState ss, Ref *refIO)
|
|||
AVER(refIO != NULL);
|
||||
|
||||
ref = *refIO;
|
||||
EVENT4(TraceFix, ss, refIO, ref, ss->rank);
|
||||
if(SegOfAddr(&seg, ss->space, ref)) {
|
||||
EVENT1(TraceFixSeg, seg);
|
||||
if(TraceSetInter(seg->white, ss->traces) != TraceSetEMPTY) {
|
||||
EVENT0(TraceFixWhite);
|
||||
pool = seg->pool;
|
||||
return PoolFix(pool, ss, seg, refIO);
|
||||
}
|
||||
|
|
@ -744,6 +802,8 @@ Res TraceScanArea(ScanState ss, Addr *base, Addr *limit)
|
|||
AVER(limit != NULL);
|
||||
AVER(base < limit);
|
||||
|
||||
EVENT3(TraceScanArea, ss, base, limit);
|
||||
|
||||
TRACE_SCAN_BEGIN(ss) {
|
||||
p = base;
|
||||
loop:
|
||||
|
|
@ -790,6 +850,8 @@ Res TraceScanAreaMasked(ScanState ss, Addr *base, Addr *limit, Word mask)
|
|||
AVER(limit != NULL);
|
||||
AVER(base < limit);
|
||||
|
||||
EVENT3(TraceScanAreaTagged, ss, base, limit);
|
||||
|
||||
TRACE_SCAN_BEGIN(ss) {
|
||||
p = base;
|
||||
loop:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* impl.c.vmnt: VIRTUAL MEMORY MAPPING FOR WIN32
|
||||
*
|
||||
* $HopeName: MMsrc!vmnt.c(trunk.15) $
|
||||
* $HopeName: MMsrc!vmw3.c(trunk.17) $
|
||||
* Copyright (C) 1995 Harlequin Group, all rights reserved
|
||||
*
|
||||
* Design: design.mps.vm
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
|
||||
#include <windows.h>
|
||||
|
||||
SRCID(vmnt, "$HopeName: MMsrc!vmnt.c(trunk.15) $");
|
||||
SRCID(vmnt, "$HopeName: MMsrc!vmw3.c(trunk.17) $");
|
||||
|
||||
|
||||
#define SpaceVM(space) (&(space)->arenaStruct.vmStruct)
|
||||
|
|
@ -135,6 +135,8 @@ Res VMCreate(Space *spaceReturn, Size size, Addr base)
|
|||
|
||||
AVERT(VM, vm);
|
||||
|
||||
EVENT4(VMCreate, vm, space, vm->base, vm->limit);
|
||||
|
||||
*spaceReturn = space;
|
||||
return ResOK;
|
||||
}
|
||||
|
|
@ -159,6 +161,7 @@ void VMDestroy(Space space)
|
|||
|
||||
b = VirtualFree((LPVOID)space, (DWORD)0, MEM_RELEASE);
|
||||
AVER(b != 0);
|
||||
EVENT1(VMDestroy, vm);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -219,6 +222,8 @@ Res VMMap(Space space, Addr base, Addr limit)
|
|||
|
||||
vm->mapped += AddrOffset(base, limit);
|
||||
|
||||
EVENT3(VMMap, vm, base, limit);
|
||||
|
||||
return ResOK;
|
||||
}
|
||||
|
||||
|
|
@ -242,4 +247,6 @@ void VMUnmap(Space space, Addr base, Addr limit)
|
|||
b = VirtualFree((LPVOID)base, (DWORD)AddrOffset(base, limit), MEM_DECOMMIT);
|
||||
AVER(b != 0); /* .assume.free.success */
|
||||
vm->mapped -= AddrOffset(base, limit);
|
||||
|
||||
EVENT3(VMUnmap, vm, base, limit);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue