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! |
Free forum by Nabble | Edit this page |