Hi Mikhail, I'm afraid this commit causes VM crash in Struts test scenario. Please see HARMONY-4995 for details. I've reopened HARMONY-4875.
Thanks, Alexei 2007/10/12, [EMAIL PROTECTED] <[EMAIL PROTECTED]>: > Author: mfursov > Date: Fri Oct 12 01:24:55 2007 > New Revision: 584097 > > URL: http://svn.apache.org/viewvc?rev=584097&view=rev > Log: > Fix for HARMONY-4875 [drlvm][jit] Harmony has negative scalability in client > mode > > > Modified: > harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.cpp > harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.h > harmony/enhanced/drlvm/trunk/vm/include/open/ee_em_intf.h > harmony/enhanced/drlvm/trunk/vm/include/open/em.h > harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/client.emconf > harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf > harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h > harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp > harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp > harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h > harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp > harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/jet.h > harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/mib.cpp > harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/mib.h > harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/rt.cpp > 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/DrlJITInterface.cpp > > Modified: harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.cpp > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.cpp?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.cpp (original) > +++ harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.cpp Fri Oct 12 01:24:55 > 2007 > @@ -72,7 +72,6 @@ > emInstance = NULL; > } > > - > static EM_PCTYPE get_pc_type(EM_Handle _this, PC_Handle pc) { > assert(_this!=NULL); > assert(pc!=NULL); > @@ -86,7 +85,6 @@ > return (PC_Handle)em->getProfileCollector(profile_type, jh, jit_role); > } > > - > static Method_Profile_Handle > get_method_profile(EM_Handle _this, PC_Handle pch, Method_Handle mh) { > assert(_this!=NULL); > @@ -97,7 +95,6 @@ > } > > > - > RStep::RStep(JIT_Handle _jit, const std::string& _jitName, RChain* _chain, > apr_dso_handle_t* _libHandle) > : jit(_jit), jitName(_jitName), > catName(std::string(LOG_DOMAIN)+"."+_jitName), > chain(_chain), loggingEnabled(false), enable_profiling(NULL), > @@ -373,6 +370,9 @@ > return false; > } > > +static void profile_notification_callback_stub(JIT_Handle, PC_Handle, > Method_Handle) { > +} > + > bool DrlEMImpl::initJIT(const std::string& libName, apr_dso_handle_t* > libHandle, RStep& step) { > apr_dso_handle_sym_t fn = NULL; > if (apr_dso_sym(&fn, libHandle, "JIT_init") != APR_SUCCESS) { > @@ -395,6 +395,12 @@ > step.enable_profiling = enable_profiling_stub; > } > > + if (pcEnabled && apr_dso_sym(&fn, libHandle, > "JIT_profile_notification_callback") == APR_SUCCESS) { > + step.profile_notification_callback = (void(*)(JIT_Handle, PC_Handle, > Method_Handle))fn; > + } else { > + step.profile_notification_callback = > profile_notification_callback_stub; > + } > + > return true; > } > > @@ -749,6 +755,7 @@ > hymutex_unlock(&recompilationLock); > return; > } > + > methodsInRecompile.insert((Method_Profile_Handle)mp); > nMethodsRecompiled++; > hymutex_unlock(&recompilationLock); > @@ -764,10 +771,13 @@ > for (RSteps::const_iterator sit = chain->steps.begin(), send = > chain->steps.end(); sit!=send; ++sit) { > RStep* step = *sit; > if (step->jit == jit) { > + > + //notify JIT which has generated this profile that profile > is ready. > + step->profile_notification_callback(step->jit, mp->pc, > mp->mh); > + > ++sit; > RStep* nextStep = sit!=send ? *sit: NULL; > if (nextStep != NULL) { > - > if (nextStep->loggingEnabled) { > methodName = method_get_name(mp->mh); > Class_Handle ch = method_get_class(mp->mh); > > Modified: harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.h > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.h?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.h (original) > +++ harmony/enhanced/drlvm/trunk/vm/em/src/DrlEMImpl.h Fri Oct 12 01:24:55 > 2007 > @@ -55,6 +55,7 @@ > apr_dso_handle_t* libHandle; > > bool (*enable_profiling)(JIT_Handle, PC_Handle, EM_JIT_PC_Role); > + void (*profile_notification_callback)(JIT_Handle, PC_Handle, > Method_Handle); > }; > > > > Modified: harmony/enhanced/drlvm/trunk/vm/include/open/ee_em_intf.h > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/ee_em_intf.h?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/include/open/ee_em_intf.h (original) > +++ harmony/enhanced/drlvm/trunk/vm/include/open/ee_em_intf.h Fri Oct 12 > 01:24:55 2007 > @@ -98,6 +98,23 @@ > */ > JITEXPORT bool JIT_enable_profiling(JIT_Handle jit, PC_Handle pc, > EM_JIT_PC_Role role); > > + > + > +/** > +* Notifies JIT that profile is collected. > +* > +* EM uses this method to notify JIT that profile is collected. > +* JIT could use this information to patch profiling counters. > +* > +* @param[in] jit - the JIT instance handle > +* @param[in] pc - the handle of the profile collector instance > +* @param[in] mh - the handle of the method with collected profile > +* > +* @note The given method is optional. Currently only JET supports this > method. > +*/ > +JITEXPORT void JIT_profile_notification_callback(JIT_Handle jit, PC_Handle > pc, Method_Handle mh); > + > + > #ifdef __cplusplus > } > #endif > > Modified: harmony/enhanced/drlvm/trunk/vm/include/open/em.h > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/em.h?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/include/open/em.h (original) > +++ harmony/enhanced/drlvm/trunk/vm/include/open/em.h Fri Oct 12 01:24:55 2007 > @@ -57,7 +57,7 @@ > */ > typedef enum JIT_Result { > /** > - * The method compilation has finished successufuly. > + * The method compilation has finished successfully. > */ > JIT_SUCCESS, > /** > > Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/client.emconf > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/client.emconf?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/client.emconf > (original) > +++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/client.emconf Fri > Oct 12 01:24:55 2007 > @@ -30,19 +30,21 @@ > JET_DPGO.file=jitrino > CD_OPT.file=jitrino > > + > #Confuguration of profile collector and recompilation > JET_DPGO.genProfile=EB_PROF > EB_PROF.profilerType=EB_PROFILER > CD_OPT.useProfile=EB_PROF > > > -EB_PROF.mode=SYNC > +EB_PROF.mode=ASYNC > EB_PROF.entryThreshold=10000 > EB_PROF.backedgeThreshold=100000 > > -# these options could be used only in async profiler mode > -#EB_PROF.tbsTimeout=5 > -#EB_PROF.tbsInitialTimeout=0 > +# these options are used only in ASYNC profiler mode only > +EB_PROF.tbsTimeout=7 > +EB_PROF.tbsInitialTimeout=0 > + > > > > > Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf > (original) > +++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf Fri Oct > 12 01:24:55 2007 > @@ -36,13 +36,13 @@ > CD_OPT.useProfile=EB_PROF > > > -EB_PROF.mode=SYNC > +EB_PROF.mode=ASYNC > EB_PROF.entryThreshold=10000 > EB_PROF.backedgeThreshold=100000 > > -# these options are used only in ASYNC profiler mode > -#EB_PROF.tbsTimeout=5 > -#EB_PROF.tbsInitialTimeout=0 > +# these options are used only in ASYNC profiler mode only > +EB_PROF.tbsTimeout=7 > +EB_PROF.tbsInitialTimeout=0 > > > > > Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h (original) > +++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h Fri Oct 12 01:24:55 > 2007 > @@ -102,6 +102,32 @@ > return slots; > } > > +/** > + * The structure contains information about counter for patching profiling > counter after > + * profile is ready > + */ > +struct ProfileCounterInfo { > + //This field contains composite info on counter size (first byte) and > offset (last 3 bytes) > + uint32 offsetInfo; > + //Link to the basic block to calculate counter's offset after code layout > + BBInfo* bb; > + ProfileCounterInfo() : offsetInfo(0), bb(NULL){} > + > + static uint32 getInstSize(uint32 offsetInfo) { return offsetInfo >> 24;} > + static uint32 getInstOffset(uint32 offsetInfo) { return offsetInfo & > 0x00FFFFFF;} > + static uint32 createOffsetInfo(uint32 instSize, uint32 instOffset) { > + assert(instSize<0xFF && instOffset<0xFFFFFF); > + return (instSize<<24) | (instOffset); > + } > +}; > + > +/** > + * Map contains patching information for all the counters in current method > + */ > +typedef std::vector<ProfileCounterInfo> ProfileCounterInfos; > + > + > + > /** the class is used by codegen internally to keep field information */ > class FieldOpInfo { > public: > @@ -1287,6 +1313,8 @@ > * @brief Compilation handle. > */ > Compile_Handle m_compileHandle; > + > + ProfileCounterInfos m_profileCountersMap; > > }; > > > Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp (original) > +++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp Fri Oct 12 > 01:24:55 2007 > @@ -31,6 +31,10 @@ > namespace Jitrino { > namespace Jet { > > +//Number of nops to put before counter instruction to be able to atomically > +//replace beginning of the instruction with jump > +#define NOPS_PER_COUNTER 1 > + > void CodeGen::gen_prof_be(void) > { > if (!is_set(JMF_PROF_ENTRY_BE)) { > @@ -45,7 +49,17 @@ > movp(addr, m_p_backedge_counter); > int off = 0; > #endif > + uint32 offset = (uint32)(m_codeStream.ip() - m_codeStream.data() - > m_bbinfo->ipoff); //store offsets inside of BB now. Fix it to method's offset > after code layout > + //put number of nops to align counter instruction > + nop(NOPS_PER_COUNTER); > alu(alu_add, Opnd(i32, addr, off), 1); > + > + //store information about profiling counters > + uint32 new_offset = (uint32)(m_codeStream.ip() - m_codeStream.data() - > m_bbinfo->ipoff); > + ProfileCounterInfo info; > + info.bb = m_bbinfo; > + info.offsetInfo = ProfileCounterInfo::createOffsetInfo(new_offset - > offset, offset); > + m_profileCountersMap.push_back(info); > } > > void CodeGen::gen_gc_safe_point() > > Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp (original) > +++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp Fri Oct 12 > 01:24:55 2007 > @@ -503,6 +503,19 @@ > // > // runtime data. must be initialized before code patching > // > + > + //register profiler counters mapping info if present > + if (!m_profileCountersMap.empty()) { > + m_infoBlock.num_profiler_counters = > (uint32)m_profileCountersMap.size(); > + m_infoBlock.profiler_counters_map = new > uint32[m_infoBlock.num_profiler_counters]; > + for (size_t i =0; i<m_profileCountersMap.size(); i++) { > + ProfileCounterInfo& info = m_profileCountersMap[i]; > + uint32 offset = > ProfileCounterInfo::getInstOffset(info.offsetInfo) + (info.bb->addr - > m_vmCode); > + uint32 offsetInfo = > ProfileCounterInfo::createOffsetInfo(ProfileCounterInfo::getInstSize(info.offsetInfo), > offset); > + m_infoBlock.profiler_counters_map[i]=offsetInfo; > + } > + } > + > unsigned data_size = m_infoBlock.get_total_size(); > char * pdata; > if (m_bEmulation) { > > Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h (original) > +++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc.h Fri Oct 12 01:24:55 > 2007 > @@ -893,7 +893,7 @@ > * 'mov mem, fr' using FLD, FST and FXCH. > * > * @todo IPF support. The basic idea is to hide one or two registers from > - * application and use them in Ecoder internally to emulate complex address > + * application and use them in Encoder internally to emulate complex address > * form and other operations that are not natively support in IPF's > * instruction set. > */ > @@ -997,6 +997,16 @@ > } > alu_impl(alu, op0, op1); > } > + > + /** > + * Generates n-byte long NOP instruction. > + */ > + void nop(uint32 n) { > + if (is_trace_on()) { > + trace(string("nop"), to_str((int)n), string()); > + } > + nop_impl(n); > + } > > /** > * Performs bitwise NOT operation. > @@ -1477,6 +1487,8 @@ > void not_impl(const Opnd& op0); > /// Implementation of alu(). > void alu_impl(ALU op, const Opnd& op0, const Opnd& op1); > + //Implementation of nop() > + void nop_impl(uint32 n); > /// Implementation of cmovcc(). > void cmovcc_impl(COND c, const Opnd& op0, const Opnd& op1); > /// Implementation of cmpxchg(). > > Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp (original) > +++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/enc_ia32.cpp Fri Oct 12 > 01:24:55 2007 > @@ -680,6 +680,12 @@ > ip(EncoderBase::encode(ip(), mn, args)); > } > > +void Encoder::nop_impl(uint32 n) > +{ > + ip(EncoderBase::nops(ip(), n)); > +} > + > + > void Encoder::cmovcc_impl(COND c, const Opnd& op0, const Opnd& op1) > { > ConditionMnemonic cm = devirt(c); > > Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/jet.h > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/jet.h?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/jet.h (original) > +++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/jet.h Fri Oct 12 01:24:55 > 2007 > @@ -80,6 +80,7 @@ > void rt_unwind(JIT_Handle jit, Method_Handle method, > JitFrameContext * context); > > + > /** > * @brief Enumerates root set for a given method. > * > @@ -246,6 +247,12 @@ > * @return Supported features > */ > OpenMethodExecutionParams get_exe_capabilities(); > + > +/** > +* @brief Notifies JET that profile is collected and counters could be removed > +* now. > +*/ > +void rt_profile_notification_callback(JIT_Handle jit, PC_Handle pc, > Method_Handle mh); > > }}; // ~namespace Jitrino::Jet > > > Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/mib.cpp > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/mib.cpp?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/mib.cpp (original) > +++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/mib.cpp Fri Oct 12 > 01:24:55 2007 > @@ -20,7 +20,7 @@ > */ > /** > * @file > - * @brief MethodInfoBlock implementaion. > + * @brief MethodInfoBlock implementation. > */ > > #include "mib.h" > @@ -36,6 +36,9 @@ > // > rt_header = &m_header; > rt_header->code_start = NULL; > + num_profiler_counters = 0; > + profiler_counters_map= NULL; > + > } > > void MethodInfoBlock::init(unsigned bc_size, unsigned stack_max, > @@ -51,10 +54,10 @@ > rt_header->m_in_slots = in_slots; > rt_header->m_flags = flags; > > - // All the values must be initialized *before* get_dyn_size() ! > - unsigned dyn_size = get_dyn_size(); > - m_data = new char[dyn_size]; > - memset(m_data, 0, dyn_size); > + // All the values must be initialized *before* get_bcmap_size() ! > + unsigned bcmap_size = get_bcmap_size(); > + m_data = new char[bcmap_size]; > + memset(m_data, 0, bcmap_size); > rt_inst_addrs = (const char**)m_data; > } > > @@ -62,8 +65,15 @@ > { > memset(to, 0, get_total_size()); > memcpy(to, rt_header, get_hdr_size()); > - memcpy(to + get_hdr_size(), m_data, get_dyn_size()); > + memcpy(to + get_hdr_size(), m_data, get_bcmap_size()); > rt_inst_addrs = (const char**)(to + get_hdr_size()); > + > + //store information about profiling counters for the method in > MethodInfoBlock > + uint32* countersInfo = (uint32*)(to + get_hdr_size() + > get_bcmap_size()); > + countersInfo[0]=num_profiler_counters; > + if (num_profiler_counters > 0) { > + memcpy(countersInfo+1, profiler_counters_map, num_profiler_counters > * sizeof(uint32)); > + } > } > > const char * MethodInfoBlock::get_ip(unsigned pc) const > > Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/mib.h > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/mib.h?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/mib.h (original) > +++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/mib.h Fri Oct 12 01:24:55 > 2007 > @@ -100,6 +100,8 @@ > MethodInfoBlock(char * pdata) { > assert(is_valid_data(pdata)); > m_data = NULL; > + num_profiler_counters = 0; > + profiler_counters_map = NULL; > load(pdata); > } > > @@ -108,7 +110,7 @@ > */ > ~MethodInfoBlock() > { > - assert (m_data == NULL); > + assert (m_data == NULL); > } > > /** > @@ -236,7 +238,7 @@ > */ > unsigned get_total_size(void) const > { > - return get_hdr_size() + get_dyn_size(); > + return get_hdr_size() + get_bcmap_size() + > get_profile_counters_map_size(); > } > /** > * @brief Sets a length of 'warm-up code'. > @@ -312,10 +314,20 @@ > // MethodInfoBlock instance, then feel free to remove this assert(). > // and **UNCOMMENT the delete[]** > assert(m_data == NULL); > + assert(profiler_counters_map == NULL); > + assert(num_profiler_counters == 0); > //delete[] m_data; m_data = NULL; // just for sure > > rt_header = (BlockHeader*)from; > rt_inst_addrs = (const char**)(from + get_hdr_size()); > + > + // load profiling counters info > + char* countersInfo = from + get_hdr_size() + get_bcmap_size(); > + num_profiler_counters = *(uint32*)countersInfo; > + if (num_profiler_counters > 0) { > + profiler_counters_map = (uint32*)(countersInfo + > sizeof(uint32)); > + } > + profiler_counters_map = (uint32*)(countersInfo + sizeof(uint32)); > } > > /** > @@ -391,7 +403,7 @@ > } > > /** > - * @brief Calculates and returns size occupied by variable part of > + * @brief Calculates and returns size occupied by bc-map related > variable part of > * MethodInfoBlock. > * > * @note Obviously, all fields used to calculate the variable size > @@ -400,11 +412,20 @@ > * > * @return size needed to store variable part of MethodInfoBlock. > */ > - unsigned get_dyn_size(void) const > + unsigned get_bcmap_size(void) const > { > return sizeof(rt_inst_addrs[0])*rt_header->m_bc_size; > } > > + /** > + * @brief Calculates and returns size occupied by profiling counters info > in > + * MethodInfoBlock. > + * > + */ > + unsigned get_profile_counters_map_size() const { > + return sizeof (uint32) + num_profiler_counters * sizeof(uint32); > + } > + > /** > * @brief Disallows copying. > */ > @@ -527,9 +548,16 @@ > * #init). During runtime, it points into the buffer provided to #load. > */ > const char ** rt_inst_addrs; // [bc_size] > - char ** data_ips; // [m_num_datas] > - unsigned* depths; // [m_num_datas] > - unsigned* masks; // [m_num_datas*words(m_max_stack_depth)] > + > +public: > + /** > + * Number of profile counters in the method > + */ > + uint32 num_profiler_counters; > + /** > + * Profiling counters information for patching: counter size and offset > + */ > + uint32* profiler_counters_map; > }; > > > > Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/rt.cpp > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/rt.cpp?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/rt.cpp (original) > +++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/rt.cpp Fri Oct 12 > 01:24:55 2007 > @@ -32,6 +32,7 @@ > #include "jit_intf.h" > > #include "port_threadunsafe.h" > +#include "EMInterface.h" > > #if !defined(_IPF_) > #include "enc_ia32.h" > @@ -590,6 +591,63 @@ > } > > return EXE_ERROR_NONE; > +} > + > + > +void rt_profile_notification_callback(JIT_Handle jit, PC_Handle pch, > Method_Handle mh) > +{ > + JITInstanceContext* jitContext = > JITInstanceContext::getContextForJIT(jit); > + > + //heck that profiler type is EB, counters are patched only for Entry > Backage profile > + if ((jitContext->getProfilingInterface())->getProfileType(pch) == > EM_PCTYPE_ENTRY_BACKEDGE) { > + //Get MethodInfoBlock of the method to be patched > + char * pinfo = (char*)method_get_info_block_jit(mh, jit); > + assert(MethodInfoBlock::is_valid_data(pinfo)); > + MethodInfoBlock infoBlock(pinfo); > + > + if (infoBlock.get_flags() & DBG_TRACE_RT) { > + const char* methodName = method_get_name(mh); > + const char* className = class_get_name(method_get_class(mh)); > + dbg_rt("rt.patch_eb_counters: patching method %s.%s\n", > className, methodName); > + } > + > + //Replace counters with nops in 3 steps: > + //1. Atomically replace first 2 bytes of counter instruction with > jump to the > + //next instruction > + //2. Replace all the remaining bytes of counter instruction with nops > + //3. Atomically replace jump with 2 nops > + Byte* methodAddr = method_get_code_block_addr_jit(mh, jit); > + for (uint32 i = 0 ; i<infoBlock.num_profiler_counters; i++) { > + uint32 offsetInfo = infoBlock.profiler_counters_map[i]; > + uint32 codeOffset = ProfileCounterInfo::getInstOffset(offsetInfo); > + uint32 patchedSize = ProfileCounterInfo::getInstSize(offsetInfo); > + > + Byte* patchedAddr = methodAddr + codeOffset; > + //1. Generate jump to the next instruction > + char* jmpIP = (char*)patchedAddr; > + char jmpOffset = (char)(patchedSize - 2); > + if (((POINTER_SIZE_INT)jmpIP)&0x1) { > + jmpIP++; > + jmpOffset--; > + } > + > + //to guarantee that first replacing will be atomic we have to > + //manually write jmp instruction instead of using encoder > + *(uint16*)jmpIP = (uint16)((0xeb) | jmpOffset << 8); > + assert(((uint16)(int_ptr)(jmpIP) & 0x01)==0); > + > + //2. Put nops instead of inst, 1 byte nops are used here for asm > + //readability > + char* ip = jmpIP + 2; > + for (int i=0; i<jmpOffset; i++) { > + EncoderBase::nops(ip+i, 1); > + } > + > + //3. Atomically replace jump with nop; > + *(uint16*)jmpIP = (uint16)0x9090; //2 nops atomically. > + } > + infoBlock.release(); > + } > } > > }}; // ~namespace Jitrino::Jet > > 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?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/EMInterface.h (original) > +++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/EMInterface.h Fri Oct 12 > 01:24:55 2007 > @@ -107,6 +107,8 @@ > // at run-time i.e. when there is no any memory managers available. > Method_Profile_Handle getMethodProfileHandle(ProfileType type, > MethodDesc& md) const; > > + EM_PCTYPE getProfileType(PC_Handle pc) const; > + > bool hasMethodProfile(ProfileType type, MethodDesc& md, JITProfilingRole > role=JITProfilingRole_USE) const; > bool enableProfiling(PC_Handle pc, JITProfilingRole role); > bool isProfilingEnabled(ProfileType pcType, JITProfilingRole jitRole) > const; > > 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?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlEMInterface.cpp > (original) > +++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlEMInterface.cpp Fri > Oct 12 01:24:55 2007 > @@ -59,6 +59,9 @@ > return profileAccessInterface->get_method_profile(emHandle, > getPCHandle(type), md.getMethodHandle()); > } > > +EM_PCTYPE ProfilingInterface::getProfileType(PC_Handle pch) const { > + return profileAccessInterface->get_pc_type(emHandle, pch); > +} > > bool ProfilingInterface::hasMethodProfile(ProfileType type, MethodDesc& md, > JITProfilingRole role) const { > > > Modified: > harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlJITInterface.cpp > URL: > http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlJITInterface.cpp?rev=584097&r1=584096&r2=584097&view=diff > ============================================================================== > --- harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlJITInterface.cpp > (original) > +++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlJITInterface.cpp > Fri Oct 12 01:24:55 2007 > @@ -151,6 +151,17 @@ > > extern "C" > JITEXPORT void > +JIT_profile_notification_callback(JIT_Handle jit, PC_Handle pc, > Method_Handle mh) > +{ > + JITInstanceContext* jitContext = Jitrino::getJITInstanceContext(jit); > + if (jitContext->isJet()) { > + Jet::rt_profile_notification_callback(jit, pc, mh); > + } //opt does not support counters patching today. > +} > + > + > +extern "C" > +JITEXPORT void > JIT_gc_start(JIT_Handle jit) > { > } > > > -- Alexei Zakharov, Intel ESSD
