Index: vm/em/src/DrlEMImpl.cpp =================================================================== --- vm/em/src/DrlEMImpl.cpp (revision 711940) +++ vm/em/src/DrlEMImpl.cpp (working copy) @@ -25,6 +25,7 @@ #include "EBProfileCollector.h" #include "EdgeProfileCollector.h" #include "NValueProfileCollector.h" +#include "DelayProfileCollector.h" #include "open/vm_properties.h" #include "open/vm_ee.h" @@ -46,6 +47,7 @@ #define EDGE_PROFILER_STR "EDGE_PROFILER" #define VALUE_PROFILER_STR "VALUE_PROFILER" #define ENTRY_BACKEDGE_PROFILER_STR "EB_PROFILER" +#define DELAY_PROFILER_STR "DL_PROFILER" #define EM_CONFIG_EXT std::string(".emconf") @@ -151,6 +153,9 @@ profileAccessInterface.value_profiler_get_top_value = value_profiler_get_top_value; profileAccessInterface.value_profiler_dump_values = value_profiler_dump_values; + //Delay profile + profileAccessInterface.delay_profiler_create_profile = delay_profiler_create_profile; + return; } @@ -593,7 +598,7 @@ return NULL; } std::string profilerType = getParam(config, profilerName+".profilerType"); - if (profilerType!=ENTRY_BACKEDGE_PROFILER_STR && profilerType!=EDGE_PROFILER_STR && profilerType!=VALUE_PROFILER_STR) { + if (profilerType!=ENTRY_BACKEDGE_PROFILER_STR && profilerType!=EDGE_PROFILER_STR && profilerType!=VALUE_PROFILER_STR && profilerType != DELAY_PROFILER_STR) { LECHO(7, "EM: Unsupported profiler type"); return NULL; } @@ -692,7 +697,24 @@ } pc = new ValueProfileCollector(this, profilerName, step->jit, vpSteadySize, vpClearSize, vpClearInterval, vpMode, updateStrategy); + } else if (profilerType == DELAY_PROFILER_STR) { + int delayTimeout = 10; + int initialTimeout = 0; + bool ok = false; + initialTimeout = toNum(getParam(config, profilerName+".initialTimeout"), &ok); + if (!ok) { + LECHO(9, "EM: illegal '{0}' value" << "InitialTimeout"); + return NULL; + } + + delayTimeout = toNum(getParam(config, profilerName+".delayTimeout"), &ok); + if (!ok) { + LECHO(9, "EM: illegal '{0}' value" << "DelayTimeout"); + return NULL; + } + pc = new DelayProfileCollector(this, profilerName, step->jit, initialTimeout, delayTimeout); } + return pc; } Index: vm/em/src/DelayProfileCollector.cpp =================================================================== --- vm/em/src/DelayProfileCollector.cpp (revision 0) +++ vm/em/src/DelayProfileCollector.cpp (revision 0) @@ -0,0 +1,142 @@ +/* + * 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 Mikhail Y. Fursov, Aleksey Shipilev +* @version $Revision: 1.1.2.2.4.3 $ +*/ + +#include "DelayProfileCollector.h" + +#include +#include + +#include "cxxlog.h" +#include + +#include "open/vm_method_access.h" +#include "open/vm_class_manipulation.h" +#include "port_mutex.h" + +#define LOG_DOMAIN "em" + + +DelayProfileCollector::DelayProfileCollector(EM_PC_Interface* em, const std::string& name, JIT_Handle genJit, + U_32 _initialTimeout, U_32 _timeout) + : ProfileCollector(em, name, EM_PCTYPE_DELAY, genJit), + initialTimeout(_initialTimeout), timeout(_timeout) + +{ + if (!loggingEnabled) { + loggingEnabled = log_is_info_enabled(catName.c_str()); + } + if (loggingEnabled) { + std::ostringstream msg; + msg<< "EM: delay profiler intialized: "<< name <<" timeout:"<< timeout; + INFO2(catName.c_str(), msg.str().c_str()); + } + + port_mutex_create(&profilesLock, APR_THREAD_MUTEX_NESTED); +} + + +DelayProfileCollector::~DelayProfileCollector() { + for (DelayProfilesMap::iterator it = profilesByMethod.begin(), end = profilesByMethod.end(); it!=end; ++it) { + DelayMethodProfile* profile = it->second; + delete profile; + } + + port_mutex_destroy(&profilesLock); +} + +Method_Profile_Handle delay_profiler_create_profile( PC_Handle ph, + Method_Handle mh ) +{ + ProfileCollector* pc = (ProfileCollector*)ph; + assert(pc->type == EM_PCTYPE_DELAY); + + DelayMethodProfile* profile = + ((DelayProfileCollector*)pc)->createProfile(mh); + return (Method_Profile_Handle)profile; +} + + + +MethodProfile* DelayProfileCollector::getMethodProfile(Method_Handle mh) const { + port_mutex_lock(&profilesLock); + MethodProfile* res = NULL; + DelayProfilesMap::const_iterator it = profilesByMethod.find(mh); + if (it != profilesByMethod.end()) { + res = it->second; + } + port_mutex_unlock(&profilesLock); + return res; +} + +DelayMethodProfile* DelayProfileCollector::createProfile(Method_Handle mh) { + DelayMethodProfile* profile = new DelayMethodProfile(this, mh); + + port_mutex_lock(&profilesLock); + + assert(profilesByMethod.find(mh) == profilesByMethod.end()); + profilesByMethod[mh] = profile; + newProfiles.push_back(profile); + + port_mutex_unlock(&profilesLock); + + return profile; +} + +static void logReadyProfile(const std::string& catName, const std::string& profilerName, DelayMethodProfile* mp) { + const char* methodName = method_get_name(mp->mh); + Class_Handle ch = method_get_class(mp->mh); + const char* className = class_get_name(ch); + const char* signature = method_get_descriptor(mp->mh); + + std::ostringstream msg; + msg <<"EM: profiler["<methodProfileIsReady(profile); + } + tmpProfiles.clear(); + } + + // propagate recently added profiles to tmpProfiles + + if(!newProfiles.empty()) { + port_mutex_lock(&profilesLock); + tmpProfiles.insert(tmpProfiles.end(), newProfiles.begin(), newProfiles.end()); + newProfiles.clear(); + port_mutex_unlock(&profilesLock); + } + +} + Index: vm/em/src/DelayProfileCollector.h =================================================================== --- vm/em/src/DelayProfileCollector.h (revision 0) +++ vm/em/src/DelayProfileCollector.h (revision 0) @@ -0,0 +1,87 @@ +/* + * 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 Mikhail Y. Fursov, Aleksey Shipilev +* @version $Revision: 1.1.2.2.4.3 $ +*/ + +#ifndef _DELAY_PROFILE_COLLECTOR_H_ +#define _DELAY_PROFILE_COLLECTOR_H_ + +#include "DrlProfileCollectionFramework.h" + +#include "open/vm_util.h" +#include "port_mutex.h" + +#include + +class DelayMethodProfile; +typedef std::map DelayProfilesMap; +typedef std::vector DelayProfiles; + + +class DelayProfileCollector : public ProfileCollector, public TbsEMClient { +public: + + DelayProfileCollector(EM_PC_Interface* em, const std::string& name, JIT_Handle genJit, U_32 _initialTimeout = 0, U_32 _timeout=0); + + virtual ~DelayProfileCollector(); + + virtual TbsEMClient* getTbsEmClient() const { return (TbsEMClient*)this; } + + MethodProfile* getMethodProfile(Method_Handle mh) const ; + DelayMethodProfile* createProfile( Method_Handle mh ); + + virtual U_32 getInitialTimeout() const {return initialTimeout;} + virtual U_32 getTimeout() const {return timeout;} + virtual void onTimeout(); + + + //Mapping of method profile by method handles + DelayProfilesMap profilesByMethod; + + DelayProfiles greenProfiles; + DelayProfiles newProfiles; + DelayProfiles tmpProfiles; + + +private: + + + U_32 timeout; + U_32 initialTimeout; + bool loggingEnabled; + std::string catName; + + mutable osmutex_t profilesLock; + +}; + + +class DelayMethodProfile : public MethodProfile { + +public: + DelayMethodProfile(DelayProfileCollector* pc, Method_Handle mh) + : MethodProfile(pc, mh) {} + +private: + +}; + +Method_Profile_Handle delay_profiler_create_profile(PC_Handle ph, Method_Handle mh); + +#endif Index: vm/include/open/em_profile_access.h =================================================================== --- vm/include/open/em_profile_access.h (revision 711940) +++ vm/include/open/em_profile_access.h (working copy) @@ -50,7 +50,9 @@ * Value profiler. * Collects profile for each given instruction. */ - EM_PCTYPE_VALUE=3 + EM_PCTYPE_VALUE=3, + + EM_PCTYPE_DELAY=4 }; @@ -249,6 +251,9 @@ void (*value_profiler_dump_values) (Method_Profile_Handle mph, std::ostream& os); + + Method_Profile_Handle (*delay_profiler_create_profile) (PC_Handle ph, Method_Handle mh); + } EM_ProfileAccessInterface; Index: vm/jitrino/config/ia32/client.emconf =================================================================== --- vm/jitrino/config/ia32/client.emconf (revision 711940) +++ vm/jitrino/config/ia32/client.emconf (working copy) @@ -17,7 +17,7 @@ chains=chain1,chain2 chain1.jits=JET_CLINIT -chain2.jits=JET_DPGO,CD_OPT +chain2.jits=JET_QUICK,JET_DPGO,CD_OPT # JET_CLINIT compiles only methods, all other methods compiled with JET_DPGO @@ -27,6 +27,7 @@ chain1.filter=- JET_CLINIT.file=jitrino +JET_QUICK.file=jitrino JET_DPGO.file=jitrino CD_OPT.file=jitrino @@ -35,7 +36,13 @@ EB_PROF.profilerType=EB_PROFILER CD_OPT.useProfile=EB_PROF +# generate the dummy delay profiler first +JET_QUICK.genProfile=DL_PROF +DL_PROF.profilerType=DL_PROFILER +DL_PROF.initialTimeout=0 +DL_PROF.delayTimeout=100 + EB_PROF.mode=ASYNC EB_PROF.entryThreshold=10000 EB_PROF.backedgeThreshold=100000 @@ -49,6 +56,7 @@ # Options to be passed to JIT -XX:jit.JET_CLINIT.path= +-XX:jit.JET_QUICK.path= -XX:jit.JET_DPGO.path= -XX:jit.CD_OPT.path=opt_init,lock_method,translator,optimizer,hir2lir,codegen,unlock_method Index: vm/jitrino/src/jet/compiler.cpp =================================================================== --- vm/jitrino/src/jet/compiler.cpp (revision 711940) +++ vm/jitrino/src/jet/compiler.cpp (working copy) @@ -1618,6 +1618,18 @@ } g_compileLock.unlock(); } + + if (pi->isProfilingEnabled(ProfileType_Delay, JITProfilingRole_GEN)) { + MemoryManager mm("jet_profiling_mm"); + MethodDesc md(m_method, m_hjit); + + DelayMethodProfile* mp = + (DelayMethodProfile*)pi->getMethodProfile(mm, + ProfileType_Delay, md, JITProfilingRole_GEN); + if (mp == NULL) { + mp = pi->createDelayMethodProfile(mm, md); + } + } #endif } Index: vm/jitrino/src/vm/EMInterface.cpp =================================================================== --- vm/jitrino/src/vm/EMInterface.cpp (revision 711940) +++ vm/jitrino/src/vm/EMInterface.cpp (working copy) @@ -30,6 +30,8 @@ return edgePCHandle; case ProfileType_Value: return valuePCHandle; + case ProfileType_Delay: + return delayPCHandle; default: assert(0); } @@ -105,13 +107,13 @@ bool ProfilingInterface::enableProfiling(PC_Handle pc, JITProfilingRole role) { EM_PCTYPE _pcType = profileAccessInterface->get_pc_type(emHandle, pc); - if (_pcType != EM_PCTYPE_EDGE && _pcType != EM_PCTYPE_ENTRY_BACKEDGE && _pcType != EM_PCTYPE_VALUE) { + if (_pcType != EM_PCTYPE_EDGE && _pcType != EM_PCTYPE_ENTRY_BACKEDGE && _pcType != EM_PCTYPE_VALUE && _pcType != EM_PCTYPE_DELAY) { return false; } JITInstanceContext* jitMode = JITInstanceContext::getContextForJIT(jitHandle); if (jitMode->isJet()) { if (role == JITProfilingRole_GEN) { - profilingEnabled = _pcType == EM_PCTYPE_ENTRY_BACKEDGE; + profilingEnabled = (_pcType == EM_PCTYPE_ENTRY_BACKEDGE || _pcType == EM_PCTYPE_DELAY); } else { profilingEnabled = false; } @@ -131,6 +133,9 @@ case EM_PCTYPE_VALUE: valuePCHandle = pc; break; + case EM_PCTYPE_DELAY: + delayPCHandle = pc; + break; default: assert(0); return false; @@ -175,6 +180,21 @@ return p; } +DelayMethodProfile* ProfilingInterface::createDelayMethodProfile( MemoryManager& mm, + MethodDesc& md + ) +{ + assert(isProfilingEnabled(ProfileType_Delay, JITProfilingRole_GEN)); + PC_Handle pcHandle = getPCHandle(ProfileType_Delay); + Method_Profile_Handle mpHandle = profileAccessInterface->delay_profiler_create_profile( + pcHandle, md.getMethodHandle()); + assert( mpHandle != NULL ); + + DelayMethodProfile* p = new (mm) DelayMethodProfile(mpHandle, md, profileAccessInterface); + return p; +} + + ValueMethodProfile* ProfilingInterface::createValueMethodProfile(MemoryManager& mm, MethodDesc& md, U_32 numKeys, Index: vm/jitrino/src/vm/EMInterface.h =================================================================== --- vm/jitrino/src/vm/EMInterface.h (revision 711940) +++ vm/jitrino/src/vm/EMInterface.h (working copy) @@ -27,7 +27,8 @@ ProfileType_Invalid = 0, ProfileType_EntryBackedge = 1, ProfileType_Edge = 2, - ProfileType_Value = 3 + ProfileType_Value = 3, + ProfileType_Delay = 4 }; enum JITProfilingRole{ @@ -95,7 +96,17 @@ EM_ProfileAccessInterface* profileAccessInterface; }; +class DelayMethodProfile : public MethodProfile { +public: + DelayMethodProfile (Method_Profile_Handle handle, MethodDesc& md, EM_ProfileAccessInterface* _profileAccessInterface) + : MethodProfile(handle, ProfileType_Edge, md), profileAccessInterface(_profileAccessInterface){} +private: + EM_ProfileAccessInterface* profileAccessInterface; +}; + + + class ProfilingInterface { public: @@ -125,6 +136,7 @@ EdgeMethodProfile* createEdgeMethodProfile(MemoryManager& mm, MethodDesc& md, U_32 numEdgeCounters, U_32* counterKeys, U_32 checkSum); + DelayMethodProfile* createDelayMethodProfile(MemoryManager& mm, MethodDesc& md); U_32 getMethodEntryThreshold() const; U_32 getBackedgeThreshold() const; @@ -146,13 +158,13 @@ } ProfilingInterface(EM_Handle _em, JIT_Handle _jit, EM_ProfileAccessInterface* emProfileAccess) - : emHandle(_em), ebPCHandle(NULL), edgePCHandle(NULL), valuePCHandle(NULL), jitHandle(_jit), profileAccessInterface(emProfileAccess), + : emHandle(_em), ebPCHandle(NULL), edgePCHandle(NULL), valuePCHandle(NULL), delayPCHandle(NULL), jitHandle(_jit), profileAccessInterface(emProfileAccess), jitRole(JITProfilingRole_USE), profilingEnabled(false){} private: EM_Handle emHandle; // Various types of the profile collectors - PC_Handle ebPCHandle, edgePCHandle, valuePCHandle; + PC_Handle ebPCHandle, edgePCHandle, valuePCHandle, delayPCHandle; // ProfileType pcType; JIT_Handle jitHandle; EM_ProfileAccessInterface* profileAccessInterface;