You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@harmony.apache.org by Alexei Zakharov <al...@gmail.com> on 2007/10/22 17:44:56 UTC
Re: svn commit: r584097 - in /harmony/enhanced/drlvm/trunk/vm: em/src/ include/open/ jitrino/config/em64t/ jitrino/config/ia32/ jitrino/src/jet/ jitrino/src/vm/ jitrino/src/vm/drl/
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, mfursov@apache.org <mf...@apache.org>:
> 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