1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-04-27 08:43:40 -07:00

Mps br/timing: traceanc.c -- all this ancillary stuff was making

trace.c very cluttered.  Put it here instead.

Copied from Perforce
 Change: 166911
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Kistruck 2008-12-09 16:55:22 +00:00
parent 6c15ecf521
commit beb476fd52
7 changed files with 263 additions and 2622 deletions

View file

@ -195,17 +195,17 @@ PLINTH = mpsliban.c mpsioan.c
EVENTPROC = eventcnv.c eventpro.c table.c
MPMCOMMON = mpsi.c mpm.c arenavm.c arenacl.c arena.c global.c locus.c \
tract.c walk.c reserv.c protocol.c pool.c poolabs.c \
trace.c root.c seg.c format.c buffer.c ref.c bt.c ring.c \
shield.c ld.c event.c sac.c message.c \
trace.c traceanc.c root.c seg.c format.c buffer.c ref.c \
bt.c ring.c shield.c ld.c event.c sac.c message.c \
poolmrg.c poolmfs.c poolmv.c dbgpool.c dbgpooli.c \
boot.c meter.c splay.c cbs.c diag.c version.c
MPM = $(MPMCOMMON) $(MPMPF)
SWCOMMON = mpsi.c mpm.c arenavm.c arenacl.c arena.c global.c locus.c \
tract.c walk.c reserv.c protocol.c pool.c poolabs.c \
trace.c root.c seg.c format.c buffer.c ref.c bt.c ring.c \
shield.c ld.c event.c sac.c message.c \
poolmrg.c poolmfs.c poolmv.c dbgpool.c dbgpooli \
poolams.c poolamsi.c poolmvff.c \
trace.c traceanc.c root.c seg.c format.c buffer.c ref.c \
bt.c ring.c shield.c ld.c event.c sac.c message.c \
poolmrg.c poolmfs.c poolmv.c dbgpool.c dbgpooli \
poolams.c poolamsi.c poolmvff.c \
boot.c meter.c splay.c cbs.c version.c mpsioan.c
SW = $(SWCOMMON) $(SWPF)

View file

@ -379,6 +379,23 @@ extern void TraceSegAccess(Arena arena, Seg seg, AccessSet mode);
extern Res TraceFix(ScanState ss, Ref *refIO);
extern Res TraceFixEmergency(ScanState ss, Ref *refIO);
/* support for traceanc.c */
extern void traceQuantum(Trace trace);
extern Res traceStartCollectAll(Trace *traceReturn, Arena arena, int why);
/* traceanc.c -- Trace Ancillary */
/* trace begin */
extern Bool TraceStartMessageCheck(TraceStartMessage message);
extern void TraceStartMessageInit(Arena arena, TraceStartMessage tsMessage);
extern void traceStartWhyToTextBuffer(char *s, size_t len, int why);
#define TraceStartMessageMessage(traceStartMessage) \
(&((traceStartMessage)->messageStruct))
/* trace end */
extern Bool TraceMessageCheck(TraceMessage message); /* trace end */
extern void tracePostMessage(Trace trace);
/* Collection control parameters */

View file

@ -77,8 +77,6 @@ typedef PoolClass AbstractBufferPoolClass; /* <code/poolabs.c> */
typedef PoolClass AbstractSegBufPoolClass; /* <code/poolabs.c> */
typedef PoolClass AbstractScanPoolClass; /* <code/poolabs.c> */
typedef PoolClass AbstractCollectPoolClass; /* <code/poolabs.c> */
typedef struct TraceStartMessageStruct
*TraceStartMessage; /* <design/message-gc> */
typedef struct TraceStruct *Trace; /* <design/trace/> */
typedef struct ScanStateStruct *ScanState; /* <design/trace/> */
typedef struct ChainStruct *Chain; /* <design/trace/> */
@ -123,16 +121,6 @@ typedef void (*ArenaChunkFinishMethod)(Chunk chunk);
typedef Res (*ArenaDescribeMethod)(Arena arena, mps_lib_FILE *stream);
/* Messages
*
* See <design/message/>
*/
typedef unsigned MessageType;
typedef struct MessageStruct *Message;
typedef struct MessageClassStruct *MessageClass;
/* TraceFixMethod */
typedef Res (*TraceFixMethod)(ScanState ss, Ref *refIO);
@ -227,6 +215,15 @@ typedef Res (*PoolDescribeMethod)(Pool pool, mps_lib_FILE *stream);
typedef PoolDebugMixin (*PoolDebugMixinMethod)(Pool pool);
/* Messages
*
* See <design/message/>
*/
typedef unsigned MessageType;
typedef struct MessageStruct *Message;
typedef struct MessageClassStruct *MessageClass;
/* Message*Method -- <design/message/> */
typedef void (*MessageDeleteMethod)(Message message);
@ -237,10 +234,10 @@ typedef Size (*MessageGCCondemnedSizeMethod)(Message message);
typedef Size (*MessageGCNotCondemnedSizeMethod)(Message message);
typedef const char * (*MessageGCStartWhyMethod)(Message message);
/* Message Types -- <design/message/> and elsewhere */
typedef struct MessageFinalizationStruct *MessageFinalization;
typedef struct TraceStartMessageStruct *TraceStartMessage;
typedef struct TraceMessageStruct *TraceMessage; /* trace end */
/* Format*Method -- see design.mps.format-interface */
@ -428,7 +425,7 @@ enum {
enum {
MessageTypeFINALIZATION, /* MPS_MESSAGE_TYPE_FINALIZATION */
MessageTypeGC, /* MPS_MESSAGE_TYPE_GC */
MessageTypeGC, /* MPS_MESSAGE_TYPE_GC = trace end */
MessageTypeGCSTART, /* MPS_MESSAGE_TYPE_GC_START */
MessageTypeLIMIT /* not a message type, the limit of the enum. */
};

View file

@ -14,7 +14,6 @@
SRCID(trace, "$Id$");
/* Forward declarations */
static void TraceStartMessageInit(Arena arena, TraceStartMessage tsMessage);
Rank traceBand(Trace);
Bool traceBandAdvance(Trace);
Bool traceBandFirstStretch(Trace);
@ -30,278 +29,6 @@ enum {
};
typedef int traceAccountingPhase;
struct RememberedSummaryBlockStruct {
RingStruct globalRing; /* link on globals->rememberedSummaryRing */
struct SummaryPair {
Addr base;
RefSet summary;
} the[RememberedSummaryBLOCK];
};
/* Forward Declarations -- avoid compiler warning. */
Res arenaRememberSummaryOne(Globals global, Addr base, RefSet summary);
void arenaForgetProtection(Globals globals);
void rememberedSummaryBlockInit(struct RememberedSummaryBlockStruct *block);
/* TraceMessage -- type of GC end messages */
#define TraceMessageSig ((Sig)0x51926359)
typedef struct TraceMessageStruct {
Sig sig;
Size liveSize;
Size condemnedSize;
Size notCondemnedSize;
MessageStruct messageStruct;
} TraceMessageStruct, *TraceMessage;
#define TraceMessageMessage(traceMessage) (&((traceMessage)->messageStruct))
#define MessageTraceMessage(message) \
(PARENT(TraceMessageStruct, messageStruct, message))
static Bool TraceMessageCheck(TraceMessage message)
{
CHECKS(TraceMessage, message);
CHECKD(Message, TraceMessageMessage(message));
CHECKL(MessageGetType(TraceMessageMessage(message)) ==
MessageTypeGC);
/* We can't check anything about the statistics. In particular, */
/* liveSize may exceed condemnedSize because they are only estimates. */
return TRUE;
}
static void TraceMessageDelete(Message message)
{
TraceMessage tMessage;
Arena arena;
AVERT(Message, message);
tMessage = MessageTraceMessage(message);
AVERT(TraceMessage, tMessage);
arena = MessageArena(message);
ControlFree(arena, (void *)tMessage, sizeof(TraceMessageStruct));
}
static Size TraceMessageLiveSize(Message message)
{
TraceMessage tMessage;
AVERT(Message, message);
tMessage = MessageTraceMessage(message);
AVERT(TraceMessage, tMessage);
return tMessage->liveSize;
}
static Size TraceMessageCondemnedSize(Message message)
{
TraceMessage tMessage;
AVERT(Message, message);
tMessage = MessageTraceMessage(message);
AVERT(TraceMessage, tMessage);
return tMessage->condemnedSize;
}
static Size TraceMessageNotCondemnedSize(Message message)
{
TraceMessage tMessage;
AVERT(Message, message);
tMessage = MessageTraceMessage(message);
AVERT(TraceMessage, tMessage);
return tMessage->notCondemnedSize;
}
static MessageClassStruct TraceMessageClassStruct = {
MessageClassSig, /* sig */
"TraceGC", /* name */
MessageTypeGC, /* Message Type */
TraceMessageDelete, /* Delete */
MessageNoFinalizationRef, /* FinalizationRef */
TraceMessageLiveSize, /* GCLiveSize */
TraceMessageCondemnedSize, /* GCCondemnedSize */
TraceMessageNotCondemnedSize, /* GCNotCondemnedSize */
MessageNoGCStartWhy, /* GCStartWhy */
MessageClassSig /* <design/message/#class.sig.double> */
};
static void TraceMessageInit(Arena arena, TraceMessage tMessage)
{
AVERT(Arena, arena);
MessageInit(arena, TraceMessageMessage(tMessage),
&TraceMessageClassStruct, MessageTypeGC);
tMessage->liveSize = (Size)0;
tMessage->condemnedSize = (Size)0;
tMessage->notCondemnedSize = (Size)0;
tMessage->sig = TraceMessageSig;
AVERT(TraceMessage, tMessage);
}
/* TraceStartMessage - manages info needed by start of trace message
(mps_message_type_gc_start).
(structure declared in <code/mpmst.h> ) */
#define TraceStartMessageMessage(traceStartMessage) \
(&((traceStartMessage)->messageStruct))
#define MessageTraceStartMessage(message) \
(PARENT(TraceStartMessageStruct, messageStruct, message))
static Bool TraceStartMessageCheck(TraceStartMessage message)
{
size_t i;
CHECKS(TraceStartMessage, message);
CHECKD(Message, TraceStartMessageMessage(message));
CHECKL(MessageGetType(TraceStartMessageMessage(message)) ==
MessageTypeGCSTART);
/* Check that why is NUL terminated. */
for(i=0; i<NELEMS(message->why); ++i) {
if(message->why[i] == 0) {
break;
}
}
CHECKL(i<NELEMS(message->why));
return TRUE;
}
static void TraceStartMessageDelete(Message message)
{
TraceStartMessage tsMessage;
AVERT(Message, message);
tsMessage = MessageTraceStartMessage(message);
AVERT(TraceStartMessage, tsMessage);
TraceStartMessageInit(MessageArena(message), tsMessage);
return;
}
static const char *TraceStartMessageWhy(Message message)
{
TraceStartMessage tsMessage;
AVERT(Message, message);
tsMessage = MessageTraceStartMessage(message);
AVERT(TraceStartMessage, tsMessage);
return tsMessage->why;
}
static MessageClassStruct TraceStartMessageClassStruct = {
MessageClassSig, /* sig */
"TraceGCStart", /* name */
MessageTypeGCSTART, /* Message Type */
TraceStartMessageDelete, /* Delete */
MessageNoFinalizationRef, /* FinalizationRef */
MessageNoGCLiveSize, /* GCLiveSize */
MessageNoGCCondemnedSize, /* GCCondemnedSize */
MessageNoGCNotCondemnedSize, /* GCNotCondemnedSize */
TraceStartMessageWhy, /* GCStartWhy */
MessageClassSig /* <design/message/#class.sig.double> */
};
static void TraceStartMessageInit(Arena arena, TraceStartMessage tsMessage)
{
AVERT(Arena, arena);
MessageInit(arena, TraceStartMessageMessage(tsMessage),
&TraceStartMessageClassStruct, MessageTypeGCSTART);
tsMessage->why[0] = '\0';
tsMessage->sig = TraceStartMessageSig;
AVERT(TraceStartMessage, tsMessage);
return;
}
/* traceStartWhyToString -- why-code to text
*
* Converts a TraceStartWhy* code into a constant string describing
* why a trace started.
*/
static const char *traceStartWhyToString(int why)
{
const char *r;
switch(why) {
case TraceStartWhyCHAIN_GEN0CAP:
r = "Generation 0 of a chain has reached capacity:"
" start a minor collection.";
break;
case TraceStartWhyDYNAMICCRITERION:
r = "Need to start full collection now, or there won't be enough"
" memory (ArenaAvail) to complete it.";
break;
case TraceStartWhyOPPORTUNISM:
r = "Opportunism: client predicts plenty of idle time,"
" so start full collection.";
break;
case TraceStartWhyCLIENTFULL_INCREMENTAL:
r = "Client requests: start incremental full collection now.";
break;
case TraceStartWhyCLIENTFULL_BLOCK:
r = "Client requests: immediate full collection.";
break;
case TraceStartWhyWALK:
r = "Walking all live objects.";
break;
default:
NOTREACHED;
r = "Unknown reason (internal error).";
break;
}
return r;
}
/* traceStartWhyToTextBuffer
*
* Converts a TraceStartWhy* code into a string describing why a trace
* started, and copies that into the text buffer the caller provides.
* s specifies the beginning of the buffer to write the string
* into, len specifies the length of the buffer.
* The string written into will be NUL terminated (truncated if
* necessary).
*/
static void traceStartWhyToTextBuffer(char *s, size_t len, int why)
{
const char *r;
size_t i;
AVER(s);
/* len can be anything, including 0. */
AVER(TraceStartWhyBASE <= why);
AVER(why < TraceStartWhyLIMIT);
r = traceStartWhyToString(why);
for(i=0; i<len; ++i) {
s[i] = r[i];
if(r[i] == '\0')
break;
}
s[len-1] = '\0';
return;
}
/* ScanStateCheck -- check consistency of a ScanState object */
Bool ScanStateCheck(ScanState ss)
@ -1032,40 +759,6 @@ void TraceDestroy(Trace trace)
}
/* tracePostMessage -- post trace end message
*
* .message.data: The trace end message contains the live size
* (forwardedSize + preservedInPlaceSize), the condemned size
* (condemned), and the not-condemned size (notCondemned). */
static void tracePostMessage(Trace trace)
{
Arena arena;
void *p;
TraceMessage message;
Res res;
AVERT(Trace, trace);
AVER(trace->state == TraceFINISHED);
arena = trace->arena;
res = ControlAlloc(&p, arena, sizeof(TraceMessageStruct), FALSE);
if(res == ResOK) {
message = (TraceMessage)p;
TraceMessageInit(arena, message);
message->liveSize = trace->forwardedSize + trace->preservedInPlaceSize;
message->condemnedSize = trace->condemned;
message->notCondemnedSize = trace->notCondemned;
MessagePost(arena, TraceMessageMessage(message));
}
if(arena->alertCollection) {
(*arena->alertCollection)(MPS_ALERT_COLLECTION_STOP, trace->why);
}
return;
}
/* traceReclaim -- reclaim the remaining objects white for this trace */
static void traceReclaim(Trace trace)
@ -1997,7 +1690,7 @@ void TraceStart(Trace trace, double mortality, double finishingTime)
/* traceQuantum -- progresses a trace by one quantum */
static void traceQuantum(Trace trace)
void traceQuantum(Trace trace)
{
Size pollEnd;
@ -2038,7 +1731,7 @@ static void traceQuantum(Trace trace)
* "why" is a TraceStartWhy* enum member that specifies why the
* collection is starting. */
static Res traceStartCollectAll(Trace *traceReturn, Arena arena, int why)
Res traceStartCollectAll(Trace *traceReturn, Arena arena, int why)
{
Trace trace;
Res res;
@ -2160,242 +1853,6 @@ failStart:
}
/* ArenaClamp -- clamp the arena (no optional collection increments) */
void ArenaClamp(Globals globals)
{
AVERT(Globals, globals);
globals->clamped = TRUE;
}
/* ArenaRelease -- release the arena (allow optional collection
* increments) */
void ArenaRelease(Globals globals)
{
AVERT(Globals, globals);
arenaForgetProtection(globals);
globals->clamped = FALSE;
(void)TracePoll(globals);
}
/* ArenaPark -- finish all current collections and clamp the arena */
void ArenaPark(Globals globals)
{
TraceId ti;
Trace trace;
Arena arena;
AVERT(Globals, globals);
arena = GlobalsArena(globals);
globals->clamped = TRUE;
while(arena->busyTraces != TraceSetEMPTY) {
/* Poll active traces to make progress. */
TRACE_SET_ITER(ti, trace, arena->busyTraces, arena)
traceQuantum(trace);
if(trace->state == TraceFINISHED) {
TraceDestroy(trace);
}
TRACE_SET_ITER_END(ti, trace, arena->busyTraces, arena);
}
}
/* Low level stuff for Expose / Remember / Restore */
typedef struct RememberedSummaryBlockStruct *RememberedSummaryBlock;
void rememberedSummaryBlockInit(struct RememberedSummaryBlockStruct *block)
{
size_t i;
RingInit(&block->globalRing);
for(i = 0; i < RememberedSummaryBLOCK; ++ i) {
block->the[i].base = (Addr)0;
block->the[i].summary = RefSetUNIV;
}
return;
}
Res arenaRememberSummaryOne(Globals global, Addr base, RefSet summary)
{
Arena arena;
RememberedSummaryBlock block;
AVER(summary != RefSetUNIV);
arena = GlobalsArena(global);
if(global->rememberedSummaryIndex == 0) {
void *p;
RememberedSummaryBlock newBlock;
int res;
res = ControlAlloc(&p, arena, sizeof *newBlock, 0);
if(res != ResOK) {
return res;
}
newBlock = p;
rememberedSummaryBlockInit(newBlock);
RingAppend(GlobalsRememberedSummaryRing(global),
&newBlock->globalRing);
}
block = RING_ELT(RememberedSummaryBlock, globalRing,
RingPrev(GlobalsRememberedSummaryRing(global)));
AVER(global->rememberedSummaryIndex < RememberedSummaryBLOCK);
AVER(block->the[global->rememberedSummaryIndex].base == (Addr)0);
AVER(block->the[global->rememberedSummaryIndex].summary == RefSetUNIV);
block->the[global->rememberedSummaryIndex].base = base;
block->the[global->rememberedSummaryIndex].summary = summary;
++ global->rememberedSummaryIndex;
if(global->rememberedSummaryIndex >= RememberedSummaryBLOCK) {
AVER(global->rememberedSummaryIndex == RememberedSummaryBLOCK);
global->rememberedSummaryIndex = 0;
}
return ResOK;
}
/* ArenaExposeRemember -- park arena and then lift all protection
barriers. Parameter 'rememember' specifies whether to remember the
protection state or not (for later restoration with
ArenaRestoreProtection).
*/
void ArenaExposeRemember(Globals globals, int remember)
{
Seg seg;
Arena arena;
AVERT(Globals, globals);
ArenaPark(globals);
arena = GlobalsArena(globals);
if(SegFirst(&seg, arena)) {
Addr base;
do {
base = SegBase(seg);
if(IsSubclassPoly(ClassOfSeg(seg), GCSegClassGet())) {
if(remember) {
RefSet summary;
summary = SegSummary(seg);
if(summary != RefSetUNIV) {
Res res = arenaRememberSummaryOne(globals, base, summary);
if(res != ResOK) {
/* If we got an error then stop trying to remember any
protections. */
remember = 0;
}
}
}
SegSetSummary(seg, RefSetUNIV);
AVER(SegSM(seg) == AccessSetEMPTY);
}
} while(SegNext(&seg, arena, base));
}
return;
}
void ArenaRestoreProtection(Globals globals)
{
Ring node, next;
Arena arena;
arena = GlobalsArena(globals);
RING_FOR(node, GlobalsRememberedSummaryRing(globals), next) {
RememberedSummaryBlock block =
RING_ELT(RememberedSummaryBlock, globalRing, node);
size_t i;
for(i = 0; i < RememberedSummaryBLOCK; ++ i) {
Seg seg;
Bool b;
if(block->the[i].base == (Addr)0) {
AVER(block->the[i].summary == RefSetUNIV);
continue;
}
b = SegOfAddr(&seg, arena, block->the[i].base);
if(b && SegBase(seg) == block->the[i].base) {
AVER(IsSubclassPoly(ClassOfSeg(seg), GCSegClassGet()));
SegSetSummary(seg, block->the[i].summary);
} else {
/* Either seg has gone or moved, both of which are */
/* client errors. */
NOTREACHED;
}
}
}
arenaForgetProtection(globals);
return;
}
void arenaForgetProtection(Globals globals)
{
Ring node, next;
Arena arena;
arena = GlobalsArena(globals);
/* Setting this early means that we preserve the invariant
<code/global.c#remembered.summary> */
globals->rememberedSummaryIndex = 0;
RING_FOR(node, GlobalsRememberedSummaryRing(globals), next) {
RememberedSummaryBlock block =
RING_ELT(RememberedSummaryBlock, globalRing, node);
RingRemove(node);
ControlFree(arena, block, sizeof *block);
}
return;
}
/* ArenaStartCollect -- start a collection of everything in the
* arena; leave unclamped. */
Res ArenaStartCollect(Globals globals, int why)
{
Arena arena;
Res res;
Trace trace;
AVERT(Globals, globals);
arena = GlobalsArena(globals);
ArenaPark(globals);
res = traceStartCollectAll(&trace, arena, why);
if(res != ResOK)
goto failStart;
ArenaRelease(globals);
return ResOK;
failStart:
ArenaRelease(globals);
return res;
}
/* ArenaCollect -- collect everything in arena; leave clamped */
Res ArenaCollect(Globals globals, int why)
{
Res res;
AVERT(Globals, globals);
res = ArenaStartCollect(globals, why);
if(res != ResOK)
return res;
ArenaPark(globals);
return ResOK;
}
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2003, 2006, 2007 Ravenbrook Limited

File diff suppressed because it is too large Load diff

View file

@ -30,7 +30,8 @@ MPM = <ring> <mpm> <bt> <protocol> <boot> \
<arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \
<pool> <poolabs> <poolmfs> <poolmv> \
<root> <format> <buffer> <walk> <lockw3> \
<ref> <trace> <protw3> <proti3> <prmci3w3> <shield> <vmw3> \
<ref> <trace> <traceanc> <protw3> <proti3> <prmci3w3> \
<shield> <vmw3> \
<thw3i3> <ssw3i3> <mpsi> <mpsiw3> <ld> <spi3> \
<event> <seg> <sac> <poolmrg> <message> <dbgpool> <dbgpooli> \
<abq> <meter> <cbs> <poolmv2> <splay> <diag> <version>
@ -38,7 +39,8 @@ SW = <ring> <mpm> <bt> <protocol> <boot> \
<arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \
<pool> <poolabs> <poolmfs> <poolmv> \
<root> <format> <buffer> <walk> \
<ref> <trace> <protsw> <prmcan> <shield> <vmw3> \
<ref> <trace> <traceanc> <protsw> <prmcan> \
<shield> <vmw3> \
<thw3i3> <ssan> <mpsi> <ld> \
<event> <seg> <sac> <poolmrg> <message> <mpsioan> \
<poolams> <poolamsi> <dbgpool> <dbgpooli> \

View file

@ -18,7 +18,8 @@ MPM = <ring> <mpm> <bt> <protocol> <boot> \
<arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \
<pool> <poolabs> <poolmfs> <poolmv> \
<root> <format> <buffer> <walk> <lockw3> \
<ref> <trace> <protw3> <proti3> <prmci3w3> <shield> <vmw3> \
<ref> <trace> <traceanc> <protw3> <proti3> <prmci3w3> \
<shield> <vmw3> \
<thw3i3> <ssw3i3> <mpsi> <mpsiw3> <ld> <spi3> \
<event> <seg> <sac> <poolmrg> <message> <dbgpool> <dbgpooli> \
<abq> <meter> <cbs> <poolmv2> <splay> <diag> <version>
@ -26,7 +27,8 @@ SW = <ring> <mpm> <bt> <protocol> <boot> \
<arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \
<pool> <poolabs> <poolmfs> <poolmv> \
<root> <format> <buffer> <walk> \
<ref> <trace> <protsw> <prmcan> <shield> <vmw3> \
<ref> <trace> <traceanc> <protsw> <prmcan> \
<shield> <vmw3> \
<thw3i3> <ssan> <mpsi> <ld> \
<event> <seg> <sac> <poolmrg> <message> <mpsioan> \
<poolams> <poolamsi> <dbgpool> <dbgpooli> \