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