* src/vm/builtin.c (builtin_print_cycles_stats): Added.
authoredwin <none@none>
Wed, 19 Apr 2006 01:05:18 +0000 (01:05 +0000)
committeredwin <none@none>
Wed, 19 Apr 2006 01:05:18 +0000 (01:05 +0000)
(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.

configure.ac
src/cacaoh/headers.c
src/vm/Makefile.am
src/vm/builtin.c
src/vm/builtin.h
src/vm/cycles-stats.h [new file with mode: 0644]
src/vm/jit/asmpart.h
src/vm/jit/i386/asmpart.S
src/vm/vm.c

index 24938943d4dd19730510de8c46bbdc3bc8002cfe..f160c8470497ef9becb8ef57a428375fc42f3e35 100644 (file)
@@ -390,6 +390,23 @@ if test x"${ENABLE_RT_TIMING}" = "xyes"; then
 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],
index e9243fb3e7640beabeb563d90c1d1b12dcabc5c0..0bf54b0bbdec6f312aa18d8137f9405c0de0c56e 100644 (file)
@@ -31,7 +31,7 @@
             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 $
 
 */
 
@@ -143,6 +143,11 @@ void asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out) {}
 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)
 {
index db3b93cbf93763bfc895f48b946a90184d35e580..53aff9b178ebb439cc1b66e776f6b4b062d39f0e 100644 (file)
@@ -28,7 +28,7 @@
 ##
 ## 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
 
@@ -49,6 +49,11 @@ RT_TIMING_OBJ = \
        rt-timing.c
 endif
 
+if ENABLE_CYCLES_STATS
+CYCLES_STATS_SOURCE = \
+       cycles-stats.h
+endif
+
 if ENABLE_ZLIB
 ZLIB_OBJ = \
        zip.c \
@@ -73,6 +78,7 @@ libvmcore_la_SOURCES = \
        class.h \
        classcache.c \
        classcache.h \
+       $(CYCLES_STATS_SOURCE) \
        descriptor.c \
        descriptor.h \
        field.c \
index ab228980862e4d8bef6e81dfae21ccee1239162f..a03e3f801a0df8fc0f78401e22e6d71791bc4acf 100644 (file)
@@ -37,7 +37,7 @@
    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 $
 
 */
 
@@ -85,6 +85,7 @@
 #include "vm/jit/asmpart.h"
 #include "vm/jit/patcher.h"
 #include "vm/rt-timing.h"
+#include "vm/cycles-stats.h"
 
 
 /* include builtin tables *****************************************************/
@@ -1761,6 +1762,24 @@ void internal_unlock_mutex_for_object (java_objectheader *object)
 }
 #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)
@@ -1768,7 +1787,10 @@ 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;
 
@@ -1782,16 +1804,21 @@ void builtin_monitorenter(java_objectheader *o)
                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
 
@@ -1813,7 +1840,10 @@ void builtin_monitorexit(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_end, cyc;
+#endif
+
 #if !defined(NATIVE_THREADS)
        int hashValue;
 
@@ -1831,16 +1861,19 @@ void builtin_monitorexit(java_objectheader *o)
                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
 
index b4f57694c9f07463c991a73856eac5a045bdc0a5..612c31debf28262a003175b881126736e58e3d48 100644 (file)
@@ -29,7 +29,7 @@
    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 $
 
 */
 
@@ -321,6 +321,10 @@ inline java_objectheader **builtin_get_exceptionptrptr(void)
 }
 #endif
 
+#if defined(ENABLE_CYCLES_STATS)
+void builtin_print_cycles_stats(FILE *file);
+#endif
+
 #endif /* _BUILTIN_H */
 
 
diff --git a/src/vm/cycles-stats.h b/src/vm/cycles-stats.h
new file mode 100644 (file)
index 0000000..084ba1d
--- /dev/null
@@ -0,0 +1,113 @@
+/* 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:
+ */
index 5788cda17297efe355e5c98b8abcb2bce1bda85f..0388eab413928e63dbc337d62b152cde7df83a9b 100644 (file)
@@ -30,7 +30,7 @@
    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 $
 
 */
 
@@ -179,6 +179,8 @@ u1*  asm_initialize_thread_stack(void *func, u1 *stack);
 /* cache flush function */
 void asm_cacheflush(u1 *addr, s4 nbytes);
 
+u8 asm_get_cycle_count(void);
+
 #endif /* _ASMPART_H */
 
 
index eb563e5a5211a3c53132b7e809ff9678e87e0b4c..a4d6b1270c818520ee2b89dd88fe68da3ea9d8aa 100644 (file)
@@ -31,7 +31,7 @@
    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 $
 
 */
 
@@ -81,6 +81,8 @@
        .globl asm_criticalsections
        .globl asm_getclassvalues_atomic
 
+       .globl asm_get_cycle_count
+
 
 /* asm_md_init *****************************************************************
 
@@ -827,6 +829,22 @@ asm_criticalsections:
 #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
index 8067172b9dc4647473084fdbd61fb2cde9329cc0..d0e82f2428f655d4acef40d38e436812ba7f5c9b 100644 (file)
@@ -1343,6 +1343,10 @@ void vm_exit_handler(void)
        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");