You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2008/05/27 06:54:15 UTC
svn commit: r660377 - in /harmony/enhanced/drlvm/trunk/vm: include/open/
jitrino/src/vm/ vmcore/include/ vmcore/src/class_support/
Author: varlax
Date: Mon May 26 21:54:07 2008
New Revision: 660377
URL: http://svn.apache.org/viewvc?rev=660377&view=rev
Log:
Fixed HARMONY-5822 [drlvm][vmcore] class unloading does not clean JIT recompilation callbacks
Modified:
harmony/enhanced/drlvm/trunk/vm/include/open/vm_class_support.h
harmony/enhanced/drlvm/trunk/vm/include/open/vm_ee.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h
harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h
harmony/enhanced/drlvm/trunk/vm/vmcore/include/classloader.h
harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp
Modified: harmony/enhanced/drlvm/trunk/vm/include/open/vm_class_support.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/vm_class_support.h?rev=660377&r1=660376&r2=660377&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/vm_class_support.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/vm_class_support.h Mon May 26 21:54:07 2008
@@ -50,28 +50,6 @@
void vm_patch_code_block(U_8* code_block, U_8* new_code, size_t size);
/**
- * Called by a EE in order to be notified whenever the vtable entries for the given method
- * are changed. This could happen, e.g., when a method is first compiled, or when it is
- * recompiled. The callback_data pointer will be passed back to the JIT during the callback.
- * The callback method is JIT_recompiled_method_callback.
- */
-void vm_register_jit_recompiled_method_callback(JIT_Handle jit, Method_Handle method, void* callback_data);
-
-/**
- * Called by a JIT in order to be notified whenever the given method is overridden by a newly
- * loaded class. The callback_data pointer will be passed back to the JIT during the callback.
- * The callback function is JIT_overridden_method_callback.
- */
-void vm_register_jit_overridden_method_callback(JIT_Handle jit, Method_Handle method, void* callback_data);
-
-/**
- * Called by a JIT in order to be notified whenever the given class is extended.
- * The callback_data pointer will be passed back to the JIT during the callback.
- * The callback function is JIT_extended_class_callback.
- */
-void vm_register_jit_extended_class_callback(JIT_Handle jit, Class_Handle clss, void* callback_data);
-
-/**
* Called by a JIT to have the VM recompile a method using the specified JIT. After
* recompilation, the corresponding vtable entries will be updated, and the necessary
* callbacks to JIT_recompiled_method_callback will be made. It is a requirement that
Modified: harmony/enhanced/drlvm/trunk/vm/include/open/vm_ee.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/vm_ee.h?rev=660377&r1=660376&r2=660377&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/vm_ee.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/vm_ee.h Mon May 26 21:54:07 2008
@@ -198,8 +198,10 @@
* will be passed back to the JIT during the callback. The callback method is
* <code>JIT_recompiled_method_callback</code>.
*/
-DECLARE_OPEN(void, vm_register_jit_recompiled_method_callback, (JIT_Handle jit, Method_Handle method,
- void *callback_data));
+DECLARE_OPEN(void, vm_register_jit_recompiled_method_callback, (JIT_Handle jit,
+ Method_Handle method,
+ Method_Handle caller,
+ void *callback_data));
/**
* Called by a JIT to have the VM replace a section of executable code in a
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.cpp?rev=660377&r1=660376&r2=660377&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.cpp Mon May 26 21:54:07 2008
@@ -1036,7 +1036,8 @@
void CompilationInterface::setNotifyWhenMethodIsRecompiled(MethodDesc * methodDesc,
void * callbackData) {
Method_Handle drlMethod = methodDesc->getMethodHandle();
- vm_register_jit_recompiled_method_callback(getJitHandle(),drlMethod,callbackData);
+ vm_register_jit_recompiled_method_callback(getJitHandle(),drlMethod,
+ getMethodToCompile()->getMethodHandle(), callbackData);
}
void CompilationInterface::sendCompiledMethodLoadEvent(MethodDesc* methodDesc, MethodDesc* outerDesc,
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h?rev=660377&r1=660376&r2=660377&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h Mon May 26 21:54:07 2008
@@ -1059,6 +1059,8 @@
/** Clears member variables within a class.*/
void clear_internals();
+ void notify_unloading();
+
/** Determines whether the given class has a super class.
* @return <code>true</code> if the current class has a super class;
* otherwise <code>false</code>.*/
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h?rev=660377&r1=660376&r2=660377&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h Mon May 26 21:54:07 2008
@@ -22,6 +22,8 @@
#include "Class.h"
#include "vm_java_support.h"
+typedef std::vector<Method*> MethodSet;
+
struct String;
class ByteReader;
class JIT;
@@ -347,20 +349,11 @@
// Used to notify interested JITs whenever a method is changed: overwritten, recompiled,
// or initially compiled.
struct Method_Change_Notification_Record {
- Method *method_of_interest;
+ Method *caller;
JIT *jit;
void *callback_data;
Method_Change_Notification_Record *next;
- bool equals(Method *method_of_interest_, JIT *jit_, void *callback_data_) {
- if ((method_of_interest == method_of_interest_) &&
- (jit == jit_) &&
- (callback_data == callback_data_)) {
- return true;
- }
- return false;
- }
- // Optimized equals method. Most callbacks know method of interest, so we could skip one check.
inline bool equals(JIT *jit_, void *callback_data_) {
if ((callback_data == callback_data_) &&
(jit == jit_)) {
@@ -569,8 +562,9 @@
CodeChunkInfo *create_code_chunk_info_mt();
// Notify JITs whenever this method is recompiled or initially compiled.
- void register_jit_recompiled_method_callback(JIT *jit_to_be_notified, void *callback_data);
+ void register_jit_recompiled_method_callback(JIT *jit_to_be_notified, Method* caller, void *callback_data);
void do_jit_recompiled_method_callbacks();
+ void unregister_jit_recompiled_method_callbacks(const Method* caller);
Method_Side_Effects get_side_effects() { return _side_effects; }
void set_side_effects(Method_Side_Effects mse) { _side_effects = mse; }
@@ -606,6 +600,7 @@
// destructor should be instead of this function, but it's not allowed to use it because copy for Method class is
// done with memcpy, and old value is destroyed with delete operator.
void MethodClearInternals();
+ void NotifyUnloading();
//
// access modifiers
@@ -717,6 +712,9 @@
/** Information about methods inlined to this. */
InlineInfo* _inline_info;
+
+
+ MethodSet* _recompilation_callbacks;
public:
/**
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/classloader.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/classloader.h?rev=660377&r1=660376&r2=660377&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/classloader.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/classloader.h Mon May 26 21:54:07 2008
@@ -240,6 +240,9 @@
STD_FREE(m_table);
m_table = NULL;
}
+
+ void NotifyUnloading();
+
inline void* Alloc(size_t size) {
assert(pool);
Lock();
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp?rev=660377&r1=660376&r2=660377&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp Mon May 26 21:54:07 2008
@@ -1729,12 +1729,14 @@
// initially compiled. The callback_data pointer will be passed back to the JIT during the callback.
// The callback method is JIT_recompiled_method_callback.
void vm_register_jit_recompiled_method_callback(JIT_Handle jit, Method_Handle method,
+ Method_Handle caller,
void *callback_data)
{
assert(method);
+ assert(caller);
JIT *jit_to_be_notified = (JIT *)jit;
Method *m = (Method *)method;
- m->register_jit_recompiled_method_callback(jit_to_be_notified, callback_data);
+ m->register_jit_recompiled_method_callback(jit_to_be_notified, caller, callback_data);
} //vm_register_jit_recompiled_method_callback
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class.cpp?rev=660377&r1=660376&r2=660377&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class.cpp Mon May 26 21:54:07 2008
@@ -144,6 +144,13 @@
m_verify_data = 0;
}
+void Class::notify_unloading() {
+ if(m_methods != NULL) {
+ for (int i = 0; i < m_num_methods; i++){
+ m_methods[i].NotifyUnloading();
+ }
+ }
+}
void Class::clear_internals() {
if(m_fields != NULL)
@@ -615,6 +622,7 @@
_method_sig = 0;
_notify_recompiled_records = NULL;
+ _recompilation_callbacks = NULL;
_index = 0;
_max_stack=_max_locals=_n_exceptions=_n_handlers=0;
_exceptions = NULL;
@@ -639,6 +647,18 @@
_inline_info = NULL;
} //Method::Method
+
+void Method::NotifyUnloading()
+{
+ if (_recompilation_callbacks != NULL) {
+ MethodSet::const_iterator it;
+ for (it = _recompilation_callbacks->begin(); it != _recompilation_callbacks->end(); it++)
+ {
+ (*it)->unregister_jit_recompiled_method_callbacks(this);
+ }
+ }
+}
+
void Method::MethodClearInternals()
{
CodeChunkInfo *jit_info;
@@ -656,6 +676,10 @@
}
jit_info->_target_exception_handlers = NULL;
}
+
+ if (_recompilation_callbacks != NULL) {
+ delete _recompilation_callbacks;
+ }
if (_notify_recompiled_records != NULL)
{
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp?rev=660377&r1=660376&r2=660377&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp Mon May 26 21:54:07 2008
@@ -106,6 +106,22 @@
return true;
}
+void ClassLoader::NotifyUnloading()
+{
+ Global_Env *env = VM_Global_State::loader_env;
+ env->em_interface->ClassloaderUnloadingCallback((Class_Loader_Handle)this);
+
+ ClassTable::iterator it;
+ ClassTable* LoadedClasses = GetLoadedClasses();
+ for (it = LoadedClasses->begin(); it != LoadedClasses->end(); it++)
+ {
+ Class* c;
+ c = it->second;
+ assert(c);
+ c->notify_unloading();
+ }
+}
+
ClassLoader::~ClassLoader()
{
Global_Env *env = VM_Global_State::loader_env;
@@ -147,7 +163,6 @@
natives_unload_library(info->handle);
}
- env->em_interface->ClassloaderUnloadingCallback((Class_Loader_Handle)this);
delete CodeMemoryManager;
CodeMemoryManager = NULL;
@@ -582,9 +597,15 @@
unloadinglist.push_back(m_table[i]);
}
+ vector<ClassLoader*>::reverse_iterator it;
+ for (it = unloadinglist.rbegin(); it != unloadinglist.rend(); it++)
+ {
+ (*it)->NotifyUnloading();
+ }
+
// safely remove classloaders from m_table
- vector<ClassLoader*>::iterator it;
- for (it = unloadinglist.begin(); it != unloadinglist.end(); it++)
+ // iterate in reverse order to unload child loaders first
+ for (it = unloadinglist.rbegin(); it != unloadinglist.rend(); it++)
{
UnloadClassLoader(*it);
}
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp?rev=660377&r1=660376&r2=660377&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp Mon May 26 21:54:07 2008
@@ -553,7 +553,9 @@
// Notify the given JIT whenever this method is recompiled or initially compiled.
// The callback_data pointer will be passed back to the JIT during the callback.
// The JIT's callback function is JIT_recompiled_method_callback.
-void Method::register_jit_recompiled_method_callback(JIT *jit_to_be_notified, void *callback_data)
+void Method::register_jit_recompiled_method_callback(JIT *jit_to_be_notified,
+ Method* caller,
+ void *callback_data)
{
// Don't insert the same entry repeatedly on the _notify_recompiled_records list.
Method_Change_Notification_Record *nr = _notify_recompiled_records;
@@ -567,13 +569,43 @@
// Insert a new notification record.
Method_Change_Notification_Record *new_nr =
(Method_Change_Notification_Record *)STD_MALLOC(sizeof(Method_Change_Notification_Record));
- new_nr->method_of_interest = this;
+ new_nr->caller = caller;
new_nr->jit = jit_to_be_notified;
new_nr->callback_data = callback_data;
new_nr->next = _notify_recompiled_records;
_notify_recompiled_records = new_nr;
+
+ // Record a callback in the caller method to let it unregister itself if unloaded.
+ ClassLoader* this_loader = get_class()->get_class_loader();
+ ClassLoader* caller_loader = caller->get_class()->get_class_loader();
+ if (this_loader == caller_loader || caller_loader->IsBootstrap()) return;
+
+ MethodSet *vec = caller->_recompilation_callbacks;
+ if (vec == NULL) {
+ vec = caller->_recompilation_callbacks = new MethodSet();
+ }
+ vec->push_back(this);
} //Method::register_jit_recompiled_method_callback
+void Method::unregister_jit_recompiled_method_callbacks(const Method* caller) {
+ TRACE2("cu.debug", "unregister jit callback, caller=" << caller << " callee=" << this);
+ Method_Change_Notification_Record *nr,*prev = NULL;
+ for (nr = _notify_recompiled_records; nr != NULL; ) {
+ if (nr->caller == caller) {
+ if (prev) {
+ prev->next = nr->next;
+ } else {
+ _notify_recompiled_records = nr->next;
+ }
+ Method_Change_Notification_Record *next = nr->next;
+ STD_FREE(nr);
+ nr = next;
+ } else {
+ prev = nr;
+ nr = nr->next;
+ }
+ }
+}
void Method::do_jit_recompiled_method_callbacks()
{