You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by mf...@apache.org on 2007/08/17 13:23:17 UTC
svn commit: r567018 - in /harmony/enhanced/drlvm/trunk/vm: em/src/
include/open/ jitrino/src/vm/ vmcore/include/ vmcore/src/class_support/
Author: mfursov
Date: Fri Aug 17 04:23:16 2007
New Revision: 567018
URL: http://svn.apache.org/viewvc?view=rev&rev=567018
Log:
Fix for HARMONY-2039: [drlvm][em] EM must deallocate resources if class is unloaded
Removed:
harmony/enhanced/drlvm/trunk/vm/vmcore/include/dll_em_intf.h
Modified:
harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.cpp
harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.h
harmony/enhanced/drlvm/trunk/vm/em/src/DrlProfileCollectionFramework.h
harmony/enhanced/drlvm/trunk/vm/em/src/EBProfileCollector.cpp
harmony/enhanced/drlvm/trunk/vm/em/src/EBProfileCollector.h
harmony/enhanced/drlvm/trunk/vm/em/src/EdgeProfileCollector.cpp
harmony/enhanced/drlvm/trunk/vm/em/src/EdgeProfileCollector.h
harmony/enhanced/drlvm/trunk/vm/em/src/em_intf.cpp
harmony/enhanced/drlvm/trunk/vm/include/open/em_vm.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/EMInterface.h
harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp
Modified: harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.cpp?view=diff&rev=567018&r1=567017&r2=567018
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.cpp Fri Aug 17 04:23:16 2007
@@ -162,7 +162,7 @@
RChain* chain = *cit;
for (RSteps::const_iterator sit = chain->steps.begin(), send = chain->steps.end(); sit!=send; ++sit) {
RStep* step = *sit;
- //todo: handle jit instance -> unload or deinit
+ //todo:call deinit on JIT instance
delete step;
}
delete chain;
@@ -838,3 +838,6 @@
+void DrlEMImpl::classloaderUnloadingCallback(ClassLoaderHandle class_handle) {
+ //notify every profile collector about classloader unloading
+}
\ No newline at end of file
Modified: harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.h?view=diff&rev=567018&r1=567017&r2=567018
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.h Fri Aug 17 04:23:16 2007
@@ -93,6 +93,8 @@
virtual JIT_Result compileMethod(Method_Handle method_handle);
virtual unsigned int getNumProfilerThreads() const { return tbsClients.empty() ? 0 : 1;}
+ virtual void classloaderUnloadingCallback(ClassLoaderHandle class_handle);
+
//EM_PC interface impl:
virtual void methodProfileIsReady(MethodProfile* mp);
Modified: harmony/enhanced/drlvm/trunk/vm/em/src/DrlProfileCollectionFramework.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/em/src/DrlProfileCollectionFramework.h?view=diff&rev=567018&r1=567017&r2=567018
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/em/src/DrlProfileCollectionFramework.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/em/src/DrlProfileCollectionFramework.h Fri Aug 17 04:23:16 2007
@@ -64,6 +64,7 @@
virtual void addUseJit(JIT_Handle jit) { useJits.push_back(jit);}
+ virtual void classloaderUnloadingCallback(ClassLoaderHandle h) {}
EM_PC_Interface* em;
std::string name;
Modified: harmony/enhanced/drlvm/trunk/vm/em/src/EBProfileCollector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/em/src/EBProfileCollector.cpp?view=diff&rev=567018&r1=567017&r2=567018
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/em/src/EBProfileCollector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/em/src/EBProfileCollector.cpp Fri Aug 17 04:23:16 2007
@@ -134,7 +134,8 @@
assert(profilesByMethod.find(mh) == profilesByMethod.end());
profilesByMethod[mh] = profile;
if (mode == EB_PCMODE_ASYNC) {
- newProfiles.push_back(profile);
+ //can't modify profiles map -> it could be iterated by the checker thread without lock
+ newProfiles.push_back(profile);
}
hymutex_unlock(&profilesLock);
@@ -164,7 +165,11 @@
hymutex_unlock(&profilesLock);
}
- for (std::vector<EBMethodProfile*>::iterator it = greenProfiles.begin(), end = greenProfiles.end(); it!=end; ++it) {
+ if (!unloadedMethodProfiles.empty()) {
+ cleanUnloadedProfiles(true);
+ }
+
+ for (EBProfiles::iterator it = greenProfiles.begin(), end = greenProfiles.end(); it!=end; ++it) {
EBMethodProfile* profile = *it;
if (profile->entryCounter >= eThreshold || profile->backedgeCounter >= bThreshold) {
tmpProfiles.push_back(profile);
@@ -172,9 +177,11 @@
}
}
if (!tmpProfiles.empty()) {
+ hymutex_lock(&profilesLock);
std::remove(greenProfiles.begin(), greenProfiles.end(), (EBMethodProfile*)NULL);
greenProfiles.resize(greenProfiles.size() - tmpProfiles.size());
- for (std::vector<EBMethodProfile*>::iterator it = tmpProfiles.begin(), end = tmpProfiles.end(); it!=end; ++it) {
+ hymutex_unlock(&profilesLock);
+ for (EBProfiles::iterator it = tmpProfiles.begin(), end = tmpProfiles.end(); it!=end; ++it) {
EBMethodProfile* profile = *it;
if (loggingEnabled) {
logReadyProfile(catName, name, profile);
@@ -192,4 +199,53 @@
logReadyProfile(catName, name, (EBMethodProfile*)mp);
}
em->methodProfileIsReady(mp);
+}
+
+static void addProfilesForClassloader(ClassLoaderHandle h, EBProfiles& from, EBProfiles& to, bool erase) {
+ for (EBProfiles::iterator it = from.begin(), end = from.end(); it!=end; ++it) {
+ EBMethodProfile* profile = *it;
+ Class_Handle ch = method_get_class(profile->mh);;
+ ClassLoaderHandle clh = class_get_class_loader(ch);
+ if (clh == h) {
+ to.push_back(profile);
+ if (erase) {
+ *it=NULL;
+ }
+ }
+ }
+ if (erase) {
+ from.erase(std::remove(from.begin(), from.end(), (EBMethodProfile*)NULL), from.end());
+ }
+}
+
+void EBProfileCollector::cleanUnloadedProfiles(bool removeFromGreen) {
+ for (EBProfiles::const_iterator it = unloadedMethodProfiles.begin(), end = unloadedMethodProfiles.end(); it!=end; ++it) {
+ EBMethodProfile* profile = *it;
+ profilesByMethod.erase(profile->mh);
+ if (removeFromGreen) {
+ EBProfiles::iterator it2 = std::find(greenProfiles.begin(), greenProfiles.end(), profile);
+ assert(it2!=greenProfiles.end());
+ *it2=NULL;
+ }
+ delete profile;
+ }
+ unloadedMethodProfiles.clear();
+ if (removeFromGreen) {
+ greenProfiles.erase(std::remove(greenProfiles.begin(), greenProfiles.end(), (EBMethodProfile*)NULL), greenProfiles.end());
+ }
+}
+
+void EBProfileCollector::classloaderUnloadingCallback(ClassLoaderHandle h) {
+ hymutex_lock(&profilesLock);
+
+ //can't modify profiles map in async mode here -> it could be iterated by the checker thread without lock
+ bool erase = mode != EB_PCMODE_ASYNC;
+ addProfilesForClassloader(h, greenProfiles, unloadedMethodProfiles, erase);
+ addProfilesForClassloader(h, newProfiles, unloadedMethodProfiles, erase);
+
+ if (erase) {
+ cleanUnloadedProfiles(false);
+ }
+
+ hymutex_unlock(&profilesLock);
}
Modified: harmony/enhanced/drlvm/trunk/vm/em/src/EBProfileCollector.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/em/src/EBProfileCollector.h?view=diff&rev=567018&r1=567017&r2=567018
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/em/src/EBProfileCollector.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/em/src/EBProfileCollector.h Fri Aug 17 04:23:16 2007
@@ -30,6 +30,9 @@
class EBMethodProfile;
+typedef std::map<Method_Handle, EBMethodProfile*> EBProfilesMap;
+typedef std::vector<EBMethodProfile*> EBProfiles;
+
class EBProfileCollector : public ProfileCollector, public TbsEMClient {
public:
// Profile checking modes
@@ -56,6 +59,7 @@
virtual uint32 getTimeout() const {return timeout;}
virtual void onTimeout();
virtual MethodProfile* getMethodProfile(Method_Handle mh) const ;
+ virtual void classloaderUnloadingCallback(ClassLoaderHandle h);
EBMethodProfile* createProfile(Method_Handle mh);
void syncModeJitCallback(MethodProfile* mp);
@@ -66,6 +70,9 @@
EB_ProfilerMode getMode() const {return mode;}
private:
+
+ void cleanUnloadedProfiles(bool removeFromGreen);
+
EB_ProfilerMode mode;
uint32 eThreshold;
uint32 bThreshold;
@@ -74,20 +81,22 @@
bool loggingEnabled;
std::string catName;
- typedef std::map<Method_Handle, EBMethodProfile*> EBProfilesMap;
//Mapping of method profile by method handles
EBProfilesMap profilesByMethod;
// method profiles to check every during tbs callback
// field is used only in EB_PCMODE_ASYNC mode
- std::vector<EBMethodProfile*> greenProfiles;
+ EBProfiles greenProfiles;
// newly created method profiles since the last check during tbs callback
// field is used only in EB_PCMODE_ASYNC mode
- std::vector<EBMethodProfile*> newProfiles;
+ EBProfiles newProfiles;
// preallocated mem for temporary (method-local) needs
- std::vector<EBMethodProfile*> tmpProfiles;
+ EBProfiles tmpProfiles;
+
+ EBProfiles unloadedMethodProfiles;
+
mutable hymutex_t profilesLock;
};
Modified: harmony/enhanced/drlvm/trunk/vm/em/src/EdgeProfileCollector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/em/src/EdgeProfileCollector.cpp?view=diff&rev=567018&r1=567017&r2=567018
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/em/src/EdgeProfileCollector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/em/src/EdgeProfileCollector.cpp Fri Aug 17 04:23:16 2007
@@ -234,8 +234,7 @@
}
-void EdgeProfileCollector::onTimeout()
-{
+void EdgeProfileCollector::onTimeout() {
if(!newProfiles.empty()) {
hymutex_lock(&profilesLock);
greenProfiles.insert(greenProfiles.end(), newProfiles.begin(), newProfiles.end());
@@ -243,24 +242,26 @@
hymutex_unlock(&profilesLock);
}
- std::vector<EdgeMethodProfile*>::iterator it = greenProfiles.begin();
- std::vector<EdgeMethodProfile*>::iterator end = greenProfiles.end();
+ if (!unloadedMethodProfiles.empty()) {
+ cleanUnloadedProfiles();
+ }
- while( it != end ){
+
+ for (EdgeProfiles::iterator it = greenProfiles.begin(), end = greenProfiles.end(); it!=end; ++it) {
EdgeMethodProfile* profile = *it;
-
if( isMethodHot( profile ) ){
profile->setHotMethod();
tmpProfiles.push_back(profile);
*it = NULL;
}
- it++;
}
if (!tmpProfiles.empty()) {
+ hymutex_lock(&profilesLock);
std::remove(greenProfiles.begin(), greenProfiles.end(), (EdgeMethodProfile*)NULL);
greenProfiles.resize(greenProfiles.size() - tmpProfiles.size());
- for (std::vector<EdgeMethodProfile*>::iterator it = tmpProfiles.begin(), end = tmpProfiles.end(); it!=end; ++it) {
+ hymutex_unlock(&profilesLock);
+ for (EdgeProfiles::iterator it = tmpProfiles.begin(), end = tmpProfiles.end(); it!=end; ++it) {
EdgeMethodProfile* profile = *it;
if (loggingEnabled) {
logReadyProfile(catName, name, profile);
@@ -269,6 +270,41 @@
}
tmpProfiles.clear();
}
+}
+
+void EdgeProfileCollector::cleanUnloadedProfiles() {
+ for (EdgeProfiles::const_iterator it = unloadedMethodProfiles.begin(), end = unloadedMethodProfiles.end(); it!=end; ++it) {
+ EdgeMethodProfile* profile = *it;
+ profilesByMethod.erase(profile->mh);
+
+ EdgeProfiles::iterator it2 = std::find(greenProfiles.begin(), greenProfiles.end(), profile);
+ assert(it2!=greenProfiles.end());
+ *it2=NULL;
+
+ delete profile;
+ }
+ unloadedMethodProfiles.clear();
+ greenProfiles.erase(std::remove(greenProfiles.begin(), greenProfiles.end(), (EdgeMethodProfile*)NULL), greenProfiles.end());
+}
+
+
+static void addProfilesForClassloader(ClassLoaderHandle h, EdgeProfiles& from, EdgeProfiles& to) {
+ for (EdgeProfiles::iterator it = from.begin(), end = from.end(); it!=end; ++it) {
+ EdgeMethodProfile* profile = *it;
+ Class_Handle ch = method_get_class(profile->mh);;
+ ClassLoaderHandle clh = class_get_class_loader(ch);
+ if (clh == h) {
+ to.push_back(profile);
+ }
+ }
+}
+
+void EdgeProfileCollector::classloaderUnloadingCallback(ClassLoaderHandle h) {
+ hymutex_lock(&profilesLock);
+
+ //can't modify profiles map in async mode here -> it could be iterated by the checker thread without lock
+ addProfilesForClassloader(h, greenProfiles, unloadedMethodProfiles);
+ addProfilesForClassloader(h, newProfiles, unloadedMethodProfiles);
- return;
+ hymutex_unlock(&profilesLock);
}
Modified: harmony/enhanced/drlvm/trunk/vm/em/src/EdgeProfileCollector.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/em/src/EdgeProfileCollector.h?view=diff&rev=567018&r1=567017&r2=567018
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/em/src/EdgeProfileCollector.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/em/src/EdgeProfileCollector.h Fri Aug 17 04:23:16 2007
@@ -29,6 +29,9 @@
#include <map>
class EdgeMethodProfile;
+typedef std::map<Method_Handle, EdgeMethodProfile*> EdgeProfilesMap;
+typedef std::vector<EdgeMethodProfile*> EdgeProfiles;
+
class EdgeProfileCollector : public ProfileCollector, public TbsEMClient {
public:
@@ -42,7 +45,8 @@
virtual uint32 getInitialTimeout() const {return initialTimeout;}
virtual uint32 getTimeout() const {return timeout;}
virtual void onTimeout();
-
+ virtual void classloaderUnloadingCallback(ClassLoaderHandle h);
+
MethodProfile* getMethodProfile(Method_Handle mh) const ;
EdgeMethodProfile* createProfile(Method_Handle mh, uint32 numCounters, uint32* counterKeys, uint32 checkSum);
@@ -51,6 +55,8 @@
private:
+ void cleanUnloadedProfiles();
+
uint32 initialTimeout;
uint32 timeout;
uint32 eThreshold;
@@ -61,9 +67,10 @@
bool isMethodHot( EdgeMethodProfile* profile );
typedef std::map<Method_Handle, EdgeMethodProfile*> EdgeProfilesMap;
EdgeProfilesMap profilesByMethod;
- std::vector<EdgeMethodProfile*> greenProfiles;
- std::vector<EdgeMethodProfile*> newProfiles;
- std::vector<EdgeMethodProfile*> tmpProfiles;
+ EdgeProfiles greenProfiles;
+ EdgeProfiles newProfiles;
+ EdgeProfiles tmpProfiles;
+ EdgeProfiles unloadedMethodProfiles;
mutable hymutex_t profilesLock;
};
Modified: harmony/enhanced/drlvm/trunk/vm/em/src/em_intf.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/em/src/em_intf.cpp?view=diff&rev=567018&r1=567017&r2=567018
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/em/src/em_intf.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/em/src/em_intf.cpp Fri Aug 17 04:23:16 2007
@@ -55,6 +55,11 @@
DrlEMFactory::getEMInstance()->tbsTimeout();
}
+static void
+ClassloaderUnloadingCallback(ClassLoaderHandle class_handle) {
+ DrlEMFactory::getEMInstance()->classloaderUnloadingCallback(class_handle);
+}
+
static const char*
GetName() {
return OPEN_EM;
@@ -174,6 +179,7 @@
vm_intf->ExecuteMethod = ExecuteMethod;
vm_intf->CompileMethod = CompileMethod;
vm_intf->ProfilerThreadTimeout = ProfilerThreadTimeout;
+ vm_intf->ClassloaderUnloadingCallback = ClassloaderUnloadingCallback;
component_interface = (OpenComponentHandle) c_intf;
allocator_interface = (OpenInstanceAllocatorHandle) a_intf;
Modified: harmony/enhanced/drlvm/trunk/vm/include/open/em_vm.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/em_vm.h?view=diff&rev=567018&r1=567017&r2=567018
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/em_vm.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/em_vm.h Fri Aug 17 04:23:16 2007
@@ -80,6 +80,8 @@
*/
void (*ProfilerThreadTimeout) ();
+ void (*ClassloaderUnloadingCallback) (ClassLoaderHandle class_handle);
+
};
typedef const struct _OpenEmVm* OpenEmVmHandle;
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/EMInterface.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/EMInterface.h?view=diff&rev=567018&r1=567017&r2=567018
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/EMInterface.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/EMInterface.h Fri Aug 17 04:23:16 2007
@@ -39,10 +39,15 @@
public:
MethodProfile(Method_Profile_Handle _handle, ProfileType _type, MethodDesc& _md)
: handle(_handle), type(_type), md(_md){}
- virtual ~MethodProfile(){};
- Method_Profile_Handle getHandle() const { return handle;}
- MethodDesc& getMethod() const {return md;}
- ProfileType getProfileType() const {return type;}
+
+ virtual ~MethodProfile(){};
+
+ Method_Profile_Handle getHandle() const { return handle;}
+
+ MethodDesc& getMethod() const {return md;}
+
+ ProfileType getProfileType() const {return type;}
+
private:
Method_Profile_Handle handle;
ProfileType type;
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?view=diff&rev=567018&r1=567017&r2=567018
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/classloader.cpp Fri Aug 17 04:23:16 2007
@@ -95,6 +95,7 @@
ClassLoader::~ClassLoader()
{
+ Global_Env *env = VM_Global_State::loader_env;
ClassTable::iterator it;
ClassTable* LoadedClasses = GetLoadedClasses();
for (it = LoadedClasses->begin(); it != LoadedClasses->end(); it++)
@@ -133,6 +134,7 @@
natives_unload_library(info->handle);
}
+ env->em_interface->ClassloaderUnloadingCallback((ClassLoaderHandle)this);
delete CodeMemoryManager;
CodeMemoryManager = NULL;