20. "Subprimitives"
.setq subprimitive-chapter chapter-number
Subprimitives are functions which are not intended to be used by
the average program, only by "system programs". They allow one to
manipulate the environment at a level lower than normal Lisp.
They are described in this chapter.
Subprimitives usually have names which start with a % character.
The "primitives" described in other sections of the manual typically
use subprimitives to accomplish their work. The subprimitives take
the place of machine language in other systems, to some extent.
Subprimitives are normally hand-coded in microcode.
There is plenty of stuff in this chapter that is not fully
explained; there are terms that are undefined, there are forward references,
and so on. Furthermore, most of what is in here is considered subject
to change without notice. In fact, this chapter does not exactly belong
in this manual, but in some other more low-level manual. Since the latter
manual does not exist, it is here for the interim.
Subprimitives by their very nature cannot do full checking.
Improper use of subprimitives can destroy the environment.
Subprimitives come in varying degrees of dangerousness. Those without
a % sign in their name cannot destroy the environment, but are
dependent on "internal" details of the Lisp implementation. The ones
whose names start with a % sign can
violate system conventions if used improperly. The subprimitives are documented here
since they need to be documented somewhere, but this manual does not
document all the things you need to know in order to use them. Still other
subprimitives are not documented here because they are very specialized.
Most of these are never used explicitly by a programmer; the compiler
inserts them into the program to perform operations which are expressed
differently in the source code.
The most common problem you can cause using subprimitives, though
by no means the only one, is to create illegal pointers: pointers
that are, for one reason or another, according to storage conventions,
not allowed to exist. The storage conventions are not documented;
as we said, you have to be an expert to correctly use a lot of the functions
in this chapter. If you create such an illegal pointer, it probably will
not be detected immediately, but later on parts of the system may see it,
notice that it is illegal, and (probably) halt the Lisp Machine.
In a certain sense car, cdr, rplaca, and rplacd are
subprimitives. If these are given a locative instead of a list, they will
access or modify the cell addressed by the locative without regard to what
object the cell is inside. Subprimitives can be used to create locatives
to strange places.
20.1 Data Types
- Function: data-type arg
- data-type returns a symbol which is the name
for the internal data-type of the "pointer" which represents arg.
Note that some types as seen by the user are not distinguished from each other
at this level, and some user types may be represented by more than one
internal type. For example, dtp-extended-number is the symbol that
data-type would return for either a flonum or a bignum, even though
those two types are quite different.
The typep function ((typep-fun)) is a higher-level
primitive which is more useful in most cases; normal programs
should always use typep rather than data-type.
Some of these type codes are internal tag fields that are never
used in pointers that represent Lisp objects at all, but they are
documented here anyway.
dtp-symbol
- The object is a symbol.
dtp-fix
- The object is a fixnum; the numeric value is contained in the address field of
the pointer.
dtp-small-flonum
- The object is a small flonum; the numeric value is contained in the address field of
the pointer.
dtp-extended-number
- The object is a flonum or a bignum. This value will also be used for future numeric
types.
dtp-list
- The object is a cons.
dtp-locative
- The object is a locative pointer.
dtp-array-pointer
- The object is an array.
dtp-fef-pointer
- The object is a compiled function.
dtp-u-entry
- The object is a microcode entry.
dtp-closure
- The object is a closure; see (closure).
dtp-stack-group
- The object is a stack-group; see (stack-group).
dtp-instance
- The object is an instance of a flavor, i.e. an "active object". See (flavor).
dtp-entity
- The object is an entity; see (entity).
dtp-select-method
- The object is a "select-method"; see (select-method).
dtp-header
- An internal type used to mark the first word of a multi-word structure.
dtp-array-header
- An internal type used in arrays.
dtp-symbol-header
- An internal type used to mark the first word of a symbol.
dtp-instance-header
- An internal type used to mark the first word of an instance.
dtp-null
- Nothing to do with nil. This is used in unbound value and function cells.
dtp-trap
- The zero data-type, which is not used. This hopes to detect microcode bugs.
dtp-free
- This type is used to fill free storage, to catch wild references.
dtp-external-value-cell-pointer
- An "invisible pointer" used for external value cells,
which are part of the closure mechanism (see (closure)),
and used by compiled code to address value and function cells.
dtp-header-forward
- An "invisible pointer" used to indicate that the structure containing
it has been moved elsewhere. The "header word" of the structure is
replaced by one of these invisible pointers. See the function structure-forward
((structure-forward-fun)).
dtp-body-forward
- An "invisible pointer" used to indicate that the structure containing
it has been moved elsewhere. This points to the word containing
the header-forward, which points to the new copy of the structure.
dtp-one-q-forward
- An "invisible pointer" used to indicate that the single cell containing
it has been moved elsewhere.
dtp-gc-forward
- This is used by the copying garbage collector to flag the obsolete copy
of an object; it points to the new copy.
- Variable: q-data-types
- The value of q-data-types is a list of all of the symbolic
names for data types described above under data-type.
These are the symbols whose print names begin
with "dtp-". The values of these symbols are the internal numeric data-type codes
for the various types.
- Function: q-data-types type-code
- Given the internal numeric data-type code, returns the corresponding symbolic name.
This "function" is actually an array.
20.2 Forwarding
An invisible pointer is a kind of pointer that does not represent a
Lisp object, but just resides in memory. There are several kinds of
invisible pointer, and there are various rules about where
they may or may not appear. The basic property of an invisible pointer
is that if the Lisp Machine reads a word of memory and finds an
invisible pointer there, instead of seeing the invisible pointer as the
result of the read, it does a second read, at the location addressed by
the invisible pointer, and returns that as the result instead. Writing behaves
in a similar fashion. When the Lisp Machine writes a word of memory it first
checks to see if that word contains an invisible pointer; if so it goes to
the location pointed to by the invisible pointer and tries to write there instead.
Many subprimitives that read and write memory do not do this checking.
The simplest kind of invisible pointer has the data type code
dtp-one-q-forward. It is used to forward a single word of memory to
someplace else. The invisible pointers with data types
dtp-header-forward and dtp-body-forward are used for moving
whole Lisp objects (such as cons cells or arrays) somewhere else. The
dtp-external-value-cell-pointer is very similar to the
dtp-one-q-forward; the difference is that it is not "invisible" to
the operation of binding. If the (internal) value cell of a symbol
contains a dtp-external-value-cell-pointer that points to some other
word (the external value cell), then symeval or set operations on
the symbol will consider the pointer to be invisible and use the
external value cell, but binding the symbol will save away the
dtp-external-value-cell-pointer itself, and store the new value into
the internal value cell of the symbol. This is how closures are implemented.
dtp-gc-forward is not an invisible pointer at all; it only appears in
"old space" and will never be seen by any program other than the garbage
collector. When an object is found not to be garbage, and the garbage collector
moves it from "old space" to "new space", a dtp-gc-forward is left behind
to point to the new copy of the object. This ensures that other references
to the same object get the same new copy.
- Function: structure-forward old-object new-object
- This causes references to old-object to actually reference
new-object, by storing invisible pointers in old-object.
It returns old-object.
An example of the use of structure-forward is adjust-array-size.
If the array is being made bigger and cannot be expanded in place, a new
array is allocated, the contents are copied, and the old array is
structure-forwarded to the new one. This forwarding ensures that pointers
to the old array, or to cells within it, continue to work. When the garbage
collector goes to copy the old array, it notices the forwarding and uses
the new array as the copy; thus the overhead of forwarding disappears
eventually if garbage collection is in use.
- Function: follow-structure-forwarding object
- Normally returns object, but if object has been structure-forward'ed,
returns the object at the end of the chain of forwardings. If object
is not exactly an object, but a locative to a cell in the middle of an object,
a locative to the corresponding cell in the latest copy of the object will be
returned.
- Function: forward-value-cell from-symbol to-symbol
- This alters from-symbol so that it always has the same value
as to-symbol, by sharing its value cell. A dtp-one-q-forward
invisible pointer is stored into from-symbol's value cell.
Do not do this while from-symbol is lambda-bound, as
the microcode does not bother to check for that case and something
bad will happen when from-symbol gets unbound. The microcode check
is omitted to speed up binding and unbinding.
To forward one arbitrary cell to another (rather than specifically
one value cell to another), given two locatives do
| (%p-store-tag-and-pointer locative1 dtp-one-q-forward locative2)
|
- Function: follow-cell-forwarding loc evcp-p
- loc is a locative to a cell. Normally loc is returned, but if the
cell has been forwarded, this follows the chain of forwardings and returns
a locative to the final cell. If the cell is part of a structure which has
been forwarded, the chain of structure forwardings is followed, too.
If evcp-p is t, external value cell pointers are followed; if
it is nil they are not.
20.3 Pointer Manipulation
It should again be emphasized that improper use of these functions
can damage or destroy the Lisp environment. It is possible to create
pointers with illegal data-type, pointers to non-existent objects, and
pointers to untyped storage which will completely confuse the garbage
collector.
- Function: %data-type x
- Returns the data-type field of x, as a fixnum.
- Function: %pointer x
- Returns the pointer field of x, as a fixnum. For most
types, this is dangerous since the garbage collector can copy the object
and change its address.
- Function: %make-pointer data-type pointer
- This makes up a pointer, with data-type in the data-type
field and pointer in the pointer field, and returns it. data-type
should be an internal numeric data-type code; these are the values of
the symbols that start with dtp-. pointer may be any object;
its pointer field is used. This is
most commonly used for changing the type of a pointer. Do not use this
to make pointers which are not allowed to be in the machine, such as
dtp-null, invisible pointers, etc.
- Function: %make-pointer-offset data-type pointer offset
- This returns a pointer with data-type in the data-type
field, and pointer plus offset in the pointer field. The
data-type and pointer arguments are like those of %make-pointer;
offset may be any object but is usually a fixnum. The
types of the arguments are not checked; their pointer fields are simply
added together. This is useful for constructing locative pointers
into the middle of an object. However, note that it is illegal to
have a pointer to untyped data, such as the inside of a FEF or
a numeric array.
- Function: %pointer-difference pointer-1 pointer-2
- Returns a fixnum which is pointer-1 minus pointer-2.
No type checks are made. For the result to be meaningful, the two pointers
must point into the same object, so that their difference cannot change
as a result of garbage collection.
20.4 Analyzing Structures
- Function: %find-structure-header pointer
- This subprimitive finds the structure into which
pointer points, by searching backward for a header.
It is a basic low-level function used by such things as the
garbage collector.
pointer is normally a locative, but its data-type is ignored.
Note that it is illegal to point into an "unboxed" portion of
a structure, for instance the middle of a numeric array.
In structure space, the "containing structure" of a pointer
is well-defined by system storage conventions. In list space,
it is considered to be the contiguous, cdr-coded segment of
list surrounding the location pointed to. If a cons of the list
has been copied out by rplacd, the contiguous list includes
that pair and ends at that point.
- Function: %find-structure-leader pointer
- This is identical to %find-structure-header, except that if the
structure is an array with a leader, this returns a locative pointer
to the leader-header, rather than returning the array-pointer itself.
Thus the result of %find-structure-leader is always the lowest
address in the structure. This is the one used internally by the garbage collector.
- Function: %structure-boxed-size object
- Returns the number of "boxed Q's" in object. This is the number
of words at the front of the structure which contain normal Lisp objects.
Some structures, for example FEFs and numeric arrays, contain additional
"unboxed Q's" following their "boxed Q's".
Note that the boxed size of a PDL (either regular or special) does not
include Q's above the current top of the PDL. Those locations are boxed
but their contents is considered garbage, and is not protected by the
garbage collector.
- Function: %structure-total-size object
- Returns the total number of words occupied by the representation
of object, including boxed Q's, unboxed Q's, and garbage Q's off
the ends of PDLs.
20.5 Creating Objects
- Function: %allocate-and-initialize data-type header-type header second-word area size
- This is the subprimitive for creating most structured-type objects.
area is the area in which it is to be created, as a fixnum or a symbol.
size is the number of words to be allocated. The value returned
points to the first word allocated, and has data-type data-type.
Uninterruptibly, the words allocated are initialized so that storage
conventions are preserved at all times. The first word, the header,
is initialized to have header-type in its data-type field
and header in its pointer field. The second word is initialized
to second-word. The remaining words are initialized to nil.
The flag bits of all words are set to 0. The cdr codes of all words
except the last are set to cdr-next; the cdr code of the last word
is set to cdr-nil. It is probably a bad idea to rely on this.
The basic functions for creating list-type objects are cons and
make-list; no special subprimitive is needed. Closures, entities,
and select-methods are based on lists, but there is no primitive
for creating them. To create one, create a list and then use %make-pointer
to change the data type from dtp-list to the desired type.
- Function: %allocate-and-initialize-array header data-length leader-length area size
- This is the subprimitive for creating arrays, called only by make-array.
It is different from %allocate-and-initialize because arrays have
a more complicated header structure.
20.6 Locking Subprimitive
- Function: %store-conditional pointer old new
- This is the basic locking primitive. pointer is a locative to
a cell which is uninterruptibly read and written. If the contents of
the cell is eq to old, then it is replaced by new and
t is returned. Otherwise, nil is returned and the contents
of the cell is not changed.
20.7 I/O Device Subprimitives
- Function: %unibus-read address
- Returns the contents of the register at the specified Unibus
address, as a fixnum. You must specify a full 18-bit address. This
is guaranteed to read the location only once. Since the Lisp
Machine Unibus does not support byte operations, this always references
a 16-bit word, and so address will normally be an even number.
- Function: %unibus-write address data
- Writes the 16-bit number data at the specified Unibus
address, exactly once.
- Function: %xbus-read io-offset
- Returns the contents
of the register at the specified Xbus address. io-offset is
an offset into the I/O portion of Xbus physical address space.
This is guaranteed to read the location exactly once.
The returned value can be either a fixnum or a bignum.
- Function: %xbus-write io-offset data
- Writes data, which can be a fixnum or a bignum, into the register at
the specified Xbus address. io-offset is an offset into the I/O
portion of Xbus physical address space. This is guaranteed to write the
location exactly once.
- Function: sys:%xbus-write-sync w-loc w-data delay sync-loc sync-mask sync-value
- Does (%xbus-write w-loc w-data), but first synchronizes to
within about one microsecond of a certain condition. The synchronization
is achieved by looping until
| (= (logand (%xbus-read sync-loc) sync-mask) sync-value)
|
is false, then looping until it is true, then looping delay times.
Thus the write happens a specified delay after the leading edge of the
synchronization condition.
The number of microseconds of delay is roughly one third of delay.
- Function: sys:%halt
- Stops the machine.
20.8 Special Memory Referencing
- Function: %p-contents-offset base-pointer offset
- This checks the cell pointed to by base-pointer for
a forwarding pointer. Having followed forwarding pointers to the
real structure pointed to, it adds offset to the resulting
forwarded base-pointer and returns the contents of that location.
There is no %p-contents, since car performs that operation.
- Function: %p-contents-as-locative pointer
- Given a pointer to a memory location containing a pointer which isn't
allowed to be "in the machine" (typically an invisible pointer)
this function returns the contents of the location as a dtp-locative.
It changes the disallowed data type to dtp-locative so that you can safely
look at it and see what it points to.
- Function: %p-contents-as-locative-offset base-pointer offset
- This checks the cell pointed to by base-pointer for
a forwarding pointer. Having followed forwarding pointers to the
real structure pointed to, it adds offset to the resulting
forwarded base-pointer, fetches the contents of that location,
and returns it with the data type changed to dtp-locative in case
it was a type which isn't allowed to be "in the machine" (typically
an invisible pointer). This can be used, for example, to analyze the
dtp-external-value-cell-pointer pointers in a FEF, which are
used by the compiled code to reference value cells and function cells
of symbols.
- Function: %p-store-contents pointer value
- value is stored into the data-type and pointer
fields of the location addressed by pointer. The cdr-code
and flag-bit fields remain unchanged. value is returned.
- Function: %p-store-contents-offset value base-pointer offset
- This checks the cell pointed to by base-pointer for
a forwarding pointer. Having followed forwarding pointers to the
real structure pointed to, it adds offset to the resulting
forwarded base-pointer, and stores value into the data-type and pointer
fields of that location. The cdr-code
and flag-bit fields remain unchanged. value is returned.
- Function: %p-store-tag-and-pointer pointer miscfields pntrfield
- Creates a Q by taking 8 bits from miscfields
and 24 bits from pntrfield, and stores that into the
location addressed by pointer. The low 5 bits of miscfields
become the data-type, the next bit becomes the flag-bit, and the
top two bits become the cdr-code. This is a good
way to store a forwarding pointer from one structure
to another (for example).
- Function: %p-ldb ppss pointer
- This is like ldb but gets a byte from the location
addressed by pointer. Note that
you can load bytes out of the data type etc. bits, not just
the pointer field, and that the word loaded out of need not
be a fixnum. The result returned is always a fixnum.
- Function: %p-ldb-offset ppss base-pointer offset
- This checks the cell pointed to by base-pointer for
a forwarding pointer. Having followed forwarding pointers to the
real structure pointed to, the byte specified by ppss is
loaded from the contents of the location addressed by the forwarded
base-pointer plus offset, and returned as a fixnum.
This is the way to reference byte fields within a structure
without violating system storage conventions.
- Function: %p-dpb value ppss pointer
- The value, a fixnum, is stored into the byte selected
by ppss in the word addressed by pointer. nil is returned.
You can use this to alter data types, cdr codes, etc.
- Function: %p-dpb-offset value ppss base-pointer offset
- This checks the cell pointed to by base-pointer for
a forwarding pointer. Having followed forwarding pointers to the
real structure pointed to, the value is stored into the byte specified by ppss in
the location addressed by the forwarded
base-pointer plus offset. nil is returned.
This is the way to alter unboxed data within a structure
without violating system storage conventions.
- Function: %p-mask-field ppss pointer
- This is similar to %p-ldb, except that the selected
byte is returned in its original position within the word instead
of right-aligned.
- Function: %p-mask-field-offset ppss base-pointer offset
- This is similar to %p-ldb-offset, except that the selected
byte is returned in its original position within the word instead
of right-aligned.
- Function: %p-deposit-field value ppss pointer
- This is similar to %p-dpb, except that the selected
byte is stored from the corresponding bits of value rather than
the right-aligned bits.
- Function: %p-deposit-field-offset value ppss base-pointer offset
- This is similar to %p-dpb-offset, except that the selected
byte is stored from the corresponding bits of value rather than
the right-aligned bits.
- Function: %p-pointer pointer
- Extracts the pointer field of the contents of the
location addressed by pointer and returns
it as a fixnum.
- Function: %p-data-type pointer
- Extracts the data-type field of the contents of the
location addressed by pointer and returns
it as a fixnum.
- Function: %p-cdr-code pointer
- Extracts the cdr-code field of the contents of the
location addressed by pointer and returns
it as a fixnum.
- Function: %p-flag-bit pointer
- Extracts the flag-bit field of the contents of the
location addressed by pointer and returns
it as a fixnum.
- Function: %p-store-pointer pointer value
- Clobbers the pointer field of the location
addressed by pointer to value, and returns value.
- Function: %p-store-data-type pointer value
- Clobbers the data-type field of the location
addressed by pointer to value, and returns value.
- Function: %p-store-cdr-code pointer value
- Clobbers the cdr-code field of the location
addressed by pointer to value, and returns value.
- Function: %p-store-flag-bit pointer value
- Clobbers the flag-bit field of the location
addressed by pointer to value, and returns value.
- Function: %stack-frame-pointer
- Returns a locative pointer to its caller's stack frame. This
function is not defined in the interpreted Lisp environment; it only works
in compiled code. Since it turns into a "misc" instruction,
the "caller's stack frame" really means "the frame for the FEF
that executed the %stack-frame-pointer instruction".
20.9 Storage Layout Definitions
The following special variables have values which define the most important attributes
of the way Lisp data structures are laid out in storage. In addition to the variables
documented here, there are many others which are more specialized. They are not
documented in this manual since they are in the system package rather than
the global package. The variables whose names start with %% are
byte specifiers, intended to be used with subprimitives such as %p-ldb.
If you change the value of any of these variables, you will probably bring the
machine to a crashing halt.
- Variable: %%q-cdr-code
- The field of a memory word which contains the cdr-code. See (cdr-code).
- Variable: %%q-flag-bit
- The field of a memory word which contains the flag-bit. In most data structures
this bit is not used by the system and is available for the user.
- Variable: %%q-data-type
- The field of a memory word which contains the data-type code. See (data-type-fun).
- Variable: %%q-pointer
- The field of a memory which contains the pointer address, or immediate data.
- Variable: %%q-pointer-within-page
- The field of a memory word which contains the part of the address that lies
within a single page.
- Variable: %%q-typed-pointer
- The concatenation of the %%q-data-type and %%q-pointer fields.
- Variable: %%q-all-but-typed-pointer
- The field of a memory word which contains the tag fields, %%q-cdr-code
and %%q-flag-bit.
- Variable: %%q-all-but-pointer
- The concatenation of all fields of a memory word except for %%q-pointer.
- Variable: %%q-all-but-cdr-code
- The concatenation of all fields of a memory word except for %%q-cdr-code.
- Variable: %%q-high-half
-
- Variable: %%q-low-half
- The two halves of a memory word. These fields are only used in storing compiled code.
- Variable: cdr-normal
-
- Variable: cdr-next
-
- Variable: cdr-nil
-
- Variable: cdr-error
- The values of these four variables are the numeric values which go in the cdr-code
field of a memory word. See (cdr-code) for the details of cdr-coding.
20.10 Function-Calling Subprimitives
These subprimitives can be used (carefully!) to call a function with the
number of arguments variable at run time. They only work in compiled code
and are not defined in the interpreted Lisp environment.
The preferred higher-level primitive is lexpr-funcall ((lexpr-funcall-fun)).
- Function: %open-call-block function n-adi-pairs destination
- Starts a call to function. n-adi-pairs is the number of
pairs of additional information words already %push'ed; normally
this should be 0. destination is where to put the result;
the useful values are 0 for the value to be ignored, 1
for the value to go onto the stack, 3 for the value to be
the last argument to the previous open call block, and 4
for the value to be returned from this frame.
- Function: %push value
- Pushes value onto the stack. Use this to push the arguments.
- Function: %activate-open-call-block
- Causes the call to happen.
- Function: %pop
- Pops the top value off of the stack and returns it as its value.
Use this to recover the result from a call made by %open-call-block
with a destination of 1.
- Function: %assure-pdl-room n-words
- Call this before doing a sequence of %push's or %open-call-blocks
which will add n-words to the current frame. This subprimitive checks
that the frame will not exceed the maximum legal frame size, which is 255 words
including all overhead. This limit is dictated by the way stack frames are linked together.
If the frame is going to exceed the legal limit, %assure-pdl-room will signal
an error.
20.11 Lambda-Binding Subprimitive
- Function: bind locative value
- Binds the cell pointed to by locative to x, in the caller's
environment. This function is not defined in the interpreted Lisp
environment; it only works from compiled code. Since it turns into an
instruction, the "caller's environment" really means "the binding block
for the stack frame that executed the bind instruction". The preferred
higher-level primitives which turn into this are let ((let-fun)),
let-if ((let-if-fun)), and progv ((progv-fun)).
.br
[This will be renamed to %bind in the future.]
20.12 The Paging System
[Someday this may discuss how it works.]
- Variable: sys:%disk-switches
- This variable contains bits which control various disk usage features.
Bit 0 (the least significant bit) enables read-compares after disk read
operations. This causes a considerable slowdown, so it is rarely used.
Bit 1 enables read-compares after disk write operations.
Bit 2 enables the
multiple page swap-out feature. When this is enabled, as it is by
default, each time a page is swapped out, up to 20 contiguous pages will
also be written out to the disk if they have been modified. This
greatly improves swapping performance.
Bit 3 controls the multiple page swap-in feature, which is also on by
default. This feature causes pages to be swapped in in groups; each
time a page is needed, several contiguous pages are swapped in in the
same disk operation. The number of pages swapped in can be specified
for each area using si:set-swap-recommendations-of-area.
- Function: si:set-swap-recommendations-of-area area-number recommendation
- Specifies that pages of area area-number should be swapped in in
groups of recommendation at a time. This recommendation is used
only if the multiple page swap-in feature is enabled.
Generally, the more memory a machine has, the higher the swap
recommendations should be to get optimum performance.
- Function: si:set-all-swap-recommendations recommendation
- Specifies the swap-in recommendation of all areas at once.
- Function: si:wire-page address &optional (wire-p t)
- If wire-p is t, the page containing address is wired-down; that is,
it cannot be paged-out. If wire-p is nil, the page ceases to be wired-down.
- Function: si:unwire-page address
- (si:unwire-page address) is the same as
(si:wire-page address nil).
- Function: sys:page-in-structure object
- Makes sure that the storage which represents object is in main
memory. Any pages which have been swapped out to disk are read in,
using as few disk operations as possible. Consecutive disk pages are
transferred together, taking advantage of the full speed of the disk.
If object is large, this will be much faster than bringing the pages
in one at a time on demand. The storage occupied by object is defined
by the %find-structure-leader and %structure-total-size subprimitives.
- Function: sys:page-in-array array &optional from to
- This is a version of sys:page-in-structure which can bring in a portion
of an array. from and to are lists of subscripts; if they are shorter
than the dimensionality of array, the remaining subscripts are assumed to
be zero.
- Function: sys:page-in-words address n-words
- Any pages in the range of address space starting at address and
continuing for n-words which have been swapped out to disk are read
in with as few disk operations as possible.
- Function: sys:page-in-area area-number
-
- Function: sys:page-in-region region-number
- All swapped-out pages of the specified region or area are brought into main memory.
- Function: sys:page-out-structure object
-
- Function: sys:page-out-array array &optional from to
-
- Function: sys:page-out-words address n-words
-
- Function: sys:page-out-area area-number
-
- Function: sys:page-out-region region-number
- These are similar to the above, except that take pages out of main
memory rather than bringing them in. Actually, they only mark the pages
as having priority for replacement by others. Use these operations when
you are done with a large object, to make the virtual memory system
prefer reclaiming that object's memory over swapping something else out.
- Function: sys:%change-page-status virtual-address swap-status access-status-and-meta-bits
- The page hash table entry for the page containing virtual-address
is found and altered as specified. t is returned if it was found,
nil if it was not (presumably the page is swapped out.) swap-status
and access-status-and-meta-bits can be nil if those fields are not
to be changed. This doesn't make any error checks; you can really
screw things up if you call it with the wrong arguments.
- Function: sys:%compute-page-hash virtual-address
- This makes the hashing function for the page hash table
available to the user.
- Function: sys:%create-physical-page physical-address
- This is used when adjusting the size of real memory available
to the machine. It adds an entry for the page frame at physical-address
to the page hash table, with virtual address -1, swap status flushable,
and map status 120 (read only). This doesn't make error checks; you
can really screw things up if you call it with the wrong arguments.
- Function: sys:%delete-physical-page physical-address
- If there is a page in the page frame at physical-address,
it is swapped out and its entry is deleted from the page hash table,
making that page frame unavailable for swapping in of pages in the
future. This doesn't make error checks; you
can really screw things up if you call it with the wrong arguments.
- Function: sys:%disk-restore high-16-bits low-16-bits
- Loads virtual memory from the partition named by the concatenation of
the two 16-bit arguments, and starts executing it. The name 0
refers to the default load (the one the machine loads when it is
started up). This is the primitive used by disk-restore (see (disk-restore-fun)).
- Function: sys:%disk-save physical-mem-size high-16-bits low-16-bits
- Copies virtual memory into the partition named by the concatenation
of the two 16-bit arguments (0 means the default), then restarts
the world, as if it had just been restored. The physical-mem-size
argument should come from %sys-com-memory-size in system-communication-area.
This is the primitive used by disk-save (see (disk-save-fun)).
20.13 Closure Subprimitives
These functions deal with things like what closures deal with: the distinction
between internal and external value cells and control over how they work.
- Function: sys:%binding-instances list-of-symbols
- This is the primitive that could be used by closure.
First, if any of the symbols in list-of-symbols has no external
value cell, a new external value cell is created for it, with
the contents of the internal value cell. Then a list of locatives,
twice as long as list-of-symbols, is created and returned.
The elements are grouped in pairs: pointers to the internal
and external value cells, respectively, of each of the symbols.
closure could have been defined by:
| (defun closure (variables function)
(%make-pointer dtp-closure
(cons function (sys:%binding-instances variables))))
|
- Function: sys:%using-binding-instances instance-list
- This function is the primitive operation that invocation of closures
could use. It takes a list such as sys:%binding-instances returns,
and for each pair of elements in the list, it "adds" a binding to the
current stack frame, in the same manner that the bind function
(which should be called %bind) does. These bindings remain in effect
until the frame returns or is unwound.
sys:%using-binding-instances checks for redundant bindings and ignores them.
(A binding is redundant if the symbol is already bound to the desired external
value cell). This check avoids excessive growth of the special pdl in some cases
and is also made by the microcode which invokes closures, entities, and instances.
- Function: sys:%internal-value-cell symbol
- Returns the contents of the internal value cell of symbol.
dtp-one-q-forward pointers are considered invisible, as usual, but
dtp-external-value-cell-pointers are not; this function can
return a dtp-external-value-cell-pointer. Such pointers will be
considered invisible as soon as they leave the "inside of the machine",
meaning internal registers and the stack.
20.14 Microcode Variables
The following variables' values actually reside in the scratchpad memory
of the processor. They are put there by dtp-one-q-forward invisible
pointers. The values of these variables are used by the microcode.
Many of these variables are highly internal and you shouldn't expect to
understand them.
- Variable: %microcode-version-number
- This is the version number of the currently-loaded microcode, obtained
from the version number of the microcode source file.
- Variable: sys:%number-of-micro-entries
- Size of micro-code-entry-area and related areas.
default-cons-area is documented on (default-cons-area-var).
- Variable: sys:number-cons-area
- The area number of the area where bignums and flonums are consed.
Normally this variable contains the value of sys:extra-pdl-area, which
enables the "temporary storage" feature for numbers, saving garbage collection
overhead.
sys:%current-stack-group and sys:%current-stack-group-previous-stack-group
are documented on (sys:%current-stack-group-var).
- Variable: sys:%current-stack-group-state
- The sg-state of the currently-running stack group.
- Variable: sys:%current-stack-group-calling-args-pointer
- The argument list of the currently-running stack group.
- Variable: sys:%current-stack-group-calling-args-number
- The number of arguments to the currently-running stack group.
- Variable: sys:%trap-micro-pc
- The microcode address of the most recent error trap.
- Variable: sys:%initial-fef
- The function which is called when the machine starts up.
Normally this is the definition of si:lisp-top-level.
- Variable: sys:%initial-stack-group
- The stack group in which the machine starts up.
- Variable: sys:%error-handler-stack-group
- The stack group which receives control when a microcode-detected error
occurs. This stack group cleans up, signals the appropriate condition,
or assigns a stack group to run the debugger on the erring stack group.
- Variable: sys:%scheduler-stack-group
- The stack group which receives control when a sequence break occurs.
- Variable: sys:%chaos-csr-address
- A fixnum which is the virtual address which maps to the Unibus location of the
Chaosnet interface.
- Variable: %mar-low
- A fixnum which is the inclusive lower bound of the region of virtual
memory subject to the MAR feature (see (mar)).
- Variable: %mar-high
- A fixnum which is the inclusive upper bound of the region of virtual
memory subject to the MAR feature (see (mar)).
- Variable: sys:%inhibit-read-only
- If non-nil, you can write into read-only areas. This is used by fasload.
self is documented on (self-var).
inhibit-scheduling-flag is documented on (inhibit-scheduling-flag-var).
- Variable: inhibit-scavenging-flag
- If non-nil, the scavenger is turned off. The scavenger is
the quasi-asynchronous portion of the garbage collector,
which normally runs during consing operations.
- Variable: sys:%region-cons-alarm
- Incremented whenever a new region is allocated.
- Variable: sys:%page-cons-alarm
- Increments whenever a new page is allocated.
- Variable: sys:%gc-flip-ready
- t while the scavenger is running, nil when there are no pointers
to oldspace.
- Variable: sys:%gc-generation-number
- A fixnum which is incremented whenever the garbage collector flips, converting
one or more regions from newspace to oldspace.
If this number has changed, the %pointer of an object may have changed.
- Variable: sys:%disk-run-light
- A fixnum which is the virtual address of the TV buffer location of the run-light
which lights up when the disk is active. This plus 2 is the address of the run-light
for the processor. This minus 2 is the address of the run-light for the garbage collector.
- Variable: sys:%loaded-band
- A fixnum which contains the high 24 bits of the name of the disk partition
from which virtual memory was booted. Used to create the greeting message.
- Variable: sys:%disk-blocks-per-track
-
- Variable: sys:%disk-blocks-per-cylinder
- Configuration of the disk being used for paging. Don't change these!
- Variable: sys:%read-compare-enables
- A fixnum which controls extra disk error-checking. Bit 0 enables read-compare
after a read, bit 1 enables read-compare after a write. Normally this is 0.
- Variable: sys:currently-prepared-sheet
- Used for communication between the window system and the microcoded graphics primitives.
The next four have to do with a metering system which is not yet documented in this manual.
- Variable: sys:%meter-global-enable
- t if the metering system is turned on for all stack-groups.
- Variable: sys:%meter-buffer-pointer
- A temporary buffer used by the metering system.
- Variable: sys:%meter-disk-address
- Where the metering system writes its next block of results on the disk.
- Variable: sys:%meter-disk-count
- The number of disk blocks remaining for recording of metering information.
- Variable: sys:a-memory-location-names
- A list of all of the above symbols (and any others added after this documentation
was written).
20.15 Meters
- Function: read-meter name
- Returns the contents of the microcode meter named name, which can be a fixnum
or a bignum. name must be one the symbols listed below.
- Function: write-meter name value
- Writes value, a fixnum or a bignum, into the microcode meter named name.
name must be one the symbols listed below.
The microcode meters are as follows:
.defmeter sys:%count-chaos-transmit-aborts
The number of times transmission on the Chaosnet was aborted, either by a collision
or because the receiver was busy.
.end_defmeter
.defmeter sys:%count-cons-work
.defmeter1 sys:%count-scavenger-work
Internal state of the garbage collection algorithm.
.end_defmeter
.defmeter sys:%tv-clock-rate
The number of TV frames per clock sequence break.
The default value is 67 which causes clock sequence breaks to happen
about once per second.
.end_defmeter
.defmeter sys:%count-first-level-map-reloads
The number of times the first-level virtual-memory map was invalid
and had to be reloaded from the page hash table.
.end_defmeter
.defmeter sys:%count-second-level-map-reloads
The number of times the second-level virtual-memory map was invalid
and had to be reloaded from the page hash table.
.end_defmeter
.defmeter sys:%count-meta-bits-map-reloads
The number of times the virtual address map was reloaded to contain only
"meta bits", not an actual physical address.
.end_defmeter
.defmeter sys:%count-pdl-buffer-read-faults
The number of read references to the pdl buffer which were
virtual memory references that trapped.
.end_defmeter
.defmeter sys:%count-pdl-buffer-write-faults
The number of write references to the pdl buffer which were
virtual memory references that trapped.
.end_defmeter
.defmeter sys:%count-pdl-buffer-memory-faults
The number of virtual memory references which trapped in case
they should have gone to the pdl buffer, but turned out to be
real memory references after all (and therefore were needlessly
slowed down.)
.end_defmeter
.defmeter sys:%count-disk-page-reads
The number of pages read from the disk.
.end_defmeter
.defmeter sys:%count-disk-page-writes
The number of pages written to the disk.
.end_defmeter
.defmeter sys:%count-fresh-pages
The number of fresh (newly-consed) pages created in core,
which would have otherwise been read from the disk.
.end_defmeter
.defmeter sys:%count-disk-page-read-operations
The number of paging read operations; this can be smaller than the number of
disk pages read when more than one page at a time is read.
.end_defmeter
.defmeter sys:%count-disk-page-write-operations
The number of paging write operations; this can be smaller than the number of
disk pages written when more than one page at a time is written.
.end_defmeter
.defmeter sys:%count-disk-prepages-used
The number of times a page was used after being read in before it was needed.
.end_defmeter
.defmeter sys:%count-disk-prepages-not-used
The number of times a page was read in before it was needed, but got evicted
before it was ever used.
.end_defmeter
.defmeter sys:%count-disk-page-write-waits
The number of times the machine waited for a page to finish being written out
in order to evict the page.
.end_defmeter
.defmeter sys:%count-disk-page-write-busys
The number of times the machine waited for a page to finish being written out
in order to do something else with the disk.
.end_defmeter
.defmeter sys:%disk-wait-time
The time spent waiting for the disk, in microseconds. This can be used to
distinguish paging time from running time when measuring and optimizing the`
performance of programs.
.end_defmeter
.defmeter sys:%count-disk-errors
The number of recoverable disk errors.
.end_defmeter
.defmeter sys:%count-disk-recalibrates
The number of times the disk seek mechanism was recalibrated,
usually as part of error recovery.
.end_defmeter
.defmeter sys:%count-disk-ecc-corrected-errors
The number of disk errors which were corrected through the error correcting code.
.end_defmeter
.defmeter sys:%count-disk-read-compare-differences
The number of times a read compare was done, no disk error occurred, but the
data on disk did not match the data in memory.
.end_defmeter
.defmeter sys:%count-disk-read-compare-rereads
The number of times a disk read was done over because after the read a read
compare was done and did not succeed (either it got an error or the data on disk
did not match the data in memory).
.end_defmeter
.defmeter sys:%count-disk-read-compare-rewrites
The number of times a disk write was done over because after the write a read
compare was done and did not succeed (either it got an error or the data on disk
did not match the data in memory).
.end_defmeter
.defmeter sys:%disk-error-log-pointer
Address of the next entry to be written in the disk error log. The function
si:print-disk-error-log (see (si:print-disk-error-log-fun)) prints this log.
.end_defmeter
.defmeter sys:%count-aged-pages
The number of times the page ager set an age trap on a page, to determine
whether it was being referenced.
.end_defmeter
.defmeter sys:%count-age-flushed-pages
The number of times the page ager saw that a page still had an age trap
and hence made it "flushable", a candidate for eviction from main memory.
.end_defmeter
.defmeter sys:%aging-depth
A number from 0 to 3 which controls how long a page must remain unreferenced
before it becomes a candidate for eviction from main memory.
.end_defmeter
.defmeter sys:%count-findcore-steps
The number of pages inspected by the page replacement algorithm.
.end_defmeter
.defmeter sys:%count-findcore-emergencies
The number of times no evictable page was found and extra aging had to be done.
.end_defmeter
- Variable: sys:a-memory-counter-block-names
- A list of all of the above symbols (and any others added after this documentation
was written).
This document was generated
by Brad Parker on June, 13 2006
using texi2html