VM Maker: VMMaker.oscog-eem.2951.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

VM Maker: VMMaker.oscog-eem.2951.mcz

commits-2
 
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2951.mcz

==================== Summary ====================

Name: VMMaker.oscog-eem.2951
Author: eem
Time: 13 April 2021, 6:11:29.780025 pm
UUID: 5ebb0375-9fe1-4133-b602-5f607dd20f3e
Ancestors: VMMaker.oscog-eem.2950

All debug printing routines must use <export: true> not <api> to be accessible on win32.

=============== Diff against VMMaker.oscog-eem.2950 ===============

Item was changed:
  ----- Method: CoInterpreter>>printCogMethod: (in category 'debug printing') -----
  printCogMethod: cogMethod
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  <var: #cogMethod type: #'CogMethod *'>
  | address primitive |
  self cCode: ''
  inSmalltalk:
  [self transcript ensureCr.
  cogMethod isInteger ifTrue:
  [^self printCogMethod: (self cCoerceSimple: cogMethod to: #'CogMethod *')]].
  address := cogMethod asInteger.
  self printHex: address;
  print: ' <-> ';
  printHex: address + cogMethod blockSize.
  cogMethod cmType = CMMethod ifTrue:
  [self print: ': method: ';
  printHex: cogMethod methodObject.
  primitive := self primitiveIndexOfMethod: cogMethod methodObject
  header: cogMethod methodHeader.
  primitive ~= 0 ifTrue:
  [self print: ' prim '; printNum: primitive].
  ((objectMemory addressCouldBeObj: cogMethod methodObject)
  and: [objectMemory addressCouldBeObj: (self methodClassOf: cogMethod methodObject)]) ifTrue:
  [self space; printNameOfClass: (self methodClassOf: cogMethod methodObject) count: 2]].
  cogMethod cmType = CMBlock ifTrue:
  [self print: ': block home: ';
  printHex: (self cCoerceSimple: cogMethod to: #'CogBlockMethod *') cmHomeMethod asUnsignedInteger].
  cogMethod cmType = CMClosedPIC ifTrue:
  [self print: ': Closed PIC N: ';
  printHex: cogMethod cPICNumCases].
  cogMethod cmType = CMOpenPIC ifTrue:
  [self print: ': Open PIC '].
  self print: ' selector: '; printHex: cogMethod selector.
  cogMethod selector = objectMemory nilObject
  ifTrue: [| s |
  (cogMethod cmType = CMMethod
  and: [(s := self maybeSelectorOfMethod: cogMethod methodObject) notNil])
  ifTrue: [self print: ' (nil: '; printStringOf: s; print: ')']
  ifFalse: [self print: ' (nil)']]
  ifFalse: [self space; printStringOf: cogMethod selector].
  self cr!

Item was changed:
  ----- Method: CoInterpreter>>printFrame:WithSP: (in category 'debug printing') -----
  printFrame: theFP WithSP: theSP
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | theMethod theMethodEnd numArgs numTemps rcvrAddress topThing |
  <inline: false>
  <var: #theFP type: #'char *'>
  <var: #theSP type: #'char *'>
  <var: #addr type: #'char *'>
  <var: #rcvrAddress type: #'char *'>
  <var: #cogMethod type: #'CogBlockMethod *'>
  <var: #homeMethod type: #'CogMethod *'>
  self cCode: '' inSmalltalk: [self transcript ensureCr].
  (stackPages couldBeFramePointer: theFP) ifNil:
  [self printHexPtr: theFP; print: ' is not in the stack zone?!!'; cr.
  ^nil].
  (self isMachineCodeFrame: theFP)
  ifTrue:
  [| cogMethod homeMethod |
  cogMethod := self mframeCogMethod: theFP.
  homeMethod := self mframeHomeMethod: theFP.
  theMethod := homeMethod asInteger.
  theMethodEnd := homeMethod asInteger + homeMethod blockSize.
  numArgs := cogMethod cmNumArgs.
  numTemps := self temporaryCountOfMethodHeader: homeMethod methodHeader]
  ifFalse:
  [theMethod := self frameMethodObject: theFP.
  theMethodEnd := theMethod + (objectMemory sizeBitsOfSafe: theMethod).
  numArgs := self iframeNumArgs: theFP.
  numTemps := self tempCountOf: theMethod].
  (self frameIsBlockActivation: theFP) ifTrue:
  [| rcvrOrClosure |
  "No BlockLocalTempCounter in the Cogit's C code, so quick hack is to use numCopied + numArgs"
  rcvrOrClosure := self pushedReceiverOrClosureOfFrame: theFP.
  ((objectMemory isNonImmediate: rcvrOrClosure)
  and: [(objectMemory addressCouldBeObj: rcvrOrClosure)
  and: [(objectMemory fetchClassOfNonImm: rcvrOrClosure) = (objectMemory splObj: ClassBlockClosure)]])
  ifTrue: [numTemps := numArgs + (self stSizeOf: rcvrOrClosure)]
  ifFalse: [numTemps := numArgs]].
  self shortPrintFrame: theFP.
  (self isBaseFrame: theFP) ifTrue:
  [self printFrameOop: '(caller ctxt'
  at: theFP + (self frameStackedReceiverOffset: theFP) + (2 * objectMemory wordSize).
  self printFrameOop: '(saved ctxt'
  at: theFP + (self frameStackedReceiverOffset: theFP) + (1 * objectMemory wordSize)].
  self printFrameOop: 'rcvr/clsr'
  at: theFP + FoxCallerSavedIP + ((numArgs + 1) * objectMemory wordSize).
  numArgs to: 1 by: -1 do:
  [:i|
  self printFrameOop: 'arg' index: numArgs - i at: theFP + FoxCallerSavedIP + (i * objectMemory wordSize)].
  self printFrameThing: 'caller ip'
  at: theFP + FoxCallerSavedIP
  extraString: ((stackPages longAt: theFP + FoxCallerSavedIP) = cogit ceReturnToInterpreterPC ifTrue:
  ['ceReturnToInterpreter']).
  self printFrameThing: 'saved fp' at: theFP + FoxSavedFP.
  self printFrameMethodFor: theFP.
  (self isMachineCodeFrame: theFP) ifTrue:
  [self printFrameFlagsForFP: theFP].
  self printFrameOop: 'context' at: theFP + FoxThisContext.
  (self isMachineCodeFrame: theFP) ifFalse:
  [self printFrameFlagsForFP: theFP].
  (self isMachineCodeFrame: theFP)
  ifTrue: [rcvrAddress := theFP + FoxMFReceiver]
  ifFalse:
  [self printFrameThing: 'saved ip'
  at: theFP + FoxIFSavedIP
  extra: ((self iframeSavedIP: theFP) = 0
  ifTrue: [0]
  ifFalse: [(self iframeSavedIP: theFP) - theMethod + 2 - objectMemory baseHeaderSize]).
  rcvrAddress := theFP + FoxIFReceiver].
  self printFrameOop: 'receiver' at: rcvrAddress.
  topThing := stackPages longAt: theSP.
  (self oop: topThing isGreaterThanOrEqualTo: theMethod andLessThan: theMethodEnd)
  ifTrue:
  [rcvrAddress - objectMemory wordSize to: theSP + objectMemory wordSize by: objectMemory wordSize negated do:
  [:addr| | index |
  index := rcvrAddress - addr / objectMemory wordSize + numArgs.
  index <= numTemps
  ifTrue: [self printFrameOop: 'temp' index: index - 1 at: addr]
  ifFalse: [self printFrameOop: ((self frameIsBlockActivation: theFP)
  ifTrue: ['temp/stck']
  ifFalse: ['stck'])
  at: addr]].
  self printFrameThing: 'frame ip'
  at: theSP
  extra: ((self isMachineCodeFrame: theFP)
  ifTrue: [topThing - theMethod]
  ifFalse: [topThing - theMethod + 2 - objectMemory baseHeaderSize])]
  ifFalse:
  [rcvrAddress - objectMemory wordSize to: theSP by: objectMemory wordSize negated do:
  [:addr| | index |
  index := rcvrAddress - addr / objectMemory wordSize + numArgs.
  index <= numTemps
  ifTrue: [self printFrameOop: 'temp' index: index - 1 at: addr]
  ifFalse: [self printFrameOop: ((self frameIsBlockActivation: theFP)
  ifTrue: ['temp/stck']
  ifFalse: ['stck'])
  at: addr]]]!

Item was changed:
  ----- Method: CoInterpreter>>printMethodCacheFor: (in category 'debug printing') -----
  printMethodCacheFor: thing
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | n |
  n := 0.
  0 to: MethodCacheSize - 1 by: MethodCacheEntrySize do:
  [:i | | s c m p |
  s := methodCache at: i + MethodCacheSelector.
  c := methodCache at: i + MethodCacheClass.
  m := methodCache at: i + MethodCacheMethod.
  p := methodCache at: i + MethodCachePrimFunction.
  ((thing = -1 or: [s = thing or: [c = thing or: [p = thing or: [m = thing
  or: [(objectMemory addressCouldBeObj: m)
  and: [(self maybeMethodHasCogMethod: m)
  and: [(self cogMethodOf: m) asInteger = thing]]]]]]])
  and: [(objectMemory addressCouldBeOop: s)
  and: [c ~= 0
  and: [(self addressCouldBeClassObj: c)
  or: [self addressCouldBeClassObj: (objectMemory classForClassTag: c)]]]]) ifTrue:
  [n := n + 1.
  self cCode: [] inSmalltalk: [self transcript ensureCr].
  self printNum: i; space; printHexnp: i; cr; tab.
  (objectMemory isBytesNonImm: s)
  ifTrue: [self cCode: 'printf("%" PRIxSQPTR " %.*s\n", s, (int)(numBytesOf(s)), (char *)firstIndexableField(s))'
  inSmalltalk: [self printHex: s; space; print: (self stringOf: s); cr]]
  ifFalse: [self shortPrintOop: s].
  self tab.
  (self addressCouldBeClassObj: c)
  ifTrue: [self shortPrintOop: c]
  ifFalse: [self printNum: c; space; printHexnp: c; space; shortPrintOop: (objectMemory classForClassTag: c)].
  self tab; shortPrintOop: m; tab.
  self cCode:
  [p > 1024
  ifTrue: [self printHexnp: p]
  ifFalse: [self printNum: p]]
  inSmalltalk:
  [p isSymbol ifTrue: [self print: p] ifFalse: [self printNum: p]].
  self cr]].
  n > 1 ifTrue:
  [self printNum: n; cr]!

Item was changed:
  ----- Method: CogMethodZone>>whereIsMaybeCodeThing: (in category 'debug printing') -----
  whereIsMaybeCodeThing: anOop
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32"
+ <returnTypeC: #'char *'>
- <api>
- <returnTypeC: 'char *'>
  (self oop: anOop isGreaterThanOrEqualTo: cogit cogCodeBase andLessThan: limitAddress) ifTrue:
  [(self oop: anOop isLessThan: cogit minCogMethodAddress) ifTrue:
  [^' is in generated runtime'].
  (self oop: anOop isLessThan: mzFreeStart) ifTrue:
  [^' is in generated methods'].
  (self oop: anOop isLessThan: youngReferrers) ifTrue:
  [^' is in code zone'].
  ^' is in young referrers'].
  ^nil!

Item was changed:
  ----- Method: NewObjectMemory>>longPrintReferencesTo: (in category 'debug printing') -----
  longPrintReferencesTo: anOop
  "Scan the heap long printing the oops of any and all objects that refer to anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  | oop i prntObj |
- <api>
  prntObj := false.
  oop := self firstAccessibleObject.
  [oop = nil] whileFalse:
  [((self isPointersNonImm: oop) or: [self isCompiledMethod: oop]) ifTrue:
  [(self isCompiledMethod: oop)
  ifTrue:
  [i := (self literalCountOf: oop) + LiteralStart]
  ifFalse:
  [(self isContextNonImm: oop)
  ifTrue: [i := CtxtTempFrameStart + (coInterpreter fetchStackPointerOf: oop)]
  ifFalse: [i := self lengthOf: oop]].
  [(i := i - 1) >= 0] whileTrue:
  [anOop = (self fetchPointer: i ofObject: oop) ifTrue:
  [self printHex: oop; print: ' @ '; printNum: i; cr.
  prntObj := true.
  i := 0]].
  prntObj ifTrue:
  [prntObj := false.
  coInterpreter longPrintOop: oop]].
  oop := self accessibleObjectAfter: oop]!

Item was changed:
  ----- Method: NewObjectMemory>>printActivationsOf: (in category 'debug printing') -----
  printActivationsOf: aMethodObj
  "Scan the heap printing the oops of any and all contexts that refer to anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  | oop |
- <api>
  oop := self firstAccessibleObject.
  [oop = nil] whileFalse:
  [((self isContextNonImm: oop)
   and: [aMethodObj = (self fetchPointer: MethodIndex ofObject: oop)]) ifTrue:
  [coInterpreter
  printHex: oop; space; printOopShort: oop; print: ' pc ';
  printHex: (self fetchPointer: InstructionPointerIndex ofObject: oop); cr].
  oop := self accessibleObjectAfter: oop]!

Item was changed:
  ----- Method: NewObjectMemory>>printContextReferencesTo: (in category 'debug printing') -----
  printContextReferencesTo: anOop
  "Scan the heap printing the oops of any and all contexts that refer to anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  | oop i |
- <api>
  oop := self firstAccessibleObject.
  [oop = nil] whileFalse:
  [(self isContextNonImm: oop) ifTrue:
  [i := CtxtTempFrameStart + (coInterpreter fetchStackPointerOf: oop)].
  [(i := i - 1) >= 0] whileTrue:
  [anOop = (self fetchPointer: i ofObject: oop) ifTrue:
  [coInterpreter
  printHex: oop; print: ' @ '; printNum: i; space; printOopShort: oop;
  print: ' pc '; printHex: (self fetchPointer: InstructionPointerIndex ofObject: oop); cr.
  i := 0]].
  oop := self accessibleObjectAfter: oop]!

Item was changed:
  ----- Method: NewObjectMemory>>printObjectsFrom:to: (in category 'debug printing') -----
  printObjectsFrom: startAddress to: endAddress
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | oop |
  oop := startAddress.
  [self oop: oop isLessThan: endAddress] whileTrue:
  [(self isFreeObject: oop) ifFalse:
  [coInterpreter printOop: oop].
  oop := self objectAfter: oop].!

Item was changed:
  ----- Method: NewObjectMemory>>printReferencesTo: (in category 'debug printing') -----
  printReferencesTo: anOop
  "Scan the heap printing the oops of any and all objects that refer to anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  | oop i |
- <api>
  oop := self firstAccessibleObject.
  [oop = nil] whileFalse:
  [((self isPointersNonImm: oop) or: [self isCompiledMethod: oop]) ifTrue:
  [(self isCompiledMethod: oop)
  ifTrue:
  [i := (self literalCountOf: oop) + LiteralStart]
  ifFalse:
  [(self isContextNonImm: oop)
  ifTrue: [i := CtxtTempFrameStart + (coInterpreter fetchStackPointerOf: oop)]
  ifFalse: [i := self lengthOf: oop]].
  [(i := i - 1) >= 0] whileTrue:
  [anOop = (self fetchPointer: i ofObject: oop) ifTrue:
  [coInterpreter printHex: oop; print: ' @ '; printNum: i; space; printOopShort: oop; cr.
  i := 0]]].
  oop := self accessibleObjectAfter: oop]!

Item was changed:
  ----- Method: NewObjectMemory>>printWronglySizedContexts: (in category 'debug printing') -----
  printWronglySizedContexts: printContexts
  "Scan the heap printing the oops of any and all contexts whose size is not either SmallContextSize or LargeContextSize"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  | oop |
- <api>
  oop := self firstAccessibleObject.
  [oop = nil] whileFalse:
  [((self isContextNonImm: oop)
    and: [self badContextSize: oop]) ifTrue:
  [self printHex: oop; space; printNum: (self numBytesOf: oop); cr.
  printContexts ifTrue:
  [coInterpreter printContext: oop]].
  oop := self accessibleObjectAfter: oop]!

Item was changed:
  ----- Method: ObjectMemory>>longPrintInstancesOf: (in category 'debug printing') -----
  longPrintInstancesOf: aClassOop
  "Scan the heap printing the oops of any and all objects that are instances of aClassOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32"
  | oop |
- <api>
  oop := self firstAccessibleObject.
  [oop = nil] whileFalse:
  [(self fetchClassOfNonImm: oop) = aClassOop ifTrue:
  [self longPrintOop: oop; cr].
  oop := self accessibleObjectAfter: oop]!

Item was changed:
  ----- Method: ObjectMemory>>printActivationsOf: (in category 'debug printing') -----
  printActivationsOf: aMethodObj
  "Scan the heap printing the oops of any and all contexts that refer to anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32"
  | oop |
- <api>
  oop := self firstAccessibleObject.
  [oop = nil] whileFalse:
  [((self isContextNonImm: oop)
   and: [aMethodObj = (self fetchPointer: MethodIndex ofObject: oop)]) ifTrue:
  [self interpreter
  printHex: oop; space; printOopShort: oop; print: ' pc ';
  printHex: (self fetchPointer: InstructionPointerIndex ofObject: oop); cr].
  oop := self accessibleObjectAfter: oop]!

Item was changed:
  ----- Method: ObjectMemory>>printContextReferencesTo: (in category 'debug printing') -----
  printContextReferencesTo: anOop
  "Scan the heap printing the oops of any and all contexts that refer to anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32"
  | oop i |
- <api>
  oop := self firstAccessibleObject.
  [oop = nil] whileFalse:
  [(self isContextNonImm: oop) ifTrue:
  [i := CtxtTempFrameStart + (self fetchStackPointerOf: oop)].
  [(i := i - 1) >= 0] whileTrue:
  [anOop = (self fetchPointer: i ofObject: oop) ifTrue:
  [self interpreter printHex: oop; print: ' @ '; printNum: i; space; printOopShort: oop; cr.
  i := 0]].
  oop := self accessibleObjectAfter: oop]!

Item was changed:
  ----- Method: ObjectMemory>>printInstancesOf: (in category 'debug printing') -----
  printInstancesOf: aClassOop
  "Scan the heap printing the oops of any and all objects that are instances of aClassOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32"
  | oop |
- <api>
  oop := self firstAccessibleObject.
  [oop = nil] whileFalse:
  [(self fetchClassOfNonImm: oop) = aClassOop ifTrue:
  [self printHex: oop; cr].
  oop := self accessibleObjectAfter: oop]!

Item was changed:
  ----- Method: ObjectMemory>>printMethodImplementorsOf: (in category 'debug printing') -----
  printMethodImplementorsOf: anOop
  "Scan the heap printing the oops of any and all methods that implement anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32"
- <api>
  | obj |
  obj := self firstAccessibleObject.
  [obj = nil] whileFalse:
  [((self isCompiledMethod: obj)
   and: [(self maybeSelectorOfMethod: obj) = anOop]) ifTrue:
  [self printHex: obj; space; printOopShort: obj; cr]]!

Item was changed:
  ----- Method: ObjectMemory>>printMethodReferencesTo: (in category 'debug printing') -----
  printMethodReferencesTo: anOop
  "Scan the heap printing the oops of any and all objects that refer to anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32"
  | oop i |
- <api>
  oop := self firstAccessibleObject.
  [oop = nil] whileFalse:
  [(self isCompiledMethod: oop) ifTrue:
  [i := (self literalCountOf: oop) + LiteralStart - 1.
  [i >= 0] whileTrue:
  [anOop = (self fetchPointer: i ofObject: oop) ifTrue:
  [self printHex: oop; print: ' @ '; printNum: i; cr.
  i := 0].
  i := i - 1]].
  oop := self accessibleObjectAfter: oop]!

Item was changed:
  ----- Method: ObjectMemory>>printReferencesTo: (in category 'debug printing') -----
  printReferencesTo: anOop
  "Scan the heap printing the oops of any and all objects that refer to anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32"
  | oop i |
- <api>
  oop := self firstAccessibleObject.
  [oop = nil] whileFalse:
  [((self isPointersNonImm: oop) or: [self isCompiledMethod: oop]) ifTrue:
  [(self isCompiledMethod: oop)
  ifTrue:
  [i := (self literalCountOf: oop) + LiteralStart]
  ifFalse:
  [(self isContextNonImm: oop)
  ifTrue: [i := CtxtTempFrameStart + (self fetchStackPointerOf: oop)]
  ifFalse: [i := self lengthOf: oop]].
  [(i := i - 1) >= 0] whileTrue:
  [anOop = (self fetchPointer: i ofObject: oop) ifTrue:
  [self interpreter printHex: oop; print: ' @ '; printNum: i; space; printOopShort: oop; cr.
  i := 0]]].
  oop := self accessibleObjectAfter: oop]!

Item was changed:
  ----- Method: ObjectMemory>>printWronglySizedContexts (in category 'debug printing') -----
  printWronglySizedContexts
  "Scan the heap printing the oops of any and all contexts whose size is not either SmallContextSize or LargeContextSize"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32"
  | oop |
- <api>
  oop := self firstAccessibleObject.
  [oop = nil] whileFalse:
  [((self isContextNonImm: oop)
    and: [self badContextSize: oop]) ifTrue:
  [self printHex: oop; space; printNum: (self numBytesOf: oop); cr].
  oop := self accessibleObjectAfter: oop]!

Item was changed:
  ----- Method: SpurMemoryManager>>inOrderPrintFreeTree:printList: (in category 'debug printing') -----
  inOrderPrintFreeTree: freeChunk printList: printNextList
  "print free chunks in freeTree in order."
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | next |
  (next := self fetchPointer: self freeChunkSmallerIndex ofFreeChunk: freeChunk) ~= 0 ifTrue:
  [self inOrderPrintFreeTree: next printList: printNextList].
  self printFreeChunk: freeChunk printAsTreeNode: true.
  printNextList ifTrue:
  [next := freeChunk.
  [(next := self fetchPointer: self freeChunkNextIndex ofFreeChunk: next) ~= 0] whileTrue:
  [coInterpreter tab.
  self printFreeChunk: next printAsTreeNode: false]].
  (next := self fetchPointer: self freeChunkLargerIndex ofFreeChunk: freeChunk) ~= 0 ifTrue:
  [self inOrderPrintFreeTree: next printList: printNextList]!

Item was changed:
  ----- Method: SpurMemoryManager>>longPrintInstancesOf: (in category 'debug printing') -----
  longPrintInstancesOf: aClassOop
  "Scan the heap printing the oops of any and all objects that are instances of aClassOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | classIndex |
  classIndex := self rawHashBitsOf: aClassOop.
  classIndex ~= self isFreeObjectClassIndexPun ifTrue:
  [self longPrintInstancesWithClassIndex: classIndex]!

Item was changed:
  ----- Method: SpurMemoryManager>>longPrintInstancesWithClassIndex: (in category 'debug printing') -----
  longPrintInstancesWithClassIndex: classIndex
  "Scan the heap printing any and all objects whose classIndex equals the argument."
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  <inline: false>
  self allHeapEntitiesDo:
  [:obj|
  (self classIndexOf: obj) = classIndex ifTrue:
  [coInterpreter longPrintOop: obj; cr]]!

Item was changed:
  ----- Method: SpurMemoryManager>>longPrintReferencesTo: (in category 'debug printing') -----
  longPrintReferencesTo: anOop
  "Scan the heap long printing the oops of any and all objects that refer to anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  | prntObj |
- <api>
  prntObj := false.
  self allObjectsDo:
  [:obj| | i |
  ((self isPointersNonImm: obj) or: [self isCompiledMethod: obj]) ifTrue:
  [(self isCompiledMethod: obj)
  ifTrue:
  [i := (self literalCountOf: obj) + LiteralStart]
  ifFalse:
  [(self isContextNonImm: obj)
  ifTrue: [i := CtxtTempFrameStart + (coInterpreter fetchStackPointerOf: obj)]
  ifFalse: [i := self numSlotsOf: obj]].
  [(i := i - 1) >= 0] whileTrue:
  [anOop = (self fetchPointer: i ofObject: obj) ifTrue:
  [coInterpreter printHex: obj; print: ' @ '; printNum: i; cr.
  prntObj := true.
  i := 0]].
  prntObj ifTrue:
  [prntObj := false.
  coInterpreter longPrintOop: obj]]]!

Item was changed:
  ----- Method: SpurMemoryManager>>printActivationsOf: (in category 'debug printing') -----
  printActivationsOf: aMethodObj
  "Scan the heap printing the oops of any and all contexts that refer to anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  self allObjectsDo:
  [:obj|
  ((self isContextNonImm: obj)
   and: [aMethodObj = (self fetchPointer: MethodIndex ofObject: obj)]) ifTrue:
  [coInterpreter
  printHex: obj; space; printOopShort: obj; print: ' pc ';
  printHex: (self fetchPointer: InstructionPointerIndex ofObject: obj); cr]]!

Item was changed:
  ----- Method: SpurMemoryManager>>printBogons (in category 'debug printing') -----
  printBogons
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  compactor printTheBogons: bogon!

Item was changed:
  ----- Method: SpurMemoryManager>>printContextReferencesTo: (in category 'debug printing') -----
  printContextReferencesTo: anOop
  "Scan the heap printing the oops of any and all contexts that refer to anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  self allObjectsDo:
  [:obj| | i |
  (self isContextNonImm: obj) ifTrue:
  [i := CtxtTempFrameStart + (coInterpreter fetchStackPointerOf: obj).
  [(i := i - 1) >= 0] whileTrue:
  [anOop = (self fetchPointer: i ofObject: obj) ifTrue:
  [coInterpreter
  printHex: obj; print: ' @ '; printNum: i; space; printOopShort: obj;
  print: ' pc '; printHex: (self fetchPointer: InstructionPointerIndex ofObject: obj); cr.
  i := 0]]]]!

Item was changed:
  ----- Method: SpurMemoryManager>>printEntity: (in category 'debug printing') -----
  printEntity: oop
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | printFlags |
  printFlags := false.
  coInterpreter printHex: oop; space.
  (self addressCouldBeObj: oop) ifFalse:
  [^coInterpreter print: ((self isImmediate: oop) ifTrue: ['immediate'] ifFalse: ['unknown'])].
  coInterpreter
  print: ((self isFreeObject: oop) ifTrue: ['free'] ifFalse:
  [(self isSegmentBridge: oop) ifTrue: ['bridge'] ifFalse:
  [(self isForwarded: oop) ifTrue: ['forwarder'] ifFalse:
  [(self classIndexOf: oop) <= self lastClassIndexPun ifTrue: [printFlags := true. 'pun/obj stack'] ifFalse:
  [printFlags := true. 'object']]]]);
  space; printHexnpnp: (self rawNumSlotsOf: oop); print: '/'; printHexnpnp: (self bytesInObject: oop); print: '/'; printNum: (self bytesInObject: oop).
  printFlags ifTrue:
  [coInterpreter
  space;
  print: ((self formatOf: oop) <= 16rF ifTrue: ['f:0'] ifFalse: ['f:']);
  printHexnpnp: (self formatOf: oop);
  print: ((self isGrey: oop) ifTrue: [' g'] ifFalse: [' .']);
  print: ((self isImmutable: oop) ifTrue: ['i'] ifFalse: ['.']);
  print: ((self isMarked: oop) ifTrue: ['m'] ifFalse: ['.']);
  print: ((self isPinned: oop) ifTrue: ['p'] ifFalse: ['.']);
  print: ((self isRemembered: oop) ifTrue: ['r'] ifFalse: ['.'])].
  coInterpreter cr!

Item was changed:
  ----- Method: SpurMemoryManager>>printForwarders (in category 'debug printing') -----
  printForwarders
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  self allHeapEntitiesDo:
  [:objOop|
  (self isUnambiguouslyForwarder: objOop) ifTrue:
  [coInterpreter printHex: objOop; cr]]!

Item was changed:
  ----- Method: SpurMemoryManager>>printFreeChunk: (in category 'debug printing') -----
  printFreeChunk: freeChunk
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  self printFreeChunk: freeChunk printAsTreeNode: true!

Item was changed:
  ----- Method: SpurMemoryManager>>printFreeList: (in category 'debug printing') -----
  printFreeList: chunkOrIndex
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | freeChunk |
  (chunkOrIndex >= 0 and: [chunkOrIndex < self numFreeLists]) ifTrue:
  [^self printFreeList: (freeLists at: chunkOrIndex)].
  freeChunk := chunkOrIndex.
  [freeChunk ~= 0] whileTrue:
  [self printFreeChunk: freeChunk.
  freeChunk := self fetchPointer: self freeChunkNextIndex ofFreeChunk: freeChunk]!

Item was changed:
  ----- Method: SpurMemoryManager>>printFreeListHeads (in category 'debug printing') -----
  printFreeListHeads
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | expectedMask |
  expectedMask := 0.
  0 to: self numFreeLists - 1 do:
  [:i|
  coInterpreter printHex: (freeLists at: i).
  (freeLists at: i) ~= 0 ifTrue:
  [expectedMask := expectedMask + (1 << i)].
  i + 1 \\ (32 >> self logBytesPerOop) = 0
  ifTrue: [coInterpreter cr]
  ifFalse: [coInterpreter print: '  ']].
  coInterpreter
  cr;
  print: 'mask: '; printHexnp: freeListsMask;
  print: ' expected: '; printHexnp: expectedMask;
  cr!

Item was changed:
  ----- Method: SpurMemoryManager>>printFreeTree (in category 'debug printing') -----
  printFreeTree
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  self printFreeTreeChunk: (freeLists at: 0)!

Item was changed:
  ----- Method: SpurMemoryManager>>printHeaderOf: (in category 'debug printing') -----
  printHeaderOf: objOop
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  "N.B. No safety bounds checks!!!!  We need to look e.g. at corpses."
  coInterpreter printHexnp: objOop.
  (self numSlotsOfAny: objOop) >= self numSlotsMask
  ifTrue: [coInterpreter
  print: ' hdr16 slotf '; printHexnp: (self numSlotsOfAny: objOop - self allocationUnit);
  print: ' slotc '; printHexnp: (self rawOverflowSlotsOf: objOop); space]
  ifFalse: [coInterpreter print: ' hdr8 slots '; printHexnp: (self numSlotsOfAny: objOop)].
  coInterpreter
  space;
  printChar: ((self isMarked: objOop) ifTrue: [$M] ifFalse: [$m]);
  printChar: ((self isGrey: objOop) ifTrue: [$G] ifFalse: [$g]);
  printChar: ((self isPinned: objOop) ifTrue: [$P] ifFalse: [$p]);
  printChar: ((self isRemembered: objOop) ifTrue: [$R] ifFalse: [$r]);
  printChar: ((self isImmutable: objOop) ifTrue: [$I] ifFalse: [$i]);
  print: ' hash '; printHexnp: (self rawHashBitsOf: objOop);
  print: ' fmt '; printHexnp: (self formatOf: objOop);
  print: ' cidx '; printHexnp: (self classIndexOf: objOop);
  cr!

Item was changed:
  ----- Method: SpurMemoryManager>>printInstancesOf: (in category 'debug printing') -----
  printInstancesOf: aClassOop
  "Scan the heap printing the oops of any and all objects that are instances of aClassOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | classIndex |
  classIndex := self rawHashBitsOf: aClassOop.
  classIndex ~= self isFreeObjectClassIndexPun ifTrue:
  [self printInstancesWithClassIndex: classIndex]!

Item was changed:
  ----- Method: SpurMemoryManager>>printInstancesWithClassIndex: (in category 'debug printing') -----
  printInstancesWithClassIndex: classIndex
  "Scan the heap printing the oops of any and all objects whose classIndex equals the argument."
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  <inline: false>
  self allHeapEntitiesDo:
  [:obj|
  (self classIndexOf: obj) = classIndex ifTrue:
  [coInterpreter printHex: obj; cr]]!

Item was changed:
  ----- Method: SpurMemoryManager>>printMarkedOops (in category 'debug printing') -----
  printMarkedOops
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  <option: #LLDB>
  self printOopsSuchThat: #isMarked!

Item was changed:
  ----- Method: SpurMemoryManager>>printMethodImplementorsOf: (in category 'debug printing') -----
  printMethodImplementorsOf: anOop
  "Scan the heap printing the oops of any and all methods that implement anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  self allObjectsDo:
  [:obj|
  ((self isCompiledMethod: obj)
   and: [(coInterpreter maybeSelectorOfMethod: obj) = anOop]) ifTrue:
  [coInterpreter printHex: obj; space; printOopShort: obj; cr]]!

Item was changed:
  ----- Method: SpurMemoryManager>>printMethodReferencesTo: (in category 'debug printing') -----
  printMethodReferencesTo: anOop
  "Scan the heap printing the oops of any and all methods that refer to anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  self allObjectsDo:
  [:obj| | i |
  (self isCompiledMethod: obj) ifTrue:
  [i := (self literalCountOf: obj) + LiteralStart - 1.
  [(i := i - 1) >= 0] whileTrue:
  [anOop = (self fetchPointer: i ofObject: obj) ifTrue:
  [coInterpreter printHex: obj; print: ' @ '; printNum: i; space; printOopShort: obj; cr.
  i := 0]]]]!

Item was changed:
  ----- Method: SpurMemoryManager>>printObjectsFrom:to: (in category 'debug printing') -----
  printObjectsFrom: startAddress to: endAddress
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | oop |
  oop := self objectBefore: startAddress.
  oop := oop
  ifNil: [startAddress]
  ifNotNil: [(self objectAfter: oop) = startAddress
  ifTrue: [startAddress]
  ifFalse: [oop]].
  [self oop: oop isLessThan: endAddress] whileTrue:
  [((self isFreeObject: oop)
  or: [self isSegmentBridge: oop]) ifFalse:
  [coInterpreter printOop: oop].
  oop := self objectAfter: oop]!

Item was changed:
  ----- Method: SpurMemoryManager>>printObjectsWithHash: (in category 'debug printing') -----
  printObjectsWithHash: hash
  "Scan the heap printing the oops of any and all objects whose hash equals the argument."
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  self allHeapEntitiesDo:
  [:obj|
  (self rawHashBitsOf: obj) = hash ifTrue:
  [coInterpreter shortPrintOop: obj; cr]]!

Item was changed:
  ----- Method: SpurMemoryManager>>printOopsExcept: (in category 'debug printing') -----
  printOopsExcept: function
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  <var: #function declareC: 'sqInt (*function)(sqInt)'>
  <inline: #never>
  | n |
  n := 0.
  self allHeapEntitiesDo:
  [:o|
  (self perform: function with: o) ifFalse:
  [n := n + 1.
  self printEntity: o]].
  n > 4 ifTrue: "rabbits"
  [self printNum: n; print: ' objects'; cr]!

Item was changed:
  ----- Method: SpurMemoryManager>>printOopsFrom:to: (in category 'debug printing') -----
  printOopsFrom: startAddress to: endAddress
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | oop limit firstNonEntity inEmptySpace lastNonEntity |
  oop := self objectBefore: startAddress.
  limit := endAddress asUnsignedIntegerPtr min: endOfMemory.
  oop := oop
  ifNil: [startAddress]
  ifNotNil: [(self objectAfter: oop) = startAddress
  ifTrue: [startAddress]
  ifFalse: [oop]].
  inEmptySpace := false.
  [self oop: oop isLessThan: limit] whileTrue:
  [self printEntity: oop.
  [oop := self objectAfter: oop.
   (self long64At: oop) = 0] whileTrue:
  [inEmptySpace ifFalse:
  [inEmptySpace := true.
  firstNonEntity := oop].
  lastNonEntity := oop].
  inEmptySpace ifTrue:
  [inEmptySpace := false.
  coInterpreter
  print: 'skipped empty space from '; printHexPtrnp: firstNonEntity;
  print:' to '; printHexPtrnp: lastNonEntity; cr.
  oop := self objectStartingAt: oop]]!

Item was changed:
  ----- Method: SpurMemoryManager>>printOopsSuchThat: (in category 'debug printing') -----
  printOopsSuchThat: function
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  <var: #function declareC: 'sqInt (*function)(sqInt)'>
  <inline: #never>
  | n |
  n := 0.
  self allHeapEntitiesDo:
  [:o|
  (self perform: function with: o) ifTrue:
  [n := n + 1.
  self printEntity: o]].
  n > 4 ifTrue: "rabbits"
  [self printNum: n; print: ' objects'; cr]!

Item was changed:
  ----- Method: SpurMemoryManager>>printReferencesTo: (in category 'debug printing') -----
  printReferencesTo: anOop
  "Scan the heap printing the oops of any and all objects that refer to anOop"
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  self allObjectsDo:
  [:obj| | i |
  i := self numPointerSlotsOf: obj.
  [(i := i - 1) >= 0] whileTrue:
  [anOop = (self fetchPointer: i ofMaybeForwardedObject: obj) ifTrue:
  [coInterpreter printHex: obj; print: ' @ '; printNum: i; space; printOopShort: obj; cr.
  i := 0]]]!

Item was changed:
  ----- Method: SpurMemoryManager>>printUnmarkedOops (in category 'debug printing') -----
  printUnmarkedOops
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  <option: #LLDB>
  self printOopsExcept: #isMarked!

Item was changed:
  ----- Method: SpurMemoryManager>>shortPrintObjectsFrom:to: (in category 'debug printing') -----
  shortPrintObjectsFrom: startAddress to: endAddress
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | oop |
  oop := self objectBefore: startAddress.
  oop := oop
  ifNil: [startAddress]
  ifNotNil: [(self objectAfter: oop) = startAddress
  ifTrue: [startAddress]
  ifFalse: [oop]].
  [self oop: oop isLessThan: endAddress] whileTrue:
  [(self isFreeObject: oop) ifFalse:
  [coInterpreter shortPrintOop: oop].
  oop := self objectAfter: oop]!

Item was changed:
  ----- Method: StackInterpreter class>>requiredMethodNames: (in category 'translation') -----
  requiredMethodNames: options
  "Answer the list of method names that should be retained for export or other support reasons"
  | requiredList |
  "A number of methods required by VM support code, specific platforms, etc"
  requiredList := #(
  assertValidExecutionPointe:r:s:
  characterForAscii:
  findClassOfMethod:forReceiver: findSelectorOfMethod:
  forceInterruptCheck forceInterruptCheckFromHeartbeat fullDisplayUpdate
  getCurrentBytecode getFullScreenFlag getInterruptKeycode getInterruptPending
  getSavedWindowSize getThisSessionID
  interpret
  loadInitialContext
  primitiveFail primitiveFailFor: primitiveFlushExternalPrimitives printAllStacks printCallStack printContext:
+ printExternalHeadFrame printFramesInPage: printFrame: printMemory printOop:
- printExternalHeadFrame printFramesInPage: printFrame: printHeadFrame printMemory printOop:
  printStackPages printStackPageList printStackPagesInUse printStackPageListInUse
  readImageFromFile:HeapSize:StartingAt:
  setFullScreenFlag: setInterruptKeycode: setInterruptPending: setInterruptCheckChain:
  setSavedWindowSize: success:
  validInstructionPointer:inMethod:framePointer:) asSet.
 
  "Nice to actually have all the primitives available"
  requiredList addAll: (self primitiveTable select: [:each| each isSymbol]).
 
  "InterpreterProxy is the internal analogue of sqVirtualMachine.c, so make sure to keep all those"
  InterpreterProxy organization categories do:
  [:cat |
  ((cat ~= 'initialize') and: [cat ~= 'private']) ifTrue:
  [requiredList addAll: (InterpreterProxy organization listAtCategoryNamed: cat)]].
 
  ^requiredList!

Item was changed:
  ----- Method: StackInterpreter>>activeProcess (in category 'process primitive support') -----
  activeProcess
  "Answer the current activeProcess."
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api> "useful for VM debugging"
  ^objectMemory fetchPointer: ActiveProcessIndex ofObject: self schedulerPointer!

Item was changed:
  ----- Method: StackInterpreter>>checkAllAccessibleObjectsOkay (in category 'debug support') -----
  checkAllAccessibleObjectsOkay
  "Ensure that all accessible objects in the heap are okay."
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | ok |
  ok := true.
  objectMemory allObjectsDoSafely:
  [:oop| ok := ok & (self checkOkayFields: oop)].
  ^ok!

Item was changed:
  ----- Method: StackInterpreter>>checkOkayInterpreterObjects: (in category 'debug support') -----
  checkOkayInterpreterObjects: writeBack
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | ok oopOrZero oop |
  ok := true.
  ok := ok & (self checkOkayFields: objectMemory nilObject).
  ok := ok & (self checkOkayFields: objectMemory falseObject).
  ok := ok & (self checkOkayFields: objectMemory trueObject).
  ok := ok & (self checkOkayFields: objectMemory specialObjectsOop).
  ok := ok & (self checkOkayFields: messageSelector).
  ok := ok & (self checkOkayFields: newMethod).
  ok := ok & (self checkOkayFields: lkupClass).
  0 to: MethodCacheEntries - 1 by: MethodCacheEntrySize do:
  [ :i |
  oopOrZero := methodCache at: i + MethodCacheSelector.
  oopOrZero = 0 ifFalse:
  [ok := ok & (self checkOkayFields: (methodCache at: i + MethodCacheSelector)).
  objectMemory hasSpurMemoryManagerAPI ifFalse:
  [ok := ok & (self checkOkayFields: (methodCache at: i + MethodCacheClass))].
  ok := ok & (self checkOkayFields: (methodCache at: i + MethodCacheMethod))]].
  1 to: objectMemory remapBufferCount do:
  [ :i |
  oop := objectMemory remapBuffer at: i.
  (objectMemory isImmediate: oop) ifFalse:
  [ok := ok & (self checkOkayFields: oop)]].
  ok := ok & (self checkOkayStackZone: writeBack).
  ^ok!

Item was changed:
  ----- Method: StackInterpreter>>longPrintOop: (in category 'debug printing') -----
  longPrintOop: oop
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | fmt lastIndex startIP bytecodesPerLine column |
  <var: 'field16' type: #'unsigned short'>
  <var: 'field32' type: #'unsigned int'>
  <var: 'field64' type: #usqLong>
  ((objectMemory isImmediate: oop)
  or: [(objectMemory addressCouldBeObj: oop) not
  or: [(oop bitAnd: objectMemory allocationUnit - 1) ~= 0
  or: [(objectMemory isFreeObject: oop)
  or: [objectMemory isForwarded: oop]]]]) ifTrue:
  [self printOop: oop.
  ^self].
  self printHex: oop.
  (objectMemory fetchClassOfNonImm: oop)
  ifNil: [self print: ' has a nil class!!!!']
  ifNotNil: [:class|
  self print: ': a(n) '; printNameOfClass: class count: 5;
  print: ' ('.
  objectMemory hasSpurMemoryManagerAPI ifTrue:
  [self printHexnp: (objectMemory compactClassIndexOf: oop); print: '=>'].
  self printHexnp: class; print: ')'].
  fmt := objectMemory formatOf: oop.
  self print: ' format '; printHexnp: fmt.
  fmt > objectMemory lastPointerFormat
  ifTrue: [self print: ' nbytes '; printNum: (objectMemory numBytesOf: oop)]
  ifFalse: [(objectMemory isIndexableFormat: fmt) ifTrue:
  [| len |
  len := objectMemory lengthOf: oop.
  self print: ' size '; printNum: len - (objectMemory fixedFieldsOf: oop format: fmt length: len)]].
  objectMemory printHeaderTypeOf: oop.
  self print: ' hash '; printHexnp: (objectMemory rawHashBitsOf: oop).
  self cr.
  (fmt between: objectMemory firstByteFormat and: objectMemory firstCompiledMethodFormat - 1) ifTrue:
  [^self printStringOf: oop; cr].
  (fmt between: objectMemory firstLongFormat and: objectMemory firstByteFormat - 1) ifTrue:
  [0 to: ((objectMemory num32BitUnitsOf: oop) min: 256) - 1 do:
  [:i| | field32 |
  field32 := objectMemory fetchLong32: i ofObject: oop.
  self space; printNum: i; space; printHex: field32; space; cr].
  ^self].
  objectMemory hasSpurMemoryManagerAPI ifTrue:
  [fmt = objectMemory sixtyFourBitIndexableFormat ifTrue:
  [0 to: ((objectMemory num64BitUnitsOf: oop) min: 256) - 1 do:
  [:i| | field64 |
  field64 := objectMemory fetchLong64: i ofObject: oop.
  self space; printNum: i; space; printHex: field64; space; cr].
  ^self].
  (fmt between: objectMemory firstShortFormat and: objectMemory firstShortFormat + 1) ifTrue:
  [0 to: ((objectMemory num16BitUnitsOf: oop) min: 256) - 1 do:
  [:i| | field16 |
  field16 := objectMemory fetchShort16: i ofObject: oop.
  self space; printNum: i; space; printHex: field16; space; cr].
  ^self]].
  "this is nonsense.  apologies."
  startIP := (objectMemory lastPointerOf: oop) + objectMemory bytesPerOop - objectMemory baseHeaderSize / objectMemory bytesPerOop.
  lastIndex := 256 min: startIP.
  lastIndex > 0 ifTrue:
  [1 to: lastIndex do:
  [:i| | fieldOop |
  fieldOop := objectMemory fetchPointer: i - 1 ofObject: oop.
  self space; printNum: i - 1; space; printHex: fieldOop; space.
  (i = 1 and: [objectMemory isCompiledMethod: oop])
  ifTrue: [self printMethodHeaderOop: fieldOop]
  ifFalse: [self cCode: [self printOopShort: fieldOop]
  inSmalltalk: [self print: (self shortPrint: fieldOop)]].
  self cr]].
  (objectMemory isCompiledMethod: oop)
  ifFalse:
  [startIP > lastIndex ifTrue: [self print: '...'; cr]]
  ifTrue:
  [startIP := startIP * objectMemory wordSize + 1.
  lastIndex := objectMemory lengthOf: oop.
  lastIndex - startIP > 100 ifTrue:
  [lastIndex := startIP + 100].
  bytecodesPerLine := 8.
  column := 1.
  startIP to: lastIndex do:
  [:index| | byte |
  column = 1 ifTrue:
  [self cCode: 'printf("0x%08" PRIxSQPTR ": ", (usqIntptr_t)(oop+BaseHeaderSize+index-1))'
  inSmalltalk: [self print: (oop+objectMemory baseHeaderSize+index-1) hex; print: ': ']].
  byte := objectMemory fetchByte: index - 1 ofObject: oop.
  self cCode: 'printf(" %02x/%-3d", (int)byte,(int)byte)'
  inSmalltalk: [self space; print: (byte radix: 16); printChar: $/; printNum: byte].
  column := column + 1.
  column > bytecodesPerLine ifTrue:
  [column := 1. self cr]].
  column = 1 ifFalse:
  [self cr]]!

Item was changed:
  ----- Method: StackInterpreter>>printAllStacks (in category 'debug printing') -----
  printAllStacks
  "Print all the stacks of all running processes, including those that are currently suspended."
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | proc semaphoreClass mutexClass schedLists p processList |
  <inline: false>
  proc := self activeProcess.
  self printNameOfClass: (objectMemory fetchClassOf: proc) count: 5; space; printHex: proc.
  self print: ' priority '; printNum: (self quickFetchInteger: PriorityIndex ofObject: proc); cr.
  self printCallStackFP: framePointer. "first the current activation"
  schedLists := objectMemory fetchPointer: ProcessListsIndex ofObject: self schedulerPointer.
  "then the runnable processes"
  p := highestRunnableProcessPriority = 0
  ifTrue: [objectMemory numSlotsOf: schedLists]
  ifFalse: [highestRunnableProcessPriority].
  p - 1 to: 0 by: -1 do:
  [:pri|
  processList := objectMemory fetchPointer: pri ofObject: schedLists.
  (self isEmptyList: processList) ifFalse:
  [self cr; print: 'processes at priority '; printNum: pri + 1.
  self printProcsOnList: processList]].
  self cr; print: 'suspended processes'.
  semaphoreClass := objectMemory classSemaphore.
  mutexClass := objectMemory classMutex.
  objectMemory hasSpurMemoryManagerAPI
  ifTrue:
  [semaphoreClass := objectMemory compactIndexOfClass: semaphoreClass.
  mutexClass := objectMemory compactIndexOfClass: mutexClass.
  objectMemory allHeapEntitiesDo:
  [:obj| | classIdx |
  classIdx := objectMemory classIndexOf: obj.
  (classIdx = semaphoreClass
   or: [classIdx = mutexClass]) ifTrue:
  [self printProcsOnList: obj]]]
  ifFalse:
  [objectMemory allObjectsDoSafely:
  [:obj| | classObj |
  classObj := objectMemory fetchClassOfNonImm: obj.
  (classObj = semaphoreClass
   or: [classObj = mutexClass]) ifTrue:
  [self printProcsOnList: obj]]]!

Item was changed:
  ----- Method: StackInterpreter>>printCallStack (in category 'debug printing') -----
  printCallStack
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  <inline: false>
  framePointer = nil
  ifTrue: [self printCallStackOf: (objectMemory fetchPointer: SuspendedContextIndex ofObject: self activeProcess)]
  ifFalse: [self printCallStackFP: framePointer]!

Item was changed:
  ----- Method: StackInterpreter>>printCallStackOf: (in category 'debug printing') -----
  printCallStackOf: aContextOrProcessOrFrame
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | context |
  <inline: false>
  (stackPages couldBeFramePointer: aContextOrProcessOrFrame) ifTrue:
  [^self printCallStackFP: (self cCoerceSimple: aContextOrProcessOrFrame to: #'char *')].
  aContextOrProcessOrFrame = self activeProcess ifTrue:
  [^self printCallStackOf: (self cCode: [framePointer asInteger] inSmalltalk: [self headFramePointer])].
  (self couldBeProcess: aContextOrProcessOrFrame) ifTrue:
  [^self printCallStackOf: (objectMemory
  fetchPointer: SuspendedContextIndex
  ofObject: aContextOrProcessOrFrame)].
  context := aContextOrProcessOrFrame.
  [context = objectMemory nilObject] whileFalse:
  [(self isMarriedOrWidowedContext: context)
  ifTrue:
  [(self checkIsStillMarriedContext: context currentFP: framePointer) ifFalse:
  [self shortPrintContext: context.
  ^nil].
  context := self shortReversePrintFrameAndCallers: (self frameOfMarriedContext: context)]
  ifFalse:
  [context := self printContextCallStackOf: context]]!

Item was changed:
  ----- Method: StackInterpreter>>printContext: (in category 'debug printing') -----
  printContext: aContext
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  | sender ip sp |
  <inline: false>
  self shortPrintContext: aContext.
  sender := objectMemory fetchPointer: SenderIndex ofObject: aContext.
  ip := objectMemory fetchPointer: InstructionPointerIndex ofObject: aContext.
  (objectMemory isIntegerObject: sender)
  ifTrue:
  [(self checkIsStillMarriedContext: aContext currentFP: framePointer)
  ifTrue: [self print: 'married (assuming framePointer valid)'; cr]
  ifFalse: [self print: 'widowed (assuming framePointer valid)'; cr].
  self print: 'sender   '; printNum: sender; print: ' (';
  printHexPtr: (self withoutSmallIntegerTags: sender); printChar: $); cr.
  self print: 'ip       '; printNum: ip; print: ' (';
  printHexPtr: (self withoutSmallIntegerTags: ip); printChar: $); cr]
  ifFalse:
  [self print: 'sender   '; shortPrintOop: sender.
  self print: 'ip       '.
  ip = objectMemory nilObject
  ifTrue: [self shortPrintOop: ip]
  ifFalse: [self printNum: ip; print: ' ('; printNum: (objectMemory integerValueOf: ip); space; printHex: (objectMemory integerValueOf: ip); printChar: $); cr]].
  sp := objectMemory fetchPointer: StackPointerIndex ofObject: aContext.
  self print: 'sp       '; printNum: (objectMemory integerValueOf: sp); print: ' ('; printHex: sp; printChar: $); cr.
  self print: 'method   '; printMethodFieldForPrintContext: aContext.
  self print: 'closure  '; shortPrintOop: (objectMemory fetchPointer: ClosureIndex ofObject: aContext).
  self print: 'receiver '; shortPrintOop: (objectMemory fetchPointer: ReceiverIndex ofObject: aContext).
  sp := objectMemory integerValueOf: sp.
  sp := sp min: (objectMemory lengthOf: aContext) - ReceiverIndex.
  1 to: sp do:
  [:i|
  self print: '       '; printNum: i; space; shortPrintOop: (objectMemory fetchPointer: ReceiverIndex + i ofObject: aContext)]!

Item was changed:
  ----- Method: StackInterpreter>>printExternalHeadFrame (in category 'debug printing') -----
  printExternalHeadFrame
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  <inline: false>
  self printFrame: framePointer WithSP: stackPointer!

Item was changed:
  ----- Method: StackInterpreter>>printFrame: (in category 'debug printing') -----
  printFrame: theFP
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  | thePage frameAbove theSP |
  <inline: false>
  <var: #theFP type: #'char *'>
  <var: #theSP type: #'char *'>
  <var: #frameAbove type: #'char *'>
  <var: #thePage type: #'StackPage *'>
  (stackPages couldBeFramePointer: theFP) ifFalse:
  [((objectMemory addressCouldBeObj: theFP asInteger)
   and: [(objectMemory isInMemory: theFP asInteger)
   and: [(objectMemory isContextNonImm: theFP asInteger)
   and: [(self checkIsStillMarriedContext: theFP asInteger currentFP: framePointer)]]]) ifTrue:
  [^self printFrame: (self frameOfMarriedContext: theFP asInteger)].
  self printHexPtr: theFP; print: ' is not in the stack zone?!!'; cr.
  ^nil].
  frameAbove := nil.
  theFP = framePointer
  ifTrue: [theSP := stackPointer]
  ifFalse:
  [thePage := stackPages stackPageFor: theFP.
  (stackPages isFree: thePage) ifTrue:
  [self printHexPtr: theFP; print: ' is on a free page?!!'; cr.
  ^nil].
  (thePage ~= stackPage
   and: [theFP = thePage headFP])
  ifTrue: [theSP := thePage headSP]
  ifFalse:
  [frameAbove := self safeFindFrameAbove: theFP
  on: thePage
  startingFrom: ((thePage = stackPage
  and: [framePointer
  between: thePage realStackLimit
  and: thePage baseAddress])
  ifTrue: [framePointer]
  ifFalse: [thePage headFP]).
  theSP := frameAbove ifNotNil:
  [self frameCallerSP: frameAbove]]].
  theSP ifNil:
  [self print: 'could not find sp; using bogus value'; cr.
  theSP := self frameReceiverLocation: theFP].
  self printFrame: theFP WithSP: theSP.
  frameAbove ifNotNil:
  [self printFrameThing: 'frame pc' at: frameAbove + FoxCallerSavedIP]!

Item was changed:
  ----- Method: StackInterpreter>>printFrame:WithSP: (in category 'debug printing') -----
  printFrame: theFP WithSP: theSP
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | theMethod numArgs topThing |
  <inline: false>
  <var: #theFP type: #'char *'>
  <var: #theSP type: #'char *'>
  <var: #addr type: #'char *'>
  self cCode: '' inSmalltalk: [self transcript ensureCr].
  (stackPages couldBeFramePointer: theFP) ifFalse:
  [self printHexPtr: theFP; print: ' is not in the stack zone?!!'; cr.
  ^nil].
  theMethod := self frameMethod: theFP.
  numArgs := self frameNumArgs: theFP.
  self shortPrintFrame: theFP.
  self printFrameOop: 'rcvr/clsr'
  at: theFP + FoxCallerSavedIP + ((numArgs + 1) * objectMemory wordSize).
  numArgs to: 1 by: -1 do:
  [:i| self printFrameOop: 'arg' at: theFP + FoxCallerSavedIP + (i * objectMemory wordSize)].
  self printFrameThing: 'cllr ip/ctxt' at: theFP + FoxCallerSavedIP.
  self printFrameThing: 'saved fp' at: theFP + FoxSavedFP.
  self printFrameOop: 'method' at: theFP + FoxMethod.
  self printFrameFlagsForFP: theFP.
  self printFrameThing: 'context' at: theFP + FoxThisContext.
  self printFrameOop: 'receiver' at: theFP + FoxReceiver.
  topThing := stackPages longAt: theSP.
  (topThing >= theMethod
  and: [topThing <= (theMethod + (objectMemory sizeBitsOfSafe: theMethod))])
  ifTrue:
  [theFP + FoxReceiver - objectMemory wordSize to: theSP + objectMemory wordSize by: objectMemory wordSize negated do:
  [:addr|
  self printFrameOop: 'temp/stck' at: addr].
  self printFrameThing: 'frame ip' at: theSP]
  ifFalse:
  [theFP + FoxReceiver - objectMemory wordSize to: theSP by: objectMemory wordSize negated do:
  [:addr|
  self printFrameOop: 'temp/stck' at: addr]]!

Item was changed:
  ----- Method: StackInterpreter>>printLikelyImplementorsOfSelector: (in category 'debug printing') -----
  printLikelyImplementorsOfSelector: selector
  "Print all methods whose penultimate literal is either selector,
  or an object whose first inst var is the method and whose
  second is selector (e.g. an AdditionalMethodState)."
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  objectMemory allObjectsDo:
  [:obj| | methodClassAssociation |
  ((objectMemory isCompiledMethod: obj)
  and: [(self maybeSelectorOfMethod: obj) = selector]) ifTrue:
  ["try and print the key of the method class association (the name of the implementing class)"
  methodClassAssociation := self methodClassAssociationOf: obj.
  self printHexnp: obj;
  space;
  printOopShortInner: (((objectMemory isPointers: methodClassAssociation)
   and: [(objectMemory numSlotsOf: methodClassAssociation) >= 2])
  ifTrue: [objectMemory fetchPointer: 0 ofObject: methodClassAssociation]
  ifFalse: [methodClassAssociation]);
  cr]]!

Item was changed:
  ----- Method: StackInterpreter>>printMethodCache (in category 'debug printing') -----
  printMethodCache
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  self printMethodCacheFor: -1!

Item was changed:
  ----- Method: StackInterpreter>>printMethodCacheFor: (in category 'debug printing') -----
  printMethodCacheFor: thing
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | n |
  n := 0.
  0 to: MethodCacheSize - 1 by: MethodCacheEntrySize do:
  [:i | | s c m p |
  s := methodCache at: i + MethodCacheSelector.
  c := methodCache at: i + MethodCacheClass.
  m := methodCache at: i + MethodCacheMethod.
  p := methodCache at: i + MethodCachePrimFunction.
  ((thing = -1 or: [s = thing or: [c = thing or: [p = thing or: [m = thing]]]])
  and: [(objectMemory addressCouldBeOop: s)
  and: [c ~= 0
  and: [(self addressCouldBeClassObj: c)
  or: [self addressCouldBeClassObj: (objectMemory classForClassTag: c)]]]]) ifTrue:
  [self cCode: [] inSmalltalk: [self transcript ensureCr].
  self printNum: i; space; printHexnp: i; cr; tab.
  (objectMemory isBytesNonImm: s)
  ifTrue: [self cCode: 'printf("%" PRIxSQPTR " %.*s\n", s, (int)(numBytesOf(s)), (char *)firstIndexableField(s))'
  inSmalltalk: [self printHex: s; space; print: (self stringOf: s); cr]]
  ifFalse: [self shortPrintOop: s].
  self tab.
  (self addressCouldBeClassObj: c)
  ifTrue: [self shortPrintOop: c]
  ifFalse: [self printNum: c; space; shortPrintOop: (objectMemory classForClassTag: c)].
  self tab; shortPrintOop: m; tab.
  self cCode:
  [p > 1024
  ifTrue: [self printHexnp: p]
  ifFalse: [self printNum: p]]
  inSmalltalk:
  [p isSymbol ifTrue: [self print: p] ifFalse: [self printNum: p]].
  self cr]].
  n > 1 ifTrue:
  [self printNum: n; cr]!

Item was changed:
  ----- Method: StackInterpreter>>printMethodDictionary: (in category 'debug printing') -----
  printMethodDictionary: dictionary
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | methodArray |
  methodArray := objectMemory fetchPointer: MethodArrayIndex ofObject: dictionary.
  SelectorStart to: (objectMemory numSlotsOf: dictionary) - 1 do:
  [:index | | selector meth |
  selector := objectMemory fetchPointer: index ofObject: dictionary.
  selector ~= objectMemory nilObject ifTrue:
  [meth := objectMemory fetchPointer: index - SelectorStart ofObject: methodArray.
  self
  printOopShort: selector;
  print: ' => ';
  printOopShort: meth;
  print: ' (';
  printHex: selector;
  print: ' => ';
  printHex: meth;
  putchar: $);
  cr]]!

Item was changed:
  ----- Method: StackInterpreter>>printMethodDictionaryOf: (in category 'debug printing') -----
  printMethodDictionaryOf: behavior
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  self printMethodDictionary: (objectMemory fetchPointer: MethodDictionaryIndex ofObject: behavior)!

Item was changed:
  ----- Method: StackInterpreter>>printOop: (in category 'debug printing') -----
  printOop: oop
+ <export: true> "use export: not api, so it won't be written to cointerp.h"
  | cls fmt lastIndex startIP bytecodesPerLine column |
  <inline: false>
  (objectMemory isImmediate: oop) ifTrue:
  [^self shortPrintOop: oop].
  self printHex: oop.
  (objectMemory addressCouldBeObj: oop) ifFalse:
  [(oop bitAnd: objectMemory allocationUnit - 1) ~= 0 ifTrue: [^self print: ' is misaligned'; cr].
  ((objectMemory isInNewSpace: oop)
   and: [objectMemory isForwarded: oop]) ifTrue:
  [self printForwarder: oop].
  ^self print: (self whereIs: oop); cr].
  (objectMemory isFreeObject: oop) ifTrue:
  [self print: ' is a free chunk of size '; printNum: (objectMemory sizeOfFree: oop).
  objectMemory hasSpurMemoryManagerAPI ifTrue:
  [self print: ' 0th: '; printHex: (objectMemory fetchPointer: 0 ofFreeChunk: oop).
  objectMemory printHeaderTypeOf: oop].
  ^self cr].
  (objectMemory isForwarded: oop) ifTrue:
  [^self printForwarder: oop].
  self print: ': a(n) '.
  self printNameOfClass: (cls := objectMemory fetchClassOfNonImm: oop) count: 5.
  cls = (objectMemory splObj: ClassFloat) ifTrue:
  [^self cr; printFloat: (objectMemory dbgFloatValueOf: oop); cr].
  fmt := objectMemory formatOf: oop.
  fmt > objectMemory lastPointerFormat ifTrue:
  [self print: ' nbytes '; printNum: (objectMemory numBytesOf: oop)].
  self cr.
  (fmt between: objectMemory firstLongFormat and: objectMemory firstCompiledMethodFormat - 1) ifTrue:
  ["This will answer false if splObj: ClassAlien is nilObject"
  (self is: oop KindOfClass: (objectMemory splObj: ClassAlien)) ifTrue:
  [self print: ' datasize '; printNum: (objectMemory sizeFieldOfAlien: oop).
  self print: ((self isIndirectAlien: oop)
  ifTrue: [' indirect @ ']
  ifFalse:
  [(self isPointerAlien: oop)
  ifTrue: [' pointer @ ']
  ifFalse: [' direct @ ']]).
  ^self printHex: (self startOfAlienData: oop) asUnsignedInteger; cr].
  (objectMemory isWordsNonImm: oop) ifTrue:
  [lastIndex := 64 min: ((objectMemory numBytesOf: oop) / objectMemory wordSize).
  lastIndex > 0 ifTrue:
  [1 to: lastIndex do:
  [:index|
  self space; printHex: (self cCoerceSimple: (objectMemory fetchLong32: index - 1 ofObject: oop)
  to: #'unsigned int').
  (index \\ self elementsPerPrintOopLine) = 0 ifTrue:
  [self cr]].
  (lastIndex \\ self elementsPerPrintOopLine) = 0 ifFalse:
  [self cr]].
  ^self].
  ^self printStringOf: oop; cr].
  "this is nonsense.  apologies."
  startIP := (objectMemory lastPointerOf: oop) + objectMemory bytesPerOop - objectMemory baseHeaderSize / objectMemory bytesPerOop.
  lastIndex := 256 min: startIP.
  lastIndex > 0 ifTrue:
  [1 to: lastIndex do:
  [:index|
  self cCode: [self printHex: (objectMemory fetchPointer: index - 1 ofObject: oop); space]
  inSmalltalk: [self space; printHex: (objectMemory fetchPointer: index - 1 ofObject: oop); space.
  self print: (self shortPrint: (objectMemory fetchPointer: index - 1 ofObject: oop))].
  (index \\ self elementsPerPrintOopLine) = 0 ifTrue:
  [self cr]].
  (lastIndex \\ self elementsPerPrintOopLine) = 0 ifFalse:
  [self cr]].
  (objectMemory isCompiledMethod: oop)
  ifFalse:
  [startIP > 64 ifTrue: [self print: '...'; cr]]
  ifTrue:
  [startIP := startIP * objectMemory wordSize + 1.
  lastIndex := objectMemory lengthOf: oop.
  lastIndex - startIP > 100 ifTrue:
  [lastIndex := startIP + 100].
  bytecodesPerLine := 8.
  column := 1.
  startIP to: lastIndex do:
  [:index| | byte |
  column = 1 ifTrue:
  [self cCode: 'printf("0x%08" PRIxSQPTR ": ", (usqIntptr_t)(oop+BaseHeaderSize+index-1))'
  inSmalltalk: [self print: (oop+objectMemory baseHeaderSize+index-1) hex; print: ': ']].
  byte := objectMemory fetchByte: index - 1 ofObject: oop.
  self cCode: 'printf(" %02x/%-3d", (int)byte,(int)byte)'
  inSmalltalk: [self space; print: (byte radix: 16); printChar: $/; printNum: byte].
  column := column + 1.
  column > bytecodesPerLine ifTrue:
  [column := 1. self cr]].
  column = 1 ifFalse:
  [self cr]]!

Item was changed:
  ----- Method: StackInterpreter>>printProcessStack: (in category 'debug printing') -----
  printProcessStack: aProcess
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  <inline: false>
  | ctx |
  self cr; printNameOfClass: (objectMemory fetchClassOf: aProcess) count: 5; space; printHex: aProcess.
  self print: ' priority '; printNum: (self quickFetchInteger: PriorityIndex ofObject: aProcess); cr.
  ctx := objectMemory followField: SuspendedContextIndex ofObject: aProcess.
  ctx = objectMemory nilObject ifFalse:
  [self printCallStackOf: ctx currentFP: framePointer]!

Item was changed:
  ----- Method: StackInterpreter>>printProcsOnList: (in category 'debug printing') -----
  printProcsOnList: procList
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  <inline: false>
  | proc firstProc |
  proc := firstProc := objectMemory followField: FirstLinkIndex ofObject: procList.
  [proc = objectMemory nilObject] whileFalse:
  [self printProcessStack: proc.
  proc := objectMemory followField: NextLinkIndex ofObject: proc.
  proc = firstProc ifTrue:
  [self warning: 'circular process list!!!!'.
  ^nil]]!

Item was changed:
  ----- Method: StackInterpreter>>printStackCallStackOf: (in category 'debug printing') -----
  printStackCallStackOf: aContextOrProcessOrFrame
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  | theFP context |
  <var: #theFP type: #'char *'>
  (self cCode: [false] "In the stack simulator, frame pointers are negative which upsets addressCouldBeObj:"
  inSmalltalk: [stackPages couldBeFramePointer: aContextOrProcessOrFrame]) ifFalse:
  [(objectMemory addressCouldBeObj: aContextOrProcessOrFrame) ifTrue:
  [((objectMemory isContext: aContextOrProcessOrFrame)
   and: [self checkIsStillMarriedContext: aContextOrProcessOrFrame currentFP: nil]) ifTrue:
  [^self printStackCallStackOf: (self frameOfMarriedContext: aContextOrProcessOrFrame) asInteger].
  aContextOrProcessOrFrame = self activeProcess ifTrue:
  [^self printStackCallStackOf: (self cCode: [framePointer asInteger] inSmalltalk: [self headFramePointer])].
  (self couldBeProcess: aContextOrProcessOrFrame) ifTrue:
  [^self printCallStackOf: (objectMemory
  fetchPointer: SuspendedContextIndex
  ofObject: aContextOrProcessOrFrame)].
  ^nil]].
 
  theFP := aContextOrProcessOrFrame asVoidPointer.
  [context := self shortReversePrintFrameAndCallers: theFP.
  ((self isMarriedOrWidowedContext: context)
   and:
  [theFP := self frameOfMarriedContext: context.
  self checkIsStillMarriedContext: context currentFP: theFP]) ifFalse:
  [^nil]] repeat!

Item was changed:
  ----- Method: StackInterpreter>>printStackPageList (in category 'debug printing') -----
  printStackPageList
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  | page |
  <inline: false>
  <var: #page type: #'StackPage *'>
  page := stackPages mostRecentlyUsedPage.
  [self printStackPage: page.
  self cr.
  (page := page prevPage) ~= stackPages mostRecentlyUsedPage] whileTrue!

Item was changed:
  ----- Method: StackInterpreter>>printStackPageListInUse (in category 'debug printing') -----
  printStackPageListInUse
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  | page n |
  <inline: false>
  <var: #page type: #'StackPage *'>
  page := stackPages mostRecentlyUsedPage.
  n := 0.
  [(stackPages isFree: page) ifFalse:
  [self printStackPage: page useCount: (n := n + 1); cr].
  (page := page prevPage) ~= stackPages mostRecentlyUsedPage] whileTrue!

Item was changed:
  ----- Method: StackInterpreter>>printStackPages (in category 'debug printing') -----
  printStackPages
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  0 to: numStackPages - 1 do:
  [:i|
  self printStackPage: (stackPages stackPageAt: i).
  self cr]!

Item was changed:
  ----- Method: StackInterpreter>>printStackPagesInUse (in category 'debug printing') -----
  printStackPagesInUse
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
  | n |
  n := 0.
  0 to: numStackPages - 1 do:
  [:i|
  (stackPages isFree: (stackPages stackPageAt: i)) ifFalse:
  [self printStackPage: (stackPages stackPageAt: i) useCount: (n := n + 1); cr]]!

Item was changed:
  ----- Method: StackInterpreter>>printStackReferencesTo: (in category 'object memory support') -----
  printStackReferencesTo: oop
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
- <var: #thePage type: #'StackPage *'>
- <var: #theSP type: #'char *'>
- <var: #theFP type: #'char *'>
- <var: #callerFP type: #'char *'>
  0 to: numStackPages - 1 do:
  [:i| | thePage theSP theFP callerFP |
  thePage := stackPages stackPageAt: i.
  thePage isFree ifFalse:
  [theSP := thePage headSP.
  theFP := thePage headFP.
  "Skip the instruction pointer on top of stack of inactive pages."
  thePage = stackPage ifFalse:
  [theSP := theSP + objectMemory wordSize].
  [[theSP <= (self frameReceiverLocation: theFP)] whileTrue:
  [oop = (stackPages longAt: theSP) ifTrue:
  [self print: 'FP: '; printHexnp: theFP; print: ' @ '; printHexnp: theSP; cr].
  theSP := theSP + objectMemory wordSize].
   (self frameHasContext: theFP) ifTrue:
  [oop = (self frameContext: theFP) ifTrue:
  [self print: 'FP: '; printHexnp: theFP; print: ' CTXT'; cr]].
   oop = (self frameMethod: theFP) ifTrue:
  [self print: 'FP: '; printHexnp: theFP; print: ' MTHD'; cr].
   (callerFP := self frameCallerFP: theFP) ~= 0]
  whileTrue:
  [theSP := (theFP + FoxCallerSavedIP) + objectMemory wordSize.
  theFP := callerFP].
  theSP := theFP + FoxCallerSavedIP. "a.k.a. FoxCallerContext"
  [theSP <= thePage baseAddress] whileTrue:
  [oop = (stackPages longAt: theSP) ifTrue:
  [self print: 'FP: '; printHexnp: theFP; print: ' @ '; printHexnp: theSP; cr].
  theSP := theSP + objectMemory wordSize]]]!

Item was changed:
  ----- Method: StackInterpreter>>setBreakMNUSelector: (in category 'debug support') -----
  setBreakMNUSelector: aString
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  <var: #aString type: #'char *'>
  (breakSelector := aString)
  ifNil: [breakSelectorLength := objectMemory minSmallInteger "nil's effective length is zero"]
  ifNotNil: [breakSelectorLength := (self strlen: aString) negated]!

Item was changed:
  ----- Method: StackInterpreter>>setBreakSelector: (in category 'debug support') -----
  setBreakSelector: aString
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  <var: #aString type: #'char *'>
  (breakSelector := aString)
  ifNil: [breakSelectorLength := objectMemory minSmallInteger "nil's effective length is zero"]
  ifNotNil: [breakSelectorLength := self strlen: aString]!

Item was changed:
  ----- Method: StackInterpreter>>shortPrintFrame:AndNCallers: (in category 'debug printing') -----
  shortPrintFrame: theFP AndNCallers: n
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
- <api>
  <inline: false>
  <var: #theFP type: #'char *'>
  (n ~= 0 and: [stackPages couldBeFramePointer: theFP]) ifTrue:
  [self shortPrintFrame: theFP.
  self shortPrintFrame: (self frameCallerFP: theFP) AndNCallers: n - 1]!

Item was changed:
  ----- Method: StackInterpreter>>whereIs: (in category 'debug printing') -----
  whereIs: anOop
+ <export: true> "useful for VM debugging; use export: not api, so it will be accessible on win32 and won't be written to cointerp.h"
+ <returnTypeC: #'char *'>
- <api>
- <returnTypeC: 'char *'>
  <inline: false>
  <var: 'where' type: #'char *'>
  (objectMemory whereIsMaybeHeapThing: anOop) ifNotNil: [:where| ^where].
  (stackPages whereIsMaybeStackThing: anOop) ifNotNil: [:where| ^where].
  ^' is no where obvious'!