LCOV - code coverage report
Current view: top level - vm/jit - show.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 29 500 5.8 %
Date: 2017-07-14 10:03:36 Functions: 7 17 41.2 %

          Line data    Source code
       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"
      52             : #include "vm/jit/patcher-common.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         165 : 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         163 : bool show_init(void)
      92             : {
      93             : #if defined(ENABLE_DEBUG_FILTER)
      94         163 :         show_filters_init();
      95             : #endif
      96             : 
      97             :         /* everything's ok */
      98             : 
      99         163 :         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           0 : 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           0 :         m    = jd->m;
     158           0 :         code = jd->code;
     159           0 :         cd   = jd->cd;
     160           0 :         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           0 :         mutex.lock();
     166             : 
     167             : #if defined(ENABLE_INTRP)
     168             :         if (opt_intrp)
     169             :                 irstage = SHOW_PARSE;
     170             :         else
     171             : #endif
     172           0 :                 irstage = stage;
     173             : 
     174             :         /* get the last basic block */
     175             : 
     176           0 :         for (lastbptr = jd->basicblocks; lastbptr->next != NULL; lastbptr = lastbptr->next);
     177             : 
     178           0 :         printf("\n");
     179             : 
     180           0 :         method_println(m);
     181             : 
     182           0 :         if (code_is_leafmethod(code))
     183           0 :                 printf("LEAFMETHOD\n");
     184             : 
     185           0 :         printf("\nBasic blocks: %d\n", jd->basicblockcount);
     186           0 :         if (stage >= SHOW_CODE) {
     187           0 :                 printf("Code length:  %d\n", (lastbptr->mpc - jd->basicblocks[0].mpc));
     188           0 :                 printf("Data length:  %d\n", cd->dseglen);
     189             :                 printf("Stub length:  %d\n", (s4) (code->mcodelength -
     190           0 :                                                                                    ((ptrint) cd->dseglen + lastbptr->mpc)));
     191             :         }
     192           0 :         printf("Variables:       %d (%d used)\n", jd->varcount, jd->vartop);
     193           0 :         if (stage >= SHOW_STACK)
     194           0 :                 printf("Max interfaces:  %d\n", jd->maxinterfaces);
     195           0 :         printf("Max locals:      %d\n", jd->maxlocals);
     196           0 :         printf("Max stack:       %d\n", m->maxstack);
     197           0 :         printf("Linenumbers:     %d\n", m->linenumbercount);
     198           0 :         printf("Branch to entry: %s\n", (jd->branchtoentry) ? "yes" : "no");
     199           0 :         printf("Branch to end:   %s\n", (jd->branchtoend) ? "yes" : "no");
     200           0 :         if (stage >= SHOW_STACK) {
     201           0 :                 printf("Number of RETURNs: %d", jd->returncount);
     202           0 :                 if (jd->returncount == 1)
     203           0 :                         printf(" (block L%03d)", jd->returnblock->nr);
     204           0 :                 printf("\n");
     205             :         }
     206             : 
     207           0 :         if (stage >= SHOW_PARSE) {
     208           0 :                 printf("Exceptions (number=%d):\n", jd->exceptiontablelength);
     209           0 :                 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
     210           0 :                         printf("    L%03d ... ", ex->start->nr );
     211           0 :                         printf("L%03d  = ", ex->end->nr);
     212           0 :                         printf("L%03d", ex->handler->nr);
     213           0 :                         printf("  (catchtype: ");
     214           0 :                         if (ex->catchtype.any)
     215           0 :                                 if (ex->catchtype.is_classref())
     216           0 :                                         class_classref_print(ex->catchtype.ref);
     217             :                                 else
     218           0 :                                         class_print(ex->catchtype.cls);
     219             :                         else
     220           0 :                                 printf("ANY");
     221           0 :                         printf(")\n");
     222             :                 }
     223             :         }
     224             : 
     225           0 :         if (irstage >= SHOW_PARSE && rd && jd->localcount > 0) {
     226           0 :                 printf("Local Table:\n");
     227           0 :                 for (i = 0; i < jd->localcount; i++) {
     228           0 :                         printf("   %3d: ", i);
     229             : 
     230             : #if defined(ENABLE_JIT)
     231             : # if defined(ENABLE_INTRP)
     232             :                         if (!opt_intrp) {
     233             : # endif
     234           0 :                                 printf("   (%s) ", show_jit_type_names[VAR(i)->type]);
     235           0 :                                 if (irstage >= SHOW_REGS)
     236           0 :                                         show_allocation(VAR(i)->type, VAR(i)->flags, VAR(i)->vv.regoff);
     237           0 :                                 printf("\n");
     238             : # if defined(ENABLE_INTRP)
     239             :                         }
     240             : # endif
     241             : #endif /* defined(ENABLE_JIT) */
     242             :                 }
     243           0 :                 printf("\n");
     244             :         }
     245             : 
     246           0 :         if (jd->maxlocals > 0 && jd->local_map != NULL) {
     247           0 :                 printf("Local Map:\n");
     248           0 :                 printf("    index ");
     249           0 :                 for (j = 0; j < jd->maxlocals; j++) {
     250           0 :                         printf(" [%2d]", j);
     251             :                 }
     252           0 :                 printf("\n");
     253           0 :                 for (i = 0; i < 5; i++) {
     254           0 :                         printf("    %5s ",show_jit_type_names[i]);
     255           0 :                         for (j = 0; j < jd->maxlocals; j++) {
     256           0 :                                 if (jd->local_map[j*5+i] == jitdata::UNUSED)
     257           0 :                                         printf("  -- ");
     258             :                                 else
     259           0 :                                         printf("%4i ",jd->local_map[j*5+i]);
     260             :                         }
     261           0 :                         printf("\n");
     262             :                 }
     263           0 :                 printf("\n");
     264             :         }
     265             : 
     266           0 :         if (jd->maxinterfaces > 0 && jd->interface_map && irstage >= SHOW_STACK) {
     267           0 :                 bool exist = false;
     268           0 :                 interface_info *mapptr = jd->interface_map;
     269             :                 
     270             :                 /* look if there exist any INOUTS */
     271           0 :                 for (i = 0; (i < (5 * jd->maxinterfaces)) && !exist; i++, mapptr++)
     272           0 :                         exist = (mapptr->flags != jitdata::UNUSED);
     273             : 
     274           0 :                 if (exist) {
     275           0 :                         printf("Interface Table: (In/Outvars)\n");
     276           0 :                         printf("    depth ");
     277           0 :                         for (j = 0; j < jd->maxinterfaces; j++) {
     278           0 :                                 printf("      [%2d]", j);
     279             :                         }
     280           0 :                         printf("\n");
     281             : 
     282           0 :                         for (i = 0; i < 5; i++) {
     283           0 :                                 printf("    %5s      ",show_jit_type_names[i]);
     284           0 :                                 for (j = 0; j < jd->maxinterfaces; j++) {
     285           0 :                                         s4 flags  = jd->interface_map[j*5+i].flags;
     286           0 :                                         s4 regoff = jd->interface_map[j*5+i].regoff;
     287           0 :                                         if (flags == jitdata::UNUSED)
     288           0 :                                                 printf("  --      ");
     289             :                                         else {
     290             :                                                 int ch;
     291             : 
     292           0 :                                                 if (irstage >= SHOW_REGS) {
     293           0 :                                                         if (flags & SAVEDVAR) {
     294           0 :                                                                 if (flags & INMEMORY)
     295           0 :                                                                         ch = 'M';
     296             :                                                                 else
     297           0 :                                                                         ch = 'R';
     298             :                                                         }
     299             :                                                         else {
     300           0 :                                                                 if (flags & INMEMORY)
     301           0 :                                                                         ch = 'm';
     302             :                                                                 else
     303           0 :                                                                         ch = 'r';
     304             :                                                         }
     305           0 :                                                         printf("%c%03d(", ch, regoff);
     306           0 :                                                         show_allocation(i, flags, regoff);
     307           0 :                                                         printf(") ");
     308             :                                                 }
     309             :                                                 else {
     310           0 :                                                         if (flags & SAVEDVAR)
     311           0 :                                                                 printf("  I       ");
     312             :                                                         else
     313           0 :                                                                 printf("  i       ");
     314             :                                                 }
     315             :                                         }
     316             :                                 }
     317           0 :                                 printf("\n");
     318             :                         }
     319           0 :                         printf("\n");
     320             :                 }
     321             :         }
     322             : 
     323           0 :         if (rd->memuse && irstage >= SHOW_REGS) {
     324             :                 int max;
     325             : 
     326           0 :                 max = rd->memuse;
     327           0 :                 printf("Stack slots (memuse=%d", rd->memuse);
     328           0 :                 if (irstage >= SHOW_CODE) {
     329           0 :                         printf(", stackframesize=%d", cd->stackframesize);
     330           0 :                         max = cd->stackframesize;
     331             :                 }
     332           0 :                 printf("):\n");
     333           0 :                 for (i = 0; i < max; ++i) {
     334           0 :                         printf("    M%02d = 0x%02x(sp): ", i, i * 8);
     335           0 :                         for (j = 0; j < jd->vartop; ++j) {
     336           0 :                                 varinfo *v = VAR(j);
     337           0 :                                 if ((v->flags & INMEMORY) && (v->vv.regoff == i)) {
     338           0 :                                         show_variable(jd, j, irstage);
     339           0 :                                         putchar(' ');
     340             :                                 }
     341             :                         }
     342             : 
     343           0 :                         printf("\n");
     344             : 
     345             :                 }
     346           0 :                 printf("\n");
     347             :         }
     348             : 
     349           0 :         if (!code->patchers->empty()) {
     350           0 :                 int number = code->patchers->size();
     351           0 :                 printf("Patcher References (number=%d):\n", number);
     352           0 :                 patcher_list_show(code);
     353           0 :                 printf("\n");
     354             :         }
     355             : 
     356             : #if defined(ENABLE_REPLACEMENT)
     357             :         if (code->rplpoints) {
     358             :                 printf("Replacement Points:\n");
     359             :                 replace_show_replacement_points(code);
     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           0 :         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next)
     380           0 :                 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           0 :         mutex.unlock();
     400             : 
     401             :         /* finally flush the output */
     402             : 
     403           0 :         fflush(stdout);
     404           0 : }
     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           0 : 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           0 :         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           0 :                         deadcode = (bptr->state < basicblock::REACHED);
     473           0 :                         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           0 :                            (bptr->next) ? (bptr->next->nr) : -1);
     485             : 
     486           0 :                 switch (bptr->type) {
     487             :                 case basicblock::TYPE_STD:
     488           0 :                         printf("STD");
     489           0 :                         break;
     490             :                 case basicblock::TYPE_EXH:
     491           0 :                         printf("EXH");
     492           0 :                         break;
     493             :                 case basicblock::TYPE_SBR:
     494           0 :                         printf("SBR");
     495             :                         break;
     496             :                 }
     497             : 
     498           0 :                 printf(", icount: %d", bptr->icount);
     499             : 
     500           0 :                 if (irstage >= SHOW_CFG) {
     501           0 :                         printf(", preds: %d [ ", bptr->predecessorcount);
     502             : 
     503           0 :                         for (i = 0; i < bptr->predecessorcount; i++)
     504           0 :                                 printf("%d ", bptr->predecessors[i]->nr);
     505             : 
     506           0 :                         printf("]");
     507             :                 }
     508             : 
     509           0 :                 printf("):");
     510             : 
     511           0 :                 if (bptr->original)
     512           0 :                         printf(" (clone of L%03d)", bptr->original->nr);
     513             :                 else {
     514           0 :                         basicblock *b = bptr->copied_to;
     515           0 :                         if (b) {
     516           0 :                                 printf(" (copied to ");
     517           0 :                                 for (; b; b = b->copied_to)
     518           0 :                                         printf("L%03d ", b->nr);
     519           0 :                                 printf(")");
     520             :                         }
     521             :                 }
     522             : 
     523           0 :                 printf("\n");
     524             : 
     525           0 :                 if (irstage >= SHOW_CFG) {
     526           0 :                         printf("succs: %d [ ", bptr->successorcount);
     527             : 
     528           0 :                         for (i = 0; i < bptr->successorcount; i++)
     529           0 :                                 printf("%d ", bptr->successors[i]->nr);
     530             : 
     531           0 :                         printf("]\n");
     532             :                 }
     533             : 
     534           0 :                 if (irstage >= SHOW_STACK) {
     535           0 :                         printf("IN:  ");
     536           0 :                         show_variable_array(jd, bptr->invars, bptr->indepth, irstage);
     537           0 :                         printf(" javalocals: ");
     538           0 :                         if (bptr->javalocals)
     539           0 :                                 show_javalocals_array(jd, bptr->javalocals, bptr->method->maxlocals, irstage);
     540             :                         else
     541           0 :                                 printf("null");
     542           0 :                         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           0 :                 iptr = bptr->iinstr;
     566             : 
     567           0 :                 for (i = 0; i < bptr->icount; i++, iptr++) {
     568           0 :                         printf("%4d:%4d:  ", iptr->line, iptr->flags.bits >> INS_FLAG_ID_SHIFT);
     569             : 
     570           0 :                         show_icmd(jd, iptr, deadcode, irstage);
     571           0 :                         printf("\n");
     572             :                 }
     573             : 
     574           0 :                 if (irstage >= SHOW_STACK) {
     575           0 :                         printf("OUT: ");
     576           0 :                         show_variable_array(jd, bptr->outvars, bptr->outdepth, irstage);
     577           0 :                         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           0 : }
     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           0 : void show_allocation(s4 type, s4 flags, s4 regoff)
     761             : {
     762           0 :         if (type == TYPE_RET) {
     763           0 :                 printf("N/A");
     764           0 :                 return;
     765             :         }
     766             : 
     767           0 :         if (flags & INMEMORY) {
     768           0 :                 printf("M%02d", regoff);
     769           0 :                 return;
     770             :         }
     771             : 
     772           0 :         if (IS_FLT_DBL_TYPE(type)) {
     773           0 :                 printf("F%02d", regoff);
     774           0 :                 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)],
     787             :                                    abi_registers_integer_name[GET_HIGH_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           0 :                 printf("%3s", abi_registers_integer_name[regoff]);
     803             : #else
     804             :         printf("%3d", regoff);
     805             : #endif
     806             : }
     807             : 
     808           0 : void show_variable(jitdata *jd, s4 index, int stage)
     809             : {
     810           0 :         show_variable_intern(jd, index, stage);
     811           0 :         putchar(' ');
     812           0 : }
     813             : 
     814           0 : static void show_variable_intern(jitdata *jd, s4 index, int stage)
     815             : {
     816             :         char type;
     817             :         char kind;
     818             :         varinfo *v;
     819             : 
     820           0 :         if (index < 0 || index >= jd->vartop) {
     821           0 :                 printf("<INVALID INDEX:%d>", index);
     822           0 :                 return;
     823             :         }
     824             : 
     825           0 :         v = VAR(index);
     826             : 
     827           0 :         switch (v->type) {
     828           0 :                 case TYPE_INT: type = 'i'; break;
     829           0 :                 case TYPE_LNG: type = 'l'; break;
     830           0 :                 case TYPE_FLT: type = 'f'; break;
     831           0 :                 case TYPE_DBL: type = 'd'; break;
     832           0 :                 case TYPE_ADR: type = 'a'; break;
     833           0 :                 case TYPE_RET: type = 'r'; break;
     834           0 :                 default:       type = '?';
     835             :         }
     836             : 
     837           0 :         if (index < jd->localcount) {
     838           0 :                 kind = 'L';
     839           0 :                 if (v->flags & (PREALLOC | INOUT))
     840           0 :                                 printf("<INVALID FLAGS!>");
     841             :         }
     842             :         else {
     843           0 :                 if (v->flags & PREALLOC) {
     844           0 :                         kind = 'A';
     845           0 :                         if (v->flags & INOUT) {
     846             :                                 /* PREALLOC is used to avoid allocation of TYPE_RET */
     847           0 :                                 if (v->type == TYPE_RET)
     848           0 :                                         kind = 'i';
     849             :                                 else
     850           0 :                                         printf("<INVALID FLAGS!>");
     851             :                         }
     852             :                 }
     853           0 :                 else if (v->flags & INOUT)
     854           0 :                         kind = 'I';
     855             :                 else
     856           0 :                         kind = 'T';
     857             :         }
     858             : 
     859           0 :         printf("%c%c%d", kind, type, index);
     860             : 
     861           0 :         if (v->flags & SAVEDVAR)
     862           0 :                 putchar('!');
     863             : 
     864           0 :         if (stage >= SHOW_REGS || (v->flags & PREALLOC)) {
     865           0 :                 putchar('(');
     866           0 :                 show_allocation(v->type, v->flags, v->vv.regoff);
     867           0 :                 putchar(')');
     868             :         }
     869             : 
     870           0 :         if (v->type == TYPE_RET && (v->flags & PREALLOC)) {
     871           0 :                 printf("(L%03d)", v->vv.retaddr->nr);
     872             :         }
     873             : }
     874             : 
     875           0 : 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           0 :         if (vars == NULL) {
     882           0 :                 printf("<null>");
     883           0 :                 return;
     884             :         }
     885             : 
     886           0 :         printf("[");
     887           0 :         for (i=0; i<n; ++i) {
     888           0 :                 if (i)
     889           0 :                         putchar(' ');
     890           0 :                 if (vars[i] < 0) {
     891           0 :                         if (vars[i] == jitdata::UNUSED)
     892           0 :                                 putchar('-');
     893           0 :                         else if (javalocals) {
     894           0 :                                 nr = RETADDR_FROM_JAVALOCAL(vars[i]);
     895           0 :                                 printf("ret(L%03d)", nr);
     896             :                         }
     897             :                         else {
     898           0 :                                 printf("<INVALID INDEX:%d>", vars[i]);
     899             :                         }
     900             :                 }
     901             :                 else
     902           0 :                         show_variable_intern(jd, vars[i], stage);
     903             :         }
     904           0 :         printf("]");
     905             : }
     906             : 
     907           0 : void show_variable_array(jitdata *jd, s4 *vars, int n, int stage)
     908             : {
     909           0 :         show_variable_array_intern(jd, vars, n, stage, false);
     910           0 : }
     911             : 
     912           0 : void show_javalocals_array(jitdata *jd, s4 *vars, int n, int stage)
     913             : {
     914           0 :         show_variable_array_intern(jd, vars, n, stage, true);
     915           0 : }
     916             : 
     917           0 : 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           0 :         ICMD opcode = iptr->opc;
     928             : 
     929           0 :         printf("%s ", icmd_table[opcode].name);
     930             : 
     931           0 :         if (stage < SHOW_PARSE)
     932           0 :                 return;
     933             : 
     934           0 :         if (deadcode)
     935           0 :                 stage = SHOW_PARSE;
     936             : 
     937             :         /* Print the condition for conditional instructions. */
     938             : 
     939             :         /* XXX print condition from flags */
     940             : 
     941           0 :         if (iptr->flags.bits & INS_FLAG_UNRESOLVED)
     942           0 :                 printf("(UNRESOLVED) ");
     943             : 
     944           0 :         switch (opcode) {
     945             : 
     946             :         case ICMD_POP:
     947             :         case ICMD_CHECKNULL:
     948           0 :                 SHOW_S1(iptr);
     949           0 :                 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           0 :                 SHOW_S1(iptr);
     973           0 :                 SHOW_DST(iptr);
     974           0 :                 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           0 :                 SHOW_S1(iptr);
    1015           0 :                 SHOW_S2(iptr);
    1016           0 :                 SHOW_DST(iptr);
    1017           0 :                 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           0 :                 SHOW_S1(iptr);
    1036           0 :                 SHOW_INT_CONST(iptr->sx.val.i);      
    1037           0 :                 SHOW_DST(iptr);
    1038           0 :                 break;
    1039             : 
    1040             :                 /* ?ASTORECONST (trinary/const INT) */
    1041             :         case ICMD_IASTORECONST:
    1042             :         case ICMD_BASTORECONST:
    1043             :         case ICMD_CASTORECONST:
    1044             :         case ICMD_SASTORECONST:
    1045           0 :                 SHOW_S1(iptr);
    1046           0 :                 SHOW_S2(iptr);
    1047           0 :                 SHOW_INT_CONST(iptr->sx.s23.s3.constval);
    1048           0 :                 break;
    1049             : 
    1050             :                 /* const INT */
    1051             :         case ICMD_ICONST:
    1052           0 :                 SHOW_INT_CONST(iptr->sx.val.i);      
    1053           0 :                 SHOW_DST(iptr);
    1054           0 :                 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           0 :                 SHOW_S1(iptr);
    1067           0 :                 SHOW_LNG_CONST(iptr->sx.val.l);
    1068           0 :                 SHOW_DST(iptr);
    1069           0 :                 break;
    1070             : 
    1071             :                 /* trinary/const LNG (<= pointer size) */
    1072             :         case ICMD_LASTORECONST:
    1073           0 :                 SHOW_S1(iptr);
    1074           0 :                 SHOW_S2(iptr);
    1075           0 :                 SHOW_ADR_CONST(iptr->sx.s23.s3.constval);
    1076           0 :                 break;
    1077             : 
    1078             :                 /* const LNG */
    1079             :         case ICMD_LCONST:
    1080           0 :                 SHOW_LNG_CONST(iptr->sx.val.l);      
    1081           0 :                 SHOW_DST(iptr);
    1082           0 :                 break;
    1083             : 
    1084             :                 /* const FLT */
    1085             :         case ICMD_FCONST:
    1086           0 :                 SHOW_FLT_CONST(iptr->sx.val.f);      
    1087           0 :                 SHOW_DST(iptr);
    1088           0 :                 break;
    1089             : 
    1090             :                 /* const DBL */
    1091             :         case ICMD_DCONST:
    1092           0 :                 SHOW_DBL_CONST(iptr->sx.val.d);      
    1093           0 :                 SHOW_DST(iptr);
    1094           0 :                 break;
    1095             : 
    1096             :                 /* const ADR */
    1097             :         case ICMD_ACONST:
    1098           0 :                 if (iptr->flags.bits & INS_FLAG_CLASS) {
    1099           0 :                         SHOW_ADR_CONST(iptr->sx.val.anyptr);
    1100           0 :                         SHOW_CLASSREF_OR_CLASSINFO(iptr->sx.val.c);
    1101             :                 }
    1102           0 :                 else if (iptr->sx.val.anyptr == NULL) {
    1103           0 :                         printf("NULL ");
    1104             :                 }
    1105             :                 else {
    1106           0 :                         SHOW_ADR_CONST(iptr->sx.val.anyptr);
    1107           0 :                         SHOW_STRING(iptr->sx.val.stringconst);
    1108             :                 }
    1109           0 :                 SHOW_DST(iptr);
    1110           0 :                 break;
    1111             : 
    1112             :         case ICMD_AASTORECONST:
    1113           0 :                 SHOW_S1(iptr);
    1114           0 :                 SHOW_S2(iptr);
    1115           0 :                 printf("%p ", (void*) iptr->sx.s23.s3.constval);
    1116           0 :                 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           0 :                 if (opcode != ICMD_GETSTATIC && opcode != ICMD_PUTSTATICCONST) {
    1125           0 :                         SHOW_S1(iptr);
    1126           0 :                         if (opcode == ICMD_PUTFIELD) {
    1127           0 :                                 SHOW_S2(iptr);
    1128             :                         }
    1129             :                 }
    1130           0 :                 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
    1131           0 :                 SHOW_FIELD(fmiref);
    1132             : 
    1133           0 :                 if (opcode == ICMD_GETSTATIC || opcode == ICMD_GETFIELD) {
    1134           0 :                         SHOW_DST(iptr);
    1135             :                 }
    1136           0 :                 break;
    1137             : 
    1138             :         case ICMD_IINC:
    1139           0 :                 SHOW_S1_LOCAL(iptr);
    1140           0 :                 SHOW_INT_CONST(iptr->sx.val.i);
    1141           0 :                 SHOW_DST_LOCAL(iptr);
    1142           0 :                 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           0 :                 SHOW_S1(iptr);
    1153           0 :                 SHOW_S2(iptr);
    1154           0 :                 SHOW_S3(iptr);
    1155           0 :                 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           0 :                 SHOW_S1(iptr);
    1166           0 :                 SHOW_S2(iptr);
    1167           0 :                 SHOW_DST(iptr);
    1168           0 :                 break;
    1169             : 
    1170             :         case ICMD_RET:
    1171           0 :                 SHOW_S1_LOCAL(iptr);
    1172           0 :                 if (stage >= SHOW_STACK) {
    1173           0 :                         printf(" ---> L%03d", iptr->dst.block->nr);
    1174             :                 }
    1175           0 :                 break;
    1176             : 
    1177             :         case ICMD_ILOAD:
    1178             :         case ICMD_LLOAD:
    1179             :         case ICMD_FLOAD:
    1180             :         case ICMD_DLOAD:
    1181             :         case ICMD_ALOAD:
    1182           0 :                 SHOW_S1_LOCAL(iptr);
    1183           0 :                 SHOW_DST(iptr);
    1184           0 :                 break;
    1185             : 
    1186             :         case ICMD_ISTORE:
    1187             :         case ICMD_LSTORE:
    1188             :         case ICMD_FSTORE:
    1189             :         case ICMD_DSTORE:
    1190             :         case ICMD_ASTORE:
    1191           0 :                 SHOW_S1(iptr);
    1192           0 :                 SHOW_DST_LOCAL(iptr);
    1193           0 :                 if (stage >= SHOW_STACK && iptr->sx.s23.s3.javaindex != jitdata::UNUSED)
    1194           0 :                         printf(" (javaindex %d)", iptr->sx.s23.s3.javaindex);
    1195           0 :                 if (iptr->flags.bits & INS_FLAG_RETADDR) {
    1196           0 :                         printf(" (retaddr L%03d)", RETADDR_FROM_JAVALOCAL(iptr->sx.s23.s2.retaddrnr));
    1197             :                 }
    1198           0 :                 break;
    1199             : 
    1200             :         case ICMD_NEW:
    1201           0 :                 SHOW_DST(iptr);
    1202           0 :                 break;
    1203             : 
    1204             :         case ICMD_NEWARRAY:
    1205           0 :                 SHOW_DST(iptr);
    1206           0 :                 break;
    1207             : 
    1208             :         case ICMD_ANEWARRAY:
    1209           0 :                 SHOW_DST(iptr);
    1210           0 :                 break;
    1211             : 
    1212             :         case ICMD_MULTIANEWARRAY:
    1213           0 :                 if (stage >= SHOW_STACK) {
    1214           0 :                         argp = iptr->sx.s23.s2.args;
    1215           0 :                         i = iptr->s1.argcount;
    1216           0 :                         while (i--) {
    1217           0 :                                 SHOW_VARIABLE(*(argp++));
    1218             :                         }
    1219             :                 }
    1220             :                 else {
    1221           0 :                         printf("argcount=%d ", iptr->s1.argcount);
    1222             :                 }
    1223           0 :                 class_classref_or_classinfo_print(iptr->sx.s23.s3.c);
    1224           0 :                 putchar(' ');
    1225           0 :                 SHOW_DST(iptr);
    1226           0 :                 break;
    1227             : 
    1228             :         case ICMD_CHECKCAST:
    1229           0 :                 SHOW_S1(iptr);
    1230           0 :                 class_classref_or_classinfo_print(iptr->sx.s23.s3.c);
    1231           0 :                 putchar(' ');
    1232           0 :                 SHOW_DST(iptr);
    1233           0 :                 break;
    1234             : 
    1235             :         case ICMD_INSTANCEOF:
    1236           0 :                 SHOW_S1(iptr);
    1237           0 :                 SHOW_DST(iptr);
    1238           0 :                 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           0 :                 break;
    1250             : 
    1251             :         case ICMD_BUILTIN:
    1252           0 :                 if (stage >= SHOW_STACK) {
    1253           0 :                         argp = iptr->sx.s23.s2.args;
    1254           0 :                         i = iptr->s1.argcount;
    1255           0 :                         while (i--) {
    1256           0 :                                 if ((iptr->s1.argcount - 1 - i) == iptr->sx.s23.s3.bte->md->paramcount)
    1257           0 :                                         printf(" pass-through: ");
    1258           0 :                                 SHOW_VARIABLE(*(argp++));
    1259             :                         }
    1260             :                 }
    1261           0 :                 printf("%s ", iptr->sx.s23.s3.bte->cname);
    1262           0 :                 if (iptr->sx.s23.s3.bte->md->returntype.type != TYPE_VOID) {
    1263           0 :                         SHOW_DST(iptr);
    1264             :                 }
    1265           0 :                 break;
    1266             : 
    1267             :         case ICMD_INVOKEVIRTUAL:
    1268             :         case ICMD_INVOKESPECIAL:
    1269             :         case ICMD_INVOKESTATIC:
    1270             :         case ICMD_INVOKEINTERFACE:
    1271           0 :                 if (stage >= SHOW_STACK) {
    1272             :                         methoddesc *md;
    1273           0 :                         INSTRUCTION_GET_METHODDESC(iptr, md);
    1274           0 :                         argp = iptr->sx.s23.s2.args;
    1275           0 :                         i = iptr->s1.argcount;
    1276           0 :                         while (i--) {
    1277           0 :                                 if ((iptr->s1.argcount - 1 - i) == md->paramcount)
    1278           0 :                                         printf(" pass-through: ");
    1279           0 :                                 SHOW_VARIABLE(*(argp++));
    1280             :                         }
    1281             :                 }
    1282           0 :                 INSTRUCTION_GET_METHODREF(iptr, fmiref);
    1283           0 :                 method_methodref_print(fmiref);
    1284           0 :                 if (fmiref->parseddesc.md->returntype.type != TYPE_VOID) {
    1285           0 :                         putchar(' ');
    1286           0 :                         SHOW_DST(iptr);
    1287             :                 }
    1288           0 :                 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           0 :                 SHOW_S1(iptr);
    1297           0 :                 SHOW_INT_CONST(iptr->sx.val.i);      
    1298           0 :                 SHOW_TARGET(iptr->dst);
    1299           0 :                 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           0 :                 SHOW_S1(iptr);
    1308           0 :                 SHOW_LNG_CONST(iptr->sx.val.l);      
    1309           0 :                 SHOW_TARGET(iptr->dst);
    1310           0 :                 break;
    1311             : 
    1312             :         case ICMD_GOTO:
    1313           0 :                 SHOW_TARGET(iptr->dst);
    1314           0 :                 break;
    1315             : 
    1316             :         case ICMD_JSR:
    1317           0 :                 SHOW_TARGET(iptr->sx.s23.s3.jsrtarget);
    1318           0 :                 SHOW_DST(iptr);
    1319           0 :                 break;
    1320             : 
    1321             :         case ICMD_IFNULL:
    1322             :         case ICMD_IFNONNULL:
    1323           0 :                 SHOW_S1(iptr);
    1324           0 :                 SHOW_TARGET(iptr->dst);
    1325           0 :                 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           0 :                 SHOW_S1(iptr);
    1344           0 :                 SHOW_S2(iptr);
    1345           0 :                 SHOW_TARGET(iptr->dst);
    1346           0 :                 break;
    1347             : 
    1348             :         case ICMD_TABLESWITCH:
    1349           0 :                 SHOW_S1(iptr);
    1350           0 :                 table = iptr->dst.table;
    1351             : 
    1352           0 :                 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1;
    1353             : 
    1354           0 :                 printf("high=%d low=%d count=%d\n", iptr->sx.s23.s3.tablehigh, iptr->sx.s23.s2.tablelow, i);
    1355           0 :                 while (--i >= 0) {
    1356           0 :                         printf("\t\t%d --> ", (int) (table - iptr->dst.table));
    1357           0 :                         printf("L%03d\n", table->block->nr);
    1358           0 :                         table++;
    1359             :                 }
    1360             : 
    1361           0 :                 break;
    1362             : 
    1363             :         case ICMD_LOOKUPSWITCH:
    1364           0 :                 SHOW_S1(iptr);
    1365             : 
    1366             :                 printf("count=%d, default=L%03d\n",
    1367             :                            iptr->sx.s23.s2.lookupcount,
    1368           0 :                            iptr->sx.s23.s3.lookupdefault.block->nr);
    1369             : 
    1370           0 :                 lookup = iptr->dst.lookup;
    1371           0 :                 i = iptr->sx.s23.s2.lookupcount;
    1372             : 
    1373           0 :                 while (--i >= 0) {
    1374             :                         printf("\t\t%d --> L%03d\n",
    1375             :                                    lookup->value,
    1376           0 :                                    lookup->target.block->nr);
    1377           0 :                         lookup++;
    1378             :                 }
    1379           0 :                 break;
    1380             : 
    1381             :         case ICMD_FRETURN:
    1382             :         case ICMD_IRETURN:
    1383             :         case ICMD_DRETURN:
    1384             :         case ICMD_LRETURN:
    1385           0 :                 SHOW_S1(iptr);
    1386           0 :                 break;
    1387             : 
    1388             :         case ICMD_ARETURN:
    1389             :         case ICMD_ATHROW:
    1390           0 :                 SHOW_S1(iptr);
    1391           0 :                 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           0 :                 break;
    1398             : 
    1399             :         case ICMD_COPY:
    1400             :         case ICMD_MOVE:
    1401           0 :                 SHOW_S1(iptr);
    1402           0 :                 SHOW_DST(iptr);
    1403           0 :                 break;
    1404             :         case ICMD_GETEXCEPTION:
    1405           0 :                 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           0 :         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. */
    1434             :         u1 enabled;
    1435             :         /* Regular expression the method name is matched against */
    1436             :         regex_t regex;
    1437             :         /* Flag set on m->filtermatches if regex matches */
    1438             :         u1 flag;
    1439             : };
    1440             : 
    1441             : typedef struct show_filter show_filter_t;
    1442             : 
    1443             : #define SHOW_FILTERS_SIZE 3
    1444             : 
    1445             : /* Array of filters applyed on a method */
    1446             : static struct show_filter show_filters[SHOW_FILTERS_SIZE];
    1447             : 
    1448         489 : 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         489 :         if (str) {
    1453           0 :                 err = regcomp(&cf->regex, str, REG_EXTENDED | REG_NOSUB);
    1454           0 :                 if (err != 0) {
    1455           0 :                         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           0 :                         );
    1460             :                 }
    1461           0 :                 cf->flag = flag;
    1462           0 :                 cf->enabled = 1;
    1463             :         } else {
    1464         489 :                 cf->flag = default_flag;
    1465         489 :                 cf->enabled = 0;
    1466             :         }
    1467         489 : }
    1468             : 
    1469         163 : void show_filters_init(void) {
    1470             : 
    1471             :         show_filter_init(
    1472             :                 show_filters + 0,
    1473             :                 opt_filter_verbosecall_include,
    1474             :                 SHOW_FILTER_FLAG_VERBOSECALL_INCLUDE,
    1475             :                 SHOW_FILTER_FLAG_VERBOSECALL_INCLUDE,
    1476             :                 "verbose call include filter"
    1477         163 :         );
    1478             : 
    1479             :         show_filter_init(
    1480             :                 show_filters + 1,
    1481             :                 opt_filter_verbosecall_exclude,
    1482             :                 SHOW_FILTER_FLAG_VERBOSECALL_EXCLUDE,
    1483             :                 0,
    1484             :                 "verbose call exclude filter"
    1485         163 :         );
    1486             : 
    1487             :         show_filter_init(
    1488             :                 show_filters + 2,
    1489             :                 opt_filter_show_method,
    1490             :                 SHOW_FILTER_FLAG_SHOW_METHOD,
    1491             :                 SHOW_FILTER_FLAG_SHOW_METHOD,
    1492             :                 "show method filter"
    1493         163 :         );
    1494         163 : }
    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             : 
    1525       92267 : void show_filters_apply(methodinfo *m) {
    1526             :         // compose full name of method
    1527       92267 :         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       92267 :                                      .c_str();
    1534             : 
    1535             :         /* reset all flags */
    1536             : 
    1537       92267 :         m->filtermatches = 0;
    1538             : 
    1539      369068 :         for (int i = 0; i < SHOW_FILTERS_SIZE; ++i) {
    1540      276801 :                 if (show_filters[i].enabled) {
    1541             : 
    1542           0 :                         int res = regexec(&show_filters[i].regex, method_name, 0, NULL, 0);
    1543             : 
    1544           0 :                         if (res == 0) {
    1545           0 :                                 m->filtermatches |= show_filters[i].flag;
    1546             :                         }
    1547             :                 } else {
    1548             :                         /* Default is to show all */
    1549      276801 :                         m->filtermatches |= show_filters[i].flag;
    1550             :                 }
    1551           0 :         }
    1552       92267 : }
    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             : 
    1572           0 : int show_filters_test_verbosecall_enter(methodinfo *m) {
    1573             : 
    1574           0 :         int force_show = 0;
    1575             : 
    1576           0 :         if (STATE_IS_INITIAL()) {
    1577           0 :                 if (EVENT_INCLUDE()) {
    1578           0 :                         TRANSITION_NEXT_INCLUDE();
    1579             :                 }
    1580           0 :         } else if (STATE_IS_INCLUDE()) {
    1581           0 :                 if (EVENT_EXCLUDE()) {
    1582           0 :                         TRANSITION_NEXT_EXCLUDE();
    1583             :                         /* just entered exclude, show this method */
    1584           0 :                         force_show = 1;
    1585           0 :                 } else if (EVENT_INCLUDE()) {
    1586           0 :                         TRANSITION_NEXT_INCLUDE();
    1587             :                 }
    1588           0 :         } else if (STATE_IS_EXCLUDE()) {
    1589           0 :                 if (EVENT_EXCLUDE()) {
    1590           0 :                         TRANSITION_NEXT_EXCLUDE();
    1591             :                 }
    1592             :         }
    1593             : 
    1594           0 :         return STATE_IS_INCLUDE() || force_show;
    1595             : }
    1596             : 
    1597       20521 : int show_filters_test_verbosecall_exit(methodinfo *m) {
    1598             : 
    1599       20521 :         int force_show = 0;
    1600             : 
    1601       20521 :         if (m) {
    1602       20521 :                 if (STATE_IS_INCLUDE()) {
    1603           0 :                         if (EVENT_INCLUDE()) {
    1604           0 :                                 TRANSITION_PREV_INCLUDE();
    1605             :                                 /* just entered initial, show this method */
    1606           0 :                                 if (STATE_IS_INITIAL()) force_show = 1;
    1607             :                         }
    1608       20521 :             } else if (STATE_IS_EXCLUDE()) {
    1609           0 :                         if (EVENT_EXCLUDE()) {
    1610           0 :                                 TRANSITION_PREV_EXCLUDE();
    1611             :                         }
    1612             :                 }
    1613             :         }
    1614             : 
    1615       20521 :         return STATE_IS_INCLUDE() || force_show;
    1616         495 : }
    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             :  */

Generated by: LCOV version 1.11