You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by eg...@apache.org on 2008/02/03 00:38:44 UTC

svn commit: r617928 - in /harmony/enhanced/drlvm/trunk/vm/em/src: NValueProfileCollector.cpp NValueProfileCollector.h

Author: egor
Date: Sat Feb  2 15:38:41 2008
New Revision: 617928

URL: http://svn.apache.org/viewvc?rev=617928&view=rev
Log:
ValueProfiler refactoring as of HARMONY-5396

patch:
0001-ValueProfileCollector-refactoring-to-separate-FirstN-and-Divided-methods.txt

refactors the stuff to separate different strategies of value profiler. That
helps because different locking strategies might be applied for both methods.
Also improved readability a bit.

runs smoke tests in server mode smoothly on linux/x86. Introduces extra 2
virtual calls for each addNewValue, but I believe that won't slow anything down.

tested changes on DaCapo/linux/x86, no significant change
(to my great despair execution time is not very stable on my laptop)


Modified:
    harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.cpp
    harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.h

Modified: harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.cpp?rev=617928&r1=617927&r2=617928&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.cpp Sat Feb  2 15:38:41 2008
@@ -16,12 +16,11 @@
 */
 /**
 * @author Yuri Kashnikov
-* @version $Revision$
-*/
-/*
-        The idea of advanced Top-N-Value (with steady and clear parts, and clear interval)
-        from <"Value profiling and optimization", B.Calder, P.Feller, Journal of Instruction-Level Parallelism, 1999>
-
+*
+* The idea of advanced Top-N-Value (with steady and clear parts, and clear
+* interval) from <"Value profiling and optimization", B.Calder, P.Feller,
+* Journal of Instruction-Level Parallelism, 1999>
+*
 */
 #include "NValueProfileCollector.h"
 
@@ -32,116 +31,249 @@
 
 #define LOG_DOMAIN "em"
 
-void ValueProfileCollector::simple_tnv_clear (struct Simple_TNV_Table * TNV_where)
+VPInstructionProfileData* TNVTableManager::createProfileData()
+{
+    VPInstructionProfileData* data = new VPInstructionProfileData();
+    data->TNV_Table =  new (struct Simple_TNV_Table[steadySize]);
+    for (uint32 i = 0; i < steadySize; i++) {
+        (data->TNV_Table[i]).frequency = 0;
+        (data->TNV_Table[i]).value = 0;
+    }
+    if (clearSize > 0) {
+        data->TNV_clear_part = new (struct Simple_TNV_Table[clearSize]);
+        for (uint32 i = 0; i < clearSize; i++) {
+            (data->TNV_clear_part[i]).frequency = 0;
+            (data->TNV_clear_part[i]).value = 0;
+        }
+    }
+    return data;
+}
+
+int32 TNVTableManager::find(TableT* where, ValueT value_to_search, uint32 size)
+{
+    uint32 search_index;
+    for (search_index = 0; search_index < size; search_index++){
+        if (where[search_index].value == value_to_search)
+            return (search_index);
+    }
+    return (-1);
+}
+
+void TNVTableManager::clearTopElements(TableT* where)
 {
     uint32 temp_index;
-    for (temp_index = 0; temp_index < TNV_clear_size; temp_index++)
-        TNV_where[temp_index].frequency = TNV_DEFAULT_CLEAR_VALUE; 
+    for (temp_index = 0; temp_index < clearSize; temp_index++) {
+        where[temp_index].frequency = TNV_DEFAULT_CLEAR_VALUE;
+    }
 }
 
-int32 ValueProfileCollector::min_in_tnv (struct Simple_TNV_Table * TNV_where, uint32 number_of_objects)
+int32 TNVTableManager::findMinIdx(TableT* where, uint32 size)
 {
     uint32 temp_index;
     uint32 temp_min_index = 0;
-    uint32 temp_min = TNV_where[temp_min_index].frequency;
-    for (temp_index = 0; temp_index < number_of_objects; temp_index++){
-        if (TNV_where[temp_index].frequency == TNV_DEFAULT_CLEAR_VALUE)
+    uint32 temp_min = where[temp_min_index].frequency;
+    for (temp_index = 0; temp_index < size; temp_index++){
+        if (where[temp_index].frequency == TNV_DEFAULT_CLEAR_VALUE) {
             return (temp_index); 
-        if (TNV_where[temp_index].frequency < temp_min){
-            temp_min = TNV_where[temp_index].frequency;
+        }
+        if (where[temp_index].frequency < temp_min){
+            temp_min = where[temp_index].frequency;
             temp_min_index = temp_index;
         }
     }
-    return (temp_min_index);    
+    return (temp_min_index);
 }
 
-int32 ValueProfileCollector::search_in_tnv_table (struct Simple_TNV_Table * TNV_where, POINTER_SIZE_INT value_to_search, uint32 number_of_objects)
+TNVTableManager::ValueT TNVTableManager::findMax(TableT *where)
 {
-    uint32 search_index;
-    for (search_index = 0; search_index < number_of_objects; search_index++){
-        if (TNV_where[search_index].value == value_to_search)
-            return (search_index);
+    ValueT max_value = 0;
+    uint32 temp_index, temp_max_frequency = 0;
+    for (temp_index = 0; temp_index < steadySize; temp_index++) {
+        TableT *current_tbl = &(where[temp_index]);
+        if (current_tbl->frequency > temp_max_frequency){
+            temp_max_frequency = current_tbl->frequency;
+            max_value = current_tbl->value;
+        }
     }
-    return (-1);
+    return (max_value);
+}
+
+void TNVTableManager::flushLastValueCounter(VPData *instProfile)
+{
+    POINTER_SIZE_INT last_value = instProfile->last_value;
+    uint32* num_times_profiled = &(instProfile->num_times_profiled);
+    struct Simple_TNV_Table* clear_part = instProfile->TNV_clear_part;
+    struct Simple_TNV_Table* steady_part = instProfile->TNV_Table;
+
+    insert(steady_part, clear_part, last_value, *num_times_profiled);
+
+    *num_times_profiled = 0;
 }
 
-void ValueProfileCollector::insert_into_tnv_table (struct Simple_TNV_Table* TNV_table, struct Simple_TNV_Table* TNV_clear_part, POINTER_SIZE_INT value_to_insert, uint32 times_met)
+void TNVTableManager::dumpValues
+    (VPInstructionProfileData* data, std::ostream& os)
 {
-    uint32 insert_index, temp_min_index;
-    POINTER_SIZE_INT temp_min_value;
-    uint32 temp_min_freq;
-    insert_index = search_in_tnv_table(TNV_table, value_to_insert, TNV_steady_size);
-    if ((insert_index != -1)  && (TNV_table[insert_index].frequency != TNV_DEFAULT_CLEAR_VALUE)){
-        TNV_table[insert_index].frequency += times_met;
-    } else if ((TNV_algo_type == TNV_FIRST_N) || (TNV_algo_type != TNV_DIVIDED)){
-        insert_index = min_in_tnv(TNV_table, TNV_steady_size);
-        if (times_met > TNV_table[insert_index].frequency){
-            TNV_table[insert_index].value = value_to_insert;
-            TNV_table[insert_index].frequency = times_met;
+    os << ", num_times_profiled: " << data->num_times_profiled 
+        << ", profile_tick: " << data->profile_tick << std::endl;
+    struct Simple_TNV_Table * TNV_steady_part = data->TNV_Table;
+    if (TNV_steady_part != NULL) {
+        uint32 size = steadySize;
+        os << "= TNV_steady_part, size = " << size << std::endl;
+        for (uint32 i = 0; i < size; i++) {
+            os << "== Frequency: " << TNV_steady_part[i].frequency << " = Value: ";
+            POINTER_SIZE_INT value = TNV_steady_part[i].value;
+            if (value != 0) {
+                os << class_get_name(vtable_get_class((VTable_Handle)value));
+            } else {
+                os << "NULL";
+            }
+            os << " ==" << std::endl;
         }
-    } else if (TNV_algo_type == TNV_DIVIDED) {
-        insert_index = search_in_tnv_table(TNV_clear_part, value_to_insert, TNV_clear_size);
+    }
+    struct Simple_TNV_Table * TNV_clear_part = data->TNV_clear_part;
+    if (TNV_clear_part != NULL) {
+        uint32 size = clearSize;
+        os << "= TNV_clear_part, size = " << size << std::endl;
+        for (uint32 i = 0; i < size; i++) {
+            os << "== " << TNV_clear_part[i].frequency << " = Value: ";
+            POINTER_SIZE_INT value = TNV_clear_part[i].value;
+            if (value != 0) {
+                os << class_get_name(vtable_get_class((VTable_Handle)value));
+            } else {
+                os << "NULL";
+            }
+            os << " ==" << std::endl;
+        }
+    }
+}
+//------------------------------------------------------------------------------
+
+void TNVTableFirstNManager::insert(TableT* where, TableT* clear_part,
+        ValueT value_to_insert, uint32 times_met)
+{
+    uint32 insert_index = find(where, value_to_insert, steadySize);
+    if ((insert_index != -1) &&
+        (where[insert_index].frequency != TNV_DEFAULT_CLEAR_VALUE)){
+        where[insert_index].frequency += times_met;
+    } else {
+        insert_index = findMinIdx(where, steadySize);
+        if (times_met > where[insert_index].frequency){
+            where[insert_index].value = value_to_insert;
+            where[insert_index].frequency = times_met;
+        }
+    }
+}
+
+void TNVTableFirstNManager::addNewValue(ValueMethodProfile* methProfile,
+            VPData* instProfile, ValueT curr_value)
+{
+    // TODO(egor):
+    // 1. options to enable/disable locking
+    // 2. flagged locking
+    methProfile->lockProfile();
+    ValueT* last_value = &(instProfile->last_value);
+    uint32* num_times_profiled = &(instProfile->num_times_profiled);
+    if (curr_value == *last_value){
+        (*num_times_profiled)++;
+    } else {
+        struct Simple_TNV_Table* clear_part = instProfile->TNV_clear_part;
+        struct Simple_TNV_Table* steady_part = instProfile->TNV_Table;
+        flushLastValueCounter(instProfile);
+        *num_times_profiled = 1;
+        insert(steady_part, clear_part, curr_value, *num_times_profiled);
+        *last_value = curr_value;
+    }
+    methProfile->unlockProfile();
+}
+//------------------------------------------------------------------------------
+
+void TNVTableDividedManager::insert(TableT* where, TableT* clear_part,
+        ValueT value_to_insert, uint32 times_met)
+{
+    uint32 insert_index = find(where, value_to_insert, steadySize);
+    if ((insert_index != -1) &&
+        (where[insert_index].frequency != TNV_DEFAULT_CLEAR_VALUE)){
+        where[insert_index].frequency += times_met;
+    }else{
+        ValueT temp_min_value;
+        uint32 temp_min_index, temp_min_freq;
+        insert_index = find(clear_part, value_to_insert, clearSize);
         if (insert_index != -1){
-            TNV_clear_part[insert_index].frequency = TNV_clear_part[insert_index].frequency + times_met;
-            temp_min_index = min_in_tnv(TNV_table, TNV_steady_size);
-            if (TNV_clear_part[insert_index].frequency > TNV_table[temp_min_index].frequency){
-                temp_min_value = TNV_table[temp_min_index].value;
-                temp_min_freq = TNV_table[temp_min_index].frequency;
-                TNV_table[temp_min_index].value = TNV_clear_part[insert_index].value;
-                TNV_table[temp_min_index].frequency = TNV_clear_part[insert_index].frequency;
-                TNV_clear_part[insert_index].frequency = TNV_DEFAULT_CLEAR_VALUE;
-                temp_min_index = min_in_tnv(TNV_clear_part, TNV_clear_size);
-                if (temp_min_freq > TNV_clear_part[temp_min_index].frequency){
-                    TNV_clear_part[temp_min_index].value = temp_min_value;
-                    TNV_clear_part[temp_min_index].frequency = temp_min_freq;
+            clear_part[insert_index].frequency = clear_part[insert_index].frequency + times_met;
+            temp_min_index = findMinIdx(where, steadySize);
+            if (clear_part[insert_index].frequency > where[temp_min_index].frequency){
+                temp_min_value = where[temp_min_index].value;
+                temp_min_freq = where[temp_min_index].frequency;
+                where[temp_min_index].value = clear_part[insert_index].value;
+                where[temp_min_index].frequency = clear_part[insert_index].frequency;
+                clear_part[insert_index].frequency = TNV_DEFAULT_CLEAR_VALUE;
+                temp_min_index = findMinIdx(clear_part, clearSize);
+                if (temp_min_freq > clear_part[temp_min_index].frequency){
+                    clear_part[temp_min_index].value = temp_min_value;
+                    clear_part[temp_min_index].frequency = temp_min_freq;
                 }
             }
-        }
-        else {
-            temp_min_index = min_in_tnv(TNV_table, TNV_steady_size);
-            if (times_met > TNV_table[temp_min_index].frequency)
+        } else {
+            temp_min_index = findMinIdx(where, steadySize);
+            if (times_met > where[temp_min_index].frequency)
             {
-                temp_min_value = TNV_table[temp_min_index].value;
-                temp_min_freq = TNV_table[temp_min_index].frequency;
-                TNV_table[temp_min_index].value = value_to_insert;
-                TNV_table[temp_min_index].frequency = times_met;
-                temp_min_index = min_in_tnv(TNV_clear_part, TNV_clear_size);
-                if (temp_min_freq > TNV_clear_part[temp_min_index].frequency)
+                temp_min_value = where[temp_min_index].value;
+                temp_min_freq = where[temp_min_index].frequency;
+                where[temp_min_index].value = value_to_insert;
+                where[temp_min_index].frequency = times_met;
+                temp_min_index = findMinIdx(clear_part, clearSize);
+                if (temp_min_freq > clear_part[temp_min_index].frequency)
                 {
-                    TNV_clear_part[temp_min_index].value = temp_min_value;
-                    TNV_clear_part[temp_min_index].frequency = temp_min_freq;
+                    clear_part[temp_min_index].value = temp_min_value;
+                    clear_part[temp_min_index].frequency = temp_min_freq;
                 }
-            }
-            else {
-                temp_min_index = min_in_tnv(TNV_clear_part, TNV_clear_size);
-                if (times_met > TNV_clear_part[temp_min_index].frequency){
-                    TNV_clear_part[temp_min_index].value = value_to_insert;
-                    TNV_clear_part[temp_min_index].frequency = times_met;
+            } else {
+                temp_min_index = findMinIdx(clear_part, clearSize);
+                if (times_met > clear_part[temp_min_index].frequency){
+                    clear_part[temp_min_index].value = value_to_insert;
+                    clear_part[temp_min_index].frequency = times_met;
                 }
             }
         }
     }
 }
 
-ValueMethodProfile* ValueProfileCollector::createProfile(Method_Handle mh, uint32 numkeys, uint32 keys[])
+void TNVTableDividedManager::addNewValue(ValueMethodProfile* methProfile,
+            VPData* instProfile, ValueT curr_value)
+{
+    methProfile->lockProfile();
+    struct Simple_TNV_Table* clear_part = instProfile->TNV_clear_part;
+    uint32* profile_tick = &(instProfile->profile_tick);
+    if (*profile_tick == clearInterval){
+        *profile_tick = 0;
+        clearTopElements(clear_part);
+    }
+    (*profile_tick)++;
+
+    ValueT* last_value = &(instProfile->last_value);
+    uint32* num_times_profiled = &(instProfile->num_times_profiled);
+    if (curr_value == *last_value){
+        (*num_times_profiled)++;
+    } else {
+        flushLastValueCounter(instProfile);
+        *num_times_profiled = 1;
+        struct Simple_TNV_Table* steady_part = instProfile->TNV_Table;
+        insert(steady_part, clear_part, curr_value, *num_times_profiled);
+        *last_value = curr_value;
+    }
+    methProfile->unlockProfile();
+}
+//------------------------------------------------------------------------------
+
+ValueMethodProfile* ValueProfileCollector::createProfile
+    (Method_Handle mh, uint32 numkeys, uint32 keys[])
 {
     hymutex_lock(&profilesLock);
     ValueMethodProfile* profile = new ValueMethodProfile(this, mh);
     // Allocate space for value maps
     for (uint32 index = 0; index < numkeys; index++){
-        VPInstructionProfileData* profileData = new VPInstructionProfileData();
-        profileData->TNV_Table =  new (struct Simple_TNV_Table[TNV_steady_size]);
-        for (uint32 i = 0; i < TNV_steady_size; i++) {
-            (profileData->TNV_Table[i]).frequency = 0;
-            (profileData->TNV_Table[i]).value = 0;
-        }
-        if (TNV_clear_size > 0) {
-            profileData->TNV_clear_part = new (struct Simple_TNV_Table[TNV_clear_size]);
-            for (uint32 i = 0; i < TNV_clear_size; i++) {
-                (profileData->TNV_clear_part[i]).frequency = 0;
-                (profileData->TNV_clear_part[i]).value = 0;
-            }
-        }
+        VPInstructionProfileData* profileData =
+            getTnvMgr()->createProfileData();
         uint32 key = keys[index];
         (profile->ValueMap)[key] = profileData;
     }
@@ -151,29 +283,19 @@
     return profile;
 }
 
-POINTER_SIZE_INT ValueProfileCollector::find_max(Simple_TNV_Table *TNV_where)
-{
-    POINTER_SIZE_INT max_value = 0;
-    uint32 temp_index, temp_max_frequency = 0;
-    for (temp_index = 0; temp_index < TNV_steady_size; temp_index++) {
-        Simple_TNV_Table *TNV_current = &(TNV_where[temp_index]);
-        if (TNV_current->frequency > temp_max_frequency){
-            temp_max_frequency = TNV_current->frequency;
-            max_value = TNV_current->value;
-        }
-    }
-    return (max_value);
-}
-
 ValueProfileCollector::ValueProfileCollector(EM_PC_Interface* em, const std::string& name, JIT_Handle genJit, 
                                              uint32 _TNV_steady_size, uint32 _TNV_clear_size,
                                              uint32 _clear_interval, algotypes _TNV_algo_type)
-                                           : ProfileCollector(em, name, EM_PCTYPE_VALUE, genJit), 
-                                             TNV_steady_size(_TNV_steady_size), TNV_clear_size(_TNV_clear_size),
-                                             clear_interval(_clear_interval), TNV_algo_type(_TNV_algo_type)
-
+                                           : ProfileCollector(em, name, EM_PCTYPE_VALUE, genJit)
 {
     hymutex_create(&profilesLock, TM_MUTEX_NESTED);
+    if (_TNV_algo_type == TNV_DIVIDED) {
+        tnvTableManager = new TNVTableDividedManager
+            (_TNV_steady_size, _TNV_clear_size, _clear_interval);
+    }else if (_TNV_algo_type == TNV_FIRST_N) {
+        tnvTableManager = new TNVTableFirstNManager
+            (_TNV_steady_size, _TNV_clear_size, _clear_interval);
+    }
     catName = std::string(LOG_DOMAIN) + ".profiler." + name;
     loggingEnabled =  is_info_enabled(LOG_DOMAIN) ||  is_info_enabled(catName.c_str());
     if (loggingEnabled) {
@@ -191,9 +313,23 @@
         ValueMethodProfile* profile = it->second;
         delete profile;
     }
+    delete tnvTableManager;
     hymutex_destroy(&profilesLock);
 }
 
+MethodProfile* ValueProfileCollector::getMethodProfile(Method_Handle mh) const
+{
+    MethodProfile* res = NULL;
+    hymutex_lock(&profilesLock);
+    ValueProfilesMap::const_iterator it = profilesByMethod.find(mh);
+    if (it != profilesByMethod.end()) {
+        res =  it->second;
+    }
+    hymutex_unlock(&profilesLock);
+    return res;
+}
+//------------------------------------------------------------------------------
+
 ValueMethodProfile::ValueMethodProfile(ValueProfileCollector* pc, Method_Handle mh)
     : MethodProfile(pc, mh)
 {
@@ -205,37 +341,14 @@
     hymutex_destroy(&lock);
 }
 
-void ValueMethodProfile::addNewValue(uint32 instructionKey, POINTER_SIZE_INT valueToAdd)
+void ValueMethodProfile::addNewValue
+    (uint32 instructionKey, POINTER_SIZE_INT valueToAdd)
 {
-    POINTER_SIZE_INT curr_value = valueToAdd;
-    lockProfile();
     VPDataMap::const_iterator it =  ValueMap.find(instructionKey);
     assert(it != ValueMap.end());
-    VPInstructionProfileData* _temp_vp = it->second;
-    POINTER_SIZE_INT* last_value = &(_temp_vp->last_value);
-    uint32* profile_tick = &(_temp_vp->profile_tick);
-    uint32* num_times_profiled = &(_temp_vp->num_times_profiled);
-    struct Simple_TNV_Table* TNV_clear_part = _temp_vp->TNV_clear_part;
-    struct Simple_TNV_Table* TNV_steady_part = _temp_vp->TNV_Table;
-    if ( getVPC()->TNV_algo_type == ValueProfileCollector::TNV_DIVIDED){
-        if (*profile_tick == getVPC()->clear_interval){
-            *profile_tick = 0;
-            getVPC()->simple_tnv_clear(TNV_clear_part);
-        }
-        (*profile_tick)++;
-    }
-    if (curr_value == *last_value){
-        (*num_times_profiled)++;
-    }
-    else {
-        flushInstProfile(_temp_vp);
-        *num_times_profiled = 1;
-        getVPC()->insert_into_tnv_table (TNV_steady_part, TNV_clear_part, valueToAdd, *num_times_profiled);
-        *last_value = curr_value;
-    }
-    unlockProfile();
-}
 
+    getVPC()->getTnvMgr()->addNewValue(this, it->second, valueToAdd);
+}
 
 POINTER_SIZE_INT ValueMethodProfile::getResult(uint32 instructionKey)
 {
@@ -251,22 +364,12 @@
         unlockProfile();
         return 0;
     }
-    flushInstProfile(_temp_vp);
-    POINTER_SIZE_INT result = getVPC()->find_max(_temp_vp->TNV_Table);
+    getVPC()->getTnvMgr()->flushLastValueCounter(_temp_vp);
+    POINTER_SIZE_INT result = getVPC()->getTnvMgr()->findMax(_temp_vp->TNV_Table);
     unlockProfile();
     return result; 
 }
 
-void ValueMethodProfile::flushInstProfile(VPInstructionProfileData* instProfile)
-{
-    POINTER_SIZE_INT last_value = instProfile->last_value;
-    uint32* num_times_profiled = &(instProfile->num_times_profiled);
-    struct Simple_TNV_Table* TNV_clear_part = instProfile->TNV_clear_part;
-    struct Simple_TNV_Table* TNV_steady_part = instProfile->TNV_Table;
-    getVPC()->insert_into_tnv_table (TNV_steady_part, TNV_clear_part, last_value, *num_times_profiled);
-    *num_times_profiled = 0;
-}
-
 void ValueMethodProfile::dumpValues(std::ostream& os)
 {
     VPDataMap::const_iterator mapIter;
@@ -276,38 +379,9 @@
     for (mapIter = ValueMap.begin(); mapIter != ValueMap.end(); mapIter++) {
         os << "=== Instruction key: " << mapIter->first;
         VPInstructionProfileData* _temp_vp = mapIter->second;
-        flushInstProfile(_temp_vp);
-        os << ", num_times_profiled: " << _temp_vp->num_times_profiled << ", profile_tick: " << _temp_vp->profile_tick << std::endl;
-        struct Simple_TNV_Table * TNV_steady_part = _temp_vp->TNV_Table;
-        if (TNV_steady_part != NULL) {
-            uint32 size = ((ValueProfileCollector*)pc)->TNV_steady_size;
-            os << "= TNV_steady_part, size = " << size << std::endl;
-            for (uint32 i = 0; i < size; i++) {
-                os << "== Frequency: " << TNV_steady_part[i].frequency << " = Value: ";
-                POINTER_SIZE_INT value = TNV_steady_part[i].value;
-                if (value != 0) {
-                    os << class_get_name(vtable_get_class((VTable_Handle)value));
-                } else {
-                    os << "NULL";
-                }
-                os << " ==" << std::endl;
-            }
-        }
-        struct Simple_TNV_Table * TNV_clear_part = _temp_vp->TNV_clear_part;
-        if (TNV_clear_part != NULL) {
-            uint32 size = ((ValueProfileCollector*)pc)->TNV_clear_size;
-            os << "= TNV_clear_part, size = " << size << std::endl;
-            for (uint32 i = 0; i < size; i++) {
-                os << "== " << TNV_clear_part[i].frequency << " = Value: ";
-                POINTER_SIZE_INT value = TNV_clear_part[i].value;
-                if (value != 0) {
-                    os << class_get_name(vtable_get_class((VTable_Handle)value));
-                } else {
-                    os << "NULL";
-                }
-                os << " ==" << std::endl;
-            }
-        }
+        TNVTableManager* tnvMgr = getVPC()->getTnvMgr();
+        tnvMgr->flushLastValueCounter(_temp_vp);
+        tnvMgr->dumpValues(_temp_vp, os);
     }
     unlockProfile();
     os << "====== End of dump ======================" << std::endl;
@@ -317,23 +391,9 @@
     assert(pc->type == EM_PCTYPE_VALUE);
     return ((ValueProfileCollector*)pc);
 }
+//------------------------------------------------------------------------------
 
-
-MethodProfile* ValueProfileCollector::getMethodProfile(Method_Handle mh) const
-{
-    MethodProfile* res = NULL;
-    hymutex_lock(&profilesLock);
-    ValueProfilesMap::const_iterator it = profilesByMethod.find(mh);
-    if (it != profilesByMethod.end()) {
-        res =  it->second;
-    }
-    hymutex_unlock(&profilesLock);
-    return res;
-}
-
-
-
-POINTER_SIZE_INT value_profiler_get_top_value (Method_Profile_Handle mph, uint32 instructionKey)
+POINTER_SIZE_INT value_profiler_get_top_value(Method_Profile_Handle mph, uint32 instructionKey)
 {
     assert(mph != NULL);
     MethodProfile* mp = (MethodProfile*)mph;
@@ -342,7 +402,7 @@
     return vmp->getResult(instructionKey);
 }
 
-void value_profiler_add_value (Method_Profile_Handle mph, uint32 instructionKey, POINTER_SIZE_INT valueToAdd)
+void value_profiler_add_value(Method_Profile_Handle mph, uint32 instructionKey, POINTER_SIZE_INT valueToAdd)
 {
     assert(mph != NULL);
     MethodProfile* mp = (MethodProfile*)mph;

Modified: harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.h?rev=617928&r1=617927&r2=617928&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.h Sat Feb  2 15:38:41 2008
@@ -42,34 +42,103 @@
     uint32 frequency;
 };
 
+class TNVTableManager {
+public:
+    typedef struct Simple_TNV_Table TableT;
+    typedef POINTER_SIZE_INT ValueT;
+    typedef VPInstructionProfileData VPData;
+    TNVTableManager(uint32 steady_size, uint32 clear_size,
+            uint32 clear_interval) :
+        steadySize(steady_size),
+        clearSize(clear_size),
+        clearInterval(clear_interval)
+    {}
+
+    VPInstructionProfileData* createProfileData();
+
+    // finds a given value in TNV table, returns the index, (-1) if not found
+    int32 find(TableT* where, ValueT value_to_search, uint32 size);
+
+    // clearSize elements are cleared from the top
+    void clearTopElements(TableT* where);
+
+    // returns the index of the minimum element
+    int32 findMinIdx(TableT* where, uint32 size);
+
+    // returns the maximum value in a given steady TNV table
+    ValueT findMax(TableT* TNV_where);
+
+    // adds value to method profile with appropriate locking of the methProfile
+    virtual void addNewValue(ValueMethodProfile* methProfile,
+            VPData* instProfile, ValueT curr_value) = 0;
+
+    // flush num_times_profiled data back to the TNV table
+    //     note: unsynchronized method - must be called from synchronized ones
+    void flushLastValueCounter(VPData* instProfile);
+
+    void dumpValues(VPInstructionProfileData* data, std::ostream& os);
+
+protected:
+    virtual void insert(TableT* where, TableT* clear_part,
+            ValueT value_to_insert, uint32 times_met) = 0;
+
+    const uint32 steadySize, clearSize, clearInterval;
+};
+
+class TNVTableDividedManager : public TNVTableManager {
+public:
+    // c-tor
+    TNVTableDividedManager(uint32 steady_size, uint32 clear_size,
+            uint32 clear_interval) :
+        TNVTableManager(steady_size, clear_size, clear_interval)
+    {}
+
+    virtual void addNewValue(ValueMethodProfile* methProfile,
+            VPData* instProfile, ValueT curr_value);
+
+protected:
+    virtual void insert(TableT* where, TableT* clear_part,
+            ValueT value_to_insert, uint32 times_met);
+};
+
+class TNVTableFirstNManager : public TNVTableManager {
+public:
+    // c-tor
+    TNVTableFirstNManager(uint32 steady_size, uint32 clear_size,
+            uint32 clear_interval) :
+        TNVTableManager(steady_size, clear_size, clear_interval)
+    {}
+
+    virtual void addNewValue(ValueMethodProfile* methProfile,
+            VPData* instProfile, ValueT curr_value);
+
+private:
+    void insert(TableT* where, TableT* clear_part,
+            ValueT value_to_insert, uint32 times_met);
+
+};
+
 class ValueProfileCollector : public ProfileCollector {
 public:
     enum algotypes {TNV_DIVIDED, TNV_FIRST_N};
-    uint32 TNV_steady_size;
-    uint32 TNV_clear_size;
-    uint32 clear_interval;
-    algotypes TNV_algo_type;
-public:
+
     ValueProfileCollector(EM_PC_Interface* em, const std::string& name, JIT_Handle genJit,
                                                 uint32 _TNV_steady_size, uint32 _TNV_clear_size,
                                                 uint32 _clear_interval, algotypes _TNV_algo_type);
+
     virtual TbsEMClient* getTbsEmClient() const {return (NULL);}
     virtual ~ValueProfileCollector();
     MethodProfile* getMethodProfile(Method_Handle mh) const ;
     ValueMethodProfile* createProfile(Method_Handle mh, uint32 numkeys, uint32 keys[]);
-    
-    int32  search_in_tnv_table (struct Simple_TNV_Table * TNV_where, POINTER_SIZE_INT value_to_search, uint32 number_of_objects);
-    int32  min_in_tnv (struct Simple_TNV_Table * TNV_where, uint32 number_of_objects);
-    void insert_into_tnv_table (struct Simple_TNV_Table* TNV_table, struct Simple_TNV_Table* TNV_clear_part, POINTER_SIZE_INT value_to_insert, uint32 times_met);
-    POINTER_SIZE_INT find_max(struct Simple_TNV_Table* TNV_where);
-    void simple_tnv_clear (struct Simple_TNV_Table* TNV_where);
 
+    TNVTableManager* getTnvMgr() { return tnvTableManager; }
 private:
     std::string catName;
     bool   loggingEnabled;
     typedef std::map<Method_Handle, ValueMethodProfile*> ValueProfilesMap;
     ValueProfilesMap profilesByMethod;
     mutable hymutex_t profilesLock;
+    TNVTableManager* tnvTableManager;
 };
 
 class VPInstructionProfileData
@@ -78,7 +147,11 @@
     struct Simple_TNV_Table* TNV_Table;
     struct Simple_TNV_Table * TNV_clear_part;
 public:
-    VPInstructionProfileData() : last_value(TNV_DEFAULT_CLEAR_VALUE), num_times_profiled(0), profile_tick(0) {}
+    VPInstructionProfileData() :
+        last_value(TNV_DEFAULT_CLEAR_VALUE),
+        num_times_profiled(0),
+        profile_tick(0)
+    {}
 public:
     POINTER_SIZE_INT last_value;
     uint32 num_times_profiled;
@@ -88,7 +161,7 @@
 typedef std::map<uint32, VPInstructionProfileData*> VPDataMap;
 class ValueMethodProfile : public MethodProfile {
 public:
-    VPDataMap ValueMap;
+    VPDataMap ValueMap; // TODO: make it private
 public:
     ValueMethodProfile(ValueProfileCollector* pc, Method_Handle mh);
     ~ValueMethodProfile();
@@ -98,8 +171,6 @@
     void addNewValue(uint32 instructionKey, POINTER_SIZE_INT valueToAdd);
     POINTER_SIZE_INT getResult(uint32 instructionKey);
 private:
-    // unsynchronized method - must be called from synchronized ones
-    void flushInstProfile(VPInstructionProfileData* instProfile);
     ValueProfileCollector* getVPC() const;
 
     hymutex_t lock;