harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From var...@apache.org
Subject svn commit: r486662 [1/2] - in /harmony/enhanced/drlvm/trunk: build/custom/msvc_2003/em/ build/custom/msvc_2003/jitrino/ src/test/microbenchmark/harmony-2012/ vm/em/src/ vm/include/open/ vm/jitrino/config/em64t/ vm/jitrino/config/ia32/ vm/jitrino/src/c...
Date Wed, 13 Dec 2006 14:11:12 GMT
Author: varlax
Date: Wed Dec 13 06:11:10 2006
New Revision: 486662

URL: http://svn.apache.org/viewvc?view=rev&rev=486662
Log:
Applied HARMONY-2012 [drlvm][em] value-profling implemenation
Tested on SUSE9.

Added:
    harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-2012/
    harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-2012/test2012.java
    harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.cpp   (with props)
    harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.h   (with props)
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp
Modified:
    harmony/enhanced/drlvm/trunk/build/custom/msvc_2003/em/em.vcproj
    harmony/enhanced/drlvm/trunk/build/custom/msvc_2003/jitrino/jitrino.vcproj
    harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.cpp
    harmony/enhanced/drlvm/trunk/vm/include/open/em_profile_access.h
    harmony/enhanced/drlvm/trunk/vm/include/open/vm.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Printer.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeGenerator.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/EMInterface.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlEMInterface.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlEMInterface.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp

Modified: harmony/enhanced/drlvm/trunk/build/custom/msvc_2003/em/em.vcproj
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/build/custom/msvc_2003/em/em.vcproj?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/build/custom/msvc_2003/em/em.vcproj (original)
+++ harmony/enhanced/drlvm/trunk/build/custom/msvc_2003/em/em.vcproj Wed Dec 13 06:11:10 2006
@@ -139,6 +139,12 @@
 			<File
 				RelativePath="..\..\..\..\vm\em\src\EdgeProfileCollector.h">
 			</File>
+			<File
+				RelativePath="..\..\..\..\vm\em\src\NValueProfileCollector.cpp">
+			</File>
+			<File
+				RelativePath="..\..\..\..\vm\em\src\NValueProfileCollector.h">
+			</File>
 		</Filter>
 		<File
 			RelativePath="..\..\..\..\vm\em\src\DrlEMImpl.cpp">

Modified: harmony/enhanced/drlvm/trunk/build/custom/msvc_2003/jitrino/jitrino.vcproj
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/build/custom/msvc_2003/jitrino/jitrino.vcproj?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/build/custom/msvc_2003/jitrino/jitrino.vcproj (original)
+++ harmony/enhanced/drlvm/trunk/build/custom/msvc_2003/jitrino/jitrino.vcproj Wed Dec 13 06:11:10 2006
@@ -949,6 +949,9 @@
 			<File
 				RelativePath="..\..\..\..\vm\jitrino\src\dynopt\StaticProfiler.h">
 			</File>
+			<File
+				RelativePath="..\..\..\..\vm\jitrino\src\dynopt\ValueProfiler.cpp">
+			</File>
 		</Filter>
 		<Filter
 			Name="translator"

Added: harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-2012/test2012.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-2012/test2012.java?view=auto&rev=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-2012/test2012.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/microbenchmark/harmony-2012/test2012.java Wed Dec 13 06:11:10 2006
@@ -0,0 +1,50 @@
+interface Intf {
+    public void inc();
+    public long getNum();
+    public void reset();
+}
+
+class IntfImpl implements Intf {
+
+    private long num;
+
+    public IntfImpl() { num = 0; }
+    public void inc() { num++; }
+    public long getNum() { return num; }
+    public void reset() { num = 0; }
+}
+
+public class test2012 {
+    
+    static final long limit = 10000000;
+
+    static Intf obj = new IntfImpl();
+
+    public static void main(String[] args) {
+        test2012 testObject = new test2012();
+
+        long before = 0, after = 0;
+	long best = 0;
+
+        for (int i = 0; i < 10; i++) {    
+            obj.reset();
+
+            before = System.currentTimeMillis();
+            testObject.run();
+            after = System.currentTimeMillis();
+            
+            long current = obj.getNum() / (((after - before)==0) ? 1 : (after - before));
+            System.out.println("Current score: " + current);
+            if (current > best) best = current;
+        }
+        System.out.println("Calls per millisecond: " + best);
+    }
+
+    public void run() {
+
+        for (long k = 0; k < limit; k++ ) {
+            obj.inc();
+	}
+    }
+
+}

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=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.cpp Wed Dec 13 06:11:10 2006
@@ -23,6 +23,7 @@
 
 #include "EBProfileCollector.h"
 #include "EdgeProfileCollector.h"
+#include "NValueProfileCollector.h"
 
 #include "jit_import.h"
 #include "em_intf.h"
@@ -41,6 +42,7 @@
 #define LOG_DOMAIN "em"
 
 #define EDGE_PROFILER_STR  "EDGE_PROFILER"
+#define VALUE_PROFILER_STR  "VALUE_PROFILER"
 #define ENTRY_BACKEDGE_PROFILER_STR  "EB_PROFILER"
 
 #define EM_CONFIG_EXT std::string(".emconf")
@@ -141,6 +143,12 @@
     profileAccessInterface.edge_profiler_get_entry_threshold = edge_profiler_get_entry_threshold;
     profileAccessInterface.edge_profiler_get_backedge_threshold = edge_profiler_get_backedge_threshold;
     
+    
+    //Value profile
+    profileAccessInterface.value_profiler_create_profile = value_profiler_create_profile;
+    profileAccessInterface.value_profiler_add_value = value_profiler_add_value;
+    profileAccessInterface.value_profiler_get_top_value = value_profiler_get_top_value;
+    
     return;
 }
 
@@ -572,48 +580,80 @@
         return NULL;
     }    
     std::string profilerType = getParam(config, profilerName+".profilerType");
-    if (profilerType!=ENTRY_BACKEDGE_PROFILER_STR && profilerType!=EDGE_PROFILER_STR) {
+    if (profilerType!=ENTRY_BACKEDGE_PROFILER_STR && profilerType!=EDGE_PROFILER_STR  && profilerType!=VALUE_PROFILER_STR) {
         ECHO("EM: Unsupported profiler type");
         return NULL;
     }
-    EBProfileCollector::EB_ProfilerMode ebMode = EBProfileCollector::EB_PCMODE_SYNC;
-    std::string mode = profilerType==EDGE_PROFILER_STR ? "ASYNC" : getParam(config, profilerName+".mode");
-    
-    if (mode == "ASYNC") {
-        ebMode = EBProfileCollector::EB_PCMODE_ASYNC;
-    }  else if (mode!="SYNC") {
-        ECHO("EM: unsupported profiler mode");
-        return NULL;
-    }
-    
-    bool ok = false;
-    uint32 eThreshold = toNum(getParam(config, profilerName+".entryThreshold"), &ok);//todo: default values..
-        if (!ok) {
-        ECHO("EM: illegal 'entryThreshold' value");
-        return NULL;
+
+    if (profilerType == ENTRY_BACKEDGE_PROFILER_STR || profilerType == EDGE_PROFILER_STR) {
+        EBProfileCollector::EB_ProfilerMode ebMode = EBProfileCollector::EB_PCMODE_SYNC;
+        std::string mode = profilerType==EDGE_PROFILER_STR ? "ASYNC" : getParam(config, profilerName+".mode");
+        
+        if (mode == "ASYNC") {
+            ebMode = EBProfileCollector::EB_PCMODE_ASYNC;
+        }  else if (mode!="SYNC") {
+            ECHO("EM: unsupported profiler mode");
+            return NULL;
         }
-            uint32 bThreshold = toNum(getParam(config, profilerName+".backedgeThreshold"), &ok);
-    if (!ok) {
-        ECHO("EM: illegal 'backedgeThreshold' value");
-        return NULL;
-    }
-    uint32 tbsTimeout = 0, tbsInitialTimeout = 0;
-    if (ebMode == EBProfileCollector::EB_PCMODE_ASYNC) {
-        tbsTimeout= toNum(getParam(config, profilerName+".tbsTimeout"), &ok);
+        
+        bool ok = false;
+        uint32 eThreshold = toNum(getParam(config, profilerName+".entryThreshold"), &ok);//todo: default values..
+            if (!ok) {
+            ECHO("EM: illegal 'entryThreshold' value");
+            return NULL;
+            }
+                uint32 bThreshold = toNum(getParam(config, profilerName+".backedgeThreshold"), &ok);
         if (!ok) {
-            ECHO("EM: illegal 'tbsTimeout' value");
+            ECHO("EM: illegal 'backedgeThreshold' value");
             return NULL;
+        }
+        uint32 tbsTimeout = 0, tbsInitialTimeout = 0;
+        if (ebMode == EBProfileCollector::EB_PCMODE_ASYNC) {
+            tbsTimeout= toNum(getParam(config, profilerName+".tbsTimeout"), &ok);
+            if (!ok) {
+                ECHO("EM: illegal 'tbsTimeout' value");
+                return NULL;
+                }
+            tbsInitialTimeout= toNum(getParam(config, profilerName+".tbsInitialTimeout"), &ok);
+            if (!ok) {
+                ECHO("EM: illegal 'tbsInitialTimeout' value");
+                return NULL;
             }
-        tbsInitialTimeout= toNum(getParam(config, profilerName+".tbsInitialTimeout"), &ok);
+        }
+        if (profilerType == EDGE_PROFILER_STR) {
+            pc = new EdgeProfileCollector(this, profilerName, step->jit, tbsInitialTimeout, tbsTimeout, eThreshold, bThreshold);
+        } else {
+            pc = new EBProfileCollector(this, profilerName, step->jit, ebMode, eThreshold, bThreshold, tbsInitialTimeout, tbsTimeout);
+        }
+    } else if (profilerType == VALUE_PROFILER_STR) {
+        int vpSteadySize = 4, vpClearSize = 0, vpClearInterval = 0;
+        std::string vpalgo = getParam(config, profilerName+".vpalgo");
+        ValueProfileCollector::algotypes vpMode = ValueProfileCollector::TNV_FIRST_N;
+        if (vpalgo == "TNV_DIVIDED") {
+            vpMode = ValueProfileCollector::TNV_DIVIDED;    
+        } else if (vpalgo != "TNV_FIRST_N") {
+            ECHO("EM: unsupported value profiler algotype");
+            return NULL;
+        }
+        bool ok = false;
+        vpSteadySize = toNum(getParam(config, profilerName+".vpSteadySize"), &ok);
         if (!ok) {
-            ECHO("EM: illegal 'tbsInitialTimeout' value");
+            ECHO("EM: illegal 'SteadySize' value");
             return NULL;
         }
-    }
-    if (profilerType == EDGE_PROFILER_STR) {
-        pc = new EdgeProfileCollector(this, profilerName, step->jit, tbsInitialTimeout, tbsTimeout, eThreshold, bThreshold);
-    } else {
-    pc = new EBProfileCollector(this, profilerName, step->jit, ebMode, eThreshold, bThreshold, tbsInitialTimeout, tbsTimeout);
+        if (vpMode == ValueProfileCollector::TNV_DIVIDED) {
+            vpClearSize = toNum(getParam(config, profilerName+".vpClearSize"), &ok);
+            if (!ok) {
+                ECHO("EM: illegal 'ClearSize' value");
+                return NULL;
+            }
+            vpClearInterval = toNum(getParam(config, profilerName+".vpClearInterval"), &ok);
+            if (!ok) {
+                ECHO("EM: illegal 'ClearInterval' value");
+                return NULL;
+            }
+        }
+        pc = new ValueProfileCollector(this, profilerName, step->jit, vpSteadySize, vpClearSize, vpClearInterval, vpMode);
     }
     return pc;
 }
@@ -632,54 +672,60 @@
     bool failed = false;
     for (RSteps::const_iterator it = chain->steps.begin(), end = chain->steps.end(); it!=end; ++it) {
         RStep* step = *it;
-        std::string profilerName = getParam(config, step->jitName + ".genProfile");
-        if (!profilerName.empty()) {
-            ProfileCollector* pc = createProfileCollector(profilerName, config, step);
-            if (pc == NULL) {
-                ECHO(("EM: profile configuration failed: "+ profilerName).c_str());
-                failed = true;
-                break;
-            }
-            bool genOk = step->enable_profiling(step->jit, (PC_Handle)pc, EM_JIT_PROFILE_ROLE_GEN);
-            if (genOk) {
-                collectors.push_back(pc);
-                TbsEMClient* tbsClient = pc->getTbsEmClient();
-                if (tbsClient!=NULL) {
-                    assert(tbsClient->getTimeout() != 0 && tbsClient->getTimeout()!=0);
-                    tbsClient->setNextTick(tbsClient->getInitialTimeout());
-                    tbsClients.push_back(tbsClient);
+        StringList genProfNames = getParamAsList(config, step->jitName + ".genProfile", ',', false);
+        for (StringList::const_iterator profIt = genProfNames.begin(), profEnd = genProfNames.end(); profIt!=profEnd; ++profIt) {
+            std::string profilerName = *profIt;
+            if (!profilerName.empty()) {
+                ProfileCollector* pc = createProfileCollector(profilerName, config, step);
+                if (pc == NULL) {
+                    ECHO(("EM: profile configuration failed: "+ profilerName).c_str());
+                    failed = true;
+                    break;
+                }
+                bool genOk = step->enable_profiling(step->jit, (PC_Handle)pc, EM_JIT_PROFILE_ROLE_GEN);
+                if (genOk) {
+                    collectors.push_back(pc);
+                    TbsEMClient* tbsClient = pc->getTbsEmClient();
+                    if (tbsClient!=NULL) {
+                        assert(tbsClient->getTimeout() != 0 && tbsClient->getTimeout()!=0);
+                        tbsClient->setNextTick(tbsClient->getInitialTimeout());
+                        tbsClients.push_back(tbsClient);
+                    }
+                } else {
+                    ECHO(("EM: profile generation is not supported: " + profilerName).c_str());
+                    delete pc;
+                    failed = true;
+                    break;
                 }
-            } else {
-                ECHO(("EM: profile generation is not supported: " + profilerName).c_str());
-                delete pc;
-                failed = true;
-                break;
-            }
 
+            }
         }
-        profilerName = getParam(config, step->jitName+ ".useProfile");
-        if (!profilerName.empty()) {
-            ProfileCollector* pc = getProfileCollector(profilerName);
-            bool invalidChain = true;
-            if (pc!=NULL) {
-                for(RSteps::const_iterator it2=chain->steps.begin(); it2 <it; ++it2) {
-                    RStep* prevStep = *it2;
-                    if (prevStep->jit == pc->genJit) {
-                        invalidChain = false;
-                        break;
+        StringList useProfNames = getParamAsList(config, step->jitName + ".useProfile", ',', false);
+        for (StringList::const_iterator profIt = useProfNames.begin(), profEnd = useProfNames.end(); profIt!=profEnd; ++profIt) {
+            std::string profilerName = *profIt;
+            if (!profilerName.empty()) {
+                ProfileCollector* pc = getProfileCollector(profilerName);
+                bool invalidChain = true;
+                if (pc!=NULL) {
+                    for(RSteps::const_iterator it2=chain->steps.begin(); it2 <it; ++it2) {
+                        RStep* prevStep = *it2;
+                        if (prevStep->jit == pc->genJit) {
+                            invalidChain = false;
+                            break;
+                        }
                     }
                 }
-            }
-            bool useOk = !invalidChain && (pc!=NULL && step->enable_profiling(step->jit, (PC_Handle)pc, EM_JIT_PROFILE_ROLE_USE));
-            if (useOk) {
-                pc->addUseJit(step->jit);
-            } else {
-                if (pc == NULL) {
-                    ECHO(("EM: profile not found: " + profilerName).c_str());
-                } else if (invalidChain) {
-                    ECHO(("EM: illegal use of profile: " + profilerName).c_str());
+                bool useOk = !invalidChain && (pc!=NULL && step->enable_profiling(step->jit, (PC_Handle)pc, EM_JIT_PROFILE_ROLE_USE));
+                if (useOk) {
+                    pc->addUseJit(step->jit);
                 } else {
-                    ECHO(("EM: profile usage is not supported: " + profilerName).c_str());
+                    if (pc == NULL) {
+                        ECHO(("EM: profile not found: " + profilerName).c_str());
+                    } else if (invalidChain) {
+                        ECHO(("EM: illegal use of profile: " + profilerName).c_str());
+                    } else {
+                        ECHO(("EM: profile usage is not supported: " + profilerName).c_str());
+                    }
                 }
             }
         }

Added: harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.cpp?view=auto&rev=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.cpp Wed Dec 13 06:11:10 2006
@@ -0,0 +1,280 @@
+/*
+*  Licensed to the Apache Software Foundation (ASF) under one or more
+*  contributor license agreements.  See the NOTICE file distributed with
+*  this work for additional information regarding copyright ownership.
+*  The ASF licenses this file to You under the Apache License, Version 2.0
+*  (the "License"); you may not use this file except in compliance with
+*  the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*/
+/**
+* @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>
+
+*/
+#include "NValueProfileCollector.h"
+
+#include <algorithm>
+#include <assert.h>
+#include "cxxlog.h"
+#include <sstream>
+
+#define LOG_DOMAIN "em"
+
+void ValueProfileCollector::simple_tnv_clear (struct Simple_TNV_Table * TNV_where)
+{
+    uint32 temp_index;
+    for (temp_index = 0; temp_index < TNV_clear_size; temp_index++)
+        TNV_where[temp_index].frequency = TNV_DEFAULT_CLEAR_VALUE; 
+}
+
+int32 ValueProfileCollector::min_in_tnv (struct Simple_TNV_Table * TNV_where, uint32 number_of_objects)
+{
+    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)
+            return (temp_index); 
+        if (TNV_where[temp_index].frequency < temp_min){
+            temp_min = TNV_where[temp_index].frequency;
+            temp_min_index = temp_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)
+{
+    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);
+    }
+    return (-1);
+}
+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)
+{
+    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;
+        }
+    } else if (TNV_algo_type == TNV_DIVIDED) {
+        insert_index = search_in_tnv_table(TNV_clear_part, value_to_insert, TNV_clear_size);
+        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;
+                }
+            }
+        }
+        else {
+            temp_min_index = min_in_tnv(TNV_table, TNV_steady_size);
+            if (times_met > 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 = 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)
+                {
+                    TNV_clear_part[temp_min_index].value = temp_min_value;
+                    TNV_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;
+                }
+            }
+        }
+    }
+}
+
+ValueMethodProfile* ValueProfileCollector::createProfile(Method_Handle mh, uint32 numkeys, uint32 keys[])
+{
+    hymutex_lock(profilesLock);
+    ValueMethodProfile* profile = new ValueMethodProfile(this, mh);
+    VPInstructionProfileData* vpmap = new VPInstructionProfileData[numkeys];
+    // 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;
+            }
+        }
+        (profile->ValueMap)[keys[index]] = profileData;
+    }
+    assert(profilesByMethod.find(mh) == profilesByMethod.end());
+    profilesByMethod[mh] = profile;
+    hymutex_unlock(profilesLock);
+    return profile;
+}
+
+
+
+void ValueProfileCollector::addNewValue(Method_Profile_Handle mph, uint32 instructionKey, POINTER_SIZE_INT valueToAdd)
+{
+    POINTER_SIZE_INT curr_value = valueToAdd;
+    ValueMethodProfile* vmp = ((ValueMethodProfile*)mph);
+    vmp->lockProfile();
+    VPInstructionProfileData* _temp_vp = vmp->ValueMap[instructionKey];
+    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 ( TNV_algo_type == TNV_DIVIDED){
+        if (*profile_tick == clear_interval){
+            *profile_tick = 0;
+            simple_tnv_clear(TNV_clear_part);
+        }
+        (*profile_tick)++;
+    }
+    if (curr_value == *last_value){
+        (*num_times_profiled)++;
+    }
+    else {
+        *num_times_profiled = 1;
+        insert_into_tnv_table (TNV_steady_part, TNV_clear_part, valueToAdd, *num_times_profiled);
+        *last_value = curr_value;
+    }
+    vmp->unlockProfile();
+}
+
+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++)
+        if (TNV_where->frequency > temp_max_frequency){
+            temp_max_frequency = TNV_where->frequency;
+            max_value = TNV_where->value;
+        }
+    return (max_value);
+}
+
+POINTER_SIZE_INT ValueProfileCollector::getResult(Method_Profile_Handle mph, uint32 instructionKey)
+{
+    ValueMethodProfile* vmp = ((ValueMethodProfile*)mph);
+    vmp->lockProfile();
+    VPInstructionProfileData* _temp_vp = vmp->ValueMap[instructionKey];
+    POINTER_SIZE_INT result = (_temp_vp == NULL) ? 0 : find_max(_temp_vp->TNV_Table);
+    vmp->unlockProfile();
+    return result; 
+}
+
+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)
+
+{
+    hymutex_create(&profilesLock, TM_MUTEX_NESTED);
+    catName = std::string(LOG_DOMAIN) + ".profiler." + name;
+    loggingEnabled =  is_info_enabled(LOG_DOMAIN) ||  is_info_enabled(catName.c_str());
+    if (loggingEnabled) {
+        std::ostringstream msg;
+        msg<< "EM: value profiler intialized: "<<name;
+        INFO2(catName.c_str(), msg.str().c_str());
+    }
+}
+
+
+ValueProfileCollector::~ValueProfileCollector()
+{
+    ValueProfilesMap::iterator it;
+    for( it = profilesByMethod.begin(); it != profilesByMethod.end(); it++ ){
+        ValueMethodProfile* profile = it->second;
+        delete profile;
+    }
+    hymutex_destroy(profilesLock);
+}
+
+ValueMethodProfile::ValueMethodProfile(ValueProfileCollector* pc, Method_Handle mh)
+    : MethodProfile(pc, mh)
+{
+    hymutex_create(&lock, TM_MUTEX_DEFAULT);
+}
+
+ValueMethodProfile::~ValueMethodProfile()
+{
+    hymutex_destroy(lock);
+}
+
+MethodProfile* ValueProfileCollector::getMethodProfile(Method_Handle mh) const
+{
+    ValueProfilesMap::const_iterator it = profilesByMethod.find(mh);
+    if (it == profilesByMethod.end()) {
+        return NULL;
+    }
+    return it->second;
+}
+
+
+
+POINTER_SIZE_INT value_profiler_get_top_value (Method_Profile_Handle mph, uint32 instructionKey)
+{
+    assert(mph != NULL);
+    MethodProfile* mp = (MethodProfile*)mph;
+    assert(mp->pc->type == EM_PCTYPE_VALUE);
+    ValueMethodProfile* vmp = (ValueMethodProfile*)mp;
+    return ((ValueProfileCollector*)(vmp->pc))->getResult(mph, instructionKey);
+}
+void value_profiler_add_value (Method_Profile_Handle mph, uint32 instructionKey, POINTER_SIZE_INT valueToAdd)
+{
+    assert(mph != NULL);
+    MethodProfile* mp = (MethodProfile*)mph;
+    assert(mp->pc->type == EM_PCTYPE_VALUE);
+    ValueMethodProfile* vmp = (ValueMethodProfile*)mp;
+    return ((ValueProfileCollector*)(vmp->pc))->addNewValue(mph, instructionKey, valueToAdd);
+}
+Method_Profile_Handle value_profiler_create_profile(PC_Handle pch, Method_Handle mh, uint32 numkeys, uint32 keys[])
+{
+    assert(pch!=NULL);
+    ProfileCollector* pc = (ProfileCollector*)pch;
+    assert(pc->type == EM_PCTYPE_VALUE);
+    ValueMethodProfile* profile = ((ValueProfileCollector*)pc)->createProfile(mh, numkeys, keys);
+    return (Method_Profile_Handle)profile;
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.h?view=auto&rev=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.h Wed Dec 13 06:11:10 2006
@@ -0,0 +1,107 @@
+/*
+*  Licensed to the Apache Software Foundation (ASF) under one or more
+*  contributor license agreements.  See the NOTICE file distributed with
+*  this work for additional information regarding copyright ownership.
+*  The ASF licenses this file to You under the Apache License, Version 2.0
+*  (the "License"); you may not use this file except in compliance with
+*  the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*/
+/**
+* @author Yuri Kashnikov
+* @version $Revision$
+*/
+/*
+        The idea of advanced Top-N-Value (with steady and clear parts, and clear interval)
+        from <"Value profilling and optimization", B.Calder, P.Feller, Journal of Instruction-Level Parallelism, 1999>
+
+*/
+#ifndef _VALUE_PROFILE_COLLECTOR_H_
+#define _VALUE_PROFILE_COLLECTOR_H_
+
+#include "DrlProfileCollectionFramework.h"
+#include "open/vm_util.h"
+
+#include <map>
+
+#define TNV_DEFAULT_CLEAR_VALUE 0
+
+class ValueMethodProfile;
+class VPInstructionProfileData;
+
+struct Simple_TNV_Table
+{
+    POINTER_SIZE_INT value;
+    uint32 frequency;
+};
+
+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;
+    struct Simple_TNV_Table * TNV_clear_part;
+    struct Simple_TNV_Table * TNV_steady_part;
+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[]);
+    POINTER_SIZE_INT getResult(Method_Profile_Handle mph, uint32 instructionKey);
+    void addNewValue(Method_Profile_Handle mph, uint32 instructionKey, POINTER_SIZE_INT valueToAdd);
+private:
+    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);
+    std::string catName;
+    bool   loggingEnabled;
+    typedef std::map<Method_Handle, ValueMethodProfile*> ValueProfilesMap;
+    ValueProfilesMap profilesByMethod;
+    hymutex_t profilesLock;
+};
+
+class VPInstructionProfileData
+{
+public:
+    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) {}
+public:
+    POINTER_SIZE_INT last_value;
+    uint32 num_times_profiled;
+    uint32 profile_tick;
+};
+
+class ValueMethodProfile : public MethodProfile {
+public:
+    std::map<uint32, VPInstructionProfileData*> ValueMap;
+public:
+    ValueMethodProfile(ValueProfileCollector* pc, Method_Handle mh);
+    ~ValueMethodProfile();
+    void lockProfile() {hymutex_lock(lock);}
+    void unlockProfile() {hymutex_unlock(lock);}
+private:
+    hymutex_t lock;
+};
+
+Method_Profile_Handle value_profiler_create_profile(PC_Handle ph, Method_Handle mh, uint32 instructionKey, ValueProfileCollector::algotypes, uint32 steadySize, uint32 clearSize, uint32 clearInterval);
+
+POINTER_SIZE_INT value_profiler_get_top_value (Method_Profile_Handle mph, uint32 instructionKey);
+void value_profiler_add_value (Method_Profile_Handle mph, uint32 instructionKey, POINTER_SIZE_INT valueToAdd);
+Method_Profile_Handle value_profiler_create_profile(PC_Handle pch, Method_Handle mh, uint32 numkeys, uint32 keys[]);
+
+#endif

Propchange: harmony/enhanced/drlvm/trunk/vm/em/src/NValueProfileCollector.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/vm/include/open/em_profile_access.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/em_profile_access.h?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/em_profile_access.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/em_profile_access.h Wed Dec 13 06:11:10 2006
@@ -43,10 +43,15 @@
       *  Collects profile for method entry and 
       *  all edges in IR Control Flow Graph
       */
-    EM_PCTYPE_EDGE=2
+    EM_PCTYPE_EDGE=2,
+    /** Value profiler
+      * Collects profile for each given instruction
+      */
+    EM_PCTYPE_VALUE=3
+    
 };
 
-/** A EM interface used to access to profile collectos*/
+/** A EM interface used to access to profile collectors*/
 typedef struct EM_ProfileAccessInterface {
 
     /** Request profile collector typ for specified profile collector handle 
@@ -163,7 +168,7 @@
     /** Return profile checksum*/
     uint32 (*edge_profiler_get_checksum)(Method_Profile_Handle mph);
 
-    /** Return the address of counter assosiated with key*/
+    /** Return the address of counter associated with key*/
     void* (*edge_profiler_get_counter_addr)(Method_Profile_Handle mph, uint32 key);
 
     /** Return the address of entry counter*/
@@ -176,6 +181,28 @@
     /** Return the edge threshold for profile collector
       */
     uint32 (*edge_profiler_get_backedge_threshold)(PC_Handle pch);
+    // Value profiler interface
+
+    /** Create an value profile for a method. 
+    * Only one profile per method can be created for a single 
+    * profile collector instance 
+    * @param pch              - value profile collector handle
+    * @param mh               - method handle to create profile for
+    * @param numKeys          - number of instructions to be profiled
+    * @param keys             - the keys, or numbers, will be associated with 
+    *                           each instruction. The key must be used to access to
+    *                           instruction value
+    */
+    Method_Profile_Handle (*value_profiler_create_profile) (PC_Handle pch, Method_Handle mh, uint32 numKeys, uint32* keys);
+    
+    /** Update frequency or insert the new value of given instruction.
+      */
+    void (*value_profiler_add_value)(Method_Profile_Handle mph, uint32 instructionKey, POINTER_SIZE_INT valueToAdd);
+    
+    /** Return the maximum value(by frequency) of give instruction.
+      */
+    POINTER_SIZE_INT (*value_profiler_get_top_value) (Method_Profile_Handle mph, uint32 instructionKey);
+
 
 
 } EM_ProfileAccessInterface;

Modified: harmony/enhanced/drlvm/trunk/vm/include/open/vm.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/vm.h?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/vm.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/vm.h Wed Dec 13 06:11:10 2006
@@ -229,6 +229,9 @@
 // checking.
 VMEXPORT int vtable_get_super_array_offset();
 
+// Returns class handle given object's VTable_Handle.
+VMEXPORT Class_Handle vtable_get_class(VTable_Handle vh);
+
 // Returns the number of superclass hierarchy elements that are
 // stored within the vtable.  This is for use with fast type checking.
 VMEXPORT int vm_max_fast_instanceof_depth();

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf Wed Dec 13 06:11:10 2006
@@ -32,8 +32,11 @@
 EDGE_PROF.tbsTimeout=10
 EDGE_PROF.tbsInitialTimeout=0
 
-SD1_OPT.genProfile=EDGE_PROF
-SD2_OPT.useProfile=EDGE_PROF
+VALUE_PROF.profilerType=VALUE_PROFILER
+VALUE_PROF.vpalgo=TNV_FIRST_N
+VALUE_PROF.vpSteadySize=4
+SD1_OPT.genProfile=EDGE_PROF,VALUE_PROF
+SD2_OPT.useProfile=EDGE_PROF,VALUE_PROF
 
 #options for JIT
 
@@ -42,7 +45,7 @@
 
 -XDjit.SD1_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
 
--XDjit.SD1_OPT.path.optimizer=ssa,simplify,dce,uce,edge_instrument,dessa,statprof,markglobals
+-XDjit.SD1_OPT.path.optimizer=ssa,simplify,dce,uce,vp_instrument,edge_instrument,dessa,statprof,markglobals
 -XDjit.SD1_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l-,early_prop-,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce-,stack,break-,iprof-,emitter!,si_insts,gcmap,info,unlock_method
 -XDjit.SD1_OPT.path.dce1=cg_dce
 -XDjit.SD1_OPT.path.dce2=cg_dce

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf Wed Dec 13 06:11:10 2006
@@ -32,8 +32,11 @@
 EDGE_PROF.tbsTimeout=10
 EDGE_PROF.tbsInitialTimeout=0
 
-SD1_OPT.genProfile=EDGE_PROF
-SD2_OPT.useProfile=EDGE_PROF
+VALUE_PROF.profilerType=VALUE_PROFILER
+VALUE_PROF.vpalgo=TNV_FIRST_N
+VALUE_PROF.vpSteadySize=4
+SD1_OPT.genProfile=EDGE_PROF,VALUE_PROF
+SD2_OPT.useProfile=EDGE_PROF,VALUE_PROF
 
 #options for JIT
 
@@ -42,7 +45,7 @@
 
 -XDjit.SD1_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
 
--XDjit.SD1_OPT.path.optimizer=ssa,simplify,dce,uce,edge_instrument,dessa,statprof,markglobals
+-XDjit.SD1_OPT.path.optimizer=ssa,simplify,dce,uce,vp_instrument,edge_instrument,dessa,statprof,markglobals
 -XDjit.SD1_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
 -XDjit.SD1_OPT.path.dce1=cg_dce
 -XDjit.SD1_OPT.path.dce2=cg_dce

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/CodeGenIntfc.h Wed Dec 13 06:11:10 2006
@@ -169,7 +169,8 @@
         PseudoCanThrow,
         SaveThisState,
         ReadThisState,
-        LockedCompareAndExchange
+        LockedCompareAndExchange,
+        AddValueProfileValue
     };
 };
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32IRManager.cpp Wed Dec 13 06:11:10 2006
@@ -23,6 +23,7 @@
 #include "Ia32Encoder.h"
 #include "Ia32Printer.h"
 #include "Log.h"
+#include "EMInterface.h"
 #include "Ia32Printer.h"
 #include "Ia32CodeGenerator.h"
 #include "Dominator.h"
@@ -1987,6 +1988,14 @@
         case Opnd::RuntimeInfo::Kind_ConstantAreaItem:
             /** The value of the operand is address of constant pool item  ((ConstantPoolItem*)[0])->getAddress() */
             value=(POINTER_SIZE_INT)((ConstantAreaItem*)info->getValue(0))->getAddress();
+            break;
+        case Opnd::RuntimeInfo::Kind_EM_ProfileAccessInterface:
+            /** The value of the operand is a pointer to the EM_ProfileAccessInterface */
+            value=(POINTER_SIZE_INT)(getProfilingInterface()->getEMProfileAccessInterface());
+            break;
+        case Opnd::RuntimeInfo::Kind_Method_Value_Profile_Handle:
+            /** The value of the operand is Method_Profile_Handle for the value profile of the compiled method */
+            value=(POINTER_SIZE_INT)(getProfilingInterface()->getMethodProfileHandle(ProfileType_Value, getMethodDesc()));
             break;
         default:
             assert(0);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Inst.h Wed Dec 13 06:11:10 2006
@@ -149,6 +149,11 @@
             /** The value of the operand is address of constant pool item  ((ConstantPoolItem*)[0])->getAddress() */
             Kind_ConstantAreaItem=0x80,
 
+            /** The value of the operand is a pointer to the EM_ProfileAccessInterface */
+            Kind_EM_ProfileAccessInterface,
+            /** The value of the operand is Method_Profile_Handle for the value profile of the compiled method */
+            Kind_Method_Value_Profile_Handle,
+
             /** more ... */
         };
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp Wed Dec 13 06:11:10 2006
@@ -29,6 +29,9 @@
 #include "EMInterface.h"
 #include "DrlVMInterface.h"
 #include "Opcode.h"
+#include "open/em_profile_access.h"
+#include "open/vm.h"
+
 
 #include <float.h>
 #include <math.h>
@@ -180,6 +183,12 @@
     }
 }
 
+void __stdcall add_value_profile_value(EM_ProfileAccessInterface* profileAccessInterface, Method_Profile_Handle mpHandle, uint32 index, POINTER_SIZE_INT value) stdcall__;
+void __stdcall add_value_profile_value(EM_ProfileAccessInterface* profileAccessInterface, Method_Profile_Handle mpHandle, uint32 index, POINTER_SIZE_INT value) {
+    profileAccessInterface->value_profiler_add_value(mpHandle, index, value);
+}
+
+
 //_______________________________________________________________________________________________________________
 uint32 InstCodeSelector::_tauUnsafe;
 
@@ -199,6 +208,7 @@
     irManager.registerInternalHelperInfo("remF4", IRManager::InternalHelperInfo((void*)&remF4,&CallingConvention_STDCALL));
 
     irManager.registerInternalHelperInfo("initialize_array", IRManager::InternalHelperInfo((void*)&initialize_array,&CallingConvention_STDCALL));
+    irManager.registerInternalHelperInfo("add_value_profile_value", IRManager::InternalHelperInfo((void*)&add_value_profile_value,&CallingConvention_STDCALL));
 }
 
 //_______________________________________________________________________________________________________________
@@ -2809,6 +2819,16 @@
         //save the result
         appendInsts(irManager.newInst(Mnemonic_MOV, dstOpnd, irManager.newImmOpnd(typeManager.getInt32Type(), 0)));
         appendInsts(irManager.newInst(Mnemonic_SETZ, dstOpnd));
+        break;
+    }
+    case AddValueProfileValue:
+    {
+        assert(numArgs == 2);
+        Opnd* empiOpnd = irManager.newImmOpnd(getRuntimeIdType(), Opnd::RuntimeInfo::Kind_EM_ProfileAccessInterface);
+        Opnd* mphOpnd = irManager.newImmOpnd(getRuntimeIdType(), Opnd::RuntimeInfo::Kind_Method_Value_Profile_Handle);
+        const uint32 nArgs = 4;
+        Opnd* newArgs[4] = {empiOpnd, mphOpnd, ((Opnd **)args)[0], ((Opnd **)args)[1]};
+        appendInsts(irManager.newInternalRuntimeHelperCallInst("add_value_profile_value", nArgs, newArgs, dstOpnd));
         break;
     }
     default:

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Printer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Printer.cpp?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Printer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32Printer.cpp Wed Dec 13 06:11:10 2006
@@ -511,6 +511,16 @@
             os<<"vtso:"; 
             os<<md->getParentType()->getName()<<"."<<md->getName();
             }break;
+        case Opnd::RuntimeInfo::Kind_EM_ProfileAccessInterface:
+            /** The value of the operand is a pointer to the EM_ProfileAccessInterface */
+            {
+                os<<"em_pi"; 
+            }break;
+        case Opnd::RuntimeInfo::Kind_Method_Value_Profile_Handle:
+            /** The value of the operand is Method_Profile_Handle for the value profile of the compiled method */
+            {
+                os<<"mvph"; 
+            }break;
         default:
             assert(0);
     }

Added: harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp?view=auto&rev=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/dynopt/ValueProfiler.cpp Wed Dec 13 06:11:10 2006
@@ -0,0 +1,143 @@
+/*
+*  Licensed to the Apache Software Foundation (ASF) under one or more
+*  contributor license agreements.  See the NOTICE file distributed with
+*  this work for additional information regarding copyright ownership.
+*  The ASF licenses this file to You under the Apache License, Version 2.0
+*  (the "License"); you may not use this file except in compliance with
+*  the License.  You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+*  Unless required by applicable law or agreed to in writing, software
+*  distributed under the License is distributed on an "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*  See the License for the specific language governing permissions and
+*  limitations under the License.
+*/
+/* COPYRIGHT_NOTICE */
+
+/**
+* @author Pavel Ozhdikhin
+* @version $Revision$
+*/
+
+
+#include "Jitrino.h"
+#include "optpass.h"
+#include "devirtualizer.h"
+#include "irmanager.h"
+#include "Inst.h"
+#include "FlowGraph.h"
+#include "EMInterface.h"
+
+namespace Jitrino {
+
+DEFINE_SESSION_ACTION(ValueProfilerInstrumentationPass, vp_instrument, "Perform value profiler instrumentation pass")
+
+void ValueProfilerInstrumentationPass::_run(IRManager& irm)
+{
+    // Currently value profile is used by interface devirtualization only
+    const OptimizerFlags& optFlags = irm.getOptimizerFlags();
+    if (!optFlags.devirt_intf_methods) return;
+
+    ControlFlowGraph& flowGraph = irm.getFlowGraph();
+    MemoryManager mm( 1024, "Value Profiler Instrumentation Pass");
+    MethodDesc& md = irm.getMethodDesc();
+    InstFactory& instFactory = irm.getInstFactory();
+    OpndManager& opndManager = irm.getOpndManager();
+    TypeManager& typeManager = irm.getTypeManager();
+    StlVector<uint32> counterKeys(mm);
+    bool debug = Log::isEnabled();
+    uint32 key = 0;
+
+    StlVector<Node*> nodes(mm);
+    flowGraph.getNodesPostOrder(nodes); 
+    for (StlVector<Node*>::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) {
+        Node* node = *it;
+        if(node->isBlockNode()) {
+            Inst* lastInst = (Inst*)node->getLastInst();
+            MethodInst* methodInst = NULL;
+            Opnd* base = NULL;
+            Opnd* tauNullChecked = NULL;
+            Opnd* tauTypesChecked = NULL;
+            uint32 argOffset = 0;
+            if(Devirtualizer::isGuardableVirtualCall(lastInst, methodInst, base, tauNullChecked, tauTypesChecked, argOffset)) {
+                assert(methodInst && base && tauNullChecked && tauTypesChecked && argOffset);
+                assert(base->getType()->isObject());
+
+                CallInst* call = lastInst->asCallInst();
+                assert(call != NULL);
+                
+                if (debug) {
+                    Log::out() << "Indirect call detected. \n\tNode: ";
+                    FlowGraph::printLabel(Log::out(), node);
+                    Log::out() << "\n\tCall inst: ";
+                    call->print(Log::out());
+                    Log::out() << std::endl;
+                }
+
+                Inst* vtableInst = methodInst->getSrc(0)->getInst();
+                Opcode vtableInstOpcode = vtableInst->getOpcode();
+                if (vtableInstOpcode == Op_TauLdVTableAddr) {
+                    // That is what we are looking for
+                    if (debug) {
+                        Log::out() << "\tFound ldVTable instruction to instrument: ";
+                        vtableInst->print(Log::out());
+                        Log::out() << std::endl;
+                    }
+                    // Don't profile virtual calls so far
+                    continue;
+                } else if (vtableInstOpcode == Op_TauLdIntfcVTableAddr) {
+                    // Need to generate VTable loading
+                    Opnd* vTable = opndManager.createSsaTmpOpnd(typeManager.getVTablePtrType(typeManager.getSystemObjectType()));
+                    Inst* ldVtableInst = instFactory.makeTauLdVTableAddr(vTable, base, tauNullChecked);
+                    ((CFGInst *)ldVtableInst)->insertBefore(vtableInst);
+                    vtableInst = ldVtableInst;
+                    if (debug) {
+                        Log::out() << "\tInserted ldVTable instruction to instrument: ";
+                        ldVtableInst->print(Log::out());
+                        Log::out() << std::endl;
+                    }
+                } else {
+                    assert(0);
+                }
+                VectorHandler* bc2HIRMapHandler = new VectorHandler(bcOffset2HIRHandlerName, &md);
+                uint64 callInstId = (uint64)lastInst->getId();
+                key = (uint32)bc2HIRMapHandler->getVectorEntry(callInstId);
+                assert(key != 0);
+                if (debug) {
+                    Log::out() << "Use call instruction bcOffset = " << (int32)key << std::endl;
+                }
+
+                Opnd* indexOpnd = opndManager.createSsaTmpOpnd(typeManager.getInt32Type());
+                Inst* loadIndexInst = instFactory.makeLdConst(indexOpnd, (int32)key);
+                counterKeys.push_back(key);
+                Opnd* valueOpnd = vtableInst->getDst();
+                const uint32 numArgs = 2;
+                Opnd* args[numArgs] = {indexOpnd, valueOpnd};
+                Inst* addValueInst = instFactory.makeJitHelperCall(opndManager.getNullOpnd(), AddValueProfileValue, numArgs, args);
+                ((CFGInst *)loadIndexInst)->insertAfter(vtableInst);
+                ((CFGInst *)addValueInst)->insertAfter(loadIndexInst);
+            }
+        }
+    }
+
+    uint32 cc_size = counterKeys.size();
+    if (cc_size == 0) return;
+
+    irm.getCompilationInterface().lockMethodData();
+    
+    ProfilingInterface* pi = irm.getProfilingInterface();
+    if (!pi->hasMethodProfile(ProfileType_Value, md, JITProfilingRole_GEN)) {
+        pi->createValueMethodProfile(mm , md,  cc_size,  (uint32*)&counterKeys.front());
+    }
+
+    irm.getCompilationInterface().unlockMethodData();
+
+    if (debug) {
+        Log::out() << std::endl << "ValuePC:: instrumented, nCounters = " << cc_size << std::endl;
+    }
+
+}
+
+} //namespace

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeGenerator.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeGenerator.cpp?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeGenerator.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/CodeGenerator.cpp Wed Dec 13 06:11:10 2006
@@ -442,6 +442,7 @@
         case SaveThisState: return JitHelperCallOp::SaveThisState;
         case ReadThisState: return JitHelperCallOp::ReadThisState;
         case LockedCompareAndExchange: return JitHelperCallOp::LockedCompareAndExchange;
+        case AddValueProfileValue: return JitHelperCallOp::AddValueProfileValue;
         }
         assert(0);
         return JitHelperCallOp::InitializeArray; // to keep compiler quiet

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp Wed Dec 13 06:11:10 2006
@@ -324,7 +324,7 @@
         uint64 instID = inst->getId();
         if (irBuilderFlags.fullBcMap) {
             bc2HIRmapHandler->setVectorEntry(instID, offset);
-        } else if (inst->asMethodCallInst()) {
+        } else if (inst->asMethodCallInst() || inst->asCallInst()) {
             bc2HIRmapHandler->setVectorEntry(instID, offset);
         }
 //#ifdef _DEBUG

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp Wed Dec 13 06:11:10 2006
@@ -466,6 +466,8 @@
         os << "ReadThisState"; break;
     case LockedCompareAndExchange:
         os << "LockedCmpExchange"; break;
+    case AddValueProfileValue:
+        os << "AddValueProfileValue"; break;
     default:
         assert(0); break;
         }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h Wed Dec 13 06:11:10 2006
@@ -274,7 +274,8 @@
     PseudoCanThrow,
     SaveThisState, //todo: replace with GetTLS + offset sequence
     ReadThisState, //todo: replace with GetTLS + offset sequence
-    LockedCompareAndExchange
+    LockedCompareAndExchange,
+    AddValueProfileValue
 };
 
 enum Opcode {

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp Wed Dec 13 06:11:10 2006
@@ -26,6 +26,7 @@
 #include "Dominator.h"
 #include "inliner.h"
 #include "EMInterface.h"
+#include "open/vm.h"
 
 namespace Jitrino {
 
@@ -59,6 +60,7 @@
     _devirtSkipExceptionPath = optFlags.devirt_skip_exception_path;
     _devirtBlockHotnessMultiplier = optFlags.devirt_block_hotness_multiplier;
     _devirtSkipJLObjectMethods = optFlags.devirt_skip_object_methods;
+    _devirtInterfaceMethods = optFlags.devirt_intf_methods;
 
     _directCallPercent = optFlags.unguard_dcall_percent;
     _directCallPercientOfEntry = optFlags.unguard_dcall_percent_of_entry;
@@ -73,6 +75,8 @@
     Opcode opcode = inst->getOpcode();
     if(opcode == Op_TauVirtualCall) { 
         // Virtual function call
+        // We don't use this instruction any more - indirect calls are used instead
+        assert(0);
         assert(inst->getNumSrcOperands() >= 3);
         MethodCallInst *methodCallInst = inst->asMethodCallInst();
         assert(methodCallInst != NULL);
@@ -168,12 +172,12 @@
 
 
 void
-Devirtualizer::genGuardedDirectCall(IRManager &regionIRM, Node* node, Inst* call, MethodDesc* methodDesc, Opnd *tauNullChecked, Opnd *tauTypesChecked, uint32 argOffset) {
+Devirtualizer::genGuardedDirectCall(IRManager &regionIRM, Node* node, Inst* call, MethodDesc* methodDesc, ObjectType* objectType, Opnd *tauNullChecked, Opnd *tauTypesChecked, uint32 argOffset) {
     ControlFlowGraph &regionFG = regionIRM.getFlowGraph();
     assert(!methodDesc->isStatic());
     assert(call == node->getLastInst());
 
-    Log::out() << "Generating guarded direct call to " << methodDesc->getParentType()->getName() 
+    Log::out() << "Generating guarded direct call to " << objectType->getName()
         << "." << methodDesc->getName() << ::std::endl;
     Log::out() << "Guarded call bytecode size=" << (int) methodDesc->getByteCodeSize() << ::std::endl;
 
@@ -252,6 +256,13 @@
                                                              ldSlot->getMethodDesc());
         virtualCallBlock->appendInst(ldSlot2);
         icall->setSrc(0, funPtr2);
+        // Move ldInterfaceVTable to the virtual call block
+        Inst* ldVTable = vtable->getInst();
+        if (ldVTable->getOpcode() == Op_TauLdIntfcVTableAddr) {
+            ldVTable->unlink();
+            ldSlot->unlink();
+            ldVTable->insertBefore(ldSlot2);
+        }
     }
     virtualCallBlock->appendInst(virtualCall);
 
@@ -320,14 +331,13 @@
     //
     Opnd* base = directCall->getSrc(2); // skip over taus
     assert(base->getType()->isObject());
-    ObjectType* baseType = (ObjectType*) base->getType();
-    Opnd* dynamicVTableAddr = _opndManager.createSsaTmpOpnd(_typeManager.getVTablePtrType(baseType));
-    Opnd* staticVTableAddr = _opndManager.createSsaTmpOpnd(_typeManager.getVTablePtrType(baseType));
-    guard->appendInst(_instFactory.makeTauLdVTableAddr(dynamicVTableAddr, base,
-                                                  tauNullChecked));
-    guard->appendInst(_instFactory.makeGetVTableAddr(staticVTableAddr, baseType));
+    assert(base->getType()->isInterface() || (((ObjectType*) base->getType()) == objectType));
+    Opnd* dynamicVTableAddr = _opndManager.createSsaTmpOpnd(_typeManager.getVTablePtrType(objectType));
+    Opnd* staticVTableAddr = _opndManager.createSsaTmpOpnd(_typeManager.getVTablePtrType(objectType));
+    guard->appendInst(_instFactory.makeTauLdVTableAddr(dynamicVTableAddr, base, tauNullChecked));
+    guard->appendInst(_instFactory.makeGetVTableAddr(staticVTableAddr, objectType));
     guard->appendInst(_instFactory.makeBranch(Cmp_EQ, Type::VTablePtr, dynamicVTableAddr, staticVTableAddr, (LabelInst*)directCallBlock->getFirstInst()));
-}
+ }
 
 bool
 Devirtualizer::doGuard(IRManager& irm, Node* node, MethodDesc& methodDesc) {
@@ -375,8 +385,7 @@
         Opnd* tauNullChecked = 0;
         Opnd* tauTypesChecked = 0;
         uint32 argOffset = 0;
-        if(isGuardableVirtualCall(last, methodInst, base, tauNullChecked, tauTypesChecked,
-                                  argOffset)) {
+        if(isGuardableVirtualCall(last, methodInst, base, tauNullChecked, tauTypesChecked, argOffset)) {
             assert(methodInst && base && tauNullChecked && tauTypesChecked && argOffset);
 
             assert(base->getType()->isObject());
@@ -384,34 +393,79 @@
             MethodDesc* origMethodDesc = methodInst->getMethodDesc();
             
             // If base type is concrete, consider an explicit guarded test against it
-            if(!baseType->isNullObject() && (!baseType->isAbstract() || baseType->isArray()) && !baseType->isInterface()) {
+            if(!baseType->isNullObject() && ((_devirtInterfaceMethods && baseType->isInterface()) || !baseType->isAbstract() || baseType->isArray())) {
                 MethodDesc* candidateMeth = NULL;
                 int candidateExecCount = 0;
                 CompilationContext* cc = regionIRM.getCompilationContext();
                 bool profileSelection = _devirtUseCHAWithProfile && cc->hasDynamicProfileToUse();
-                if (profileSelection) {
+                if (baseType->isInterface()) {
+                    assert(regionIRM.getCompilationInterface().isBCMapInfoRequired());
+                    MethodDesc& methDesc = regionIRM.getMethodDesc();
+
+                    Log::out() << std::endl << "Devirtualizing interface call in the method :" << std::endl << "\t";
+                    methDesc.printFullName(Log::out());
+                    Log::out() << std::endl << "call to the method: " << std::endl << "\t";
+                    origMethodDesc->printFullName(Log::out());
+                    Log::out() << std::endl;
+
+                    ProfilingInterface* pi = cc->getProfilingInterface();
+                    // Don't devirtualize if there is no value profile
+                    if (!pi->hasMethodProfile(ProfileType_Value, methDesc)) return;
+                    ValueMethodProfile* mp = pi->getValueMethodProfile(regionIRM.getMemoryManager(), methDesc);
+                    MethodDesc* rootMethodDesc = regionIRM.getCompilationInterface().getMethodToCompile();
+
+                    // Get bytecode offset of the call
+                    VectorHandler* bc2HIRMapHandler = new VectorHandler(bcOffset2HIRHandlerName, rootMethodDesc);
+                    uint64 callInstId = (uint64)last->getId();
+                    uint32 bcOffset = (uint32)bc2HIRMapHandler->getVectorEntry(callInstId);
+                    assert(bcOffset != 0);
+                    Log::out() << "Call instruction bcOffset = " << (int32)bcOffset << std::endl;
+
+                    // Get profiled vtable value
+                    POINTER_SIZE_INT vtHandle = mp->getTopValue(bcOffset);
+                    if (vtHandle == 0) {
+                        // Do not devirtualize - there were no real calls here
+                        return;
+                    }
+                    Log::out() << "Valued type: " << class_get_name(vtable_get_class((VTable_Handle)vtHandle)) << std::endl;
+
+                    // get desired MethodDesc object
+                    assert(vtHandle != 0);
+                    ObjectType* clssObjectType = _typeManager.getObjectType(vtable_get_class((VTable_Handle)vtHandle));
+                    candidateMeth = regionIRM.getCompilationInterface().resolveMethod(clssObjectType, origMethodDesc->getName(), origMethodDesc->getSignatureString());
+                    Log::out() << "candidateMeth: "<< std::endl;
+                    candidateMeth->printFullName(Log::out());
+                    Log::out() << std::endl;
+ 
+                    if(doGuard(regionIRM, node, *candidateMeth )) {
+                        Log::out() << "Guard call to " << baseType->getName() << "::" << candidateMeth->getName() << std::endl;
+                        genGuardedDirectCall(regionIRM, node, last, candidateMeth, clssObjectType, tauNullChecked, tauTypesChecked, argOffset);
+                        Log::out() << "Done guarding call to " << baseType->getName() << "::" << candidateMeth->getName() << std::endl;
+                    } else {
+                        Log::out() << "Don't guard call to " << baseType->getName() << "::" << origMethodDesc->getName() << std::endl;
+                    }
+                    
+                    return;
+
+                } else if (profileSelection) {
                     ClassHierarchyMethodIterator* iterator = regionIRM.getCompilationInterface().getClassHierarchyMethodIterator(baseType, origMethodDesc);
                     if(iterator) {
-                        if (profileSelection) {
-                            ProfilingInterface* pi = cc->getProfilingInterface();
-                            while (iterator->hasNext()) {
-                                MethodDesc* tmpMeth = iterator->getNext();
-                                int tmpCount = pi->getProfileMethodCount(*tmpMeth);
-                                Log::out() << "CHA devirt profile-selection" << baseType->getName() << "::" << tmpMeth->getName() << tmpMeth->getSignatureString() 
-                                    << " exec_count=" << tmpCount << std::endl;
-                                if (candidateExecCount < tmpCount) {
-                                    candidateExecCount = tmpCount;
-                                    candidateMeth = tmpMeth;
-                                }
+                        ProfilingInterface* pi = cc->getProfilingInterface();
+                        while (iterator->hasNext()) {
+                            MethodDesc* tmpMeth = iterator->getNext();
+                            int tmpCount = pi->getProfileMethodCount(*tmpMeth);
+                            Log::out() << "CHA devirt profile-selection: " << baseType->getName() << "::" << tmpMeth->getName() << tmpMeth->getSignatureString() 
+                                << " exec_count=" << tmpCount << std::endl;
+                            if (candidateExecCount < tmpCount) {
+                                candidateExecCount = tmpCount;
+                                candidateMeth = tmpMeth;
                             }
                         }
                     }
                 } else {
                     NamedType* methodType = origMethodDesc->getParentType();
                     if (_typeManager.isSubClassOf(baseType, methodType)) {
-                        // only bother if the baseType has the given method
-                        // for an interface call, this may not be the case
-                        candidateMeth = regionIRM.getCompilationInterface().getOverriddenMethod(baseType, origMethodDesc);
+                         candidateMeth = regionIRM.getCompilationInterface().getOverriddenMethod(baseType, origMethodDesc);
                     }
                 }
                 if (candidateMeth) {
@@ -423,7 +477,7 @@
                     if(doGuard(regionIRM, node, *candidateMeth )) {
                         Log::out() << "Guard call to " << baseType->getName() << "::" << candidateMeth->getName() 
                             <<" CHAWithProfile="<<(profileSelection ? "true":"false")<<" execCnt="<<candidateExecCount<< std::endl;
-                        genGuardedDirectCall(regionIRM, node, last, candidateMeth, tauNullChecked, tauTypesChecked, argOffset);
+                        genGuardedDirectCall(regionIRM, node, last, candidateMeth, baseType, tauNullChecked, tauTypesChecked, argOffset);
                         Log::out() << "Done guarding call to " << baseType->getName() << "::" << candidateMeth->getName() << std::endl;
                     } else {
                         Log::out() << "Don't guard call to " << baseType->getName() << "::" << origMethodDesc->getName() << std::endl;

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.h Wed Dec 13 06:11:10 2006
@@ -37,12 +37,13 @@
 
     void unguardCallsInRegion(IRManager& irm);
 
+    static bool isGuardableVirtualCall(Inst* inst, MethodInst*& methodInst, Opnd*& base, 
+        Opnd* & tauNullChecked, Opnd*&tauTypesChecked, uint32 &argOffset);
+
+
 private:
     void guardCallsInBlock(IRManager& irm, Node* node);
-    void genGuardedDirectCall(IRManager& irm, Node* node, Inst* call, MethodDesc* methodDesc, Opnd *tauNullChecked, Opnd *tauTypesChecked, uint32 argOffset);
-    bool isGuardableVirtualCall(Inst* inst, MethodInst*& methodInst, Opnd*& base,
-                                Opnd* & tauNullChecked, Opnd*&tauTypesChecked,
-                                uint32 &argOffset);
+    void genGuardedDirectCall(IRManager& irm, Node* node, Inst* call, MethodDesc* methodDesc, ObjectType* valuedType, Opnd *tauNullChecked, Opnd *tauTypesChecked, uint32 argOffset);
     bool doGuard(IRManager& irm, Node* node, MethodDesc& methodDesc);
     
     bool _hasProfileInfo;
@@ -53,6 +54,7 @@
     bool _devirtSkipExceptionPath;
     float _devirtBlockHotnessMultiplier;
     bool _devirtSkipJLObjectMethods;
+    bool _devirtInterfaceMethods;
 
 
     //unguard pass params

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp Wed Dec 13 06:11:10 2006
@@ -666,6 +666,7 @@
             case SaveThisState:
             case ReadThisState:
             case LockedCompareAndExchange:
+            case AddValueProfileValue:
                 break;
             default:
                 assert(0);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.cpp Wed Dec 13 06:11:10 2006
@@ -164,6 +164,7 @@
     optimizerFlags.devirt_skip_exception_path = getBoolArg("devirt_skip_exception_path", true);
     optimizerFlags.devirt_block_hotness_multiplier= (float)getIntArg("devirt_block_hotness_multiplier", 10);
     optimizerFlags.devirt_skip_object_methods = getBoolArg("devirt_skip_object_methods", false);
+    optimizerFlags.devirt_intf_methods = getBoolArg("devirt_intf_methods", true);
 
     //unguard
     optimizerFlags.unguard_dcall_percent = getIntArg("unguard_dcall_percent", 30);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/optimizer.h Wed Dec 13 06:11:10 2006
@@ -97,6 +97,7 @@
     bool devirt_skip_exception_path;
     float devirt_block_hotness_multiplier;
     bool devirt_skip_object_methods;
+    bool devirt_intf_methods;
 
     //unguard
     int unguard_dcall_percent;

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=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/EMInterface.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/EMInterface.h Wed Dec 13 06:11:10 2006
@@ -26,18 +26,18 @@
 
 #include "VMInterface.h"
 
-
 namespace Jitrino {
 
 enum ProfileType {
-    ProfileType_Invalid =0,
-    ProfileType_EntryBackedge =1,
-    ProfileType_Edge = 2
+    ProfileType_Invalid = 0,
+    ProfileType_EntryBackedge = 1,
+    ProfileType_Edge = 2,
+    ProfileType_Value = 3
 };
 
 enum JITProfilingRole{
-    JITProfilingRole_GEN =1,
-    JITProfilingRole_USE =2
+    JITProfilingRole_GEN = 1,
+    JITProfilingRole_USE = 2
 };
 
 //M1 implementation of profiling interfaces
@@ -45,6 +45,7 @@
 class MemoryManager;
 class EntryBackedgeMethodProfile;
 class EdgeMethodProfile;
+class ValueMethodProfile;
 
 typedef void PC_Callback_Fn(Method_Profile_Handle);
 
@@ -53,6 +54,11 @@
     virtual ~ProfilingInterface(){};
 
     virtual MethodProfile* getMethodProfile(MemoryManager& mm, ProfileType type, MethodDesc& md, JITProfilingRole role=JITProfilingRole_USE) const = 0;
+    // Returns EM method profile handle. This method is needed when we need to update method profile
+    // at run-time i.e. when there is no any memory managers available.
+    virtual Method_Profile_Handle getMethodProfileHandle(ProfileType type, MethodDesc& md) const = 0;
+    virtual EM_ProfileAccessInterface* getEMProfileAccessInterface() const = 0;
+
     virtual bool hasMethodProfile(ProfileType type, MethodDesc& md, JITProfilingRole role=JITProfilingRole_USE) const = 0;
     virtual bool enableProfiling(PC_Handle pc, JITProfilingRole role) = 0;
     virtual bool isProfilingEnabled(ProfileType pcType, JITProfilingRole jitRole) const = 0;
@@ -78,7 +84,14 @@
     virtual EdgeMethodProfile* getEdgeMethodProfile(MemoryManager& mm, MethodDesc& md, JITProfilingRole role=JITProfilingRole_USE) const {
         return (EdgeMethodProfile*)getMethodProfile(mm, ProfileType_Edge, md, role);    
     }
-
+    
+    
+    // value profiler
+    virtual ValueMethodProfile* createValueMethodProfile (MemoryManager& mm, MethodDesc& md, uint32 numKeys, uint32* Keys) = 0;
+    
+    virtual ValueMethodProfile* getValueMethodProfile(MemoryManager& mm, MethodDesc& md, JITProfilingRole role=JITProfilingRole_USE) const {
+        return (ValueMethodProfile*)getMethodProfile(mm, ProfileType_Value, md, role);    
+    }
 };
 
 class MethodProfile {
@@ -114,6 +127,14 @@
     virtual uint32* getEntryCounter() const = 0;
     virtual uint32* getCounter(uint32 key) const = 0;
 };
+
+class ValueMethodProfile: public MethodProfile {
+public:
+    ValueMethodProfile (Method_Profile_Handle handle, MethodDesc& md) : MethodProfile(handle, ProfileType_Value, md){}
+
+	virtual POINTER_SIZE_INT getTopValue(uint32 instructionKey) const = 0;
+};
+
 
 };//namespace
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlEMInterface.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlEMInterface.cpp?view=diff&rev=486662&r1=486661&r2=486662
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlEMInterface.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlEMInterface.cpp Wed Dec 13 06:11:10 2006
@@ -30,16 +30,31 @@
 
 namespace Jitrino {
 
+PC_Handle DrlProfilingInterface::getPCHandle(ProfileType type) const {
+    switch (type) {
+        case ProfileType_EntryBackedge:
+            return ebPCHandle;
+        case ProfileType_Edge:
+            return edgePCHandle;
+        case ProfileType_Value:
+            return valuePCHandle;
+        default:
+            assert(0);
+    }
+    return NULL;
+}
 
 MethodProfile* DrlProfilingInterface::getMethodProfile(MemoryManager& mm, ProfileType type, MethodDesc& md, JITProfilingRole role) const {
-    assert(type == ProfileType_EntryBackedge || type == ProfileType_Edge);
-    Method_Profile_Handle mpHandle = profileAccessInterface->get_method_profile(emHandle, pcHandle, ((DrlVMMethodDesc&)md).getDrlVMMethod());
+    
+    Method_Profile_Handle mpHandle = profileAccessInterface->get_method_profile(emHandle, getPCHandle(type), ((DrlVMMethodDesc&)md).getDrlVMMethod());
     if (mpHandle==0) {
         return NULL;
     }
     MethodProfile* p = NULL;
     if (type == ProfileType_Edge) {
         p = new (mm) DrlEdgeMethodProfile(mpHandle, md, profileAccessInterface);
+    } else if (type == ProfileType_Value) {
+        p = new (mm) DrlValueMethodProfile(mpHandle, md, profileAccessInterface);
     } else {
         uint32* eCounter = (uint32*)profileAccessInterface->eb_profiler_get_entry_counter_addr(mpHandle);
         uint32* bCounter = (uint32*)profileAccessInterface->eb_profiler_get_backedge_counter_addr(mpHandle);
@@ -48,11 +63,19 @@
     return p;
 }
 
+Method_Profile_Handle DrlProfilingInterface::getMethodProfileHandle(ProfileType type, MethodDesc& md) const {
+    return profileAccessInterface->get_method_profile(emHandle, getPCHandle(type), ((DrlVMMethodDesc&)md).getDrlVMMethod());
+}
+
+
 bool DrlProfilingInterface::hasMethodProfile(ProfileType type, MethodDesc& md, JITProfilingRole role) const {
-    if (type!=pcType) {
+
+    PC_Handle pcHandle = getPCHandle(type);
+
+    if (pcHandle == NULL) {
         return false;
     }
-    if (jitRole!=role) {
+    if (jitRole != role) {
         return false;
     }
     if (profileAccessInterface != NULL) {
@@ -63,8 +86,14 @@
 }
 
 uint32 DrlProfilingInterface::getProfileMethodCount(MethodDesc& md, JITProfilingRole role) const {
-    assert(pcType ==ProfileType_Edge || pcType == ProfileType_EntryBackedge);
     assert(jitRole == role);
+    PC_Handle pcHandle = getPCHandle(ProfileType_Edge);
+    ProfileType pcType = ProfileType_Edge;
+    if (pcHandle == NULL) {
+        pcHandle = getPCHandle(ProfileType_EntryBackedge);
+        pcType = ProfileType_EntryBackedge;
+    }
+    assert (pcHandle != NULL);
     Method_Handle methodHandle = ((DrlVMMethodDesc&)md).getDrlVMMethod();
     Method_Profile_Handle mph = profileAccessInterface->get_method_profile(emHandle, pcHandle, methodHandle);
     if (mph == NULL) {
@@ -80,9 +109,8 @@
 }
 
 bool DrlProfilingInterface::enableProfiling(PC_Handle pc, JITProfilingRole role) {
-    assert(!profilingEnabled);
     EM_PCTYPE _pcType =  profileAccessInterface->get_pc_type(emHandle, pc);
-    if (_pcType != EM_PCTYPE_EDGE && _pcType!=EM_PCTYPE_ENTRY_BACKEDGE) {
+    if (_pcType != EM_PCTYPE_EDGE && _pcType != EM_PCTYPE_ENTRY_BACKEDGE && _pcType != EM_PCTYPE_VALUE) {
         return false;
     }
     JITInstanceContext* jitMode = JITInstanceContext::getContextForJIT(jitHandle);
@@ -96,30 +124,36 @@
         profilingEnabled = true;
     }
     if (profilingEnabled) {
-        jitRole = role;       
-        pcHandle = pc;
-        pcType = (_pcType == EM_PCTYPE_EDGE) ? ProfileType_Edge : ProfileType_EntryBackedge;
+        jitRole = role;
+        switch(_pcType)
+        {
+        case EM_PCTYPE_EDGE:
+            edgePCHandle = pc;
+            break;
+        case EM_PCTYPE_ENTRY_BACKEDGE:
+            ebPCHandle = pc;
+            break;
+        case EM_PCTYPE_VALUE:
+            valuePCHandle = pc;
+            break;
+        default:
+            assert(0);
+            return false;
+        }
     }
     return profilingEnabled;
 }
 
 bool DrlProfilingInterface::isProfilingEnabled(ProfileType pcType, JITProfilingRole role) const {
-    if( !profilingEnabled || (jitRole != role) ){
+    if(!profilingEnabled || (jitRole != role) || (getPCHandle(pcType) == NULL)){
         return false;
     }
-
-    const EM_PCTYPE emPcType = profileAccessInterface->get_pc_type( emHandle, pcHandle );
-    if( (emPcType == EM_PCTYPE_EDGE) && (pcType == ProfileType_Edge ) ){
-        return true;
-    }
-    if( (emPcType == EM_PCTYPE_ENTRY_BACKEDGE) && (pcType == ProfileType_EntryBackedge) ){
-        return true;
-    }
-    return false;
+    return true;
 }
 
 EntryBackedgeMethodProfile* DrlProfilingInterface::createEBMethodProfile(MemoryManager& mm, MethodDesc& md) {
     assert(isProfilingEnabled(ProfileType_EntryBackedge, JITProfilingRole_GEN));
+    PC_Handle pcHandle = getPCHandle(ProfileType_EntryBackedge);
     Method_Profile_Handle mpHandle = profileAccessInterface->eb_profiler_create_profile(pcHandle, ((DrlVMMethodDesc&)md).getDrlVMMethod());
     assert(mpHandle!=0);
     uint32* eCounter = (uint32*)profileAccessInterface->eb_profiler_get_entry_counter_addr(mpHandle);
@@ -137,6 +171,7 @@
                                                                   uint32 checkSum )
 {
     assert(isProfilingEnabled(ProfileType_Edge, JITProfilingRole_GEN));
+    PC_Handle pcHandle = getPCHandle(ProfileType_Edge);
     Method_Profile_Handle mpHandle =  profileAccessInterface->edge_profiler_create_profile( 
         pcHandle, ((DrlVMMethodDesc&)md).getDrlVMMethod(), numCounters, counterKeys, checkSum);
     assert( mpHandle != NULL );
@@ -145,38 +180,51 @@
     return p;
 }
 
+ValueMethodProfile* DrlProfilingInterface::createValueMethodProfile(MemoryManager& mm,
+                                                                    MethodDesc& md,
+                                                                    uint32 numKeys,
+                                                                    uint32* Keys)
+{
+    assert(isProfilingEnabled(ProfileType_Value, JITProfilingRole_GEN));
+    PC_Handle pcHandle = getPCHandle(ProfileType_Value);
+    Method_Profile_Handle mpHandle =  profileAccessInterface->value_profiler_create_profile( 
+        pcHandle, ((DrlVMMethodDesc&)md).getDrlVMMethod(), numKeys, Keys);
+    assert(mpHandle != NULL);
+
+    DrlValueMethodProfile* p = new (mm) DrlValueMethodProfile(mpHandle, md, profileAccessInterface);
+    return p;
+}
+
+
 uint32 DrlProfilingInterface::getMethodEntryThreshold() const {
-    assert(pcHandle!=NULL);
-    EM_PCTYPE pcType =  profileAccessInterface->get_pc_type(emHandle, pcHandle);
-    if (pcType == EM_PCTYPE_EDGE) {
+    PC_Handle pcHandle = getPCHandle(ProfileType_Edge);
+    if (pcHandle != NULL) {
         return profileAccessInterface->edge_profiler_get_entry_threshold(pcHandle);
-    } else if ( pcType==EM_PCTYPE_ENTRY_BACKEDGE) {
+    } else if ((pcHandle = getPCHandle(ProfileType_EntryBackedge)) != NULL) {
         return profileAccessInterface->eb_profiler_get_entry_threshold(pcHandle);
-    } else {
-        assert(0);
     }
+    assert(0);
     return 0;
 }
 
 uint32 DrlProfilingInterface::getBackedgeThreshold() const {
-    assert(pcHandle!=NULL);
-    EM_PCTYPE pcType =  profileAccessInterface->get_pc_type(emHandle, pcHandle);
-    if (pcType == EM_PCTYPE_EDGE) {
+    PC_Handle pcHandle = getPCHandle(ProfileType_Edge);
+    if (pcHandle != NULL) {
         return profileAccessInterface->edge_profiler_get_backedge_threshold(pcHandle);
-    } else if ( pcType==EM_PCTYPE_ENTRY_BACKEDGE) {
+    } else if ((pcHandle = getPCHandle(ProfileType_EntryBackedge)) != NULL) {
         return profileAccessInterface->eb_profiler_get_backedge_threshold(pcHandle);
-    } 
+    }
     assert(0);
     return 0;
 }
 
-bool   DrlProfilingInterface::isEBProfilerInSyncMode() const {
+bool DrlProfilingInterface::isEBProfilerInSyncMode() const {
+    PC_Handle pcHandle = getPCHandle(ProfileType_EntryBackedge);
     assert(pcHandle!=NULL);
     return profileAccessInterface->eb_profiler_is_in_sync_mode(pcHandle)!=0;
 }
 
 PC_Callback_Fn* DrlProfilingInterface::getEBProfilerSyncModeCallback() const {
-    assert(pcHandle!=NULL);
     assert(profileAccessInterface->eb_profiler_sync_mode_callback!=NULL);
     return (PC_Callback_Fn*)profileAccessInterface->eb_profiler_sync_mode_callback;
 }
@@ -207,6 +255,14 @@
     return counter;
 }
 
+// Value profile
+DrlValueMethodProfile::DrlValueMethodProfile(Method_Profile_Handle handle, MethodDesc& md,  EM_ProfileAccessInterface* _profileAccessInterface)
+: ValueMethodProfile(handle, md),  profileAccessInterface(_profileAccessInterface) {
+}
+
+POINTER_SIZE_INT DrlValueMethodProfile::getTopValue(uint32 instructionKey) const {
+    return profileAccessInterface->value_profiler_get_top_value(getHandle(), instructionKey);
+}
 
 } //namespace
 



Mime
View raw message