* src/vm/jit/show.c: Likewise.
* src/vm/jit/jit.c (jit_compile_intern): Honour filters.
* src/vm/jit/codegen-common.c (codegen_add_patch_ref, codegen_generate_stub_native): Honour PATCHER_LONGBRANCHES_NOPS if defined, honour filters.
* src/vm/builtin.c (builtin_trace_exception, builtin_verbosecall_enter, builtin_verbosecall_exit): Honour filters.
* src/vm/signal.c (signal_init): Register SIGILL handler on s390.
* src/vm/vm.c: Handle -XXfi, -XXfe, -XXfm commandline options.
* src/vm/signallocal.h (md_signal_handler_sigill): Forward declare on s390.
* src/threads/none/threads.h (_no_threads_filterverbosecallctr, FILTERVERBOSECALLCTR): Added.
* src/threads/native/threads.h (struct threadobject): Added filterverbosecallctr.
* src/threads/native/threads.c (threads_impl_thread_new): Initialize filterverbosecallctr.
* src/threads/critical.c (critical_comparator): On s390, clear bit 32 of pointer when comparing.
* src/vmcore/options.h (opt_filter_verbosecall_include, opt_filter_verbosecall_exclude, opt_filter_show_method): Added.
* src/vmcore/options.c: Likewise.
* src/vmcore/method.h (struct methodinfo): Added filtermatches.
* configure.ac: If no NDEBUG and regex.h header is present, define ENABLE_DEBUG_FILTER.
* src/vm/jit/s390/emit.c,
src/vm/jit/s390/md.c,
src/vm/jit/s390/codegen.c,
src/vm/jit/s390/codegen.h,
src/vm/jit/s390/tests/dacapo.status,
src/vm/jit/s390/patcher.c: Changed a lot.
dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
dnl 02110-1301, USA.
dnl
-dnl $Id: configure.ac 7960 2007-05-23 22:04:49Z twisti $
+dnl $Id: configure.ac 7966 2007-05-25 12:41:03Z pm $
dnl Process this file with autoconf to produce a configure script.
AC_PROG_JAVAC
AC_PROG_JAR
+dnl If debug build, check for regex.h. If found enable debug filter
+if test x"${NDEBUG}" = "xno"; then
+ AC_CHECK_HEADERS([regex.h], [AC_DEFINE(ENABLE_DEBUG_FILTER, 1, [debug filter])])
+fi
dnl finally pass CFLAGS to Makefiles via AM_CFLAGS
CFLAGS=$OPT_CFLAGS
treecsn = treenode;
csn = node;
+#ifdef __S390__
+# define ADDR_MASK(x) ((u1 *)((s4)(x) & 0x7FFFFFFF))
+#else
+# define ADDR_MASK(x) (x)
+#endif
+
/* compare for avl_find if we have found an entry */
- if ((treecsn->start <= csn->start) && (csn->start < treecsn->end))
+ if (
+ (ADDR_MASK(treecsn->start) <= ADDR_MASK(csn->start)) &&
+ (ADDR_MASK(csn->start) < ADDR_MASK(treecsn->end))
+ )
return 0;
/* these are for walking the tree */
- if (treecsn->start < csn->start)
+ if (ADDR_MASK(treecsn->start) < ADDR_MASK(csn->start))
return -1;
else
return 1;
+
+#undef ADDR_MASK
}
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: threads.c 7963 2007-05-24 10:21:16Z twisti $
+ $Id: threads.c 7966 2007-05-25 12:41:03Z pm $
*/
pthread_mutex_init(&(t->waitmutex), NULL);
pthread_cond_init(&(t->waitcond), NULL);
+
+#if defined(ENABLE_DEBUG_FILTER)
+ /* Initialize filter counters */
+ t->filterverbosecallctr[0] = 0;
+ t->filterverbosecallctr[1] = 0;
+#endif
}
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: threads.h 7963 2007-05-24 10:21:16Z twisti $
+ $Id: threads.h 7966 2007-05-25 12:41:03Z pm $
*/
#endif
dumpinfo_t dumpinfo; /* dump memory info structure */
+
+#if defined(ENABLE_DEBUG_FILTER)
+ u2 filterverbosecallctr[2]; /* counters for verbose call filter */
+#endif
+
listnode_t linkage; /* threads-list */
};
#define STACKFRAMEINFO (THREADOBJECT->_stackframeinfo)
+/* counter for verbose call filter ********************************************/
+
+#if defined(ENABLE_DEBUG_FILTER)
+# define FILTERVERBOSECALLCTR (THREADOBJECT->filterverbosecallctr)
+#endif
/* functions ******************************************************************/
#define STACKFRAMEINFO (_no_threads_stackframeinfo)
+#if defined(ENABLE_DEBUG_FILTER)
+extern u2 _no_threads_filterverbosecallctr[2];
+#define FILTERVERBOSECALLCTR (_no_threads_filterverbosecallctr)
+#endif
+
#endif /* _THREADS_H */
calls instead of machine instructions, using the C calling
convention.
- $Id: builtin.c 7907 2007-05-15 09:25:27Z tbfg $
+ $Id: builtin.c 7966 2007-05-25 12:41:03Z pm $
*/
#include <vmlog_cacao.h>
#endif
+#if defined(ENABLE_DEBUG_FILTER)
+# include "vm/jit/show.h"
+#endif
/* include builtin tables *****************************************************/
s4 dumpsize;
codeinfo *code;
+#if defined(ENABLE_DEBUG_FILTER)
+ if (! show_filters_test_verbosecall_exit(m)) return xptr;
+#endif
+
#if defined(ENABLE_VMLOG)
return xptr;
#endif
}
#endif /* !defined(NDEBUG) */
-
/* builtin_verbosecall_enter ***************************************************
Print method call with arguments for -verbose:call.
s4 i;
s4 pos;
+#if defined(ENABLE_DEBUG_FILTER)
+ if (! show_filters_test_verbosecall_enter(m)) return;
+#endif
+
#if defined(ENABLE_VMLOG)
vmlog_cacao_enter_method(m);
return;
dump_release(dumpsize);
methodindent++;
+
}
#endif
#endif /* !defined(NDEBUG) */
s4 pos;
imm_union val;
+#if defined(ENABLE_DEBUG_FILTER)
+ if (! show_filters_test_verbosecall_exit(m)) return;
+#endif
+
#if defined(ENABLE_VMLOG)
vmlog_cacao_leave_method(m);
return;
/* release memory */
dump_release(dumpsize);
+
}
#endif /* !defined(NDEBUG) */
memory. All functions writing values into the data area return the offset
relative the begin of the code area (start of procedure).
- $Id: codegen-common.c 7939 2007-05-23 09:40:05Z tbfg $
+ $Id: codegen-common.c 7966 2007-05-25 12:41:03Z pm $
*/
#include <vmlog_cacao.h>
#endif
+#include "show.h"
/* in this tree we store all method addresses *********************************/
avl_insert(methodtree, mte);
#endif /* defined(ENABLE_JIT) */
+
}
+
}
if (opt_shownops)
PATCHER_NOPS;
+ /* If the codegen provides a PACHER_LONGBRANCHES_NOPS macro, honour it. */
+
+#if defined(PATCHER_LONGBRANCHES_NOPS)
+ if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
+ PATCHER_LONGBRANCHES_NOPS;
+ }
+#endif
+
#if defined(ENABLE_JIT) && (defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__))
+
/* On some architectures the patcher stub call instruction might
be longer than the actual instruction generated. On this
architectures we store the last patcher call position and after
/* disassemble native stub */
if (opt_shownativestub) {
+#if defined(ENABLE_DEBUG_FILTER)
+ if (m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
+#endif
+ {
#if defined(ENABLE_DISASSEMBLER)
- codegen_disassemble_nativestub(m,
- (u1 *) (ptrint) code->entrypoint,
- (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen));
+ codegen_disassemble_nativestub(m,
+ (u1 *) (ptrint) code->entrypoint,
+ (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen));
#endif
- /* show data segment */
+ /* show data segment */
- if (opt_showddatasegment)
- dseg_display(jd);
+ if (opt_showddatasegment)
+ dseg_display(jd);
+ }
}
#endif /* !defined(NDEBUG) */
return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
}
-
/* codegen_emit_phi_moves ****************************************************
Emits phi moves at the end of the basicblock.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: jit.c 7949 2007-05-23 17:46:27Z twisti $
+ $Id: jit.c 7966 2007-05-25 12:41:03Z pm $
*/
DEBUG_JIT_COMPILEVERBOSE("Compiling: ");
+#if defined(ENABLE_DEBUG_FILTER)
+ show_filters_apply(jd->m);
+#endif
+
/* handle native methods and create a native stub */
if (m->flags & ACC_NATIVE) {
DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
#if !defined(NDEBUG)
- /* intermediate and assembly code listings */
+#if defined(ENABLE_DEBUG_FILTER)
+ if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
+#endif
+ {
+ /* intermediate and assembly code listings */
- if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
- show_method(jd, SHOW_CODE);
- }
- else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
+ if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
+ show_method(jd, SHOW_CODE);
+ }
+ else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
# if defined(ENABLE_DISASSEMBLER)
- DISASSEMBLE(code->entrypoint,
- code->entrypoint + (code->mcodelength - cd->dseglen));
+ DISASSEMBLE(code->entrypoint,
+ code->entrypoint + (code->mcodelength - cd->dseglen));
# endif
- }
+ }
- if (opt_showddatasegment)
- dseg_display(jd);
+ if (opt_showddatasegment)
+ dseg_display(jd);
+ }
#endif
DEBUG_JIT_COMPILEVERBOSE("Compiling done: ");
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: codegen.c 7848 2007-05-01 21:40:26Z pm $
+ $Id: codegen.c 7966 2007-05-25 12:41:03Z pm $
*/
M_ILD(d, REG_ITMP1, 0);
break;
case TYPE_LNG:
- d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
M_LLD(d, REG_ITMP1, 0);
break;
case TYPE_ADR:
M_ILD(d, s1, disp);
break;
case TYPE_LNG:
- d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+ d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
if (GET_HIGH_REG(d) == s1) {
M_ILD(GET_LOW_REG(d), s1, disp + 4);
M_ILD(GET_HIGH_REG(d), s1, disp);
break;
case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
+ {
+ u1 *ref;
s1 = emit_load_s1_notzero(jd, iptr, REG_ITMP1);
emit_nullpointer_check(cd, iptr, s1);
disp = fi->offset;
}
+ /* We can't add a patcher ref behind this load,
+ * because the patcher would destroy REG_ITMP3.
+ *
+ * We pass in the disp parameter, how many bytes
+ * to skip to the to the actual store.
+ *
+ * XXX this relies on codegen_add_patch_ref internals
+ */
+
+ if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+ codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
+ ref = cd->mcodeptr;
+ }
+
+
if (IS_INT_LNG_TYPE(fieldtype)) {
if (IS_2_WORD_TYPE(fieldtype))
s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
else
s2 = emit_load_s2(jd, iptr, REG_ITMP2);
- }
- else
+ } else {
s2 = emit_load_s2(jd, iptr, REG_FTMP2);
+ }
- if (INSTRUCTION_IS_UNRESOLVED(iptr))
- codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
+ if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
+ cd->patchrefs->disp = (cd->mcodeptr - ref);
+ }
switch (fieldtype) {
- case TYPE_INT:
- M_IST(s2, s1, disp);
- break;
- case TYPE_LNG:
- /* TODO really order */
- M_IST(GET_LOW_REG(s2), s1, disp + 4); /* keep this order */
- M_IST(GET_HIGH_REG(s2), s1, disp); /* keep this order */
- break;
- case TYPE_ADR:
- M_AST(s2, s1, disp);
- break;
- case TYPE_FLT:
- M_FST(s2, s1, disp);
- break;
- case TYPE_DBL:
- M_DST(s2, s1, disp);
- break;
+ case TYPE_INT:
+ M_IST(s2, s1, disp);
+ break;
+ case TYPE_LNG:
+ M_IST(GET_LOW_REG(s2), s1, disp + 4); /* keep this order */
+ M_IST(GET_HIGH_REG(s2), s1, disp); /* keep this order */
+ break;
+ case TYPE_ADR:
+ M_AST(s2, s1, disp);
+ break;
+ case TYPE_FLT:
+ M_FST(s2, s1, disp);
+ break;
+ case TYPE_DBL:
+ M_DST(s2, s1, disp);
+ break;
+ }
+
}
break;
supervftbl = super->vftbl;
}
-#if defined(ENABLE_THREADS)
- codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+ if ((super == NULL) || !(super->flags & ACC_INTERFACE))
+ CODEGEN_CRITICAL_SECTION_NEW;
+
s1 = emit_load_s1_notzero(jd, iptr, REG_ITMP1);
/* if class is not resolved, check which code to call */
M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
M_ALD(REG_ITMP3, REG_PV, disp);
-#if defined(ENABLE_THREADS)
- codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
+ CODEGEN_CRITICAL_SECTION_START;
+
M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
M_ISUB(REG_ITMP3, REG_ITMP2);
M_ALD(REG_ITMP3, REG_PV, disp);
M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
-#if defined(ENABLE_THREADS)
- codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
+ CODEGEN_CRITICAL_SECTION_END;
+
M_CMPU(REG_ITMP2, REG_ITMP3); /* Unsigned compare */
/* M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3); itmp3 = (itmp2 <= itmp3) */
/* M_BEQZ(REG_ITMP3, 0); branch if (! itmp) -> branch if > */
# define LABEL_EXIT_INTERFACE_DONE BRANCH_LABEL_5
# define LABEL_EXIT_CLASS_NULL BRANCH_LABEL_6
-#if defined(ENABLE_THREADS)
- codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+ if ((super == NULL) || !(super->flags & ACC_INTERFACE))
+ CODEGEN_CRITICAL_SECTION_NEW;
+
s1 = emit_load_s1_notzero(jd, iptr, REG_ITMP1);
d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
if (s1 == d) {
M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
M_ALD(REG_ITMP2, REG_PV, disp);
-#if defined(ENABLE_THREADS)
- codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
+ CODEGEN_CRITICAL_SECTION_START;
+
M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
-#if defined(ENABLE_THREADS)
- codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
-#endif
+
+ CODEGEN_CRITICAL_SECTION_END;
+
M_ISUB(REG_ITMP3, REG_ITMP1); /* itmp1 := itmp1 (sub.baseval) - itmp3 (super.baseval) */
M_CMPU(REG_ITMP1, REG_ITMP2); /* d := (uint)REG_ITMP1 <= (uint)REG_ITMP2 */
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: codegen.h 7848 2007-05-01 21:40:26Z pm $
+ $Id: codegen.h 7966 2007-05-25 12:41:03Z pm $
*/
#define PATCHER_NOPS \
do { \
- M_NOP; \
- M_NOP; \
- M_NOP; \
+ /* do not generate additonal nops for long patcher branches */ \
+ if (! CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) { \
+ M_NOP; \
+ M_NOP; \
+ M_NOP; \
+ } \
} while (0)
+#define PATCHER_LONGBRANCHES_NOPS \
+ do { \
+ M_BR(SZ_BRC + (10 * 2)); \
+ M_NOP2; M_NOP2; M_NOP2; M_NOP2; M_NOP2; M_NOP2; M_NOP2; M_NOP2; /* ild */ \
+ M_NOP2; /* aadd */ \
+ M_NOP2; /* jmp */ \
+ } while (0)
+
#define PATCHER_NOPS_SKIP 12
+#define PATCHER_LONGBRANCHES_NOPS_SKIP 24
/* branch defines ************************************************************/
-#define BRANCH_NOPS M_NOP /* Size of at least M_BRC */
+#define BRANCH_NOPS \
+ do { \
+ if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) { \
+ M_NOP2; M_NOP2; /* brc */ \
+ M_NOP2; M_NOP2; M_NOP2; M_NOP2; M_NOP2; M_NOP2; M_NOP2; M_NOP2; /* ild */ \
+ M_NOP2; /* ar, bcr */ \
+ } else { \
+ M_NOP; /* brc */ \
+ } \
+ } while (0)
/* stub defines **************************************************************/
do { \
if (N_VALID_DISP(d)) { \
N_L(r, d, RN, b); \
- } else if (r == R0) { \
+ } else if ((r == R0) && N_VALID_IMM(d)) { \
N_LR(R0, R1); \
N_LHI(R1, d); \
N_L(R1, 0, R1, b); \
N_XR(R1, R0); \
N_XR(R0, R1); \
N_XR(R1, R0); \
- } else { \
+ } else if ((r != R0) && N_VALID_IMM(d)) { \
N_LHI(r, d); N_L(r, 0, r, b); \
+ } else { \
+ N_BRAS(r, SZ_BRAS + SZ_LONG); \
+ N_LONG(d); \
+ N_L(r, 0, RN, r); \
+ N_L(r, 0, r, b); \
} \
} while (0)
#define M_ALD(r, b, d) M_ILD(r, b, d)
-#define M_LDA(r, b, d) _IFNEG( \
- d, \
- N_LHI(r, d); N_LA(r, 0, r, b), \
- N_LA(r, d, RN, b) \
-)
+#define M_LDA(r, b, d) \
+ do { \
+ if (N_VALID_DISP(d)) { \
+ N_LA(r, d, RN, b); \
+ } else if (N_VALID_IMM(d)) { \
+ N_LHI(r, d); \
+ N_LA(r, 0, r, b); \
+ } else { \
+ N_BRAS(r, SZ_BRAS + SZ_LONG); \
+ N_LONG(d); \
+ N_L(r, 0, RN, r); \
+ N_LA(r, 0, r, b); \
+ } \
+ } while (0)
#define M_FLD(r, b, d) N_LE(r, d, RN, b)
#define M_BR(disp) N_BRC(DD_ANY, disp)
#define M_JMP(rs, rd) _IF(rs == RN, N_BCR(DD_ANY, rd), N_BASR(rs, rd))
#define M_NOP N_BC(0, 0, RN, RN)
+#define M_NOP2 N_BCR(0, RN)
#define M_JSR(reg_ret, reg_addr) N_BASR(reg_ret, reg_addr)
#define M_ICMP(a, b) N_CR(a, b)
#define M_ICMPU(a, b) N_CLR(a, b)
#define M_CVTFI(src, dst) N_CFEBR(dst, 5, src)
#define M_CVTDI(src, dst) N_CFDBR(dst, 5, src)
#define M_IADD(a, dest) N_AR(dest, a)
+#define M_AADD(a, dest) N_AR(dest, a)
#define M_ISUB(a, dest) N_SR(dest, a)
#define M_ASUB(a, dest) N_SR(dest, a)
#define M_IAND(a, dest) N_NR(dest, a)
#define M_AST_IMM32(a,b,c) _DEPR( M_AST_IMM32(a,b,c) )
-#define M_AADD(a,b) _DEPR( M_AADD(a,b) )
-
#define M_LADD_IMM32(a,b) _DEPR( M_LADD_IMM32(a,b) )
#define M_AADD_IMM32(a,b) _DEPR( M_AADD_IMM32(a,b) )
#define M_LSUB_IMM32(a,b) _DEPR( M_LSUB_IMM32(a,b) )
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: emit.c 7848 2007-05-01 21:40:26Z pm $
+ $Id: emit.c 7966 2007-05-25 12:41:03Z pm $
*/
u1 *tmpmcodeptr;
s4 targetdisp;
s4 disp;
+ u1 *ref;
/* get required compiler data */
cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
disp = (savedmcodeptr) - (tmpmcodeptr);
- M_BSR(REG_ITMP3, disp);
+
+ if (! N_VALID_BRANCH(disp)) {
+ /* Displacement overflow */
+
+ /* If LONGBRANCHES is not set, the flag and the error flag */
+
+ if (! CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
+ cd->flags |= (CODEGENDATA_FLAG_ERROR |
+ CODEGENDATA_FLAG_LONGBRANCHES);
+ }
+
+ /* If error flag is set, do nothing. The method has to be recompiled. */
+
+ if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd) && CODEGENDATA_HAS_FLAG_ERROR(cd)) {
+ return;
+ }
+ }
+
+ if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
+
+ /* Generating long branches */
+
+ disp = dseg_add_s4(cd, savedmcodeptr - cd->mcodebase);
+
+ M_ILD(REG_ITMP3, REG_PV, disp);
+ M_AADD(REG_PV, REG_ITMP3);
+
+ /* Do the branch at the end of NOP sequence.
+ * This way the patch position is at a *fixed* offset
+ * (PATCHER_LONGBRANCHES_NOPS_SKIP) of the return address.
+ */
+
+ cd->mcodeptr = tmpmcodeptr + PATCHER_LONGBRANCHES_NOPS_SKIP - SZ_BASR;
+ M_JMP(REG_ITMP3, REG_ITMP3);
+ } else {
+
+ /* Generating short branches */
+
+ M_BSR(REG_ITMP3, disp);
+ }
cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
disp = ((cd->mcodebase) + targetdisp) -
(( cd->mcodeptr) );
- M_BR(disp);
+ emit_branch(cd, disp, BRANCH_UNCONDITIONAL, RN, 0);
}
}
}
void emit_branch(codegendata *cd, s4 disp, s4 condition, s4 reg, u4 opt) {
s4 branchdisp = disp;
+ s4 branchmpc;
+ u1 *ref;
+
+ if (N_VALID_BRANCH(branchdisp)) {
+
+ /* valid displacement */
- switch (condition) {
- case BRANCH_EQ:
- M_BEQ(branchdisp);
- break;
- case BRANCH_NE:
- M_BNE(branchdisp);
- break;
- case BRANCH_LT:
- M_BLT(branchdisp);
- break;
- case BRANCH_GE:
- M_BGE(branchdisp);
- break;
- case BRANCH_GT:
- M_BGT(branchdisp);
- break;
- case BRANCH_LE:
- M_BLE(branchdisp);
- break;
- case BRANCH_UNCONDITIONAL:
- M_BR(branchdisp);
- break;
- default:
- vm_abort("emit_branch: unknown condition %d", condition);
+ switch (condition) {
+ case BRANCH_EQ:
+ M_BEQ(branchdisp);
+ break;
+ case BRANCH_NE:
+ M_BNE(branchdisp);
+ break;
+ case BRANCH_LT:
+ M_BLT(branchdisp);
+ break;
+ case BRANCH_GE:
+ M_BGE(branchdisp);
+ break;
+ case BRANCH_GT:
+ M_BGT(branchdisp);
+ break;
+ case BRANCH_LE:
+ M_BLE(branchdisp);
+ break;
+ case BRANCH_UNCONDITIONAL:
+ M_BR(branchdisp);
+ break;
+ default:
+ vm_abort("emit_branch: unknown condition %d", condition);
+ }
+ } else {
+
+ /* If LONGBRANCHES is not set, the flag and the error flag */
+
+ if (!CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
+ cd->flags |= (CODEGENDATA_FLAG_ERROR |
+ CODEGENDATA_FLAG_LONGBRANCHES);
+ }
+
+ /* If error flag is set, do nothing. The method has to be recompiled. */
+
+ if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd) && CODEGENDATA_HAS_FLAG_ERROR(cd)) {
+ return;
+ }
+
+ /* Patch the displacement to branch over the actual branch manually
+ * to not get yet more nops.
+ */
+
+ branchmpc = cd->mcodeptr - cd->mcodebase;
+ ref = cd->mcodeptr;
+
+ switch (condition) {
+ case BRANCH_EQ:
+ M_BNE(0);
+ break;
+ case BRANCH_NE:
+ M_BEQ(0);
+ break;
+ case BRANCH_LT:
+ M_BGE(0);
+ break;
+ case BRANCH_GE:
+ M_BLT(0);
+ break;
+ case BRANCH_GT:
+ M_BLE(0);
+ break;
+ case BRANCH_LE:
+ M_BGT(0);
+ break;
+ case BRANCH_UNCONDITIONAL:
+ /* fall through, no displacement to patch */
+ ref = NULL;
+ break;
+ default:
+ vm_abort("emit_branch: unknown condition %d", condition);
+ }
+
+ /* The actual long branch */
+
+ disp = dseg_add_s4(cd, branchmpc + disp);
+ M_ILD(REG_ITMP3, REG_PV, disp);
+ M_AADD(REG_PV, REG_ITMP3);
+ M_JMP(RN, REG_ITMP3);
+
+ /* Patch back the displacement */
+
+ if (ref != NULL) {
+ *(u4 *)ref |= (u4)((cd->mcodeptr - ref) / 2);
+ }
}
}
Changes: Edwin Steiner
- $Id: md.c 7848 2007-05-01 21:40:26Z pm $
+ $Id: md.c 7966 2007-05-25 12:41:03Z pm $
*/
void md_init(void)
{
- struct sigaction act;
-
- act.sa_sigaction = md_signal_handler_sigill;
- act.sa_flags = SA_NODEFER | SA_SIGINFO;
-
- if (sigaction(SIGILL, &act, NULL) == -1) {
- vm_abort("%s: error registering SIGILL signal handler.", __FUNCTION__);
- }
}
/* md_dump_context ************************************************************
#if defined(ENABLE_THREADS)
-void thread_restartcriticalsection(ucontext_t *_uc)
+void md_critical_section_restart(ucontext_t *_uc)
{
mcontext_t *_mc;
- void *pc;
+ u1 *pc;
+ void *npc;
_mc = &_uc->uc_mcontext;
- pc = critical_find_restart_point((void *) _mc->psw.addr);
+ pc = (u1 *)_mc->psw.addr;
- if (pc != NULL)
- _mc->psw.addr = (ptrint) pc;
+ npc = critical_find_restart_point(pc);
+
+ if (npc != NULL) {
+ log_println("%s: pc=%p, npc=%p", __FUNCTION__, pc, npc);
+ _mc->psw.addr = (ptrint) npc;
+ }
}
#endif
Changes:
- $Id: patcher.c 7839 2007-04-29 22:46:56Z pm $
+ $Id: patcher.c 7966 2007-05-25 12:41:03Z pm $
+
+ GENERATED PATCHER BRANCH AFTER PATCH
+
+ Short patcher call:
+
+ foo bras %r14, OFFSET foo
+ bar ===> bar ===> bar
+ baz baz baz
+
+ Short patcher call with nops:
+ PATCHER_NOPS_SKIP <-+
+ |
+ nop bras %r14, OFFSET nop --+
+ nop ===> nop ===> nop |
+ nop nop nop --+
+ foo foo foo
+
+ Long pacher call:
+ PATCHER_LONGBRANCHES_NOPS_SKIP <-+
+ |
+ br exit: ild itmp3, disp(pv) br exit -+
+ nop aadd pv, itmp3 aadd pv, itmp3 |
+ nop ===> nop ===> nop |
+ ..... .... .... |
+ nop basr itmp3, itmp3 basr itmp3, itmp3 -+
+ exit: exit:
*/
#define OOPS() assert(0);
#define __PORTED__
+/* A normal patcher branch done using BRAS */
+#define PATCHER_IS_SHORTBRANCH(brcode) ((brcode & 0xFF0F0000) == 0xA7050000)
+
/* patcher_wrapper *************************************************************
Wrapper for all patchers. It also creates the stackframe info
java_objectheader *patcher_wrapper(u1 *sp, u1 *pv, u1 *ra)
{
-#if 1
stackframeinfo sfi;
u1 *xpc;
java_objectheader *o;
o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
f = (functionptr) *((ptrint *) (sp + 0 * 4));
- xpc = xpc - 4; /* the patch position is 4 bytes before the RA */
+ /* For a normal branch, the patch position is SZ_BRAS bytes before the RA.
+ * For long branches it is PATCHER_LONGBRANCHES_NOPS_SKIP before the RA.
+ */
+
+ if (PATCHER_IS_SHORTBRANCH(*(u4 *)(xpc - SZ_BRAS))) {
+ xpc = xpc - SZ_BRAS;
+ } else {
+ xpc = xpc - PATCHER_LONGBRANCHES_NOPS_SKIP;
+ }
*((ptrint *) (sp + 5 * 4)) = (ptrint) xpc;
PATCHER_MARK_PATCHED_MONITOREXIT;
return NULL;
-#else
-
- stackframeinfo sfi;
- u1 *xpc;
- java_objectheader *o;
- u4 mcode;
- functionptr f;
- bool result;
- java_objectheader *e;
-
- /* define the patcher function */
-
- bool (*patcher_function)(u1 *);
-
- assert(pv != NULL);
-
- /* get stuff from the stack */
-
- xpc = (u1 *) *((ptrint *) (sp + 5 * 4));
- o = (java_objectheader *) *((ptrint *) (sp + 4 * 4));
- f = (functionptr) *((ptrint *) (sp + 0 * 4));
-
- /* Correct RA is calculated in codegen.c and stored in the patcher
- stub stack. There's no need to adjust xpc. */
-
- /* store PV into the patcher function position */
-
- *((ptrint *) (sp + 0 * 4)) = (ptrint) pv;
-
- /* cast the passed function to a patcher function */
-
- patcher_function = (bool (*)(u1 *)) (ptrint) f;
-
- /* enter a monitor on the patching position */
-
- PATCHER_MONITORENTER;
-
- /* create the stackframeinfo */
-
- stacktrace_create_extern_stackframeinfo(&sfi, pv, sp + 8 * 4, ra, xpc);
-
- /* call the proper patcher function */
-
- result = (patcher_function)(sp);
-
- /* remove the stackframeinfo */
-
- stacktrace_remove_stackframeinfo(&sfi);
-
- /* check for return value and exit accordingly */
-
- if (result == false) {
- e = exceptions_get_and_clear_exception();
-
- PATCHER_MONITOREXIT;
-
- return e;
- }
-
- PATCHER_MARK_PATCHED_MONITOREXIT;
-
- return NULL;
-#endif
}
bool patcher_get_putfield(u1 *sp)
{
u1 *ra;
- u4 mcode;
+ u4 mcode, brcode;
unresolved_field *uf;
fieldinfo *fi;
u1 byte;
+ s4 disp;
/* get stuff from the stack */
ra = (u1 *) *((ptrint *) (sp + 5 * 4));
mcode = *((u4 *) (sp + 3 * 4));
uf = (unresolved_field *) *((ptrint *) (sp + 2 * 4));
+ disp = *((s4 *) (sp + 1 * 4));
/* get the fieldinfo */
/* patch back original code */
+ brcode = *((u4 *) ra);
*((u4 *) ra) = mcode;
/* If NOPs are generated, skip them */
- if (opt_shownops)
+ if (! PATCHER_IS_SHORTBRANCH(brcode))
+ ra += PATCHER_LONGBRANCHES_NOPS_SKIP;
+ else if (opt_shownops)
ra += PATCHER_NOPS_SKIP;
+ /* If there is an operand load before, skip the load size passed in disp (see ICMD_PUTFIELD) */
+
+ ra += disp;
+
/* patch correct offset */
if (fi->type == TYPE_LNG) {
bool patcher_invokevirtual(u1 *sp)
{
u1 *ra;
- u4 mcode;
+ u4 mcode, brcode;
unresolved_method *um;
methodinfo *m;
s4 off;
/* patch back original code */
+ brcode = *((u4 *) ra);
*((u4 *) ra) = mcode;
/* If NOPs are generated, skip them */
- if (opt_shownops)
+ if (! PATCHER_IS_SHORTBRANCH(brcode))
+ ra += PATCHER_LONGBRANCHES_NOPS_SKIP;
+ else if (opt_shownops)
ra += PATCHER_NOPS_SKIP;
/* patch vftbl index */
bool patcher_invokeinterface(u1 *sp)
{
u1 *ra;
- u4 mcode;
+ u4 mcode, brcode;
unresolved_method *um;
methodinfo *m;
s4 idx, off;
/* patch back original code */
+ brcode = *((u4 *) ra);
*((u4 *) ra) = mcode;
/* If NOPs are generated, skip them */
- if (opt_shownops)
+ if (! PATCHER_IS_SHORTBRANCH(brcode))
+ ra += PATCHER_LONGBRANCHES_NOPS_SKIP;
+ else if (opt_shownops)
ra += PATCHER_NOPS_SKIP;
/* get interfacetable index */
bool patcher_checkcast_instanceof_interface(u1 *sp)
{
u1 *ra;
- u4 mcode;
+ u4 mcode, brcode;
constant_classref *cr;
classinfo *c;
/* patch back original code */
+ brcode = *((u4 *) ra);
*((u4 *) ra) = mcode;
/* If NOPs are generated, skip them */
- if (opt_shownops)
+ if (! PATCHER_IS_SHORTBRANCH(brcode))
+ ra += PATCHER_LONGBRANCHES_NOPS_SKIP;
+ else if (opt_shownops)
ra += PATCHER_NOPS_SKIP;
/* patch super class index */
* parses one or more grammar files and generates a parser and lexical analyzer for each.
* Tue May 1 18:49:29 CEST 2007: ===== DaCapo antlr PASSED in 37095 msec =====
+ * Wed May 9 23:58:51 CEST 2007: (ibm java) ===== DaCapo antlr PASSED in 269244 msec =====
+ * Thu May 10 00:05:50 CEST 2007: ===== DaCapo antlr PASSED in 70164 msec =====
+ * Thu May 10 08:54:54 CEST 2007: (ibm java intrp) ===== DaCapo antlr PASSED in 686373 msec =====
+
bloat
chart
* uses JFreeChart to plot a number of complex line graphs and renders them as PDF
+ * Fri May 18 02:08:25 CEST 2007: ===== DaCapo chart PASSED in 549048 msec =====
eclipse
luindex
* Uses lucene to indexes a set of documents; the works of Shakespeare and the King James Bible
+ * Sat May 12 20:27:43 CEST 2007: ===== DaCapo luindex PASSED in 92671 msec =====
lusearch
LOG: [0x77dc66c0] Generating code: org.apache.xalan.processor.XSLTSchema.build()V
32834 (0x8042) is not an signed 16 bit integer at /home/peter/cacao-dev/build-s390/../svn/src/vm/jit/s390/emit.c:258.
=> branch to patcher overflow
+
+ * HANGUP !
#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 ***********************************************************/
LOCK_INIT_OBJECT_LOCK(show_global_lock);
#endif
+#if defined(ENABLE_DEBUG_FILTER)
+ show_filters_init();
+#endif
+
/* everything's ok */
return true;
}
#endif /* !defined(NDEBUG) */
+/* Debug output filtering */
+
+#if defined(ENABLE_DEBUG_FILTER)
+
+#if !defined(ENABLE_THREADS)
+u4 _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.
void show_allocation(s4 type, s4 flags, s4 regoff);
#endif /* !defined(NDEBUG) */
+/* Debug output filtering */
+
+#if defined(ENABLE_DEBUG_FILTER)
+void show_filters_init(void);
+#define SHOW_FILTER_FLAG_VERBOSECALL_INCLUDE 0x01
+#define SHOW_FILTER_FLAG_VERBOSECALL_EXCLUDE 0x02
+#define SHOW_FILTER_FLAG_SHOW_METHOD 0x04
+void show_filters_apply(methodinfo *m);
+int show_filters_test_verbosecall_enter(methodinfo *m);
+int show_filters_test_verbosecall_exit(methodinfo *m);
+#endif
+
+
#endif /* _SHOW_H */
/*
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: signal.c 7831 2007-04-26 12:48:16Z twisti $
+ $Id: signal.c 7966 2007-05-25 12:41:03Z pm $
*/
sigaction(SIGFPE, &act, NULL);
# endif
-# if defined(__ARM__)
+# if defined(__ARM__) || defined(__S390__)
/* XXX use better defines for that (in arch.h) */
/* SIGILL handler */
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: signallocal.h 7596 2007-03-28 21:05:53Z twisti $
+ $Id: signallocal.h 7966 2007-05-25 12:41:03Z pm $
*/
void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p);
#endif
-#if defined(__ARM__)
+#if defined(__ARM__) || defined(__S390__)
/* XXX use better defines for that (in arch.h) */
void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p);
#endif
OPT_AGENTPATH,
#endif
+#if defined(ENABLE_DEBUG_FILTER)
+ OPT_FILTER_VERBOSECALL_INCLUDE,
+ OPT_FILTER_VERBOSECALL_EXCLUDE,
+ OPT_FILTER_SHOW_METHOD,
+#endif
+
DUMMY
};
{ "s", true, OPT_SHOW },
{ "debug-color", false, OPT_DEBUGCOLOR },
+#if defined(ENABLE_DEBUG_FILTER)
+ { "XXfi", true, OPT_FILTER_VERBOSECALL_INCLUDE },
+ { "XXfx", true, OPT_FILTER_VERBOSECALL_EXCLUDE },
+ { "XXfm", true, OPT_FILTER_SHOW_METHOD },
+#endif
+
{ NULL, false, 0 }
};
#if defined(ENABLE_SSA)
puts(" -lsra use linear scan register allocation (with SSA)");
#endif
-
+#if defined(ENABLE_DEBUG_FILTER)
+ puts(" -XXfi <regex> begin of dynamic scope for verbosecall filter");
+ puts(" -XXfx <regex> end of dynamic scope for verbosecall filter");
+ puts(" -XXfm <regex> filter for show options");
+#endif
/* exit with error code */
exit(1);
break;
#endif
+#if defined(ENABLE_DEBUG_FILTER)
+ case OPT_FILTER_VERBOSECALL_INCLUDE:
+ opt_filter_verbosecall_include = opt_arg;
+ break;
+
+ case OPT_FILTER_VERBOSECALL_EXCLUDE:
+ opt_filter_verbosecall_exclude = opt_arg;
+ break;
+
+ case OPT_FILTER_SHOW_METHOD:
+ opt_filter_show_method = opt_arg;
+ break;
+
+#endif
default:
printf("Unknown option: %s\n",
vm_args->options[opt_index].optionString);
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: method.h 7575 2007-03-25 20:30:50Z twisti $
+ $Id: method.h 7966 2007-05-25 12:41:03Z pm $
*/
#if defined(ENABLE_REPLACEMENT)
s4 hitcountdown; /* decreased for each hit */
#endif
+
+#if defined(ENABLE_DEBUG_FILTER)
+ u1 filtermatches; /* flags indicating which filters the method matches */
+#endif
};
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: options.c 7894 2007-05-10 14:04:05Z twisti $
+ $Id: options.c 7966 2007-05-25 12:41:03Z pm $
*/
bool vm_debug = false; /* XXX this should be called `opt_trace' */
#endif
+#if defined(ENABLE_DEBUG_FILTER)
+const char *opt_filter_verbosecall_include = 0;
+const char *opt_filter_verbosecall_exclude = 0;
+const char *opt_filter_show_method = 0;
+#endif
/* options_get *****************************************************************
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: options.h 7894 2007-05-10 14:04:05Z twisti $
+ $Id: options.h 7966 2007-05-25 12:41:03Z pm $
*/
extern bool vm_debug;
#endif
+/* debug output filtering options *********************************************/
+
+#if defined(ENABLE_DEBUG_FILTER)
+extern const char *opt_filter_verbosecall_include;
+extern const char *opt_filter_verbosecall_exclude;
+extern const char *opt_filter_show_method;
+#endif
/* function prototypes ********************************************************/