[Vm-dev] VM Maker: VMMaker.oscog-eem.370.mcz
commits at source.squeak.org
commits at source.squeak.org
Wed Sep 11 14:48:04 UTC 2013
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.370.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.370
Author: eem
Time: 11 September 2013, 7:43:11.841 am
UUID: b42d44b7-3f55-465e-80d5-d609a89ec601
Ancestors: VMMaker.oscog-eem.369
Implement hashing for Spur. Split hashBitsOf: into rawHashBitsOf:.
Implement Lehmer's algorithm (for now).
Use ensureBehaviorHash: in instantiation routines.
Add classTableIndex.
Put the survivor spaces below eden for tenuring. Eliminate
newSpaceStart.
Add SpurMemMgr>>isContextHeader:
=============== Diff against VMMaker.oscog-eem.369 ===============
Item was changed:
----- Method: InterpreterPrimitives>>primitiveBehaviorHash (in category 'object access primitives') -----
primitiveBehaviorHash
| hashOrError |
+ self assert: ((objectMemory isNonImmediate: self stackTop)
+ and: [self addressCouldBeClassObj: self stackTop]).
- self assert: (objectMemory isIntegerObject: self stackTop) not.
hashOrError := objectMemory ensureBehaviorHash: self stackTop.
hashOrError >= 0
ifTrue: [self pop: 1 thenPushInteger: hashOrError]
ifFalse: [self primitiveFailFor: hashOrError negated]!
Item was changed:
----- Method: InterpreterPrimitives>>primitiveIdentityHash (in category 'object access primitives') -----
primitiveIdentityHash
| thisReceiver |
thisReceiver := self stackTop.
+ (objectMemory isImmediate: thisReceiver)
- (objectMemory isIntegerObject: thisReceiver)
ifTrue: [self primitiveFail]
ifFalse: [self pop: argumentCount + 1
thenPushInteger: (objectMemory hashBitsOf: thisReceiver)]!
Item was changed:
----- 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 arrayFormat] ->
[numSlots := nElements.
fillValue := nilObj].
[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 ensureBehaviorHash: classObj.
+ classIndex < 0 ifTrue:
+ [coInterpreter primitiveFailFor: classIndex negated.
+ ^nil].
- 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 changed:
----- 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 arrayFormat] ->
[numSlots := nElements.
fillValue := nilObj].
[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 ensureBehaviorHash: classObj.
+ classIndex < 0 ifTrue:
+ [coInterpreter primitiveFailFor: classIndex negated.
+ ^nil].
- 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 changed:
----- Method: SpurGenerationScavenger>>manager:memory:newSpaceStart:newSpaceBytes:edenBytes: (in category 'initialization') -----
manager: aSpurMemoryManager memory: memoryArray newSpaceStart: startAddress newSpaceBytes: totalBytes edenBytes: requestedEdenBytes
+ | edenBytes survivorBytes |
- | edenBytes edenLimit edenStart survivorBytes |
manager := aSpurMemoryManager.
memory := memoryArray.
edenBytes := requestedEdenBytes.
- edenStart := startAddress.
survivorBytes := totalBytes - edenBytes // 2 truncateTo: manager allocationUnit.
edenBytes := totalBytes - survivorBytes - survivorBytes truncateTo: manager allocationUnit.
+ self assert: totalBytes - edenBytes - survivorBytes - survivorBytes < manager allocationUnit.
+ "for tenuring we require older objects below younger objects. since allocation
+ grows up this means that the survivor spaces must preceed eden."
- edenLimit := edenStart + edenBytes roundUpTo: manager allocationUnit.
- self assert: totalBytes - (edenLimit - edenStart) - survivorBytes - survivorBytes < manager allocationUnit.
- eden := SpurNewSpaceSpace new.
pastSpace := SpurNewSpaceSpace new.
futureSpace := SpurNewSpaceSpace new.
+ eden := SpurNewSpaceSpace new.
+ pastSpace start: startAddress limit: startAddress + survivorBytes.
- eden start: edenStart limit: edenLimit.
- pastSpace start: edenLimit limit: edenLimit + survivorBytes.
futureSpace start: pastSpace limit limit: pastSpace limit + survivorBytes.
+ eden start: futureSpace limit limit: futureSpace limit + edenBytes.
self assert: futureSpace limit <= (startAddress + totalBytes).
self assert: eden start \\ manager allocationUnit
+ (eden limit \\ manager allocationUnit) = 0.
self assert: pastSpace start \\ manager allocationUnit
+ (pastSpace limit \\ manager allocationUnit) = 0.
self assert: futureSpace start \\ manager allocationUnit
+ (futureSpace limit \\ manager allocationUnit) = 0.
self initPastSpaceForObjectEnumeration.
manager initSpaceForAllocationCheck: eden!
Item was changed:
CogClass subclass: #SpurMemoryManager
(excessive size, no diff calculated)
Item was changed:
----- Method: SpurMemoryManager>>allocateMemoryOfSize:newSpaceSize:codeSize: (in category 'simulation') -----
allocateMemoryOfSize: memoryBytes newSpaceSize: newSpaceBytes codeSize: codeBytes
"Intialize the receiver for bootsraping an image.
Set up a large oldSpace and an empty newSpace and set-up freeStart and scavengeThreshold
to allocate in oldSpace. Later on (in initializePostBootstrap) freeStart and scavengeThreshold
will be set to sane values."
<doNotGenerate>
self assert: (memoryBytes \\ self allocationUnit = 0
and: [newSpaceBytes \\ self allocationUnit = 0
and: [codeBytes \\ self allocationUnit = 0]]).
memory := (self endianness == #little
ifTrue: [LittleEndianBitmap]
ifFalse: [Bitmap]) new: (memoryBytes + newSpaceBytes + codeBytes) // 4.
startOfMemory := codeBytes.
endOfMemory := memoryBytes + newSpaceBytes + codeBytes.
"leave newSpace empty for the bootstrap"
freeStart := newSpaceBytes + startOfMemory.
- newSpaceStart := startOfMemory.
newSpaceLimit := newSpaceBytes + startOfMemory.
scavengeThreshold := memory size * 4. "Bitmap is a 4-byte per word array"
scavenger := SpurGenerationScavenger new
manager: self
memory: memory
+ newSpaceStart: startOfMemory
- newSpaceStart: newSpaceStart
newSpaceBytes: newSpaceBytes
edenBytes: newSpaceBytes * 5 // 7 "David's paper uses 140Kb eden + 2 x 28kb survivor spaces :-)"!
Item was added:
+ ----- Method: SpurMemoryManager>>classIndexOfHeader: (in category 'header access') -----
+ classIndexOfHeader: aHeader
+ <inline: true>
+ ^aHeader bitAnd: self classIndexMask!
Item was added:
+ ----- Method: SpurMemoryManager>>classTableIndex (in category 'accessing') -----
+ classTableIndex
+ ^classTableIndex!
Item was added:
+ ----- Method: SpurMemoryManager>>classTableIndex: (in category 'accessing') -----
+ classTableIndex: n
+ classTableIndex := n!
Item was added:
+ ----- Method: SpurMemoryManager>>classTableObjectsDo: (in category 'object enumeration') -----
+ classTableObjectsDo: aBlock
+ 0 to: (self numSlotsOf: classTableRootObj) - 1 do:
+ [:i| | page |
+ page := self fetchPointer: i ofObject: classTableRootObj.
+ 0 to: (self numSlotsOf: page) - 1 do:
+ [:j| | classOrNil |
+ classOrNil := self fetchPointer: j ofObject: page.
+ classOrNil ~= nilObj ifTrue:
+ [aBlock value: classOrNil]]]!
Item was changed:
----- Method: SpurMemoryManager>>compactIndexOfClass: (in category 'class membership') -----
compactIndexOfClass: objOop
+ self assert: (self rawHashBitsOf: objOop) ~= 0.
+ ^self rawHashBitsOf: objOop!
- ^self hashBitsOf: objOop!
Item was changed:
----- Method: SpurMemoryManager>>ensureBehaviorHash: (in category 'class table') -----
ensureBehaviorHash: aBehavior
| newHash err |
+ <inline: true>
+ self assert: (self isImmediate: aBehavior) not.
+ (newHash := self rawHashBitsOf: aBehavior) = 0 ifTrue:
- self assert: (self isIntegerObject: aBehavior) not.
- (newHash := self hashBitsOf: aBehavior) = 0 ifTrue:
[(err := self enterIntoClassTable: aBehavior) ~= 0 ifTrue:
[^err negated].
+ newHash := self rawHashBitsOf: aBehavior.
+ self assert: (self classAtIndex: newHash) = aBehavior].
- newHash := self hashBitsOf: aBehavior].
^newHash!
Item was added:
+ ----- Method: SpurMemoryManager>>firstValidIndexOfIndexableObject:withFormat: (in category 'indexing primitive support') -----
+ firstValidIndexOfIndexableObject: obj withFormat: fmt
+ "Answer the one-relative index of the first valid index in an indexbale object
+ with the given format. This is 1 for all objects except compiled methods
+ where the first index is beyond the last literal.
+ Used for safer bounds-checking on methods."
+ ^fmt >= self firstCompiledMethodFormat
+ ifTrue: [coInterpreter firstByteIndexOfMethod: obj]
+ ifFalse: [1]!
Item was changed:
----- Method: SpurMemoryManager>>hashBitsOf: (in category 'header access') -----
hashBitsOf: objOop
+ | hash |
+ hash := self rawHashBitsOf: objOop.
+ hash = 0 ifTrue:
+ ["would like to assert
+ self assert: (coInterpreter addressCouldBeClassObj: objOop) not
+ but instance-specific behaviors that are instances of themselves may
+ fail this test."
+ hash := self newObjectHash.
+ self setHashBitsOf: objOop to: (hash bitAnd: self identityHashHalfWordMask)].
+ ^hash!
- self flag: #endianness.
- ^(self longAt: objOop + 4) bitAnd: self identityHashHalfWordMask!
Item was changed:
----- Method: SpurMemoryManager>>instantiateClass: (in category 'allocation') -----
instantiateClass: classObj
| instSpec classFormat numSlots classIndex newObj |
classFormat := self formatOfClass: classObj.
instSpec := self instSpecOfClassFormat: classFormat.
(self isFixedSizePointerFormat: instSpec) ifFalse:
[^nil].
+ classIndex := self ensureBehaviorHash: classObj.
+ classIndex < 0 ifTrue:
+ [coInterpreter primitiveFailFor: classIndex negated.
+ ^nil].
- classIndex := self hashBitsOf: classObj.
- classIndex = 0 ifTrue:
- [(self enterIntoClassTable: classObj) ifFalse:
- [^nil].
- classIndex := self hashBitsOf: classObj].
numSlots := self fixedFieldsOfClassFormat: classFormat.
newObj := self allocateSlots: numSlots format: instSpec classIndex: classIndex.
newObj ifNotNil:
[self fillObj: newObj numSlots: numSlots with: nilObj].
^newObj!
Item was added:
+ ----- Method: SpurMemoryManager>>isContextHeader: (in category 'header access') -----
+ isContextHeader: aHeader
+ <inline: true>
+ ^(self classIndexOfHeader: aHeader) = ClassMethodContextCompactIndex!
Item was changed:
----- Method: SpurMemoryManager>>isIntegerObject: (in category 'object testing') -----
isIntegerObject: oop
"This list records the valid senders of isIntegerObject: as we replace uses of
isIntegerObject: by isImmediate: where appropriate."
(#( makeBaseFrameFor:
quickFetchInteger:ofObject:
frameOfMarriedContext:
addressCouldBeClassObj:
isMarriedOrWidowedContext:
shortPrint:
bytecodePrimAt
commonAt:
loadFloatOrIntFrom:
positive32BitValueOf:
primitiveExternalCall
checkedIntegerValueOf:
bytecodePrimAtPut
commonAtPut:
primitiveVMParameter
+ checkIsStillMarriedContext:currentFP:
+ displayBitsOf:Left:Top:Right:Bottom:) includes: thisContext sender method selector) ifFalse:
- checkIsStillMarriedContext:currentFP:) includes: thisContext sender method selector) ifFalse:
[self halt].
^(oop bitAnd: 1) ~= 0!
Item was added:
+ ----- Method: SpurMemoryManager>>lastHash (in category 'accessing') -----
+ lastHash
+ ^lastHash!
Item was added:
+ ----- Method: SpurMemoryManager>>lastHash: (in category 'accessing') -----
+ lastHash: seed
+ lastHash := seed!
Item was added:
+ ----- Method: SpurMemoryManager>>memory (in category 'accessing') -----
+ memory
+ ^memory!
Item was added:
+ ----- Method: SpurMemoryManager>>newObjectHash (in category 'accessing') -----
+ newObjectHash
+ "Use simple algorithm by D.H. Lehmer from 1951, for now."
+ lastHash := lastHash * 16807 "7 raisedTo: 5" \\ 16r7ffffffd "(2 raisedTo: 31) - 1".
+ self assert: lastHash ~= 0.
+ ^lastHash!
Item was added:
+ ----- Method: SpurMemoryManager>>rawHashBitsOf: (in category 'header access') -----
+ rawHashBitsOf: objOop
+ self flag: #endianness.
+ ^(self longAt: objOop + 4) bitAnd: self identityHashHalfWordMask!
Item was changed:
----- Method: StackInterpreter>>displayBitsOf:Left:Top:Right:Bottom: (in category 'I/O primitives') -----
displayBitsOf: aForm Left: l Top: t Right: r Bottom: b
"Repaint the portion of the Smalltalk screen bounded by the affected rectangle. Used to synchronize the screen after a Bitblt to the Smalltalk Display object."
| displayObj dispBits w h dispBitsIndex d left right top bottom surfaceHandle |
displayObj := objectMemory splObj: TheDisplay.
aForm = displayObj ifFalse: [^ nil].
self success: ((objectMemory isPointers: displayObj) and: [(objectMemory lengthOf: displayObj) >= 4]).
self successful ifTrue: [
dispBits := objectMemory fetchPointer: 0 ofObject: displayObj.
w := self fetchInteger: 1 ofObject: displayObj.
h := self fetchInteger: 2 ofObject: displayObj.
d := self fetchInteger: 3 ofObject: displayObj.
].
l < 0 ifTrue:[left := 0] ifFalse: [left := l].
r > w ifTrue: [right := w] ifFalse: [right := r].
t < 0 ifTrue: [top := 0] ifFalse: [top := t].
b > h ifTrue: [bottom := h] ifFalse: [bottom := b].
((left <= right) and: [top <= bottom]) ifFalse: [^nil].
self successful ifTrue: [
(objectMemory isIntegerObject: dispBits) ifTrue: [
surfaceHandle := objectMemory integerValueOf: dispBits.
showSurfaceFn = 0 ifTrue: [
showSurfaceFn := self ioLoadFunction: 'ioShowSurface' From: 'SurfacePlugin'.
showSurfaceFn = 0 ifTrue: [^self success: false]].
self cCode:'((sqInt (*)(sqInt, sqInt, sqInt, sqInt, sqInt))showSurfaceFn)(surfaceHandle, left, top, right-left, bottom-top)'.
] ifFalse: [
+ self assert: (objectMemory isNonImmediate: dispBits).
+ dispBitsIndex := dispBits + objectMemory baseHeaderSize. "index in memory byte array"
- dispBitsIndex := dispBits + BaseHeaderSize. "index in memory byte array"
self cCode: 'ioShowDisplay(dispBitsIndex, w, h, d, left, right, top, bottom)'
inSmalltalk: [self showDisplayBits: dispBitsIndex
w: w h: h d: d
left: left right: right top: top bottom: bottom]
].
]!
More information about the Vm-dev
mailing list