VM Maker: VMMaker.oscog-eem.2741.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

VM Maker: VMMaker.oscog-eem.2741.mcz

commits-2
 
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)!