Preserve method identity when updating class methods (when possible). development
authorJan Vrany <jan.vrany@fit.cvut.cz>
Fri, 19 Apr 2013 00:29:56 +0200
branchdevelopment
changeset 2528 bc5ce044d5a1
parent 2527 c380a7c258fb
child 2529 764ab6925cf5
Preserve method identity when updating class methods (when possible). Upon class update, method identity is preserved when possoble. As a consequence, when method is bytecode interpreted, this allows for installing new bytecode and restarting existing context with new code.
JavaClassReloader.st
JavaMethod.st
--- a/JavaClassReloader.st	Fri Apr 19 00:01:10 2013 +0200
+++ b/JavaClassReloader.st	Fri Apr 19 00:29:56 2013 +0200
@@ -270,12 +270,29 @@
      simply copy methods and other info from new class to old one. 
      References must be flushed anyway!!"
 
+    | oldMethods newMethods |
 
+    oldMethods := oldClass methodDictionary.
+    newMethods := newClass methodDictionary copy.
+
+    newMethods keysDo:[:selector|
+        | oldM newM |
 
-    oldClass setMethodDictionary: newClass methodDictionary.
+        oldM := oldMethods at: selector ifAbsent:[nil].
+        oldM notNil ifTrue:[
+            newM := newMethods at: selector.
+            (oldM canBeUpdatedFrom: newM) ifTrue:[
+                oldM updateFrom: newM.
+                newMethods at: selector put: oldM.
+            ]
+        ]
+    ].
+    newMethods do:[:m|m setJavaClass: oldClass].
+    oldClass setMethodDictionary: newMethods.
     oldClass setConstantPool: newClass constantPool.
 
     "Created: / 16-12-2012 / 17:36:52 / Marcel Hlopko <marcel.hlopko@fit.cvut.cz>"
+    "Modified: / 19-04-2013 / 00:24:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaClassReloader::SingleClassReloader methodsFor:'reloading'!
--- a/JavaMethod.st	Fri Apr 19 00:01:10 2013 +0200
+++ b/JavaMethod.st	Fri Apr 19 00:29:56 2013 +0200
@@ -1385,6 +1385,17 @@
     ^javaClass programmingLanguage
 
     "Created: / 26-10-2010 / 23:42:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateFrom: anotherMethod
+
+    self class allInstVarNames keysAndValuesDo:[:index :name|
+        (#(#'code*' #'javaClass') includes: name) ifFalse:[
+            self instVarAt: index put: (anotherMethod instVarAt: index)
+        ]
+    ]
+
+    "Created: / 19-04-2013 / 00:08:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !JavaMethod methodsFor:'debugging'!
@@ -2144,7 +2155,17 @@
      to just to take anotherMethod's bytecode. Used to implement fix & restart
      workflow"
 
-    ^false
+    "/ Allready jitted method cannot be updated - no way to restart existing context into
+    "/ new code 
+    self code notNil ifTrue:[ ^ false ].
+
+    "/ Args and their types must match
+    selector ~~ anotherMethod selector ifTrue: [ ^ false ].
+
+    "/ max stack depth must be smaller or equal of the current
+    (self numVars + self stackSize) < (anotherMethod numVars + anotherMethod stackSize) ifTrue:[ ^ false ].
+
+    ^true
 
     "Created: / 18-04-2013 / 23:43:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !