[Vm-dev] VM Maker: VMMaker.oscog-eem.999.mcz
commits at source.squeak.org
commits at source.squeak.org
Fri Dec 26 01:58:39 UTC 2014
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.999.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.999
Author: eem
Time: 25 December 2014, 5:56:07.016 pm
UUID: b0fe8d34-046c-4ef4-8ca5-cdfe166c52fe
Ancestors: VMMaker.oscog-eem.998
Spur:
Fix argument count slips in three primitives.
Check for sufficient memory in two-way become.
All:
Fix checking of boolean arg in
primitiveArrayBecomeOneWayCopyHash.
Make primitiveSlotAt[Put] cope with non-pointer
objects.
Sista: Simplify genGetNumBytesOf:into:
=============== Diff against VMMaker.oscog-eem.998 ===============
Item was changed:
----- Method: CogObjectRepresentationFor32BitSpur>>genGetNumBytesOf:into: (in category 'compile abstract instructions') -----
genGetNumBytesOf: srcReg into: destReg
"Get the size in byte-sized slots of the object in srcReg into destReg.
srcReg may equal destReg.
+ destReg <- numSlots << self shiftForWord - (fmt bitAnd: 3).
+ Assumes the object in srcReg has a byte format, i.e. 16 to 23 or 24 to 31 "
- destReg <- numSlots << self shiftForWord - (fmt bitAnd: 7)."
<var: #jmp type: #'AbstractInstruction'>
| jmp |
self genGetRawSlotSizeOfNonImm: srcReg into: TempReg.
cogit CmpCq: objectMemory numSlotsMask R: TempReg.
jmp := cogit JumpLess: 0.
+ cogit MoveMw: objectMemory wordSize negated r: srcReg R: destReg.
+ jmp jmpTarget: (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: destReg).
- cogit MoveMw: objectMemory wordSize negated r: srcReg R: TempReg.
- jmp jmpTarget: (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: TempReg).
"Now: TempReg = numSlots << shiftForWord"
+ cogit MoveMw: 0 r: srcReg R: TempReg.
+ cogit LogicalShiftRightCq: objectMemory formatShift R: TempReg.
+ cogit AndCq: objectMemory wordSize - 1 R: TempReg.
+ "Now: fmt bitAnd: 3 in TempReg"
- cogit MoveMw: 0 r: srcReg R: destReg.
- cogit LogicalShiftRightCq: objectMemory formatShift R: destReg.
- cogit AndCq: objectMemory formatMask R: destReg.
- cogit AndCq: objectMemory wordSize - 1 R: destReg.
- "Now: fmt bitAnd: 7 in destReg"
cogit SubR: TempReg R: destReg.
^0!
Item was changed:
----- Method: InterpreterPrimitives>>primitiveArrayBecomeOneWayCopyHash (in category 'object access primitives') -----
primitiveArrayBecomeOneWayCopyHash
+ "Similar to primitiveArrayBecomeOneWay but accepts a third argument deciding whether to
+ copy the receiver's element's identity hash over the argument's elementy's identity hash."
- "Similar to primitiveArrayBecomeOneWay but accepts a third argument whether to copy
- the receiver's identity hash over the argument's identity hash."
+ | copyHashFlag ec |
+ self stackTop = objectMemory trueObject
+ ifTrue: [copyHashFlag := true]
+ ifFalse:
+ [self stackTop = objectMemory falseObject
+ ifTrue: [copyHashFlag := false]
+ ifFalse:
+ [self primitiveFailFor: PrimErrBadArgument.
+ ^nil]].
+ ec := objectMemory
+ become: (self stackValue: 2)
+ with: (self stackValue: 1)
+ twoWay: false
+ copyHash: copyHashFlag.
- | copyHashFlag arg rcvr ec |
- copyHashFlag := self booleanValueOf: (self stackTop).
- arg := self stackValue: 1.
- rcvr := self stackValue: 2.
- ec := objectMemory become: rcvr with: arg twoWay: false copyHash: copyHashFlag.
ec = PrimNoErr
+ ifTrue: [self pop: argumentCount]
- ifTrue: [self pop: 2]
ifFalse: [self primitiveFailFor: ec]!
Item was changed:
----- Method: InterpreterPrimitives>>primitiveImmediateAsInteger (in category 'arithmetic float primitives') -----
primitiveImmediateAsInteger
"For a Smalnteger, answer itself.
For a Character, answer its code as an unsigned integer.
For a SmallFloat, answer the signed, but unadjusted bit pattern (so as to keep the result a SmallInteger).
This is a good value for an immediate's hash."
<option: #Spur64BitMemoryManager>
| oop value |
oop := self stackTop.
(objectMemory isIntegerObject: oop) ifTrue:
[value := objectMemory integerValueOf: oop] ifFalse:
[(objectMemory isCharacterObject: oop) ifTrue:
[value := objectMemory characterValueOf: oop] ifFalse:
[(objectMemory isImmediateFloat: oop) ifTrue:
[value := objectMemory rotatedFloatBitsOf: oop] ifFalse:
[^self primitiveFailFor: PrimErrBadReceiver]]].
+ self pop: argumentCount + 1 thenPushInteger: value!
- self pop: argumentCount thenPushInteger: value!
Item was changed:
----- Method: InterpreterPrimitives>>primitiveIsPinned (in category 'memory space primitives') -----
primitiveIsPinned
"Answer if the receiver is pinned, i.e. immobile."
| obj |
obj := self stackTop.
((objectMemory isImmediate: obj)
or: [objectMemory isForwarded: obj]) ifTrue:
[^self primitiveFailFor: PrimErrBadReceiver].
+ self pop: argumentCount + 1
+ thenPushBool: (objectMemory hasSpurMemoryManagerAPI
+ and: [objectMemory booleanObjectOf: (objectMemory isPinned: obj)])!
- self pop: argumentCount - 1.
- self stackTopPut:
- (objectMemory hasSpurMemoryManagerAPI
- ifTrue: [objectMemory booleanObjectOf: (objectMemory isPinned: obj)]
- ifFalse: [objectMemory falseObject])!
Item was changed:
----- Method: InterpreterPrimitives>>primitivePin (in category 'memory space primitives') -----
primitivePin
"Pin or unpin the receiver, i.e. make it immobile or mobile, based on the argument.
Answer whether the object was already pinned. N.B. pinning does *not* prevent
an object from being garbage collected."
| obj boolean wasPinned |
objectMemory hasSpurMemoryManagerAPI ifFalse:
[^self primitiveFailFor: PrimErrUnsupported].
obj := self stackValue: 1.
((objectMemory isImmediate: obj)
or: [(objectMemory isForwarded: obj)
or: [(objectMemory isContext: obj)
and: [self isStillMarriedContext: obj]]]) ifTrue:
[^self primitiveFailFor: PrimErrBadReceiver].
boolean := self stackTop.
(boolean = objectMemory falseObject
or: [boolean = objectMemory trueObject]) ifFalse:
[^self primitiveFailFor: PrimErrBadArgument].
(objectMemory isPinned: obj)
ifTrue:
[wasPinned := objectMemory trueObject.
objectMemory setIsPinnedOf: obj to: boolean = objectMemory trueObject]
ifFalse:
[wasPinned := objectMemory falseObject.
(boolean = objectMemory trueObject
and: [objectMemory pinObject: obj]) = 0 ifTrue:
[^self primitiveFailFor: PrimErrNoMemory]].
+ self pop: argumentCount + 1 thenPush: wasPinned!
- self pop: argumentCount - 1 thenPush: wasPinned!
Item was changed:
----- Method: InterpreterPrimitives>>primitiveSlotAt (in category 'object access primitives') -----
primitiveSlotAt
+ "Answer a slot in an object. This numbers all slots from 1, ignoring the distinction between
+ named and indexed inst vars. In objects with both named and indexed inst vars, the named
+ inst vars preceed the indexed ones. In non-object indexed objects (objects that contain
+ bits, not object references) this primitive answers the raw integral value at each slot.
+ e.g. for Strings it answers the character code, not the Character object at each slot."
+ | index rcvr fmt numSlots |
- | index rcvr numSlots |
index := self stackTop.
rcvr := self stackValue: 1.
(objectMemory isIntegerObject: index) ifFalse:
[^self primitiveFailFor: PrimErrBadArgument].
(objectMemory isImmediate: rcvr) ifTrue:
[^self primitiveFailFor: PrimErrBadReceiver].
+ fmt := objectMemory formatOf: rcvr.
index := objectMemory integerValueOf: index.
+
+ fmt <= objectMemory lastPointerFormat ifTrue:
- (objectMemory isPointersNonImm: rcvr) ifTrue:
[numSlots := objectMemory numSlotsOf: rcvr.
(self asUnsigned: index) < numSlots ifTrue:
[self pop: argumentCount + 1 thenPush: (objectMemory fetchPointer: index ofObject: rcvr).
^0].
^self primitiveFailFor: PrimErrBadIndex].
+
+ fmt >= objectMemory firstByteFormat ifTrue:
+ [fmt >= objectMemory firstCompiledMethodFormat ifTrue:
+ [^self primitiveFailFor: PrimErrUnsupported].
+ numSlots := objectMemory numBytesOf: rcvr.
+ (self asUnsigned: index) < numSlots ifTrue:
+ [self pop: argumentCount + 1 thenPushInteger: (objectMemory fetchByte: index ofObject: rcvr).
+ ^0].
+ ^self primitiveFailFor: PrimErrBadIndex].
+
+ (objectMemory hasSpurMemoryManagerAPI
+ and: [fmt >= objectMemory firstShortFormat]) ifTrue:
+ [numSlots := objectMemory num16BitUnitsOf: rcvr.
+ (self asUnsigned: index) < numSlots ifTrue:
+ [self pop: argumentCount + 1 thenPushInteger: (objectMemory fetchShort16: index ofObject: rcvr).
+ ^0].
+ ^self primitiveFailFor: PrimErrBadIndex].
+
+ fmt = objectMemory sixtyFourBitIndexableFormat ifTrue:
+ [numSlots := objectMemory num64BitUnitsOf: rcvr.
+ (self asUnsigned: index) < numSlots ifTrue:
+ [self pop: argumentCount + 1
+ thenPush: (self positive64BitIntegerFor: (objectMemory fetchLong64: index ofObject: rcvr)).
+ ^0].
+ ^self primitiveFailFor: PrimErrBadIndex].
+
+ fmt >= objectMemory firstLongFormat ifTrue:
+ [numSlots := objectMemory num32BitUnitsOf: rcvr.
+ (self asUnsigned: index) < numSlots ifTrue:
+ [self pop: argumentCount + 1
+ thenPush: (objectMemory bytesPerOop = 8
+ ifTrue: [objectMemory integerObjectOf: (objectMemory fetchLong32: index ofObject: rcvr)]
+ ifFalse: [self positive32BitIntegerFor: (objectMemory fetchLong32: index ofObject: rcvr)]).
+ ^0].
+ ^self primitiveFailFor: PrimErrBadIndex].
+
- "for now just fail for non-pointer objects; the issue here is should
- strings answer characters and if so how do we efficiently identify strings?"
^self primitiveFailFor: PrimErrBadReceiver!
Item was changed:
----- Method: InterpreterPrimitives>>primitiveSlotAtPut (in category 'object access primitives') -----
primitiveSlotAtPut
+ "Assign a slot in an object. This numbers all slots from 1, ignoring the distinction between
+ named and indexed inst vars. In objects with both named and indexed inst vars, the named
+ inst vars preceed the indexed ones. In non-object indexed objects (objects that contain
+ bits, not object references) this primitive assigns a raw integral value at each slot."
+ | newValue index rcvr fmt numSlots value |
- | newValue index rcvr numSlots |
newValue := self stackTop.
index := self stackValue: 1.
rcvr := self stackValue: 2.
(objectMemory isIntegerObject: index) ifFalse:
[^self primitiveFailFor: PrimErrBadArgument].
(objectMemory isImmediate: rcvr) ifTrue:
[^self primitiveFailFor: PrimErrBadReceiver].
+ fmt := objectMemory formatOf: rcvr.
index := objectMemory integerValueOf: index.
+
+ fmt <= objectMemory lastPointerFormat ifTrue:
- (objectMemory isPointersNonImm: rcvr) ifTrue:
[numSlots := objectMemory numSlotsOf: rcvr.
(self asUnsigned: index) < numSlots ifTrue:
[objectMemory storePointer: index ofObject: rcvr withValue: newValue.
self pop: argumentCount + 1 thenPush: newValue.
^0].
^self primitiveFailFor: PrimErrBadIndex].
+
+ value := self positiveMachineIntegerValueOf: newValue.
+ self failed ifTrue:
+ [primFailCode := PrimErrBadArgument.
+ ^0].
+
+ fmt >= objectMemory firstByteFormat ifTrue:
+ [fmt >= objectMemory firstCompiledMethodFormat ifTrue:
+ [^self primitiveFailFor: PrimErrUnsupported].
+ (self asUnsigned: value) > 16rFF ifTrue:
+ [^self primitiveFailFor: PrimErrBadArgument].
+ numSlots := objectMemory numBytesOf: rcvr.
+ (self asUnsigned: index) < numSlots ifTrue:
+ [objectMemory storeByte: index ofObject: rcvr withValue: value.
+ self pop: argumentCount + 1 thenPush: newValue.
+ ^0].
+ ^self primitiveFailFor: PrimErrBadIndex].
+
+ (objectMemory hasSpurMemoryManagerAPI
+ and: [fmt >= objectMemory firstShortFormat]) ifTrue:
+ [(self asUnsigned: value) > 16rFFFF ifTrue:
+ [^self primitiveFailFor: PrimErrBadArgument].
+ numSlots := objectMemory num16BitUnitsOf: rcvr.
+ (self asUnsigned: index) < numSlots ifTrue:
+ [objectMemory storeShort16: index ofObject: rcvr withValue: value.
+ self pop: argumentCount + 1 thenPush: newValue.
+ ^0].
+ ^self primitiveFailFor: PrimErrBadIndex].
+
+ (objectMemory bytesPerOop = 8
+ and: [fmt = objectMemory sixtyFourBitIndexableFormat]) ifTrue:
+ [numSlots := objectMemory num64BitUnitsOf: rcvr.
+ (self asUnsigned: index) < numSlots ifTrue:
+ [objectMemory storeLong64: index ofObject: rcvr withValue: value.
+ self pop: argumentCount + 1 thenPush: newValue.
+ ^0].
+ ^self primitiveFailFor: PrimErrBadIndex].
+
+ fmt >= objectMemory firstLongFormat ifTrue:
+ [(objectMemory wordSize > 4
+ and: [(self asUnsigned: value) > 16rFFFFFFFF]) ifTrue:
+ [^self primitiveFailFor: PrimErrBadArgument].
+ numSlots := objectMemory num32BitUnitsOf: rcvr.
+ (self asUnsigned: index) < numSlots ifTrue:
+ [objectMemory storeLong32: index ofObject: rcvr withValue: value.
+ self pop: argumentCount + 1 thenPush: newValue.
+ ^0].
+ ^self primitiveFailFor: PrimErrBadIndex].
+
- "for now just fail for non-pointer objects; the issue here is should
- strings answer characters and if so how do we efficiently identify strings?"
^self primitiveFailFor: PrimErrBadReceiver!
Item was added:
+ ----- Method: ObjectMemory>>sixtyFourBitIndexableFormat (in category 'header formats') -----
+ sixtyFourBitIndexableFormat
+ ^7!
Item was changed:
----- Method: SpurMemoryManager>>containsOnlyValidBecomeObjects:and: (in category 'become implementation') -----
containsOnlyValidBecomeObjects: array1 and: array2
"Answer 0 if neither array contains only unpinned non-immediates.
Otherwise answer an informative error code.
Can't become: immediates!! Shouldn't become pinned objects."
+ | fieldOffset effectsFlags oop size |
- | fieldOffset effectsFlags oop |
fieldOffset := self lastPointerOf: array1.
+ effectsFlags := size := 0.
- effectsFlags := 0.
"same size as array2"
[fieldOffset >= self baseHeaderSize] whileTrue:
[oop := self longAt: array1 + fieldOffset.
(self isOopForwarded: oop) ifTrue:
[oop := self followForwarded: oop.
self longAt: array1 + fieldOffset put: oop].
(self isImmediate: oop) ifTrue: [^PrimErrInappropriate].
(self isPinned: oop) ifTrue: [^PrimErrObjectIsPinned].
effectsFlags := effectsFlags bitOr: (self becomeEffectFlagsFor: oop).
+ size := size + (self bytesInObject: oop).
oop := self longAt: array2 + fieldOffset.
(self isOopForwarded: oop) ifTrue:
[oop := self followForwarded: oop.
self longAt: array2 + fieldOffset put: oop].
(self isImmediate: oop) ifTrue: [^PrimErrInappropriate].
(self isPinned: oop) ifTrue: [^PrimErrObjectIsPinned].
effectsFlags := effectsFlags bitOr: (self becomeEffectFlagsFor: oop).
+ size := size + (self bytesInObject: oop).
fieldOffset := fieldOffset - self bytesPerOop].
"only set flags after checking all args."
becomeEffectsFlags := effectsFlags.
+ size >= (totalFreeOldSpace + (scavengeThreshold - freeStart)) ifTrue:
+ [^PrimErrNoMemory].
^0!
More information about the Vm-dev
mailing list