(builtin_monitorenter): Gather cycle count statistics.
(builtin_monitorexit): Likewise.
* src/vm/builtin.h (builtin_print_cycles_stats): Added.
* src/vm/jit/i386/asmpart.S (asm_get_cycle_count): Added.
* src/vm/jit/asmpart.h (asm_get_cycle_count): Added.
* src/vm/vm.c (vm_exit_handler): Call builtin_print_cycles_stats.
* src/vm/cycles-stats.h: New file.
* src/vm/Makefile.am (CYCLES_STATS_SOURCE): Added.
* src/cacaoh/headers.c (asm_get_cycle_count): Dummy implementation added.
* configure.ac (--enable-cycles-stats): Added configure option.
fi
+dnl check for cycle count statistics
+AC_MSG_CHECKING(whether cycle count statistics should be enabled)
+AC_ARG_ENABLE([cycles-stats],
+ [AS_HELP_STRING(--enable-cycles-stats,enable cycle count statistics [[default=no]])],
+ [case "${enableval}" in
+ yes) ENABLE_CYCLES_STATS=yes;;
+ *) ENABLE_CYCLES_STATS=no;;
+ esac],
+ [ENABLE_CYCLES_STATS=no])
+AC_MSG_RESULT(${ENABLE_CYCLES_STATS})
+AM_CONDITIONAL([ENABLE_CYCLES_STATS], test x"${ENABLE_CYCLES_STATS}" = "xyes")
+
+if test x"${ENABLE_CYCLES_STATS}" = "xyes"; then
+ AC_DEFINE([ENABLE_CYCLES_STATS], 1, [enable cycle count statistics])
+fi
+
+
dnl check for JVMTI
AC_MSG_CHECKING(whether to compile JVMTI support)
AC_ARG_ENABLE([jvmti],
Christian Thalinger
Edwin Steiner
- $Id: headers.c 4598 2006-03-14 22:16:47Z edwin $
+ $Id: headers.c 4792 2006-04-19 01:05:18Z edwin $
*/
void intrp_asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out) {}
#endif
+u8 asm_get_cycle_count(void)
+{
+ return 0;
+}
+
void *Java_java_lang_VMObject_clone(void *env, void *clazz, void * this)
{
##
## Changes:
##
-## $Id: Makefile.am 4762 2006-04-12 22:20:49Z edwin $
+## $Id: Makefile.am 4792 2006-04-19 01:05:18Z edwin $
## Process this file with automake to produce Makefile.in
rt-timing.c
endif
+if ENABLE_CYCLES_STATS
+CYCLES_STATS_SOURCE = \
+ cycles-stats.h
+endif
+
if ENABLE_ZLIB
ZLIB_OBJ = \
zip.c \
class.h \
classcache.c \
classcache.h \
+ $(CYCLES_STATS_SOURCE) \
descriptor.c \
descriptor.h \
field.c \
calls instead of machine instructions, using the C calling
convention.
- $Id: builtin.c 4781 2006-04-17 15:20:45Z edwin $
+ $Id: builtin.c 4792 2006-04-19 01:05:18Z edwin $
*/
#include "vm/jit/asmpart.h"
#include "vm/jit/patcher.h"
#include "vm/rt-timing.h"
+#include "vm/cycles-stats.h"
/* include builtin tables *****************************************************/
}
#endif
+CYCLES_STATS_DECLARE(builtin_monitorenter,100,2)
+CYCLES_STATS_DECLARE(builtin_monitorexit,100,2)
+CYCLES_STATS_DECLARE(builtin_overhead,80,1)
+
+#if defined(ENABLE_CYCLES_STATS)
+void builtin_print_cycles_stats(FILE *file)
+{
+ s4 i;
+
+ fprintf(file,"builtin cylce count statistics:\n");
+
+ CYCLES_STATS_PRINT(builtin_monitorenter,file);
+ CYCLES_STATS_PRINT(builtin_monitorexit ,file);
+ CYCLES_STATS_PRINT(builtin_overhead ,file);
+
+ fprintf(file,"\n");
+}
+#endif /* defined(ENABLE_CYCLES_STATS) */
#if defined(USE_THREADS)
void builtin_monitorenter(java_objectheader *o)
#if defined(ENABLE_RT_TIMING)
struct timespec time_start, time_overhead, time_lock;
#endif
-
+#if defined(ENABLE_CYCLES_STATS)
+ u8 cycles_start, cycles_overhead, cycles_end;
+#endif
+
#if !defined(NATIVE_THREADS)
int hashValue;
internal_lock_mutex_for_object(o);
--blockInts;
-#else
+#else /* defined(NATIVE_THREADS) */
RT_TIMING_GET_TIME(time_start);
RT_TIMING_GET_TIME(time_overhead);
+ CYCLES_STATS_GET(cycles_start);
+ CYCLES_STATS_GET(cycles_overhead);
monitorEnter((threadobject *) THREADOBJECT, o);
+ CYCLES_STATS_GET(cycles_end);
+ CYCLES_STATS_COUNT(builtin_monitorenter, cycles_end - cycles_overhead);
+ CYCLES_STATS_COUNT(builtin_overhead , cycles_overhead - cycles_start);
RT_TIMING_GET_TIME(time_lock);
RT_TIMING_TIME_DIFF(time_start,time_overhead,RT_TIMING_LOCK_MEASERR);
RT_TIMING_TIME_DIFF(time_overhead,time_lock,RT_TIMING_LOCK_LOCK);
-#endif
+#endif /* defined(NATIVE_THREADS) */
}
#endif
#if defined(ENABLE_RT_TIMING)
struct timespec time_start, time_overhead, time_lock;
#endif
-
+#if defined(ENABLE_CYCLES_STATS)
+ u8 cycles_start, cycles_end, cyc;
+#endif
+
#if !defined(NATIVE_THREADS)
int hashValue;
internal_unlock_mutex_for_object(o);
--blockInts;
-#else
+#else /* defined(NATIVE_THREADS) */
RT_TIMING_GET_TIME(time_start);
RT_TIMING_GET_TIME(time_overhead);
+ CYCLES_STATS_GET(cycles_start);
monitorExit((threadobject *) THREADOBJECT, o);
+ CYCLES_STATS_GET(cycles_end);
+ CYCLES_STATS_COUNT(builtin_monitorexit, cycles_end - cycles_start);
RT_TIMING_GET_TIME(time_lock);
RT_TIMING_TIME_DIFF(time_start,time_overhead,RT_TIMING_LOCK_MEASERR);
RT_TIMING_TIME_DIFF(time_overhead,time_lock,RT_TIMING_LOCK_UNLOCK);
-#endif
+#endif /* defined(NATIVE_THREADS) */
}
#endif
Changes: Edwin Steiner
Christian Thalinger
- $Id: builtin.h 4749 2006-04-11 10:20:18Z twisti $
+ $Id: builtin.h 4792 2006-04-19 01:05:18Z edwin $
*/
}
#endif
+#if defined(ENABLE_CYCLES_STATS)
+void builtin_print_cycles_stats(FILE *file);
+#endif
+
#endif /* _BUILTIN_H */
--- /dev/null
+/* src/vm/cycles-stats.h - macros for cycle count statistics
+
+ Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+ Contact: cacao@cacaojvm.org
+
+ Authors: Edwin Steiner
+
+ Changes:
+
+ $Id$
+
+*/
+
+#ifndef _CYCLES_STATS_H
+#define _CYCLES_STATS_H
+
+#include "config.h"
+#include "vm/types.h"
+
+#if defined(ENABLE_CYCLES_STATS)
+
+#define CYCLES_STATS_DECLARE(name,nbins,divisor) \
+ static const int CYCLES_STATS_##name##_MAX = (nbins); \
+ static const int CYCLES_STATS_##name##_DIV = (divisor); \
+ static u4 cycles_stats_##name##_bins[(nbins) + 1] = { 0 }; \
+ static u4 cycles_stats_##name##_count = 0; \
+ static u8 cycles_stats_##name##_max = 0; \
+ static u8 cycles_stats_##name##_min = 1000000000;
+
+#define CYCLES_STATS_GET(var) \
+ (var) = asm_get_cycle_count() \
+
+#define CYCLES_STATS_COUNT(name,cyclesexpr) \
+ do { \
+ u8 cyc = (cyclesexpr); \
+ if (cyc > cycles_stats_##name##_max) \
+ cycles_stats_##name##_max = cyc; \
+ if (cyc < cycles_stats_##name##_min) \
+ cycles_stats_##name##_min = cyc; \
+ cyc /= CYCLES_STATS_##name##_DIV; \
+ if (cyc < CYCLES_STATS_##name##_MAX) \
+ cycles_stats_##name##_bins[cyc]++; \
+ else \
+ cycles_stats_##name##_bins[CYCLES_STATS_##name##_MAX]++; \
+ cycles_stats_##name##_count++; \
+ } while (0)
+
+#define CYCLES_STATS_PRINT(name,file) \
+ do { \
+ s4 local_i; \
+ fprintf(file,"\t%s: %u calls\n", \
+ #name, cycles_stats_##name##_count); \
+ fprintf(file,"\t%s cycles distribution:\n", #name); \
+ fprintf(file,"\t\tmin = %llu\n", \
+ (unsigned long long)cycles_stats_##name##_min); \
+ for (local_i=0; local_i<CYCLES_STATS_##name##_MAX; ++local_i) { \
+ fprintf(file,"\t\t< %5d: %u\n", \
+ (local_i+1) * CYCLES_STATS_##name##_DIV, \
+ cycles_stats_##name##_bins[local_i]); \
+ } \
+ fprintf(file,"\t\t>= %5d: %u\n", \
+ CYCLES_STATS_##name##_MAX * CYCLES_STATS_##name##_DIV, \
+ cycles_stats_##name##_bins[local_i]); \
+ fprintf(file,"\t\tmax = %llu\n", \
+ (unsigned long long)cycles_stats_##name##_max); \
+ } while (0)
+
+
+#else /* !defined(ENABLE_CYCLES_STATS) */
+
+#define CYCLES_STATS_DECLARE(name,nbins,divisor)
+#define CYCLES_STATS_GET(var)
+#define CYCLES_STATS_COUNT(name,cyclesexpr)
+#define CYCLES_STATS_PRINT(name,file)
+
+#endif /* defined(ENABLE_CYCLES_STATS) */
+
+#endif /* _CYCLES_STATS_H */
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
Changes: Christian Thalinger
Edwin Steiner
- $Id: asmpart.h 4707 2006-03-30 09:52:49Z twisti $
+ $Id: asmpart.h 4792 2006-04-19 01:05:18Z edwin $
*/
/* cache flush function */
void asm_cacheflush(u1 *addr, s4 nbytes);
+u8 asm_get_cycle_count(void);
+
#endif /* _ASMPART_H */
Changes: Joseph Wenninger
Edwin Steiner
- $Id: asmpart.S 4749 2006-04-11 10:20:18Z twisti $
+ $Id: asmpart.S 4792 2006-04-19 01:05:18Z edwin $
*/
.globl asm_criticalsections
.globl asm_getclassvalues_atomic
+ .globl asm_get_cycle_count
+
/* asm_md_init *****************************************************************
#endif
+/* asm_get_cycle_count *********************************************************
+
+ Get the current time-stamp counter from the CPU.
+
+*******************************************************************************/
+
+asm_get_cycle_count:
+ push bp
+ mov sp,bp /* save stackptr */
+
+ rdtsc
+
+ leave
+ ret
+
+
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where
rt_timing_print_time_stats(stderr);
#endif
+#if defined(ENABLE_CYCLES_STATS)
+ builtin_print_cycles_stats(stderr);
+#endif
+
if (opt_verbose || getcompilingtime || opt_stat) {
log_text("CACAO terminated");