CACAO
show.cpp
Go to the documentation of this file.
1 /* src/vm/jit/show.cpp - showing the intermediate representation
2 
3  Copyright (C) 1996-2014
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 #include "vm/jit/show.hpp"
26 #include <assert.h> // for assert
27 #include <stdint.h> // for int32_t
28 #include <inttypes.h> // for printf formatting macros
29 #include <stdio.h> // for printf, putchar, fflush
30 #include "codegen-common.hpp" // for codegendata
31 #include "config.h" // for ENABLE_DEBUG_FILTER, etc
32 #include "replace.hpp"
33 #include "threads/lock.hpp"
34 #include "threads/mutex.hpp" // for Mutex
35 #include "threads/thread.hpp" // for threadobject, etc
36 #include "toolbox/buffer.hpp" // for Buffer
37 #include "toolbox/list.hpp" // for LockedList
38 #include "vm/class.hpp"
39 #include "vm/descriptor.hpp" // for methoddesc, typedesc
40 #include "vm/field.hpp" // for field_fieldref_print
41 #include "vm/global.hpp" // for imm_union, Type::TYPE_RET, etc
42 #include "vm/jit/abi.hpp" // for abi_registers_integer_name
43 #include "vm/jit/builtin.hpp" // for builtintable_entry
44 #include "vm/jit/code.hpp" // for codeinfo, etc
45 #include "vm/jit/disass.hpp"
46 #include "vm/jit/ir/icmd.hpp" // for ::ICMD_GETSTATIC, etc
47 #include "vm/jit/ir/instruction.hpp" // for instruction, etc
48 #include "vm/jit/jit.hpp" // for basicblock, jitdata, etc
49 #include "vm/jit/linenumbertable.hpp" // for LinenumberTable
50 #include "vm/jit/parse.hpp"
51 #include "vm/jit/patcher-common.hpp" // for patcher_list_show
52 #include "vm/jit/reg.hpp" // for varinfo, etc
53 #include "vm/jit/stack.hpp"
54 #include "vm/method.hpp" // for methodinfo, etc
55 #include "vm/options.hpp" // for opt_filter_show_method, etc
56 #include "vm/references.hpp" // for classref_or_classinfo, etc
57 #include "vm/string.hpp" // for JavaString
58 #include "vm/types.hpp" // for s4, ptrint, u1, u2
59 #include "vm/utf8.hpp" // for utf_display_printable_ascii
60 #include "vm/vm.hpp" // for vm_abort
61 
62 
63 #if defined(ENABLE_DEBUG_FILTER)
64 # include <sys/types.h>
65 # include <regex.h> // for regcomp, regerror, regexec, etc
66 # include "threads/thread.hpp"
67 #endif
68 
69 /* global variables ***********************************************************/
70 
71 #if !defined(NDEBUG)
72 static Mutex mutex;
73 #endif
74 
75 
76 /* prototypes *****************************************************************/
77 
78 #if !defined(NDEBUG)
79 static void show_variable_intern(jitdata *jd, s4 index, int stage);
80 #endif
81 
82 
83 /* show_init *******************************************************************
84 
85  Initialized the show subsystem (called by jit_init).
86 
87 *******************************************************************************/
88 
89 #if !defined(NDEBUG)
90 bool show_init(void)
91 {
92 #if defined(ENABLE_DEBUG_FILTER)
94 #endif
95 
96  /* everything's ok */
97 
98  return true;
99 }
100 #endif
101 
102 
103 #if !defined(NDEBUG)
104 const char *show_jit_type_names[] = {
105  "INT",
106  "LNG",
107  "FLT",
108  "DBL",
109  "ADR",
110  "??5",
111  "??6",
112  "??7",
113  "RET"
114 };
115 
116 const char show_jit_type_letters[] = {
117  'I',
118  'L',
119  'F',
120  'D',
121  'A',
122  '5',
123  '6',
124  '7',
125  'R'
126 };
127 #endif
128 
129 
130 /* show_method *****************************************************************
131 
132  Print the intermediate representation of a method.
133 
134  NOTE: Currently this function may only be called after register allocation!
135 
136 *******************************************************************************/
137 
138 #if !defined(NDEBUG)
139 void show_method(jitdata *jd, int stage)
140 {
141  methodinfo *m;
142  codeinfo *code;
143  codegendata *cd;
144  registerdata *rd;
145  basicblock *bptr;
146  basicblock *lastbptr;
147  exception_entry *ex;
148  s4 i, j;
149  int irstage;
150 #if defined(ENABLE_DISASSEMBLER)
151  u1 *pc;
152 #endif
153 
154  /* get required compiler data */
155 
156  m = jd->m;
157  code = jd->code;
158  cd = jd->cd;
159  rd = jd->rd;
160 
161  // We need to enter a lock here, since the binutils disassembler
162  // is not reentrant-able and we could not read functions printed
163  // at the same time.
164  mutex.lock();
165 
166 #if defined(ENABLE_INTRP)
167  if (opt_intrp)
168  irstage = SHOW_PARSE;
169  else
170 #endif
171  irstage = stage;
172 
173  /* get the last basic block */
174 
175  for (lastbptr = jd->basicblocks; lastbptr->next != NULL; lastbptr = lastbptr->next);
176 
177  printf("\n");
178 
179  method_println(m);
180 
181  if (code_is_leafmethod(code))
182  printf("LEAFMETHOD\n");
183 
184  printf("\nBasic blocks: %d\n", jd->basicblockcount);
185  if (stage >= SHOW_CODE) {
186  printf("Code length: %d\n", (lastbptr->mpc - jd->basicblocks[0].mpc));
187  printf("Data length: %d\n", cd->dseglen);
188  printf("Stub length: %d\n", (s4) (code->mcodelength -
189  ((ptrint) cd->dseglen + lastbptr->mpc)));
190  }
191  printf("Variables: %d (%d used)\n", jd->varcount, jd->vartop);
192  if (stage >= SHOW_STACK)
193  printf("Max interfaces: %d\n", jd->maxinterfaces);
194  printf("Max locals: %d\n", jd->maxlocals);
195  printf("Max stack: %d\n", m->maxstack);
196  printf("Linenumbers: %d\n", m->linenumbercount);
197  printf("Branch to entry: %s\n", (jd->branchtoentry) ? "yes" : "no");
198  printf("Branch to end: %s\n", (jd->branchtoend) ? "yes" : "no");
199  if (stage >= SHOW_STACK) {
200  printf("Number of RETURNs: %d", jd->returncount);
201  if (jd->returncount == 1)
202  printf(" (block L%03d)", jd->returnblock->nr);
203  printf("\n");
204  }
205 
206  if (stage >= SHOW_PARSE) {
207  printf("Exceptions (number=%d):\n", jd->exceptiontablelength);
208  for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
209  printf(" L%03d ... ", ex->start->nr );
210  printf("L%03d = ", ex->end->nr);
211  printf("L%03d", ex->handler->nr);
212  printf(" (catchtype: ");
213  if (ex->catchtype.any)
214  if (ex->catchtype.is_classref())
216  else
218  else
219  printf("ANY");
220  printf(")\n");
221  }
222  }
223 
224  if (irstage >= SHOW_PARSE && rd && jd->localcount > 0) {
225  printf("Local Table:\n");
226  for (i = 0; i < jd->localcount; i++) {
227  printf(" %3d: ", i);
228 
229 #if defined(ENABLE_JIT)
230 # if defined(ENABLE_INTRP)
231  if (!opt_intrp) {
232 # endif
233  printf(" (%s) ", show_jit_type_names[VAR(i)->type]);
234  if (irstage >= SHOW_REGS)
235  show_allocation(VAR(i)->type, VAR(i)->flags, VAR(i)->vv.regoff);
236  printf("\n");
237 # if defined(ENABLE_INTRP)
238  }
239 # endif
240 #endif /* defined(ENABLE_JIT) */
241  }
242  printf("\n");
243  }
244 
245  if (jd->maxlocals > 0 && jd->local_map != NULL) {
246  printf("Local Map:\n");
247  printf(" index ");
248  for (j = 0; j < jd->maxlocals; j++) {
249  printf(" [%2d]", j);
250  }
251  printf("\n");
252  for (i = 0; i < 5; i++) {
253  printf(" %5s ",show_jit_type_names[i]);
254  for (j = 0; j < jd->maxlocals; j++) {
255  if (jd->local_map[j*5+i] == jitdata::UNUSED)
256  printf(" -- ");
257  else
258  printf("%4i ",jd->local_map[j*5+i]);
259  }
260  printf("\n");
261  }
262  printf("\n");
263  }
264 
265  if (jd->maxinterfaces > 0 && jd->interface_map && irstage >= SHOW_STACK) {
266  bool exist = false;
267  interface_info *mapptr = jd->interface_map;
268 
269  /* look if there exist any INOUTS */
270  for (i = 0; (i < (5 * jd->maxinterfaces)) && !exist; i++, mapptr++)
271  exist = (mapptr->flags != jitdata::UNUSED);
272 
273  if (exist) {
274  printf("Interface Table: (In/Outvars)\n");
275  printf(" depth ");
276  for (j = 0; j < jd->maxinterfaces; j++) {
277  printf(" [%2d]", j);
278  }
279  printf("\n");
280 
281  for (i = 0; i < 5; i++) {
282  printf(" %5s ",show_jit_type_names[i]);
283  for (j = 0; j < jd->maxinterfaces; j++) {
284  s4 flags = jd->interface_map[j*5+i].flags;
285  s4 regoff = jd->interface_map[j*5+i].regoff;
286  if (flags == jitdata::UNUSED)
287  printf(" -- ");
288  else {
289  int ch;
290 
291  if (irstage >= SHOW_REGS) {
292  if (flags & SAVEDVAR) {
293  if (flags & INMEMORY)
294  ch = 'M';
295  else
296  ch = 'R';
297  }
298  else {
299  if (flags & INMEMORY)
300  ch = 'm';
301  else
302  ch = 'r';
303  }
304  printf("%c%03d(", ch, regoff);
305  show_allocation(i, flags, regoff);
306  printf(") ");
307  }
308  else {
309  if (flags & SAVEDVAR)
310  printf(" I ");
311  else
312  printf(" i ");
313  }
314  }
315  }
316  printf("\n");
317  }
318  printf("\n");
319  }
320  }
321 
322  if (rd->memuse && irstage >= SHOW_REGS) {
323  int max;
324 
325  max = rd->memuse;
326  printf("Stack slots (memuse=%d", rd->memuse);
327  if (irstage >= SHOW_CODE) {
328  printf(", stackframesize=%d", cd->stackframesize);
329  max = cd->stackframesize;
330  }
331  printf("):\n");
332  for (i = 0; i < max; ++i) {
333  printf(" M%02d = 0x%02x(sp): ", i, i * 8);
334  for (j = 0; j < jd->vartop; ++j) {
335  varinfo *v = VAR(j);
336  if ((v->flags & INMEMORY) && (v->vv.regoff == i)) {
337  show_variable(jd, j, irstage);
338  putchar(' ');
339  }
340  }
341 
342  printf("\n");
343 
344  }
345  printf("\n");
346  }
347 
348  if (!code->patchers->empty()) {
349  int number = code->patchers->size();
350  printf("Patcher References (number=%d):\n", number);
351  patcher_list_show(code);
352  printf("\n");
353  }
354 
355 #if defined(ENABLE_DISASSEMBLER)
356  /* show code before first basic block */
357 
358  if ((stage >= SHOW_CODE) && JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
359  pc = (u1 *) ((ptrint) code->mcode + cd->dseglen);
360 
361  for (; pc < (u1 *) ((ptrint) code->mcode + cd->dseglen + jd->basicblocks[0].mpc);)
362  DISASSINSTR(pc);
363 
364  printf("\n");
365  }
366 #endif
367 
368  /* show code of all basic blocks */
369 
370  for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next)
371  show_basicblock(jd, bptr, stage);
372 
373 #if 0 && defined(ENABLE_DISASSEMBLER)
374  /* show code after last basic block */
375 
376  if (stage >= SHOW_CODE && opt_showdisassemble) {
377  printf("\nStubs code:\n");
378  printf("Length: %d\n\n", (s4) (code->mcodelength -
379  ((ptrint) cd->dseglen + lastbptr->mpc)));
380 
381  pc = (u1 *) ((ptrint) code->mcode + cd->dseglen + lastbptr->mpc);
382 
383  for (; (ptrint) pc < ((ptrint) code->mcode + code->mcodelength);)
384  DISASSINSTR(pc);
385 
386  printf("\n");
387  }
388 #endif
389 
390  mutex.unlock();
391 
392  /* finally flush the output */
393 
394  fflush(stdout);
395 }
396 #endif /* !defined(NDEBUG) */
397 
398 
399 #if !defined(NDEBUG) && defined(ENABLE_INLINING)
400 static void show_inline_info(jitdata *jd, insinfo_inline *ii, s4 opcode, s4 stage)
401 {
402  s4 *jl;
403  s4 n;
404 
405  printf("(pt %d+%d+%d st ",
406  ii->throughcount - (ii->stackvarscount - ii->paramcount),
407  ii->stackvarscount - ii->paramcount,
408  ii->paramcount);
409  show_variable_array(jd, ii->stackvars, ii->stackvarscount, stage);
410 
411  if (opcode == ICMD_INLINE_START || opcode == ICMD_INLINE_END) {
412  printf(" jl ");
413  jl = (opcode == ICMD_INLINE_START) ? ii->javalocals_start : ii->javalocals_end;
414  n = (opcode == ICMD_INLINE_START) ? ii->method->maxlocals : ii->outer->maxlocals;
415  show_javalocals_array(jd, jl, n, stage);
416  }
417 
418  printf(") ");
419 
420 #if 0
421  printf("(");
422  method_print(ii->outer);
423  printf(" ==> ");
424 #endif
425 
426  method_print(ii->method);
427 }
428 #endif /* !defined(NDEBUG) && defined(ENABLE_INLINING) */
429 
430 
431 /* show_basicblock *************************************************************
432 
433  Print the intermediate representation of a basic block.
434 
435  NOTE: Currently this function may only be called after register allocation!
436 
437 *******************************************************************************/
438 
439 #if !defined(NDEBUG)
440 void show_basicblock(jitdata *jd, basicblock *bptr, int stage)
441 {
442  s4 i;
443  bool deadcode;
444  instruction *iptr;
445  int irstage;
446 #if defined(ENABLE_DISASSEMBLER)
447  methodinfo *m; /* this is only a dummy */
448  void *pc;
449  s4 linenumber;
450  s4 currentlinenumber;
451 #endif
452 
453 
454  if (bptr->state != basicblock::DELETED) {
455 #if defined(ENABLE_INTRP)
456  if (opt_intrp) {
457  deadcode = false;
458  irstage = SHOW_PARSE;
459  }
460  else
461 #endif
462  {
463  deadcode = (bptr->state < basicblock::REACHED);
464  irstage = stage;
465  }
466 
467  printf("======== %sL%03d ======== %s(flags: %d, bitflags: %01x, next: %d, type: ",
468 #if defined(ENABLE_REPLACEMENT)
469  (bptr->bitflags & BBFLAG_REPLACEMENT) ? "<REPLACE> " :
470 #endif
471  "",
472  bptr->nr,
473  (deadcode && stage >= SHOW_STACK) ? "DEADCODE! " : "",
474  bptr->state, bptr->bitflags,
475  (bptr->next) ? (bptr->next->nr) : -1);
476 
477  switch (bptr->type) {
479  printf("STD");
480  break;
482  printf("EXH");
483  break;
485  printf("SBR");
486  break;
487  }
488 
489  printf(", icount: %d", bptr->icount);
490 
491  if (irstage >= SHOW_CFG) {
492  printf(", preds: %d [ ", bptr->predecessorcount);
493 
494  for (i = 0; i < bptr->predecessorcount; i++)
495  printf("%d ", bptr->predecessors[i]->nr);
496 
497  printf("]");
498  }
499 
500  printf("):");
501 
502  if (bptr->original)
503  printf(" (clone of L%03d)", bptr->original->nr);
504  else {
505  basicblock *b = bptr->copied_to;
506  if (b) {
507  printf(" (copied to ");
508  for (; b; b = b->copied_to)
509  printf("L%03d ", b->nr);
510  printf(")");
511  }
512  }
513 
514  printf("\n");
515 
516  if (irstage >= SHOW_CFG) {
517  printf("succs: %d [ ", bptr->successorcount);
518 
519  for (i = 0; i < bptr->successorcount; i++)
520  printf("%d ", bptr->successors[i]->nr);
521 
522  printf("]\n");
523  }
524 
525  if (irstage >= SHOW_STACK) {
526  printf("IN: ");
527  show_variable_array(jd, bptr->invars, bptr->indepth, irstage);
528  printf(" javalocals: ");
529  if (bptr->javalocals)
530  show_javalocals_array(jd, bptr->javalocals, bptr->method->maxlocals, irstage);
531  else
532  printf("null");
533  printf("\n");
534  }
535 
536 #if defined(ENABLE_INLINING)
537  if (bptr->inlineinfo) {
538  printf("inlineinfo: ");
539  show_inline_info(jd, bptr->inlineinfo, -1, irstage);
540  printf("\n");
541  }
542 #endif /* defined(ENABLE_INLINING) */
543 
544 #if defined(ENABLE_SSA)
545 
546  iptr = bptr->phis;
547 
548  for (i = 0; i < bptr->phicount; i++, iptr++) {
549  printf("%4d:%4d: ", iptr->line, iptr->flags.bits >> INS_FLAG_ID_SHIFT);
550 
551  show_icmd(jd, iptr, deadcode, irstage);
552  printf("\n");
553  }
554 #endif
555 
556  iptr = bptr->iinstr;
557 
558  for (i = 0; i < bptr->icount; i++, iptr++) {
559  printf("%4d:%4d: ", iptr->line, iptr->flags.bits >> INS_FLAG_ID_SHIFT);
560 
561  show_icmd(jd, iptr, deadcode, irstage);
562  printf("\n");
563  }
564 
565  if (irstage >= SHOW_STACK) {
566  printf("OUT: ");
567  show_variable_array(jd, bptr->outvars, bptr->outdepth, irstage);
568  printf("\n");
569  }
570 
571 #if defined(ENABLE_DISASSEMBLER)
572  if ((stage >= SHOW_CODE) && JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd) &&
573  (!deadcode))
574  {
575  codeinfo *code = jd->code;
576  codegendata *cd = jd->cd;
577 
578  printf("\n");
579  pc = (void *) (code->mcode + cd->dseglen + bptr->mpc);
580  linenumber = 0;
581 
582  if (bptr->next != NULL) {
583  for (; pc < (void *) (code->mcode + cd->dseglen + bptr->next->mpc);) {
584  currentlinenumber = code->linenumbertable->find(&m, pc);
585 
586  if (currentlinenumber != linenumber) {
587  linenumber = currentlinenumber;
588  printf("%4d:\n", linenumber);
589  }
590 
591  DISASSINSTR(pc);
592  }
593  }
594  else {
595  for (; pc < (void *) (code->mcode + code->mcodelength);) {
596  currentlinenumber = code->linenumbertable->find(&m, pc);
597 
598  if (currentlinenumber != linenumber) {
599  linenumber = currentlinenumber;
600  printf("%4d:\n", linenumber);
601  }
602 
603  DISASSINSTR(pc);
604  }
605  }
606  printf("\n");
607  }
608 #endif
609  }
610 }
611 #endif /* !defined(NDEBUG) */
612 
613 
614 /* show_icmd *******************************************************************
615 
616  Print the intermediate representation of an instruction.
617 
618  NOTE: Currently this function may only be called after register allocation!
619 
620 *******************************************************************************/
621 
622 #if !defined(NDEBUG)
623 
624 #define SHOW_TARGET(target) \
625  if (stage >= SHOW_PARSE) { \
626  printf("--> L%03d ", (target).block->nr); \
627  } \
628  else { \
629  printf("--> insindex %d ", (target).insindex); \
630  }
631 
632 #define SHOW_INT_CONST(val) \
633  if (stage >= SHOW_PARSE) { \
634  printf("%d (0x%08x) ", (int32_t) (val), (int32_t) (val)); \
635  } \
636  else { \
637  printf("iconst "); \
638  }
639 
640 #define SHOW_LNG_CONST(val) \
641  if (stage >= SHOW_PARSE) \
642  printf("%" PRId64 " (0x%016" PRIx64 ") ", (val), (val)); \
643  else \
644  printf("lconst ");
645 
646 #define SHOW_ADR_CONST(val) \
647  if (stage >= SHOW_PARSE) \
648  printf("0x%" PRINTF_INTPTR_NUM_HEXDIGITS PRIxPTR " ", (ptrint) (val)); \
649  else \
650  printf("aconst ");
651 
652 #define SHOW_FLT_CONST(val) \
653  if (stage >= SHOW_PARSE) { \
654  imm_union v; \
655  v.f = (val); \
656  printf("%g (0x%08x) ", (val), v.i); \
657  } \
658  else { \
659  printf("fconst "); \
660  }
661 
662 #define SHOW_DBL_CONST(val) \
663  if (stage >= SHOW_PARSE) { \
664  imm_union v; \
665  v.d = (val); \
666  printf("%g (0x%016" PRIx64 ") ", (val), v.l); \
667  } \
668  else \
669  printf("dconst ");
670 
671 #define SHOW_INDEX(index) \
672  if (stage >= SHOW_PARSE) { \
673  printf("%d ", index); \
674  } \
675  else { \
676  printf("index"); \
677  }
678 
679 #define SHOW_STRING(val) \
680  if (stage >= SHOW_PARSE) { \
681  putchar('"'); \
682  utf_display_printable_ascii( \
683  JavaString((java_handle_t*) (val)).to_utf8()); \
684  printf("\" "); \
685  } \
686  else { \
687  printf("string "); \
688  }
689 
690 #define SHOW_CLASSREF_OR_CLASSINFO(c) \
691  if (stage >= SHOW_PARSE) { \
692  if (c.is_classref()) \
693  class_classref_print(c.ref); \
694  else \
695  class_print(c.cls); \
696  putchar(' '); \
697  } \
698  else { \
699  printf("class "); \
700  }
701 
702 #define SHOW_FIELD(fmiref) \
703  if (stage >= SHOW_PARSE) { \
704  field_fieldref_print(fmiref); \
705  putchar(' '); \
706  } \
707  else { \
708  printf("field "); \
709  }
710 
711 #define SHOW_VARIABLE(v) \
712  show_variable(jd, (v), stage)
713 
714 #define SHOW_S1(iptr) \
715  if (stage >= SHOW_STACK) { \
716  SHOW_VARIABLE(iptr->s1.varindex); \
717  }
718 
719 #define SHOW_S2(iptr) \
720  if (stage >= SHOW_STACK) { \
721  SHOW_VARIABLE(iptr->sx.s23.s2.varindex); \
722  }
723 
724 #define SHOW_S3(iptr) \
725  if (stage >= SHOW_STACK) { \
726  SHOW_VARIABLE(iptr->sx.s23.s3.varindex); \
727  }
728 
729 #define SHOW_DST(iptr) \
730  if (stage >= SHOW_STACK) { \
731  printf("=> "); \
732  SHOW_VARIABLE(iptr->dst.varindex); \
733  }
734 
735 #define SHOW_S1_LOCAL(iptr) \
736  if (stage >= SHOW_STACK) { \
737  printf("L%d ", iptr->s1.varindex); \
738  } \
739  else { \
740  printf("JavaL%d ", iptr->s1.varindex); \
741  }
742 
743 #define SHOW_DST_LOCAL(iptr) \
744  if (stage >= SHOW_STACK) { \
745  printf("=> L%d ", iptr->dst.varindex); \
746  } \
747  else { \
748  printf("=> JavaL%d ", iptr->dst.varindex); \
749  }
750 
751 void show_allocation(s4 type, s4 flags, s4 regoff)
752 {
753  if (type == TYPE_RET) {
754  printf("N/A");
755  return;
756  }
757 
758  if (flags & INMEMORY) {
759  printf("M%02d", regoff);
760  return;
761  }
762 
763  if (IS_FLT_DBL_TYPE(type)) {
764  printf("F%02d", regoff);
765  return;
766  }
767 
768 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
769  if (IS_2_WORD_TYPE(type)) {
770 # if defined(ENABLE_JIT)
771 # if defined(ENABLE_INTRP)
772  if (opt_intrp)
773  printf("%3d/%3d", GET_LOW_REG(regoff),
774  GET_HIGH_REG(regoff));
775  else
776 # endif
777  printf("%3s/%3s", abi_registers_integer_name[GET_LOW_REG(regoff)],
779 # else
780  printf("%3d/%3d", GET_LOW_REG(regoff),
781  GET_HIGH_REG(regoff));
782 # endif
783  return;
784  }
785 #endif /* defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
786 
787 #if defined(ENABLE_JIT)
788 # if defined(ENABLE_INTRP)
789  if (opt_intrp)
790  printf("%3d", regoff);
791  else
792 # endif
793  printf("%3s", abi_registers_integer_name[regoff]);
794 #else
795  printf("%3d", regoff);
796 #endif
797 }
798 
799 void show_variable(jitdata *jd, s4 index, int stage)
800 {
801  show_variable_intern(jd, index, stage);
802  putchar(' ');
803 }
804 
805 static void show_variable_intern(jitdata *jd, s4 index, int stage)
806 {
807  char type;
808  char kind;
809  varinfo *v;
810 
811  if (index < 0 || index >= jd->vartop) {
812  printf("<INVALID INDEX:%d>", index);
813  return;
814  }
815 
816  v = VAR(index);
817 
818  switch (v->type) {
819  case TYPE_INT: type = 'i'; break;
820  case TYPE_LNG: type = 'l'; break;
821  case TYPE_FLT: type = 'f'; break;
822  case TYPE_DBL: type = 'd'; break;
823  case TYPE_ADR: type = 'a'; break;
824  case TYPE_RET: type = 'r'; break;
825  default: type = '?';
826  }
827 
828  if (index < jd->localcount) {
829  kind = 'L';
830  if (v->flags & (PREALLOC | INOUT))
831  printf("<INVALID FLAGS!>");
832  }
833  else {
834  if (v->flags & PREALLOC) {
835  kind = 'A';
836  if (v->flags & INOUT) {
837  /* PREALLOC is used to avoid allocation of TYPE_RET */
838  if (v->type == TYPE_RET)
839  kind = 'i';
840  else
841  printf("<INVALID FLAGS!>");
842  }
843  }
844  else if (v->flags & INOUT)
845  kind = 'I';
846  else
847  kind = 'T';
848  }
849 
850  printf("%c%c%d", kind, type, index);
851 
852  if (v->flags & SAVEDVAR)
853  putchar('!');
854 
855  if (stage >= SHOW_REGS || (v->flags & PREALLOC)) {
856  putchar('(');
857  show_allocation(v->type, v->flags, v->vv.regoff);
858  putchar(')');
859  }
860 
861  if (v->type == TYPE_RET && (v->flags & PREALLOC)) {
862  printf("(L%03d)", v->vv.retaddr->nr);
863  }
864 }
865 
866 static void show_variable_array_intern(jitdata *jd, s4 *vars, int n, int stage,
867  bool javalocals)
868 {
869  int i;
870  int nr;
871 
872  if (vars == NULL) {
873  printf("<null>");
874  return;
875  }
876 
877  printf("[");
878  for (i=0; i<n; ++i) {
879  if (i)
880  putchar(' ');
881  if (vars[i] < 0) {
882  if (vars[i] == jitdata::UNUSED)
883  putchar('-');
884  else if (javalocals) {
885  nr = RETADDR_FROM_JAVALOCAL(vars[i]);
886  printf("ret(L%03d)", nr);
887  }
888  else {
889  printf("<INVALID INDEX:%d>", vars[i]);
890  }
891  }
892  else
893  show_variable_intern(jd, vars[i], stage);
894  }
895  printf("]");
896 }
897 
898 void show_variable_array(jitdata *jd, s4 *vars, int n, int stage)
899 {
900  show_variable_array_intern(jd, vars, n, stage, false);
901 }
902 
903 void show_javalocals_array(jitdata *jd, s4 *vars, int n, int stage)
904 {
905  show_variable_array_intern(jd, vars, n, stage, true);
906 }
907 
908 void show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
909 {
910  branch_target_t *table;
911  lookup_target_t *lookup;
912  constant_FMIref *fmiref;
913  s4 *argp;
914  s4 i;
915 
916  /* get the opcode and the condition */
917 
918  ICMD opcode = iptr->opc;
919 
920  printf("%s ", icmd_table[opcode].name);
921 
922  if (stage < SHOW_PARSE)
923  return;
924 
925  if (deadcode)
926  stage = SHOW_PARSE;
927 
928  /* Print the condition for conditional instructions. */
929 
930  /* XXX print condition from flags */
931 
932  if (iptr->flags.bits & INS_FLAG_UNRESOLVED)
933  printf("(UNRESOLVED) ");
934 
935  switch (opcode) {
936 
937  case ICMD_POP:
938  case ICMD_CHECKNULL:
939  SHOW_S1(iptr);
940  break;
941 
942  /* unary */
943  case ICMD_ARRAYLENGTH:
944  case ICMD_INEG:
945  case ICMD_LNEG:
946  case ICMD_FNEG:
947  case ICMD_DNEG:
948  case ICMD_I2L:
949  case ICMD_I2F:
950  case ICMD_I2D:
951  case ICMD_L2I:
952  case ICMD_L2F:
953  case ICMD_L2D:
954  case ICMD_F2I:
955  case ICMD_F2L:
956  case ICMD_F2D:
957  case ICMD_D2I:
958  case ICMD_D2L:
959  case ICMD_D2F:
960  case ICMD_INT2BYTE:
961  case ICMD_INT2CHAR:
962  case ICMD_INT2SHORT:
963  SHOW_S1(iptr);
964  SHOW_DST(iptr);
965  break;
966 
967  /* binary */
968  case ICMD_IADD:
969  case ICMD_LADD:
970  case ICMD_FADD:
971  case ICMD_DADD:
972  case ICMD_ISUB:
973  case ICMD_LSUB:
974  case ICMD_FSUB:
975  case ICMD_DSUB:
976  case ICMD_IMUL:
977  case ICMD_LMUL:
978  case ICMD_FMUL:
979  case ICMD_DMUL:
980  case ICMD_IDIV:
981  case ICMD_LDIV:
982  case ICMD_FDIV:
983  case ICMD_DDIV:
984  case ICMD_IREM:
985  case ICMD_LREM:
986  case ICMD_FREM:
987  case ICMD_DREM:
988  case ICMD_ISHL:
989  case ICMD_LSHL:
990  case ICMD_ISHR:
991  case ICMD_LSHR:
992  case ICMD_IUSHR:
993  case ICMD_LUSHR:
994  case ICMD_IAND:
995  case ICMD_LAND:
996  case ICMD_IOR:
997  case ICMD_LOR:
998  case ICMD_IXOR:
999  case ICMD_LXOR:
1000  case ICMD_LCMP:
1001  case ICMD_FCMPL:
1002  case ICMD_FCMPG:
1003  case ICMD_DCMPL:
1004  case ICMD_DCMPG:
1005  SHOW_S1(iptr);
1006  SHOW_S2(iptr);
1007  SHOW_DST(iptr);
1008  break;
1009 
1010  /* binary/const INT */
1011  case ICMD_IADDCONST:
1012  case ICMD_ISUBCONST:
1013  case ICMD_IMULCONST:
1014  case ICMD_IMULPOW2:
1015  case ICMD_IDIVPOW2:
1016  case ICMD_IREMPOW2:
1017  case ICMD_IANDCONST:
1018  case ICMD_IORCONST:
1019  case ICMD_IXORCONST:
1020  case ICMD_ISHLCONST:
1021  case ICMD_ISHRCONST:
1022  case ICMD_IUSHRCONST:
1023  case ICMD_LSHLCONST:
1024  case ICMD_LSHRCONST:
1025  case ICMD_LUSHRCONST:
1026  SHOW_S1(iptr);
1027  SHOW_INT_CONST(iptr->sx.val.i);
1028  SHOW_DST(iptr);
1029  break;
1030 
1031  /* ?ASTORECONST (trinary/const INT) */
1032  case ICMD_IASTORECONST:
1033  case ICMD_BASTORECONST:
1034  case ICMD_CASTORECONST:
1035  case ICMD_SASTORECONST:
1036  SHOW_S1(iptr);
1037  SHOW_S2(iptr);
1038  SHOW_INT_CONST(iptr->sx.s23.s3.constval);
1039  break;
1040 
1041  /* const INT */
1042  case ICMD_ICONST:
1043  SHOW_INT_CONST(iptr->sx.val.i);
1044  SHOW_DST(iptr);
1045  break;
1046 
1047  /* binary/const LNG */
1048  case ICMD_LADDCONST:
1049  case ICMD_LSUBCONST:
1050  case ICMD_LMULCONST:
1051  case ICMD_LMULPOW2:
1052  case ICMD_LDIVPOW2:
1053  case ICMD_LREMPOW2:
1054  case ICMD_LANDCONST:
1055  case ICMD_LORCONST:
1056  case ICMD_LXORCONST:
1057  SHOW_S1(iptr);
1058  SHOW_LNG_CONST(iptr->sx.val.l);
1059  SHOW_DST(iptr);
1060  break;
1061 
1062  /* trinary/const LNG (<= pointer size) */
1063  case ICMD_LASTORECONST:
1064  SHOW_S1(iptr);
1065  SHOW_S2(iptr);
1066  SHOW_ADR_CONST(iptr->sx.s23.s3.constval);
1067  break;
1068 
1069  /* const LNG */
1070  case ICMD_LCONST:
1071  SHOW_LNG_CONST(iptr->sx.val.l);
1072  SHOW_DST(iptr);
1073  break;
1074 
1075  /* const FLT */
1076  case ICMD_FCONST:
1077  SHOW_FLT_CONST(iptr->sx.val.f);
1078  SHOW_DST(iptr);
1079  break;
1080 
1081  /* const DBL */
1082  case ICMD_DCONST:
1083  SHOW_DBL_CONST(iptr->sx.val.d);
1084  SHOW_DST(iptr);
1085  break;
1086 
1087  /* const ADR */
1088  case ICMD_ACONST:
1089  if (iptr->flags.bits & INS_FLAG_CLASS) {
1090  SHOW_ADR_CONST(iptr->sx.val.anyptr);
1092  }
1093  else if (iptr->sx.val.anyptr == NULL) {
1094  printf("NULL ");
1095  }
1096  else {
1097  SHOW_ADR_CONST(iptr->sx.val.anyptr);
1098  SHOW_STRING(iptr->sx.val.stringconst);
1099  }
1100  SHOW_DST(iptr);
1101  break;
1102 
1103  case ICMD_AASTORECONST:
1104  SHOW_S1(iptr);
1105  SHOW_S2(iptr);
1106  printf("%p ", (void*) iptr->sx.s23.s3.constval);
1107  break;
1108 
1109  case ICMD_GETFIELD: /* 1 -> 1 */
1110  case ICMD_PUTFIELD: /* 2 -> 0 */
1111  case ICMD_PUTSTATIC: /* 1 -> 0 */
1112  case ICMD_GETSTATIC: /* 0 -> 1 */
1113  case ICMD_PUTSTATICCONST: /* 0 -> 0 */
1114  case ICMD_PUTFIELDCONST: /* 1 -> 0 */
1115  if (opcode != ICMD_GETSTATIC && opcode != ICMD_PUTSTATICCONST) {
1116  SHOW_S1(iptr);
1117  if (opcode == ICMD_PUTFIELD) {
1118  SHOW_S2(iptr);
1119  }
1120  }
1121  INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1122  SHOW_FIELD(fmiref);
1123 
1124  if (opcode == ICMD_GETSTATIC || opcode == ICMD_GETFIELD) {
1125  SHOW_DST(iptr);
1126  }
1127  break;
1128 
1129  case ICMD_IINC:
1130  SHOW_S1_LOCAL(iptr);
1131  SHOW_INT_CONST(iptr->sx.val.i);
1132  SHOW_DST_LOCAL(iptr);
1133  break;
1134 
1135  case ICMD_IASTORE:
1136  case ICMD_SASTORE:
1137  case ICMD_BASTORE:
1138  case ICMD_CASTORE:
1139  case ICMD_LASTORE:
1140  case ICMD_DASTORE:
1141  case ICMD_FASTORE:
1142  case ICMD_AASTORE:
1143  SHOW_S1(iptr);
1144  SHOW_S2(iptr);
1145  SHOW_S3(iptr);
1146  break;
1147 
1148  case ICMD_IALOAD:
1149  case ICMD_SALOAD:
1150  case ICMD_BALOAD:
1151  case ICMD_CALOAD:
1152  case ICMD_LALOAD:
1153  case ICMD_DALOAD:
1154  case ICMD_FALOAD:
1155  case ICMD_AALOAD:
1156  SHOW_S1(iptr);
1157  SHOW_S2(iptr);
1158  SHOW_DST(iptr);
1159  break;
1160 
1161  case ICMD_RET:
1162  SHOW_S1_LOCAL(iptr);
1163  if (stage >= SHOW_STACK) {
1164  printf(" ---> L%03d", iptr->dst.block->nr);
1165  }
1166  break;
1167 
1168  case ICMD_ILOAD:
1169  case ICMD_LLOAD:
1170  case ICMD_FLOAD:
1171  case ICMD_DLOAD:
1172  case ICMD_ALOAD:
1173  SHOW_S1_LOCAL(iptr);
1174  SHOW_DST(iptr);
1175  break;
1176 
1177  case ICMD_ISTORE:
1178  case ICMD_LSTORE:
1179  case ICMD_FSTORE:
1180  case ICMD_DSTORE:
1181  case ICMD_ASTORE:
1182  SHOW_S1(iptr);
1183  SHOW_DST_LOCAL(iptr);
1184  if (stage >= SHOW_STACK && iptr->sx.s23.s3.javaindex != jitdata::UNUSED)
1185  printf(" (javaindex %d)", iptr->sx.s23.s3.javaindex);
1186  if (iptr->flags.bits & INS_FLAG_RETADDR) {
1187  printf(" (retaddr L%03d)", RETADDR_FROM_JAVALOCAL(iptr->sx.s23.s2.retaddrnr));
1188  }
1189  break;
1190 
1191  case ICMD_NEW:
1192  SHOW_DST(iptr);
1193  break;
1194 
1195  case ICMD_NEWARRAY:
1196  SHOW_DST(iptr);
1197  break;
1198 
1199  case ICMD_ANEWARRAY:
1200  SHOW_DST(iptr);
1201  break;
1202 
1203  case ICMD_MULTIANEWARRAY:
1204  if (stage >= SHOW_STACK) {
1205  argp = iptr->sx.s23.s2.args;
1206  i = iptr->s1.argcount;
1207  while (i--) {
1208  SHOW_VARIABLE(*(argp++));
1209  }
1210  }
1211  else {
1212  printf("argcount=%d ", iptr->s1.argcount);
1213  }
1215  putchar(' ');
1216  SHOW_DST(iptr);
1217  break;
1218 
1219  case ICMD_CHECKCAST:
1220  SHOW_S1(iptr);
1222  putchar(' ');
1223  SHOW_DST(iptr);
1224  break;
1225 
1226  case ICMD_INSTANCEOF:
1227  SHOW_S1(iptr);
1228  SHOW_DST(iptr);
1229  break;
1230 
1231  case ICMD_INLINE_START:
1232  case ICMD_INLINE_END:
1233  case ICMD_INLINE_BODY:
1234 #if defined(ENABLE_INLINING)
1235  {
1236  insinfo_inline *ii = iptr->sx.s23.s3.inlineinfo;
1237  show_inline_info(jd, ii, opcode, stage);
1238  }
1239 #endif
1240  break;
1241 
1242  case ICMD_BUILTIN:
1243  if (stage >= SHOW_STACK) {
1244  argp = iptr->sx.s23.s2.args;
1245  i = iptr->s1.argcount;
1246  while (i--) {
1247  if ((iptr->s1.argcount - 1 - i) == iptr->sx.s23.s3.bte->md->paramcount)
1248  printf(" pass-through: ");
1249  SHOW_VARIABLE(*(argp++));
1250  }
1251  }
1252  printf("%s ", iptr->sx.s23.s3.bte->cname);
1253  if (iptr->sx.s23.s3.bte->md->returntype.type != TYPE_VOID) {
1254  SHOW_DST(iptr);
1255  }
1256  break;
1257 
1258  case ICMD_INVOKEVIRTUAL:
1259  case ICMD_INVOKESPECIAL:
1260  case ICMD_INVOKESTATIC:
1261  case ICMD_INVOKEINTERFACE:
1262  if (stage >= SHOW_STACK) {
1263  methoddesc *md;
1264  INSTRUCTION_GET_METHODDESC(iptr, md);
1265  argp = iptr->sx.s23.s2.args;
1266  i = iptr->s1.argcount;
1267  while (i--) {
1268  if ((iptr->s1.argcount - 1 - i) == md->paramcount)
1269  printf(" pass-through: ");
1270  SHOW_VARIABLE(*(argp++));
1271  }
1272  }
1273  INSTRUCTION_GET_METHODREF(iptr, fmiref);
1274  method_methodref_print(fmiref);
1275  if (fmiref->parseddesc.md->returntype.type != TYPE_VOID) {
1276  putchar(' ');
1277  SHOW_DST(iptr);
1278  }
1279  break;
1280 
1281  case ICMD_IFEQ:
1282  case ICMD_IFNE:
1283  case ICMD_IFLT:
1284  case ICMD_IFGE:
1285  case ICMD_IFGT:
1286  case ICMD_IFLE:
1287  SHOW_S1(iptr);
1288  SHOW_INT_CONST(iptr->sx.val.i);
1289  SHOW_TARGET(iptr->dst);
1290  break;
1291 
1292  case ICMD_IF_LEQ:
1293  case ICMD_IF_LNE:
1294  case ICMD_IF_LLT:
1295  case ICMD_IF_LGE:
1296  case ICMD_IF_LGT:
1297  case ICMD_IF_LLE:
1298  SHOW_S1(iptr);
1299  SHOW_LNG_CONST(iptr->sx.val.l);
1300  SHOW_TARGET(iptr->dst);
1301  break;
1302 
1303  case ICMD_GOTO:
1304  SHOW_TARGET(iptr->dst);
1305  break;
1306 
1307  case ICMD_JSR:
1308  SHOW_TARGET(iptr->sx.s23.s3.jsrtarget);
1309  SHOW_DST(iptr);
1310  break;
1311 
1312  case ICMD_IFNULL:
1313  case ICMD_IFNONNULL:
1314  SHOW_S1(iptr);
1315  SHOW_TARGET(iptr->dst);
1316  break;
1317 
1318  case ICMD_IF_ICMPEQ:
1319  case ICMD_IF_ICMPNE:
1320  case ICMD_IF_ICMPLT:
1321  case ICMD_IF_ICMPGE:
1322  case ICMD_IF_ICMPGT:
1323  case ICMD_IF_ICMPLE:
1324 
1325  case ICMD_IF_LCMPEQ:
1326  case ICMD_IF_LCMPNE:
1327  case ICMD_IF_LCMPLT:
1328  case ICMD_IF_LCMPGE:
1329  case ICMD_IF_LCMPGT:
1330  case ICMD_IF_LCMPLE:
1331 
1332  case ICMD_IF_ACMPEQ:
1333  case ICMD_IF_ACMPNE:
1334  SHOW_S1(iptr);
1335  SHOW_S2(iptr);
1336  SHOW_TARGET(iptr->dst);
1337  break;
1338 
1339  case ICMD_TABLESWITCH:
1340  SHOW_S1(iptr);
1341  table = iptr->dst.table;
1342 
1343  i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1;
1344 
1345  printf("high=%d low=%d count=%d\n", iptr->sx.s23.s3.tablehigh, iptr->sx.s23.s2.tablelow, i);
1346  while (--i >= 0) {
1347  printf("\t\t%d --> ", (int) (table - iptr->dst.table));
1348  printf("L%03d\n", table->block->nr);
1349  table++;
1350  }
1351 
1352  break;
1353 
1354  case ICMD_LOOKUPSWITCH:
1355  SHOW_S1(iptr);
1356 
1357  printf("count=%d, default=L%03d\n",
1358  iptr->sx.s23.s2.lookupcount,
1359  iptr->sx.s23.s3.lookupdefault.block->nr);
1360 
1361  lookup = iptr->dst.lookup;
1362  i = iptr->sx.s23.s2.lookupcount;
1363 
1364  while (--i >= 0) {
1365  printf("\t\t%d --> L%03d\n",
1366  lookup->value,
1367  lookup->target.block->nr);
1368  lookup++;
1369  }
1370  break;
1371 
1372  case ICMD_FRETURN:
1373  case ICMD_IRETURN:
1374  case ICMD_DRETURN:
1375  case ICMD_LRETURN:
1376  SHOW_S1(iptr);
1377  break;
1378 
1379  case ICMD_ARETURN:
1380  case ICMD_ATHROW:
1381  SHOW_S1(iptr);
1382  if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1383  /* XXX this needs more work */
1384 #if 0
1385  unresolved_class_debug_dump(iptr->sx.s23.s2.uc, stdout);
1386 #endif
1387  }
1388  break;
1389 
1390  case ICMD_COPY:
1391  case ICMD_MOVE:
1392  SHOW_S1(iptr);
1393  SHOW_DST(iptr);
1394  break;
1395  case ICMD_GETEXCEPTION:
1396  SHOW_DST(iptr);
1397  break;
1398 #if defined(ENABLE_SSA)
1399  case ICMD_PHI:
1400  printf("[ ");
1401  for (i = 0; i < iptr->s1.argcount; ++i) {
1402  SHOW_VARIABLE(iptr->sx.s23.s2.iargs[i]->dst.varindex);
1403  }
1404  printf("] ");
1405  SHOW_DST(iptr);
1406  if (iptr->flags.bits & (1 << 0)) printf("used ");
1407  if (iptr->flags.bits & (1 << 1)) printf("redundantAll ");
1408  if (iptr->flags.bits & (1 << 2)) printf("redundantOne ");
1409  break;
1410 #endif
1411  // ignore other ICMDs
1412  default:
1413  break;
1414  }
1415  fflush(stdout);
1416 }
1417 #endif /* !defined(NDEBUG) */
1418 
1419 /* Debug output filtering */
1420 
1421 #if defined(ENABLE_DEBUG_FILTER)
1422 
1423 struct show_filter {
1424  /* Boolean indicating if filter is enabled. */
1426  /* Regular expression the method name is matched against */
1427  regex_t regex;
1428  /* Flag set on m->filtermatches if regex matches */
1430 };
1431 
1433 
1434 #define SHOW_FILTERS_SIZE 3
1435 
1436 /* Array of filters applyed on a method */
1438 
1439 static void show_filter_init(show_filter_t *cf, const char *str, u1 flag, u1 default_flag, const char *description) {
1440  int err;
1441  char err_buf[128];
1442 
1443  if (str) {
1444  err = regcomp(&cf->regex, str, REG_EXTENDED | REG_NOSUB);
1445  if (err != 0) {
1446  regerror(err, &cf->regex, err_buf, sizeof(err_buf));
1447  vm_abort(
1448  "Invalid value given for %s: `%s' (%s).",
1449  description, str, err_buf
1450  );
1451  }
1452  cf->flag = flag;
1453  cf->enabled = 1;
1454  } else {
1455  cf->flag = default_flag;
1456  cf->enabled = 0;
1457  }
1458 }
1459 
1460 void show_filters_init(void) {
1461 
1463  show_filters + 0,
1467  "verbose call include filter"
1468  );
1469 
1471  show_filters + 1,
1474  0,
1475  "verbose call exclude filter"
1476  );
1477 
1479  show_filters + 2,
1483  "show method filter"
1484  );
1485 }
1486 
1487 /*
1488 
1489  (Pseudo)State machine:
1490 
1491  States are INITIAL, INCLUDE1, INCLUDE2, ..., EXCLUDE1, ..., EXCLUDE2, ...
1492 
1493  Enter Enter
1494  Enter Include Include
1495  Exclude | | | |
1496  | | Enter Enter Enter | | Enter | |
1497  | | Include Include Exclude | | Exclude | |
1498  | v ---------> ----------> ----------> | v ----------> | v
1499 INITIAL INCLUDE1 INCLUDE2 EXCLUDE1 EXCLUDE2
1500  | ^ <--------- <---------- <---------- | ^ <---------- | ^
1501  | | Exit Exit Exit | | Exit | |
1502  | | Include Include Exclude | | Exclude | |
1503  | | | | | |
1504  Exit Exit Exit
1505  Exclude Include Include
1506 
1507  Verbose call scope is active if we are in a INCLUDE state.
1508 
1509  State encoding:
1510 
1511  INITIAL: ctr[0] == 0, ctr[1] == 0
1512  INCLUDEN: ctr[1] == N, ctr[1] == 0
1513  EXCLUDEN: ctr[1] == N
1514 */
1515 
1517  // compose full name of method
1518  Buffer<> buf;
1519 
1520  const char *method_name = buf.write_slash_to_dot(m->clazz->name)
1521  .write('.')
1522  .write(m->name)
1523  .write(m->descriptor)
1524  .c_str();
1525 
1526  /* reset all flags */
1527 
1528  m->filtermatches = 0;
1529 
1530  for (int i = 0; i < SHOW_FILTERS_SIZE; ++i) {
1531  if (show_filters[i].enabled) {
1532 
1533  int res = regexec(&show_filters[i].regex, method_name, 0, NULL, 0);
1534 
1535  if (res == 0) {
1537  }
1538  } else {
1539  /* Default is to show all */
1541  }
1542  }
1543 }
1544 
1545 #define STATE_IS_INITIAL() ((FILTERVERBOSECALLCTR[0] == 0) && (FILTERVERBOSECALLCTR[1] == 0))
1546 #define STATE_IS_INCLUDE() ((FILTERVERBOSECALLCTR[0] > 0) && (FILTERVERBOSECALLCTR[1] == 0))
1547 #define STATE_IS_EXCLUDE() (FILTERVERBOSECALLCTR[1] > 0)
1548 #define EVENT_INCLUDE() (m->filtermatches & SHOW_FILTER_FLAG_VERBOSECALL_INCLUDE)
1549 #define EVENT_EXCLUDE() (m->filtermatches & SHOW_FILTER_FLAG_VERBOSECALL_EXCLUDE)
1550 #define TRANSITION_NEXT_INCLUDE() ++FILTERVERBOSECALLCTR[0]
1551 #define TRANSITION_PREV_INCLUDE() --FILTERVERBOSECALLCTR[0]
1552 #define TRANSITION_NEXT_EXCLUDE() ++FILTERVERBOSECALLCTR[1]
1553 #define TRANSITION_PREV_EXCLUDE() --FILTERVERBOSECALLCTR[1]
1554 
1555 #if 0
1556 void dump_state() {
1557  if (STATE_IS_INITIAL()) printf("<INITIAL>\n");
1558  else if (STATE_IS_INCLUDE()) printf("<INCLUDE %hd>\n", FILTERVERBOSECALLCTR[0]);
1559  else if (STATE_IS_EXCLUDE()) printf("<EXCLUDE %hd>\n", FILTERVERBOSECALLCTR[1]);
1560 }
1561 #endif
1562 
1564 
1565  int force_show = 0;
1566 
1567  if (STATE_IS_INITIAL()) {
1568  if (EVENT_INCLUDE()) {
1570  }
1571  } else if (STATE_IS_INCLUDE()) {
1572  if (EVENT_EXCLUDE()) {
1574  /* just entered exclude, show this method */
1575  force_show = 1;
1576  } else if (EVENT_INCLUDE()) {
1578  }
1579  } else if (STATE_IS_EXCLUDE()) {
1580  if (EVENT_EXCLUDE()) {
1582  }
1583  }
1584 
1585  return STATE_IS_INCLUDE() || force_show;
1586 }
1587 
1589 
1590  int force_show = 0;
1591 
1592  if (m) {
1593  if (STATE_IS_INCLUDE()) {
1594  if (EVENT_INCLUDE()) {
1596  /* just entered initial, show this method */
1597  if (STATE_IS_INITIAL()) force_show = 1;
1598  }
1599  } else if (STATE_IS_EXCLUDE()) {
1600  if (EVENT_EXCLUDE()) {
1602  }
1603  }
1604  }
1605 
1606  return STATE_IS_INCLUDE() || force_show;
1607 }
1608 
1609 #endif
1610 
1611 
1612 /*
1613  * These are local overrides for various environment variables in Emacs.
1614  * Please do not remove this and leave it at the end of the file, where
1615  * Emacs will automagically detect them.
1616  * ---------------------------------------------------------------------
1617  * Local variables:
1618  * mode: c++
1619  * indent-tabs-mode: t
1620  * c-basic-offset: 4
1621  * tab-width: 4
1622  * End:
1623  * vim:noexpandtab:sw=4:ts=4:
1624  */
#define SHOW_FIELD(fmiref)
Definition: show.cpp:702
#define SHOW_CODE
Definition: show.hpp:44
val_operand_t val
void show_javalocals_array(jitdata *jd, s4 *vars, int n, int stage)
Definition: show.cpp:903
Utf8String name
Definition: method.hpp:71
#define GET_HIGH_REG(a)
#define JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)
Definition: jit.hpp:231
#define EVENT_INCLUDE()
Definition: show.cpp:1548
#define SHOW_S2(iptr)
Definition: show.cpp:719
std::size_t index
methodinfo * outer
#define STATE_IS_INITIAL()
Definition: show.cpp:1545
basicblock * block
union varinfo::@19 vv
bool opt_showdisassemble
Definition: options.cpp:85
s4 exceptiontablelength
Definition: jit.hpp:167
basicblock * basicblocks
Definition: jit.hpp:141
Definition: jit.hpp:126
Definition: stack.hpp:46
void method_print(methodinfo *m)
Definition: method.cpp:1189
basicblock * returnblock
Definition: jit.hpp:170
#define TRANSITION_NEXT_EXCLUDE()
Definition: show.cpp:1552
#define max(a, b)
Definition: lsra.hpp:80
s4 localcount
Definition: jit.hpp:152
exception_entry * exceptiontable
Definition: jit.hpp:168
s4 bitflags
Definition: jit.hpp:321
State state
Definition: jit.hpp:320
bool is_classref() const
Definition: references.hpp:66
s4 maxlocals
Definition: jit.hpp:162
s4 * invars
Definition: jit.hpp:330
basicblock * next
Definition: jit.hpp:344
#define SHOW_DST_LOCAL(iptr)
Definition: show.cpp:743
void class_print(classinfo *c)
Definition: class.cpp:2231
#define TRANSITION_PREV_EXCLUDE()
Definition: show.cpp:1553
codeinfo * code
Definition: jit.hpp:128
insinfo_inline * inlineinfo
Definition: jit.hpp:350
void unresolved_class_debug_dump(unresolved_class *ref, FILE *file)
Definition: resolve.cpp:2982
s4 outdepth
Definition: jit.hpp:333
int32_t * stackvars
int32_t argcount
Definition: instruction.hpp:64
#define SHOW_PARSE
Definition: show.hpp:40
#define show_method(...)
Definition: ssa2.cpp:41
const char * c_str()
get contents of buffer as zero-terminated c-style-string This strings lifetime is tied to it&#39;s buffer...
Definition: buffer.hpp:489
bool opt_intrp
Definition: options.cpp:55
s4 successorcount
Definition: jit.hpp:338
void class_classref_or_classinfo_print(classref_or_classinfo c)
Definition: class.cpp:2306
s4 mpc
Definition: jit.hpp:352
codegendata * cd
Definition: jit.hpp:129
#define SHOW_FILTERS_SIZE
Definition: show.cpp:1434
s4 vartop
Definition: jit.hpp:149
bool show_init(void)
Definition: show.cpp:90
methoddesc * md
Definition: references.hpp:75
Dummy implementation of a mutex.
Definition: mutex-none.hpp:33
#define BBFLAG_REPLACEMENT
Definition: jit.hpp:292
constant_classref * ref
Definition: references.hpp:62
uint8_t u1
Definition: types.hpp:40
Type type
Definition: reg.hpp:44
s4 mcodelength
Definition: code.hpp:84
JNIEnv jclass jobject const char * name
Definition: jvmti.h:312
lookup_target_t * lookup
regex_t regex
Definition: show.cpp:1427
#define SHOW_DBL_CONST(val)
Definition: show.cpp:662
instruction * iinstr
Definition: jit.hpp:326
Buffer & write_slash_to_dot(const char *)
write to buffer, replacing &#39;/&#39; by &#39;.&#39;
Definition: buffer.hpp:297
#define VAR(i)
Definition: jit.hpp:259
Definition: reg.hpp:43
#define SHOW_STRING(val)
Definition: show.cpp:679
const char * opt_filter_show_method
Definition: options.cpp:145
s4 icount
Definition: jit.hpp:325
u1 enabled
Definition: show.cpp:1425
static int code_is_leafmethod(codeinfo *code)
Definition: code.hpp:150
const char * opt_filter_verbosecall_exclude
Definition: options.cpp:144
static void show_filter_init(show_filter_t *cf, const char *str, u1 flag, u1 default_flag, const char *description)
Definition: show.cpp:1439
void vm_abort(const char *text,...)
Definition: vm.cpp:2586
s4 regoff
Definition: reg.hpp:47
static void show_variable_array_intern(jitdata *jd, s4 *vars, int n, int stage, bool javalocals)
Definition: show.cpp:866
s4 varcount
Definition: jit.hpp:151
s4 * javalocals
Definition: jit.hpp:329
#define SHOW_S1(iptr)
Definition: show.cpp:714
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
#define GET_LOW_REG(a)
u1 * mcode
Definition: code.hpp:82
#define SHOW_FILTER_FLAG_VERBOSECALL_INCLUDE
Definition: show.hpp:68
#define TRANSITION_PREV_INCLUDE()
Definition: show.cpp:1551
void show_basicblock(jitdata *jd, basicblock *bptr, int stage)
Definition: show.cpp:440
#define SHOW_S1_LOCAL(iptr)
Definition: show.cpp:735
Utf8String descriptor
Definition: method.hpp:72
classref_or_classinfo c
#define SHOW_FILTER_FLAG_VERBOSECALL_EXCLUDE
Definition: show.hpp:69
#define SHOW_CFG
Definition: show.hpp:42
#define STATE_IS_EXCLUDE()
Definition: show.cpp:1547
branch_target_t target
Definition: instruction.hpp:57
dst_operand_t dst
flags_operand_t flags
#define SHOW_STACK
Definition: show.hpp:41
int show_filters_test_verbosecall_exit(methodinfo *m)
Definition: show.cpp:1588
void patcher_list_show(codeinfo *code)
Show the content of the whole patcher reference list for debugging purposes.
basicblock ** predecessors
Definition: jit.hpp:339
methodinfo * method
void method_println(methodinfo *m)
Definition: method.cpp:1218
classinfo * clazz
Definition: method.hpp:80
Option< bool > enabled("DebugCompiler2","compiler with compiler2", false, option::xx_root())
Definition: Compiler.hpp:115
basicblock * start
Definition: jit.hpp:241
static struct show_filter show_filters[SHOW_FILTERS_SIZE]
Definition: show.cpp:1437
s4 predecessorcount
Definition: jit.hpp:337
#define SHOW_FILTER_FLAG_SHOW_METHOD
Definition: show.hpp:70
Utf8String name
Definition: class.hpp:91
#define INSTRUCTION_GET_FIELDREF(iptr, fref)
basicblock * handler
Definition: jit.hpp:243
s4 returncount
Definition: jit.hpp:172
const char * show_jit_type_names[]
Definition: show.cpp:104
void show_filters_init(void)
Definition: show.cpp:1460
#define IS_FLT_DBL_TYPE(a)
Definition: global.hpp:131
int32_t paramcount
void class_classref_print(constant_classref *cr)
Definition: class.cpp:2251
#define RETADDR_FROM_JAVALOCAL(jl)
Definition: jit.hpp:424
#define TRANSITION_NEXT_INCLUDE()
Definition: show.cpp:1550
classref_or_classinfo catchtype
Definition: jit.hpp:244
s4 indepth
Definition: jit.hpp:332
u2 linenumbercount
Definition: method.hpp:94
s4 * local_map
Definition: jit.hpp:153
s4 maxstack
Definition: method.hpp:83
MIIterator i
Fieldref, Methodref and InterfaceMethodref.
Definition: references.hpp:86
typedesc returntype
Definition: descriptor.hpp:166
bool branchtoentry
Definition: jit.hpp:173
basicblock * copied_to
Definition: jit.hpp:345
int32_t s4
Definition: types.hpp:45
int32_t * javalocals_start
ICMD
Definition: icmd.hpp:37
registerdata * rd
Definition: jit.hpp:130
s4 maxlocals
Definition: method.hpp:84
#define SHOW_DST(iptr)
Definition: show.cpp:729
#define SHOW_REGS
Definition: show.hpp:43
void show_variable_array(jitdata *jd, s4 *vars, int n, int stage)
Definition: show.cpp:898
static Mutex mutex
Definition: show.cpp:72
s4 * outvars
Definition: jit.hpp:331
#define STATE_IS_INCLUDE()
Definition: show.cpp:1546
union instruction::@12 sx
#define EVENT_EXCLUDE()
Definition: show.cpp:1549
exception_entry * down
Definition: jit.hpp:247
OStream & err()
Definition: OStream.cpp:33
icmdtable_entry_t icmd_table[256]
Definition: icmd.cpp:60
const char * abi_registers_integer_name[]
Definition: md-abi.cpp:57
#define INSTRUCTION_GET_METHODDESC(iptr, md)
s1_operand_t s1
basicblock * block
Definition: instruction.hpp:50
#define FILTERVERBOSECALLCTR
Definition: thread.hpp:198
#define SHOW_TARGET(target)
Definition: show.cpp:624
static void show_variable_intern(jitdata *jd, s4 index, int stage)
Definition: show.cpp:805
void show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
Definition: show.cpp:908
int show_filters_test_verbosecall_enter(methodinfo *m)
Definition: show.cpp:1563
int memuse
Definition: reg.hpp:84
#define pc
Definition: md-asm.hpp:56
PatcherListTy * patchers
Definition: code.hpp:97
methodinfo * m
Definition: jit.hpp:127
void show_variable(jitdata *jd, s4 index, int stage)
Definition: show.cpp:799
void show_filters_apply(methodinfo *m)
Definition: show.cpp:1516
void method_methodref_print(constant_FMIref *mr)
Definition: method.cpp:1235
u1 filtermatches
Definition: method.hpp:120
void show_allocation(s4 type, s4 flags, s4 regoff)
Definition: show.cpp:751
s4 maxinterfaces
Definition: jit.hpp:165
basicblock * end
Definition: jit.hpp:242
interface_info * interface_map
Definition: jit.hpp:164
methodinfo * method
Definition: jit.hpp:349
LinenumberTable * linenumbertable
Definition: code.hpp:93
#define SHOW_CLASSREF_OR_CLASSINFO(c)
Definition: show.cpp:690
Buffer & write(char)
Definition: buffer.hpp:280
s4 flags
Definition: reg.hpp:45
java_handle_t * stringconst
s4 nr
Definition: jit.hpp:319
s4 basicblockcount
Definition: jit.hpp:144
basicblock * original
Definition: jit.hpp:347
#define SHOW_VARIABLE(v)
Definition: show.cpp:711
basicblock * retaddr
Definition: reg.hpp:52
#define INSTRUCTION_IS_UNRESOLVED(iptr)
bool branchtoend
Definition: jit.hpp:174
struct instruction::@12::@13 s23
void unlock()
Unlocks the given mutex object and checks for errors.
Definition: mutex-none.hpp:36
basicblock ** successors
Definition: jit.hpp:340
const parseddesc_t parseddesc
Definition: references.hpp:105
int32_t throughcount
Definition: jit.hpp:240
const char * opt_filter_verbosecall_include
Definition: options.cpp:143
#define str(x)
int32_t find(methodinfo **pm, void *pc)
Search the the line number table for the line corresponding to a given program counter.
uintptr_t ptrint
Definition: types.hpp:54
int32_t stackvarscount
#define SHOW_INT_CONST(val)
Definition: show.cpp:632
#define SHOW_LNG_CONST(val)
Definition: show.cpp:640
#define SHOW_ADR_CONST(val)
Definition: show.cpp:646
#define SHOW_S3(iptr)
Definition: show.cpp:724
Type type
Definition: jit.hpp:322
#define printf(...)
Definition: ssa2.cpp:40
#define INSTRUCTION_GET_METHODREF(iptr, mref)
branch_target_t * table
void lock()
Locks the given mutex object and checks for errors.
Definition: mutex-none.hpp:35
int32_t * javalocals_end
#define SHOW_FLT_CONST(val)
Definition: show.cpp:652
const char show_jit_type_letters[]
Definition: show.cpp:116
#define INS_FLAG_ID_SHIFT