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-symbolThe object is a symbol.
si:dtp-fixThe 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-listThe 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-entryThe object is a microcode entry.
si:dtp-closureThe object is a closure.
si:dtp-stackThe object is a stack.
si:dtp-instance
The object is an "active object". These are not documented yet.
si:dtp-entityThe 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-headerAn 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-nullNothing to do with nil . This is used in unbound value and function cells.
si:dtp-trapThe zero data-type, which is not used. This hopes to detect microcode errors.
si:dtp-freeThis 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-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.
%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.