Squeak
  links to this page:    
View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide
StackInterpreter
Last updated at 5:58 am UTC on 11 February 2020
Part of the VMMaker package.

This class is a complete implementation of the Smalltalk-80 virtual machine, derived originally from the Blue Book specification but quite different in some areas.

This VM supports Closures but not old-style BlockContexts.

It has been modernized

The VM does not use Contexts directly. Instead Contexts serve as proxies for a more conventional stack format that is invisible to the image. There is considerable explanation at http://www.mirandabanda.org/cogblog/2009/01/14/under-cover-contexts-and-the-big-frame-up. The VM maintains a fixed-size stack zone divided into pages, each page being capable of holding several method/block activations. A send establishes a new frame in the current stack page, a return returns to the previous frame. This eliminates allocation/deallocation of contexts and the moving of receiver and arguments from caller to callee on each send/return. Contexts are created lazily when an activation needs a context (creating a block, explicit use of thisContext, access to sender when sender is a frame, or linking of stack pages together). Contexts are either conventional and heap-resident ("single") or "married" and serve as proxies for their corresponding frame or "widowed", meaning that their spouse frame has been returned from (died). A married context is specially marked (more details in the code) and refers to its frame. Likewise a married frame is specially marked and refers to its context.

In addition to SmallInteger arithmetic and Floats, the VM supports logic on 32-bit (and 64-bit) PositiveLargeIntegers, thus allowing it to simulate itself much more efficiently than would otherwise be the case.

StackInterpreter and subclasses support multiple memory managers.

StackInterpreter is designed to be subclassed by CoInterpreter et al. CoInterpreter cooperates with a bytecode to machine-code JIT compiler (Cogit), for much higher performance


Initialisation of primitives

 StackInterpreter class>>#initializePrimitiveTable 
in the VMMaker.oscog package in source.squeak.org/VMMaker.
see List of primitives

Instance Variables


atCache
	- a small array holding tuples of oop => format,fixedFields,size to speed up at:[put:].  Unused in CoInterpreter

breakLookupClassTag
	- if non-nil, the class tag to break on sends, breaking (calling warning) if there's a match

breakSelector
	- if breakSelectorLength ~= 0, a pointer to a string to compare messageSelector against on send, breaking (calling warning) if there's a match

breakSelectorLength
	- if > 0, breakSelector is checked on each send.  If < 0, breakSelector is checked on each MNU

bytecodeSetSelector
	- if multiple bytecode sets are in use this is the offset (0 or 256) for the current bytecode set

checkAllocFiller
	- a variable used to fill eden to allow checking for overwriting the end of an object

checkedPluginName
	- the oop of a symbol which, when gcmode is GCCheckPrimCall, can check for heap memory leaks after a specific primitive has been called

classByteArrayCompactIndex
	- the compact class index of the class ByteArray, if appropriate

classNameIndex
	- the slot index of name in a class object, used or debug printing, derived from class Array at start-up

currentBytecode
	- the value of the currentBytecode

debugCallbackInvokes
	- a counter used to debug the old (Python) callback support

debugCallbackPath
	- a variable used to hold the path through the new callback support

debugCallbackReturns
	- a counter used to debug the old (Python) callback support; it should match debugCallbackInvokes

deferDisplayUpdates
	- the variable that implements primitive 126, primitiveDeferDisplayUpdates

desiredEdenBytes
	- the desired size of eden, used at image load and snapshot time

desiredNumStackPages
	- the desired number of stack pages, used at image load and snapshot time

displayBits
	- either the first indexable field of the current display object, or the handle of the current display surface

displayDepth
	- pixel depth of the current display object or surface

displayHeight
	- height in pixels of the current display object or surface

displayWidth
	- width in pixels of the current display object or surface

extA
	- if a prefix btecode set, such as SstaV1, is in use, the accumulator for extension A

extB
	- if a prefix btecode set, such as SstaV1, is in use, the accumulator for extension B

externalPrimitiveTable
	- xxxxx

externalPrimitiveTableFirstFreeIndex
	- a small array cacheing the target function pointer for external calls (primitiveExternalCall)

extraFramesToMoveOnOverflow
	- a variable used to prevent thrashing on sends and returns at the end of a page (see overflowedPage)

extraVMMemory
	- in Spur, free heap to be allocated at startup.  In V3, C memory to reserve for malloc at startup (i.e. malloc extraVMMemory, alloc heap, free extraVMMemory)

framePointer
	- the pointer to the current frame when primitives (or in the CoInterpreter, when machine-code <-> interpreter transitions) are invoked (c.f. localFP)

fullScreenFlag
	- true if the system is in full-screen mode

gcSemaphoreIndex
	- if non-zero, the index in the semaphore table of a semaphore to signal after any GC

globalSessionID
	- a non-zero number (derived from the time) identifying the current session

highestRunnableProcessPriority
	- a tide mark in the runnableProcesses array, used to reduce the time spent scanning the array looking for the highest priority runnable process.  This variable is set high when the priority of the highest process is unknown, and set to the highest found when the array is scanned.  Hence most of the time the nused entries in the array are not scanned.

imageFloatsBigEndian
	- true if the order of data in floats is big-endian

imageHeaderFlags
	- the flags stored in the image at load time or to be stored in the image at snapshto time.  These flags identify various options, sich as whether floats are in platfrm order.

inIOProcessEvents
	- true if the system is receiving events in ioProcessEvents, used to avoid recursion when receiuving events via callbacks

instructionPointer
	- the pointer to the current bytecode when primitives (or in the CoInterpreter, when machine-code <-> interpreter transitions) are invoked (c.f. localIP)

interpreterProxy
	- the table of functions used to export interpreter and memory manager functions to plugin primitives

interruptCheckChain
	- if non nil a funciton pointer to be called when a user interrupt event is received, used by plugin primitives to abort long-running calls on interrupt

interruptKeycode
	- the keycode of the event signifying a user interrupt

interruptPending
	- a variable set by ioProcessEvents if a user interrupt is pending

jmpBuf
	- a small array of jmpbufs (for setjmp/longjmp) used to manage returning in the iold (Python) callback support (see suspendedCallbacks et al)

jmpDepth
	- the index of the next free entry in jmpBuf

lastMethodCacheProbeWrite
	- the index of the last write into the method lookup cache, used by primitiveExternalCall to rewrite the method cache entry to call the target function, avoiding going through primitiveExternalCall on every plugin primitive dispatch

lkupClass
	- the implicit class argument to the class hierarchy looup routines such as lookupOrdinarySend

lkupClassTag
	- the implicit class tag argument to message send lookup

localAbsentReceiver
	- Newspeak, the absent receiver in any Newspeak absent receiver send

localAbsentReceiverOrZero
	- Newspeak, if non-zero, the absent receiver in any Newspeak outer absent receiver send

localFP
	- the frame pointer in the fully-inlined interpret routine, hopfully allowing a C compiler to assign localFP to a register variable (c.f. framePointer)

localIP
	- the instruction pointer in the fully-inlined interpret routine, hopfully allowing a C compiler to assign localFP to a register variable (c.f. instructionPointer)

localReturnValue
	- the value being returned in return bytecodes

localSP
	- the stack pointer in the fully-inlined interpret routine, hopfully allowing a C compiler to assign localFP to a register variable (c.f. framePointer)

longRunningPrimitiveCheckMethod
	- a variable used to monitor long-running primtiives via primitiveLongRunningPrimitive

longRunningPrimitiveCheckSemaphore
	- a variable used to monitor long-running primtiives via primitiveLongRunningPrimitive

longRunningPrimitiveCheckSequenceNumber
	- a variable used to monitor long-running primtiives via primitiveLongRunningPrimitive

longRunningPrimitiveGCUsecs
	- a variable used to monitor long-running primtiives via primitiveLongRunningPrimitive

longRunningPrimitiveSignalUndelivered
	- a variable used to monitor long-running primtiives via primitiveLongRunningPrimitive

longRunningPrimitiveStartUsecs
	- a variable used to monitor long-running primtiives via primitiveLongRunningPrimitive

longRunningPrimitiveStopUsecs
	- a variable used to monitor long-running primtiives via primitiveLongRunningPrimitive

lowcodeCalloutState
	- Lowcode, the state used to marshall an outgoing Lowcode call

maxExtSemTabSizeSet
	- a flag stating whether the maximum size of the external semaphore table has been set or not

metaAccessorDepth
	- Spur, the accessor depth of a primitive being invoked by one of the meta primitive primitives, primitiveDoPrimitiveWithArgs and primitiveDoNamedPrimitiveWithArgs

metaclassNumSlots
	- teh size of a Metaclass instanc, set at startup, used for debug printing

method
	- the oop of the current method

methodCache
	- a small array holding tuples of selector x class => method,functionPointer to speed up message send (avoid class hierarchy search on send)

methodDictLinearSearchLimit
	- a variable used to control searching of method dictionaries.  Dictionaries of size within the limit are searched linearly instead of hashed.  This can be used either to speed up search in small dictionaries or to turn off hashed lookup wen hashing needs to be changed

nativeSP
	- Lowcode, the native (C) stack pointer (?; then why nativeStackPointer?)

nativeStackPointer
	- Lowcode, the native (C) stack pointer (?; then why nativeSP?)

nextPollUsecs
	- if non-zero, the micosecond clock value at which to next poll for events, used to control event polling rate

nextWakeupUsecs
	- if non-zero, the micosecond clock value at which the next delay expires

nsMethodCache
	- Newspeak, a small array hilding tuples of selector x class tag x calling method x privacy code => target method,primitive function,actual receiver, used to speed up Newspeak absent receiver sends

numExtB
	- the number of bytes in extB, used to correctly maintain extB, given that it is unsigned

numStackPages
	- the number of stack pages being used

overflowedPage
	- the stack page that a send last overflowed, used to avoid thrashing on send and return at the end of a stack page (see extraFramesToMoveOnOverflow)

pendingFinalizationSignals
	- a variable used to control signalling the finalizationSemahpore

primitiveAccessorDepthTable
	- Spur, the accessor depths for the iundexed primitives, used to determine how much state to scan loking for forwarders on primitive failure

primitiveFunctionPointer
	- the function pointer (in simulation, the selector symbol) of the current primitive, nil for newMethod if there is no primitive

primitiveTable
	- the table holding the functions (in simulation the selector symbols) for the indexed primitives

savedWindowSize
	- the display size to write into a snapshot.  Avoids writing a zero window size into a snapshot when an image is loaded headless.  

shadowCallStackPointer
	- Lowcode, the shadow stack pointer, used when marshalling Lowcode external calls

showSurfaceFn
	- if non-zero, the function to call to update the display when the current display is a surface

stackLimit
	- the variable marking the end of the current stack page, also used to break out of interpretation to check for events.  When marking the end of a page, it enables a send to create an activation on a new page,  When set so that any send would fail the stack limit check, causes a check for events on stack page overflow

stackPage
	- the current stack page

stackPages
	- the set of stack pages

stackPointer
	- the pointer to the top of stack in the current frame when primitives (or in the CoInterpreter, when machine-code <-> interpreter transitions) are invoked (c.f. localSP)

statCheckForEvents
	- the count of checkForEventsMaybeContextSwitch: calls

statForceInterruptCheck
	- the count of forceInterruptCheck calls

statIOProcessEvents
	- the count of ioProcessEvents calls

statIdleUsecs
	- the count of microseconds at which the system is at idle (a bad idea; this should be replaced by its inverse; asking the OS how long the VM process has been active)

statPendingFinalizationSignals
	- the count of pendingFinalizationSignals

statProcessSwitch
	- the count of process switches

statStackOverflow
	- the count of stack overflows

statStackPageDivorce
	- the cound of stack page divorces (a stack page divorce occurs when a stack page must be freed for use)

suppressHeartbeatFlag
	- a flag controlling whether the heatbeat is in effect; the heartbeat is used to set stackLimit periodically to cause break out to chedck for events (see stackLimit)

suspendedCallbacks
	- a small array holding the processes suspended when the old callback machinery is in use (see jmpBuf et al)

suspendedMethods
	- a small array holding the methods of the processes suspended when the old callback machinery is in use

tempOop
	- if non-zero, an oop that may move during primitive execution

tempOop2
	- if non-zero, an oop that may move during primitive execution

the2ndUnknownShort
	- the value of a field in the image header that is unused in the StackInterpreter but used in the CoInterpreter (and hence to be preserved in snapshots)

theUnknownShort
	- the value of a field in the image header that is unused in the StackInterpreter but used in the CoInterpreter (and hence to be preserved in snapshots)

thisClassIndex
	- the index in a Metaclass of thisClass (the instance of the metaclass) used in debug printing