From a8452ad5b4beb2ba072802d53b3ba77f754b8e3b Mon Sep 17 00:00:00 2001 From: Michael Starzinger Date: Tue, 1 Sep 2009 02:59:25 +0200 Subject: [PATCH] * src/toolbox/list.hpp (DumpList): Made sort function accessible. * src/vm/jit/code.cpp (code_codeinfo_free): Release memory for profiling. * src/vm/jit/code.hpp (codeinfo): Basicblockcount only needed for profiling. * src/vm/jit/codegen-common.cpp (codegen_emit): Adapted CPU cycle counting. * src/vm/jit/emit-common.hpp: Likewise. * src/vm/jit/jit.cpp (jit_compile): This is not the place to free resources. * src/vm/jit/optimizing/Makefile.am (PROFILE_SOURCES): Moved to C++. * src/vm/jit/optimizing/profile.cpp: Fixed and moved to C++. * src/vm/jit/optimizing/profile.hpp: Likewise. * src/vm/vm.cpp: Fixed includes. * src/vm/jit/i386/emit.c: Added dummies for CPU cycle counting. * src/vm/jit/powerpc/emit.c: Likewise. * src/vm/jit/s390/emit.c: Likewise. * src/vm/jit/x86_64/emit.c: Moved CPU cycle counting here. --- src/toolbox/list.hpp | 1 + src/vm/jit/code.cpp | 7 ++ src/vm/jit/code.hpp | 5 +- src/vm/jit/codegen-common.cpp | 10 +-- src/vm/jit/emit-common.hpp | 4 +- src/vm/jit/i386/emit.c | 22 ++++++ src/vm/jit/jit.cpp | 12 +--- src/vm/jit/optimizing/Makefile.am | 4 +- .../jit/optimizing/{profile.c => profile.cpp} | 71 +++++++++---------- .../jit/optimizing/{profile.h => profile.hpp} | 65 ++++++----------- src/vm/jit/powerpc/emit.c | 22 ++++++ src/vm/jit/s390/codegen.c | 4 -- src/vm/jit/s390/codegen.h | 4 -- src/vm/jit/s390/emit.c | 22 ++++++ src/vm/jit/x86_64/emit.c | 40 +++++++++++ src/vm/vm.cpp | 5 +- 16 files changed, 182 insertions(+), 116 deletions(-) rename src/vm/jit/optimizing/{profile.c => profile.cpp} (85%) rename src/vm/jit/optimizing/{profile.h => profile.hpp} (56%) diff --git a/src/toolbox/list.hpp b/src/toolbox/list.hpp index 53395be00..59c9c55ce 100644 --- a/src/toolbox/list.hpp +++ b/src/toolbox/list.hpp @@ -108,6 +108,7 @@ public: using std::list >::remove; using std::list >::rend; using std::list >::size; + using std::list >::sort; }; #else diff --git a/src/vm/jit/code.cpp b/src/vm/jit/code.cpp index 53dec1fd2..4946310d8 100644 --- a/src/vm/jit/code.cpp +++ b/src/vm/jit/code.cpp @@ -238,6 +238,13 @@ void code_codeinfo_free(codeinfo *code) replace_free_replacement_points(code); #endif +#if defined(ENABLE_PROFILING) + /* Release memory for basic block profiling information. */ + + if (code->bbfrequency != NULL) + MFREE(code->bbfrequency, u4, code->basicblockcount); +#endif + FREE(code, codeinfo); #if defined(ENABLE_STATISTICS) diff --git a/src/vm/jit/code.hpp b/src/vm/jit/code.hpp index 46530ebae..c32f53188 100644 --- a/src/vm/jit/code.hpp +++ b/src/vm/jit/code.hpp @@ -71,7 +71,6 @@ struct codeinfo { uint32_t flags; /* OR of CODE_FLAG_ constants */ u1 optlevel; /* optimization level of this code */ - s4 basicblockcount; /* number of basic blocks */ /* machine code */ u1 *mcode; /* pointer to machine code */ @@ -108,9 +107,11 @@ struct codeinfo { u1 *savedmcode; /* saved code under patches */ #endif + /* profiling information */ #if defined(ENABLE_PROFILING) u4 frequency; /* number of method invocations */ - u4 *bbfrequency; + s4 basicblockcount; /* number of basic blocks */ + u4 *bbfrequency; /* basic block profiling information */ s8 cycles; /* number of cpu cycles */ #endif }; diff --git a/src/vm/jit/codegen-common.cpp b/src/vm/jit/codegen-common.cpp index b9dffac2d..76ec50c82 100644 --- a/src/vm/jit/codegen-common.cpp +++ b/src/vm/jit/codegen-common.cpp @@ -92,7 +92,7 @@ #include "vm/jit/stacktrace.hpp" #include "vm/jit/trace.hpp" -#include "vm/jit/optimizing/profile.h" +#include "vm/jit/optimizing/profile.hpp" #if defined(ENABLE_SSA) # include "vm/jit/optimizing/lsra.h" @@ -1098,10 +1098,8 @@ bool codegen_emit(jitdata *jd) // Count method frequency. emit_profile_method(cd, code); -# if defined(__X86_64__) // Start CPU cycle counting. - emit_profile_cycle_start(); -# endif + emit_profile_cycle_start(cd, code); } #endif @@ -1166,11 +1164,9 @@ bool codegen_emit(jitdata *jd) // Count basicblock frequency. emit_profile_basicblock(cd, code, bptr); -# if defined(__X86_64__) // If this is an exception handler, start profiling again. if (bptr->type == BBTYPE_EXH) - emit_profile_cycle_start(); -# endif + emit_profile_cycle_start(cd, code); } #endif diff --git a/src/vm/jit/emit-common.hpp b/src/vm/jit/emit-common.hpp index 24f6b1510..0d467fc11 100644 --- a/src/vm/jit/emit-common.hpp +++ b/src/vm/jit/emit-common.hpp @@ -221,8 +221,8 @@ void emit_monitor_exit(jitdata* jd, int32_t syncslot_offset); #if defined(ENABLE_PROFILING) void emit_profile_method(codegendata* cd, codeinfo* code); void emit_profile_basicblock(codegendata* cd, codeinfo* code, basicblock* bptr); -void emit_profile_cycle_start(); -void emit_profile_cycle_stop(); +void emit_profile_cycle_start(codegendata* cd, codeinfo* code); +void emit_profile_cycle_stop(codegendata* cd, codeinfo* code); #endif void emit_verbosecall_enter(jitdata *jd); diff --git a/src/vm/jit/i386/emit.c b/src/vm/jit/i386/emit.c index d69217920..5751e5884 100644 --- a/src/vm/jit/i386/emit.c +++ b/src/vm/jit/i386/emit.c @@ -706,6 +706,28 @@ void emit_profile_basicblock(codegendata* cd, codeinfo* code, basicblock* bptr) #endif +/** + * Emit profiling code to start CPU cycle counting. + */ +#if defined(ENABLE_PROFILING) +void emit_profile_cycle_start(codegendata* cd, codeinfo* code) +{ + // XXX Not implemented yet! +} +#endif + + +/** + * Emit profiling code to stop CPU cycle counting. + */ +#if defined(ENABLE_PROFILING) +void emit_profile_cycle_stop(codegendata* cd, codeinfo* code) +{ + // XXX Not implemented yet! +} +#endif + + /* emit_verbosecall_enter ****************************************************** Generates the code for the call trace. diff --git a/src/vm/jit/jit.cpp b/src/vm/jit/jit.cpp index 2da94922a..a8ac2b160 100644 --- a/src/vm/jit/jit.cpp +++ b/src/vm/jit/jit.cpp @@ -389,14 +389,6 @@ u1 *jit_compile(methodinfo *m) /* release codeinfo */ code_codeinfo_free(jd->code); - -#if defined(ENABLE_PROFILING) - /* Release memory for basic block profiling information. */ - - if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) - if (jd->code->bbfrequency != NULL) - MFREE(jd->code->bbfrequency, u4, jd->code->basicblockcount); -#endif } else { DEBUG_JIT_COMPILEVERBOSE("Running: "); @@ -774,8 +766,10 @@ static u1 *jit_compile_intern(jitdata *jd) _must_ be done after loop optimization and register allocation, since they can change the basic block count. */ - if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) + if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) { + code->basicblockcount = jd->basicblockcount; code->bbfrequency = MNEW(u4, jd->basicblockcount); + } #endif DEBUG_JIT_COMPILEVERBOSE("Generating code: "); diff --git a/src/vm/jit/optimizing/Makefile.am b/src/vm/jit/optimizing/Makefile.am index d725afc4d..5ce18f644 100644 --- a/src/vm/jit/optimizing/Makefile.am +++ b/src/vm/jit/optimizing/Makefile.am @@ -33,8 +33,8 @@ endif if ENABLE_PROFILING PROFILE_SOURCES = \ - profile.c \ - profile.h + profile.cpp \ + profile.hpp REORDER_SOURCES = \ reorder.c \ diff --git a/src/vm/jit/optimizing/profile.c b/src/vm/jit/optimizing/profile.cpp similarity index 85% rename from src/vm/jit/optimizing/profile.c rename to src/vm/jit/optimizing/profile.cpp index 5268c8d75..1ebc554a3 100644 --- a/src/vm/jit/optimizing/profile.c +++ b/src/vm/jit/optimizing/profile.cpp @@ -1,7 +1,8 @@ -/* src/vm/jit/optimizing/profile.c - runtime profiling +/* src/vm/jit/optimizing/profile.cpp - runtime profiling - Copyright (C) 1996-2005, 2006, 2007, 2008 + Copyright (C) 1996-2005, 2006, 2007, 2008, 2009 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO + Copyright (C) 2009 Theobroma Systems Ltd. This file is part of CACAO. @@ -93,7 +94,7 @@ static void profile_thread(void) runs++; // Lock the thread lists. - ThreadList_lock(); + ThreadList::lock(); #if 0 /* iterate over all started threads */ @@ -157,7 +158,7 @@ static void profile_thread(void) #endif // Unlock the thread lists. - ThreadList_unlock(); + ThreadList::unlock(); } } #endif @@ -186,12 +187,26 @@ bool profile_start_thread(void) #endif -/* profile_printstats ********************************************************** - - Prints profiling statistics gathered during runtime. +/** + * Comparison function used to sort a method list from higher to lower by + * comparing the method call frequencies. + * + * @param m1 First method to be compared. + * @param m2 Second method to be compared. + * @return Returns true if the first method goes before the second method in + * the specific order, and false otherwise. + */ +#if !defined(NDEBUG) +static bool profile_compare_frequency(methodinfo* m1, methodinfo* m2) +{ + return (m1->code->frequency > m2->code->frequency); +} +#endif -*******************************************************************************/ +/** + * Prints profiling statistics gathered during runtime. + */ #if !defined(NDEBUG) void profile_printstats(void) { @@ -209,10 +224,9 @@ void profile_printstats(void) frequency = 0; cycles = 0; -#if 0 /* create new method list */ - // TODO Use a sorted container. - List* l = List_new(); + + DumpList l; /* iterate through all classes and methods */ @@ -243,33 +257,19 @@ void profile_printstats(void) frequency += code->frequency; cycles += code->cycles; - /* sort the new entry into the list */ - - if (List_empty(l) == NULL) { - List_push_back(l, m); - } - else { - for (; tlme != NULL; tlme = list_next(l, tlme)) { - /* check the frequency */ - - if (code->frequency > tlme->m->code->frequency) { - list_add_before(l, tlme, lme); - break; - } - } + /* add new entry into method list */ - /* if we are at the end of the list, add - it as last entry */ - - if (tlme == NULL) - list_add_last(l, lme); - } + l.push_back(m); } } } } } + /* sort the method list */ + + l.sort(profile_compare_frequency); + /* print all methods sorted */ printf(" frequency ratio cycles ratio method name\n"); @@ -277,10 +277,8 @@ void profile_printstats(void) /* now iterate through the list and print it */ - for (lme = list_first(l); lme != NULL; lme = list_next(l, lme)) { - /* get method of the list element */ - - m = lme->m; + for (DumpList::iterator it = l.begin(); it != l.end(); ++it) { + m = *(it); code = m->code; @@ -300,7 +298,6 @@ void profile_printstats(void) j, code->bbfrequency[j]); } } -#endif printf("----------- -------------- \n"); printf("%10d %12ld\n", frequency, (long) cycles); @@ -318,7 +315,7 @@ void profile_printstats(void) * Emacs will automagically detect them. * --------------------------------------------------------------------- * Local variables: - * mode: c + * mode: c++ * indent-tabs-mode: t * c-basic-offset: 4 * tab-width: 4 diff --git a/src/vm/jit/optimizing/profile.h b/src/vm/jit/optimizing/profile.hpp similarity index 56% rename from src/vm/jit/optimizing/profile.h rename to src/vm/jit/optimizing/profile.hpp index 06a672a80..7afb4c024 100644 --- a/src/vm/jit/optimizing/profile.h +++ b/src/vm/jit/optimizing/profile.hpp @@ -1,7 +1,8 @@ -/* src/vm/jit/optimizing/profile.h - runtime profiling +/* src/vm/jit/optimizing/profile.hpp - runtime profiling - Copyright (C) 1996-2005, 2006, 2008 + Copyright (C) 1996-2005, 2006, 2008, 2009 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO + Copyright (C) 2009 Theobroma Systems Ltd. This file is part of CACAO. @@ -23,15 +24,11 @@ */ -#ifndef _PROFILE_H -#define _PROFILE_H +#ifndef _PROFILE_HPP +#define _PROFILE_HPP #include "config.h" -#ifdef __cplusplus -extern "C" { -#endif - #include "vm/types.h" #include "vm/global.h" @@ -39,44 +36,26 @@ extern "C" { /* CPU cycle counting macros **************************************************/ -#if defined(ENABLE_PROFILING) && defined(__X86_64__) +#if defined(ENABLE_PROFILING) #define PROFILE_CYCLE_START \ - do { \ - if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) { \ - M_PUSH(RAX); \ - M_PUSH(RDX); \ - \ - M_MOV_IMM(code, REG_ITMP3); \ - M_RDTSC; \ - M_ISUB_MEMBASE(RAX, REG_ITMP3, OFFSET(codeinfo, cycles)); \ - M_ISBB_MEMBASE(RDX, REG_ITMP3, OFFSET(codeinfo, cycles) + 4); \ - \ - M_POP(RDX); \ - M_POP(RAX); \ - } \ - } while (0) + do { \ + if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) { \ + emit_profile_cycle_start(cd, code); \ + } \ + } while (0) #define PROFILE_CYCLE_STOP \ - do { \ - if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) { \ - M_PUSH(RAX); \ - M_PUSH(RDX); \ - \ - M_MOV_IMM(code, REG_ITMP3); \ - M_RDTSC; \ - M_IADD_MEMBASE(RAX, REG_ITMP3, OFFSET(codeinfo, cycles)); \ - M_IADC_MEMBASE(RDX, REG_ITMP3, OFFSET(codeinfo, cycles) + 4); \ - \ - M_POP(RDX); \ - M_POP(RAX); \ - } \ - } while (0) + do { \ + if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) { \ + emit_profile_cycle_stop(cd, code); \ + } \ + } while (0) #else -#define PROFILE_CYCLE_START -#define PROFILE_CYCLE_STOP +#define PROFILE_CYCLE_START /* nop */ +#define PROFILE_CYCLE_STOP /* nop */ #endif @@ -90,11 +69,7 @@ bool profile_start_thread(void); void profile_printstats(void); #endif -#ifdef __cplusplus -} -#endif - -#endif /* _PROFILE_H */ +#endif /* _PROFILE_HPP */ /* @@ -103,7 +78,7 @@ void profile_printstats(void); * Emacs will automagically detect them. * --------------------------------------------------------------------- * Local variables: - * mode: c + * mode: c++ * indent-tabs-mode: t * c-basic-offset: 4 * tab-width: 4 diff --git a/src/vm/jit/powerpc/emit.c b/src/vm/jit/powerpc/emit.c index 1e35669c8..7ff37e917 100644 --- a/src/vm/jit/powerpc/emit.c +++ b/src/vm/jit/powerpc/emit.c @@ -735,6 +735,28 @@ void emit_profile_basicblock(codegendata* cd, codeinfo* code, basicblock* bptr) #endif +/** + * Emit profiling code to start CPU cycle counting. + */ +#if defined(ENABLE_PROFILING) +void emit_profile_cycle_start(codegendata* cd, codeinfo* code) +{ + // XXX Not implemented yet! +} +#endif + + +/** + * Emit profiling code to stop CPU cycle counting. + */ +#if defined(ENABLE_PROFILING) +void emit_profile_cycle_stop(codegendata* cd, codeinfo* code) +{ + // XXX Not implemented yet! +} +#endif + + /* emit_verbosecall_enter ****************************************************** Generates the code for the call trace. diff --git a/src/vm/jit/s390/codegen.c b/src/vm/jit/s390/codegen.c index 77c685e77..334dbada2 100644 --- a/src/vm/jit/s390/codegen.c +++ b/src/vm/jit/s390/codegen.c @@ -330,13 +330,9 @@ void codegen_emit_instruction(jitdata* jd, instruction* iptr) constant_classref *cr = iptr->sx.val.c.ref; disp = dseg_add_unique_address(cd, cr); -/* PROFILE_CYCLE_STOP; */ - patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, cr, disp); -/* PROFILE_CYCLE_START; */ - M_ALD_DSEG(d, disp); } else { if (iptr->sx.val.anyptr == 0) { diff --git a/src/vm/jit/s390/codegen.h b/src/vm/jit/s390/codegen.h index fcaeba527..2cce3c635 100644 --- a/src/vm/jit/s390/codegen.h +++ b/src/vm/jit/s390/codegen.h @@ -816,10 +816,6 @@ static inline uint8_t N_ILL_GET_TYPE(uint8_t *instrp) { #define M_ASUB_IMM32(imm, tmpreg, reg) M_ISUB_IMM32(imm, tmpreg, reg) -#define PROFILE_CYCLE_START - -#define PROFILE_CYCLE_STOP - #endif /* _CODEGEN_H */ /* diff --git a/src/vm/jit/s390/emit.c b/src/vm/jit/s390/emit.c index 358d154e6..f93363435 100644 --- a/src/vm/jit/s390/emit.c +++ b/src/vm/jit/s390/emit.c @@ -414,6 +414,28 @@ void emit_profile_basicblock(codegendata* cd, codeinfo* code, basicblock* bptr) #endif +/** + * Emit profiling code to start CPU cycle counting. + */ +#if defined(ENABLE_PROFILING) +void emit_profile_cycle_start(codegendata* cd, codeinfo* code) +{ + // XXX Not implemented yet! +} +#endif + + +/** + * Emit profiling code to stop CPU cycle counting. + */ +#if defined(ENABLE_PROFILING) +void emit_profile_cycle_stop(codegendata* cd, codeinfo* code) +{ + // XXX Not implemented yet! +} +#endif + + /* emit_verbosecall_enter ****************************************************** Generates the code for the call trace. diff --git a/src/vm/jit/x86_64/emit.c b/src/vm/jit/x86_64/emit.c index 649270abe..830024cc0 100644 --- a/src/vm/jit/x86_64/emit.c +++ b/src/vm/jit/x86_64/emit.c @@ -600,6 +600,46 @@ void emit_profile_basicblock(codegendata* cd, codeinfo* code, basicblock* bptr) #endif +/** + * Emit profiling code to start CPU cycle counting. + */ +#if defined(ENABLE_PROFILING) +void emit_profile_cycle_start(codegendata* cd, codeinfo* code) +{ + M_PUSH(RAX); + M_PUSH(RDX); + + M_MOV_IMM(code, REG_ITMP3); + M_RDTSC; + M_ISUB_MEMBASE(RAX, REG_ITMP3, OFFSET(codeinfo, cycles)); + M_ISBB_MEMBASE(RDX, REG_ITMP3, OFFSET(codeinfo, cycles) + 4); + + M_POP(RDX); + M_POP(RAX); +} +#endif + + +/** + * Emit profiling code to stop CPU cycle counting. + */ +#if defined(ENABLE_PROFILING) +void emit_profile_cycle_stop(codegendata* cd, codeinfo* code) +{ + M_PUSH(RAX); + M_PUSH(RDX); + + M_MOV_IMM(code, REG_ITMP3); + M_RDTSC; + M_IADD_MEMBASE(RAX, REG_ITMP3, OFFSET(codeinfo, cycles)); + M_IADC_MEMBASE(RDX, REG_ITMP3, OFFSET(codeinfo, cycles) + 4); + + M_POP(RDX); + M_POP(RAX); +} +#endif + + /* emit_verbosecall_enter ****************************************************** Generates the code for the call trace. diff --git a/src/vm/vm.cpp b/src/vm/vm.cpp index 1239da685..f83e80e74 100644 --- a/src/vm/vm.cpp +++ b/src/vm/vm.cpp @@ -91,10 +91,7 @@ #include "vm/jit/jit.hpp" #include "vm/jit/methodtree.h" -#if defined(ENABLE_PROFILING) -# include "vm/jit/optimizing/profile.h" -#endif - +#include "vm/jit/optimizing/profile.hpp" #include "vm/jit/optimizing/recompiler.hpp" #if defined(ENABLE_PYTHON) -- 2.25.1