David T. Lewis uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-dtl.461.mcz
==================== Summary ====================
Name: System-dtl.461
Author: dtl
Time: 27 November 2011, 6:50:49.443 pm
UUID: 11a6c0c8-eceb-43c1-bede-0c884b9323a6
Ancestors: System-eem.460
Fix ReferenceStream handling of weak references. Test and patches by Juan Vuletich.
<http://lists.squeakfoundation.org/pipermail/squeak-dev/2011-November/162285…>
Packages affected:
Kernel-Objects
System-Object Storage
Tests-Object Storage
If we serialize a model with weak references to views, only the model should be serialized and not the views.
The bug became apparent only when dumping a model to a SmartRefStream, that calls #references, and the serialized stream was later materialized in an image where the view classes had been deleted. In such rare cases, materialization would fail when trying to reference these absent classes. If serializing to a ReferenceStream, the bug didn't become apparent (views were never serialized). If serializing to a SmartRefStream, but view classes still existed, the bug didn't really become apparent (because views were not actually deserialized), the only effect was a larger file.
=============== Diff against System-eem.460 ===============
Item was changed:
----- Method: DiskProxy>>storeDataOn: (in category 'i/o') -----
+ storeDataOn: aReferenceStream
- storeDataOn: aDataStream
"Besides just storing, get me inserted into references, so structures will know about class DiskProxy."
+ super storeDataOn: aReferenceStream.
+
+ "just so instVarInfo: will find it and put it into structures"
+ " aReferenceStream references at: self put: #none."
+ aReferenceStream addSpecialReference: self!
- super storeDataOn: aDataStream.
- aDataStream references at: self put: #none.
- "just so instVarInfo: will find it and put it into structures"!
Item was added:
+ ----- Method: ReferenceStream>>addSpecialReference: (in category 'writing') -----
+ addSpecialReference: aDiskProxy
+ "See senders. Added to avoid breaking encapsulation (assuming that #references would answer the actual collection)"
+ references at: aDiskProxy put: #none!
Item was changed:
----- Method: ReferenceStream>>references (in category 'writing') -----
references
+ "Do not include provisory references created in #nextPutWeak that never became normal references,
+ because the referenced object was never added from a call to #nextPut:"
+ ^ references select: [ :value | value isNumber ]!
- ^ references!
Item was changed:
----- Method: ReferenceStream>>statisticsOfRefs (in category 'statistics') -----
statisticsOfRefs
"Analyze the information in references, the objects being written out"
+ | parents ownerBags tallies n nm owners normalReferences |
+ normalReferences := self references. "Exclude unrealized weaks"
+ parents := IdentityDictionary new: normalReferences size * 2.
- | parents ownerBags tallies n nm owners |
- parents := IdentityDictionary new: references size * 2.
n := 0.
'Finding Owners...'
+ displayProgressFrom: 0 to: normalReferences size
- displayProgressFrom: 0 to: references size
during: [:bar |
+ normalReferences keysDo:
- references keysDo:
[:parent | | kids |
bar value: (n := n+1).
kids := parent class isFixed
+ ifTrue: [(1 to: parent class instSize) collect: [:i | parent instVarAt: i]]
- ifTrue: [(1 to: parent class instSize) collect: [:i | parent
- instVarAt: i]]
ifFalse: [parent class isBits ifTrue: [Array new]
+ ifFalse: [(1 to: parent basicSize) collect: [:i | parent basicAt: i]]].
+ (kids select: [:x | normalReferences includesKey: x])
- ifFalse: [(1 to: parent basicSize) collect: [:i | parent basicAt:
- i]]].
- (kids select: [:x | references includesKey: x])
do: [:child | parents at: child put: parent]]].
ownerBags := Dictionary new.
tallies := Bag new.
n := 0.
'Tallying Owners...'
+ displayProgressFrom: 0 to: normalReferences size
- displayProgressFrom: 0 to: references size
during: [:bar |
+ normalReferences keysDo: "For each class of obj, tally a bag of owner classes"
- references keysDo: "For each class of obj, tally a bag of owner
- classes"
[:obj | | objParent | bar value: (n := n+1).
nm := obj class name.
tallies add: nm.
owners := ownerBags at: nm ifAbsent: [ownerBags at: nm put: Bag new].
(objParent := parents at: obj ifAbsent: [nil]) == nil
ifFalse: [owners add: objParent class name]]].
^ String streamContents:
[:strm | tallies sortedCounts do:
[:assn | n := assn key. nm := assn value.
owners := ownerBags at: nm.
strm cr; nextPutAll: nm; space; print: n.
owners size > 0 ifTrue:
[strm cr; tab; print: owners sortedCounts]]]!
David T. Lewis uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-dtl.655.mcz
==================== Summary ====================
Name: Kernel-dtl.655
Author: dtl
Time: 27 November 2011, 6:50:19.012 pm
UUID: a7fda999-52a1-42f1-92da-9cdae7a9614a
Ancestors: Kernel-bf.654
Fix ReferenceStream handling of weak references. Test and patches by Juan Vuletich.
<http://lists.squeakfoundation.org/pipermail/squeak-dev/2011-November/162285…>
Packages affected:
Kernel-Objects
System-Object Storage
Tests-Object Storage
If we serialize a model with weak references to views, only the model should be serialized and not the views.
The bug became apparent only when dumping a model to a SmartRefStream, that calls #references, and the serialized stream was later materialized in an image where the view classes had been deleted. In such rare cases, materialization would fail when trying to reference these absent classes. If serializing to a ReferenceStream, the bug didn't become apparent (views were never serialized). If serializing to a SmartRefStream, but view classes still existed, the bug didn't really become apparent (because views were not actually deserialized), the only effect was a larger file.
=============== Diff against Kernel-bf.654 ===============
Item was changed:
----- Method: Object>>storeDataOn: (in category 'objects from disk') -----
storeDataOn: aDataStream
"Store myself on a DataStream. Answer self. This is a low-level DataStream/ReferenceStream method. See also objectToStoreOnDataStream. NOTE: This method must send 'aDataStream beginInstance:size:' and then (nextPut:/nextPutWeak:) its subobjects. readDataFrom:size: reads back what we write here."
| cntInstVars cntIndexedVars |
cntInstVars := self class instSize.
cntIndexedVars := self basicSize.
aDataStream
beginInstance: self class
size: cntInstVars + cntIndexedVars.
1 to: cntInstVars do:
[:i | aDataStream nextPut: (self instVarAt: i)].
"Write fields of a variable length object. When writing to a dummy
stream, don't bother to write the bytes"
((aDataStream byteStream class == DummyStream) and: [self class isBits]) ifFalse: [
+ self class isWeak
+ ifTrue: [
+ "For weak classes (for example DependentsArray) write the referenced object only
+ if referenced from elsewhere in the dumped object graph.
+ This means, for instance that if we only dump a model, no dependents are stored,
+ but if we store a view (i.e. a Morph), it is properly handled as a dependent after the object graph is revived."
+ 1 to: cntIndexedVars do: [ :i |
+ aDataStream nextPutWeak: (self basicAt: i)]]
+ ifFalse: [
+ 1 to: cntIndexedVars do: [ :i |
+ aDataStream nextPut: (self basicAt: i)]]]!
- 1 to: cntIndexedVars do:
- [:i | aDataStream nextPut: (self basicAt: i)]].
- !
David T. Lewis uploaded a new version of Tests to project The Trunk:
http://source.squeak.org/trunk/Tests-dtl.136.mcz
==================== Summary ====================
Name: Tests-dtl.136
Author: dtl
Time: 27 November 2011, 6:51:19.271 pm
UUID: 4b78cc43-10bc-4d80-a724-44c94ba846ac
Ancestors: Tests-ul.135
Fix ReferenceStream handling of weak references. Test and patches by Juan Vuletich.
<http://lists.squeakfoundation.org/pipermail/squeak-dev/2011-November/162285…>
Packages affected:
Kernel-Objects
System-Object Storage
Tests-Object Storage
If we serialize a model with weak references to views, only the model should be serialized and not the views.
The bug became apparent only when dumping a model to a SmartRefStream, that calls #references, and the serialized stream was later materialized in an image where the view classes had been deleted. In such rare cases, materialization would fail when trying to reference these absent classes. If serializing to a ReferenceStream, the bug didn't become apparent (views were never serialized). If serializing to a SmartRefStream, but view classes still existed, the bug didn't really become apparent (because views were not actually deserialized), the only effect was a larger file.
=============== Diff against Tests-ul.135 ===============
Item was changed:
SystemOrganization addCategory: #'Tests-Exceptions'!
SystemOrganization addCategory: #'Tests-Files'!
SystemOrganization addCategory: #'Tests-Compiler'!
SystemOrganization addCategory: #'Tests-Digital Signatures'!
SystemOrganization addCategory: #'Tests-Object Events'!
SystemOrganization addCategory: #'Tests-System-Support'!
SystemOrganization addCategory: #'Tests-Bugs'!
SystemOrganization addCategory: #'Tests-ObjectsAsMethods'!
SystemOrganization addCategory: #'Tests-PrimCallController'!
SystemOrganization addCategory: #'Tests-Release'!
SystemOrganization addCategory: #'Tests-Utilities'!
SystemOrganization addCategory: #'Tests-VM'!
SystemOrganization addCategory: #'Tests-Hex'!
SystemOrganization addCategory: #'Tests-Monticello'!
SystemOrganization addCategory: #'Tests-Localization'!
SystemOrganization addCategory: #'Tests-FilePackage'!
SystemOrganization addCategory: #'Tests-Finalization'!
SystemOrganization addCategory: #'Tests-Dependencies'!
SystemOrganization addCategory: #'Tests-Monticello-Mocks'!
+ SystemOrganization addCategory: #'Tests-Object Storage'!
+ SystemOrganization addCategory: #'Tests-System-Object Storage'!
Item was added:
+ TestCase subclass: #ReferenceStreamTest
+ instanceVariableNames: ''
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Tests-System-Object Storage'!
Item was added:
+ ----- Method: ReferenceStreamTest>>testWeakDumps (in category 'testing') -----
+ testWeakDumps
+ "Test that if we serialize a model with weak references to views, only the model is serialized and not the views.
+
+ Note: The bug became apparent only when dumping a model to a SmartRefStream, that calls #references, and the serialized stream
+ was later materialized in an image where the view classes had been deleted. In such rare cases, materialization would fail when trying to reference these
+ absent classes. If serializing to a ReferenceStream, the bug didn't become apparent (views were never serialized). If serializing to a SmartRefStream, but
+ view classes still existed, the bug didn't really become apparent (because views were not actually deserialized), the only effect was a larger file.
+
+ ReferenceStreamTest new testWeakDumps
+ "
+ | oldInstance refStream |
+ oldInstance :=StringHolder new contents: 'This is a text'.
+ oldInstance addDependent: Morph new.
+ refStream := ReferenceStream on: (DummyStream on: nil).
+ refStream nextPut: oldInstance.
+ self deny: (refStream references keys anySatisfy: [ :dumpedObject | dumpedObject isKindOf: Morph ])!
David T. Lewis uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-dtl.461.mcz
==================== Summary ====================
Name: System-dtl.461
Author: dtl
Time: 27 November 2011, 6:50:49.443 pm
UUID: 11a6c0c8-eceb-43c1-bede-0c884b9323a6
Ancestors: System-eem.460
Fix ReferenceStream handling of weak references. Test and patches by Juan Vuletich.
<http://lists.squeakfoundation.org/pipermail/squeak-dev/2011-November/162285…>
Packages affected:
Kernel-Objects
System-Object Storage
Tests-Object Storage
If we serialize a model with weak references to views, only the model should be serialized and not the views.
The bug became apparent only when dumping a model to a SmartRefStream, that calls #references, and the serialized stream was later materialized in an image where the view classes had been deleted. In such rare cases, materialization would fail when trying to reference these absent classes. If serializing to a ReferenceStream, the bug didn't become apparent (views were never serialized). If serializing to a SmartRefStream, but view classes still existed, the bug didn't really become apparent (because views were not actually deserialized), the only effect was a larger file.
=============== Diff against System-eem.460 ===============
Item was changed:
----- Method: DiskProxy>>storeDataOn: (in category 'i/o') -----
+ storeDataOn: aReferenceStream
- storeDataOn: aDataStream
"Besides just storing, get me inserted into references, so structures will know about class DiskProxy."
+ super storeDataOn: aReferenceStream.
+
+ "just so instVarInfo: will find it and put it into structures"
+ " aReferenceStream references at: self put: #none."
+ aReferenceStream addSpecialReference: self!
- super storeDataOn: aDataStream.
- aDataStream references at: self put: #none.
- "just so instVarInfo: will find it and put it into structures"!
Item was added:
+ ----- Method: ReferenceStream>>addSpecialReference: (in category 'writing') -----
+ addSpecialReference: aDiskProxy
+ "See senders. Added to avoid breaking encapsulation (assuming that #references would answer the actual collection)"
+ references at: aDiskProxy put: #none!
Item was changed:
----- Method: ReferenceStream>>references (in category 'writing') -----
references
+ "Do not include provisory references created in #nextPutWeak that never became normal references,
+ because the referenced object was never added from a call to #nextPut:"
+ ^ references select: [ :value | value isNumber ]!
- ^ references!
Item was changed:
----- Method: ReferenceStream>>statisticsOfRefs (in category 'statistics') -----
statisticsOfRefs
"Analyze the information in references, the objects being written out"
+ | parents ownerBags tallies n nm owners normalReferences |
+ normalReferences := self references. "Exclude unrealized weaks"
+ parents := IdentityDictionary new: normalReferences size * 2.
- | parents ownerBags tallies n nm owners |
- parents := IdentityDictionary new: references size * 2.
n := 0.
'Finding Owners...'
+ displayProgressFrom: 0 to: normalReferences size
- displayProgressFrom: 0 to: references size
during: [:bar |
+ normalReferences keysDo:
- references keysDo:
[:parent | | kids |
bar value: (n := n+1).
kids := parent class isFixed
+ ifTrue: [(1 to: parent class instSize) collect: [:i | parent instVarAt: i]]
- ifTrue: [(1 to: parent class instSize) collect: [:i | parent
- instVarAt: i]]
ifFalse: [parent class isBits ifTrue: [Array new]
+ ifFalse: [(1 to: parent basicSize) collect: [:i | parent basicAt: i]]].
+ (kids select: [:x | normalReferences includesKey: x])
- ifFalse: [(1 to: parent basicSize) collect: [:i | parent basicAt:
- i]]].
- (kids select: [:x | references includesKey: x])
do: [:child | parents at: child put: parent]]].
ownerBags := Dictionary new.
tallies := Bag new.
n := 0.
'Tallying Owners...'
+ displayProgressFrom: 0 to: normalReferences size
- displayProgressFrom: 0 to: references size
during: [:bar |
+ normalReferences keysDo: "For each class of obj, tally a bag of owner classes"
- references keysDo: "For each class of obj, tally a bag of owner
- classes"
[:obj | | objParent | bar value: (n := n+1).
nm := obj class name.
tallies add: nm.
owners := ownerBags at: nm ifAbsent: [ownerBags at: nm put: Bag new].
(objParent := parents at: obj ifAbsent: [nil]) == nil
ifFalse: [owners add: objParent class name]]].
^ String streamContents:
[:strm | tallies sortedCounts do:
[:assn | n := assn key. nm := assn value.
owners := ownerBags at: nm.
strm cr; nextPutAll: nm; space; print: n.
owners size > 0 ifTrue:
[strm cr; tab; print: owners sortedCounts]]]!
David T. Lewis uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-dtl.655.mcz
==================== Summary ====================
Name: Kernel-dtl.655
Author: dtl
Time: 27 November 2011, 6:50:19.012 pm
UUID: a7fda999-52a1-42f1-92da-9cdae7a9614a
Ancestors: Kernel-bf.654
Fix ReferenceStream handling of weak references. Test and patches by Juan Vuletich.
<http://lists.squeakfoundation.org/pipermail/squeak-dev/2011-November/162285…>
Packages affected:
Kernel-Objects
System-Object Storage
Tests-Object Storage
If we serialize a model with weak references to views, only the model should be serialized and not the views.
The bug became apparent only when dumping a model to a SmartRefStream, that calls #references, and the serialized stream was later materialized in an image where the view classes had been deleted. In such rare cases, materialization would fail when trying to reference these absent classes. If serializing to a ReferenceStream, the bug didn't become apparent (views were never serialized). If serializing to a SmartRefStream, but view classes still existed, the bug didn't really become apparent (because views were not actually deserialized), the only effect was a larger file.
=============== Diff against Kernel-bf.654 ===============
Item was changed:
----- Method: Object>>storeDataOn: (in category 'objects from disk') -----
storeDataOn: aDataStream
"Store myself on a DataStream. Answer self. This is a low-level DataStream/ReferenceStream method. See also objectToStoreOnDataStream. NOTE: This method must send 'aDataStream beginInstance:size:' and then (nextPut:/nextPutWeak:) its subobjects. readDataFrom:size: reads back what we write here."
| cntInstVars cntIndexedVars |
cntInstVars := self class instSize.
cntIndexedVars := self basicSize.
aDataStream
beginInstance: self class
size: cntInstVars + cntIndexedVars.
1 to: cntInstVars do:
[:i | aDataStream nextPut: (self instVarAt: i)].
"Write fields of a variable length object. When writing to a dummy
stream, don't bother to write the bytes"
((aDataStream byteStream class == DummyStream) and: [self class isBits]) ifFalse: [
+ self class isWeak
+ ifTrue: [
+ "For weak classes (for example DependentsArray) write the referenced object only
+ if referenced from elsewhere in the dumped object graph.
+ This means, for instance that if we only dump a model, no dependents are stored,
+ but if we store a view (i.e. a Morph), it is properly handled as a dependent after the object graph is revived."
+ 1 to: cntIndexedVars do: [ :i |
+ aDataStream nextPutWeak: (self basicAt: i)]]
+ ifFalse: [
+ 1 to: cntIndexedVars do: [ :i |
+ aDataStream nextPut: (self basicAt: i)]]]!
- 1 to: cntIndexedVars do:
- [:i | aDataStream nextPut: (self basicAt: i)]].
- !
David T. Lewis uploaded a new version of Tests to project The Trunk:
http://source.squeak.org/trunk/Tests-dtl.136.mcz
==================== Summary ====================
Name: Tests-dtl.136
Author: dtl
Time: 27 November 2011, 6:51:19.271 pm
UUID: 4b78cc43-10bc-4d80-a724-44c94ba846ac
Ancestors: Tests-ul.135
Fix ReferenceStream handling of weak references. Test and patches by Juan Vuletich.
<http://lists.squeakfoundation.org/pipermail/squeak-dev/2011-November/162285…>
Packages affected:
Kernel-Objects
System-Object Storage
Tests-Object Storage
If we serialize a model with weak references to views, only the model should be serialized and not the views.
The bug became apparent only when dumping a model to a SmartRefStream, that calls #references, and the serialized stream was later materialized in an image where the view classes had been deleted. In such rare cases, materialization would fail when trying to reference these absent classes. If serializing to a ReferenceStream, the bug didn't become apparent (views were never serialized). If serializing to a SmartRefStream, but view classes still existed, the bug didn't really become apparent (because views were not actually deserialized), the only effect was a larger file.
=============== Diff against Tests-ul.135 ===============
Item was changed:
SystemOrganization addCategory: #'Tests-Exceptions'!
SystemOrganization addCategory: #'Tests-Files'!
SystemOrganization addCategory: #'Tests-Compiler'!
SystemOrganization addCategory: #'Tests-Digital Signatures'!
SystemOrganization addCategory: #'Tests-Object Events'!
SystemOrganization addCategory: #'Tests-System-Support'!
SystemOrganization addCategory: #'Tests-Bugs'!
SystemOrganization addCategory: #'Tests-ObjectsAsMethods'!
SystemOrganization addCategory: #'Tests-PrimCallController'!
SystemOrganization addCategory: #'Tests-Release'!
SystemOrganization addCategory: #'Tests-Utilities'!
SystemOrganization addCategory: #'Tests-VM'!
SystemOrganization addCategory: #'Tests-Hex'!
SystemOrganization addCategory: #'Tests-Monticello'!
SystemOrganization addCategory: #'Tests-Localization'!
SystemOrganization addCategory: #'Tests-FilePackage'!
SystemOrganization addCategory: #'Tests-Finalization'!
SystemOrganization addCategory: #'Tests-Dependencies'!
SystemOrganization addCategory: #'Tests-Monticello-Mocks'!
+ SystemOrganization addCategory: #'Tests-Object Storage'!
+ SystemOrganization addCategory: #'Tests-System-Object Storage'!
Item was added:
+ TestCase subclass: #ReferenceStreamTest
+ instanceVariableNames: ''
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Tests-System-Object Storage'!
Item was added:
+ ----- Method: ReferenceStreamTest>>testWeakDumps (in category 'testing') -----
+ testWeakDumps
+ "Test that if we serialize a model with weak references to views, only the model is serialized and not the views.
+
+ Note: The bug became apparent only when dumping a model to a SmartRefStream, that calls #references, and the serialized stream
+ was later materialized in an image where the view classes had been deleted. In such rare cases, materialization would fail when trying to reference these
+ absent classes. If serializing to a ReferenceStream, the bug didn't become apparent (views were never serialized). If serializing to a SmartRefStream, but
+ view classes still existed, the bug didn't really become apparent (because views were not actually deserialized), the only effect was a larger file.
+
+ ReferenceStreamTest new testWeakDumps
+ "
+ | oldInstance refStream |
+ oldInstance :=StringHolder new contents: 'This is a text'.
+ oldInstance addDependent: Morph new.
+ refStream := ReferenceStream on: (DummyStream on: nil).
+ refStream nextPut: oldInstance.
+ self deny: (refStream references keys anySatisfy: [ :dumpedObject | dumpedObject isKindOf: Morph ])!
David T. Lewis uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-dtl.461.mcz
==================== Summary ====================
Name: System-dtl.461
Author: dtl
Time: 27 November 2011, 6:50:49.443 pm
UUID: 11a6c0c8-eceb-43c1-bede-0c884b9323a6
Ancestors: System-eem.460
Fix ReferenceStream handling of weak references. Test and patches by Juan Vuletich.
<http://lists.squeakfoundation.org/pipermail/squeak-dev/2011-November/162285…>
Packages affected:
Kernel-Objects
System-Object Storage
Tests-Object Storage
If we serialize a model with weak references to views, only the model should be serialized and not the views.
The bug became apparent only when dumping a model to a SmartRefStream, that calls #references, and the serialized stream was later materialized in an image where the view classes had been deleted. In such rare cases, materialization would fail when trying to reference these absent classes. If serializing to a ReferenceStream, the bug didn't become apparent (views were never serialized). If serializing to a SmartRefStream, but view classes still existed, the bug didn't really become apparent (because views were not actually deserialized), the only effect was a larger file.
=============== Diff against System-eem.460 ===============
Item was changed:
----- Method: DiskProxy>>storeDataOn: (in category 'i/o') -----
+ storeDataOn: aReferenceStream
- storeDataOn: aDataStream
"Besides just storing, get me inserted into references, so structures will know about class DiskProxy."
+ super storeDataOn: aReferenceStream.
+
+ "just so instVarInfo: will find it and put it into structures"
+ " aReferenceStream references at: self put: #none."
+ aReferenceStream addSpecialReference: self!
- super storeDataOn: aDataStream.
- aDataStream references at: self put: #none.
- "just so instVarInfo: will find it and put it into structures"!
Item was added:
+ ----- Method: ReferenceStream>>addSpecialReference: (in category 'writing') -----
+ addSpecialReference: aDiskProxy
+ "See senders. Added to avoid breaking encapsulation (assuming that #references would answer the actual collection)"
+ references at: aDiskProxy put: #none!
Item was changed:
----- Method: ReferenceStream>>references (in category 'writing') -----
references
+ "Do not include provisory references created in #nextPutWeak that never became normal references,
+ because the referenced object was never added from a call to #nextPut:"
+ ^ references select: [ :value | value isNumber ]!
- ^ references!
Item was changed:
----- Method: ReferenceStream>>statisticsOfRefs (in category 'statistics') -----
statisticsOfRefs
"Analyze the information in references, the objects being written out"
+ | parents ownerBags tallies n nm owners normalReferences |
+ normalReferences := self references. "Exclude unrealized weaks"
+ parents := IdentityDictionary new: normalReferences size * 2.
- | parents ownerBags tallies n nm owners |
- parents := IdentityDictionary new: references size * 2.
n := 0.
'Finding Owners...'
+ displayProgressFrom: 0 to: normalReferences size
- displayProgressFrom: 0 to: references size
during: [:bar |
+ normalReferences keysDo:
- references keysDo:
[:parent | | kids |
bar value: (n := n+1).
kids := parent class isFixed
+ ifTrue: [(1 to: parent class instSize) collect: [:i | parent instVarAt: i]]
- ifTrue: [(1 to: parent class instSize) collect: [:i | parent
- instVarAt: i]]
ifFalse: [parent class isBits ifTrue: [Array new]
+ ifFalse: [(1 to: parent basicSize) collect: [:i | parent basicAt: i]]].
+ (kids select: [:x | normalReferences includesKey: x])
- ifFalse: [(1 to: parent basicSize) collect: [:i | parent basicAt:
- i]]].
- (kids select: [:x | references includesKey: x])
do: [:child | parents at: child put: parent]]].
ownerBags := Dictionary new.
tallies := Bag new.
n := 0.
'Tallying Owners...'
+ displayProgressFrom: 0 to: normalReferences size
- displayProgressFrom: 0 to: references size
during: [:bar |
+ normalReferences keysDo: "For each class of obj, tally a bag of owner classes"
- references keysDo: "For each class of obj, tally a bag of owner
- classes"
[:obj | | objParent | bar value: (n := n+1).
nm := obj class name.
tallies add: nm.
owners := ownerBags at: nm ifAbsent: [ownerBags at: nm put: Bag new].
(objParent := parents at: obj ifAbsent: [nil]) == nil
ifFalse: [owners add: objParent class name]]].
^ String streamContents:
[:strm | tallies sortedCounts do:
[:assn | n := assn key. nm := assn value.
owners := ownerBags at: nm.
strm cr; nextPutAll: nm; space; print: n.
owners size > 0 ifTrue:
[strm cr; tab; print: owners sortedCounts]]]!
David T. Lewis uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-dtl.655.mcz
==================== Summary ====================
Name: Kernel-dtl.655
Author: dtl
Time: 27 November 2011, 6:50:19.012 pm
UUID: a7fda999-52a1-42f1-92da-9cdae7a9614a
Ancestors: Kernel-bf.654
Fix ReferenceStream handling of weak references. Test and patches by Juan Vuletich.
<http://lists.squeakfoundation.org/pipermail/squeak-dev/2011-November/162285…>
Packages affected:
Kernel-Objects
System-Object Storage
Tests-Object Storage
If we serialize a model with weak references to views, only the model should be serialized and not the views.
The bug became apparent only when dumping a model to a SmartRefStream, that calls #references, and the serialized stream was later materialized in an image where the view classes had been deleted. In such rare cases, materialization would fail when trying to reference these absent classes. If serializing to a ReferenceStream, the bug didn't become apparent (views were never serialized). If serializing to a SmartRefStream, but view classes still existed, the bug didn't really become apparent (because views were not actually deserialized), the only effect was a larger file.
=============== Diff against Kernel-bf.654 ===============
Item was changed:
----- Method: Object>>storeDataOn: (in category 'objects from disk') -----
storeDataOn: aDataStream
"Store myself on a DataStream. Answer self. This is a low-level DataStream/ReferenceStream method. See also objectToStoreOnDataStream. NOTE: This method must send 'aDataStream beginInstance:size:' and then (nextPut:/nextPutWeak:) its subobjects. readDataFrom:size: reads back what we write here."
| cntInstVars cntIndexedVars |
cntInstVars := self class instSize.
cntIndexedVars := self basicSize.
aDataStream
beginInstance: self class
size: cntInstVars + cntIndexedVars.
1 to: cntInstVars do:
[:i | aDataStream nextPut: (self instVarAt: i)].
"Write fields of a variable length object. When writing to a dummy
stream, don't bother to write the bytes"
((aDataStream byteStream class == DummyStream) and: [self class isBits]) ifFalse: [
+ self class isWeak
+ ifTrue: [
+ "For weak classes (for example DependentsArray) write the referenced object only
+ if referenced from elsewhere in the dumped object graph.
+ This means, for instance that if we only dump a model, no dependents are stored,
+ but if we store a view (i.e. a Morph), it is properly handled as a dependent after the object graph is revived."
+ 1 to: cntIndexedVars do: [ :i |
+ aDataStream nextPutWeak: (self basicAt: i)]]
+ ifFalse: [
+ 1 to: cntIndexedVars do: [ :i |
+ aDataStream nextPut: (self basicAt: i)]]]!
- 1 to: cntIndexedVars do:
- [:i | aDataStream nextPut: (self basicAt: i)]].
- !
David T. Lewis uploaded a new version of Tests to project The Trunk:
http://source.squeak.org/trunk/Tests-dtl.136.mcz
==================== Summary ====================
Name: Tests-dtl.136
Author: dtl
Time: 27 November 2011, 6:51:19.271 pm
UUID: 4b78cc43-10bc-4d80-a724-44c94ba846ac
Ancestors: Tests-ul.135
Fix ReferenceStream handling of weak references. Test and patches by Juan Vuletich.
<http://lists.squeakfoundation.org/pipermail/squeak-dev/2011-November/162285…>
Packages affected:
Kernel-Objects
System-Object Storage
Tests-Object Storage
If we serialize a model with weak references to views, only the model should be serialized and not the views.
The bug became apparent only when dumping a model to a SmartRefStream, that calls #references, and the serialized stream was later materialized in an image where the view classes had been deleted. In such rare cases, materialization would fail when trying to reference these absent classes. If serializing to a ReferenceStream, the bug didn't become apparent (views were never serialized). If serializing to a SmartRefStream, but view classes still existed, the bug didn't really become apparent (because views were not actually deserialized), the only effect was a larger file.
=============== Diff against Tests-ul.135 ===============
Item was changed:
SystemOrganization addCategory: #'Tests-Exceptions'!
SystemOrganization addCategory: #'Tests-Files'!
SystemOrganization addCategory: #'Tests-Compiler'!
SystemOrganization addCategory: #'Tests-Digital Signatures'!
SystemOrganization addCategory: #'Tests-Object Events'!
SystemOrganization addCategory: #'Tests-System-Support'!
SystemOrganization addCategory: #'Tests-Bugs'!
SystemOrganization addCategory: #'Tests-ObjectsAsMethods'!
SystemOrganization addCategory: #'Tests-PrimCallController'!
SystemOrganization addCategory: #'Tests-Release'!
SystemOrganization addCategory: #'Tests-Utilities'!
SystemOrganization addCategory: #'Tests-VM'!
SystemOrganization addCategory: #'Tests-Hex'!
SystemOrganization addCategory: #'Tests-Monticello'!
SystemOrganization addCategory: #'Tests-Localization'!
SystemOrganization addCategory: #'Tests-FilePackage'!
SystemOrganization addCategory: #'Tests-Finalization'!
SystemOrganization addCategory: #'Tests-Dependencies'!
SystemOrganization addCategory: #'Tests-Monticello-Mocks'!
+ SystemOrganization addCategory: #'Tests-Object Storage'!
+ SystemOrganization addCategory: #'Tests-System-Object Storage'!
Item was added:
+ TestCase subclass: #ReferenceStreamTest
+ instanceVariableNames: ''
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Tests-System-Object Storage'!
Item was added:
+ ----- Method: ReferenceStreamTest>>testWeakDumps (in category 'testing') -----
+ testWeakDumps
+ "Test that if we serialize a model with weak references to views, only the model is serialized and not the views.
+
+ Note: The bug became apparent only when dumping a model to a SmartRefStream, that calls #references, and the serialized stream
+ was later materialized in an image where the view classes had been deleted. In such rare cases, materialization would fail when trying to reference these
+ absent classes. If serializing to a ReferenceStream, the bug didn't become apparent (views were never serialized). If serializing to a SmartRefStream, but
+ view classes still existed, the bug didn't really become apparent (because views were not actually deserialized), the only effect was a larger file.
+
+ ReferenceStreamTest new testWeakDumps
+ "
+ | oldInstance refStream |
+ oldInstance :=StringHolder new contents: 'This is a text'.
+ oldInstance addDependent: Morph new.
+ refStream := ReferenceStream on: (DummyStream on: nil).
+ refStream nextPut: oldInstance.
+ self deny: (refStream references keys anySatisfy: [ :dumpedObject | dumpedObject isKindOf: Morph ])!