1 /* src/vm/jit/profile.c - runtime profiling
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Christian Thalinger
31 $Id: cacao.c 4357 2006-01-22 23:33:38Z twisti $
42 #include "mm/memory.h"
43 #include "native/jni.h"
44 #include "native/include/java_lang_Thread.h"
45 #include "native/include/java_lang_VMThread.h"
47 #if defined(USE_THREADS)
48 # if defined(NATIVE_THREADS)
49 # include "threads/native/threads.h"
51 # include "threads/green/threads.h"
55 #include "vm/builtin.h"
57 #include "vm/classcache.h"
58 #include "vm/method.h"
59 #include "vm/options.h"
60 #include "vm/stringlocal.h"
63 /* list_method_entry **********************************************************/
65 typedef struct list_method_entry list_method_entry;
67 struct list_method_entry {
73 /* global variables ***********************************************************/
75 #if defined(USE_THREADS)
76 static java_lang_VMThread *profile_vmthread;
80 /* profile_init ****************************************************************
82 Initializes the profile global lock.
84 *******************************************************************************/
86 bool profile_init(void)
94 /* profile_thread **************************************************************
98 *******************************************************************************/
100 #if defined(USE_THREADS)
101 static void profile_thread(void)
106 /* sleep thread for 100 nanos */
108 thread_sleep(0, 100);
111 /* get the lock on the finalizer lock object, so we can call wait */
113 builtin_monitorenter(lock_profile_thread);
117 wait_cond_for_object(lock_profile_thread, 0, 100);
121 builtin_monitorexit(lock_profile_thread);
124 /* if ((i++ % 1000) == 0) */
125 /* printf("profile_thread: %d\n", i); */
131 /* profile_start_thread ********************************************************
133 Starts the profile sampling thread.
135 *******************************************************************************/
137 #if defined(USE_THREADS)
138 bool profile_start_thread(void)
142 /* create the profile object */
145 (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
147 if (!profile_vmthread)
150 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
152 t->vmThread = profile_vmthread;
153 t->name = javastring_new_from_ascii("Profiling Sampler");
157 profile_vmthread->thread = t;
159 /* actually start the profile sampling thread */
161 threads_start_thread(t, profile_thread);
163 /* everything's ok */
170 /* profile_printstats **********************************************************
172 Prints profiling statistics gathered during runtime.
174 *******************************************************************************/
177 void profile_printstats(void)
180 list_method_entry *lme;
181 list_method_entry *tlme;
185 classcache_name_entry *nmen;
186 classcache_class_entry *clsen;
195 /* create new method list */
199 list_init(l, OFFSET(list_method_entry, linkage));
201 /* iterate through all classes and methods */
203 for (slot = 0; slot < hashtable_classcache.size; slot++) {
204 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
206 for (; nmen; nmen = nmen->hashlink) {
207 /* iterate over all class entries */
209 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
215 /* compile all class methods */
217 for (i = 0; i < c->methodscount; i++) {
218 m = &(c->methods[i]);
220 /* was this method actually called? */
222 if (m->frequency > 0) {
223 /* add to overall stats */
225 frequency += m->frequency;
228 /* create new list entry */
230 lme = NEW(list_method_entry);
233 /* sort the new entry into the list */
235 if ((tlme = list_first(l)) == NULL) {
236 list_addfirst(l, lme);
239 for (; tlme != NULL; tlme = list_next(l, tlme)) {
240 /* check the frequency */
242 if (m->frequency > tlme->m->frequency) {
243 list_add_before(l, tlme, lme);
248 /* if we are at the end of the list, add
252 list_addlast(l, lme);
260 /* print all methods sorted */
262 printf(" frequency ratio cycles ratio method name\n");
263 printf("----------- --------- -------------- --------- -------------\n");
265 /* now iterate through the list and print it */
267 for (lme = list_first(l); lme != NULL; lme = list_next(l, lme)) {
268 /* get method of the list element */
272 printf("%10d %.5f %12ld %.5f ",
274 (double) m->frequency / (double) frequency,
276 (double) m->cycles / (double) cycles);
280 /* print basic block frequencies */
283 for (j = 0; j < m->basicblockcount; j++)
284 printf(" L%03d: %10d\n",
285 j, m->bbfrequency[j]);
289 printf("----------- -------------- \n");
290 printf("%10d %12ld\n", frequency, (long)cycles);
292 #endif /* !defined(NDEBUG) */
296 * These are local overrides for various environment variables in Emacs.
297 * Please do not remove this and leave it at the end of the file, where
298 * Emacs will automagically detect them.
299 * ---------------------------------------------------------------------
302 * indent-tabs-mode: t