Fixes for reloading
- when class is reloaded, all cached values in corresponding java.lang.Class object
have to be invalidated. Otherwise recompilation won't help as reflective environment
will still see old (invalid or incomplete) values.
- correctly handle multiple version in GETFIELD/PUTFIELD
--- a/JavaClassMemberRef2.st Thu Aug 14 16:00:39 2014 +0100
+++ b/JavaClassMemberRef2.st Sat Aug 16 08:13:09 2014 +0100
@@ -133,6 +133,10 @@
"Modified: / 12-05-2011 / 18:39:27 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!
+resolvedClass
+ ^ resolvedClass
+!
+
selector
^ self nameAndType selector.
--- a/JavaClassRegistry.st Thu Aug 14 16:00:39 2014 +0100
+++ b/JavaClassRegistry.st Sat Aug 16 08:13:09 2014 +0100
@@ -331,6 +331,8 @@
"Class already exists, reload & reinstall"
| reloadedClass |
+
+ self registerClassRedefined: oldClass.
reloadedClass := JavaClassReloader reload: oldClass with: newClass.
"/OK, full reload, not just method dictionary update"
reloadedClass ~~ oldClass ifTrue:[
@@ -377,7 +379,7 @@
"Created: / 23-10-2011 / 11:53:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
"Modified: / 02-11-2011 / 18:40:52 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
- "Modified: / 11-08-2014 / 01:41:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 15-08-2014 / 15:19:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
registerClasses: classes
@@ -545,6 +547,23 @@
"Modified: / 08-10-2013 / 19:27:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
+registerClassRedefined: class
+ "Class has been redefined, so we have to invalidate
+ caches in coresponding java.lang.Class. Luckily enough,
+ thee seem to be support for this - all we have to is to
+ increase class redefinition count."
+
+ | classObject classObjectRedefinitionCountIndex classObjectRedefinitionCount |
+
+ classObject := JavaVM reflection javaClassObjectForClass: class.
+ classObjectRedefinitionCountIndex := classObject class instVarIndexFor: #classRedefinedCount.
+ classObjectRedefinitionCount := classObject instVarAt:classObjectRedefinitionCountIndex.
+ classObjectRedefinitionCount := classObjectRedefinitionCount + 1.
+ classObject instVarAt:classObjectRedefinitionCountIndex put: classObjectRedefinitionCount.
+
+ "Created: / 15-08-2014 / 15:09:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
unregisterClassInClassLoader: class
"Unregisters class from it's classloader"
--- a/JavaExceptionTests.st Thu Aug 14 16:00:39 2014 +0100
+++ b/JavaExceptionTests.st Sat Aug 16 08:13:09 2014 +0100
@@ -65,7 +65,6 @@
"Created: / 30-03-2012 / 13:38:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
-
!JavaExceptionTests methodsFor:'callbacks'!
call: trhower with: aBoolean
--- a/JavaFieldRef2.st Thu Aug 14 16:00:39 2014 +0100
+++ b/JavaFieldRef2.st Sat Aug 16 08:13:09 2014 +0100
@@ -102,6 +102,19 @@
"Modified: / 05-10-2013 / 23:57:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
+!JavaFieldRef2 methodsFor:'printing & storing'!
+
+printOn:aStream
+ super printOn: aStream.
+ aStream nextPut: $(.
+ self classRef javaClassName printOn: aStream.
+ aStream nextPut:$#.
+ aStream nextPutAll: self nameAndType name.
+ aStream nextPut: $).
+
+ "Modified: / 15-08-2014 / 15:30:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
!JavaFieldRef2 methodsFor:'private - resolving'!
findInstOffset
--- a/JavaMethodRef2.st Thu Aug 14 16:00:39 2014 +0100
+++ b/JavaMethodRef2.st Sat Aug 16 08:13:09 2014 +0100
@@ -78,6 +78,16 @@
"
! !
+!JavaMethodRef2 methodsFor:'printing'!
+
+displayString
+ "superclass JavaRef2 says that I am responsible to implement this method"
+
+ ^ self classRef displayString , '.' , self name , self descriptor
+
+ "Created: / 15-08-2014 / 13:43:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
!JavaMethodRef2 methodsFor:'printing & storing'!
printOn:aStream
--- a/JavaVM.st Thu Aug 14 16:00:39 2014 +0100
+++ b/JavaVM.st Sat Aug 16 08:13:09 2014 +0100
@@ -5253,14 +5253,25 @@
_GETFIELD_R: fieldRef _: obj
"Called by jitted code for GETFIELD insn iff fieldref is not yet resolved"
+ | class offset |
+
obj isNil ifTrue:[
^self throwNullPointerException.
].
- fieldRef resolve.
- ^ obj instVarAt: fieldRef resolvedOffset.
+ class := fieldRef classRef resolve; javaClass.
+ class hasMultipleVersions ifTrue:[
+ fieldRef classRef resolveForVersionOf: obj or: nil.
+ fieldRef resolve.
+ offset := fieldRef resolvedOffset.
+ fieldRef invalidate.
+ ] ifFalse:[
+ fieldRef resolve.
+ offset := fieldRef resolvedOffset.
+ ].
+ ^ obj instVarAt: offset.
"Created: / 20-01-2014 / 14:56:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 31-01-2014 / 09:15:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 16-08-2014 / 07:55:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
_GETSTATIC_R: fieldRef
@@ -6955,15 +6966,28 @@
_PUTFIELD_R: fieldRef _: obj _: value
"Called by jitted code for PUTFIELD insn iff fieldref is not yet resolved"
+ | class offset |
+
+ obj isNil ifTrue:[
+ ^self throwNullPointerException.
+ ].
obj isNil ifTrue:[
^self throwNullPointerException.
].
-
- fieldRef resolve.
- ^ obj instVarAt: fieldRef resolvedOffset put: value
+ class := fieldRef classRef resolve; javaClass.
+ class hasMultipleVersions ifTrue:[
+ fieldRef classRef resolveForVersionOf: obj or: nil.
+ fieldRef resolve.
+ offset := fieldRef resolvedOffset.
+ fieldRef invalidate.
+ ] ifFalse:[
+ fieldRef resolve.
+ offset := fieldRef resolvedOffset.
+ ].
+ obj instVarAt: offset put: value
"Created: / 20-01-2014 / 15:01:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
- "Modified: / 31-01-2014 / 09:15:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 16-08-2014 / 07:57:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
_PUTSTATIC_R: fieldRef _: value