Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2741.mcz ==================== Summary ==================== Name: VMMaker.oscog-eem.2741 Author: eem Time: 14 April 2020, 2:03:09.122947 pm UUID: 809e8b1f-fe07-4d33-bfc1-db9e5ab13a99 Ancestors: VMMaker.oscog-eem.2740 Spur: Make sure that becomeForward: answers a useful error code for read-only targets (when copyHash is true). =============== Diff against VMMaker.oscog-eem.2740 =============== Item was changed: ----- Method: SpurMemoryManager>>containsOnlyValidBecomeObjects:and:twoWay:copyHash: (in category 'become implementation') ----- containsOnlyValidBecomeObjects: array1 and: array2 twoWay: isTwoWay copyHash: copyHash "Answer 0 if neither array contains an object inappropriate for the become operation. Otherwise answer an informative error code for the first offending object found: Can't become: immediates => PrimErrInappropriate Shouldn't become pinned objects => PrimErrObjectIsPinned. Shouldn't become immutable objects => PrimErrNoModification. Can't copy hash into immediates => PrimErrInappropriate. Two-way become may require memory to create copies => PrimErrNoMemory. As a side-effect unforward any forwarders in the two arrays if answering 0." <inline: true> | fieldOffset effectsFlags oop1 oop2 size | fieldOffset := self lastPointerOf: array1. effectsFlags := size := 0. "array1 is known to be the same size as array2" [fieldOffset >= self baseHeaderSize] whileTrue: [oop1 := self longAt: array1 + fieldOffset. (self isOopForwarded: oop1) ifTrue: [oop1 := self followForwarded: oop1. self longAt: array1 + fieldOffset put: oop1]. self ifOopInvalidForBecome: oop1 errorCodeInto: [:errCode| ^errCode]. oop2 := self longAt: array2 + fieldOffset. (self isOopForwarded: oop2) ifTrue: [oop2 := self followForwarded: oop2. self longAt: array2 + fieldOffset put: oop2]. + oop1 ~= oop2 ifTrue: + [isTwoWay + ifTrue: + [self ifOopInvalidForBecome: oop2 errorCodeInto: [:errCode| ^errCode]. + size := size + (self bytesInObject: oop1) + (self bytesInObject: oop2). - isTwoWay - ifTrue: - [self ifOopInvalidForBecome: oop2 errorCodeInto: [:errCode| ^errCode]. - oop1 ~= oop2 ifTrue: - [size := size + (self bytesInObject: oop1) + (self bytesInObject: oop2). effectsFlags := (effectsFlags bitOr: (self becomeEffectFlagsFor: oop1)) + bitOr: (self becomeEffectFlagsFor: oop2)] + ifFalse: + [copyHash ifTrue: + [(self isImmediate: oop2) ifTrue: + [^PrimErrInappropriate]. + (self isObjImmutable: oop2) ifTrue: + [^PrimErrNoModification]]. + effectsFlags := effectsFlags bitOr: (self becomeEffectFlagsFor: oop1)]]. - bitOr: (self becomeEffectFlagsFor: oop2)]] - ifFalse: - [(copyHash and: [(self isImmediate: oop2) or: [self isImmutable: oop2]]) ifTrue: - [^PrimErrInappropriate]. - oop1 ~= oop2 ifTrue: - [effectsFlags := effectsFlags bitOr: (self becomeEffectFlagsFor: oop1)]]. fieldOffset := fieldOffset - self bytesPerOop]. size >= (totalFreeOldSpace + (scavengeThreshold - freeStart)) ifTrue: [^PrimErrNoMemory]. "only set flags after checking all args." becomeEffectsFlags := effectsFlags. ^0! Item was changed: ----- Method: SpurMemoryManager>>postBecomeScanClassTable: (in category 'become implementation') ----- postBecomeScanClassTable: effectsFlags "Scan the class table post-become (iff an active class object was becommed) to ensure no forwarding pointers, and no unhashed classes exist in the class table. Note that one-way become can cause duplications in the class table. + So if pointer objects have been becommed, scan all pages in the class table + and eliminate ay entries that have a zero hash. doBecome:and:copyHash: has + already ensured that any becomed class has been stored at the right index." - When can these be eliminated? We use the classTableBitmap to mark classTable entries - (not the classes themselves, since marking a class doesn't help in knowing if its index is used). - On image load, and during incrememtal scan-mark and full GC, classIndices are marked. - We can somehow avoid following classes from the classTable until after this mark phase." self assert: self validClassTableRootPages. (effectsFlags anyMask: BecamePointerObjectFlag) ifFalse: [^self]. 0 to: numClassTablePages - 1 do: [:i| | page | page := self fetchPointer: i ofObject: hiddenRootsObj. self assert: (self isForwarded: page) not. 0 to: (self numSlotsOf: page) - 1 do: [:j| | classOrNil | classOrNil := self fetchPointer: j ofObject: page. classOrNil ~= nilObj ifTrue: [(self isForwarded: classOrNil) ifTrue: [classOrNil := self followForwarded: classOrNil. self storePointer: j ofObject: page withValue: classOrNil]. (self rawHashBitsOf: classOrNil) = 0 ifTrue: [self storePointerUnchecked: j ofObject: page withValue: nilObj. "If the removed class is before the classTableIndex, set the classTableIndex to point to the empty slot so as to reuse it asap." (i << self classTableMajorIndexShift + j) < classTableIndex ifTrue: [classTableIndex := i << self classTableMajorIndexShift + j]]]]]. "classTableIndex must never index the first page, which is reserved for classes known to the VM." self assert: classTableIndex >= (1 << self classTableMajorIndexShift)! |
Free forum by Nabble | Edit this page |