ClassBuilder.st
changeset 8610 071f830dae18
parent 8539 e2fd35af7360
child 8636 c7b8998a99dd
--- a/ClassBuilder.st	Thu Sep 30 14:16:23 2004 +0200
+++ b/ClassBuilder.st	Thu Sep 30 14:36:14 2004 +0200
@@ -464,6 +464,8 @@
         old:oldClass 
         name:className) ifFalse:[^ nil].
 
+    self checkValidPools.
+
     newMetaclass := self instantiateMetaclass.
     newClass := self instantiateNewClassFrom:newMetaclass.
 
@@ -487,6 +489,9 @@
         ].
     ].
     newClass setComment:newComment category:category.
+    poolDictionaries notEmptyOrNil ifTrue:[
+        newClass sharedPools:poolDictionaries
+    ].
 
     "/ for new classes, we are almost done here
     "/ (also for autoloaded classes)
@@ -498,14 +503,14 @@
 
     "/ here comes the hard part - we are actually changing the
     "/ definition of an existing class ....
-    "/ Try hard to get away WITHOUT recompiling, since it makes all
-    "/ compiled code into interpreted ...
+    "/ Try hard to get away WITHOUT recompiling, since it is both slow
+    "/ and it makes all compiled code into interpreted (which is reJITed then)...
     oldInstVars := oldClass instanceVariableString asCollectionOfWords.
     newInstVars := newClass instanceVariableString asCollectionOfWords.
     oldClassVars := oldClass classVariableString asCollectionOfWords.
     newClassVars := newClass classVariableString asCollectionOfWords.
 
-    "/ we are on the bright side of life, if the instance layout and inheritance do not change.
+    "/ We are on the bright side of life, if the instance layout and inheritance do not change.
     "/ In this case, we can go ahead and patch the class object.
     "/ (only comment and/or classVars have changed)
     oldSuperClass := oldClass superclass.
@@ -907,7 +912,14 @@
 !
 
 handleEasyNewClass:newClass
-    |newComment anyChange changeSet1|
+    "instance layout remains the same.
+     We only have to recompile methods which access changed class variables
+     and changed pool variables."
+
+    |newComment anyChange setOfChangedVariables oldPoolVars newPoolVars|
+
+    oldPoolVars := oldClass sharedPools collectAll:[:pool | pool keys].
+    newPoolVars := newClass sharedPools collectAll:[:pool | pool keys].
 
     newComment := newClass comment.
 
@@ -919,7 +931,8 @@
         ]
     ]. 
 
-    (oldClassVars = newClassVars) ifTrue:[
+    ((oldClassVars = newClassVars)
+    and:[oldPoolVars = newPoolVars]) ifTrue:[
         "/ really no change (just comment and/or category)
 
         anyChange := false.
@@ -960,34 +973,30 @@
     "/ by creating new / deleting obsolete ones.
 
     oldClass classVariableString:classVariableNames.
+    oldClass sharedPools:newClass sharedPools.
 
     "
      get the set of changed class variables
     "
-    changeSet1 := Set new.
-    oldClassVars do:[:nm |
-        (newClassVars includes:nm) ifFalse:[
-            "/ a removed classVar;
-            "/ must recompile methods accessing that one:
-            "/ access was: classVar; now: global.
-            changeSet1 add:nm
-        ]
-    ].
-    newClassVars do:[:nm |
-        (oldClassVars includes:nm) ifFalse:[
-            "/ an added classVar;
-            "/ must recompile methods accessing that one:
-            "/ access was: global; now: classVar.
-            "/ but only, if such a global existed in the first
-            "/ place. (otherwise, it is a brand-new name)
-"/ cg: no, this is not a good check.
-"/                      (Smalltalk includesKey:nm asSymbol) ifTrue:[
-                changeSet1 add:nm
-  "/                      ]  
-        ]
-    ].
+    setOfChangedVariables := Set new.
+
+    "
+     add the set of changed class variables (those which are not in both)
+    "
+    setOfChangedVariables addAll:(oldClassVars xor:newClassVars).
 
-    changeSet1 notEmpty ifTrue:[
+    "
+     add the set of changed pool variables (those which are not in both)
+    "
+    setOfChangedVariables addAll:(oldPoolVars xor:newPoolVars).
+
+    "
+     add the set of pool vars which are now classVars and vice versa
+    "
+    setOfChangedVariables addAll:(oldPoolVars intersect:newClassVars).
+    setOfChangedVariables addAll:(oldClassVars intersect:newPoolVars).
+
+    setOfChangedVariables notEmpty ifTrue:[
 
         "/ recompile all methods accessing set of changed classvars
         "/ here and also in all subclasses ...
@@ -997,12 +1006,12 @@
         Class withoutUpdatingChangesDo:[
 
 "/                      Smalltalk silentLoading ifFalse:[
-"/                          Transcript showCR:'recompiling class & inst methods accessing ' , changeSet1 printString.
+"/                          Transcript showCR:'recompiling class & inst methods accessing ' , setOfChangedVariables printString.
 "/                          Transcript endEntry.
 "/                      ].
             oldClass withAllSubclasses do:[:aClass |
-                aClass class recompileMethodsAccessingAnyClassvarOrGlobal:changeSet1.
-                aClass recompileMethodsAccessingAnyClassvarOrGlobal:changeSet1.
+                aClass class recompileMethodsAccessingAnyClassvarOrGlobal:setOfChangedVariables.
+                aClass recompileMethodsAccessingAnyClassvarOrGlobal:setOfChangedVariables.
             ].
         ].
     ].
@@ -1938,7 +1947,7 @@
             (pool notNil
             and:[pool isBehavior
             and:[pool isSharedPool]]) ifFalse:[
-                self error:('Not a valid pool: ' , eachPoolName).
+                self error:('Not a valid pool: ' , eachPoolName) mayProceed:true.
             ]
         ]
     ].
@@ -1991,5 +2000,5 @@
 !ClassBuilder class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/ClassBuilder.st,v 1.38 2004-09-13 08:57:43 ca Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/ClassBuilder.st,v 1.39 2004-09-30 12:36:14 cg Exp $'
 ! !