15. Subprimitives
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.
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.
Subprimitives by their very nature cannot do full checking.
Improper use of subprimitives can destroy the environment.
15.1 Data Types
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.
si:dtp-symbol | The object is a symbol.
|
si:dtp-fix | The object is a fixnum; the numeric value is contained immediately in the pointer field.
|
si:dtp-small-flonum | |
| The object is an immediate small floating-point number.
|
si:dtp-extended-number | |
| The object is a flonum or a bignum. This value will be used for future numeric
types.
|
si:dtp-list | The object is a cons.
|
si:dtp-locative | |
| The object is a locative pointer.
|
si:dtp-array-pointer | |
| The object is an array.
|
si:dtp-fef-pointer | |
| The object is a fef.
|
si:dtp-u-entry | The object is a microcode entry.
|
si:dtp-closure | The object is a closure.
|
si:dtp-stack | The object is a stack.
|
si:dtp-instance | |
| The object is an "active object". These are not documented yet.
|
si:dtp-entity | The same as dtp-closure except it is a kind of "active object".
These are not documented yet.
|
si:dtp-select-method | |
| Another type associated with "active objects" and not documented yet.
|
si:dtp-header | An internal type used to mark the first word of a multi-word structure.
|
si:dtp-array-header | |
| An internal type used in arrays.
|
si:dtp-symbol-header | |
| An internal type used to mark the first word of a symbol.
|
si:dtp-instance-header | |
| An internal type used to mark the first word of an instance.
|
si:dtp-null | Nothing to do with nil . This is used in unbound value and function cells.
|
si:dtp-trap | The zero data-type, which is not used. This hopes to detect microcode errors.
|
si:dtp-free | This type is used to fill free storage, to catch wild references.
|
si:dtp-external-value-cell-pointer | |
| An "invisible pointer" used for external value cells,
which are part of the closure mechanism (see LINK:(closure)).
and used by compiled code to address value and function cells.
|
si: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
(LINK:(structure-forward-fun)).
|
si: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.
|
si:dtp-one-q-forward | |
| An "invisible pointer" used to indicate that the single cell containing
it has been moved elsewhere.
|
si:dtp-gc-forward | |
| This is used by the copying garbage collector to flag old objects that
have already been copied.
|
q-data-types Variable
The value of q-data-types is a list of all of the symbolic
names for data types described above under data-type .
(the symbols whose print names begin
with "dtp- ")
q-data-types
type-code
An array, indexed by the internal numeric data-type code,
which contains the corresponding symbolic names.
15.2 Creating Objects
make-list
area size
This function makes a cdr-coded list of nil s of a
specified length in a specified area.
area is which area to create it in, which may be either a fixnum
or a symbol whose value will be used. size is the number
of words to be allocated. Each word has cdr code cdr-next ,
except for the last which has cdr-nil .
This function is to be used only for making lists. If
making a "structure" (any data type that has a header), use one
of the two functions below. This is because the two classes of object
must be created in different storage regions, for the sake of
system storage conventions and the garbage collector.
%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 cdr codes are initialized as in make-list , currently.
%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.
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 .
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 one-q-forward
invisible pointer is stored into from-symbol 's value cell.
Do not do this when from-symbol is lambda -bound, as
the microcode does not bother to check for that case (doing so would
make binding slower).
15.3 Pointer Manipulation
It should again be emphasized that improper use of these functions
can destroy the Lisp environment, primarily because of interactions
between the garbage collector and the illegal pointers that
can be created by these sub-primitives.
%data-type
x
Returns the data-type field of x , as a fixnum.
%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.
%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. 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.
%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
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.
%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.
%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.
%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, containing 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. These locations are boxed
but their contents is considered garbage, and is not protected by the
garbage collector.
%structure-total-size
object
Returns the total number of words occupied by the representation
of object .
15.4 Special Memory Referencing
%store-conditional
pointer old new
This is the basic locking primitive. pointer points 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.
The following four functions are for I/O programming.
%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.
%unibus-write
address data
Writes the 16-bit number data at the specified Unibus
address, exactly once.
%xbus-read
io-offset
Returns a fixnum which is the low 24 bits of 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.
%xbus-write
io-offset data
Writes the pointer field of data , which should be a fixnum,
into the register at the specified Xbus address.
The high eight bits of the word written are always zero.
io-offset is
an offset into the I/O portion of Xbus physical address space.
This is guaranteed to write the location exactly once.
%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.
%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 . I.e.
it changes the disallowed data type to locative so that you can safely
look at it and see what it points to.
%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 is 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.
%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.
%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.
%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).
%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, unlike
%p-contents and friends.
%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.
%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.
%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.
%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.
%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.
%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.
%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.
%p-pointer
pointer
Extracts the pointer field of the contents of the
location addressed by pointer and returns
it as a fixnum.
%p-data-type
pointer
Extracts the data-type field of the contents of the
location addressed by pointer and returns
it as a fixnum.
%p-cdr-code
pointer
Extracts the cdr-code field of the contents of the
location addressed by pointer and returns
it as a fixnum.
%p-flag-bit
pointer
Extracts the flag-bit field of the contents of the
location addressed by pointer and returns
it as a fixnum.
%p-store-pointer
pointer value
Clobbers the pointer field of the location
addressed by pointer to value , and returns value .
%p-store-data-type
pointer value
Clobbers the data-type field of the location
addressed by pointer to value , and returns value .
%p-store-cdr-code
pointer value
Clobbers the cdr-code field of the location
addressed by pointer to value , and returns value .
%p-store-flag-bit
pointer value
Clobbers the flag-bit field of the location
addressed by pointer to value , and returns value .
%stack-frame-pointer
pointer value
Returns a locative pointer to its caller's stack frame. This
function is not defined in the interpreted Lisp environment; it only works
from 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".
bind
locative value
[This will be renamed to %bind in the future.]
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 FEF
that executed the bind instruction".
%halt
locative value
Stops the machine.
15.5 The Paging System
[Someday this will discuss how it works.]
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.
si:unwire-page
address
(si:unwire-page address) is the same as (si:wire-page address) .
si:%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.
si:%compute-page-hash
virtual-address
This makes the hashing function for the page hash table
available to the user.
si:%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.
si:%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.
si:%disk-restore
high-16-bits low-16-bits
Loads virtual memory from the partition named by the catenation 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).
si:%disk-save
physical-mem-size high-16-bits low-16-bits
Copies virtual memory into the partition named by the catenation
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 .
15.6 The Paging System
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.
%microcode-version-number Variable
This is the version number of the currently-loaded microcode, obtained
from the version number of the microcode source file.
sys:%number-of-micro-entries Variable
Size of micro-code-entry-area and related areas. Currently the
data-type is missing from this number.
default-cons-area Variable
The area number of the default area in which new data are to be consed.
This is normally working-storage-area .
si:%initial-fef Variable
The function which is called when the machine starts up.
Normally si:lisp-top-level .
%error-handler-stack Variable
The stack which receives control when a microcode-detected error
occurs. This stack cleans up, signals the appropriate condition,
or enters the debugger.
si:%current-stack Variable
The stack which is currently running.
%initial-stack Variable
The stack in which the machine starts up.
si:%current-stack-state Variable
The sg-state of the currently-running stack.
si:%current-stack-previous-stack Variable
The resumer of the currently-running stack.
si:%current-stack-calling-args-pointer Variable
The argument list of the currently-running stack.
si:%current-stack-calling-args-number Variable
The number of arguments to the currently-running stack.
si:%trap-micro-pc Variable
The microcode address of the most recent error trap.
si:%count-first-level-map-reloads Variable
The number of times the first-level virtual-memory map was invalid
and had to be reloaded from the page hash table.
si:%count-second-level-map-reloads Variable
The number of times the second-level virtual-memory map was invalid
and had to be reloaded from the page hash table.
si:%count-pdl-buffer-read-faults Variable
The number of read references to the pdl buffer which happened
as virtual memory references which trapped.
si:%count-pdl-buffer-write-faults Variable
The number of read references to the pdl buffer which happened
as virtual memory references which trapped.
si:%count-pdl-buffer-memory-faults Variable
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.)
si:%count-disk-page-reads Variable
The number of pages read from the disk.
si:%count-disk-page-writes Variable
The number of pages written to the disk.
si:%count-disk-errors Variable
The number of recoverable disk errors.
si:%count-fresh-pages Variable
The number of fresh (newly-consed) pages created in core,
which would have otherwise been read from the disk.
si:%aging-rate Variable
The number of age steps per disk read or write. This parameter
controls how long a page must remain unreferenced before it is
evicted from main memory.
si:%count-aged-pages Variable
The number of times the page ager set an age trap on a page, to determine
whether it was being referenced.
si:%count-age-flushed-pages Variable
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.
%mar-low Variable
A fixnum which is the inclusive lower bound of the region of virtual
memory subject to the MAR feature.
%mar-high Variable
A fixnum which is the inclusive upper bound of the region of virtual
memory subject to the MAR feature.
%self Variable
The instance which has just been called. (See LINK:(instance).)
%method-class Variable
The class in which the current method was found. (See LINK:(method).)
inhibit-scheduling-flag Variable
If non-nil , no process other than the current process can
run.
inhibit-scavenging-flag Variable
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.