previous next top contents index framed top this page unframed
Command line syntax: mm {mmCommand}*
The MAINSAIL monitor MODULE MM allows you to invoke various memory management operations or examine various memory management parameters. It takes commands that tell it what to do, e.g., a STRING garbage collection, a chunk (dynamic object) compaction, a memory map. In each case, it tells how many CPU seconds were required to do each operation (it may be interesting to see how the various memory management strategies compare timewise). ? lists the available commands, which are shown in Table 23–1.
Any of the commands that take a file, such as ai f, can take >>f in place of f to mean to append to the end of the file if it already exists (in this case a page mark is written to separate the new data from the old).
| ? | help (this message) |
| ai f | write ARRAY info to file f |
| all f | write all statistics to file f |
| amp n | set $allowedMemoryPercent to n |
| ari f | write area info to file f |
| ccs | compact chunk space |
| cda | collect dscrArea |
| cfc | coalesce free chunks |
| ci f c1 ... cn | write chunk info and records of CLASSes c1 ... cn to file f |
| cli f | write CLASS info to file f |
| cmc | check memory consistency |
| cmd | compress memory down |
| cmp n | set $collectMemoryPercent to n |
| cmu | compress memory up |
| cp | collect POINTERs |
| cps | collect POINTERs and STRINGs |
| cs | collect STRINGs |
| dc | decrement $collectLock |
| di f | write descriptor info to file f |
| dp | deallocate trailing free pages, if operating system permits |
| fr f g | fix ref info (written by ri f) to file g |
| i | show info |
| ic | increment $collectLock |
| m f | write memory map to file f |
| mai f | write MODULE age info to file f |
| mi f | write MODULE info to file f |
| opev n | set $overheadPercentExitValue to n |
| ri f a1 ... an | write ref info for areas a1 ... an to file f |
| sw s | swap out MODULE s |
| sw1 | swap out one MODULE of MAINSAIL's choice |
| swa | swap out all MODULEs |
| <eol> | quit |
The size of a free chunk includes the chunk overhead and is rounded up
according to chunk alignment so that it is the actual amount of space
occupied by the free chunk. There is some bookkeeping overhead
in a STRING space.
23.1. all
The command all {f} prints all statistics
to the file f (TTY if f is
omitted). This currently includes the output from the following
commands: i, mi, m, mai, ari,
ci, di. This is a convenient
way to get a dump of all the statistics
available from MM without having to
give the individual commands.
23.2. ari
The ari command shows for each area:
23.3. ci
The ci command displays information about currently allocated dynamic objects (each of which is said to occupy a “chunk” of memory). The chunks are not necessarily accessible; i.e., if a garbage collection were performed, some of the displayed chunks might be deallocated.
If the output file f for the ci command is omitted,
the output file defaults to logFile.
After f, ci accepts a series of CLASS names.
For each CLASS name specified,
the command displays the contents of all chunks of the CLASS.
The command always displays a summary enumerating the
number, size, type, and CLASS name of each chunk.
Examining the contents of all chunks
of a CLASS may help determine
why they are present in memory.
23.4. di
The di command displays how many times allocation, deallocation, and garbage collection have been performed for records, ARRAYs, and MODULEs for which a descriptor exists. The statistics shown indicate how often each event has occurred since the allocation of the descriptor; since descriptors are rarely collected, this is usually since the start of the MAINSAIL execution. If the output file f is omitted, it defaults to TTY. The output format should be self-explanatory.
Note: when the di command displays the number of deallocations
associated with a dynamic object descriptor
(or “chunk descriptor”),
the number of calls to $disposeArea when
a dynamic object of the given
descriptor is located in the area disposed is not
included in the deallocation count.
This can lead to misleading displays;
e.g., the di command may report 100
allocations and 50 deallocations
for a given descriptor, which
would normally mean that 50 objects
associated with that descriptor
remain in memory, when in fact none
currently remains in memory because all were removed by
$disposeArea.
If you need more a detailed history
of memory usage (which takes calls
to $disposeArea into account), you should use
the MAINPM TRACECHUNKS command.
23.5. fr
The command fr f g (“fix references”) copies the file f (created by ri f...; see Section 23.8) to a new file g, except that an attempt is made to replace local and OWN displacements with the corresponding variable names. The file f may consist of any number of pages of output created by separate ri commands (which specified >>f, i.e., append mode).
This translation is not carried out automatically by the ri command since you may not want to disturb memory in the midst of program execution to the extent that fr does, and the supporting intmods (see below) may not be available in the execution context.
To replace a local variable displacement for a PROCEDURE in some MODULE FOO, or an OWN variable displacement in FOO, FOO must have been compiled with the DEBUG option and the resulting intmod for MODULE FOO must be accessible. fr complains when it cannot find an intmod or when the intmod has insufficient information; in such cases it simply copies the original line from f to g.
There are other situations when a local or OWN displacement does not correspond to a variable name, in which case the fr command gives a message such as:
COMPIL.INITIALPROC.-16: no id for it
The original line is copied in this case also.
A common case is a local
variable inherited from an
INLINE PROCEDURE of which the body
was expanded in
the calling PROCEDURE:
the names for such inherited locals are not
available from the intmod.
Also, various OWN POINTERs are created by the
compiler and do not have variable names.
The information on CONF parameters used to build the current
bootstrap is as much as is available from within MAINSAIL.
The CONF parameter values
(some of which may change during the course
of a MAINSAIL execution) are shown in the i
command listing under the
heading $conf.
The i command also tells,
for all open libraries, the name of the
library, and if the library is mapped, its address and size.
Note that some memory used by a MAINSAIL process is unaccounted for
by the i listing (also by the m map):
23.6. i
The i command displays several kinds of information about the
current MAINSAIL session.
This information includes,
among other things, information about
CONF parameters and more detailed
information on memory usage.
23.7. Memory Gaps and the m Command
The memory manager keeps track of the total size of any gaps in the operating system's allocation of memory to MAINSAIL (i.e., where the address of the memory MAINSAIL last acquired from the operating system did not immediately follow the last address of previously acquired memory). The MM m command displays any such gaps as F pages (presumably memory consumed by the operating system or by foreign code linked with MAINSAIL). The amount of memory consumed by gaps is the amount of memory that should be specified to the CONF OSMEMORYPOOLSIZE command.
The i command shows the total static pool size actually used
so far.
This can be of assistance when trying to decide how big to
make the initial static pool
(use the default setting, run your program,
then see how big the gaps got,
then make a new boot with approximately that
value plus the default static pool size
for the initial static pool size).
It also shows file cache parameters and the maximum size that
memory has grown to.
ri f a1 ... an
(“reference info”) writes
information about references to areas with titles
a1 ... an to file f.
This command
is a debugging aid that shows all
POINTER and STRING references into an
area from outside the area.
For example, if a program is disposing of an
area at a certain point, and you suspect that this is causing a
dangling POINTER or STRING bug,
this command, given (e.g., from the
debugger) just before the area is disposed,
may help to determine what
STRING or POINTER is causing the problem.
If the ai
(and possibly f) are omitted,
MM prompts for them. If given on
the same line as ri,
separate f and ai
with one or more blanks and/or tabs.
The ai are area titles;
each title is assumed to be a single “word”
(where words are delimited by spaces
and tabs and contain no spaces or tabs)
unless it starts with a double quote, in which case it extends
to the next double quote
(double quote pairs as in STRING constants
are not recognized).
If no ai are specified,
MM prompts for them, in which case
each response is taken as the area title
(blanks and double quotes play
no special role, so that arbitrary titles
(except that embedded end-of-line characters
are not allowed) can be specified).
The file f is opened with the bits
random!input!output!$unbuffered,
so that TTY
is not suitable. Use >>f instead of just f
to append to the end of an existing file f (in
which case the new info is preceded with an end-of-page character
if f is not initially
empty).
MM first marks each area in
a1 ... an, and then finds
each POINTER and STRING that
references a marked area, but is not
itself in a marked area. The identity
of each such POINTER or STRING is
written to the file f, one line per reference.
An example of some lines from
such a file f is (the formats are subject to change):
Each informational line starts out with
type kindOfVar where type is
POINTER or STRING,
and kindOfVar is LOCAL, OWN, SHARED,
FIELD, IFIELD, ARYELEM,
or VECELEM.
The exact format of the rest of the line depends on these
first two fields.
For all but LOCAL,
the title of the area which contains the referencing
POINTER or STRING
is written in square brackets after the information
identifying the reference (this is omitted if the title
is the empty STRING).
If type is STRING,
the entry ends with “= value”,
where value is the
text for the referenced STRING (if longer than 20
characters, “...” is appended to the first 20 characters,
e.g., veryLongStringValueX...).
[referencingCoroutine]
is omitted if it is the root coroutine
MAINSAIL in which
MAINSAIL starts execution.
An example of a line written for a LOCAL reference is:
This means that one of the areas
was referenced by a local POINTER at
displacement -48 in a stack frame for the
PROCEDURE REFINFO in the MODULE $MM.
The
“local” variable $THISDB refers to the data section
POINTER that is stored in
every frame, for example:
In some rather obscure cases it
is possible for <unknown> to be written
for moduleName.
If the referencing MODULE's control section was not in
memory when the reference was written,
then the PROCEDURE name could not
be found, and in its place
is written the displacement in the control
section to which control will
return to the referencing PROCEDURE.
If the displacement is not even known,
<unknown> is written for
procedureName.
Use the fr command (described below) to translate
frameDspl to the local variable name;
e.g., the first example line
above might be translated to:
An example of a line written for a OWN reference is:
This means that one of the areas
is referenced by an OWN POINTER at
displacement 36 in a data section for the
MODULE PAKMOD, and the referencing
data section is in an area with title pass1Area.
Use the fr command described below
to translate dataSecDspl to the OWN
variable name; e.g., the example line above might be translated
to:
An example of a line written for a SHARED reference is:
This means that one of the areas
is referenced by a $SHARED POINTER at
displacement 20 in the shared data section for the
MODULE FOO, and the referencing
shared data section is in an area with title pass1Area.
Use the fr command described below to translate
sharedDataSecDspl to the $SHARED
variable name; e.g., the example line above might be translated
to:
An example of a line written for a FIELD reference is:
This means that one of the areas
is referenced by field KEY of a record
of the
CLASS $PARSENODE,
and the referencing record is in an area with title
pass1Area. The referenced STRING is $RAISEFRAME.
An example of a line written for an IFIELD reference is:
This means that one of the areas is referenced by
the field FIRSTOPENMODULE
of a data section for the MODULE INTMGR,
and the referencing
data section is in an
area with title keptCompileArea.
An example of a line written for an ARYELEM reference is:
This means that one of the areas
is referenced by MODULENAMEMAP[1], and
the referencing
data section is in an area with title compileArea. The
referenced STRING is $SYS.
An example of a line written for a VECELEM reference is:
This means that one of the areas
is referenced by a vector element with
index 3, and the referencing vector is in an area with title
compileArea. Note: vectors do not have names.
23.8. ri Command
Pointers and strings that reference the following areas
(from outside these areas):
compilArea
POINTER FIELD KERSTRSPC.$AREAREC
POINTER LOCAL $MM.REFINFO.-48
POINTER LOCAL PASS1.GETSTA.$THISDB
POINTER LOCAL PASS1.GETPROCEDURE.-134
STRING LOCAL PASS1.GETPROCEDURE.PROCNAME = "INITIALPROC"
POINTER FIELD KERAREA.$NEXTAREA [pass1Area]
POINTER OWN TREEIO.STRAREA [pass1Area]
POINTER OWN PAKMOD.36 [pass1Area]
POINTER OWN PAKMOD.0 [pass1Area]
STRING FIELD $PARSENODE.STR [pass1Area] = "44"
POINTER IFIELD INTMGR.LASTOPENMODULE [keptCompilArea]
POINTER IFIELD INTMGR.VISIBLESYMTBLNODELIST [keptCompilArea]
POINTER OWN INTMGR.STRAREA [keptCompilArea]
23.8.1. LOCAL kindOfVar
kindOfVar is
LOCAL for a local variable (more precisely,
a value in a PROCEDURE stack
frame). A local reference has the following format:
type LOCAL moduleName.procedureName.frameDspl [referencingCoroutine]
POINTER LOCAL $MM.REFINFO.-48
POINTER LOCAL $MAINEX.$MAINSAILEXEC.$THISDB
POINTER LOCAL $MM.REFINFO.AREALIST
23.8.2. OWN kindOfVar
kindOfVar is
OWN for an OWN variable;
more precisely, a value in a data section
(a normal data section, not a shared data section)
that is not an interface field.
An OWN reference has the following
format:
type OWN moduleName.dataSecDspl [referencingArea]
POINTER OWN PAKMOD.36 [pass1Area]
POINTER OWN PAKMOD.THEREC [pass1Area]
23.8.3. SHARED kindOfVar
kindOfVar is
SHARED for a $SHARED variable
(i.e., a value in a shared data section).
A SHARED reference has the following
format:
type SHARED moduleName.sharedDataSecDspl [referencingArea]
POINTER SHARED FOO.20 [pass1Area]
POINTER SHARED FOO.XRECNEXT [pass1Area]
23.8.4. FIELD kindOfVar
kindOfVar is
FIELD for a field of a record or descriptor.
A field reference has the following format:
type FIELD className.fieldName [referencingArea]
STRING FIELD $PARSENODE.KEY [pass1Area] = "$RAISEFRAME"
23.8.5. IFIELD kindOfVar
kindOfVar is
IFIELD for an interface field of a data section.
An IFIELD reference has
the following format:
type IFIELD moduleName.fieldName [referencingArea]
POINTER IFIELD INTMGR.FIRSTOPENMODULE [keptCompilArea]
23.8.6. ARYELEM kindOfVar
kindOfVar is
ARYELEM for an element of an ARRAY.
An ARYELEM reference has the
following format:
type ARYELEM arrayName[i1{,i2{,i3}}] [referencingArea]
STRING ARYELEM MODULENAMEMAP[1] [compilArea] = "$SYS"
23.8.7. VECELEM kindOfVar
kindOfVar is
VECELEM for an element of a vector (an internal data structure
used by the runtime system). A
VECELEM reference has the following format:
type VECELEM [index] [referencingArea]
POINTER VECELEM [3] [compilArea]
23.9. Other Commands
The brief descriptions of the other commands are intended to
be self-explanatory
(if you don't understand the explanation, then you probably
don't want to do it).
The list of commands is subject to change as memory management
strategies evolve.
23.10. Command Line Arguments to MM
When invoked with command line arguments, several command names
can be separated by spaces (except in the case of ci,
where all subsequent arguments are treated
as arguments to ci); e.g.,
mm m cps m
invokes MM, shows a memory map,
does a garbage collection, then shows a
memory map again.
MAINSAIL Utilities User's Guide, Chapter 23