* Removed all Id tags.
[cacao.git] / src / vm / jit / show.c
index e7a073a68a557f381456345cd04535101f4f0940..4031b6b706ebce9ef1ba576aa42a88db9fef7ff3 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/show.c - showing the intermediate representation
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Andreas Krall
-
-   Changes: Edwin Steiner
-            Christian Thalinger
-            Christian Ullrich
-
-   $Id$
-
 */
 
 
 #include "config.h"
-#include "vm/types.h"
 
 #include <assert.h>
 
+#include "vm/types.h"
+
 #include "mm/memory.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-#else
-# include "threads/none/lock.h"
-#endif
+#include "threads/lock-common.h"
 
 #include "vm/global.h"
-#include "vm/options.h"
 #include "vm/builtin.h"
 #include "vm/stringlocal.h"
+#include "vm/vm.h"
+
+#include "vm/jit/abi.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/show.h"
 #include "vm/jit/disass.h"
 #include "vm/jit/stack.h"
-
+#include "vm/jit/parse.h"
+
+#include "vmcore/options.h"
+
+#if defined(ENABLE_DEBUG_FILTER)
+#      include <sys/types.h>
+#      include <regex.h>
+#      if defined(ENABLE_THREADS)
+#              include "threads/native/threads.h"
+#      else
+#              include "threads/none/threads.h"
+#      endif
+#endif
 
 /* global variables ***********************************************************/
 
 #if defined(ENABLE_THREADS) && !defined(NDEBUG)
-static java_objectheader *show_global_lock;
+static java_object_t *show_global_lock;
 #endif
 
 
-/* forward declarations *******************************************************/
+/* prototypes *****************************************************************/
 
 #if !defined(NDEBUG)
-static void new_show_variable_array(jitdata *jd, s4 *vars, int n, int stage);
+static void show_variable_intern(jitdata *jd, s4 index, int stage);
 #endif
 
 
@@ -84,9 +85,13 @@ bool show_init(void)
 #if defined(ENABLE_THREADS)
        /* initialize the show lock */
 
-       show_global_lock = NEW(java_objectheader);
+       show_global_lock = NEW(java_object_t);
+
+       LOCK_INIT_OBJECT_LOCK(show_global_lock);
+#endif
 
-       lock_init_object_lock(show_global_lock);
+#if defined(ENABLE_DEBUG_FILTER)
+       show_filters_init();
 #endif
 
        /* everything's ok */
@@ -97,12 +102,27 @@ bool show_init(void)
 
 
 #if !defined(NDEBUG)
-static char *jit_type[] = {
+char *show_jit_type_names[] = {
        "INT",
        "LNG",
        "FLT",
        "DBL",
-       "ADR"
+       "ADR",
+       "??5",
+       "??6",
+       "??7",
+       "RET"
+};
+char show_jit_type_letters[] = {
+       'I',
+       'L',
+       'F',
+       'D',
+       'A',
+       '5',
+       '6',
+       '7',
+       'R'
 };
 #endif
 
@@ -116,7 +136,7 @@ static char *jit_type[] = {
 *******************************************************************************/
 
 #if !defined(NDEBUG)
-void new_show_method(jitdata *jd, int stage)
+void show_method(jitdata *jd, int stage)
 {
        methodinfo     *m;
        codeinfo       *code;
@@ -124,9 +144,12 @@ void new_show_method(jitdata *jd, int stage)
        registerdata   *rd;
        basicblock     *bptr;
        basicblock     *lastbptr;
-       exceptiontable *ex;
+       exception_entry *ex;
        s4              i, j;
-       u1             *u1ptr;
+       int             irstage;
+#if defined(ENABLE_DISASSEMBLER)
+       u1             *pc;
+#endif
 
        /* get required compiler data */
 
@@ -141,99 +164,95 @@ void new_show_method(jitdata *jd, int stage)
 
        LOCK_MONITOR_ENTER(show_global_lock);
 
+#if defined(ENABLE_INTRP)
+       if (opt_intrp)
+               irstage = SHOW_PARSE;
+       else
+#endif
+               irstage = stage;
+
        /* get the last basic block */
 
-       for (lastbptr = jd->new_basicblocks; lastbptr->next != NULL; lastbptr = lastbptr->next);
+       for (lastbptr = jd->basicblocks; lastbptr->next != NULL; lastbptr = lastbptr->next);
 
        printf("\n");
 
        method_println(m);
 
-       printf("\n(NEW INSTRUCTION FORMAT)\n");
-       printf("\nBasic blocks: %d\n", jd->new_basicblockcount);
+       if (jd->isleafmethod)
+               printf("LEAFMETHOD\n");
+
+       printf("\nBasic blocks: %d\n", jd->basicblockcount);
        if (stage >= SHOW_CODE) {
-               printf("Code length:  %d\n", (lastbptr->mpc - jd->new_basicblocks[0].mpc));
+               printf("Code length:  %d\n", (lastbptr->mpc - jd->basicblocks[0].mpc));
                printf("Data length:  %d\n", cd->dseglen);
                printf("Stub length:  %d\n", (s4) (code->mcodelength -
                                                                                   ((ptrint) cd->dseglen + lastbptr->mpc)));
        }
-       printf("Max locals:   %d\n", cd->maxlocals);
-       printf("Max stack:    %d\n", cd->maxstack);
-       printf("Line number table length: %d\n", m->linenumbercount);
+       printf("Variables:       %d (%d used)\n", jd->varcount, jd->vartop);
+       if (stage >= SHOW_STACK)
+               printf("Max interfaces:  %d\n", jd->maxinterfaces);
+       printf("Max locals:      %d\n", jd->maxlocals);
+       printf("Max stack:       %d\n", m->maxstack);
+       printf("Linenumbers:     %d\n", m->linenumbercount);
+       printf("Branch to entry: %s\n", (jd->branchtoentry) ? "yes" : "no");
+       printf("Branch to end:   %s\n", (jd->branchtoend) ? "yes" : "no");
+       if (stage >= SHOW_STACK) {
+               printf("Number of RETURNs: %d", jd->returncount);
+               if (jd->returncount == 1)
+                       printf(" (block L%03d)", jd->returnblock->nr);
+               printf("\n");
+       }
 
        if (stage >= SHOW_PARSE) {
-               printf("Exceptions (Number: %d):\n", cd->exceptiontablelength);
-               for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
+               printf("Exceptions (Number: %d):\n", jd->exceptiontablelength);
+               for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
                        printf("    L%03d ... ", ex->start->nr );
                        printf("L%03d  = ", ex->end->nr);
                        printf("L%03d", ex->handler->nr);
                        printf("  (catchtype: ");
                        if (ex->catchtype.any)
                                if (IS_CLASSREF(ex->catchtype))
-                                       utf_display_printable_ascii_classname(ex->catchtype.ref->name);
+                                       class_classref_print(ex->catchtype.ref);
                                else
-                                       utf_display_printable_ascii_classname(ex->catchtype.cls->name);
+                                       class_print(ex->catchtype.cls);
                        else
                                printf("ANY");
                        printf(")\n");
                }
        }
        
-       if (stage >= SHOW_PARSE && rd && cd->maxlocals > 0) {
-       printf("Local Table:\n");
-       for (i = 0; i < cd->maxlocals; i++) {
-               printf("   %3d: ", i);
+       if (irstage >= SHOW_PARSE && rd && jd->localcount > 0) {
+               printf("Local Table:\n");
+               for (i = 0; i < jd->localcount; i++) {
+                       printf("   %3d: ", i);
 
 #if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
-/*             for (j = TYPE_INT; j <= TYPE_ADR; j++) { */
 # if defined(ENABLE_INTRP)
                        if (!opt_intrp) {
 # endif
-/*                             if (rd->locals[i][j].type >= 0) { */
-                                       printf("   (%s) ", jit_type[jd->var[i].type]);
-                                       if (stage >= SHOW_REGS) {
-                                               if (jd->var[i].flags & INMEMORY)
-                                                       printf("m%2d", jd->var[i].regoff);
-# ifdef HAS_ADDRESS_REGISTER_FILE
-                                               else if (jd->var[i].type == TYPE_ADR)
-                                                       printf("r%02d", jd->var[i].regoff);
-# endif
-                                               else if ((jd->var[i].type == TYPE_FLT) ||
-                                                                (jd->var[i].type == TYPE_DBL))
-                                                       printf("f%02d", jd->var[i].regoff);
-                                               else {
-# if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                                                       if (IS_2_WORD_TYPE(j))
-                                                               printf(" %3s/%3s",
-                                                                          regs[GET_LOW_REG(jd->var[i].regoff)],
-                                                                          regs[GET_HIGH_REG(jd->var[i].regoff)]);
-                                                       else
-# endif
-                                                               printf("%3s", regs[jd->var[i].regoff]);
-                                               }
-                                       }
-/*                             } */
+                               printf("   (%s) ", show_jit_type_names[VAR(i)->type]);
+                               if (irstage >= SHOW_REGS)
+                                       show_allocation(VAR(i)->type, VAR(i)->flags, VAR(i)->vv.regoff);
+                               printf("\n");
 # if defined(ENABLE_INTRP)
                        }
 # endif
-/*             } */
 #endif /* defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER) */
-
+               }
                printf("\n");
        }
-       printf("\n");
-       }
 
-       if (cd->maxlocals > 0) {
+       if (jd->maxlocals > 0 && jd->local_map != NULL) {
                printf("Local Map:\n");
                printf("    index ");
-               for (j = 0; j < cd->maxlocals; j++) {
+               for (j = 0; j < jd->maxlocals; j++) {
                        printf(" [%2d]", j);
                }
                printf("\n");
                for (i = 0; i < 5; i++) {
-                       printf("    %5s ",jit_type[i]);
-                       for (j = 0; j < cd->maxlocals; j++) {
+                       printf("    %5s ",show_jit_type_names[i]);
+                       for (j = 0; j < jd->maxlocals; j++) {
                                if (jd->local_map[j*5+i] == UNUSED)
                                        printf("  -- ");
                                else
@@ -244,29 +263,56 @@ void new_show_method(jitdata *jd, int stage)
                printf("\n");
        }
 
-       if (cd->maxstack > 0 && jd->interface_map) {
+       if (jd->maxinterfaces > 0 && jd->interface_map && irstage >= SHOW_STACK) {
                bool exist = false;
-               s4 *mapptr = jd->interface_map;
+               interface_info *mapptr = jd->interface_map;
                
-               /* look if there exist any IN/OUTVARS */
-               for (i = 0; (i < (5 * cd->maxstack)) && !exist; i++, mapptr++)
-                       exist = (*mapptr != UNUSED);
+               /* look if there exist any INOUTS */
+               for (i = 0; (i < (5 * jd->maxinterfaces)) && !exist; i++, mapptr++)
+                       exist = (mapptr->flags != UNUSED);
 
                if (exist) {
                        printf("Interface Table: (In/Outvars)\n");
                        printf("    depth ");
-                       for (j = 0; j < cd->maxstack; j++) {
-                               printf(" [%2d]", j);
+                       for (j = 0; j < jd->maxinterfaces; j++) {
+                               printf("      [%2d]", j);
                        }
                        printf("\n");
 
                        for (i = 0; i < 5; i++) {
-                               printf("    %5s ",jit_type[i]);
-                               for (j = 0; j < cd->maxstack; j++) {
-                                       if (jd->interface_map[j*5+i] == UNUSED)
-                                               printf("  -- ");
-                                       else
-                                               printf("%4i ", jd->interface_map[j*5+i]);
+                               printf("    %5s      ",show_jit_type_names[i]);
+                               for (j = 0; j < jd->maxinterfaces; j++) {
+                                       s4 flags  = jd->interface_map[j*5+i].flags;
+                                       s4 regoff = jd->interface_map[j*5+i].regoff;
+                                       if (flags == UNUSED)
+                                               printf("  --      ");
+                                       else {
+                                               int ch;
+
+                                               if (irstage >= SHOW_REGS) {
+                                                       if (flags & SAVEDVAR) {
+                                                               if (flags & INMEMORY)
+                                                                       ch = 'M';
+                                                               else
+                                                                       ch = 'R';
+                                                       }
+                                                       else {
+                                                               if (flags & INMEMORY)
+                                                                       ch = 'm';
+                                                               else
+                                                                       ch = 'r';
+                                                       }
+                                                       printf("%c%03d(", ch, regoff);
+                                                       show_allocation(i, flags, regoff);
+                                                       printf(") ");
+                                               }
+                                               else {
+                                                       if (flags & SAVEDVAR)
+                                                               printf("  I       ");
+                                                       else
+                                                               printf("  i       ");
+                                               }
+                                       }
                                }
                                printf("\n");
                        }
@@ -274,20 +320,52 @@ void new_show_method(jitdata *jd, int stage)
                }
        }
 
+       if (rd->memuse && irstage >= SHOW_REGS) {
+               int max;
+
+               max = rd->memuse;
+               printf("Stack slots: (memuse=%d", rd->memuse);
+               if (irstage >= SHOW_CODE) {
+                       printf(", stackframesize=%d", cd->stackframesize);
+                       max = cd->stackframesize;
+               }
+               printf(")\n");
+               for (i = 0; i < max; ++i) {
+#if defined(HAS_4BYTE_STACKSLOT)
+                       printf("    M%02d = 0x%02x(sp): ", i, i * 4);
+#else
+                       printf("    M%02d = 0x%02x(sp): ", i, i * 8);
+#endif
+                       for (j = 0; j < jd->vartop; ++j) {
+                               varinfo *v = VAR(j);
+                               if ((v->flags & INMEMORY) && (v->vv.regoff == i)) {
+                                       show_variable(jd, j, irstage);
+                                       putchar(' ');
+                               }
+                       }
+
+                       printf("\n");
+
+               }
+               printf("\n");
+       }
+
+#if defined(ENABLE_REPLACEMENT)
        if (code->rplpoints) {
                printf("Replacement Points:\n");
                replace_show_replacement_points(code);
                printf("\n");
        }
+#endif /* defined(ENABLE_REPLACEMENT) */
 
 #if defined(ENABLE_DISASSEMBLER)
        /* show code before first basic block */
 
        if ((stage >= SHOW_CODE) && JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
-               u1ptr = (u1 *) ((ptrint) code->mcode + cd->dseglen);
+               pc = (u1 *) ((ptrint) code->mcode + cd->dseglen);
 
-               for (; u1ptr < (u1 *) ((ptrint) code->mcode + cd->dseglen + jd->new_basicblocks[0].mpc);)
-                       DISASSINSTR(u1ptr);
+               for (; pc < (u1 *) ((ptrint) code->mcode + cd->dseglen + jd->basicblocks[0].mpc);)
+                       DISASSINSTR(pc);
 
                printf("\n");
        }
@@ -295,8 +373,8 @@ void new_show_method(jitdata *jd, int stage)
 
        /* show code of all basic blocks */
 
-       for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next)
-               new_show_basicblock(jd, bptr, stage);
+       for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next)
+               show_basicblock(jd, bptr, stage);
 
 #if defined(ENABLE_DISASSEMBLER)
        /* show stubs code */
@@ -306,10 +384,10 @@ void new_show_method(jitdata *jd, int stage)
                printf("Length: %d\n\n", (s4) (code->mcodelength -
                                                                           ((ptrint) cd->dseglen + lastbptr->mpc)));
 
-               u1ptr = (u1 *) ((ptrint) code->mcode + cd->dseglen + lastbptr->mpc);
+               pc = (u1 *) ((ptrint) code->mcode + cd->dseglen + lastbptr->mpc);
 
-               for (; (ptrint) u1ptr < ((ptrint) code->mcode + code->mcodelength);)
-                       DISASSINSTR(u1ptr);
+               for (; (ptrint) pc < ((ptrint) code->mcode + code->mcodelength);)
+                       DISASSINSTR(pc);
 
                printf("\n");
        }
@@ -324,6 +402,38 @@ void new_show_method(jitdata *jd, int stage)
 #endif /* !defined(NDEBUG) */
 
 
+#if !defined(NDEBUG) && defined(ENABLE_INLINING)
+static void show_inline_info(jitdata *jd, insinfo_inline *ii, s4 opcode, s4 stage)
+{
+       s4 *jl;
+       s4 n;
+
+       printf("(pt %d+%d+%d st ", 
+                       ii->throughcount - (ii->stackvarscount - ii->paramcount),
+                       ii->stackvarscount - ii->paramcount,
+                       ii->paramcount);
+       show_variable_array(jd, ii->stackvars, ii->stackvarscount, stage);
+
+       if (opcode == ICMD_INLINE_START || opcode == ICMD_INLINE_END) {
+               printf(" jl ");
+               jl = (opcode == ICMD_INLINE_START) ? ii->javalocals_start : ii->javalocals_end;
+               n = (opcode == ICMD_INLINE_START) ? ii->method->maxlocals : ii->outer->maxlocals;
+               show_javalocals_array(jd, jl, n, stage);
+       }
+
+       printf(") ");
+
+#if 0
+       printf("(");
+       method_print(ii->outer);
+       printf(" ==> ");
+#endif
+
+       method_print(ii->method);
+}
+#endif /* !defined(NDEBUG) && defined(ENABLE_INLINING) */
+
+
 /* show_basicblock *************************************************************
 
    Print the intermediate representation of a basic block.
@@ -333,28 +443,47 @@ void new_show_method(jitdata *jd, int stage)
 *******************************************************************************/
 
 #if !defined(NDEBUG)
-void new_show_basicblock(jitdata *jd, basicblock *bptr, int stage)
+void show_basicblock(jitdata *jd, basicblock *bptr, int stage)
 {
-       methodinfo  *m;
        codeinfo    *code;
        codegendata *cd;
        s4           i;
        bool         deadcode;
        instruction *iptr;
-       u1          *u1ptr;
+       int          irstage;
+#if defined(ENABLE_DISASSEMBLER)
+       methodinfo  *m;                     /* this is only a dummy               */
+       u1          *pc;
+       s4           linenumber;
+       s4           currentlinenumber;
+#endif
 
        /* get required compiler data */
 
-       m    = jd->m;
        code = jd->code;
        cd   = jd->cd;
 
        if (bptr->flags != BBDELETED) {
-               deadcode = bptr->flags <= BBREACHED;
+#if defined(ENABLE_INTRP)
+               if (opt_intrp) {
+                       deadcode = false;
+                       irstage = SHOW_PARSE;
+               }
+               else
+#endif
+               {
+                       deadcode = (bptr->flags < BBREACHED);
+                       irstage = stage;
+               }
 
-               printf("======== %sL%03d ======== (flags: %d, bitflags: %01x, next: %d, type: ",
-                               (bptr->bitflags & BBFLAG_REPLACEMENT) ? "<REPLACE> " : "",
-                          bptr->nr, bptr->flags, bptr->bitflags, 
+               printf("======== %sL%03d ======== %s(flags: %d, bitflags: %01x, next: %d, type: ",
+#if defined(ENABLE_REPLACEMENT)
+                               (bptr->bitflags & BBFLAG_REPLACEMENT) ? "<REPLACE> " : 
+#endif
+                                                                                                               "",
+                          bptr->nr, 
+                          (deadcode && stage >= SHOW_STACK) ? "DEADCODE! " : "",
+                          bptr->flags, bptr->bitflags, 
                           (bptr->next) ? (bptr->next->nr) : -1);
 
                switch (bptr->type) {
@@ -369,32 +498,61 @@ void new_show_basicblock(jitdata *jd, basicblock *bptr, int stage)
                        break;
                }
 
-               printf(", instruction count: %d, predecessors: %d [ ",
-                          bptr->icount, bptr->predecessorcount);
+               printf(", icount: %d", bptr->icount);
 
-               for (i = 0; i < bptr->predecessorcount; i++)
-                       printf("%d ", bptr->predecessors[i]->nr);
+               if (irstage >= SHOW_CFG) {
+                       printf(", preds: %d [ ", bptr->predecessorcount);
 
-               printf("]):\n");
+                       for (i = 0; i < bptr->predecessorcount; i++)
+                               printf("%d ", bptr->predecessors[i]->nr);
 
-               if (stage >= SHOW_STACK) {
+                       printf("]");
+               }
+
+               printf("):");
+
+               if (bptr->original)
+                       printf(" (clone of L%03d)", bptr->original->nr);
+               else {
+                       basicblock *b = bptr->copied_to;
+                       if (b) {
+                               printf(" (copied to ");
+                               for (; b; b = b->copied_to)
+                                       printf("L%03d ", b->nr);
+                               printf(")");
+                       }
+               }
+
+               printf("\n");
+
+               if (irstage >= SHOW_STACK) {
                        printf("IN:  ");
-                       new_show_variable_array(jd, bptr->invars, bptr->indepth, stage);
+                       show_variable_array(jd, bptr->invars, bptr->indepth, irstage);
+                       printf(" javalocals: ");
+                       show_javalocals_array(jd, bptr->javalocals, bptr->method->maxlocals, irstage);
+                       printf("\n");
+               }
+
+#if defined(ENABLE_INLINING)
+               if (bptr->inlineinfo) {
+                       printf("inlineinfo: ");
+                       show_inline_info(jd, bptr->inlineinfo, -1, irstage);
                        printf("\n");
                }
+#endif /* defined(ENABLE_INLINING) */
 
                iptr = bptr->iinstr;
 
                for (i = 0; i < bptr->icount; i++, iptr++) {
-                       printf("%4d:  ", iptr->line);
+                       printf("%4d:%4d:  ", iptr->line, iptr->flags.bits >> INS_FLAG_ID_SHIFT);
 
-                       new_show_icmd(jd, iptr, deadcode, stage);
+                       show_icmd(jd, iptr, deadcode, irstage);
                        printf("\n");
                }
 
-               if (stage >= SHOW_STACK) {
+               if (irstage >= SHOW_STACK) {
                        printf("OUT: ");
-                       new_show_variable_array(jd, bptr->outvars, bptr->outdepth, stage);
+                       show_variable_array(jd, bptr->outvars, bptr->outdepth, irstage);
                        printf("\n");
                }
 
@@ -403,16 +561,34 @@ void new_show_basicblock(jitdata *jd, basicblock *bptr, int stage)
                        (!deadcode)) 
                {
                        printf("\n");
-                       u1ptr = (u1 *) (code->mcode + cd->dseglen + bptr->mpc);
+                       pc         = (u1 *) (code->mcode + cd->dseglen + bptr->mpc);
+                       linenumber = 0;
 
                        if (bptr->next != NULL) {
-                               for (; u1ptr < (u1 *) (code->mcode + cd->dseglen + bptr->next->mpc);)
-                                       DISASSINSTR(u1ptr);
+                               for (; pc < (u1 *) (code->mcode + cd->dseglen + bptr->next->mpc);) {
+                                       currentlinenumber =
+                                               dseg_get_linenumber_from_pc(&m, code->entrypoint, pc);
 
-                       } 
+                                       if (currentlinenumber != linenumber) {
+                                               linenumber = currentlinenumber;
+                                               printf("%4d:\n", linenumber);
+                                       }
+
+                                       DISASSINSTR(pc);
+                               }
+                       }
                        else {
-                               for (; u1ptr < (u1 *) (code->mcode + code->mcodelength);)
-                                       DISASSINSTR(u1ptr); 
+                               for (; pc < (u1 *) (code->mcode + code->mcodelength);) {
+                                       currentlinenumber =
+                                               dseg_get_linenumber_from_pc(&m, code->entrypoint, pc);
+
+                                       if (currentlinenumber != linenumber) {
+                                               linenumber = currentlinenumber;
+                                               printf("%4d:\n", linenumber);
+                                       }
+
+                                       DISASSINSTR(pc);
+                               }
                        }
                        printf("\n");
                }
@@ -433,49 +609,78 @@ void new_show_basicblock(jitdata *jd, basicblock *bptr, int stage)
 #if !defined(NDEBUG)
 
 #define SHOW_TARGET(target)                                          \
-        if (stage >= SHOW_STACK) {                                   \
+        if (stage >= SHOW_PARSE) {                                   \
             printf("--> L%03d ", (target).block->nr);                \
         }                                                            \
-        else if (stage >= SHOW_PARSE) {                              \
-            printf("--> insindex %d (L%03d) ", (target).insindex,    \
-                jd->new_basicblocks[jd->new_basicblockindex[         \
-                (target).insindex]].nr);                             \
-        }                                                            \
         else {                                                       \
             printf("--> insindex %d ", (target).insindex);           \
         }
 
 #define SHOW_INT_CONST(val)                                          \
         if (stage >= SHOW_PARSE) {                                   \
-            printf("%ld ", (long) (val));                            \
+            printf("%d (0x%08x) ", (val), (val));                    \
         }                                                            \
         else {                                                       \
             printf("iconst ");                                       \
         }
 
+#if SIZEOF_VOID_P == 4
 #define SHOW_LNG_CONST(val)                                          \
-        if (stage >= SHOW_PARSE) {                                   \
-            printf("%lld ", (long long)(val));                       \
-        }                                                            \
-        else {                                                       \
-            printf("lconst ");                                       \
-        }
+        if (stage >= SHOW_PARSE)                                     \
+            printf("%lld (0x%016llx) ", (val), (val));               \
+        else                                                         \
+            printf("lconst ");
+#else
+#define SHOW_LNG_CONST(val)                                          \
+        if (stage >= SHOW_PARSE)                                     \
+            printf("%ld (0x%016lx) ", (val), (val));                 \
+        else                                                         \
+            printf("lconst ");
+#endif
+
+#if SIZEOF_VOID_P == 4
+#define SHOW_ADR_CONST(val)                                          \
+        if (stage >= SHOW_PARSE)                                     \
+            printf("0x%08x ", (ptrint) (val));                       \
+        else                                                         \
+            printf("aconst ");
+#else
+#define SHOW_ADR_CONST(val)                                          \
+        if (stage >= SHOW_PARSE)                                     \
+            printf("0x%016lx ", (ptrint) (val));                     \
+        else                                                         \
+            printf("aconst ");
+#endif
 
 #define SHOW_FLT_CONST(val)                                          \
         if (stage >= SHOW_PARSE) {                                   \
-            printf("%g ", (val));                                    \
+            imm_union v;                                             \
+            v.f = (val);                                             \
+            printf("%g (0x%08x) ", (val), v.i);                      \
         }                                                            \
         else {                                                       \
             printf("fconst ");                                       \
         }
 
+#if SIZEOF_VOID_P == 4
 #define SHOW_DBL_CONST(val)                                          \
         if (stage >= SHOW_PARSE) {                                   \
-            printf("%g ", (val));                                    \
+            imm_union v;                                             \
+            v.d = (val);                                             \
+            printf("%g (0x%016llx) ", (val), v.l);                   \
         }                                                            \
-        else {                                                       \
-            printf("dconst ");                                       \
-        }
+        else                                                         \
+            printf("dconst ");
+#else
+#define SHOW_DBL_CONST(val)                                          \
+        if (stage >= SHOW_PARSE) {                                   \
+            imm_union v;                                             \
+            v.d = (val);                                             \
+            printf("%g (0x%016lx) ", (val), v.l);                    \
+        }                                                            \
+        else                                                         \
+            printf("dconst ");
+#endif
 
 #define SHOW_INDEX(index)                                            \
         if (stage >= SHOW_PARSE) {                                   \
@@ -489,7 +694,7 @@ void new_show_basicblock(jitdata *jd, basicblock *bptr, int stage)
         if (stage >= SHOW_PARSE) {                                   \
             putchar('"');                                            \
             utf_display_printable_ascii(                             \
-                javastring_toutf((java_lang_String *)(val), false)); \
+               javastring_toutf((java_handle_t *)(val), false));     \
             printf("\" ");                                           \
         }                                                            \
         else {                                                       \
@@ -544,119 +749,197 @@ void new_show_basicblock(jitdata *jd, basicblock *bptr, int stage)
 #define SHOW_S1_LOCAL(iptr)                                          \
     if (stage >= SHOW_STACK) {                                       \
         printf("L%d ", iptr->s1.varindex);                           \
+    }                                                                \
+    else {                                                           \
+        printf("JavaL%d ", iptr->s1.varindex);                       \
     }
 
 #define SHOW_DST_LOCAL(iptr)                                         \
     if (stage >= SHOW_STACK) {                                       \
         printf("=> L%d ", iptr->dst.varindex);                       \
+    }                                                                \
+    else {                                                           \
+        printf("=> JavaL%d ", iptr->dst.varindex);                   \
     }
 
-static void show_variable(jitdata *jd, s4 index, int stage)
+void show_allocation(s4 type, s4 flags, s4 regoff)
 {
-       char type;
-       char kind;
-       varinfo *v;
-
-       v = &(jd->var[index]);
-
-       switch (v->type) {
-               case TYPE_INT: type = 'i'; break;
-               case TYPE_LNG: type = 'l'; break;
-               case TYPE_FLT: type = 'f'; break;
-               case TYPE_DBL: type = 'd'; break;
-               case TYPE_ADR: type = 'a'; break;
-               default:       type = '?';
+       if (type == TYPE_RET) {
+               printf("N/A");
+               return;
        }
 
-       if (v->flags & PREALLOC)
-               kind = 'A';
-       else if (v->flags & OUTVAR)
-               kind = 'I';
-       else if (index < jd->localcount)
-               kind = 'L';
-       else
-               kind = 'T';
-
-       printf("%c%c%d", kind, type, index);
-
-       if (stage >= SHOW_REGS) {
-               putchar('(');
+       if (flags & INMEMORY) {
+               printf("M%02d", regoff);
+               return;
+       }
 
-               if (v->flags & INMEMORY)
-                       printf("M%02d", v->regoff);
 #ifdef HAS_ADDRESS_REGISTER_FILE
-               else if (v->type == TYPE_ADR)
-                       printf("R%02d", v->regoff);
+       if (type == TYPE_ADR) {
+               printf("R%02d", regoff);
+               return;
+       }
 #endif
-               else if (IS_FLT_DBL_TYPE(v->type))
-                       printf("F%02d", v->regoff);
-               else {
+
+       if (IS_FLT_DBL_TYPE(type)) {
+               printf("F%02d", regoff);
+               return;
+       }
+
 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                       if (IS_2_WORD_TYPE(v->type)) {
+       if (IS_2_WORD_TYPE(type)) {
 # if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
 #  if defined(ENABLE_INTRP)
-                               if (opt_intrp)
-                                       printf("%3d/%3d", GET_LOW_REG(v->regoff),
-                                                  GET_HIGH_REG(v->regoff));
-                               else
+               if (opt_intrp)
+                       printf("%3d/%3d", GET_LOW_REG(regoff),
+                                       GET_HIGH_REG(regoff));
+               else
 #  endif
-                                       printf("%3s/%3s", regs[GET_LOW_REG(v->regoff)],
-                                                  regs[GET_HIGH_REG(v->regoff)]);
+                       printf("%3s/%3s", abi_registers_integer_name[GET_LOW_REG(regoff)],
+                                  abi_registers_integer_name[GET_HIGH_REG(regoff)]);
 # else
-                               printf("%3d/%3d", GET_LOW_REG(v->regoff),
-                                          GET_HIGH_REG(v->regoff));
+               printf("%3d/%3d", GET_LOW_REG(regoff),
+                          GET_HIGH_REG(regoff));
 # endif
-                       } 
-                       else 
+               return;
+       } 
 #endif /* defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
-                               {
+
 #if defined(ENABLE_JIT) && defined(ENABLE_DISASSEMBLER)
 # if defined(ENABLE_INTRP)
-                                       if (opt_intrp)
-                                               printf("%3d", v->regoff);
-                                       else
+       if (opt_intrp)
+               printf("%3d", regoff);
+       else
 # endif
-                                               printf("%3s", regs[v->regoff]);
+               printf("%3s", abi_registers_integer_name[regoff]);
 #else
-                                       printf("%3d", v->regoff);
+       printf("%3d", regoff);
 #endif
-                               }
+}
+
+void show_variable(jitdata *jd, s4 index, int stage)
+{
+       show_variable_intern(jd, index, stage);
+       putchar(' ');
+}
+
+static void show_variable_intern(jitdata *jd, s4 index, int stage)
+{
+       char type;
+       char kind;
+       varinfo *v;
+
+       if (index < 0 || index >= jd->vartop) {
+               printf("<INVALID INDEX:%d>", index);
+               return;
+       }
+
+       v = VAR(index);
+
+       switch (v->type) {
+               case TYPE_INT: type = 'i'; break;
+               case TYPE_LNG: type = 'l'; break;
+               case TYPE_FLT: type = 'f'; break;
+               case TYPE_DBL: type = 'd'; break;
+               case TYPE_ADR: type = 'a'; break;
+               case TYPE_RET: type = 'r'; break;
+               default:       type = '?';
+       }
+
+       if (index < jd->localcount) {
+               kind = 'L';
+               if (v->flags & (PREALLOC | INOUT))
+                               printf("<INVALID FLAGS!>");
+       }
+       else {
+               if (v->flags & PREALLOC) {
+                       kind = 'A';
+                       if (v->flags & INOUT) {
+                               /* PREALLOC is used to avoid allocation of TYPE_RET */
+                               if (v->type == TYPE_RET)
+                                       kind = 'i';
+                               else
+                                       printf("<INVALID FLAGS!>");
+                       }
                }
+               else if (v->flags & INOUT)
+                       kind = 'I';
+               else
+                       kind = 'T';
+       }
 
+       printf("%c%c%d", kind, type, index);
 
+       if (v->flags & SAVEDVAR)
+               putchar('!');
+
+       if (stage >= SHOW_REGS || (v->flags & PREALLOC)) {
+               putchar('(');
+               show_allocation(v->type, v->flags, v->vv.regoff);
                putchar(')');
        }
-       putchar(' ');
-       fflush(stdout);
+
+       if (v->type == TYPE_RET && (v->flags & PREALLOC)) {
+               printf("(L%03d)", v->vv.retaddr->nr);
+       }
 }
 
-static void new_show_variable_array(jitdata *jd, s4 *vars, int n, int stage)
+static void show_variable_array_intern(jitdata *jd, s4 *vars, int n, int stage,
+                                                                          bool javalocals)
 {
        int i;
+       int nr;
+
+       if (vars == NULL) {
+               printf("<null>");
+               return;
+       }
 
        printf("[");
        for (i=0; i<n; ++i) {
                if (i)
-                       printf(" ");
-               show_variable(jd, vars[i], stage);
+                       putchar(' ');
+               if (vars[i] < 0) {
+                       if (vars[i] == UNUSED)
+                               putchar('-');
+                       else if (javalocals) {
+                               nr = RETADDR_FROM_JAVALOCAL(vars[i]);
+                               printf("ret(L%03d)", nr);
+                       }
+                       else {
+                               printf("<INVALID INDEX:%d>", vars[i]);
+                       }
+               }
+               else
+                       show_variable_intern(jd, vars[i], stage);
        }
        printf("]");
 }
 
-void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
+void show_variable_array(jitdata *jd, s4 *vars, int n, int stage)
+{
+       show_variable_array_intern(jd, vars, n, stage, false);
+}
+
+void show_javalocals_array(jitdata *jd, s4 *vars, int n, int stage)
+{
+       show_variable_array_intern(jd, vars, n, stage, true);
+}
+
+void show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
 {
        u2                 opcode;
        branch_target_t   *table;
        lookup_target_t   *lookup;
        constant_FMIref   *fmiref;
-       s4          *argp;
+       s4                *argp;
        s4                 i;
 
        /* get the opcode and the condition */
 
        opcode    =  iptr->opc;
 
-       printf("%s ", icmd_names[opcode]);
+       printf("%s ", icmd_table[opcode].name);
 
        if (stage < SHOW_PARSE)
                return;
@@ -675,7 +958,6 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
 
        case ICMD_POP:
        case ICMD_CHECKNULL:
-       case ICMD_CHECKNULL_POP:
                SHOW_S1(iptr);
                break;
 
@@ -795,7 +1077,7 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
        case ICMD_LORCONST:
        case ICMD_LXORCONST:
                SHOW_S1(iptr);
-               SHOW_LNG_CONST(iptr->sx.val.l); 
+               SHOW_LNG_CONST(iptr->sx.val.l);
                SHOW_DST(iptr);
                break;
 
@@ -803,7 +1085,7 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
        case ICMD_LASTORECONST:
                SHOW_S1(iptr);
                SHOW_S2(iptr);
-               SHOW_LNG_CONST(iptr->sx.s23.s3.constval);
+               SHOW_ADR_CONST(iptr->sx.s23.s3.constval);
                break;
 
                /* const LNG */
@@ -827,12 +1109,14 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
                /* const ADR */
        case ICMD_ACONST:
                if (iptr->flags.bits & INS_FLAG_CLASS) {
+                       SHOW_ADR_CONST(iptr->sx.val.anyptr);
                        SHOW_CLASSREF_OR_CLASSINFO(iptr->sx.val.c);
                }
                else if (iptr->sx.val.anyptr == NULL) {
                        printf("NULL ");
                }
                else {
+                       SHOW_ADR_CONST(iptr->sx.val.anyptr);
                        SHOW_STRING(iptr->sx.val.stringconst);
                }
                SHOW_DST(iptr);
@@ -898,6 +1182,9 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
 
        case ICMD_RET:
                SHOW_S1_LOCAL(iptr);
+               if (stage >= SHOW_STACK) {
+                       printf(" ---> L%03d", iptr->dst.block->nr);
+               }
                break;
 
        case ICMD_ILOAD:
@@ -916,6 +1203,11 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
        case ICMD_ASTORE:
                SHOW_S1(iptr);
                SHOW_DST_LOCAL(iptr);
+               if (stage >= SHOW_STACK && iptr->sx.s23.s3.javaindex != UNUSED)
+                       printf(" (javaindex %d)", iptr->sx.s23.s3.javaindex);
+               if (iptr->flags.bits & INS_FLAG_RETADDR) {
+                       printf(" (retaddr L%03d)", RETADDR_FROM_JAVALOCAL(iptr->sx.s23.s2.retaddrnr));
+               }
                break;
 
        case ICMD_NEW:
@@ -946,6 +1238,8 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
 
        case ICMD_CHECKCAST:
                SHOW_S1(iptr);
+               putchar(' ');
+               class_classref_or_classinfo_print(iptr->sx.s23.s3.c);
                SHOW_DST(iptr);
                break;
 
@@ -956,6 +1250,13 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
 
        case ICMD_INLINE_START:
        case ICMD_INLINE_END:
+       case ICMD_INLINE_BODY:
+#if defined(ENABLE_INLINING)
+               {
+                       insinfo_inline *ii = iptr->sx.s23.s3.inlineinfo;
+                       show_inline_info(jd, ii, opcode, stage);
+               }
+#endif
                break;
 
        case ICMD_BUILTIN:
@@ -1004,6 +1305,7 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
        case ICMD_IFGT:
        case ICMD_IFLE:
                SHOW_S1(iptr);
+               SHOW_INT_CONST(iptr->sx.val.i); 
                SHOW_TARGET(iptr->dst);
                break;
 
@@ -1014,11 +1316,11 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
        case ICMD_IF_LGT:
        case ICMD_IF_LLE:
                SHOW_S1(iptr);
+               SHOW_LNG_CONST(iptr->sx.val.l); 
                SHOW_TARGET(iptr->dst);
                break;
 
        case ICMD_GOTO:
-       case ICMD_INLINE_GOTO:
                SHOW_TARGET(iptr->dst);
                break;
 
@@ -1084,18 +1386,12 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
                SHOW_S1(iptr);
                table = iptr->dst.table;
 
-               i = iptr->sx.s23.s3.tablehigh
-                       - iptr->sx.s23.s2.tablelow + 1;
+               i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1;
 
                printf("high=%d low=%d count=%d\n", iptr->sx.s23.s3.tablehigh, iptr->sx.s23.s2.tablelow, i);
                while (--i >= 0) {
-                       printf("\t\t%d --> ", table - iptr->dst.table);
-                       if (stage >= SHOW_STACK) {
-                               printf("L%03d\n", table->block->nr);
-                       }
-                       else {
-                               printf("insindex %d (L%03d)\n", table->insindex, BLOCK_OF(table->insindex)->nr);
-                       }
+                       printf("\t\t%d --> ", (int) (table - iptr->dst.table));
+                       printf("L%03d\n", table->block->nr);
                        table++;
                }
 
@@ -1104,121 +1400,264 @@ void new_show_icmd(jitdata *jd, instruction *iptr, bool deadcode, int stage)
        case ICMD_LOOKUPSWITCH:
                SHOW_S1(iptr);
 
-               printf("count=%d, default=", iptr->sx.s23.s2.lookupcount);
-               if (stage >= SHOW_STACK) {
-                       printf("L%03d\n", iptr->sx.s23.s3.lookupdefault.block->nr);
-               }
-               else {
-                       printf("insindex %d (L%03d)\n", iptr->sx.s23.s3.lookupdefault.insindex, BLOCK_OF(iptr->sx.s23.s3.lookupdefault.insindex)->nr);
-               }
+               printf("count=%d, default=L%03d\n",
+                          iptr->sx.s23.s2.lookupcount,
+                          iptr->sx.s23.s3.lookupdefault.block->nr);
 
                lookup = iptr->dst.lookup;
                i = iptr->sx.s23.s2.lookupcount;
+
                while (--i >= 0) {
-                       printf("\t\t%d --> ", lookup->value);
-                       if (stage >= SHOW_STACK) {
-                               printf("L%03d\n", lookup->target.block->nr);
-                       }
-                       else {
-                               printf("insindex %d (L%03d)\n", lookup->target.insindex, BLOCK_OF(lookup->target.insindex)->nr);
-                       }
+                       printf("\t\t%d --> L%03d\n",
+                                  lookup->value,
+                                  lookup->target.block->nr);
                        lookup++;
                }
                break;
 
-       case ICMD_ARETURN:
+       case ICMD_FRETURN:
+       case ICMD_IRETURN:
+       case ICMD_DRETURN:
+       case ICMD_LRETURN:
                SHOW_S1(iptr);
                break;
 
+       case ICMD_ARETURN:
        case ICMD_ATHROW:
                SHOW_S1(iptr);
+               if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+                       /* XXX this needs more work */
+#if 0
+                       unresolved_class_debug_dump(iptr->sx.s23.s2.uc, stdout);
+#endif
+               }
                break;
 
-       case ICMD_DUP:
        case ICMD_COPY:
        case ICMD_MOVE:
                SHOW_S1(iptr);
                SHOW_DST(iptr);
                break;
+       }
+       fflush(stdout);
+}
+#endif /* !defined(NDEBUG) */
 
-       case ICMD_DUP2:
-               if (stage >= SHOW_STACK) {
-                       SHOW_VARIABLE(iptr->dst.dupslots[0]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[1]);
-                       printf("=> ");
-                       SHOW_VARIABLE(iptr->dst.dupslots[2+0]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[2+1]);
-               }
-               break;
+/* Debug output filtering */
 
-       case ICMD_DUP_X1:
-               if (stage >= SHOW_STACK) {
-                       SHOW_VARIABLE(iptr->dst.dupslots[0]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[1]);
-                       printf("=> ");
-                       SHOW_VARIABLE(iptr->dst.dupslots[2+0]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[2+1]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[2+2]);
-               }
-               break;
+#if defined(ENABLE_DEBUG_FILTER)
 
-       case ICMD_DUP2_X1:
-               if (stage >= SHOW_STACK) {
-                       SHOW_VARIABLE(iptr->dst.dupslots[0]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[1]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[2]);
-                       printf("=> ");
-                       SHOW_VARIABLE(iptr->dst.dupslots[3+0]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[3+1]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[3+2]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[3+3]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[3+4]);
-               }
-               break;
+#if !defined(ENABLE_THREADS)
+u2 _no_threads_filterverbosecallctr[2] = { 0, 0 };
+#endif
 
-       case ICMD_DUP_X2:
-               if (stage >= SHOW_STACK) {
-                       SHOW_VARIABLE(iptr->dst.dupslots[0]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[1]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[2]);
-                       printf("=> ");
-                       SHOW_VARIABLE(iptr->dst.dupslots[3+0]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[3+1]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[3+2]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[3+3]);
+struct show_filter {
+       /* Boolean indicating if filter is enabled. */
+       u1 enabled;
+       /* Regular expression the method name is matched against */
+       regex_t regex;
+       /* Flag set on m->filtermatches if regex matches */
+       u1 flag;
+};
+
+typedef struct show_filter show_filter_t;
+
+#define SHOW_FILTERS_SIZE 3
+
+/* Array of filters applyed on a method */
+static struct show_filter show_filters[SHOW_FILTERS_SIZE];
+
+static void show_filter_init(show_filter_t *cf, const char *str, u1 flag, u1 default_flag, const char *description) {
+       int err;
+       char err_buf[128];
+
+       if (str) {
+               err = regcomp(&cf->regex, str, REG_EXTENDED | REG_NOSUB);
+               if (err != 0) {
+                       regerror(err, &cf->regex, err_buf, sizeof(err_buf));
+                       vm_abort(
+                               "Invalid value given for %s: `%s' (%s).", 
+                               description, str, err_buf
+                       );
                }
-               break;
+               cf->flag = flag;
+               cf->enabled = 1;
+       } else {
+               cf->flag = default_flag;
+               cf->enabled = 0;
+       }
+}
 
-       case ICMD_DUP2_X2:
-               if (stage >= SHOW_STACK) {
-                       SHOW_VARIABLE(iptr->dst.dupslots[0]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[1]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[2]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[4]);
-                       printf("=> ");
-                       SHOW_VARIABLE(iptr->dst.dupslots[4+0]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[4+1]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[4+2]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[4+3]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[4+4]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[4+5]);
+void show_filters_init(void) {
+
+       show_filter_init(
+               show_filters + 0,
+               opt_filter_verbosecall_include,
+               SHOW_FILTER_FLAG_VERBOSECALL_INCLUDE,
+               SHOW_FILTER_FLAG_VERBOSECALL_INCLUDE,
+               "verbose call include filter"
+       );
+
+       show_filter_init(
+               show_filters + 1,
+               opt_filter_verbosecall_exclude,
+               SHOW_FILTER_FLAG_VERBOSECALL_EXCLUDE,
+               0,
+               "verbose call exclude filter"
+       );
+
+       show_filter_init(
+               show_filters + 2,
+               opt_filter_show_method,
+               SHOW_FILTER_FLAG_SHOW_METHOD,
+               SHOW_FILTER_FLAG_SHOW_METHOD,
+               "show method filter"
+       );
+}
+
+/*
+ (Pseudo)State machine:
+
+ States are INITIAL, INCLUDE1, INCLUDE2, ..., EXCLUDE1, ..., EXCLUDE2, ...
+
+                                                        Enter              Enter
+ Enter                                                  Include            Include
+ Exclude                                                  | |                | |
+  | |    Enter              Enter              Enter      | |     Enter      | |
+  | |    Include            Include            Exclude    | |     Exclude    | |
+  | v   --------->        ---------->        ---------->  | v   ---------->  | v
+INITIAL           INCLUDE1           INCLUDE2           EXCLUDE1           EXCLUDE2
+  | ^   <---------        <----------        <----------  | ^   <----------  | ^
+  | |    Exit               Exit               Exit       | |     Exit       | |
+  | |    Include            Include            Exclude    | |     Exclude    | |
+  | |                                                     | |                | |
+ Exit                                                    Exit               Exit
+ Exclude                                                 Include            Include
+
+  Verbose call scope is active if we are in a INCLUDE state.
+
+  State encoding:
+
+  INITIAL: ctr[0] == 0, ctr[1] == 0
+  INCLUDEN: ctr[1] == N, ctr[1] == 0
+  EXCLUDEN: ctr[1] == N
+*/
+
+void show_filters_apply(methodinfo *m) {
+       int i;
+       int res;
+       char *method_name;
+       s4 len;
+       s4 dumpsize;
+
+       /* compose full name of method */
+
+       len = 
+               utf_bytes(m->class->name) +
+               1 +
+               utf_bytes(m->name) +
+               utf_bytes(m->descriptor) +
+               1;
+
+       dumpsize = dump_size(); /* allocate memory */
+
+       method_name = DMNEW(char, len);
+
+       utf_cat_classname(method_name, m->class->name);
+       strcat(method_name, ".");
+       utf_cat(method_name, m->name);
+       utf_cat(method_name, m->descriptor);
+
+       /* reset all flags */
+
+       m->filtermatches = 0;
+
+       for (i = 0; i < SHOW_FILTERS_SIZE; ++i) {
+               if (show_filters[i].enabled) {
+
+                       res = regexec(&show_filters[i].regex, method_name, 0, NULL, 0);
+
+                       if (res == 0) {
+                               m->filtermatches |= show_filters[i].flag;
+                       }
+               } else {
+                       /* Default is to show all */
+                       m->filtermatches |= show_filters[i].flag;
                }
-               break;
+       }
 
-       case ICMD_SWAP:
-               if (stage >= SHOW_STACK) {
-                       SHOW_VARIABLE(iptr->dst.dupslots[0]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[1]);
-                       printf("=> ");
-                       SHOW_VARIABLE(iptr->dst.dupslots[2+0]);
-                       SHOW_VARIABLE(iptr->dst.dupslots[2+1]);
+       /* release memory */
+
+       dump_release(dumpsize); 
+
+}
+
+#define STATE_IS_INITIAL() ((FILTERVERBOSECALLCTR[0] == 0) && (FILTERVERBOSECALLCTR[1] == 0))
+#define STATE_IS_INCLUDE() ((FILTERVERBOSECALLCTR[0] > 0) && (FILTERVERBOSECALLCTR[1] == 0))
+#define STATE_IS_EXCLUDE() (FILTERVERBOSECALLCTR[1] > 0)
+#define EVENT_INCLUDE() (m->filtermatches & SHOW_FILTER_FLAG_VERBOSECALL_INCLUDE)
+#define EVENT_EXCLUDE() (m->filtermatches & SHOW_FILTER_FLAG_VERBOSECALL_EXCLUDE)
+#define TRANSITION_NEXT_INCLUDE() ++FILTERVERBOSECALLCTR[0]
+#define TRANSITION_PREV_INCLUDE() --FILTERVERBOSECALLCTR[0]
+#define TRANSITION_NEXT_EXCLUDE() ++FILTERVERBOSECALLCTR[1]
+#define TRANSITION_PREV_EXCLUDE() --FILTERVERBOSECALLCTR[1]
+
+#if 0
+void dump_state() {
+       if (STATE_IS_INITIAL()) printf("<INITIAL>\n");
+       else if (STATE_IS_INCLUDE()) printf("<INCLUDE %hd>\n", FILTERVERBOSECALLCTR[0]);
+       else if (STATE_IS_EXCLUDE()) printf("<EXCLUDE %hd>\n", FILTERVERBOSECALLCTR[1]);
+}
+#endif
+
+int show_filters_test_verbosecall_enter(methodinfo *m) {
+
+       int force_show = 0;
+
+       if (STATE_IS_INITIAL()) {
+               if (EVENT_INCLUDE()) {
+                       TRANSITION_NEXT_INCLUDE();
                }
-               break;
+       } else if (STATE_IS_INCLUDE()) {
+               if (EVENT_EXCLUDE()) {
+                       TRANSITION_NEXT_EXCLUDE();
+                       /* just entered exclude, show this method */
+                       force_show = 1;
+               } else if (EVENT_INCLUDE()) {
+                       TRANSITION_NEXT_INCLUDE();
+               }
+       } else if (STATE_IS_EXCLUDE()) {
+               if (EVENT_EXCLUDE()) {
+                       TRANSITION_NEXT_EXCLUDE();
+               }
+       }
+
+       return STATE_IS_INCLUDE() || force_show;
+}
+
+int show_filters_test_verbosecall_exit(methodinfo *m) {
 
+       int force_show = 0;
+
+       if (m) {
+               if (STATE_IS_INCLUDE()) {
+                       if (EVENT_INCLUDE()) {
+                               TRANSITION_PREV_INCLUDE();
+                               /* just entered initial, show this method */
+                               if (STATE_IS_INITIAL()) force_show = 1;
+                       }
+           } else if (STATE_IS_EXCLUDE()) {
+                       if (EVENT_EXCLUDE()) {
+                               TRANSITION_PREV_EXCLUDE();
+                       }
+               }
        }
-       fflush(stdout);
+
+       return STATE_IS_INCLUDE() || force_show;
 }
-#endif /* !defined(NDEBUG) */
+
+#endif
 
 
 /*