CACAO
statistics.cpp
Go to the documentation of this file.
1 /* src/vm/statistics.cpp - global variables for statistics
2 
3  Copyright (C) 1996-2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 
26 #include <stdint.h>
27 
28 #include "vm/rt-timing.hpp"
29 #include "vm/statistics.hpp"
30 #include "vm/types.hpp"
31 
32 
33 /* global variables ***********************************************************/
34 
37 
38 RT_REGISTER_GROUP(legacy_group,"legacy group","legacy group")
39 RT_REGISTER_GROUP_TIMER(loadingtime,"loading time", "Time for loading classes",legacy_group)
40 RT_REGISTER_GROUP_TIMER(compilingtime,"compiling time", "Time for compiling code",legacy_group)
41 
42 
43 /* loadingtime_stop ************************************************************
44 
45  XXX
46 
47 *******************************************************************************/
48 
50 {
52 
53  if (loadingtime_recursion == 1) {
54  RT_TIMER_START(loadingtime);
55  }
56 }
57 
58 
59 /* loadingtime_stop ************************************************************
60 
61  XXX
62 
63 *******************************************************************************/
64 
65 void loadingtime_stop(void)
66 {
67  if (loadingtime_recursion == 1) {
68  RT_TIMER_STOP(loadingtime);
69  }
70 
72 }
73 
74 
75 /* compilingtime_stop **********************************************************
76 
77  XXX
78 
79 *******************************************************************************/
80 
82 {
84 
85  if (compilingtime_recursion == 1) {
86  RT_TIMER_START(compilingtime);
87  }
88 }
89 
90 /* compilingtime_stop **********************************************************
91 
92  XXX
93 
94 *******************************************************************************/
95 
97 {
98  if (compilingtime_recursion == 1) {
99  RT_TIMER_STOP(compilingtime);
100  }
101 
103 }
104 
105 /* print_stats *****************************************************************
106 
107  outputs detailed compiler statistics
108 
109 *******************************************************************************/
110 
111 #if 0
112 void print_stats(void)
113 {
114  s4 i;
115  float f;
116  s4 sum;
117 
118 
119  // DONE
120  dolog("Number of JIT compiler calls: %6d", count_jit_calls);
121  // DONE
122  dolog("Number of compiled methods: %6d", count_methods);
123 
124  // DONE
125  dolog("Number of compiled basic blocks: %6d",
126  count_basic_blocks);
127  // DONE
128  dolog("Number of max. basic blocks per method: %6d",
129  count_max_basic_blocks);
130 
131  // DONE
132  dolog("Number of compiled JavaVM instructions: %6d",
133  count_javainstr);
134  // DONE
135  dolog("Number of max. JavaVM instructions per method: %6d",
136  count_max_javainstr);
137  // PARTLY DONE
138  dolog("Size of compiled JavaVM instructions: %6d(%d)",
139  count_javacodesize, count_javacodesize - count_methods * 18);
140 
141  // DONE
142  dolog("Size of compiled Exception Tables: %d", count_javaexcsize);
143  // XXX 4 byte instructions hardcoded oO. I guess this is no longer valid.
144  dolog("Number of Machine-Instructions: %d", count_code_len >> 2);
145  // DONE
146  dolog("Number of Spills (write to memory) <all [i/l/a|flt|dbl]>: %d [%d|%d|%d]",
147  count_spills_write_ila + count_spills_write_flt + count_spills_write_dbl,
148  count_spills_write_ila, count_spills_write_flt, count_spills_write_dbl);
149  // DONE
150  dolog("Number of Spills (read from memory) <all [i/l/a|flt|dbl]>: %d [%d|%d|%d]",
151  count_spills_read_ila + count_spills_read_flt + count_spills_read_dbl,
152  count_spills_read_ila, count_spills_read_flt, count_spills_read_dbl);
153  // NOT used?!
154  dolog("Number of Activ Pseudocommands: %6d", count_pcmd_activ);
155  // NOT used?!
156  dolog("Number of Drop Pseudocommands: %6d", count_pcmd_drop);
157  // DONE
158  dolog("Number of Const Pseudocommands: %6d (zero:%5d)",
159  count_pcmd_load, count_pcmd_zero);
160  // NOT used?!
161  dolog("Number of ConstAlu Pseudocommands: %6d (cmp: %5d, store:%5d)",
162  count_pcmd_const_alu, count_pcmd_const_bra, count_pcmd_const_store);
163  // NOT used?!
164  dolog("Number of Move Pseudocommands: %6d", count_pcmd_move);
165  // DONE
166  dolog("Number of Load Pseudocommands: %6d", count_load_instruction);
167  // DONE
168  // count_pcmd_store_comb NOT used?!
169  dolog("Number of Store Pseudocommands: %6d (combined: %5d)",
170  count_pcmd_store, count_pcmd_store - count_pcmd_store_comb);
171  // DONE
172  dolog("Number of OP Pseudocommands: %6d", count_pcmd_op);
173  // DONE
174  dolog("Number of DUP Pseudocommands: %6d", count_dup_instruction);
175  // DONE
176  dolog("Number of Mem Pseudocommands: %6d", count_pcmd_mem);
177  // DONE
178  dolog("Number of Method Pseudocommands: %6d", count_pcmd_met);
179  // DONE
180  dolog("Number of Branch Pseudocommands: %6d (rets:%5d, Xrets: %5d)",
181  count_pcmd_bra, count_pcmd_return, count_pcmd_returnx);
182  // DONE
183  log_println(" resolved branches: %6d", count_branches_resolved);
184  // DONE
185  log_println(" unresolved branches: %6d", count_branches_unresolved);
186  // DONE
187  dolog("Number of Table Pseudocommands: %6d", count_pcmd_table);
188  dolog("Number of Useful Pseudocommands: %6d", count_pcmd_table +
189  count_pcmd_bra + count_pcmd_load + count_pcmd_mem + count_pcmd_op);
190  // DONE
191  dolog("Number of Null Pointer Checks: %6d", count_check_null);
192  // DONE
193  dolog("Number of Array Bound Checks: %6d", count_check_bound);
194  // DONE
195  dolog("Number of Try-Blocks: %d", count_tryblocks);
196 
197  // DONE
198  dolog("Number of branch_emit (total, 8bit/16bit/32bit/64bit offset): %d, %d/%d/%d/%d",
199  count_emit_branch, count_emit_branch_8bit, count_emit_branch_16bit,
200  count_emit_branch_32bit, count_emit_branch_64bit);
201 
202  // DONE
203  dolog("Maximal count of stack elements: %d", count_max_new_stack);
204  // DONE
205  dolog("Upper bound of max stack elements: %d", count_upper_bound_new_stack);
206  // DONE
207  dolog("Distribution of stack sizes at block boundary");
208  dolog(" 0 1 2 3 4 5 6 7 8 9 >=10");
209  dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
210  count_block_stack[0], count_block_stack[1], count_block_stack[2],
211  count_block_stack[3], count_block_stack[4], count_block_stack[5],
212  count_block_stack[6], count_block_stack[7], count_block_stack[8],
213  count_block_stack[9], count_block_stack[10]);
214  // DONE
215  dolog("Distribution of store stack depth");
216  dolog(" 0 1 2 3 4 5 6 7 8 9 >=10");
217  dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
218  count_store_depth[0], count_store_depth[1], count_store_depth[2],
219  count_store_depth[3], count_store_depth[4], count_store_depth[5],
220  count_store_depth[6], count_store_depth[7], count_store_depth[8],
221  count_store_depth[9], count_store_depth[10]);
222  dolog("Distribution of store creator chains first part");
223  dolog(" 0 1 2 3 4 5 6 7 8 9");
224  // DONE
225  dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
226  count_store_length[0], count_store_length[1], count_store_length[2],
227  count_store_length[3], count_store_length[4], count_store_length[5],
228  count_store_length[6], count_store_length[7], count_store_length[8],
229  count_store_length[9]);
230  // DONE
231  dolog("Distribution of store creator chains second part");
232  dolog(" 10 11 12 13 14 15 16 17 18 19 >=20");
233  dolog("%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d%6d",
234  count_store_length[10], count_store_length[11],
235  count_store_length[12], count_store_length[13],
236  count_store_length[14], count_store_length[15],
237  count_store_length[16], count_store_length[17],
238  count_store_length[18], count_store_length[19],
239  count_store_length[20]);
240  // DONE
241  dolog("Distribution of analysis iterations");
242  dolog(" 1 2 3 4 >=5");
243  dolog("%6d%6d%6d%6d%6d",
244  count_analyse_iterations[0], count_analyse_iterations[1],
245  count_analyse_iterations[2], count_analyse_iterations[3],
246  count_analyse_iterations[4]);
247 
248 
249  /* Distribution of basic blocks per method ********************************/
250 
251  // DONE
252  log_println("Distribution of basic blocks per method:");
253  log_println(" <=5 <=10 <=15 <=20 <=30 <=40 <=50 <=75 >75");
254 
255  log_start();
256  for (i = 0; i <= 8; i++)
257  log_print("%6d", count_method_bb_distribution[i]);
258  log_finish();
259 
260  /* print ratio */
261 
262  f = (float) count_methods;
263 
264  log_start();
265  for (i = 0; i <= 8; i++)
266  log_print("%6.2f", (float) count_method_bb_distribution[i] / f);
267  log_finish();
268 
269  /* print cumulated ratio */
270 
271  log_start();
272  for (i = 0, sum = 0; i <= 8; i++) {
273  sum += count_method_bb_distribution[i];
274  log_print("%6.2f", (float) sum / f);
275  }
276  log_finish();
277 
278 
279  /* Distribution of basic block sizes **************************************/
280 
281  // DONE
282  log_println("Distribution of basic block sizes:");
283  log_println(" 0 1 2 3 4 5 6 7 8 9 <13 <15 <17 <19 <21 <26 <31 >30");
284 
285  /* print block sizes */
286 
287  log_start();
288  for (i = 0; i <= 17; i++)
289  log_print("%6d", count_block_size_distribution[i]);
290  log_finish();
291 
292  /* print ratio */
293 
294  f = (float) count_basic_blocks;
295 
296  log_start();
297  for (i = 0; i <= 17; i++)
298  log_print("%6.2f", (float) count_block_size_distribution[i] / f);
299  log_finish();
300 
301  /* print cumulated ratio */
302 
303  log_start();
304  for (i = 0, sum = 0; i <= 17; i++) {
305  sum += count_block_size_distribution[i];
306  log_print("%6.2f", (float) sum / f);
307  }
308  log_finish();
309 
310  // DONE
311  statistics_print_memory_usage();
312 
313  // DONE
314  dolog("Number of class loads: %6d", count_class_loads);
315  // DONE
316  dolog("Number of class inits: %6d", count_class_inits);
317  // DONE
318  dolog("Number of loaded Methods: %6d\n", count_all_methods);
319 
320  // DONE
321  dolog("Calls of utf_new: %6d", count_utf_new);
322  // NOT used?!
323  dolog("Calls of utf_new (element found): %6d\n", count_utf_new_found);
324 
325 
326  /* LSRA statistics ********************************************************/
327 
328  // DONE
329  dolog("Moves reg -> reg: %6d", count_mov_reg_reg);
330  // DONE
331  dolog("Moves mem -> reg: %6d", count_mov_mem_reg);
332  // DONE
333  dolog("Moves reg -> mem: %6d", count_mov_reg_mem);
334  // DONE
335  dolog("Moves mem -> mem: %6d", count_mov_mem_mem);
336 
337  // DONE
338  dolog("Methods allocated by LSRA: %6d",
339  count_methods_allocated_by_lsra);
340  // DONE
341  dolog("Conflicts between local Variables: %6d", count_locals_conflicts);
342  // DONE
343  dolog("Local Variables held in Memory: %6d", count_locals_spilled);
344  // DONE
345  dolog("Local Variables held in Registers: %6d", count_locals_register);
346  // DONE
347  dolog("Stackslots held in Memory: %6d", count_ss_spilled);
348  // DONE
349  dolog("Stackslots held in Registers: %6d", count_ss_register);
350  // not used!?
351  dolog("Memory moves at BB Boundaries: %6d", count_mem_move_bb);
352  // DONE
353  dolog("Number of interface slots: %6d\n", count_interface_size);
354  // DONE
355  dolog("Number of Argument stack slots in register: %6d",
356  count_argument_reg_ss);
357  // DONE
358  dolog("Number of Argument stack slots in memory: %6d\n",
359  count_argument_mem_ss);
360  // DONE
361  dolog("Number of Methods kept in registers: %6d\n",
362  count_method_in_register);
363 
364 
365  /* instruction scheduler statistics ***************************************/
366 
367 #if defined(USE_SCHEDULER)
368  dolog("Instruction scheduler statistics:");
369  dolog("Number of basic blocks: %7d", count_schedule_basic_blocks);
370  dolog("Number of nodes: %7d", count_schedule_nodes);
371  dolog("Number of leaders nodes: %7d", count_schedule_leaders);
372  dolog("Number of max. leaders nodes: %7d", count_schedule_max_leaders);
373  dolog("Length of critical path: %7d\n", count_schedule_critical_path);
374 #endif
375 
376 
377  /* call statistics ********************************************************/
378 
379  dolog("Function call statistics:");
380  // DONE
381  dolog("Number of jni->CallXMethod function invokations: %ld",
382  count_jni_callXmethod_calls);
383  // DONE
384  dolog("Overall number of jni invokations: %ld",
385  count_jni_calls);
386 
387  // DONE
388  log_println("java-to-native calls: %10ld", count_calls_java_to_native);
389  // DONE
390  log_println("native-to-java calls: %10ld", count_calls_native_to_java);
391 
392 
393  /* now print other statistics ********************************************/
394 
395 #if defined(ENABLE_INTRP)
397 #endif
398 }
399 
400 /* statistics_print_date *******************************************************
401 
402  Print current date and time.
403 
404 *******************************************************************************/
405 
406 void statistics_print_date(void)
407 {
408  time_t t;
409  struct tm tm;
410 
411 #if defined(HAVE_TIME)
412  time(&t);
413 #else
414 # error !HAVE_TIME
415 #endif
416 
417 #if defined(HAVE_LOCALTIME_R)
418  localtime_r(&t, &tm);
419 #else
420 # error !HAVE_LOCALTIME_R
421 #endif
422 
423  log_println("%d-%02d-%02d %02d:%02d:%02d",
424  1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
425  tm.tm_hour, tm.tm_min, tm.tm_sec);
426 }
427 
428 
429 /* statistics_print_memory_usage ***********************************************
430 
431  Print current memory usage.
432 
433 *******************************************************************************/
434 
435 void statistics_print_memory_usage(void)
436 {
437  s4 sum;
438 
439  log_println("memory usage ----------------------");
440  log_println("");
441  log_println("code: %10d", count_code_len);
442  log_println("data: %10d", count_data_len);
443  log_println(" ----------");
444 
445  sum =
446  count_code_len +
447  count_data_len;
448 
449  log_println(" %10d", sum);
450 
451  log_println("");
452 
453  log_println("classinfo (%3d B): %10d", (int) sizeof(classinfo), size_classinfo);
454  log_println("fieldinfo (%3d B): %10d", (int) sizeof(fieldinfo), size_fieldinfo);
455  log_println("methodinfo (%3d B): %10d", (int) sizeof(methodinfo), size_methodinfo);
456  log_println("lineinfo (%3d B): %10d", (int) sizeof(lineinfo), size_lineinfo);
457  log_println("codeinfo (%3d B): %10d", (int) sizeof(codeinfo), size_codeinfo);
458  log_println(" ----------");
459 
460  sum =
461  size_classinfo +
463  size_methodinfo +
464  size_lineinfo +
465  size_codeinfo;
466 
467  log_println(" %10d", sum);
468 
469  log_println("");
470 
471  log_println("linenumber tables (%5d): %10d", count_linenumbertable, size_linenumbertable);
472  log_println("exception tables: %10d", count_extable_len);
473  log_println("patcher references: %10d", size_patchref);
474  log_println(" ----------");
475 
476  sum =
477  size_linenumbertable +
478  count_extable_len +
479  size_patchref;
480 
481  log_println(" %10d", sum);
482 
483  log_println("");
484 
485  log_println("constant pool: %10d", count_const_pool_len);
486  log_println("classref: %10d", count_classref_len);
487  log_println("parsed descriptors: %10d", count_parsed_desc_len);
488  log_println("vftbl: %10d", count_vftbl_len);
489  log_println("compiler stubs: %10d", count_cstub_len);
490  log_println("native stubs: %10d", size_stub_native);
491  log_println("utf: %10d", count_utf_len);
492  log_println("vmcode: %10d", count_vmcode_len);
493  log_println("stack map: %10d", size_stack_map);
494  log_println("string: %10d", size_string);
495  log_println("threadobject: %10d", size_threadobject);
496  log_println("thread index: %10d", size_thread_index_t);
497  log_println("stack size: %10d", size_stacksize);
498  log_println("lock record: %10d", size_lock_record);
499  log_println("lock hashtable: %10d", size_lock_hashtable);
500  log_println("lock waiter: %10d", size_lock_waiter);
501  log_println(" ----------");
502 
503  sum =
504  count_const_pool_len +
505  count_classref_len +
506  count_parsed_desc_len +
507  count_vftbl_len +
508  count_cstub_len +
509  size_stub_native +
510  count_utf_len +
511  count_vmcode_len +
512  size_stack_map +
513  size_string +
514  size_threadobject +
515  size_thread_index_t +
516  size_stacksize +
517  size_lock_record +
518  size_lock_hashtable +
519  size_lock_waiter;
520 
521  log_println(" %10d", sum);
522 
523  log_println("");
524 
525  log_println("max. code memory: %10d", maxcodememusage);
526  log_println("max. heap memory: %10d", maxmemusage);
527  log_println("max. dump memory: %10d", maxdumpsize);
528  log_println("");
529  log_println("heap memory not freed: %10d", (int32_t) memoryusage);
530  log_println("dump memory not freed: %10d", (int32_t) globalallocateddumpsize);
531 
532  log_println("");
533 }
534 
535 
536 /* statistics_print_gc_memory_usage ********************************************
537 
538  Print current GC memory usage.
539 
540 *******************************************************************************/
541 
542 void statistics_print_gc_memory_usage(void)
543 {
544  static int64_t count = 0;
545  int64_t max;
546  int64_t size;
547  int64_t free;
548  int64_t used;
549  int64_t total;
550 
551  count++;
552 
553  max = gc_get_max_heap_size();
554  size = gc_get_heap_size();
555  free = gc_get_free_bytes();
556  used = size - free;
557  total = gc_get_total_bytes();
558 
560  if (count == 1)
561  fprintf(opt_ProfileMemoryUsageGNUPlot, "plot \"profile.dat\" using 1:2 with lines title \"max. Java heap size\", \"profile.dat\" using 1:3 with lines title \"Java heap size\", \"profile.dat\" using 1:4 with lines title \"used\", \"profile.dat\" using 1:5 with lines title \"free\"\n");
562 
564  "%" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 "\n",
565  count, max, size, used, free);
566 
568  }
569  else {
570  log_println("GC memory usage -------------------");
571  log_println("");
572  log_println("max. Java heap size: %10lld", max);
573  log_println("");
574  log_println("Java heap size: %10lld", size);
575  log_println("used: %10lld", used);
576  log_println("free: %10lld", free);
577  log_println("totally used: %10lld", total);
578  log_println("");
579  }
580 }
581 #endif
582 
583 
584 /*
585  * These are local overrides for various environment variables in Emacs.
586  * Please do not remove this and leave it at the end of the file, where
587  * Emacs will automagically detect them.
588  * ---------------------------------------------------------------------
589  * Local variables:
590  * mode: c++
591  * indent-tabs-mode: t
592  * c-basic-offset: 4
593  * tab-width: 4
594  * End:
595  * vim:noexpandtab:sw=4:ts=4:
596  */
#define dolog
Definition: logging.hpp:171
size_fieldinfo
Definition: loader.cpp:91
#define RT_TIMER_STOP(var)
Stop the timer var.
Definition: rt-timing.hpp:695
#define max(a, b)
Definition: lsra.hpp:80
static s4 compilingtime_recursion
Definition: statistics.cpp:36
#define RT_TIMER_START(var)
Start the timer var.
Definition: rt-timing.hpp:694
void log_finish(void)
Definition: logging.cpp:117
void log_println(const char *text,...)
Definition: logging.cpp:193
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
s8 gc_get_free_bytes(void)
Definition: gc.c:553
s8 gc_get_max_heap_size(void)
Definition: gc.c:555
#define RT_REGISTER_GROUP(var, name, description)
Register a new (toplevel) group.
Definition: rt-timing.hpp:683
void log_print(const char *text,...)
Definition: logging.cpp:149
#define RT_REGISTER_GROUP_TIMER(var, name, description, group)
Register a new timer.
Definition: rt-timing.hpp:682
s8 gc_get_total_bytes(void)
Definition: gc.c:554
This file contains the statistics framework.
FILE * opt_ProfileMemoryUsageGNUPlot
Definition: options.cpp:201
void log_start(void)
Definition: logging.cpp:106
MIIterator i
int32_t s4
Definition: types.hpp:45
This file contains the real-time timing utilities.
void compilingtime_start(void)
Definition: statistics.cpp:81
void loadingtime_stop(void)
Definition: statistics.cpp:65
s8 gc_get_heap_size(void)
Definition: gc.c:552
static s4 loadingtime_recursion
Definition: statistics.cpp:35
void print_dynamic_super_statistics(void)
void compilingtime_stop(void)
Definition: statistics.cpp:96
void loadingtime_start(void)
Definition: statistics.cpp:49