This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch: not checked in: -Xtrace


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__ */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]