diff --git a/smalltalksrc/VMMaker-Tools/SpurByteLayout.class.st b/smalltalksrc/VMMaker-Tools/SpurByteLayout.class.st new file mode 100644 index 00000000000..7ee8b1736ef --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurByteLayout.class.st @@ -0,0 +1,43 @@ +Class { + #name : #SpurByteLayout, + #superclass : #SpurLayout, + #category : #'VMMaker-Tools-imageInspector' +} + +{ #category : #accessing } +SpurByteLayout >> asLocalByteArray [ + | localByteArray | + localByteArray := ByteArray new: self byteSize . + 1 to: localByteArray size do: [ :i | + localByteArray byteAt: i put: (self at: i). + ]. + ^ localByteArray +] + +{ #category : #accessing } +SpurByteLayout >> at: anInteger [ + + " ToDo: consider inst vars " + | slotIndex byteIndex | + slotIndex := (anInteger - 1) // self wordSize . + byteIndex := (anInteger - 1) % self wordSize . + ^ (self slotAt: slotIndex + 1) at: byteIndex + 1 +] + +{ #category : #accessing } +SpurByteLayout >> objectPrintOn: aStream [ + aStream nextPutAll: self object asLocalByteArray asString +] + +{ #category : #accessing } +SpurByteLayout >> slotAt: anInteger [ + + | bodyAddress | + self assert: anInteger > 0 description: 'Index must be greater than 0'. + self assert: self numberOfSlots >= anInteger description: 'Index Out of Bounds'. + + bodyAddress := self address + self headerSize + ((anInteger - 1) * self wordSize). + + ^ self memory copyFrom: bodyAddress to: bodyAddress + self wordSize + (0 - 1) + +] diff --git a/smalltalksrc/VMMaker-Tools/SpurClass.class.st b/smalltalksrc/VMMaker-Tools/SpurClass.class.st new file mode 100644 index 00000000000..f66a90a2b3f --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurClass.class.st @@ -0,0 +1,113 @@ +Class { + #name : #SpurClass, + #superclass : #SpurObject, + #category : #'VMMaker-Tools-imageInspector' +} + +{ #category : #'accessing - instance variables' } +SpurClass >> allInstanceVariableNames [ + ^ (1 to: self numberOfSlots) collect: [ :index | self slotAt: index ] . +] + +{ #category : #'as yet unclassified' } +SpurClass >> classFormat [ + ^ self slotAt: self slotIndexForClassFormat +] + +{ #category : #accessing } +SpurClass >> className [ +"We assume this is a byteSymbol here" + ^ self image printByteSymbol: (self slotAt: self slotIndexForClassName) + + " ] on: Error + do: [ (self slotAt: self slotIndexForMetaclassSoleInstance ) asSpurClass className , ' class'] " + +] + +{ #category : #'gt-inspector-extension' } +SpurClass >> gtInspectorLayoutIn: composite [ + ^ composite table + title: 'asd'; + display: [ + { + 'self' -> self . + 'superclass' -> self spSuperclass . + 'format:' -> self classFormat . + 'instSpec' -> self instSpec . + 'instSize' -> self instSize} ]; + column: 'Key' evaluated: [:each | each key ]; + column: 'Value' evaluated: [ :each | each value ]; + send: #value + +] + +{ #category : #'accessing-header' } +SpurClass >> instSize [ + "Answer the number of named instance variables + (as opposed to indexed variables) of the receiver. + Above Cog Spur the class format is + <5 bits inst spec><16 bits inst size>" + ^self classFormat bitAnd: 16rFFFF +] + +{ #category : #'accessing-header' } +SpurClass >> instSpec [ + ^ (self classFormat bitShift: -16) bitAnd: 16r1F +] + +{ #category : #accessing } +SpurClass >> methodDictionary [ + + ^ SpurMethodDictionary on: (self slotAt: self slotIndexForMethodDictionary) address image: self image +] + +{ #category : #'accessing - instance variables' } +SpurClass >> printOn: aStream [ + aStream nextPutAll: self className + "aStream nextPutAll: self className" + +] + +{ #category : #constants } +SpurClass >> slotIndexForClassFormat [ + ^ 3 +] + +{ #category : #constants } +SpurClass >> slotIndexForClassName [ + self flag: '4 for Candle'. + ^ "4" 7 +] + +{ #category : #constants } +SpurClass >> slotIndexForMetaclassInstanceVariableNames [ + self flag: '5 for Candle'. + ^ "5" 0 +] + +{ #category : #constants } +SpurClass >> slotIndexForMetaclassSoleInstance [ + self flag: '4 for Candle'. + + ^ "4" 6 +] + +{ #category : #constants } +SpurClass >> slotIndexForMethodDictionary [ + + ^ 2 +] + +{ #category : #constants } +SpurClass >> slotIndexForSuperclass [ + ^ 1 +] + +{ #category : #accessing } +SpurClass >> spSuperclass [ + | superclassOrNil | + superclassOrNil := self slotAt: self slotIndexForSuperclass. + ^ superclassOrNil spIsNil + ifTrue: [ superclassOrNil ] + ifFalse: [ superclassOrNil asSpurClass ] +] diff --git a/smalltalksrc/VMMaker-Tools/SpurCompiledMethodLayout.class.st b/smalltalksrc/VMMaker-Tools/SpurCompiledMethodLayout.class.st new file mode 100644 index 00000000000..1b1af53bb1a --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurCompiledMethodLayout.class.st @@ -0,0 +1,11 @@ +Class { + #name : #SpurCompiledMethodLayout, + #superclass : #SpurLayout, + #category : #'VMMaker-Tools-imageInspector' +} + +{ #category : #testing } +SpurCompiledMethodLayout >> isCompiledMethod [ + + ^ true +] diff --git a/smalltalksrc/VMMaker-Tools/SpurEmptyLayout.class.st b/smalltalksrc/VMMaker-Tools/SpurEmptyLayout.class.st new file mode 100644 index 00000000000..bab65e4c2b0 --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurEmptyLayout.class.st @@ -0,0 +1,5 @@ +Class { + #name : #SpurEmptyLayout, + #superclass : #SpurLayout, + #category : #'VMMaker-Tools-imageInspector' +} diff --git a/smalltalksrc/VMMaker-Tools/SpurFileImage.class.st b/smalltalksrc/VMMaker-Tools/SpurFileImage.class.st new file mode 100644 index 00000000000..acfcec79e54 --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurFileImage.class.st @@ -0,0 +1,321 @@ +Class { + #name : #SpurFileImage, + #superclass : #SpurImage, + #instVars : [ + 'format', + 'memory', + 'headerSize', + 'dataSize', + 'oldBaseAddress', + 'specialObjectsArrayOop' + ], + #category : #'VMMaker-Tools-imageInspector' +} + +{ #category : #'as yet unclassified' } +SpurFileImage class >> onFile: aFile [ + + | memory | + memory := aFile asFileReference binaryReadStream contents. + ^ self onMemory: memory +] + +{ #category : #'as yet unclassified' } +SpurFileImage class >> onMemory: aByteArray [ + + ^ self basicNew + memory: aByteArray; + initialize; + yourself +] + +{ #category : #'as yet unclassified' } +SpurFileImage class >> onMyself [ +| memory nilOop VM| + "nilOop := aSpur32BitMMLESimulator nilObject. + memory := aSpur32BitMMLESimulator memory asByteArray. + memory := fullMemory copyFrom: nilOop + 1 to: fullMemory size." + VM = VirtualMachine new. + + ^ self basicNew + memory: memory; + version: VM parameterAt: 41; + headerSize: nilOop; + specialObjectsArrayOop: VM specialObjectsOop; + oldBaseAddress: nilOop; + yourself +] + +{ #category : #'as yet unclassified' } +SpurFileImage class >> onSpurSimulator: aSpur32BitMMLESimulator [ + | memory nilOop | + nilOop := aSpur32BitMMLESimulator nilObject. + memory := aSpur32BitMMLESimulator memory memoryObject. + "memory := fullMemory copyFrom: nilOop + 1 to: fullMemory size." + + ^ self basicNew + memory: memory; + headerSize: nilOop - aSpur32BitMMLESimulator memory initialAddress - 1; + specialObjectsArrayOop: aSpur32BitMMLESimulator specialObjectsOop - aSpur32BitMMLESimulator memory initialAddress; + oldBaseAddress: nilOop - aSpur32BitMMLESimulator memory initialAddress; + hiddenRoots: aSpur32BitMMLESimulator hiddenRootsObject - aSpur32BitMMLESimulator memory initialAddress; + format: 64; + yourself +] + +{ #category : #'special-classes' } +SpurFileImage >> arrayClass [ + "indexInClassTable 51" + ^ self specialObjectsArray slotAt: 8 +] + +{ #category : #'special-classes' } +SpurFileImage >> byteArrayClass [ + "indexInClassTable 50" + ^ self specialObjectsArray slotAt: 27 +] + +{ #category : #'special-classes' } +SpurFileImage >> byteStringClass [ + "indexInClassTable 52" + ^ self specialObjectsArray slotAt: 7 +] + +{ #category : #'special-classes' } +SpurFileImage >> characterClass [ + "indexInClassTable 2" + ^ self specialObjectsArray slotAt: 20 +] + +{ #category : #'special-objects' } +SpurFileImage >> classTableFirstPage [ + ^ self hiddenRootsObj classTableFirstPage +] + +{ #category : #'special-objects' } +SpurFileImage >> firstObject [ + + ^ SpurObject on: headerSize + 1 image: self +] + +{ #category : #accessing } +SpurFileImage >> format [ + ^format +] + +{ #category : #accessing } +SpurFileImage >> format: anObject [ + + format := anObject +] + +{ #category : #'gt-inspector-extension' } +SpurFileImage >> gtInspectorSpecialObjectsArrayIn: composite [ + + + ^ [(self specialObjectsArray gtInspectorLayoutIn: composite) title: 'SOArray' ] on:Error do: [ 'lalala' ] +] + +{ #category : #accessing } +SpurFileImage >> headerSize [ + + ^ headerSize +] + +{ #category : #accessing } +SpurFileImage >> headerSize: anInteger [ + headerSize := anInteger +] + +{ #category : #accessing } +SpurFileImage >> initialize [ + + super initialize. + self readImageHeader. + simulator := self wordsize = 4 + ifTrue: [ Spur32BitMemoryManager simulatorClass new ] + ifFalse: [ Spur64BitMemoryManager simulatorClass new ]. +] + +{ #category : #'special-classes' } +SpurFileImage >> is32Bit [ + ^ format = 32 +] + +{ #category : #'special-classes' } +SpurFileImage >> is64Bit [ + ^ format = 64 +] + +{ #category : #'special-classes' } +SpurFileImage >> largeNegativeIntegerClass [ + "indexInClassTable 32" + ^ self specialObjectsArray slotAt: 43 +] + +{ #category : #'special-classes' } +SpurFileImage >> largePositiveIntegerClass [ + "indexInClassTable 33" + ^ self specialObjectsArray slotAt: 14 +] + +{ #category : #accessing } +SpurFileImage >> memory [ + ^ memory +] + +{ #category : #accessing } +SpurFileImage >> memory: aCollection [ + memory := aCollection +] + +{ #category : #'special-classes' } +SpurFileImage >> messageClass [ + "indexInClassTable 35" + ^ self specialObjectsArray slotAt: 16 +] + +{ #category : #'special-objects' } +SpurFileImage >> nextObjectOf: aSpurObject [ + | maybeObject | + maybeObject := SpurObject on: aSpurObject endAddress + self headerSize image: self. + ^ maybeObject basicNumberOfSlots = 16rFF + ifTrue: [ maybeObject ] + ifFalse: [ SpurObject on: aSpurObject endAddress image: self ]. +] + +{ #category : #'special-objects' } +SpurFileImage >> nilObject [ + ^ self firstObject +] + +{ #category : #accessing } +SpurFileImage >> oldBaseAddress [ + ^ oldBaseAddress +] + +{ #category : #accessing } +SpurFileImage >> oldBaseAddress: anInteger [ + oldBaseAddress := anInteger +] + +{ #category : #'special-classes' } +SpurFileImage >> pointClass [ + "indexInClassTable 54" + ^ self specialObjectsArray slotAt: 13 +] + +{ #category : #accessing } +SpurFileImage >> printByteSymbol: aByteSymbolClass [ + + ^ aByteSymbolClass asLocalByteArray asString reject: [ :e | e = Character null] +] + +{ #category : #accessing } +SpurFileImage >> readImageHeader [ + +"Reading the version will allow us to find the format" + self readVersionFromImageHeader. + self is32Bit ifTrue:[ + self readImageHeader32 ]. + self is64Bit ifTrue:[ + self readImageHeader64 ] + +] + +{ #category : #accessing } +SpurFileImage >> readImageHeader32 [ + | lastHash savedWindowSize headerFlags | + + headerSize := (memory copyFrom: 5 to: 8) + unsignedLongAt: 1 + bigEndian: false. + dataSize := (memory copyFrom: 9 to: 12) + unsignedLongAt: 1 + bigEndian: false. + self assert: headerSize + dataSize = memory size. + oldBaseAddress := (memory copyFrom: 13 to: 16) + unsignedLongAt: 1 + bigEndian: false. + specialObjectsArrayOop := (memory copyFrom: 17 to: 20) + unsignedLongAt: 1 + bigEndian: false. + lastHash := (memory copyFrom: 21 to: 24) + unsignedLongAt: 1 + bigEndian: false. + savedWindowSize := (memory copyFrom: 25 to: 28) + unsignedLongAt: 1 + bigEndian: false. + headerFlags := (memory copyFrom: 29 to: 32) + unsignedLongAt: 1 + bigEndian: false +] + +{ #category : #accessing } +SpurFileImage >> readImageHeader64 [ + | lastHash savedWindowSize headerFlags | + + headerSize := (memory copyFrom: 5 to: 8) + unsignedLongAt: 1 + bigEndian: false. + dataSize := (memory copyFrom: 9 to: 16) + unsignedLong64At: 1 + bigEndian: false. + self assert: headerSize + dataSize = memory size. + oldBaseAddress := (memory copyFrom: 17 to: 24) + unsignedLong64At: 1 + bigEndian: false. + specialObjectsArrayOop := (memory copyFrom: 25 to: 32) + unsignedLong64At: 1 + bigEndian: false. + lastHash := (memory copyFrom: 33 to: 40) + unsignedLong64At: 1 + bigEndian: false. + savedWindowSize := (memory copyFrom: 41 to: 48) + unsignedLong64At: 1 + bigEndian: false. + headerFlags := (memory copyFrom: 49 to: 56) + unsignedLong64At: 1 + bigEndian: false +] + +{ #category : #accessing } +SpurFileImage >> readVersionFromImageHeader [ + | version | + version := (memory copyFrom: 1 to: 4) + unsignedLongAt: 1 + bigEndian: false. + self flag: #ugly. + version < 10000 + ifTrue: [ format := 32] + ifFalse: [ format := 64]. + +] + +{ #category : #'special-classes' } +SpurFileImage >> semaphoreClass [ + "indexInClassTable 48" + ^ self specialObjectsArray slotAt: 19 +] + +{ #category : #'special-classes' } +SpurFileImage >> smallIntegerClass [ + "indexInClassTable 1" + ^ self specialObjectsArray slotAt: 6 +] + +{ #category : #accessing } +SpurFileImage >> specialObjectsArray [ + + ^ SpurObject on: specialObjectsArrayOop - oldBaseAddress + headerSize + 1 image: self +] + +{ #category : #accessing } +SpurFileImage >> specialObjectsArrayOop: anInteger [ + specialObjectsArrayOop := anInteger +] + +{ #category : #'special-classes' } +SpurFileImage >> wordsize [ + ^ self is32Bit ifTrue: [ 4 ] ifFalse: [ 8 ] +] diff --git a/smalltalksrc/VMMaker-Tools/SpurFixedLayout.class.st b/smalltalksrc/VMMaker-Tools/SpurFixedLayout.class.st new file mode 100644 index 00000000000..4f9c14f15b3 --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurFixedLayout.class.st @@ -0,0 +1,21 @@ +Class { + #name : #SpurFixedLayout, + #superclass : #SpurLayout, + #category : #'VMMaker-Tools-imageInspector' +} + +{ #category : #'gt-inspector-extension' } +SpurFixedLayout >> allSlots [ + ^ (1 to: self object numberOfSlots) collect: [ :index | self object slotAt: index ] +] + +{ #category : #'gt-inspector-extension' } +SpurFixedLayout >> gtInspectorLayoutIn: composite [ + ^ composite table + title: 'Inst Vars'; + display: [ + self allSlots collectWithIndex: [ :slot :index | index -> slot ] ]; + column: 'Index' evaluated: [:each | each key ]; + column: 'Value' evaluated: [ :each | each value ]; + send: #value +] diff --git a/smalltalksrc/VMMaker-Tools/SpurHiddenRoots.class.st b/smalltalksrc/VMMaker-Tools/SpurHiddenRoots.class.st new file mode 100644 index 00000000000..79d729008c9 --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurHiddenRoots.class.st @@ -0,0 +1,36 @@ +Class { + #name : #SpurHiddenRoots, + #superclass : #SpurObject, + #category : #'VMMaker-Tools-imageInspector' +} + +{ #category : #'as yet unclassified' } +SpurHiddenRoots >> classOrNilAtIndex: classIndex [ + + | classTablePage nilObj | + + "self assert: (classIndex <= self tagMask or: [classIndex >= image arrayClassIndexPun])." + nilObj := image nilObject. + classTablePage := self classTablePageNumber: (classIndex >> image classTableMajorIndexShift) + 1. + classTablePage = nilObj ifTrue: + [^nilObj]. + ^ (classTablePage + slotAt: (classIndex bitAnd: image classTableMinorIndexMask) + 1) asSpurClass +] + +{ #category : #'as yet unclassified' } +SpurHiddenRoots >> classTableFirstPage [ + ^ self classTablePageNumber: 1 +] + +{ #category : #'as yet unclassified' } +SpurHiddenRoots >> classTablePageNumber: anInteger [ + "anInteger is 1 based" + | classTablePage | + classTablePage := SpurObject + on:(self slotAt: anInteger) address + image: image. + self assert: classTablePage format = image arrayFormat. + self assert: classTablePage classIndex = image arrayClassIndexPun. + ^ classTablePage +] diff --git a/smalltalksrc/VMMaker-Tools/SpurImage.class.st b/smalltalksrc/VMMaker-Tools/SpurImage.class.st new file mode 100644 index 00000000000..7e5fe00f914 --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurImage.class.st @@ -0,0 +1,131 @@ +" +""| version (4 bytes) | headerSize (4 bytes) | datasize (4 bytes) | old base address (4 bytes) | special objects oop (4 bytes) | = 20 bytes + | last hash (4 bytes)| saved window size (4 bytes) | headerFlags (4 bytes) | extraVMMemory (4bytes) | stack pages (2 bytes) | = 18 bytes + | native method zone size (2 bytes) | eden size (4 bytes) | semaphore table max size (2 bytes) | the2ndUnknownShort (2 bytes) | = 10 bytes + | first segment size (4 bytes) | free old space (4 bytes) | = 8 bytes + | The rest 8 bytes are empty"" + +(spur specialObjectsArray slotAt: 1) address = spur firstObject address. +" +Class { + #name : #SpurImage, + #superclass : #Object, + #instVars : [ + 'hiddenRoots', + 'classTable', + 'simulator' + ], + #category : #'VMMaker-Tools-imageInspector' +} + +{ #category : #constants } +SpurImage >> arrayClassIndexPun [ + ^ 16 +] + +{ #category : #constants } +SpurImage >> arrayFormat [ + ^ 2 +] + +{ #category : #constants } +SpurImage >> classIndexFieldWidth [ + "22-bit class mask => ~ 4M classes" + ^22 +] + +{ #category : #accessing } +SpurImage >> classTable [ + + ^ classTable +] + +{ #category : #accessing } +SpurImage >> classTable: anObject [ + + classTable := anObject +] + +{ #category : #constants } +SpurImage >> classTableMajorIndexShift [ + "1024 entries per page (2^10); 22 bit classIndex implies 2^12 pages" + ^10 +] + +{ #category : #constants } +SpurImage >> classTableMinorIndexMask [ + "1024 entries per page (2^10); 22 bit classIndex implies 2^12 pages" + "self basicNew classTableMinorIndexMask" + ^1 << self classTableMajorIndexShift - 1 +] + +{ #category : #constants } +SpurImage >> classTablePageSize [ + + ^1 << self classTableMajorIndexShift +] + +{ #category : #constants } +SpurImage >> classTableRootSlots [ + "Answer the number of slots for class table pages in the hidden root object." + ^1 << (self classIndexFieldWidth - self classTableMajorIndexShift) +] + +{ #category : #'special-objects' } +SpurImage >> falseObject [ + ^ self nilObject nextObject +] + +{ #category : #'special-objects' } +SpurImage >> freeListObj [ + + ^ self trueObject nextObject +] + +{ #category : #'as yet unclassified' } +SpurImage >> hiddenRoots: anInteger [ + hiddenRoots := anInteger +] + +{ #category : #'special-objects' } +SpurImage >> hiddenRootsObj [ + + hiddenRoots ifNil: [ + hiddenRoots := self freeListObj nextObject address ]. + ^ SpurHiddenRoots on: hiddenRoots image: self +] + +{ #category : #'as yet unclassified' } +SpurImage >> imageFormat: anInteger [ + self shouldBeImplemented. +] + +{ #category : #'special-objects' } +SpurImage >> nextObjectOf: anOop [ + ^ self subclassResponsibility +] + +{ #category : #'special-objects' } +SpurImage >> nilObject [ + ^ self subclassResponsibility +] + +{ #category : #'as yet unclassified' } +SpurImage >> simulator [ + ^ simulator +] + +{ #category : #'as yet unclassified' } +SpurImage >> simulator: aSpur64BitMMLESimulator [ + simulator := aSpur64BitMMLESimulator +] + +{ #category : #'special-objects' } +SpurImage >> trueObject [ + ^ self falseObject nextObject +] + +{ #category : #'special-objects' } +SpurImage >> wordsize [ + ^ self subclassResponsibility +] diff --git a/smalltalksrc/VMMaker-Tools/SpurImmediateLayout.class.st b/smalltalksrc/VMMaker-Tools/SpurImmediateLayout.class.st new file mode 100644 index 00000000000..6c0e8a3c5f9 --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurImmediateLayout.class.st @@ -0,0 +1,5 @@ +Class { + #name : #SpurImmediateLayout, + #superclass : #SpurLayout, + #category : #'VMMaker-Tools-imageInspector' +} diff --git a/smalltalksrc/VMMaker-Tools/SpurLayout.class.st b/smalltalksrc/VMMaker-Tools/SpurLayout.class.st new file mode 100644 index 00000000000..592b339fe3d --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurLayout.class.st @@ -0,0 +1,141 @@ +Class { + #name : #SpurLayout, + #superclass : #Object, + #instVars : [ + 'object' + ], + #category : #'VMMaker-Tools-imageInspector' +} + +{ #category : #'as yet unclassified' } +SpurLayout class >> layoutClassFromFormat: objFormat [ + (objFormat = 0) + ifTrue: [ ^ SpurEmptyLayout ]. + (objFormat = 1) + ifTrue: [ ^ SpurFixedLayout ]. + (objFormat = 2) + ifTrue: [ ^ SpurVariableLayout ]. + (objFormat = 3) + ifTrue: [ ^SpurVariableWithInstanceVariablesLayout ]. + (objFormat = 4) + ifTrue: [ ^SpurVariableWithInstanceVariablesLayout ]. + (objFormat = 5) + ifTrue: [ ^SpurVariableWithInstanceVariablesLayout ]. + + (objFormat = 7) + ifTrue: [ ^SpurImmediateLayout]. + + (objFormat < 24 and: [ objFormat > 8 ]) + ifTrue: [ ^ SpurByteLayout ]. + (objFormat < 32 and: [ objFormat > 23 ]) + ifTrue: [ ^ SpurCompiledMethodLayout ]. + + ^ self error: 'Unused or invalid format.' + +] + +{ #category : #'as yet unclassified' } +SpurLayout class >> on: aSpurObject image: aSpurImage [ + | layoutClass | + "TH; Why passing the image here ?" + + layoutClass := self layoutClassFromFormat: aSpurObject objectFormat. + + ^ layoutClass new + object: aSpurObject. +] + +{ #category : #accessing } +SpurLayout >> address [ + ^ self object address +] + +{ #category : #accessing } +SpurLayout >> at: anInteger [ + + ^ self slotAt: anInteger +] + +{ #category : #accessing } +SpurLayout >> basicNumberOfSlots [ + ^ self headerInteger >> (self headerSize * 8 "bits" - 8 "number of slots mask size") +] + +{ #category : #accessing } +SpurLayout >> byteSize [ + ^ self object byteSize . +] + +{ #category : #'gt-inspector-extension' } +SpurLayout >> gtInspectorLayoutIn: composite [ + ^composite text + title: 'Spur view'; + display: [ [self object asString] on:Error do: [ 'Error printing' ] ] +] + +{ #category : #accessing } +SpurLayout >> headerInteger [ + ^ self object headerInteger +] + +{ #category : #accessing } +SpurLayout >> headerSize [ + ^ self object headerSize +] + +{ #category : #accessing } +SpurLayout >> image [ + ^ self object image +] + +{ #category : #testing } +SpurLayout >> isCompiledMethod [ + + ^ false +] + +{ #category : #accessing } +SpurLayout >> memory [ + ^ self object memory +] + +{ #category : #accessing } +SpurLayout >> numberOfSlots [ + + | slotsInHeader | + slotsInHeader := self basicNumberOfSlots. + slotsInHeader == 16rFF + ifTrue: [ ^ self previousHeaderInteger ]. + ^ slotsInHeader +] + +{ #category : #accessing } +SpurLayout >> object [ + ^ object +] + +{ #category : #accessing } +SpurLayout >> object: anObject [ + object := anObject +] + +{ #category : #printing } +SpurLayout >> objectPrintOn: aStream [ + aStream nextPutAll: 'a ', (self object basicClass asString) +] + +{ #category : #accessing } +SpurLayout >> previousHeaderInteger [ + ^ self object previousHeaderInteger +] + +{ #category : #accessing } +SpurLayout >> slotAt: anInteger [ + + ^ self image objectForOop: (object fetchPointer: anInteger) +] + +{ #category : #accessing } +SpurLayout >> wordSize [ + ^ self object wordSize +] diff --git a/smalltalksrc/VMMaker-Tools/SpurMethod.class.st b/smalltalksrc/VMMaker-Tools/SpurMethod.class.st new file mode 100644 index 00000000000..58e91ca2971 --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurMethod.class.st @@ -0,0 +1,55 @@ +Class { + #name : #SpurMethod, + #superclass : #SpurObject, + #category : #'VMMaker-Tools-imageInspector' +} + +{ #category : #accessing } +SpurMethod >> lastLiteral [ + + ^ self literalAt: (self numberOfLiterals + 1) +] + +{ #category : #accessing } +SpurMethod >> literalAt: anIndex [ + + ^ self slotAt: anIndex +] + +{ #category : #accessing } +SpurMethod >> methodClass [ + + | methodClassBinding | + methodClassBinding := self lastLiteral. + ^ (methodClassBinding slotAt: 2) vmPrintOop +] + +{ #category : #accessing } +SpurMethod >> methodHeader [ + ^ self slotAt: 1 +] + +{ #category : #accessing } +SpurMethod >> numberOfLiterals [ + "Mask to get the numberOfLietrals" + ^self methodHeader bitAnd: 16r7FFF +] + +{ #category : #accessing } +SpurMethod >> penultimateLiteral [ + + ^ self literalAt: self numberOfLiterals +] + +{ #category : #accessing } +SpurMethod >> selector [ + | selectorLiteral | + selectorLiteral := self penultimateLiteral. + (selectorLiteral basicClass asSpurClass className + = 'AdditionalMethodState') + ifFalse: [ ^ self image printByteSymbol: selectorLiteral ] + ifTrue: [ | selectorInAdditional | + selectorInAdditional := selectorLiteral + slotAt: 2. "Supossed to be the selector" + ^ self image printByteSymbol: selectorInAdditional ] +] diff --git a/smalltalksrc/VMMaker-Tools/SpurMethodDictionary.class.st b/smalltalksrc/VMMaker-Tools/SpurMethodDictionary.class.st new file mode 100644 index 00000000000..d50b39f7cdb --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurMethodDictionary.class.st @@ -0,0 +1,35 @@ +Class { + #name : #SpurMethodDictionary, + #superclass : #SpurObject, + #category : #'VMMaker-Tools-imageInspector' +} + +{ #category : #accessing } +SpurMethodDictionary >> firstMethod [ + + | index arrayOfMethod | + index := self firstSelectorIndex. + + arrayOfMethod := self slotAt: 2. + ^arrayOfMethod slotAt: index. + +] + +{ #category : #accessing } +SpurMethodDictionary >> firstSelector [ + + ^ self slotAt: self firstSelectorIndex + 2 +] + +{ #category : #accessing } +SpurMethodDictionary >> firstSelectorIndex [ + | currentIndex found | + currentIndex := 1. + found := nil. + [ currentIndex + 2 < self numberOfSlots and: [ found isNil ] ] + whileTrue: [ | object | + (object := (self slotAt: currentIndex + 2)) spIsNil + ifTrue: [ currentIndex := currentIndex + 1 ] + ifFalse: [ found := object. ^currentIndex ]. ]. + ^ nil +] diff --git a/smalltalksrc/VMMaker-Tools/SpurObject.class.st b/smalltalksrc/VMMaker-Tools/SpurObject.class.st new file mode 100644 index 00000000000..dc364c74d5a --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurObject.class.st @@ -0,0 +1,417 @@ +" +spur := SpurImage onFile: Smalltalk imagePath. +firstObject := spur firstObject. +secondObject := firstObject nextObject. +thirdObject := secondObject nextObject. +fourthObject := thirdObject nextObject. +fifthObject := fourthObject nextObject. + +firstObject basicNumberOfSlots. +secondObject basicNumberOfSlots. +thirdObject basicNumberOfSlots. +fourthObject classIndex. + +fifthObject classIndex. +fifthObject format. +fifthObject numberOfSlots. + +fifthObject nextObject nextObject nextObject nextObject nextObject nextObject numberOfSlots. + +(spur specialObjectsArray slotAt: 1) address = spur firstObject address. + +1) Podemos encontrar a nil? +2) Podemos encontrar a true? +3) Podemos encontrar a false? + +4) Podemos encontrar la tabla de clases? + 4.1) Como a partir de un class index (en el header del objeto) encontramos una clase en la tabla. + 4.2) Una vez que tenes la clase, recuperar el nombre de la clase (7ma variable es el nombre) + 4.3) Transformar un string en la imagen a un string normal. + 4.4) hacer un pretty print del objeto: + - nombre de la clase + - tipo de objeto / format + - tamaƱo +" +Class { + #name : #SpurObject, + #superclass : #Object, + #instVars : [ + 'address', + 'image', + 'spurLayout' + ], + #category : #'VMMaker-Tools-imageInspector' +} + +{ #category : #'as yet unclassified' } +SpurObject class >> on: address image: anImage [ + ^self new + address: address; + image: anImage; + yourself. + +] + +{ #category : #testing } +SpurObject >> = anotherObject [ + "if an oop is provided directly, we still allow the comparison" + (anotherObject isKindOf: SmallInteger) ifTrue: [ ^ anotherObject = address ]. + + ^ anotherObject address = address +] + +{ #category : #accessing } +SpurObject >> address [ + ^ address +] + +{ #category : #accessing } +SpurObject >> address: anInteger [ + address := anInteger +] + +{ #category : #'accessing-slots' } +SpurObject >> allSlots [ + + ^ self spurLayout allSlots +] + +{ #category : #converting } +SpurObject >> asLocalByteArray [ + ^ self spurLayout asLocalByteArray +] + +{ #category : #converting } +SpurObject >> asSpurClass [ + ^ SpurClass on: address image: self image +] + +{ #category : #accessing } +SpurObject >> basicClass [ + + ^ self image hiddenRootsObj classOrNilAtIndex: self classIndex. +] + +{ #category : #'accessing-slots' } +SpurObject >> basicNumberOfSlots [ + + ^ self spurLayout basicNumberOfSlots +] + +{ #category : #'accessing-header' } +SpurObject >> byteSize [ + + | numberOfSlots | + numberOfSlots := self numberOfSlots. + ^ (numberOfSlots = 0 + ifTrue: [ 1 ] + ifFalse: [ numberOfSlots ]) * self wordSize. +] + +{ #category : #'accessing-header' } +SpurObject >> classIndex [ + + ^ self headerInteger bitAnd: (2 raisedTo: 22) -1 +] + +{ #category : #printing } +SpurObject >> classOop [ + ^ self simulator fetchClassOf: address value +] + +{ #category : #printing } +SpurObject >> classSpurObject [ + ^ self class on: self classOop image: image +] + +{ #category : #accessing } +SpurObject >> endAddress [ + + | basicSize padding | + "All objects start aligned to 64 bits. + This means all objects FINISH aligned to 64 bits too" + basicSize := self headerSize + self byteSize. + padding := basicSize % 8. + ^ address + basicSize + padding +] + +{ #category : #accessing } +SpurObject >> fetchPointer: anInteger [ + + ^ self image fetchPointer: anInteger ofObject: self address value +] + +{ #category : #'accessing-header' } +SpurObject >> format [ + + ^ (self headerInteger >> 24) bitAnd: 2r11111 +] + +{ #category : #'gt-inspector-extension' } +SpurObject >> gtInspectorLayoutIn: composite [ + + ^self spurLayout gtInspectorLayoutIn: composite + +] + +{ #category : #accessing } +SpurObject >> header [ + ^ self isImmediate ifFalse: [ image simulator baseHeader: address value] +] + +{ #category : #'accessing-header' } +SpurObject >> headerInteger [ + + ^ self image headerOf: address +] + +{ #category : #'accessing-header' } +SpurObject >> headerSize [ + + ^ 8 "always 64 bits" +] + +{ #category : #constants } +SpurObject >> identityHashHalfWordMask [ + + ^16r3fffff +] + +{ #category : #accessing } +SpurObject >> image [ + ^ image +] + +{ #category : #accessing } +SpurObject >> image: anImage [ + image := anImage +] + +{ #category : #'accessing-header' } +SpurObject >> indexInClassTable [ + " Applies only if self contains a class. + Returns the index in the classTable of the class stored in objOop" + ^ self rawHashBits +] + +{ #category : #accessing } +SpurObject >> inspectionItems: aBuilder [ + + | items | + self isImmediate ifTrue: [ + ^ address value inspectIntegerIn: aBuilder ]. + items := { + #header -> (self header printStringBase: 2). + #class -> self classSpurObject. + #classIndex -> self classIndex. + #numSlots -> self numSlots. + } asOrderedCollection . + 1 to: self numSlots do: [ :i| + items add: (('slot', i printString) -> (self slotAt: i)) ]. + items add: #format -> self format. + items add: #hash -> self oopHash. + items add: #pinned -> self isPinned. + items add: (#space -> (self isOld ifTrue: 'Old Space' ifFalse: 'Young Space')). + items add: #immutable -> self isImmutable. + + + + ^ aBuilder newTable + addColumn: (SpStringTableColumn + title: 'Key' + evaluated: [ :each | StObjectPrinter asTruncatedTextFrom: each key ]) + beSortable; + addColumn: (SpStringTableColumn + title: 'Value' + evaluated: [ :each | StObjectPrinter asTruncatedTextFrom: each value ]) + beSortable; + items: items; + yourself +] + +{ #category : #'accessing-slots' } +SpurObject >> instanceVariables [ + ^ (1 to: self numSlots) collect: [ :index | self slotAt: index ] +] + +{ #category : #testing } +SpurObject >> isImmediate [ + ^ self simulator isImmediate: address value +] + +{ #category : #testing } +SpurObject >> isImmutable [ + ^ image simulator isImmutable: address value +] + +{ #category : #testing } +SpurObject >> isOld [ + ^ self simulator isOldObject: self address value +] + +{ #category : #testing } +SpurObject >> isYoung [ + ^ self simulator isYoungObject: self address value +] + +{ #category : #accessing } +SpurObject >> memory [ + + ^ image memory +] + +{ #category : #something } +SpurObject >> nextObject [ + ^ image nextObjectOf: self +] + +{ #category : #'accessing-slots' } +SpurObject >> numSlots [ + ^ self image numSlotsOf: self. +] + +{ #category : #'accessing-header' } +SpurObject >> objectFormat [ + + ^ (self headerInteger >> 24) bitAnd: 2r11111 +] + +{ #category : #converting } +SpurObject >> oop [ + + ^ address +] + +{ #category : #something } +SpurObject >> oopHash [ + ^ image simulator rawHashBitsOf: address value +] + +{ #category : #'accessing-header' } +SpurObject >> previousHeaderInteger [ + + ^ self memory integerAt: address + (0 - self headerSize) size: 4 signed: false +] + +{ #category : #printing } +SpurObject >> printAsCharacter [ + ^ self shouldBeImplemented +] + +{ #category : #printing } +SpurObject >> printAsImmediate [ + self isCharacter ifTrue: [ ^ self printAsCharacter ]. + "default case is a smallInteger" + ^ self printAsInteger +] + +{ #category : #printing } +SpurObject >> printAsInteger [ + ^ 'SmallInteger: ', address printString +] + +{ #category : #printing } +SpurObject >> printOn: aStream [ + | knownObject | + knownObject := VMFrameBuilder new memory: self simulator ; adaptAddressToMemory: address. + knownObject isString ifTrue: [ ^ aStream << knownObject ]. + + self isImmediate ifTrue:[ ^ aStream << self printAsImmediate ]. + + address printOn: aStream + +] + +{ #category : #printing } +SpurObject >> printString [ + | knownObject | + knownObject := VMFrameBuilder new memory: self simulator ; adaptAddressToMemory: address. + knownObject isString ifTrue: [ ^ knownObject ]. + + self isImmediate ifTrue:[ ^ self printAsImmediate ]. + + ^ String streamContents: [ :s | + s << address printString. + ] + +] + +{ #category : #'accessing-header' } +SpurObject >> rawHashBits [ + " Returns the index in the classTable of the class in objOop" + self flag: #endianness. + ^((self memory unsignedLongAt: self oop + 4 bigEndian: false) bitAnd: self identityHashHalfWordMask) +] + +{ #category : #accessing } +SpurObject >> simulator [ + ^self image simulator +] + +{ #category : #'accessing-slots' } +SpurObject >> slotAt: anIndex [ + "Api is 1 based but the memory api is O based" + self numSlots >= anIndex ifFalse: [ SubscriptOutOfBounds signal ]. + ^ SpurObject on: (self spurLayout slotAt: anIndex - 1) image: image +] + +{ #category : #'accessing-slots' } +SpurObject >> slotAt: anIndex put: aSpurObjectOrOop [ + "Our api is 1 based but the simulator is 0 based" + + | value | + self numSlots >= anIndex ifFalse: [ SubscriptOutOfBounds signal ]. + + value := aSpurObjectOrOop isInteger + ifTrue:[ aSpurObjectOrOop ] + ifFalse: [ aSpurObjectOrOop address ]. + + ^ self simulator + storePointer: anIndex - 1 + ofObject: self address + withValue: value +] + +{ #category : #accessing } +SpurObject >> slots [ + ^(self headerInteger bitAnd: 16rFF00000000000000) >> 56. +] + +{ #category : #testing } +SpurObject >> spIsNil [ + ^ self address = self image nilObject address +] + +{ #category : #accessing } +SpurObject >> spurLayout [ + ^ spurLayout ifNil: [ spurLayout := SpurLayout on: self image: image ] +] + +{ #category : #accessing } +SpurObject >> spurLayout: anObject [ + spurLayout := anObject +] + +{ #category : #testing } +SpurObject >> value [ + ^ (address class includesBehavior: SpurObject) + ifTrue: [ address address ] + ifFalse: [ address ] +] + +{ #category : #accessing } +SpurObject >> vmClass [ + ^self image classOf: self +] + +{ #category : #printing } +SpurObject >> vmPrintOop [ + + +] + +{ #category : #constants } +SpurObject >> wordSize [ + + ^ self image wordSize +] diff --git a/smalltalksrc/VMMaker-Tools/SpurSimulatorImage.class.st b/smalltalksrc/VMMaker-Tools/SpurSimulatorImage.class.st new file mode 100644 index 00000000000..dade6b16f0e --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurSimulatorImage.class.st @@ -0,0 +1,97 @@ +Class { + #name : #SpurSimulatorImage, + #superclass : #SpurImage, + #instVars : [ + 'currentObject' + ], + #classInstVars : [ + 'simulator' + ], + #category : #'VMMaker-Tools-imageInspector' +} + +{ #category : #'as yet unclassified' } +SpurSimulatorImage class >> onSpurSimulator: aSpur64BitMMLESimulator [ + + ^ self new + simulator: aSpur64BitMMLESimulator; + yourself +] + +{ #category : #'as yet unclassified' } +SpurSimulatorImage >> classOf: aSpurObject [ + ^self objectForOop: (simulator fetchClassOf: aSpurObject address) +] + +{ #category : #accessing } +SpurSimulatorImage >> currentObject: anOop [ + currentObject := anOop +] + +{ #category : #'as yet unclassified' } +SpurSimulatorImage >> falseObject [ + ^ self objectForOop: simulator falseObject +] + +{ #category : #'as yet unclassified' } +SpurSimulatorImage >> fetchPointer: anInteger ofObject: objectOop [ + + ^ simulator fetchPointer: anInteger ofObject: objectOop +] + +{ #category : #'as yet unclassified' } +SpurSimulatorImage >> headerOf: anInteger [ + ^simulator objectMemory baseHeader: anInteger value +] + +{ #category : #'as yet unclassified' } +SpurSimulatorImage >> inspectOop: anOop [ + ^ (SpurObject on: anOop image: self) inspect +] + +{ #category : #'as yet unclassified' } +SpurSimulatorImage >> inspectionItems: aBuilder [ + + ^ aBuilder newList + items: { currentObject }; + yourself +] + +{ #category : #'as yet unclassified' } +SpurSimulatorImage >> memory [ + ^simulator +] + +{ #category : #'as yet unclassified' } +SpurSimulatorImage >> nextObjectOf: anOop [ + "The simulator relies on class indexes, which we do not really set" + self shouldNotImplement +] + +{ #category : #'as yet unclassified' } +SpurSimulatorImage >> nilObject [ + ^ SpurObject on: simulator nilObject image: self + +] + +{ #category : #'as yet unclassified' } +SpurSimulatorImage >> numSlotsOf: aSpurObject [ + + ^simulator numSlotsOf: aSpurObject address value +] + +{ #category : #'as yet unclassified' } +SpurSimulatorImage >> objectForOop: anInteger [ + + ^ SpurObject on: anInteger image: self +] + +{ #category : #'as yet unclassified' } +SpurSimulatorImage >> trueObject [ + ^ self objectForOop: simulator trueObject +] + +{ #category : #'as yet unclassified' } +SpurSimulatorImage >> wordSize [ + ^ simulator wordSize +] diff --git a/smalltalksrc/VMMaker-Tools/SpurVariableLayout.class.st b/smalltalksrc/VMMaker-Tools/SpurVariableLayout.class.st new file mode 100644 index 00000000000..5dbeb2fd8dc --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurVariableLayout.class.st @@ -0,0 +1,21 @@ +Class { + #name : #SpurVariableLayout, + #superclass : #SpurLayout, + #category : #'VMMaker-Tools-imageInspector' +} + +{ #category : #'gt-inspector-extension' } +SpurVariableLayout >> allSlots [ + ^ self object instanceVariables +] + +{ #category : #'gt-inspector-extension' } +SpurVariableLayout >> gtInspectorLayoutIn: composite [ + ^ composite table + title: 'Items'; + display: [ + self allSlots collectWithIndex: [ :slot :index | index -> slot ] ]; + column: 'Index' evaluated: [:each | each key ]; + column: 'Value' evaluated: [ :each | each value ]; + send: #value +] diff --git a/smalltalksrc/VMMaker-Tools/SpurVariableWithInstanceVariablesLayout.class.st b/smalltalksrc/VMMaker-Tools/SpurVariableWithInstanceVariablesLayout.class.st new file mode 100644 index 00000000000..e710a991be7 --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/SpurVariableWithInstanceVariablesLayout.class.st @@ -0,0 +1,5 @@ +Class { + #name : #SpurVariableWithInstanceVariablesLayout, + #superclass : #SpurLayout, + #category : #'VMMaker-Tools-imageInspector' +} diff --git a/smalltalksrc/VMMaker-Tools/VMBytecodeToIRMapping.class.st b/smalltalksrc/VMMaker-Tools/VMBytecodeToIRMapping.class.st index d130040229f..1dc1ae633cd 100644 --- a/smalltalksrc/VMMaker-Tools/VMBytecodeToIRMapping.class.st +++ b/smalltalksrc/VMMaker-Tools/VMBytecodeToIRMapping.class.st @@ -5,7 +5,7 @@ Class { 'bytecodeInstruction', 'irInstruction' ], - #category : #'VMMaker-Tools' + #category : #'VMMaker-Tools-InspectorExtensions' } { #category : #accessing } diff --git a/smalltalksrc/VMMaker-Tools/VMDebugger.class.st b/smalltalksrc/VMMaker-Tools/VMDebugger.class.st index 7399a330a5f..0370328798f 100644 --- a/smalltalksrc/VMMaker-Tools/VMDebugger.class.st +++ b/smalltalksrc/VMMaker-Tools/VMDebugger.class.st @@ -13,7 +13,7 @@ Class { 'stack', 'frameContainer' ], - #category : #'VMMaker-Tools' + #category : #'VMMaker-Tools-MachineCodeDebugger' } { #category : #layout } diff --git a/smalltalksrc/VMMaker-Tools/VMInspectorTest.class.st b/smalltalksrc/VMMaker-Tools/VMInspectorTest.class.st new file mode 100644 index 00000000000..996e4250163 --- /dev/null +++ b/smalltalksrc/VMMaker-Tools/VMInspectorTest.class.st @@ -0,0 +1,214 @@ +Class { + #name : #VMInspectorTest, + #superclass : #VMInterpreterTests, + #instVars : [ + 'imageName', + 'image' + ], + #pools : [ + 'VMBasicConstants', + 'VMBytecodeConstants', + 'VMObjectIndices' + ], + #category : #'VMMaker-Tools-Tests' +} + +{ #category : #tests } +VMInspectorTest >> setSmallIntegerClassIntoClassTable [ + + | class | + class := self + newClassInOldSpaceWithSlots: 0 + instSpec: memory forwardedFormat. + image simulator setHashBitsOf: class to: memory smallIntegerTag. + image simulator + storePointer: memory smallIntegerTag + ofObject: memory classTableFirstPage + withValue: class. + ^class + +] + +{ #category : #running } +VMInspectorTest >> setUp [ + + super setUp. + image := SpurSimulatorImage onSpurSimulator: memory. +] + +{ #category : #'test-testing' } +VMInspectorTest >> testClassOfObjectIsNilObjectByDefault [ + | objectOop object | + objectOop := self newObjectWithSlots: 1. + + object := (image objectForOop: objectOop). + self assert: object classSpurObject equals: image simulator nilObject +] + +{ #category : #tests } +VMInspectorTest >> testEqualsOtherObject [ + | object1 object2 | + object1 := image objectForOop: (image simulator integerObjectOf: 42). + object2 := image objectForOop: (image simulator integerObjectOf: 42). + + self assert: object1 equals: object2 +] + +{ #category : #'test-testing' } +VMInspectorTest >> testImmutability [ + | object objectOop | + objectOop := (self newObjectWithSlots: 1). + object := image objectForOop: objectOop. + image simulator setIsImmutableOf: objectOop to: true. + + self assert: object isImmutable +] + +{ #category : #'test-testing' } +VMInspectorTest >> testImmutabilityISFalseByDefault [ + | object | + object := image objectForOop: (self newObjectWithSlots: 1). + + self assert: object isImmutable not +] + +{ #category : #tests } +VMInspectorTest >> testInspectOopInspectRightObject [ + | objectOop window | + objectOop := self newObjectWithSlots: 1. + window := image inspectOop: objectOop. + [self assert: window title equals: 'Inspector on ', objectOop printString] + ensure: [ window close ] +] + +{ #category : #tests } +VMInspectorTest >> testIntegerKnowsItsClass [ + | class object | + class := self setSmallIntegerClassIntoClassTable. + object := SpurObject on: (image simulator integerObjectOf: 42) image: image. + self assert: class equals: object classOop +] + +{ #category : #'test-testing' } +VMInspectorTest >> testIsImmediateObject [ + | object | + object := image objectForOop: (image simulator integerObjectOf: 42). + + self assert: object isImmediate +] + +{ #category : #'test-testing' } +VMInspectorTest >> testIsNotImmediateObject [ + | object | + object := image objectForOop: (self newObjectWithSlots: 1). + + self assert: object isImmediate not +] + +{ #category : #'test-testing' } +VMInspectorTest >> testIsOld [ + | oop | + oop := SpurObject on: (self newOldSpaceObjectWithSlots: 1) image: image. + + self assert: oop isOld. +] + +{ #category : #'test-testing' } +VMInspectorTest >> testIsYoung [ + | oop | + oop := SpurObject on: (self newObjectWithSlots: 1) image: image. + + self assert: oop isYoung. +] + +{ #category : #tests } +VMInspectorTest >> testNilHasNoInstanceVariable [ + + self assert: image nilObject instanceVariables isEmpty. +] + +{ #category : #'tests-printing' } +VMInspectorTest >> testNotEqualsNil [ + | object1 object2 | + object1 := image objectForOop: (image simulator integerObjectOf: 42). + object2 := image objectForOop: (image simulator nilObject). + + self deny: object1 equals: object2 +] + +{ #category : #'tests-printing' } +VMInspectorTest >> testObjectEqualOop [ + | object1 object2 | + object1 := image objectForOop: (image simulator integerObjectOf: 42). + object2 := image simulator integerObjectOf: 42. + + self assert: object1 equals: object2 +] + +{ #category : #tests } +VMInspectorTest >> testObjectWithInstanceVariableCycleWeCanNavigate [ + + | objectOop1 object1 objectOop2 object2 | + objectOop1 := self newObjectWithSlots: 1. + objectOop2 := self newObjectWithSlots: 1. + + object1 := (image objectForOop: objectOop1). + object2 := (image objectForOop: objectOop2). + + object1 slotAt: 1 put: object2. + object2 slotAt: 1 put: object1. + + self assert: (object1 slotAt: 1) address equals: object2. + self assert: (object2 slotAt: 1) address equals: object1. +] + +{ #category : #tests } +VMInspectorTest >> testObjectWithInstanceVariableHasInstanceVariable [ + + | objectOop | + objectOop := self newObjectWithSlots: 2. + self assert: (image objectForOop: objectOop) instanceVariables isNotEmpty. +] + +{ #category : #'tests-printing' } +VMInspectorTest >> testObjectWithNilClass [ + | oop object | + oop := self newObjectWithSlots: 1. + object := SpurObject on: oop image: image. + + self assert: object printString equals: oop printString +] + +{ #category : #'tests-printing' } +VMInspectorTest >> testPrintFalse [ + + self assert: 'falseObject' equals: image falseObject printString +] + +{ #category : #'tests-printing' } +VMInspectorTest >> testPrintNil [ + + self assert: 'nilObject' equals: image nilObject printString +] + +{ #category : #'tests-printing' } +VMInspectorTest >> testPrintTrue [ + + self assert: 'trueObject' equals: image trueObject printString +] + +{ #category : #tests } +VMInspectorTest >> testSlotAtPut [ + + | objectOop1 object1 objectOop2 object2 | + objectOop1 := self newObjectWithSlots: 1. + objectOop2 := self newObjectWithSlots: 1. + + object1 := (image objectForOop: objectOop1). + object2 := (image objectForOop: objectOop2). + + object1 slotAt: 1 put: object2. + object2 slotAt: 1 put: object1. + + self assert: (object1 slotAt: 1) address equals: object2. +] diff --git a/smalltalksrc/VMMaker-Tools/VMMachineCodeDebugger.class.st b/smalltalksrc/VMMaker-Tools/VMMachineCodeDebugger.class.st index 4c9770032c9..0f0d1cd9ba8 100644 --- a/smalltalksrc/VMMaker-Tools/VMMachineCodeDebugger.class.st +++ b/smalltalksrc/VMMaker-Tools/VMMachineCodeDebugger.class.st @@ -13,7 +13,7 @@ Class { 'ipInput', 'jumpToButton' ], - #category : #'VMMaker-Tools' + #category : #'VMMaker-Tools-MachineCodeDebugger' } { #category : #specs } diff --git a/smalltalksrc/VMMaker-Tools/VMMachineCodeDebuggerInstruction.class.st b/smalltalksrc/VMMaker-Tools/VMMachineCodeDebuggerInstruction.class.st index ff4c716ea74..d8879ba6069 100644 --- a/smalltalksrc/VMMaker-Tools/VMMachineCodeDebuggerInstruction.class.st +++ b/smalltalksrc/VMMaker-Tools/VMMachineCodeDebuggerInstruction.class.st @@ -7,7 +7,7 @@ Class { 'machineSimulator', 'debugger' ], - #category : #'VMMaker-Tools' + #category : #'VMMaker-Tools-MachineCodeDebugger' } { #category : #accessing } diff --git a/smalltalksrc/VMMaker-Tools/VMMachineCodeDebuggerStackItem.class.st b/smalltalksrc/VMMaker-Tools/VMMachineCodeDebuggerStackItem.class.st index 71406f5a9a0..b8ac1b37091 100644 --- a/smalltalksrc/VMMaker-Tools/VMMachineCodeDebuggerStackItem.class.st +++ b/smalltalksrc/VMMaker-Tools/VMMachineCodeDebuggerStackItem.class.st @@ -5,7 +5,7 @@ Class { 'address', 'machineSimulator' ], - #category : #'VMMaker-Tools' + #category : #'VMMaker-Tools-MachineCodeDebugger' } { #category : #'instance creation' } diff --git a/smalltalksrc/VMMaker-Tools/VMMethodBytecodeToIRMapping.class.st b/smalltalksrc/VMMaker-Tools/VMMethodBytecodeToIRMapping.class.st index b2296ab2bdd..da1741234cf 100644 --- a/smalltalksrc/VMMaker-Tools/VMMethodBytecodeToIRMapping.class.st +++ b/smalltalksrc/VMMaker-Tools/VMMethodBytecodeToIRMapping.class.st @@ -6,7 +6,7 @@ Class { 'ir', 'mappingList' ], - #category : #'VMMaker-Tools' + #category : #'VMMaker-Tools-InspectorExtensions' } { #category : #'instance creation' } diff --git a/smalltalksrc/VMMaker-Tools/VMTFreeListNode.class.st b/smalltalksrc/VMMaker-Tools/VMTFreeListNode.class.st index 8da7d377f6f..c5f7d16028e 100644 --- a/smalltalksrc/VMMaker-Tools/VMTFreeListNode.class.st +++ b/smalltalksrc/VMMaker-Tools/VMTFreeListNode.class.st @@ -5,7 +5,7 @@ Class { 'nodeOop', 'memory' ], - #category : #'VMMaker-Tools' + #category : #'VMMaker-Tools-InspectorExtensions' } { #category : #'instance-creation' } diff --git a/smalltalksrc/VMMaker-Tools/VMTFreeListNodeEdge.class.st b/smalltalksrc/VMMaker-Tools/VMTFreeListNodeEdge.class.st index eceeea24112..9ad7ed259bf 100644 --- a/smalltalksrc/VMMaker-Tools/VMTFreeListNodeEdge.class.st +++ b/smalltalksrc/VMMaker-Tools/VMTFreeListNodeEdge.class.st @@ -6,7 +6,7 @@ Class { 'label', 'nodeOop' ], - #category : #'VMMaker-Tools' + #category : #'VMMaker-Tools-InspectorExtensions' } { #category : #'instance-creation' } diff --git a/smalltalksrc/VMMaker-Tools/VMTFreeLists.class.st b/smalltalksrc/VMMaker-Tools/VMTFreeLists.class.st index 5a30887c109..4019272acd4 100644 --- a/smalltalksrc/VMMaker-Tools/VMTFreeLists.class.st +++ b/smalltalksrc/VMMaker-Tools/VMTFreeLists.class.st @@ -4,7 +4,7 @@ Class { #instVars : [ 'memory' ], - #category : #'VMMaker-Tools' + #category : #'VMMaker-Tools-InspectorExtensions' } { #category : #'instance-creation' } diff --git a/smalltalksrc/VMMaker-Tools/VMTFreeTreeNode.class.st b/smalltalksrc/VMMaker-Tools/VMTFreeTreeNode.class.st index af2283df513..386edc6d19e 100644 --- a/smalltalksrc/VMMaker-Tools/VMTFreeTreeNode.class.st +++ b/smalltalksrc/VMMaker-Tools/VMTFreeTreeNode.class.st @@ -1,7 +1,7 @@ Class { #name : #VMTFreeTreeNode, #superclass : #VMTFreeListNode, - #category : #'VMMaker-Tools' + #category : #'VMMaker-Tools-InspectorExtensions' } { #category : #accessing } diff --git a/smalltalksrc/VMMaker-Tools/VMTFreeTreeNodeEdge2.class.st b/smalltalksrc/VMMaker-Tools/VMTFreeTreeNodeEdge2.class.st index 42a2a312ce8..34095921650 100644 --- a/smalltalksrc/VMMaker-Tools/VMTFreeTreeNodeEdge2.class.st +++ b/smalltalksrc/VMMaker-Tools/VMTFreeTreeNodeEdge2.class.st @@ -1,5 +1,5 @@ Class { #name : #VMTFreeTreeNodeEdge2, #superclass : #VMTFreeListNodeEdge, - #category : #'VMMaker-Tools' + #category : #'VMMaker-Tools-InspectorExtensions' } diff --git a/smalltalksrc/VMMaker-Tools/VMTHiddenRoot.class.st b/smalltalksrc/VMMaker-Tools/VMTHiddenRoot.class.st index 2e3ef4fcf38..5668908a278 100644 --- a/smalltalksrc/VMMaker-Tools/VMTHiddenRoot.class.st +++ b/smalltalksrc/VMMaker-Tools/VMTHiddenRoot.class.st @@ -7,7 +7,7 @@ Class { 'label', 'oop' ], - #category : #'VMMaker-Tools' + #category : #'VMMaker-Tools-InspectorExtensions' } { #category : #accessing } diff --git a/smalltalksrc/VMMaker-Tools/VMTHiddenRootTable.class.st b/smalltalksrc/VMMaker-Tools/VMTHiddenRootTable.class.st index b619d2a4c61..edd9f08c4d7 100644 --- a/smalltalksrc/VMMaker-Tools/VMTHiddenRootTable.class.st +++ b/smalltalksrc/VMMaker-Tools/VMTHiddenRootTable.class.st @@ -4,7 +4,7 @@ Class { #instVars : [ 'memory' ], - #category : #'VMMaker-Tools' + #category : #'VMMaker-Tools-InspectorExtensions' } { #category : #'instance-creation' } diff --git a/smalltalksrc/VMMaker-Tools/VMTStackFrame.class.st b/smalltalksrc/VMMaker-Tools/VMTStackFrame.class.st index f54ca8db406..46911bce9cd 100644 --- a/smalltalksrc/VMMaker-Tools/VMTStackFrame.class.st +++ b/smalltalksrc/VMMaker-Tools/VMTStackFrame.class.st @@ -5,7 +5,7 @@ Class { 'memory', 'framePointer' ], - #category : #'VMMaker-Tools' + #category : #'VMMaker-Tools-InspectorExtensions' } { #category : #accessing } diff --git a/smalltalksrc/VMMakerTests/VMBlockTest.class.st b/smalltalksrc/VMMakerTests/VMBlockTest.class.st index 3573c2a3301..5d3e109befe 100644 --- a/smalltalksrc/VMMakerTests/VMBlockTest.class.st +++ b/smalltalksrc/VMMakerTests/VMBlockTest.class.st @@ -12,12 +12,6 @@ Class { VMBlockTest >> anEmptyMethod [ ] -{ #category : #'as yet unclassified' } -VMBlockTest >> evaluatingABlock [ - - [^1] value -] - { #category : #helpers } VMBlockTest >> installFullBlockClosureClass [ | aClass | @@ -135,22 +129,26 @@ VMBlockTest >> testCreatingABlockClosureKnowsCompiledBlock [ { #category : #testing } VMBlockTest >> testCreatingABlockClosureShouldCopyUsedMethodVariable [ - | methodReturning initialMethod | + | methodOop previousMethodOop | + methodOop := self createMethodOopFromPharoMethod: + self class >> #methodReturningABlock. - initialMethod := self createMethodOopFromPharoMethod: + previousMethodOop := self createMethodOopFromPharoMethod: self class >> #anEmptyMethod. + methodReturning := self createMethodOopFromPharoMethod: self class >> #methodReturningABlockInsideABlockWithLocal. self installFullBlockClosureClass. "We want to avoid baseFrameReturn (base frame initialisation)" - stackBuilder addNewFrame method: initialMethod. + stackBuilder addNewFrame method: previousMethodOop. stackBuilder addNewFrame - method: methodReturning; + method: methodOop; receiver: memory trueObject. stackBuilder buildStack. interpreter setMethod: stackBuilder lastFrame method. + interpreter instructionPointer: (methodBuilder bytecodeAt: 0 forMethod: methodReturning). interpreter interpretWhile: [ interpreter method = methodReturning ]. @@ -191,24 +189,27 @@ VMBlockTest >> testCreatingABlockClosureShouldHaveOuterContextObject [ { #category : #'as yet unclassified' } VMBlockTest >> testCreatingABlockInsideABlockClosureShouldCopyUsedBlockVariable [ - | methodReturning initialMethod | + | methodOop previousMethodOop | + methodOop := self createMethodOopFromPharoMethod: + self class >> #methodReturningABlockWithTwoArguments. - initialMethod := self createMethodOopFromPharoMethod: + previousMethodOop := self createMethodOopFromPharoMethod: self class >> #anEmptyMethod. + methodReturning := self createMethodOopFromPharoMethod: self class >> #methodReturningABlockInsideABlockWithLocal. self installFullBlockClosureClass. "We want to avoid baseFrameReturn (base frame initialisation)" - stackBuilder addNewFrame method: initialMethod. + stackBuilder addNewFrame method: previousMethodOop. stackBuilder addNewFrame - method: methodReturning; + method: methodOop; receiver: memory trueObject. stackBuilder buildStack. interpreter setMethod: stackBuilder lastFrame method. - interpreter instructionPointer: (methodBuilder bytecodeAt: 0 forMethod: methodReturning). - interpreter interpretWhile: [ interpreter method = methodReturning ]. + interpreter instructionPointer: (methodBuilder bytecodeAt: 0 forMethod: methodOop). + interpreter interpretWhile: [ interpreter method = methodOop ]. "We assign 2 to the local variable of the block, see methodReturningABlockInsideABlock" self assert: (memory fetchPointer: FullClosureFirstCopiedValueIndex ofObject: interpreter stackTop) equals: (memory integerObjectOf: 2). @@ -218,24 +219,21 @@ VMBlockTest >> testCreatingABlockInsideABlockClosureShouldCopyUsedBlockVariable { #category : #testing } VMBlockTest >> testCreatingABlockWithoutArgumentsClosureShouldHaveNoArgument [ - | methodReturning initialMethod | - - initialMethod := self createMethodOopFromPharoMethod: - self class >> #anEmptyMethod. - methodReturning := self createMethodOopFromPharoMethod: + | methodOop previousMethodOop | + methodOop := self createMethodOopFromPharoMethod: self class >> #methodReturningABlock. - self installFullBlockClosureClass. + self installFullBlockClosureClass. "We want to avoid baseFrameReturn (base frame initialisation)" - stackBuilder addNewFrame method: initialMethod. + stackBuilder addNewFrame method: previousMethodOop. stackBuilder addNewFrame - method: methodReturning; + method: methodOop; receiver: memory trueObject. stackBuilder buildStack. interpreter setMethod: stackBuilder lastFrame method. - interpreter instructionPointer: (methodBuilder bytecodeAt: 0 forMethod: methodReturning). - interpreter interpretWhile: [ interpreter method = methodReturning ]. + interpreter instructionPointer: (methodBuilder bytecodeAt: 0 forMethod: methodOop). + interpreter interpretWhile: [ interpreter method = methodOop ]. self assert: (memory fetchPointer: FullClosureNumArgsIndex ofObject: interpreter stackTop) equals: (memory integerObjectOf: 0). @@ -277,22 +275,22 @@ VMBlockTest >> testEvaluatingABlock [ { #category : #testing } VMBlockTest >> testPushClosureBytecodePushesClosure [ - | methodReturning initialMethod | + | methodOop previousMethodOop | + methodOop := self createMethodOopFromPharoMethod: + self class >> #methodReturningABlock. - initialMethod := self createMethodOopFromPharoMethod: + previousMethodOop := self createMethodOopFromPharoMethod: self class >> #anEmptyMethod. - methodReturning := self createMethodOopFromPharoMethod: - self class >> #methodReturningABlock. self installFullBlockClosureClass. "We want to avoid baseFrameReturn (base frame initialisation)" - stackBuilder addNewFrame method: initialMethod. + stackBuilder addNewFrame method: previousMethodOop. stackBuilder addNewFrame - method: methodReturning; + method: methodOop; receiver: memory trueObject. stackBuilder buildStack. interpreter setMethod: stackBuilder lastFrame method. - + interpreter interpretWhile: [ interpreter method = methodReturning ]. self diff --git a/smalltalksrc/VMMakerTests/VMFrameBuilder.class.st b/smalltalksrc/VMMakerTests/VMFrameBuilder.class.st index 9ca4938c7cf..3a2e22032cc 100644 --- a/smalltalksrc/VMMakerTests/VMFrameBuilder.class.st +++ b/smalltalksrc/VMMakerTests/VMFrameBuilder.class.st @@ -196,6 +196,7 @@ VMFrameBuilder >> gtInspectorItemsIn: composite [ ] + { #category : #initialization } VMFrameBuilder >> initializeWithInterpreter: anInterpreter andMemory: aMemory andMethodBuilder: aMethodBuilder [ memory := aMemory. @@ -249,6 +250,7 @@ VMFrameBuilder >> inspectFrameIn: aBuilder [ ] { #category : #accessing } + VMFrameBuilder >> instructionPointer [ ^ instructionPointer ]