[Vm-dev] VM Maker: Cog-eem.155.mcz
commits at source.squeak.org
commits at source.squeak.org
Sat May 31 15:07:11 UTC 2014
Eliot Miranda uploaded a new version of Cog to project VM Maker:
http://source.squeak.org/VMMaker/Cog-eem.155.mcz
==================== Summary ====================
Name: Cog-eem.155
Author: eem
Time: 31 May 2014, 8:06:54.424 am
UUID: 64eb21e0-b04d-428e-8d2f-5fc5c71f61b5
Ancestors: Cog-tpr.154
Add Spur method prototypes for ClassBuilder>>update:to: &
ClassDescription>>updateMethodBindingsTo:
Go some small way towards fixing the bootstrap now that pig
compact does the business (no chunks left to create a
snapshot full of segments).
=============== Diff against Cog-tpr.154 ===============
Item was added:
+ ----- Method: SpurBootstrap class>>ClassBuilderPROTOTYPEupdate:to: (in category 'method prototypes') -----
+ ClassBuilderPROTOTYPEupdate: oldClass to: newClass
+ "Convert oldClass, all its instances and possibly its meta class into newClass,
+ instances of newClass and possibly its meta class. The process is surprisingly
+ simple in its implementation and surprisingly complex in its nuances and potentially
+ bad side effects.
+ We can rely on two assumptions (which are critical):
+ #1: The method #updateInstancesFrom: will not create any lasting pointers to
+ 'old' instances ('old' is quote on quote since #updateInstancesFrom: will do
+ a become of the old vs. the new instances and therefore it will not create
+ pointers to *new* instances before the #become: which are *old* afterwards)
+ #2: The non-preemptive execution of the critical piece of code guarantees that
+ nobody can get a hold by 'other means' (such as process interruption and
+ reflection) on the old instances.
+ Given the above two, we know that after #updateInstancesFrom: there are no pointers
+ to any old instances. After the forwarding become there will be no pointers to the old
+ class or meta class either.
+ Andreas Raab, 2/27/2003 23:42"
+ | meta |
+ meta := oldClass isMeta.
+ "Note: Everything from here on will run without the ability to get interrupted
+ to prevent any other process to create new instances of the old class."
+ ["Note: The following removal may look somewhat obscure and needs an explanation.
+ When we mutate the class hierarchy we create new classes for any existing subclass.
+ So it may look as if we don't have to remove the old class from its superclass. However,
+ at the top of the hierarchy (the first class we reshape) that superclass itself is not newly
+ created so therefore it will hold both the oldClass and newClass in its (obsolete or not)
+ subclasses. Since the #become: below will transparently replace the pointers to oldClass
+ with newClass the superclass would have newClass in its subclasses TWICE. With rather
+ unclear effects if we consider that we may convert the meta-class hierarchy itself (which
+ is derived from the non-meta class hierarchy).
+ Due to this problem ALL classes are removed from their superclass just prior to converting
+ them. Here, breaking the superclass/subclass invariant really doesn't matter since we will
+ effectively remove the oldClass (becomeForward:) just a few lines below."
+
+ oldClass superclass removeSubclass: oldClass.
+ oldClass superclass removeObsoleteSubclass: oldClass.
+
+ "make sure that the VM cache is clean"
+ oldClass methodDict do: [:cm | cm flushCache].
+
+ "Convert the instances of oldClass into instances of newClass"
+ newClass updateInstancesFrom: oldClass.
+
+ meta
+ ifTrue:
+ [oldClass becomeForward: newClass.
+ oldClass updateMethodBindingsTo: oldClass binding]
+ ifFalse:
+ [{oldClass. oldClass class} elementsForwardIdentityTo: {newClass. newClass class}.
+ oldClass updateMethodBindingsTo: oldClass binding.
+ oldClass class updateMethodBindingsTo: oldClass class binding].
+
+ "eem 5/31/2014 07:22 At this point there used to be a garbage collect whose purpose was
+ to ensure no old instances existed after the becomeForward:. Without the GC it was possible
+ to resurrect old instances using e.g. allInstancesDo:. This was because the becomeForward:
+ updated references from the old objects to new objects but didn't destroy the old objects.
+ But as of late 2013/early 2014 becomeForward: has been modified to free all the old objects."]
+ valueUnpreemptively!
Item was added:
+ ----- Method: SpurBootstrap class>>ClassDescriptionPROTOTYPEupdateMethodBindingsTo: (in category 'method prototypes') -----
+ ClassDescriptionPROTOTYPEupdateMethodBindingsTo: aBinding
+ "ClassBuilder support for maintaining valid method bindings."
+ methodDict do: [:method| method methodClassAssociation: aBinding]!
Item was changed:
----- Method: SpurBootstrap>>on: (in category 'initialize-release') -----
on: imageName
StackInterpreter initializeWithOptions: Dictionary new.
+ (oldInterpreter := StackInterpreterSimulator new)
+ openOn: imageName extraMemory: 0;
+ assertValidExecutionPointersAtEachStep: false.
- oldInterpreter := StackInterpreterSimulator new.
- oldInterpreter openOn: imageName extraMemory: 0.
oldHeap := oldInterpreter objectMemory.
newHeap := Spur32BitMMLESimulator new.
newHeap
allocateMemoryOfSize: (oldHeap youngStart * 3 / 2 roundUpTo: 1024 * 1024)
newSpaceSize: 2 * 1024 * 1024
stackSize: 1024 * 1024
codeSize: 0.
newHeap setCheckForLeaks: 15 - 6. "don't check become; or newSpace; soooo many rehashes in bootstrap"
newHeap bootstrapping: true.
self initMaps!
Item was changed:
----- Method: SpurBootstrap>>writeSnapshot:ofTransformedImage:headerFlags:screenSize: (in category 'testing') -----
writeSnapshot: imageFileName ofTransformedImage: spurHeap headerFlags: headerFlags screenSize: screenSizeInteger
"The bootstrapped image typically contains a few big free chunks and one huge free chunk.
Test snapshot writing and loading by turning the largest non-huge chunks into segment bridges
and saving."
| penultimate ultimate sizes counts barriers sim |
sim := StackInterpreterSimulator onObjectMemory: spurHeap.
sim bootstrapping: true.
spurHeap coInterpreter: sim.
sim initializeInterpreter: 0;
setImageHeaderFlagsFrom: headerFlags;
setDisplayForm: (Form extent: screenSizeInteger >> 16 @ (screenSizeInteger bitAnd: 16rFFFF)).
spurHeap allOldSpaceEntitiesDo: [:e| penultimate := ultimate. ultimate := e].
self assert: (spurHeap isFreeObject: penultimate).
self assert: (spurHeap isSegmentBridge: ultimate).
sizes := Bag new.
spurHeap allObjectsInFreeTree: (spurHeap freeLists at: 0) do:
[:f|
sizes add: (spurHeap bytesInObject: f)].
counts := sizes sortedCounts.
self assert: counts last key = 1. "1 huge chunk"
counts size > 1
ifTrue:
[self assert: ((counts at: counts size - 1) key > 2
and: [(counts at: counts size - 1) value > 1024]).
barriers := (1 to: (counts at: counts size - 1) key) collect:
[:ign| spurHeap allocateOldSpaceChunkOfExactlyBytes: (counts at: counts size - 1) value].
barriers := barriers, {spurHeap allocateOldSpaceChunkOfExactlyBytes: (spurHeap bytesInObject: penultimate)}]
ifFalse:
[barriers := {spurHeap allocateOldSpaceChunkOfExactlyBytes: (spurHeap bytesInObject: penultimate)}].
+ barriers last ifNotNil:
+ [:end|
+ spurHeap setEndOfMemory: end.
+ spurHeap allOldSpaceEntitiesDo: [:e| penultimate := ultimate. ultimate := e].
+ self assert: (spurHeap addressAfter: ultimate) = end].
- spurHeap setEndOfMemory: barriers last.
- spurHeap allOldSpaceEntitiesDo: [:e| penultimate := ultimate. ultimate := e].
- self assert: (spurHeap addressAfter: ultimate) = barriers last.
spurHeap checkFreeSpace.
spurHeap runLeakCheckerForFullGC: true.
spurHeap segmentManager initializeFromFreeChunks: (barriers sort collect: [:b| spurHeap objectStartingAt: b]).
spurHeap checkFreeSpace.
spurHeap runLeakCheckerForFullGC: true.
sim bereaveAllMarriedContextsForSnapshotFlushingExternalPrimitivesIf: true.
sim imageName: imageFileName.
sim writeImageFileIO!
More information about the Vm-dev
mailing list