[Pkg] The Trunk: System-ul.498.mcz

commits at source.squeak.org commits at source.squeak.org
Sun Sep 30 17:37:14 UTC 2012


Levente Uzonyi uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-ul.498.mcz

==================== Summary ====================

Name: System-ul.498
Author: ul
Time: 28 September 2012, 11:04:36.54 am
UUID: cee97707-7da6-c943-a664-3e8a6f185f37
Ancestors: System-ul.494

Another possible fix for ClassRemovalTest >> #testClassRemovalAndRecompilcationWontCreateDuplicateVariableBindings. This time when the class is removed:
- replace the bindings in that class with a copy
- search for other referrers in the system
- if such referrer was found, then nil out the value of the original binding and move it to Undeclared

=============== Diff against System-ul.494 ===============

Item was changed:
  ----- Method: SystemDictionary>>forgetClass:logged: (in category 'classes and traits') -----
  forgetClass: aClass logged: aBool 
  	"Delete the class, aClass, from the system.
  	Note that this doesn't do everything required to dispose of a class - to do that use Class>>removeFromSystem."
  
  	aBool ifTrue: [SystemChangeNotifier uniqueInstance classRemoved: aClass fromCategory: aClass category].
  	self organization removeElement: aClass name.
  	Smalltalk removeFromStartUpList: aClass.
  	Smalltalk removeFromShutDownList: aClass.
+ 	aClass isObsolete ifFalse: [
+ 		(self associationAt: aClass name ifAbsent: [ nil ]) ifNotNil: [ :oldBinding |
+ 			| newBinding |
+ 			newBinding := oldBinding shallowCopy.
+ 			self replaceBinding: oldBinding in: aClass with: newBinding.
+ 			(self isThisBindingReferred: oldBinding) ifTrue: [
+ 				oldBinding value: nil.
+ 				Undeclared add: oldBinding ] ] ].
  	self removeKey: aClass name ifAbsent: [].
+ 	self flushClassNameCache!
- 	self flushClassNameCache.!

Item was added:
+ ----- Method: SystemDictionary>>isThisBindingReferred: (in category 'classes and traits') -----
+ isThisBindingReferred: binding
+ 
+ 	self systemNavigation allSelectorsAndMethodsDo: [ :behavior :selector :method |
+ 		(method instVarsInclude: binding) ifTrue: [ 
+ 			method literalsDo: [ :literal | "Avoid possible false positives from the primitive."
+ 				literal == binding ifTrue: [ ^true ] ] ] ].
+ 	^false!

Item was added:
+ ----- Method: SystemDictionary>>replaceBinding:in:with: (in category 'classes and traits') -----
+ replaceBinding: oldBinding in: aClass with: newBinding
+ 	"Replace oldBinding with newBinding in aClass. This method is expected to be used during the removal of aClass."
+ 
+ 	aClass methodsDo: [ :method |
+ 		1 to: method numLiterals do: [ :index |
+ 			(method literalAt: index) == oldBinding ifTrue: [
+ 				method literalAt: index put: newBinding ] ] ]!

Item was added:
+ ----- Method: SystemDictionary>>replaceBinding:inAllMethodsWith: (in category 'classes and traits') -----
+ replaceBinding: oldBinding inAllMethodsWith: newBinding
+ 	"Replace oldBinding to newBinding in all methods in the system except for those which are the methods of the class of oldBinding. Return true if such replacement were made, false otherwise."
+ 
+ 	| foundReferringMethod |
+ 	foundReferringMethod := false.
+ 	self systemNavigation allSelectorsAndMethodsDo: [ :behavior :selector :method |
+ 		(behavior ~~ oldBinding value and: [
+ 			method instVarsInclude: oldBinding ]) ifTrue: [ "Use the fast primitive first."
+ 				"The penultimate literal holds the selector of the method, the last literal is the class."
+ 				1 to: method numLiterals - 2 do: [ :index |
+ 					(method literalAt: index) == oldBinding ifTrue: [
+ 						foundReferringMethod := true.
+ 						method 
+ 							literalAt: index put: newBinding;
+ 							flushCache ] ] ] ].
+ 	^foundReferringMethod!



More information about the Packages mailing list