[Vm-dev] VM Maker: VMMaker.oscog-eem.417.mcz
commits at source.squeak.org
commits at source.squeak.org
Sun Sep 29 19:06:39 UTC 2013
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.417.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.417
Author: eem
Time: 29 September 2013, 12:03:30.837 pm
UUID: e868c34a-af52-4474-bf0f-f4a52dafd767
Ancestors: VMMaker.oscog-eem.416
Fix ephemeron processing. Any ephemerons reached during
scavenging should be copied to future space. Therefore their
contents must not be scavenged if their keys are as yet unreached.
So replace numStrongSlotsOf: with
numStrongSlotsOf:ephemeronInactiveIf:.
Further, move forwarding through ephemeron keys into
isScavengeSurvivor:, and make ephemeron assert in
scavengeReferentsOf: more accurate. Ephemeron must be either
inactive or on the ephemeronList.
Use numFixedSlotsOf: instead of numStrongSlotsOf: in
processWeakSurvivor:.
Fix tenuringThreshold computation,
(pastSpace size * (1 - tenuringProportion)
not pastSpace size * tenuringProportion.
Provide some debugging conveniences.
=============== Diff against VMMaker.oscog-eem.416 ===============
Item was changed:
----- Method: SpurGenerationScavenger>>computeTenuringThreshold (in category 'scavenger') -----
computeTenuringThreshold
| fractionSurvived |
<var: 'fractionSurvived' type: #float>
fractionSurvived := (futureSurvivorStart - futureSpace start) asFloat
/ (futureSpace limit - futureSpace start).
tenuringThreshold := fractionSurvived > 0.9
+ ifTrue: [((pastSpace limit - pastSpace start) * (1.0 - tenuringProportion)) rounded + pastSpace start]
- ifTrue: [((pastSpace limit - pastSpace start) * tenuringProportion) rounded + pastSpace start]
ifFalse: [0]!
Item was added:
+ ----- Method: SpurGenerationScavenger>>futureSpaceObjectsDo: (in category 'debug support') -----
+ futureSpaceObjectsDo: aBlock
+ | obj |
+ futureSurvivorStart > futureSpace start ifTrue:
+ [obj := manager objectStartingAt: futureSpace start.
+ [obj < futureSurvivorStart] whileTrue:
+ [aBlock value: obj.
+ obj := manager objectAfter: obj limit: futureSurvivorStart]]!
Item was added:
+ ----- Method: SpurGenerationScavenger>>is:onWeaklingList: (in category 'weakness and ephemerality') -----
+ is: oop onWeaklingList: listHead
+ | corpse |
+ corpse := self firstCorpse: listHead.
+ [corpse notNil] whileTrue:
+ [oop = (manager followForwarded: corpse) ifTrue:
+ [^true].
+ corpse := self nextCorpseOrNil: corpse].
+ ^false!
Item was changed:
----- Method: SpurGenerationScavenger>>isScavengeSurvivor: (in category 'weakness and ephemerality') -----
isScavengeSurvivor: oop
"Answer whether the oop has survived a scavenge. This is equivalent to
+ | target |
+ (manager isImmediate: oop) ifTrue:
+ [^true].
+ target := (manager isForwarded: oop)
+ ifTrue: [manager followForwarded: oop]
+ ifFalse: [oop].
+ ^((manager isInEden: target)
+ or: [(manager isInPastSpace: target)]) not"
+ | target |
+ (manager isImmediate: oop) ifTrue:
+ [^true].
+ target := (manager isForwarded: oop)
+ ifTrue: [manager followForwarded: oop]
+ ifFalse: [oop].
+ ^(manager isYoung: target) not
+ or: [manager isInFutureSpace: target]!
- ^(manager isImmediate: oop)
- or: [((manager isInEden: oop) or: [(manager isInPastSpace: oop)]) not]"
- ^(manager isImmediate: oop)
- or: [(manager isYoung: oop) not
- or: [(manager isInFutureSpace: oop)]]!
Item was changed:
----- Method: SpurGenerationScavenger>>noUnfiredEphemeronsAtEndOfRememberedSet (in category 'weakness and ephemerality') -----
noUnfiredEphemeronsAtEndOfRememberedSet
"For assert checking only."
numRememberedEphemerons to: rememberedSetSize - 1 do:
+ [:i| | referrer |
- [:i| | referrer key |
referrer := rememberedSet at: i.
(manager isEphemeron: referrer) ifTrue:
+ [(self isScavengeSurvivor: (manager keyOfEphemeron: referrer)) ifFalse:
- [key := manager keyOfEphemeron: referrer.
- (manager isForwarded: key) ifTrue:
- [key := manager followForwarded: key].
- (self isScavengeSurvivor: key) ifFalse:
[^false]]].
^true!
Item was added:
+ ----- Method: SpurGenerationScavenger>>printWeaklingList: (in category 'debug support') -----
+ printWeaklingList: listHead
+ "Print the objects on either the weakList or the ephemeronList."
+ | corpse |
+ corpse := self firstCorpse: listHead.
+ corpse ifNil:
+ [coInterpreter print: 'empty'; cr.
+ ^self].
+ [corpse notNil] whileTrue:
+ [coInterpreter printHexnp: corpse; print: ' -> '; shortPrintOop: (manager followForwarded: corpse).
+ corpse := self nextCorpseOrNil: corpse]!
Item was changed:
----- Method: SpurGenerationScavenger>>processWeakSurvivor: (in category 'weakness and ephemerality') -----
processWeakSurvivor: weakObj
"Process a weak survivor on the weakList. Those of its fields
which have not survived the scavenge should be nilled, and if any
are, the coInterpreter should be informed via signalFinalization:."
| weakObjShouldMourn |
weakObjShouldMourn := false.
+ (manager numFixedSlotsOf: weakObj)
- (manager numStrongSlotsOf: weakObj)
to: (manager numSlotsOf: weakObj) - 1
do: [:i| | referent |
referent := manager fetchPointer: i ofObject: weakObj.
"Referent could be forwarded due to scavenging or a become:, don't assume."
((manager isNonImmediate: referent)
and: [manager isForwarded: referent]) ifTrue:
[referent := manager followForwarded: referent.
(self isScavengeSurvivor: referent) ifTrue:
[manager storePointer: i ofObject: weakObj withValue: referent]].
(self isScavengeSurvivor: referent)
ifFalse:
[weakObjShouldMourn := true.
manager
storePointerUnchecked: i
ofObject: weakObj
withValue: manager nilObject]
ifTrue:
[self assert: referent = (manager fetchPointer: i ofObject: weakObj)]].
weakObjShouldMourn ifTrue:
[coInterpreter signalFinalization: weakObj]!
Item was changed:
----- Method: SpurGenerationScavenger>>scavengeReferentsOf: (in category 'scavenger') -----
scavengeReferentsOf: referrer
"scavengeReferentsOf: referrer inspects all the pointers in referrer.
If any are new objects, it has them moved to FutureSurvivorSpace,
and answers truth. If there are no new referents, it answers falsity.
To handle weak arrays only scavenge string slots and answer true
if the referrer is weak, so that it won't be removed from the
remembered set until later."
| foundNewReferent |
"forwarding objects should be followed by callers,
unless the forwarder is a root in the remembered table."
self assert: ((manager isForwarded: referrer) not
or: [manager isRemembered: referrer]).
"unscanned ephemerons should be scanned later."
self assert: ((manager isEphemeron: referrer) not
+ or: [(self isScavengeSurvivor: (manager keyOfEphemeron: referrer))
+ or: [self is: referrer onWeaklingList: ephemeronList]]).
- or: [| key |
- key := manager keyOfEphemeron: referrer.
- (manager isForwarded: key) ifTrue:
- [key := manager followForwarded: key].
- self isScavengeSurvivor: key]).
foundNewReferent := false.
+ 0 to: (manager numStrongSlotsOf: referrer ephemeronInactiveIf: #isScavengeSurvivor:) - 1
+ do: [:i| | referent newLocation |
- 0 to: (manager numStrongSlotsOf: referrer) - 1 do:
- [:i| | referent newLocation |
referent := manager fetchPointer: i ofMaybeForwardedObject: referrer.
(manager isNonImmediate: referent) ifTrue:
["a forwarding pointer could be because of become: or scavenging."
referent := (manager isForwarded: referent)
ifTrue: [manager followForwarded: referent]
ifFalse: [referent].
(manager isYoung: referent)
ifTrue:
["if target is already in future space forwarding pointer was due to a become:."
(manager isInFutureSpace: referent)
ifTrue: [newLocation := referent]
ifFalse:
[(manager isForwarded: referent)
ifTrue: [self halt. "can this even happen?"
newLocation := manager followForwarded: referent]
ifFalse: [newLocation := self copyAndForward: referent]].
(manager isYoung: newLocation) ifTrue:
[foundNewReferent := true].
manager storePointerUnchecked: i ofMaybeForwardedObject: referrer withValue: newLocation]
ifFalse:
[manager storePointerUnchecked: i ofMaybeForwardedObject: referrer withValue: referent]]].
^foundNewReferent or: [manager isWeakNonImm: referrer]!
Item was changed:
----- Method: SpurGenerationScavenger>>scavengeUnfiredEphemeronsInRememberedSet (in category 'weakness and ephemerality') -----
scavengeUnfiredEphemeronsInRememberedSet
"There are ephemerons to be scavenged in the remembered set.
Scavenge any with unfired (live) keys, removing them from the
unscavenged ephemerons, and from the set if they no longer refer
to new objects, and answer if any with unfired keys were found."
+ | unfiredEphemeronsScavenged i referrer hasNewReferents |
- | unfiredEphemeronsScavenged i referrer key hasNewReferents |
unfiredEphemeronsScavenged := false.
i := 0.
[i < numRememberedEphemerons] whileTrue:
[referrer := rememberedSet at: i.
self assert: (manager isEphemeron: referrer).
+ (self isScavengeSurvivor: (manager keyOfEphemeron: referrer))
- key := manager keyOfEphemeron: referrer.
- (manager isOopForwarded: key) ifTrue:
- [key := manager followForwarded: key].
- (self isScavengeSurvivor: key)
ifTrue:
[unfiredEphemeronsScavenged := true.
hasNewReferents := self scavengeReferentsOf: referrer.
"remove from unscanned ephemerons in set by swapping with last ephemeron"
numRememberedEphemerons := numRememberedEphemerons - 1.
rememberedSet
at: i
put: (rememberedSet at: numRememberedEphemerons).
hasNewReferents
ifTrue: "keep in set"
[rememberedSet
at: numRememberedEphemerons
put: referrer]
ifFalse: "remove from set by overwriting with next-to-be scanned"
[previousRememberedSetSize := previousRememberedSetSize - 1.
rememberedSetSize := rememberedSetSize - 1.
rememberedSet
at: numRememberedEphemerons
put: (rememberedSet at: previousRememberedSetSize);
at: previousRememberedSetSize
put: (rememberedSet at: rememberedSetSize).
manager setIsRememberedOf: referrer to: false]]
ifFalse:
[i := i + 1]].
^unfiredEphemeronsScavenged!
Item was changed:
----- Method: SpurGenerationScavenger>>scavengeUnfiredEphemeronsOnEphemeronList (in category 'weakness and ephemerality') -----
scavengeUnfiredEphemeronsOnEphemeronList
"There may be ephemerons to be scavenged on the ephemeronList.
Scavenge any with unfired (live) keys, removing them from the
list, and answer if any with unfired keys were found."
| unfiredEphemeronsScavenged corpseOffset previousCorpse |
ephemeronList ifNil:
[^false].
unfiredEphemeronsScavenged := false.
corpseOffset := ephemeronList.
[corpseOffset ~= 0] whileTrue:
+ [| ephemeronCorpse ephemeron nextCorpseOffset |
- [| ephemeronCorpse ephemeron nextCorpseOffset key |
ephemeronCorpse := self corpseForCorpseOffset: corpseOffset.
self assert: (manager isForwarded: ephemeronCorpse).
ephemeron := manager followForwarded: ephemeronCorpse.
nextCorpseOffset := self nextCorpseOffset: ephemeronCorpse.
+ (self isScavengeSurvivor: (manager keyOfEphemeron: ephemeron))
- key := manager keyOfEphemeron: ephemeron.
- (manager isOopForwarded: key) ifTrue:
- [key := manager followForwarded: key].
- (self isScavengeSurvivor: key)
ifTrue:
[corpseOffset = ephemeronList
ifTrue: [ephemeronList := nextCorpseOffset ~= 0 ifTrue: [nextCorpseOffset]]
ifFalse: [self setCorpseOffsetOf: previousCorpse to: nextCorpseOffset].
unfiredEphemeronsScavenged := true.
self cCoerceSimple: (self scavengeReferentsOf: ephemeron) to: #void]
ifFalse:
[previousCorpse := ephemeronCorpse].
corpseOffset := nextCorpseOffset].
^unfiredEphemeronsScavenged!
Item was changed:
----- Method: SpurGenerationScavenger>>scavengerTenuringThreshold: (in category 'accessing') -----
scavengerTenuringThreshold: aProportion "(Slang flattens so need unique selectors)"
<var: 'aProportion' type: #float>
tenuringProportion := aProportion.
tenuringThreshold := aProportion = 0.0
ifTrue: [0]
+ ifFalse: [((pastSpace limit - pastSpace start) * (1.0 - aProportion)) rounded + pastSpace start]!
- ifFalse: [((pastSpace limit - pastSpace start) * aProportion) rounded + pastSpace start]!
Item was added:
+ ----- Method: SpurMemoryManager>>isScavengeSurvivor: (in category 'generation scavenging') -----
+ isScavengeSurvivor: oop
+ <doNotGenerate>
+ ^scavenger isScavengeSurvivor: oop!
Item was added:
+ ----- Method: SpurMemoryManager>>numFixedSlotsOf: (in category 'object format') -----
+ numFixedSlotsOf: objOop
+ <inline: true>
+ <asmLabel: false>
+ ^self fixedFieldsOfClassFormat: (self formatOfClass: (self fetchClassOfNonImm: objOop))!
Item was added:
+ ----- Method: SpurMemoryManager>>numStrongSlotsOf:ephemeronInactiveIf: (in category 'object access') -----
+ numStrongSlotsOf: objOop ephemeronInactiveIf: criterion
+ "Answer the number of strong pointer fields in the given object.
+ Works with CompiledMethods, as well as ordinary objects."
+ <api>
+ <var: 'criterion' declareC: 'int (*criterion)(sqInt key)'>
+ <inline: true>
+ <asmLabel: false>
+ | fmt numSlots contextSize numLiterals |
+ fmt := self formatOf: objOop.
+ fmt <= self lastPointerFormat ifTrue:
+ [numSlots := self numSlotsOf: objOop.
+ fmt <= self arrayFormat ifTrue:
+ [^numSlots].
+ fmt = self indexablePointersFormat ifTrue:
+ [(self isContextNonImm: objOop) ifTrue:
+ ["contexts end at the stack pointer"
+ contextSize := coInterpreter fetchStackPointerOf: objOop.
+ ^CtxtTempFrameStart + contextSize].
+ ^numSlots].
+ fmt = self weakArrayFormat ifTrue:
+ [^self fixedFieldsOfClass: (self fetchClassOfNonImm: objOop)].
+ self assert: fmt = self ephemeronFormat.
+ ^(self perform: criterion with: (self keyOfEphemeron: objOop))
+ ifTrue: [numSlots]
+ ifFalse: [0]].
+ fmt = self forwardedFormat ifTrue: [^1].
+ fmt < self firstCompiledMethodFormat ifTrue: [^0]. "no pointers"
+
+ "CompiledMethod: contains both pointers and bytes"
+ numLiterals := coInterpreter literalCountOf: objOop.
+ ^numLiterals + LiteralStart!
More information about the Vm-dev
mailing list