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 $
43 #include "mm/memory.h"
44 #include "native/jni.h"
45 #include "native/include/java_lang_Thread.h"
46 #include "native/include/java_lang_VMThread.h"
48 #if defined(ENABLE_THREADS)
49 # include "threads/native/threads.h"
52 #include "vm/builtin.h"
54 #include "vm/classcache.h"
55 #include "vm/method.h"
56 #include "vm/options.h"
57 #include "vm/stringlocal.h"
58 #include "vm/jit/jit.h"
59 #include "vm/jit/methodheader.h"
60 #include "vm/jit/recompile.h"
63 /* global variables ***********************************************************/
65 #if defined(ENABLE_THREADS)
66 static java_lang_VMThread *profile_vmthread;
70 /* profile_init ****************************************************************
72 Initializes the profile global lock.
74 *******************************************************************************/
76 bool profile_init(void)
84 /* profile_thread **************************************************************
88 *******************************************************************************/
94 #if defined(ENABLE_THREADS)
95 static void profile_thread(void)
105 /* sleep thread for 0.5-1.0 ms */
107 nanos = 500 + (int) (500.0 * (rand() / (RAND_MAX + 1.0)));
108 /* fprintf(stderr, "%d\n", nanos); */
110 threads_sleep(0, nanos);
113 /* iterate over all started threads */
118 /* is this a Java thread? */
120 if (t->flags & THREAD_FLAG_JAVA) {
121 /* send SIGUSR2 to thread to get the current PC */
123 pthread_kill(t->tid, SIGUSR2);
125 /* the thread object now contains the current thread PC */
129 /* get the PV for the current PC */
131 pv = codegen_get_pv_from_pc_nocheck(pc);
133 /* get methodinfo pointer from data segment */
139 code = *((codeinfo **) (pv + CodeinfoPointer));
141 /* For asm_vm_call_method the codeinfo pointer is
142 NULL (which is also in the method tree). */
147 /* native methods are never recompiled */
149 if (!(m->flags & ACC_NATIVE)) {
150 /* increase the method incovation counter */
155 if (code->frequency > 500) {
156 /* clear frequency count before
161 /* add this method to the method list
162 and start recompilation */
164 recompile_queue_method(m);
172 } while ((t != NULL) && (t != mainthreadobj));
178 /* profile_start_thread ********************************************************
180 Starts the profile sampling thread.
182 *******************************************************************************/
184 #if defined(ENABLE_THREADS)
185 bool profile_start_thread(void)
189 /* create the profile object */
192 (java_lang_VMThread *) builtin_new(class_java_lang_VMThread);
194 if (profile_vmthread == NULL)
197 t = (java_lang_Thread *) builtin_new(class_java_lang_Thread);
199 t->vmThread = profile_vmthread;
200 t->name = javastring_new_from_ascii("Profiling Sampler");
204 profile_vmthread->thread = t;
206 /* actually start the profile sampling thread */
208 threads_start_thread(t, profile_thread);
210 /* everything's ok */
217 /* profile_printstats **********************************************************
219 Prints profiling statistics gathered during runtime.
221 *******************************************************************************/
224 void profile_printstats(void)
227 list_method_entry *lme;
228 list_method_entry *tlme;
233 classcache_name_entry *nmen;
234 classcache_class_entry *clsen;
243 /* create new method list */
245 l = list_create(OFFSET(list_method_entry, linkage));
247 /* iterate through all classes and methods */
249 for (slot = 0; slot < hashtable_classcache.size; slot++) {
250 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
252 for (; nmen; nmen = nmen->hashlink) {
253 /* iterate over all class entries */
255 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
261 /* interate over all class methods */
263 for (i = 0; i < c->methodscount; i++) {
264 m = &(c->methods[i]);
268 /* was this method actually called? */
270 if ((code != NULL) && (code->frequency > 0)) {
271 /* add to overall stats */
273 frequency += code->frequency;
274 cycles += code->cycles;
276 /* create new list entry */
278 lme = NEW(list_method_entry);
281 /* sort the new entry into the list */
283 if ((tlme = list_first(l)) == NULL) {
284 list_add_first(l, lme);
287 for (; tlme != NULL; tlme = list_next(l, tlme)) {
288 /* check the frequency */
290 if (code->frequency > tlme->m->code->frequency) {
291 list_add_before(l, tlme, lme);
296 /* if we are at the end of the list, add
300 list_add_last(l, lme);
308 /* print all methods sorted */
310 printf(" frequency ratio cycles ratio method name\n");
311 printf("----------- --------- -------------- --------- -------------\n");
313 /* now iterate through the list and print it */
315 for (lme = list_first(l); lme != NULL; lme = list_next(l, lme)) {
316 /* get method of the list element */
322 printf("%10d %.5f %12ld %.5f ",
324 (double) code->frequency / (double) frequency,
326 (double) code->cycles / (double) cycles);
330 /* print basic block frequencies */
333 for (j = 0; j < code->basicblockcount; j++)
334 printf(" L%03d: %10d\n",
335 j, code->bbfrequency[j]);
339 printf("----------- -------------- \n");
340 printf("%10d %12ld\n", frequency, (long) cycles);
342 printf("\nruns : %10d\n", runs);
343 printf("hits : %10d\n", hits);
344 printf("misses: %10d\n", misses);
346 #endif /* !defined(NDEBUG) */
350 * These are local overrides for various environment variables in Emacs.
351 * Please do not remove this and leave it at the end of the file, where
352 * Emacs will automagically detect them.
353 * ---------------------------------------------------------------------
356 * indent-tabs-mode: t