/* 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 show_allocation(s4 type, s4 flags, s4 regoff);
+static void show_variable_intern(jitdata *jd, s4 index, int stage);
#endif
#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);
+ LOCK_INIT_OBJECT_LOCK(show_global_lock);
+#endif
+
+#if defined(ENABLE_DEBUG_FILTER)
+ show_filters_init();
#endif
/* everything's ok */
s4 i, j;
int irstage;
#if defined(ENABLE_DISASSEMBLER)
- u1 *u1ptr;
+ u1 *pc;
#endif
/* get required compiler data */
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", m->maxlocals);
+ 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("\n");
}
- if (cd->maxlocals > 0 && jd->local_map != NULL) {
+ 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 ",show_jit_type_names[i]);
- for (j = 0; j < cd->maxlocals; j++) {
+ for (j = 0; j < jd->maxlocals; j++) {
if (jd->local_map[j*5+i] == UNUSED)
printf(" -- ");
else
#else
printf(" M%02d = 0x%02x(sp): ", i, i * 8);
#endif
- for (j = 0; j < jd->varcount; ++j) {
+ for (j = 0; j < jd->vartop; ++j) {
varinfo *v = VAR(j);
if ((v->flags & INMEMORY) && (v->vv.regoff == i)) {
show_variable(jd, j, irstage);
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->basicblocks[0].mpc);)
- DISASSINSTR(u1ptr);
+ for (; pc < (u1 *) ((ptrint) code->mcode + cd->dseglen + jd->basicblocks[0].mpc);)
+ DISASSINSTR(pc);
printf("\n");
}
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");
}
#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.
instruction *iptr;
int irstage;
#if defined(ENABLE_DISASSEMBLER)
- u1 *u1ptr;
+ methodinfo *m; /* this is only a dummy */
+ u1 *pc;
+ s4 linenumber;
+ s4 currentlinenumber;
#endif
/* get required compiler data */
}
printf("======== %sL%03d ======== %s(flags: %d, bitflags: %01x, next: %d, type: ",
- (bptr->bitflags & BBFLAG_REPLACEMENT) ? "<REPLACE> " : "",
+#if defined(ENABLE_REPLACEMENT)
+ (bptr->bitflags & BBFLAG_REPLACEMENT) ? "<REPLACE> " :
+#endif
+ "",
bptr->nr,
(deadcode && stage >= SHOW_STACK) ? "DEADCODE! " : "",
bptr->flags, bptr->bitflags,
printf("IN: ");
show_variable_array(jd, bptr->invars, bptr->indepth, irstage);
printf(" javalocals: ");
- show_variable_array(jd, bptr->javalocals, jd->m->maxlocals, irstage);
+ 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);
show_icmd(jd, iptr, deadcode, irstage);
printf("\n");
(!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");
}
#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->basicblocks[jd->basicblockindex[ \
- (target).insindex]].nr); \
- } \
else { \
printf("--> insindex %d ", (target).insindex); \
}
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 { \
printf("=> JavaL%d ", iptr->dst.varindex); \
}
-static void show_allocation(s4 type, s4 flags, s4 regoff)
+void show_allocation(s4 type, s4 flags, s4 regoff)
{
+ if (type == TYPE_RET) {
+ printf("N/A");
+ return;
+ }
+
if (flags & INMEMORY) {
printf("M%02d", regoff);
return;
GET_HIGH_REG(regoff));
else
# endif
- printf("%3s/%3s", regs[GET_LOW_REG(regoff)],
- regs[GET_HIGH_REG(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(regoff),
- GET_HIGH_REG(regoff));
+ GET_HIGH_REG(regoff));
# endif
return;
}
printf("%3d", regoff);
else
# endif
- printf("%3s", regs[regoff]);
+ printf("%3s", abi_registers_integer_name[regoff]);
#else
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->varcount) {
+ if (index < 0 || index >= jd->vartop) {
printf("<INVALID INDEX:%d>", index);
return;
}
else {
if (v->flags & PREALLOC) {
kind = 'A';
- if (v->flags & INOUT)
- printf("<INVALID FLAGS!>");
+ 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';
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);
+ }
}
-void 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>");
printf("[");
for (i=0; i<n; ++i) {
if (i)
- printf(" ");
- if (vars[i] == UNUSED)
- putchar('-');
+ 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(jd, vars[i], stage);
+ show_variable_intern(jd, vars[i], stage);
}
printf("]");
}
+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;
case ICMD_POP:
case ICMD_CHECKNULL:
- case ICMD_CHECKNULL_POP:
SHOW_S1(iptr);
break;
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:
case ICMD_INLINE_START:
case ICMD_INLINE_END:
+ case ICMD_INLINE_BODY:
#if defined(ENABLE_INLINING)
{
insinfo_inline *ii = iptr->sx.s23.s3.inlineinfo;
- printf("(");
- method_print(ii->outer);
- printf(" ==> ");
- method_print(ii->method);
- printf(")");
+ show_inline_info(jd, ii, opcode, stage);
}
#endif
break;
break;
case ICMD_GOTO:
- case ICMD_INLINE_GOTO:
SHOW_TARGET(iptr->dst);
break;
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 --> ", (int) (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("L%03d\n", table->block->nr);
table++;
}
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:
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_COPY:
}
#endif /* !defined(NDEBUG) */
+/* Debug output filtering */
+
+#if defined(ENABLE_DEBUG_FILTER)
+
+#if !defined(ENABLE_THREADS)
+u2 _no_threads_filterverbosecallctr[2] = { 0, 0 };
+#endif
+
+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
+ );
+ }
+ cf->flag = flag;
+ cf->enabled = 1;
+ } else {
+ cf->flag = default_flag;
+ cf->enabled = 0;
+ }
+}
+
+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;
+ }
+ }
+
+ /* 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();
+ }
+ } 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();
+ }
+ }
+ }
+
+ return STATE_IS_INCLUDE() || force_show;
+}
+
+#endif
+
/*
* These are local overrides for various environment variables in Emacs.