[Vm-dev] VM Maker: VMMaker.oscog-eem.359.mcz
commits at source.squeak.org
commits at source.squeak.org
Tue Sep 10 00:07:19 UTC 2013
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.359.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.359
Author: eem
Time: 9 September 2013, 5:04:34.147 pm
UUID: 40208f59-0823-4cea-a81a-98e6d484dc8a
Ancestors: VMMaker.oscog-eem.358
Eliminate most if not all integer format numbers in favour of
symbolic consants such as indexablePointersFormat.
Implement SpurMemoryManager>>instantiateClass:indexableSize:.
Move isIndexable: to ObjectMemory.
Replace isInstanceOfClassCharacter: with isCharacterObject: and put
it in ObjectMemory & SpurMemoryManager (yet to fix completely
commonVariable:at:put:cacheIndex: which is written to expect the
value inst var yielding a SmallInteger).
Fix (Foo)InterpreterSimulator>>openAsMorph to cope with a
missing image name.
=============== Diff against VMMaker.oscog-eem.358 ===============
Item was changed:
----- Method: CogVMSimulator>>openAsMorph (in category 'UI') -----
openAsMorph
"Open a morphic view on this simulation."
| localImageName borderWidth theWindow |
+ localImageName := imageName
+ ifNotNil: [FileDirectory default localNameFor: imageName]
+ ifNil: [' synthetic image'].
- localImageName := FileDirectory default localNameFor: imageName.
theWindow := (SystemWindow labelled: 'Simulation of ', localImageName) model: self.
theWindow addMorph: (displayView := ImageMorph new image: displayForm)
frame: (0 at 0 corner: 1 at 0.8).
transcript := TranscriptStream on: (String new: 10000).
theWindow addMorph: (PluggableTextMorph
on: transcript text: nil accept: nil
readSelection: nil menu: #codePaneMenu:shifted:)
frame: (0 at 0.8 corner: 0.7 at 1).
theWindow addMorph: (PluggableTextMorph on: self
text: #byteCountText accept: nil
readSelection: nil menu: #utilitiesMenu:) hideScrollBarsIndefinitely
frame: (0.7 at 0.8 corner: 1 at 1).
borderWidth := [SystemWindow borderWidth] "Squeak 4.1"
on: MessageNotUnderstood
do: [:ex| 0]. "3.8"
borderWidth := borderWidth + theWindow borderWidth.
theWindow openInWorldExtent: (self desiredDisplayExtent
+ (2 * borderWidth)
+ (0 at theWindow labelHeight)
* (1@(1/0.8))) rounded!
Item was removed:
- ----- Method: Interpreter>>isIndexable: (in category 'object format') -----
- isIndexable: oop
- ^(self formatOf: oop) >= 2!
Item was removed:
- ----- Method: InterpreterPrimitives>>isInstanceOfClassCharacter: (in category 'primitive support') -----
- isInstanceOfClassCharacter: oop
- <inline: true>
- "N.B. Because Slang always inlines is:instanceOf:compactClassIndex:
- (because is:instanceOf:compactClassIndex: has an inline: pragma) the
- phrase (objectMemory splObj: ClassCharacter) is expanded in-place
- and is _not_ evaluated if oop has a non-zero CompactClassIndex."
- ^objectMemory
- is: oop
- instanceOf: (objectMemory splObj: ClassCharacter)
- compactClassIndex: 0!
Item was changed:
----- Method: InterpreterPrimitives>>positive32BitValueOf: (in category 'primitive support') -----
positive32BitValueOf: oop
"Convert the given object into an integer value.
The object may be either a positive SmallInteger or a four-byte LargePositiveInteger."
| value ok |
+ (objectMemory isIntegerObject: oop)
+ ifTrue:
+ [value := objectMemory integerValueOf: oop.
+ value < 0 ifTrue: [self primitiveFail. value := 0].
+ ^value]
+ ifFalse:
+ [(objectMemory hasSpurMemoryManagerAPI
+ and: [objectMemory isImmediate: oop]) ifTrue:
+ [self primitiveFail.
+ ^0]].
- (objectMemory isIntegerObject: oop) ifTrue:
- [value := objectMemory integerValueOf: oop.
- value < 0 ifTrue: [self primitiveFail. value := 0].
- ^value].
ok := objectMemory isClassOfNonImm: oop
equalTo: (objectMemory splObj: ClassLargePositiveInteger)
compactClassIndex: ClassLargePositiveIntegerCompactIndex.
(ok and: [(objectMemory lengthOf: oop) = 4]) ifFalse:
[self primitiveFail.
^0].
^(objectMemory fetchByte: 0 ofObject: oop)
+ ((objectMemory fetchByte: 1 ofObject: oop) << 8)
+ ((objectMemory fetchByte: 2 ofObject: oop) << 16)
+ ((objectMemory fetchByte: 3 ofObject: oop) << 24)!
Item was changed:
----- Method: InterpreterPrimitives>>primitiveNewWithArg (in category 'object access primitives') -----
primitiveNewWithArg
"Allocate a new indexable instance. Fail if the allocation would leave less than lowSpaceThreshold bytes free. May cause a GC."
| size spaceOkay |
size := self positive32BitValueOf: self stackTop.
(self successful and: [size >= 0])
ifTrue:
+ [objectMemory hasSpurMemoryManagerAPI
+ ifTrue:
+ [(objectMemory instantiateClass: (self stackValue: 1) indexableSize: size)
+ ifNotNil: [:obj| self pop: argumentCount + 1 thenPush: obj]
+ ifNil: [self primitiveFailFor: PrimErrNoMemory]]
- [spaceOkay := objectMemory sufficientSpaceToInstantiate: (self stackValue: 1) indexableSize: size.
- spaceOkay ifTrue:
- [self
- pop: argumentCount + 1
- thenPush: (objectMemory instantiateClass: (self stackValue: 1) indexableSize: size)]
ifFalse:
+ [spaceOkay := objectMemory sufficientSpaceToInstantiate: (self stackValue: 1) indexableSize: size.
+ spaceOkay
+ ifTrue:
+ [self
+ pop: argumentCount + 1
+ thenPush: (objectMemory instantiateClass: (self stackValue: 1) indexableSize: size)]
+ ifFalse:
+ [self primitiveFailFor: PrimErrNoMemory]]]
- [self primitiveFailFor: PrimErrNoMemory]]
ifFalse:
[self primitiveFailFor: PrimErrBadArgument]!
Item was changed:
----- Method: InterpreterPrimitives>>primitiveSize (in category 'indexing primitives') -----
primitiveSize
| rcvr hdr fmt fixedFields totalLength |
rcvr := self stackTop.
((objectMemory isImmediate: rcvr) "Integers are not indexable"
or: [hdr := objectMemory baseHeader: rcvr.
(fmt := objectMemory formatOfHeader: hdr) < 2]) "This is not an indexable object"
ifTrue:
[^self primitiveFailFor: PrimErrBadReceiver].
+ (fmt = objectMemory indexablePointersFormat
+ and: [objectMemory isContextHeader: hdr]) ifTrue:
- (fmt = 3 and: [objectMemory isContextHeader: hdr]) ifTrue:
[^self primitiveContextSize].
totalLength := objectMemory lengthOf: rcvr baseHeader: hdr format: fmt.
fixedFields := objectMemory fixedFieldsOf: rcvr format: fmt length: totalLength.
self pop: argumentCount + 1 thenPush: (objectMemory integerObjectOf: totalLength - fixedFields)!
Item was changed:
----- Method: InterpreterSimulator>>openAsMorph (in category 'UI') -----
openAsMorph
"Open a morphic view on this simulation."
| window localImageName |
+ localImageName := imageName
+ ifNotNil: [FileDirectory default localNameFor: imageName]
+ ifNil: [' synthetic image'].
- localImageName := FileDirectory default localNameFor: imageName.
window := (SystemWindow labelled: 'Simulation of ' , localImageName) model: self.
window addMorph: (displayView := ImageMorph new image: displayForm)
frame: (0 at 0 corner: 1 at 0.8).
transcript := TranscriptStream on: (String new: 10000).
window addMorph: (PluggableTextMorph on: transcript text: nil accept: nil
readSelection: nil menu: #codePaneMenu:shifted:)
frame: (0 at 0.8 corner: 0.7 at 1).
window addMorph: (PluggableTextMorph on: self
text: #byteCountText accept: nil) hideScrollBarsIndefinitely
frame: (0.7 at 0.8 corner: 1 at 1).
window openInWorld!
Item was removed:
- ----- Method: NewspeakInterpreter>>isIndexable: (in category 'object format') -----
- isIndexable: oop
- ^(self formatOf: oop) >= 2!
Item was changed:
----- Method: NewspeakInterpreterSimulator>>openAsMorph (in category 'UI') -----
openAsMorph
"Open a morphic view on this simulation."
| window localImageName |
+ localImageName := imageName
+ ifNotNil: [FileDirectory default localNameFor: imageName]
+ ifNil: [' synthetic image'].
- localImageName := FileDirectory default localNameFor: imageName.
window := (SystemWindow labelled: 'Simulation of ', localImageName) model: self.
window addMorph: (displayView := ImageMorph new image: displayForm)
frame: (0 at 0 corner: 1 at 0.8).
transcript := TranscriptStream on: (String new: 10000).
window addMorph: (PluggableTextMorph
on: transcript text: nil accept: nil
readSelection: nil menu: #codePaneMenu:shifted:)
frame: (0 at 0.8 corner: 0.7 at 1).
window addMorph: (PluggableTextMorph on: self
text: #byteCountText accept: nil
readSelection: nil menu: #utilitiesMenu:) hideScrollBarsIndefinitely
frame: (0.7 at 0.8 corner: 1 at 1).
window openInWorldExtent: (self desiredDisplayExtent
+ (2 * window borderWidth)
+ (0 at window labelHeight)
* (1@(1/0.8))) rounded!
Item was added:
+ ----- Method: ObjectMemory>>firstCompiledMethodFormat (in category 'header access') -----
+ firstCompiledMethodFormat
+ ^12!
Item was added:
+ ----- Method: ObjectMemory>>firstStringyFakeFormat (in category 'header access') -----
+ firstStringyFakeFormat
+ "A fake format for the interpreter used to mark indexable strings in
+ the interpreter's at cache. This is larger than any format."
+ ^16!
Item was added:
+ ----- Method: ObjectMemory>>indexablePointersFormat (in category 'header access') -----
+ indexablePointersFormat
+ ^3!
Item was added:
+ ----- Method: ObjectMemory>>isCharacterObject: (in category 'interpreter access') -----
+ isCharacterObject: oop
+ <inline: true>
+ "N.B. Because Slang always inlines is:instanceOf:compactClassIndex:
+ (because is:instanceOf:compactClassIndex: has an inline: pragma) the
+ phrase (self splObj: ClassCharacter) is expanded in-place
+ and is _not_ evaluated if oop has a non-zero CompactClassIndex."
+ ^self
+ is: oop
+ instanceOf: (self splObj: ClassCharacter)
+ compactClassIndex: 0!
Item was added:
+ ----- Method: ObjectMemory>>isIndexable: (in category 'object format') -----
+ isIndexable: oop
+ ^(self formatOf: oop) >= 2!
Item was added:
+ ----- Method: ObjectMemory>>weakArrayFormat (in category 'header access') -----
+ weakArrayFormat
+ ^4!
Item was changed:
----- Method: Spur32BitMemoryManager>>fillObj:numSlots:with: (in category 'allocation') -----
fillObj: objOop numSlots: numSlots with: fillValue
objOop + self baseHeaderSize
+ to: objOop + self baseHeaderSize + (numSlots * 4) - 1
- to: objOop + self baseHeaderSize + (numSlots * 4)
by: self allocationUnit
do: [:p|
+ self assert: p < (self addressAfter: objOop).
self longAt: p put: fillValue;
longAt: p + 4 put: fillValue]!
Item was added:
+ ----- Method: Spur32BitMemoryManager>>instantiateClass:indexableSize: (in category 'allocation') -----
+ instantiateClass: classObj indexableSize: nElements
+ | instSpec classFormat numSlots classIndex newObj fillValue |
+ classFormat := self formatOfClass: classObj.
+ instSpec := self instSpecOfClassFormat: classFormat.
+ fillValue := 0.
+ instSpec caseOf: {
+ [self indexablePointersFormat] ->
+ [numSlots := (self fixedFieldsOfClassFormat: classFormat) + nElements.
+ fillValue := nilObj].
+ [self sixtyFourBitIndexableFormat] ->
+ [numSlots := nElements * 2].
+ [self firstLongFormat] ->
+ [numSlots := nElements].
+ [self firstShortFormat] ->
+ [numSlots := nElements + 1 // 2.
+ instSpec := instSpec + (nElements bitAnd: 1)].
+ [self firstByteFormat] ->
+ [numSlots := nElements + 3 // 4.
+ instSpec := instSpec + (nElements bitAnd: 3)].
+ [self firstCompiledMethodFormat] ->
+ [numSlots := nElements + 3 // 4.
+ instSpec := instSpec + (nElements bitAnd: 3)] }
+ otherwise: [^nil]. "non-indexable"
+ classIndex := self hashBitsOf: classObj.
+ classIndex = 0 ifTrue:
+ [(self enterIntoClassTable: classObj) ifFalse:
+ [^nil].
+ classIndex := self hashBitsOf: classObj].
+ newObj := self allocateSlots: numSlots format: instSpec classIndex: classIndex.
+ newObj ifNotNil:
+ [self fillObj: newObj numSlots: numSlots with: fillValue].
+ ^newObj!
Item was added:
+ ----- Method: Spur64BitMemoryManager>>instantiateClass:indexableSize: (in category 'allocation') -----
+ instantiateClass: classObj indexableSize: nElements
+ | instSpec classFormat numSlots classIndex newObj fillValue |
+ classFormat := self formatOfClass: classObj.
+ instSpec := self instSpecOfClassFormat: classFormat.
+ fillValue := 0.
+ instSpec caseOf: {
+ [self indexablePointersFormat] ->
+ [numSlots := (self fixedFieldsOfClassFormat: classFormat) + nElements.
+ fillValue := nilObj].
+ [self sixtyFourBitIndexableFormat] ->
+ [numSlots := nElements].
+ [self firstLongFormat] ->
+ [numSlots := nElements + 1 // 2.
+ instSpec := instSpec + (nElements bitAnd: 1)].
+ [self firstShortFormat] ->
+ [numSlots := nElements + 3 // 4.
+ instSpec := instSpec + (nElements bitAnd: 3)].
+ [self firstByteFormat] ->
+ [numSlots := nElements + 7 // 8.
+ instSpec := instSpec + (nElements bitAnd: 7)].
+ [self firstCompiledMethodFormat] ->
+ [numSlots := nElements + 7 // 8.
+ instSpec := instSpec + (nElements bitAnd: 7)] }
+ otherwise: [^nil]. "non-indexable"
+ classIndex := self hashBitsOf: classObj.
+ classIndex = 0 ifTrue:
+ [(self enterIntoClassTable: classObj) ifFalse:
+ [^nil].
+ classIndex := self hashBitsOf: classObj].
+ newObj := self allocateSlots: numSlots format: instSpec classIndex: classIndex.
+ newObj ifNotNil:
+ [self fillObj: newObj numSlots: numSlots with: fillValue].
+ ^newObj!
Item was added:
+ ----- Method: SpurMemoryManager class>>vmProxyMajorVersion (in category 'simulation only') -----
+ vmProxyMajorVersion
+ "hack around the CoInterpreter/ObjectMemory split refactoring"
+ ^StackInterpreter vmProxyMajorVersion!
Item was added:
+ ----- Method: SpurMemoryManager class>>vmProxyMinorVersion (in category 'simulation only') -----
+ vmProxyMinorVersion
+ "hack around the CoInterpreter/ObjectMemory split refactoring"
+ ^StackInterpreter vmProxyMinorVersion!
Item was added:
+ ----- Method: SpurMemoryManager>>firstStringyFakeFormat (in category 'header format') -----
+ firstStringyFakeFormat
+ "A fake format for the interpreter used to mark indexable strings in
+ the interpreter's at cache. This is larger than any format."
+ ^32!
Item was changed:
----- Method: SpurMemoryManager>>fixedFieldsOf:format:length: (in category 'object format') -----
fixedFieldsOf: objOop format: fmt length: wordLength
| class |
<inline: true>
<asmLabel: false>
+ (fmt > self lastPointerFormat or: [fmt = 2]) ifTrue: [^0]. "indexable fields only"
- (fmt > self ephemeronFormat or: [fmt = 2]) ifTrue: [^0]. "indexable fields only"
fmt < 2 ifTrue: [^wordLength]. "fixed fields only (zero or more)"
class := self fetchClassOfNonImm: objOop.
^self fixedFieldsOfClassFormat: (self formatOfClass: class)!
Item was added:
+ ----- Method: SpurMemoryManager>>instantiateClass:indexableSize: (in category 'allocation') -----
+ instantiateClass: classObj indexableSize: nElements
+ ^self subclassResponsibility!
Item was added:
+ ----- Method: SpurMemoryManager>>isArray: (in category 'object testing') -----
+ isArray: oop
+ "Answer true if this is an indexable object with pointer elements, e.g., an array"
+ ^(self isNonImmediate: oop) and: [self isArrayNonImm: oop]!
Item was added:
+ ----- Method: SpurMemoryManager>>isArrayNonImm: (in category 'object testing') -----
+ isArrayNonImm: oop
+ "Answer true if this is an indexable object with pointer elements, e.g., an array"
+ ^ (self formatOf: oop) = self arrayFormat!
Item was added:
+ ----- Method: SpurMemoryManager>>isCharacterObject: (in category 'object testing') -----
+ isCharacterObject: oop
+ ^(oop bitAnd: self tagMask) = self characterTag!
Item was added:
+ ----- Method: SpurMemoryManager>>isInEden: (in category 'object testing') -----
+ isInEden: objOop
+ ^objOop >= scavenger eden start
+ and: [objOop < scavenger eden limit]!
Item was added:
+ ----- Method: SpurMemoryManager>>isIndexable: (in category 'object testing') -----
+ isIndexable: objOop
+ ^(self formatOf: objOop) >= self sixtyFourBitIndexableFormat!
Item was added:
+ ----- Method: SpurMemoryManager>>isIndexableFormat: (in category 'object testing') -----
+ isIndexableFormat: format
+ ^format >= self sixtyFourBitIndexableFormat!
Item was changed:
----- Method: SpurMemoryManager>>isIntegerObject: (in category 'object testing') -----
isIntegerObject: oop
(#( makeBaseFrameFor:
quickFetchInteger:ofObject:
frameOfMarriedContext:
addressCouldBeClassObj:
isMarriedOrWidowedContext:
shortPrint:
bytecodePrimAt
commonAt:
+ loadFloatOrIntFrom:
+ positive32BitValueOf:
+ primitiveExternalCall
+ checkedIntegerValueOf:) includes: thisContext sender method selector) ifFalse:
- loadFloatOrIntFrom:) includes: thisContext sender method selector) ifFalse:
[self halt].
^(oop bitAnd: 1) ~= 0!
Item was added:
+ ----- Method: SpurMemoryManager>>isPointers: (in category 'object testing') -----
+ isPointers: oop
+ "Answer if the argument has only fields that can hold oops. See comment in formatOf:"
+
+ ^(self isNonImmediate: oop) and: [self isPointersNonImm: oop]!
Item was added:
+ ----- Method: SpurMemoryManager>>isPointersFormat: (in category 'object testing') -----
+ isPointersFormat: format
+ ^format <= self lastPointerFormat!
Item was changed:
----- Method: SpurMemoryManager>>isPointersNonImm: (in category 'object testing') -----
isPointersNonImm: objOop
"Answer if the argument has only fields that can hold oops. See comment in formatOf:"
+ ^(self formatOf: objOop) <= self lastPointerFormat!
- ^(self formatOf: objOop) <= 5!
Item was added:
+ ----- Method: SpurMemoryManager>>sizeBitsOfSafe: (in category 'object access') -----
+ sizeBitsOfSafe: objOop
+ ^self sizeBitsOf: objOop!
Item was changed:
----- Method: StackInterpreter>>commonVariable:at:cacheIndex: (in category 'indexing primitive support') -----
commonVariable: rcvr at: index cacheIndex: atIx
"This code assumes the receiver has been identified at location atIx in the atCache."
| stSize fmt fixedFields result |
<inline: true>
stSize := atCache at: atIx+AtCacheSize.
((self oop: index isGreaterThanOrEqualTo: 1)
and: [self oop: index isLessThanOrEqualTo: stSize]) ifTrue:
[fmt := atCache at: atIx+AtCacheFmt.
+ fmt <= objectMemory weakArrayFormat ifTrue:
- fmt <= 4 ifTrue:
[self assert: (objectMemory isContextNonInt: rcvr) not.
fixedFields := atCache at: atIx+AtCacheFixedFields.
^objectMemory fetchPointer: index + fixedFields - 1 ofObject: rcvr].
+ fmt < objectMemory firstByteFormat ifTrue: "Bitmap"
- fmt < 8 ifTrue: "Bitmap"
[result := objectMemory fetchLong32: index - 1 ofObject: rcvr.
^self positive32BitIntegerFor: result].
+ fmt >= objectMemory firstStringyFakeFormat "Note fmt >= firstStringyFormat is an artificial flag for strings"
- fmt >= 16 "Note fmt >= 16 is an artificial flag for strings"
ifTrue: "String"
[^self characterForAscii: (objectMemory fetchByte: index - 1 ofObject: rcvr)]
ifFalse:
+ [(fmt < objectMemory firstCompiledMethodFormat "ByteArray"
- [(fmt < 12 "ByteArray"
or: [index >= (self firstByteIndexOfMethod: rcvr) "CompiledMethod"]) ifTrue:
[^objectMemory integerObjectOf: (objectMemory fetchByte: index - 1 ofObject: rcvr)]]].
+ ^self primitiveFailFor: ((objectMemory isIndexable: rcvr)
+ ifFalse: [PrimErrBadReceiver]
+ ifTrue: [PrimErrBadIndex])!
- ^self primitiveFailFor: ((objectMemory formatOf: rcvr) <= 1
- ifTrue: [PrimErrBadReceiver]
- ifFalse: [PrimErrBadIndex])!
Item was changed:
----- Method: StackInterpreter>>commonVariable:at:put:cacheIndex: (in category 'indexing primitive support') -----
commonVariable: rcvr at: index put: value cacheIndex: atIx
"This code assumes the receiver has been identified at location atIx in the atCache."
| stSize fmt fixedFields valToPut isCharacter |
<inline: true>
stSize := atCache at: atIx+AtCacheSize.
((self oop: index isGreaterThanOrEqualTo: 1)
and: [self oop: index isLessThanOrEqualTo: stSize]) ifTrue:
[fmt := atCache at: atIx+AtCacheFmt.
+ fmt <= objectMemory weakArrayFormat ifTrue:
- fmt <= 4 ifTrue:
[self assert: (objectMemory isContextNonInt: rcvr) not.
fixedFields := atCache at: atIx+AtCacheFixedFields.
^objectMemory storePointer: index + fixedFields - 1 ofObject: rcvr withValue: value].
+ fmt < objectMemory firstByteFormat ifTrue: "Bitmap"
- fmt < 8 ifTrue: "Bitmap"
[valToPut := self positive32BitValueOf: value.
+ self successful ifTrue:
+ [objectMemory storeLong32: index - 1 ofObject: rcvr withValue: valToPut.
+ ^nil].
+ ^self primitiveFailFor: PrimErrBadArgument].
+ fmt >= objectMemory firstStringyFakeFormat "Note fmt >= firstStringyFormat is an artificial flag for strings"
+ ifTrue: [isCharacter := objectMemory isCharacterObject: value.
- self successful ifTrue: [objectMemory storeLong32: index - 1 ofObject: rcvr withValue: valToPut].
- ^nil].
- fmt >= 16 "Note fmt >= 16 is an artificial flag for strings"
- ifTrue: [isCharacter := self isInstanceOfClassCharacter: value.
isCharacter ifFalse:
[^self primitiveFailFor: PrimErrBadArgument].
valToPut := objectMemory fetchPointer: CharacterValueIndex ofObject: value]
ifFalse:
+ [(fmt >= objectMemory firstCompiledMethodFormat and: [index < (self firstByteIndexOfMethod: rcvr)]) ifTrue: "CompiledMethod"
- [(fmt >= 12 and: [index < (self firstByteIndexOfMethod: rcvr)]) ifTrue: "CompiledMethod"
[^self primitiveFailFor: PrimErrBadIndex].
valToPut := value].
(objectMemory isIntegerObject: valToPut) ifTrue:
[valToPut := objectMemory integerValueOf: valToPut.
((valToPut >= 0) and: [valToPut <= 255]) ifFalse: [^self primitiveFailFor: PrimErrBadArgument].
^objectMemory storeByte: index - 1 ofObject: rcvr withValue: valToPut]].
+ ^self primitiveFailFor: ((objectMemory isIndexable: rcvr)
+ ifFalse: [PrimErrBadReceiver]
+ ifTrue: [PrimErrBadIndex])!
- ^self primitiveFailFor: ((objectMemory formatOf: rcvr) <= 1
- ifTrue: [PrimErrBadReceiver]
- ifFalse: [PrimErrBadIndex])!
Item was changed:
----- Method: StackInterpreter>>install:inAtCache:at:string: (in category 'indexing primitive support') -----
install: rcvr inAtCache: cache at: atIx string: stringy
"Attempt to install the oop of this object in the given cache (at or atPut),
along with its size, format and fixedSize. Answer if this was successful."
| hdr fmt totalLength fixedFields |
<var: #cache type: 'sqInt *'>
hdr := objectMemory baseHeader: rcvr.
fmt := objectMemory formatOfHeader: hdr.
+ (fmt = objectMemory indexablePointersFormat and: [objectMemory isContextHeader: hdr]) ifTrue:
- (fmt = 3 and: [objectMemory isContextHeader: hdr]) ifTrue:
["Contexts must not be put in the atCache, since their size is not constant"
self primitiveFailFor: PrimErrBadReceiver.
^false].
totalLength := objectMemory lengthOf: rcvr baseHeader: hdr format: fmt.
fixedFields := objectMemory fixedFieldsOf: rcvr format: fmt length: totalLength.
cache at: atIx+AtCacheOop put: rcvr.
cache at: atIx+AtCacheFmt put: (stringy
+ ifTrue: [fmt + objectMemory firstStringyFakeFormat] "special flag for strings"
- ifTrue: [fmt + 16] "special flag for strings"
ifFalse: [fmt]).
cache at: atIx+AtCacheFixedFields put: fixedFields.
cache at: atIx+AtCacheSize put: totalLength - fixedFields.
^true!
Item was removed:
- ----- Method: StackInterpreter>>isIndexable: (in category 'object format') -----
- isIndexable: oop
- ^(objectMemory formatOf: oop) >= 2!
Item was changed:
----- Method: StackInterpreter>>snapshotCleanUp (in category 'image save/restore') -----
snapshotCleanUp
"Clean up right before saving an image, sweeping memory and:
* nilling out all fields of contexts above the stack pointer.
* flushing external primitives
* clearing the root bit of any object in the root table
* bereaving widowed contexts.
By ensuring that all contexts are single in a snapshot (i.e. that no married contexts
exist) we can maintain the invariant that a married or widowed context's frame
reference (in its sender field) must point into the stack pages since no married or
widowed contexts are present from older runs of the system."
| oop header fmt sz |
oop := objectMemory firstObject.
[self oop: oop isLessThan: objectMemory freeStart] whileTrue:
[(objectMemory isFreeObject: oop) ifFalse:
[header := self longAt: oop.
fmt := objectMemory formatOfHeader: header.
"Clean out context"
+ (fmt = objectMemory indexablePointersFormat
+ and: [objectMemory isContextHeader: header]) ifTrue:
- (fmt = 3 and: [objectMemory isContextHeader: header]) ifTrue:
["All contexts have been divorced. Bereave remaining widows."
(self isMarriedOrWidowedContext: oop) ifTrue:
[self markContextAsDead: oop].
sz := objectMemory sizeBitsOf: oop.
(objectMemory lastPointerOf: oop) + BytesPerWord
to: sz - BaseHeaderSize by: BytesPerWord
do: [:i | self longAt: oop + i put: objectMemory nilObject]].
+ "Clean out external functions from compiled methods"
+ fmt >= objectMemory firstCompiledMethodFormat ifTrue:
+ ["Its primitiveExternalCall"
- "Clean out external functions"
- fmt >= 12 ifTrue:
- ["This is a compiled method"
(self primitiveIndexOf: oop) = PrimitiveExternalCallIndex ifTrue:
+ [self flushExternalPrimitiveOf: oop]]].
- ["Its primitiveExternalCall"
- self flushExternalPrimitiveOf: oop]]].
oop := objectMemory objectAfter: oop].
objectMemory clearRootsTable!
Item was changed:
----- Method: StackInterpreter>>stObject:at: (in category 'indexing primitive support') -----
stObject: array at: index
"Return what ST would return for <obj> at: index."
| hdr fmt totalLength fixedFields stSize |
<inline: false>
hdr := objectMemory baseHeader: array.
fmt := objectMemory formatOfHeader: hdr.
totalLength := objectMemory lengthOf: array baseHeader: hdr format: fmt.
fixedFields := objectMemory fixedFieldsOf: array format: fmt length: totalLength.
+ (fmt = objectMemory indexablePointersFormat
+ and: [objectMemory isContextHeader: hdr])
- (fmt = 3 and: [objectMemory isContextHeader: hdr])
ifTrue:
[stSize := self stackPointerForMaybeMarriedContext: array.
((self oop: index isGreaterThanOrEqualTo: 1)
and: [(self oop: index isLessThanOrEqualTo: stSize)
and: [self isStillMarriedContext: array]]) ifTrue:
[^self noInlineTemporary: index - 1 in: (self frameOfMarriedContext: array)]]
ifFalse: [stSize := totalLength - fixedFields].
((self oop: index isGreaterThanOrEqualTo: (objectMemory firstValidIndexOfIndexableObject: array withFormat: fmt))
and: [self oop: index isLessThanOrEqualTo: stSize]) ifTrue:
[^self subscript: array with: (index + fixedFields) format: fmt].
self primitiveFailFor: (fmt <= 1 ifTrue: [PrimErrBadReceiver] ifFalse: [PrimErrBadIndex]).
^0!
Item was changed:
----- Method: StackInterpreter>>stObject:at:put: (in category 'indexing primitive support') -----
stObject: array at: index put: value
"Do what ST would return for <obj> at: index put: value."
| hdr fmt totalLength fixedFields stSize |
<inline: false>
hdr := objectMemory baseHeader: array.
fmt := objectMemory formatOfHeader: hdr.
totalLength := objectMemory lengthOf: array baseHeader: hdr format: fmt.
fixedFields := objectMemory fixedFieldsOf: array format: fmt length: totalLength.
+ (fmt = objectMemory indexablePointersFormat
- (fmt = 3
and: [objectMemory isContextHeader: hdr])
ifTrue:
[stSize := self stackPointerForMaybeMarriedContext: array.
((self oop: index isGreaterThanOrEqualTo: 1)
and: [(self oop: index isLessThanOrEqualTo: stSize)
and: [self isStillMarriedContext: array]]) ifTrue:
[^self noInlineTemporary: index - 1 in: (self frameOfMarriedContext: array) put: value]]
ifFalse: [stSize := totalLength - fixedFields].
((self oop: index isGreaterThanOrEqualTo: (objectMemory firstValidIndexOfIndexableObject: array withFormat: fmt))
and: [self oop: index isLessThanOrEqualTo: stSize])
ifTrue: [self subscript: array with: (index + fixedFields) storing: value format: fmt]
ifFalse: [self primitiveFailFor: (fmt <= 1 ifTrue: [PrimErrBadReceiver] ifFalse: [PrimErrBadIndex])].
^value!
Item was changed:
----- Method: StackInterpreter>>stSizeOf: (in category 'indexing primitive support') -----
stSizeOf: oop
"Return the number of indexable fields in the given object. (i.e., what Smalltalk would return for <obj> size)."
"Note: Assume oop is not a SmallInteger!!"
| hdr fmt totalLength fixedFields |
<inline: false>
hdr := objectMemory baseHeader: oop.
fmt := objectMemory formatOfHeader: hdr.
totalLength := objectMemory lengthOf: oop baseHeader: hdr format: fmt.
fixedFields := objectMemory fixedFieldsOf: oop format: fmt length: totalLength.
+ fmt = objectMemory indexablePointersFormat ifTrue:
+ [self assert: (objectMemory isContextHeader: hdr) not].
- fmt = 3 ifTrue: [self assert: (objectMemory isContextHeader: hdr) not].
^totalLength - fixedFields!
Item was changed:
----- Method: StackInterpreterPrimitives>>primitiveInstVarAt (in category 'object access primitives') -----
primitiveInstVarAt
| index rcvr hdr fmt totalLength fixedFields value |
index := self stackIntegerValue: 0.
rcvr := self stackValue: 1.
self successful ifFalse:
[^self primitiveFailFor: PrimErrBadArgument].
hdr := objectMemory baseHeader: rcvr.
fmt := objectMemory formatOfHeader: hdr.
totalLength := objectMemory lengthOf: rcvr baseHeader: hdr format: fmt.
fixedFields := objectMemory fixedFieldsOf: rcvr format: fmt length: totalLength.
(index >= 1 and: [index <= fixedFields]) ifFalse:
[^self primitiveFailFor: PrimErrBadIndex].
+ (fmt = objectMemory indexablePointersFormat
- (fmt = 3
and: [objectMemory isContextHeader: hdr])
ifTrue: [value := self externalInstVar: index - 1 ofContext: rcvr]
ifFalse: [value := self subscript: rcvr with: index format: fmt].
self pop: argumentCount + 1 thenPush: value!
Item was changed:
----- Method: StackInterpreterPrimitives>>primitiveInstVarAtPut (in category 'object access primitives') -----
primitiveInstVarAtPut
| newValue index rcvr hdr fmt totalLength fixedFields |
newValue := self stackTop.
index := self stackIntegerValue: 1.
rcvr := self stackValue: 2.
self successful ifFalse:
[^self primitiveFailFor: PrimErrBadArgument].
hdr := objectMemory baseHeader: rcvr.
fmt := objectMemory formatOfHeader: hdr.
totalLength := objectMemory lengthOf: rcvr baseHeader: hdr format: fmt.
fixedFields := objectMemory fixedFieldsOf: rcvr format: fmt length: totalLength.
(index >= 1 and: [index <= fixedFields]) ifFalse:
[^self primitiveFailFor: PrimErrBadIndex].
+ (fmt = objectMemory indexablePointersFormat
- (fmt = 3
and: [objectMemory isContextHeader: hdr])
ifTrue: [self externalInstVar: index - 1 ofContext: rcvr put: newValue]
ifFalse: [self subscript: rcvr with: index storing: newValue format: fmt].
self pop: argumentCount + 1 thenPush: newValue!
Item was changed:
----- Method: StackInterpreterPrimitives>>primitiveObjectPointsTo (in category 'object access primitives') -----
primitiveObjectPointsTo
"This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so.
N.B. Written to use literalHeaderOf: so that in Cog subclasses cogged methods (whose headers
point to the machine code method) are still correctly scanned, for the header as well as literals."
| rcvr thang header fmt lastField methodHeader |
thang := self stackTop.
rcvr := self stackValue: 1.
(objectMemory isIntegerObject: rcvr) ifTrue:
[^self pop: 2 thenPushBool: false].
"Inlined version of lastPointerOf: for speed in determining if rcvr is a context."
header := objectMemory baseHeader: rcvr.
fmt := objectMemory formatOfHeader: header.
+ (objectMemory isPointersFormat: fmt)
- fmt <= 4
ifTrue:
+ [(fmt = objectMemory indexablePointersFormat
- [(fmt = 3
and: [objectMemory isContextHeader: header])
ifTrue:
[(self isMarriedOrWidowedContext: rcvr) ifTrue:
[self externalWriteBackHeadFramePointers.
(self isStillMarriedContext: rcvr) ifTrue:
[^self pop: 2
thenPushBool: (self marriedContext: rcvr
pointsTo: thang
stackDeltaForCurrentFrame: 2)]].
"contexts end at the stack pointer"
lastField := CtxtTempFrameStart + (self fetchStackPointerOf: rcvr) * BytesPerWord]
ifFalse:
[lastField := (objectMemory sizeBitsOfSafe: rcvr) - BaseHeaderSize]]
ifFalse:
+ [fmt < objectMemory firstCompiledMethodFormat "no pointers" ifTrue:
- [fmt < 12 "no pointers" ifTrue:
[^self pop: 2 thenPushBool: false].
"CompiledMethod: contains both pointers and bytes:"
methodHeader := self headerOf: rcvr.
methodHeader = thang ifTrue: [^self pop: 2 thenPushBool: true].
lastField := ((self literalCountOfHeader: methodHeader) + 1) * BytesPerWord].
BaseHeaderSize to: lastField by: BytesPerWord do:
[:i |
(self longAt: rcvr + i) = thang ifTrue:
[^self pop: 2 thenPushBool: true]].
self pop: 2 thenPushBool: false!
Item was changed:
----- Method: StackInterpreterSimulator>>openAsMorph (in category 'UI') -----
openAsMorph
"Open a morphic view on this simulation."
| window localImageName |
+ localImageName := imageName
+ ifNotNil: [FileDirectory default localNameFor: imageName]
+ ifNil: [' synthetic image'].
- localImageName := FileDirectory default localNameFor: imageName.
window := (SystemWindow labelled: 'Simulation of ', localImageName) model: self.
window addMorph: (displayView := ImageMorph new image: displayForm)
frame: (0 at 0 corner: 1 at 0.8).
transcript := TranscriptStream on: (String new: 10000).
window addMorph: (PluggableTextMorph
on: transcript text: nil accept: nil
readSelection: nil menu: #codePaneMenu:shifted:)
frame: (0 at 0.8 corner: 0.7 at 1).
window addMorph: (PluggableTextMorph on: self
text: #byteCountText accept: nil
readSelection: nil menu: #utilitiesMenu:) hideScrollBarsIndefinitely
frame: (0.7 at 0.8 corner: 1 at 1).
window openInWorldExtent: (self desiredDisplayExtent
+ (2 * window borderWidth)
+ (0 at window labelHeight)
* (1@(1/0.8))) rounded!
More information about the Vm-dev
mailing list