This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: not checked in: -Xtrace
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 19 Feb 2005 14:07:22 -0700
- Subject: Patch: not checked in: -Xtrace
- Reply-to: tromey at redhat dot com
I'm not checking this in yet. It isn't quite complete and I wanted
to wait until after the 4.0 branch is made.
This adds support for a new "-Xtrace" option to gij. With this
option, we try to print a line for every method call that is made.
e.g:
opsy. gij -Xtrace C
[Call main ([Ljava.lang.String;)V]
I'm not sure how useful this will be in practice; it just seemed like
a fun hack.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* link.cc (make_vtable): Handle tracing.
* interpret.cc (FFI_RAW): New define.
(struct trace_desc): New struct.
(trampoline): New function.
(_Jv_getTraceFunction): Likewise.
* include/jvm.h (_Jv_getTraceFunction): Declare.
(gcj::trace_method_calls): Declare.
* gij.cc (main): Handle -Xtrace.
Index: link.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/link.cc,v
retrieving revision 1.10
diff -u -r1.10 link.cc
--- link.cc 19 Feb 2005 05:17:14 -0000 1.10
+++ link.cc 19 Feb 2005 21:04:48 -0000
@@ -47,6 +47,9 @@
// When true, print debugging information about class loading.
bool gcj::verbose_class_flag;
+// When true, print a message for each method call.
+bool gcj::trace_method_calls;
+
typedef unsigned int uaddr __attribute__ ((mode (pointer)));
template<typename T>
@@ -1236,6 +1239,24 @@
// Ensure all the `ncode' entries are set.
klass->engine->create_ncode(klass);
+ // If we're tracing, replace all code pointers with tracing
+ // pointers.
+#ifdef USE_LIBFFI
+ if (gcj::trace_method_calls)
+ {
+ for (int i = 0; i < klass->method_count; i++)
+ {
+ // Just skip abstract methods.
+ using namespace java::lang::reflect;
+ if ((klass->methods[i].accflags & Modifier::ABSTRACT) != 0)
+ continue;
+ klass->methods[i].ncode
+ = _Jv_getTraceFunction (&klass->methods[i],
+ klass->methods[i].ncode);
+ }
+ }
+#endif // USE_LIBFFI
+
// Class must be laid out before we can create a vtable.
if (klass->vtable_method_count == -1)
layout_vtable_methods (klass);
@@ -1566,7 +1587,7 @@
}
// Check the assertions contained in the type assertion table for KLASS.
-// This is the equivilent of bytecode verification for native, BC-ABI code.
+// This is the equivalent of bytecode verification for native, BC-ABI code.
void
_Jv_Linker::verify_type_assertions (jclass klass)
{
@@ -1624,7 +1645,7 @@
// Unknown assertion codes are ignored, for forwards-compatibility.
}
}
-
+
void
_Jv_Linker::print_class_loaded (jclass klass)
{
Index: interpret.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/interpret.cc,v
retrieving revision 1.48
diff -u -r1.48 interpret.cc
--- interpret.cc 5 Jan 2005 19:03:10 -0000 1.48
+++ interpret.cc 19 Feb 2005 21:04:48 -0000
@@ -1,6 +1,6 @@
// interpret.cc - Code for the interpreter
-/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
This file is part of libgcj.
@@ -3543,9 +3553,13 @@
#if FFI_NATIVE_RAW_API
# define FFI_PREP_RAW_CLOSURE ffi_prep_raw_closure
# define FFI_RAW_SIZE ffi_raw_size
+# define FFI_RAW(CIF, FUN, RVALUE, RAW) \
+ ffi_raw_call (CIF, FUN, RVALUE, RAW)
#else
# define FFI_PREP_RAW_CLOSURE ffi_prep_java_raw_closure
# define FFI_RAW_SIZE ffi_java_raw_size
+# define FFI_RAW(CIF, FUN, RVALUE, RAW) \
+ ffi_java_raw_call (CIF, FUN, RVALUE, RAW)
#endif
/* we put this one here, and not in interpret.cc because it
@@ -3674,6 +3688,62 @@
return self->ncode;
}
+
+
+// A structure of this type is used to describe what we're doing.
+struct trace_desc
+{
+ // The method we wrap.
+ _Jv_Method *method;
+ // The actual function to call.
+ void (*ncode) ();
+ // The cif, closure, and argument types.
+ ffi_raw_closure closure;
+ ffi_cif cif;
+ ffi_type *arg_types[0];
+};
+
+// This is called when tracing to print some information and then make
+// the real call.
+static void
+trampoline (ffi_cif *cif, void *ret, ffi_raw *arguments, void *handle)
+{
+ trace_desc *desc = (trace_desc *) handle;
+
+ fprintf (stderr, "[Call %s %s]\n", desc->method->name->chars(),
+ desc->method->signature->chars());
+
+ // Note that this trampoline shares the same CIF as the real call.
+ FFI_RAW (cif, desc->ncode, ret, arguments);
+}
+
+void *
+_Jv_getTraceFunction (_Jv_Method *method, void *real)
+{
+ using namespace java::lang::reflect;
+
+ jboolean staticp = (method->accflags & Modifier::STATIC) != 0;
+ int arg_count = _Jv_count_arguments (method->signature, staticp);
+
+ trace_desc *desc
+ = (trace_desc *) _Jv_Malloc (sizeof (trace_desc)
+ + arg_count * sizeof (ffi_type *));
+ desc->method = method;
+ desc->ncode = (void (*) ()) real;
+
+ ffi_type *ret_type;
+ init_cif (method->signature, arg_count, staticp,
+ &desc->cif, &desc->arg_types[0],
+ &ret_type);
+
+ FFI_PREP_RAW_CLOSURE (&desc->closure, &desc->cif,
+ (ffi_closure_fun) trampoline,
+ desc);
+ return (void *) &desc->closure;
+}
+
+
+
static void
throw_class_format_error (jstring msg)
{
Index: gij.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gij.cc,v
retrieving revision 1.25
diff -u -r1.25 gij.cc
--- gij.cc 18 Feb 2005 20:52:14 -0000 1.25
+++ gij.cc 19 Feb 2005 21:04:48 -0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
This file is part of libgcj.
@@ -140,10 +140,16 @@
{
if (arg[2] == '\0')
{
- printf ("gij: currently no -X options are recognized\n");
+ printf ("Accepted -X options:\n");
+ printf (" -Xtrace trace method calls\n");
exit (0);
}
- /* Ignore other -X options. */
+ else if (! strcmp (arg, "-Xtrace"))
+ gcj::trace_method_calls = 1;
+ else
+ {
+ /* Ignore other -X options. */
+ }
}
else
{
Index: include/jvm.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/jvm.h,v
retrieving revision 1.77
diff -u -r1.77 jvm.h
--- include/jvm.h 19 Feb 2005 01:16:30 -0000 1.77
+++ include/jvm.h 19 Feb 2005 21:04:49 -0000
@@ -244,6 +244,9 @@
/* Print out class names as they are initialized. */
extern bool verbose_class_flag;
+
+ /* Trace method calls. */
+ extern bool trace_method_calls;
}
// This class handles all aspects of class preparation and linking.
@@ -585,4 +588,8 @@
|| value == (GCJ_VERSION + GCJ_BINARYCOMPAT_ADDITION));
}
+// Create a trace function wrapping the indicated method.
+// Only valid when libffi is available.
+void *_Jv_getTraceFunction (_Jv_Method *method, void *real_function);
+
#endif /* __JAVA_JVM_H__ */