CACAO
profile.cpp
Go to the documentation of this file.
1 /* src/vm/jit/optimizing/profile.cpp - runtime profiling
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5  Copyright (C) 2009 Theobroma Systems Ltd.
6 
7  This file is part of CACAO.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2, or (at
12  your option) any later version.
13 
14  This program is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  02110-1301, USA.
23 
24 */
25 
26 
27 #include "config.h"
28 
29 #include <assert.h>
30 #include <stdlib.h>
31 
32 #include "vm/types.hpp"
33 
34 #include "mm/memory.hpp"
35 
36 #include "threads/threadlist.hpp"
37 #include "threads/thread.hpp"
38 
39 #include "vm/class.hpp"
40 #include "vm/classcache.hpp"
41 #include "vm/method.hpp"
42 #include "vm/options.hpp"
43 #include "vm/string.hpp"
44 
45 #include "vm/jit/builtin.hpp"
46 #include "vm/jit/code.hpp"
47 #include "vm/jit/jit.hpp"
48 #include "vm/jit/methodheader.hpp"
49 #include "vm/jit/methodtree.hpp"
50 
52 
53 
54 /* profile_init ****************************************************************
55 
56  Initializes the profile global lock.
57 
58 *******************************************************************************/
59 
60 bool profile_init(void)
61 {
62  /* everything's ok */
63 
64  return true;
65 }
66 
67 
68 /* profile_thread **************************************************************
69 
70  XXX
71 
72 *******************************************************************************/
73 
74 static s4 runs = 0;
75 #if !defined(NDEBUG)
76 static s4 hits = 0;
77 static s4 misses = 0;
78 #endif /* !defined(NDEBUG) */
79 
80 static void profile_thread(void)
81 {
82  s4 nanos;
83 #if 0
84  threadobject *t;
85  u1 *pc;
86  u1 *pv;
87  methodinfo *m;
88  codeinfo *code;
89 #endif
90 
91  while (true) {
92  /* sleep thread for 0.5-1.0 ms */
93 
94  nanos = 500 + (int) (500.0 * (rand() / (RAND_MAX + 1.0)));
95 /* fprintf(stderr, "%d\n", nanos); */
96 
97  threads_sleep(0, nanos);
98  runs++;
99 
100 #if 0
101  // Lock the thread lists.
102  ThreadList::get()->lock();
103 
104  /* iterate over all started threads */
105 
106  for (t = ThreadList_first(); t != NULL; t = ThreadList_next(t)) {
107  /* is this a Java thread? */
108 
109  if (!(t->flags & THREAD_FLAG_JAVA))
110  continue;
111 
112  /* send SIGUSR2 to thread to get the current PC */
113  /* XXX write a threads-function for that */
114 
115  pthread_kill(t->impl.tid, SIGUSR2);
116 
117  /* the thread object now contains the current thread PC */
118 
119  pc = t->pc;
120 
121  /* Get the PV for the current PC. */
122 
123  pv = methodtree_find_nocheck(pc);
124 
125  /* get methodinfo pointer from data segment */
126 
127  if (pv == NULL) {
128  misses++;
129  }
130  else {
131  code = *((codeinfo **) (pv + CodeinfoPointer));
132 
133  /* For asm_vm_call_method the codeinfo pointer is NULL
134  (which is also in the method tree). */
135 
136  if (code != NULL) {
137  m = code->m;
138 
139  /* native methods are never recompiled */
140 
141  if (!(m->flags & ACC_NATIVE)) {
142  /* increase the method incovation counter */
143 
144  code->frequency++;
145  hits++;
146 
147  if (code->frequency > 500) {
148  /* clear frequency count before
149  recompilation */
150 
151  code->frequency = 0;
152 
153  /* add this method to the method list and
154  start recompilation */
155 
157  }
158  }
159  }
160  }
161  }
162 
163  // Unlock the thread lists.
164  ThreadList::get()->unlock();
165 #endif
166  }
167 }
168 
169 /* profile_start_thread ********************************************************
170 
171  Starts the profile sampling thread.
172 
173 *******************************************************************************/
174 
176 {
177  Utf8String name = Utf8String::from_utf8("Profiling Sampler");
178 
180  return false;
181 
182  /* everything's ok */
183 
184  return true;
185 }
186 
187 
188 /**
189  * Comparison function used to sort a method list from higher to lower by
190  * comparing the method call frequencies.
191  *
192  * @param m1 First method to be compared.
193  * @param m2 Second method to be compared.
194  * @return Returns true if the first method goes before the second method in
195  * the specific order, and false otherwise.
196  */
197 #if !defined(NDEBUG)
199 {
200  return (m1->code->frequency > m2->code->frequency);
201 }
202 #endif
203 
204 
205 /**
206  * Prints profiling statistics gathered during runtime.
207  */
208 #if !defined(NDEBUG)
210 {
211  classinfo *c;
212  methodinfo *m;
213  codeinfo *code;
214  u4 slot;
215  classcache_name_entry *nmen;
216  classcache_class_entry *clsen;
217  s4 i;
218  s4 j;
219  u4 frequency;
220  s8 cycles;
221 
222  frequency = 0;
223  cycles = 0;
224 
225  /* create new method list */
226 
227  std::list<methodinfo*> l;
228  //DumpList<methodinfo*> l; // XXX currently the DumpList doesn't work here.
229 
230  /* iterate through all classes and methods */
231 
232  for (slot = 0; slot < hashtable_classcache.size; slot++) {
234 
235  for (; nmen; nmen = nmen->hashlink) {
236  /* iterate over all class entries */
237 
238  for (clsen = nmen->classes; clsen; clsen = clsen->next) {
239  c = clsen->classobj;
240 
241  if (c == NULL)
242  continue;
243 
244  /* interate over all class methods */
245 
246  for (i = 0; i < c->methodscount; i++) {
247  m = &(c->methods[i]);
248 
249  code = m->code;
250 
251  /* was this method actually called? */
252 
253  if ((code != NULL) && (code->frequency > 0)) {
254  /* add to overall stats */
255 
256  frequency += code->frequency;
257  cycles += code->cycles;
258 
259  /* add new entry into method list */
260 
261  l.push_back(m);
262  }
263  }
264  }
265  }
266  }
267 
268  /* sort the method list */
269 
271 
272  /* print all methods sorted */
273 
274  printf(" frequency ratio cycles ratio method name\n");
275  printf("----------- --------- -------------- --------- -------------\n");
276 
277  /* now iterate through the list and print it */
278 
279  for (DumpList<methodinfo*>::iterator it = l.begin(); it != l.end(); ++it) {
280  m = *(it);
281 
282  code = m->code;
283 
284  printf("%10d %.5f %12ld %.5f ",
285  code->frequency,
286  (double) code->frequency / (double) frequency,
287  (long) code->cycles,
288  (double) code->cycles / (double) cycles);
289 
290  method_println(m);
291 
292  /* print basic block frequencies */
293 
294  if (opt_prof_bb) {
295  for (j = 0; j < code->basicblockcount; j++)
296  printf(" L%03d: %10d\n",
297  j, code->bbfrequency[j]);
298  }
299  }
300 
301  printf("----------- -------------- \n");
302  printf("%10d %12ld\n", frequency, (long) cycles);
303 
304  printf("\nruns : %10d\n", runs);
305  printf("hits : %10d\n", hits);
306  printf("misses: %10d\n", misses);
307 }
308 #endif /* !defined(NDEBUG) */
309 
310 
311 /*
312  * These are local overrides for various environment variables in Emacs.
313  * Please do not remove this and leave it at the end of the file, where
314  * Emacs will automagically detect them.
315  * ---------------------------------------------------------------------
316  * Local variables:
317  * mode: c++
318  * indent-tabs-mode: t
319  * c-basic-offset: 4
320  * tab-width: 4
321  * End:
322  * vim:noexpandtab:sw=4:ts=4:
323  */
jlong jlong jlong jlong jint jmethodID jint slot
Definition: jvmti.h:497
#define pv
Definition: md-asm.hpp:65
methodinfo * methods
Definition: class.hpp:113
classcache_class_entry * next
Definition: classcache.hpp:103
static bool profile_compare_frequency(methodinfo *m1, methodinfo *m2)
Comparison function used to sort a method list from higher to lower by comparing the method call freq...
Definition: profile.cpp:198
bool threads_thread_start_internal(Utf8String name, functionptr f)
Definition: thread.cpp:402
hashtable hashtable_classcache
Definition: classcache.cpp:223
uint8_t u1
Definition: types.hpp:40
JNIEnv jclass jobject const char * name
Definition: jvmti.h:312
int64_t s8
Definition: types.hpp:48
static s4 runs
Definition: profile.cpp:74
methodinfo * m
Definition: code.hpp:75
cacao::detail::threadobject impl
Definition: thread.hpp:91
static ThreadList * get()
Provides access to singleton.
Definition: threadlist.hpp:62
classcache_class_entry * classes
Definition: classcache.hpp:95
void method_println(methodinfo *m)
Definition: method.cpp:1218
static void profile_thread(void)
Definition: profile.cpp:80
void ** ptr
Definition: hashtable.hpp:781
void profile_printstats(void)
Prints profiling statistics gathered during runtime.
Definition: profile.cpp:209
void * methodtree_find_nocheck(void *pc)
Definition: methodtree.cpp:223
static Utf8String from_utf8(const char *, size_t)
Definition: utf8.cpp:335
MIIterator i
#define CodeinfoPointer
int32_t s4
Definition: types.hpp:45
static s4 hits
Definition: profile.cpp:76
codeinfo * code
Definition: method.hpp:103
int32_t methodscount
Definition: class.hpp:112
uint32_t u4
Definition: types.hpp:46
static s4 misses
Definition: profile.cpp:77
bool profile_start_thread(void)
Definition: profile.cpp:175
#define pc
Definition: md-asm.hpp:56
bool profile_init(void)
Definition: profile.cpp:60
Definition: classcache.hpp:98
List implementation with dump memory.
Definition: list.hpp:80
classcache_name_entry * hashlink
Definition: classcache.hpp:94
void threads_sleep(int64_t millis, int32_t nanos)
s4 flags
Definition: method.hpp:70
void Recompiler_queue_method(methodinfo *m)
Definition: recompiler.cpp:213
classinfo * classobj
Definition: classcache.hpp:100
Definition: classcache.hpp:91
#define printf(...)
Definition: ssa2.cpp:40