Return-Path: Delivered-To: apmail-harmony-commits-archive@www.apache.org Received: (qmail 65259 invoked from network); 13 Dec 2006 14:12:03 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 13 Dec 2006 14:12:03 -0000 Received: (qmail 56764 invoked by uid 500); 13 Dec 2006 14:12:10 -0000 Delivered-To: apmail-harmony-commits-archive@harmony.apache.org Received: (qmail 56745 invoked by uid 500); 13 Dec 2006 14:12:10 -0000 Mailing-List: contact commits-help@harmony.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@harmony.apache.org Delivered-To: mailing list commits@harmony.apache.org Received: (qmail 56736 invoked by uid 99); 13 Dec 2006 14:12:10 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 Dec 2006 06:12:10 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 13 Dec 2006 06:12:00 -0800 Received: by eris.apache.org (Postfix, from userid 65534) id 7DF9B1A981D; Wed, 13 Dec 2006 06:11:15 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commits@harmony.apache.org From: varlax@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20061213141115.7DF9B1A981D@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 @@ + + + + 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 @@ + + 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 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 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 +#include +#include "cxxlog.h" +#include + +#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: "<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 + +#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 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 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 #include @@ -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<getParentType()->getName()<<"."<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 counterKeys(mm); + bool debug = Log::isEnabled(); + uint32 key = 0; + + StlVector nodes(mm); + flowGraph.getNodesPostOrder(nodes); + for (StlVector::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 ®ionIRM, Node* node, Inst* call, MethodDesc* methodDesc, Opnd *tauNullChecked, Opnd *tauTypesChecked, uint32 argOffset) { +Devirtualizer::genGuardedDirectCall(IRManager ®ionIRM, Node* node, Inst* call, MethodDesc* methodDesc, ObjectType* objectType, Opnd *tauNullChecked, Opnd *tauTypesChecked, uint32 argOffset) { ControlFlowGraph ®ionFG = 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="<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