[Vm-dev] VM Maker: VMMaker.oscog-eem.2741.mcz
commits at source.squeak.org
commits at source.squeak.org
Tue Apr 14 21:03:25 UTC 2020
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)!
More information about the Vm-dev
mailing list