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;