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]

Re: Illegal Package-Private Accesses in 3.4


Hi (discussion moved from java to java-patches),

On Wed, 2003-07-09 at 21:35, Ranjit Mathew wrote:
>     I applied my package-private access checking patch/kludge to 
> the 3.4 snapshot from 2007-07-02 and found that some of the 
> issues I had reported earlier in 3.3 have been resolved while 
> a new one has been added.
> 
> The issues still present are:
> 
>  2. java.lang.VMThrowable illegally calls "stackTraceAddrs( )"
>     in gnu.gcj.runtime.StackTrace.

It seems to me that the best thing to do is to move StackTrace to the
java.lang package and make it package private to prevent any 'illegal'
access to this class by user code.

>  3. gnu.gcj.runtime.NameFinder illegally uses the constructor
>     in java.lang.StackTraceElement.

Here a simple native method seems to be in place for creating the
StackTraceElement. Which was already done in a couple of other places in
this class.

2003-08-10  Mark Wielaard  <mark@klomp.org>

        * Makefile.am: Move StackTrace.java, natStackTrace.cc and MethodRef
        from gnu/gcj/runtime to java/lang.
        * Makeefile.in: Regenerated.
        * gcj/javaprims.h: Regenerated.
        * gnu/gcj/runtime/NameFinder.java (newStackTraceElement): New method.
        * gnu/gcj/runtime/natNameFinder.cc (newStackTraceElement): Likewise.
        * gnu/gcj/runtime/MethodRef.java: Removed.
        * gnu/gcj/runtime/StackTrace.java: Likewise.
        * gnu/gcj/runtime/natStackTrace.cc: Likewise.
        * java/lang/MethodRef.java: New class moved from gnu/gcj/runtime.
        * java/lang/StackTrace.java: Likewise.
        * java/lang/natStackTrace.cc: Likewise.
        * include/java-interp.h: Use StackTrace from java/lang, not
        gnu/gcj/runtime.
        * java/lang/Class.h: Likewise.
        * java/lang/VMThrowable.java: Likewise.
        * java/lang/natClass.cc: Likewise.
        * java/lang/natRuntime.cc: Likewise.
        * java/lang/natVMSecurityManager.cc: Likewise.
        * java/lang/reflect/natArray.cc: Likewise.
        * java/lang/reflect/natConstructor.cc: Likewise.
        * java/lang/reflect/natField.cc: Likewise.
        * java/lang/reflect/natMethod.cc: Likewise.
        * java/util/natResourceBundle.cc: Likewise.

OK to commit?
Make check on x86 does not show regressions.

Note that gcj/javaprims.h also got the new java.util logging and prefs
subpackages classes included. Makefile.in is not included since it is
long and boring.

Cheers,

Mark
Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.313
diff -u -r1.313 Makefile.am
--- Makefile.am	8 Aug 2003 16:25:57 -0000	1.313
+++ Makefile.am	10 Aug 2003 20:19:40 -0000
@@ -1746,6 +1746,7 @@
 java/lang/LinkageError.java \
 java/lang/Long.java \
 java/lang/Math.java \
+java/lang/MethodRef.java \
 java/lang/NegativeArraySizeException.java \
 java/lang/NoClassDefFoundError.java \
 java/lang/NoSuchFieldError.java	\
@@ -1766,6 +1767,7 @@
 java/lang/SecurityManager.java \
 java/lang/Short.java \
 java/lang/StackOverflowError.java \
+java/lang/StackTrace.java \
 java/lang/StackTraceElement.java \
 java/lang/StrictMath.java \
 java/lang/String.java \
@@ -1959,10 +1961,8 @@
 gnu/gcj/runtime/FinalizerThread.java \
 gnu/gcj/runtime/FirstThread.java \
 gnu/gcj/runtime/JNIWeakRef.java \
-gnu/gcj/runtime/MethodRef.java \
 gnu/gcj/runtime/NameFinder.java \
 gnu/gcj/runtime/SharedLibLoader.java \
-gnu/gcj/runtime/StackTrace.java \
 gnu/gcj/runtime/StringBuffer.java \
 gnu/gcj/runtime/VMClassLoader.java \
 gnu/java/io/ASN1ParsingException.java \
@@ -2578,7 +2578,6 @@
 gnu/gcj/runtime/natFirstThread.cc \
 gnu/gcj/runtime/natNameFinder.cc \
 gnu/gcj/runtime/natSharedLibLoader.cc \
-gnu/gcj/runtime/natStackTrace.cc \
 gnu/gcj/runtime/natStringBuffer.cc \
 gnu/gcj/runtime/natVMClassLoader.cc \
 gnu/java/awt/natEmbeddedWindow.cc \
@@ -2597,6 +2596,7 @@
 java/lang/natMath.cc \
 java/lang/natObject.cc \
 java/lang/natRuntime.cc	\
+java/lang/natStackTrace.cc \
 java/lang/natString.cc \
 java/lang/natStringBuffer.cc \
 java/lang/natSystem.cc \
Index: gcj/javaprims.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gcj/javaprims.h,v
retrieving revision 1.45
diff -u -r1.45 javaprims.h
--- gcj/javaprims.h	20 Jan 2003 06:46:28 -0000	1.45
+++ gcj/javaprims.h	10 Aug 2003 20:19:46 -0000
@@ -172,6 +172,7 @@
       class LinkageError;
       class Long;
       class Math;
+      class MethodRef;
       class NegativeArraySizeException;
       class NoClassDefFoundError;
       class NoSuchFieldError;
@@ -194,6 +195,7 @@
       class SecurityManager;
       class Short;
       class StackOverflowError;
+      class StackTrace;
       class StackTraceElement;
       class StrictMath;
       class String;
@@ -371,6 +373,39 @@
         class JarInputStream;
         class JarOutputStream;
         class Manifest;
+      }
+
+      namespace logging
+      {
+        class ConsoleHandler;
+        class ErrorManager;
+        class FileHandler;
+        class Filter;
+        class Formatter;
+        class Handler;
+        class Level;
+        class LogManager;
+        class LogRecord;
+        class Logger;
+        class LoggingPermission;
+        class MemoryHandler;
+        class SimpleFormatter;
+        class SocketHandler;
+        class StreamHandler;
+        class XMLFormatter;
+      }
+
+      namespace prefs
+      {
+        class AbstractPreferences;
+        class BackingStoreException;
+        class InvalidPreferencesFormatException;
+        class NodeChangeEvent;
+        class NodeChangeListener;
+        class PreferenceChangeEvent;
+        class PreferenceChangeListener;
+        class Preferences;
+        class PreferencesFactory;
       }
 
       namespace regex
Index: gnu/gcj/runtime/MethodRef.java
===================================================================
RCS file: gnu/gcj/runtime/MethodRef.java
diff -N gnu/gcj/runtime/MethodRef.java
--- gnu/gcj/runtime/MethodRef.java	3 Dec 2002 13:53:27 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,25 +0,0 @@
-// gnu.gcj.runtime.MethodRef -- used by StackTrace.
-
-/* Copyright (C) 2002  Free Software Foundation
-
-   This file is part of libgcj.
-
-This software is copyrighted work licensed under the terms of the
-Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
-details.  */
-
-package gnu.gcj.runtime;
-
-import gnu.gcj.RawData;
-
-class MethodRef
-{
-  MethodRef(RawData /* Actually _Jv_Method */ m, Class k)
-  {
-    klass = k;
-    method = m;
-  }
-
-  public RawData method; // Actually a raw pointer to _Jv_Method
-  public Class klass;
-}
Index: gnu/gcj/runtime/NameFinder.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/runtime/NameFinder.java,v
retrieving revision 1.6
diff -u -r1.6 NameFinder.java
--- gnu/gcj/runtime/NameFinder.java	21 Jul 2003 02:24:08 -0000	1.6
+++ gnu/gcj/runtime/NameFinder.java	10 Aug 2003 20:19:46 -0000
@@ -363,7 +363,7 @@
   private StackTraceElement createStackTraceElement(String name, String file)
   {
     if (!demangle)
-      return new StackTraceElement(file, -1, null, name, false);
+      return newStackTraceElement(file, -1, null, name, false);
 
     String s = demangleName(name);
     String methodName = s;
@@ -409,8 +409,18 @@
 	  }
       }
 
-    return new StackTraceElement(fileName, line, className, methodName, false);
+    return newStackTraceElement(fileName, line,
+				className, methodName,
+				false);
   }
+
+  // Creates a StackTraceElement from the given arguments.
+  // Native since StackTraceElement doesn't have a public constructor.
+  native private static StackTraceElement newStackTraceElement(String file,
+							       int line,
+							       String clazz,
+							       String meth,
+							       boolean isNat);
 
   /**
    * Demangles the given String if possible. Returns the demangled String or
Index: gnu/gcj/runtime/StackTrace.java
===================================================================
RCS file: gnu/gcj/runtime/StackTrace.java
diff -N gnu/gcj/runtime/StackTrace.java
--- gnu/gcj/runtime/StackTrace.java	3 Dec 2002 13:53:27 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,164 +0,0 @@
-/* gnu.gcj.runtime.StackTrace -- VM support methods for walking the
-   stack.
-   Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-02111-1307 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-package gnu.gcj.runtime;
-
-import gnu.gcj.RawData;
-import java.util.TreeMap;
-import java.util.IdentityHashMap;
-import java.util.SortedMap;
-import gnu.gcj.runtime.NameFinder;
-import java.util.NoSuchElementException;
-
-/**
- * VM dependent state and support methods for walking the stack.
- * <p>
- * This is the version used by libgcj (http://gcc.gnu.org/java/).
- *
- * @author Mark Wielaard (mark@klomp.org)
- * @author Andrew Haley (aph@redhat.com)
- */
-public final class StackTrace
-{
-  /**
-   * Fill in the stack trace with the top n frames on current
-   * execution stack.  Can return null if the VM does not support
-   * capturing the VM execution state.
-   *
-   * @see Throwable#fillInStackTrace()
-   */
-  public StackTrace(int n)
-  {
-    fillInStackTrace(n, 1);
-  }
-
-  /**
-   * Fill in the stack trace with state of the entire execution stack,
-   * starting from frame <code>offset</code>.  Can return null if the
-   * VM does not support capturing the VM execution state.
-   *
-   * This can be very expensive.  If you only want part of the stack,
-   * see <code>Throwable.fillInStackTrace(int)</code>
-   *
-   * @see Throwable#fillInStackTrace()
-   */
-  public StackTrace()
-  {
-    int n = 64;
-    
-    do
-      {
-	n *= 4;
-	fillInStackTrace(n, 1);
-      }
-    while (len >= n);
-  }
-
-  /**
-   * Return the class containing the execution point represented by
-   * the Nth frame down the stack.  The zeroth frame represents the
-   * top of the stack, which is the method that called classAt().
-   *
-   * If the Nth frame down the stack was not create by a method
-   * invocation, return null.
-   *
-   * It is not necessary to call <code>fillInStackTrace()</code> with
-   * a size greater than N before calling this method; if the current
-   * stack trace is insufficiently large, it will be expanded as
-   * required.  This requires some caution if
-   * <code>fillInStackTrace()</code> is called from a different
-   * invocation to the one that calls <code>classAt()</code>.
-   * classAt() will not call <code>fillInStackTrace()</code> unless N
-   * is greater than the current length.
-   *
-   */
-  public native Class classAt(int n);
-
-  /**
-   * Return the name of the method containing the execution point
-   * represented by the Nth frame down the stack.  The zeroth frame
-   * represents the top of the stack, which is the method that called
-   * classAt().
-   *
-   * If the Nth frame down the stack was not create by a method
-   * invocation, return null.
-   *
-   * It is not necessary to call <code>fillInStackTrace()</code> with
-   * a size greater than N before calling this method; if the current
-   * stack trace is insufficiently large, it will be expanded as
-   * required.  This requires some caution if
-   * <code>fillInStackTrace()</code> is called from a different
-   * invocation to the one that calls <code>classAt()</code>.
-   * classAt() will not call <code>fillInStackTrace()</code> unless N
-   * is greater than the current length.
-   *
-   */
-  public native String methodAt(int n);
-
-  /**
-   * Return the length of this stack trace.
-   *
-   */
-  public int length ()
-  {
-    return len;
-  }
-
-  private static native void update();
-  private static MethodRef methodAtAddress(RawData addr)
-  {
-    update();
-    synchronized (map)
-      {
-	return (MethodRef) map.get (addr);
-      }
-  }
-
-  gnu.gcj.RawData stackTraceAddrs()
-  {
-    return addrs;
-  }
-  
-  private native void fillInStackTrace(int n, int offset);
-
-  private static native MethodRef getCompiledMethodRef(RawData addr);
-  private static IdentityHashMap map = new IdentityHashMap();
-
-  private gnu.gcj.RawData addrs;
-  private int len;
-}
Index: gnu/gcj/runtime/natNameFinder.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/runtime/natNameFinder.cc,v
retrieving revision 1.4
diff -u -r1.4 natNameFinder.cc
--- gnu/gcj/runtime/natNameFinder.cc	10 Mar 2003 19:45:30 -0000	1.4
+++ gnu/gcj/runtime/natNameFinder.cc	10 Aug 2003 20:19:46 -0000
@@ -1,6 +1,6 @@
 // natNameFinder.cc - native helper methods for NameFinder.java
 
-/* Copyright (C) 2002  Free Software Foundation, Inc
+/* Copyright (C) 2002, 2003  Free Software Foundation, Inc
 
    This file is part of libgcj.
 
@@ -116,6 +116,16 @@
     }
 #endif
   return NULL;
+}
+
+java::lang::StackTraceElement*
+gnu::gcj::runtime::NameFinder::newStackTraceElement(java::lang::String* file,
+						    jint line,
+						    java::lang::String* clazz,
+						    java::lang::String* meth,
+						    jboolean is_native)
+{
+  return new java::lang::StackTraceElement(file, line, clazz, meth, is_native);
 }
 
 java::lang::StackTraceElement *
Index: gnu/gcj/runtime/natStackTrace.cc
===================================================================
RCS file: gnu/gcj/runtime/natStackTrace.cc
diff -N gnu/gcj/runtime/natStackTrace.cc
--- gnu/gcj/runtime/natStackTrace.cc	19 Feb 2003 16:28:36 -0000	1.4
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,198 +0,0 @@
-// natStackTrace.cc - native helper methods for Throwable
-
-/* Copyright (C) 2000, 2002, 2003  Free Software Foundation, Inc
-
-   This file is part of libgcj.
-
-This software is copyrighted work licensed under the terms of the
-Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
-details.  */
-
-/**
- * @author Andrew Haley <aph@cygnus.com>
- * @author Mark Wielaard <mark@klomp.org>
- *
- * Native helper methods for VM specific Throwable support.
- */
-
-#include <config.h>
-#include <platform.h>
-
-#include <string.h>
-
-#include <jvm.h>
-#include <gcj/cni.h>
-#include <gnu/gcj/RawData.h>
-#include <java/lang/Object.h>
-#include <java-threads.h>
-#include <gnu/gcj/runtime/MethodRef.h>
-#include <gnu/gcj/runtime/StackTrace.h>
-#include <java/lang/Thread.h>
-#include <java-interp.h>
-#include <java/util/IdentityHashMap.h>
-#include <java/lang/ArrayIndexOutOfBoundsException.h>
-
-#include <sys/types.h>
-
-#include <stdlib.h>
-
-#include <unistd.h>
-
-#ifdef HAVE_EXECINFO_H
-#include <execinfo.h>
-#endif
-
-#include <unwind.h>
-
-
-// Fill in this stack trace with MAXLEN elements starting at offset.
-void
-gnu::gcj::runtime::StackTrace::fillInStackTrace (jint maxlen, jint offset)
-{
-#ifdef HAVE_BACKTRACE
-  offset += 1;
-  void *_p[maxlen + offset];
-  len = backtrace (_p, maxlen + offset) - offset;
-  void **p = _p + offset;
-  _Jv_frame_info *frame;
-  if (len > 0)
-    {
-#ifdef INTERPRETER
-      extern void _Jv_StartOfInterpreter (void);
-      extern void _Jv_EndOfInterpreter (void);
-
-      java::lang::Thread *thread = java::lang::Thread::currentThread();
-      _Jv_MethodChain *interp_frame
-	= (thread ? reinterpret_cast<_Jv_MethodChain *> (thread->interp_frame)
-	   : NULL);
-#endif // INTERPRETER
-
-      frame = (_Jv_frame_info *) _Jv_Malloc (len * sizeof (_Jv_frame_info));
-      for (int n = 0; n < len; n++)
-	{
-	  frame[n].addr = p[n];
-#ifdef INTERPRETER
-	  if (p[n] >= &_Jv_StartOfInterpreter && p[n] <= &_Jv_EndOfInterpreter)
-	    {
-	      frame[n].interp = (void *) interp_frame->self;
-	      interp_frame = interp_frame->next;
-	    }
-	  else
-	    frame[n].interp = 0;
-#endif // INTERPRETER
-	}
-    }
-  else
-    frame = NULL;
-
-  addrs = reinterpret_cast<gnu::gcj::RawData *> (frame);
-#else // HAVE_BACKTRACE
-  (void)maxlen;
-  (void)offset;
-#endif // HAVE_BACKTRACE
-}
-
-/* Obtain the next power-of-2 of some integer.  */
-static inline jint
-nextpowerof2 (jint n)
-{
-  n |= (n >> 1);
-  n |= (n >> 2);
-  n |= (n >> 4);
-  n |= (n >> 8);
-  n |= (n >> 16);
-  return n+1;
-}
-
-#define GET_FRAME(N)						\
-({								\
-  if ((N) >= len)						\
-    fillInStackTrace (nextpowerof2 (N), 1);			\
-  if ((N) < 0 || (N) >= len)					\
-    throw new ::java::lang::ArrayIndexOutOfBoundsException ();	\
-								\
-  _Jv_frame_info *frame = (_Jv_frame_info *)addrs;		\
-  &frame[N];							\
-})
-
-gnu::gcj::runtime::MethodRef *
-gnu::gcj::runtime::StackTrace::getCompiledMethodRef (gnu::gcj::RawData *addr)
-{
-  void *p = _Unwind_FindEnclosingFunction (addr);
-  return gnu::gcj::runtime::StackTrace
-    ::methodAtAddress ((gnu::gcj::RawData *)p);
-}
-
-java::lang::Class *
-gnu::gcj::runtime::StackTrace::classAt (jint n)
-{
-  _Jv_frame_info *frame = GET_FRAME (n);
-
-#ifdef INTERPRETER
-  if (frame->interp)
-    {
-      _Jv_InterpMethod *meth
-	= reinterpret_cast<_Jv_InterpMethod *> (frame->interp);
-      return meth->defining_class;
-    }
-#endif // INTERPRETER
-  
-  gnu::gcj::runtime::MethodRef *ref 
-    = getCompiledMethodRef ((gnu::gcj::RawData *)frame->addr);
-  if (ref)
-    return ref->klass;
-  else
-    return NULL;
-}
-
-java::lang::String*
-gnu::gcj::runtime::StackTrace::methodAt (jint n)
-{
-  _Jv_frame_info *frame = GET_FRAME (n);
-  _Jv_Method *meth = NULL;
-
-#ifdef INTERPRETER
-  if (frame->interp)
-    {
-      meth
-	= reinterpret_cast<_Jv_InterpMethod *> (frame->interp)
-	->get_method();
-    }
-#endif // INTERPRETER
-  
-  if (! meth)
-    {
-      gnu::gcj::runtime::MethodRef *ref
-	= getCompiledMethodRef ((gnu::gcj::RawData *)frame->addr);
-      if (ref)
-	meth = (_Jv_Method *)ref->method;
-    }
-
-  return meth 
-    ? _Jv_NewStringUtf8Const (meth->name)
-    : NULL ;
-}
-
-void
-gnu::gcj::runtime::StackTrace::update(void)
-{
-  jclass klass;
-
-  while ((klass = _Jv_PopClass ()))
-    {
-      for (int i=0; i<klass->method_count; i++)
-	{
-	  JvSynchronize sync (map);
-	  _Jv_Method *meth = &(klass->methods[i]);
-	  if (meth->ncode) // i.e. if p is not abstract
-	    {
-	      gnu::gcj::runtime::MethodRef *ref
-		= new gnu::gcj::runtime::MethodRef 
-		((gnu::gcj::RawData *)meth, klass);
-	      map->put ((java::lang::Object*)(meth->ncode), ref);
-	    }
-	}
-    }
-}
-
-
Index: include/java-interp.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/java-interp.h,v
retrieving revision 1.22
diff -u -r1.22 java-interp.h
--- include/java-interp.h	24 Jan 2003 19:58:21 -0000	1.22
+++ include/java-interp.h	10 Aug 2003 20:19:46 -0000
@@ -21,8 +21,8 @@
 
 #include <java/lang/Class.h>
 #include <java/lang/ClassLoader.h>
+#include <java/lang/StackTrace.h>
 #include <java/lang/reflect/Modifier.h>
-#include <gnu/gcj/runtime/StackTrace.h>
 
 extern "C" {
 #include <ffi.h>
@@ -143,7 +143,7 @@
   friend class _Jv_ClassReader;
   friend class _Jv_BytecodeVerifier;
   friend class gnu::gcj::runtime::NameFinder;
-  friend class gnu::gcj::runtime::StackTrace;
+  friend class java::lang::StackTrace;
 
   friend void _Jv_PrepareClass(jclass);
 
Index: java/lang/Class.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/Class.h,v
retrieving revision 1.56
diff -u -r1.56 Class.h
--- java/lang/Class.h	21 Jul 2003 01:54:05 -0000	1.56
+++ java/lang/Class.h	10 Aug 2003 20:19:48 -0000
@@ -20,7 +20,7 @@
 #include <java/lang/reflect/Modifier.h>
 #include <java/security/ProtectionDomain.h>
 #include <java/lang/Package.h>
-#include <gnu/gcj/runtime/StackTrace.h>
+#include <java/lang/StackTrace.h>
 
 // We declare these here to avoid including gcj/cni.h.
 extern "C" void _Jv_InitClass (jclass klass);
@@ -366,7 +366,7 @@
 #endif
 
   friend class _Jv_BytecodeVerifier;
-  friend class gnu::gcj::runtime::StackTrace;
+  friend class java::lang::StackTrace;
   friend class java::io::VMObjectStreamClass;
 
   // Chain for class pool.
Index: java/lang/MethodRef.java
===================================================================
RCS file: java/lang/MethodRef.java
diff -N java/lang/MethodRef.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/lang/MethodRef.java	10 Aug 2003 20:19:48 -0000
@@ -0,0 +1,25 @@
+// java.lang.MethodRef -- used by StackTrace.
+
+/* Copyright (C) 2002, 2003  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package java.lang;
+
+import gnu.gcj.RawData;
+
+final class MethodRef
+{
+  MethodRef(RawData /* Actually _Jv_Method */ m, Class k)
+  {
+    klass = k;
+    method = m;
+  }
+
+  RawData method; // Actually a raw pointer to _Jv_Method
+  Class klass;
+}
Index: java/lang/StackTrace.java
===================================================================
RCS file: java/lang/StackTrace.java
diff -N java/lang/StackTrace.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/lang/StackTrace.java	10 Aug 2003 20:19:48 -0000
@@ -0,0 +1,163 @@
+/* java/lang.StackTrace -- gcj support methods for walking the stack.
+   Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package java.lang;
+
+import gnu.gcj.RawData;
+import java.util.TreeMap;
+import java.util.IdentityHashMap;
+import java.util.SortedMap;
+import gnu.gcj.runtime.NameFinder;
+import java.util.NoSuchElementException;
+
+/**
+ * VM dependent state and support methods for walking the stack.
+ * <p>
+ * This is the version used by libgcj (http://gcc.gnu.org/java/).
+ *
+ * @author Mark Wielaard (mark@klomp.org)
+ * @author Andrew Haley (aph@redhat.com)
+ */
+final class StackTrace
+{
+  /**
+   * Fill in the stack trace with the top n frames on current
+   * execution stack.  Can return null if the VM does not support
+   * capturing the VM execution state.
+   *
+   * @see Throwable#fillInStackTrace()
+   */
+  StackTrace(int n)
+  {
+    fillInStackTrace(n, 1);
+  }
+
+  /**
+   * Fill in the stack trace with state of the entire execution stack,
+   * starting from frame <code>offset</code>.  Can return null if the
+   * VM does not support capturing the VM execution state.
+   *
+   * This can be very expensive.  If you only want part of the stack,
+   * see <code>Throwable.fillInStackTrace(int)</code>
+   *
+   * @see Throwable#fillInStackTrace()
+   */
+  StackTrace()
+  {
+    int n = 64;
+    
+    do
+      {
+	n *= 4;
+	fillInStackTrace(n, 1);
+      }
+    while (len >= n);
+  }
+
+  /**
+   * Return the class containing the execution point represented by
+   * the Nth frame down the stack.  The zeroth frame represents the
+   * top of the stack, which is the method that called classAt().
+   *
+   * If the Nth frame down the stack was not create by a method
+   * invocation, return null.
+   *
+   * It is not necessary to call <code>fillInStackTrace()</code> with
+   * a size greater than N before calling this method; if the current
+   * stack trace is insufficiently large, it will be expanded as
+   * required.  This requires some caution if
+   * <code>fillInStackTrace()</code> is called from a different
+   * invocation to the one that calls <code>classAt()</code>.
+   * classAt() will not call <code>fillInStackTrace()</code> unless N
+   * is greater than the current length.
+   *
+   */
+  native Class classAt(int n);
+
+  /**
+   * Return the name of the method containing the execution point
+   * represented by the Nth frame down the stack.  The zeroth frame
+   * represents the top of the stack, which is the method that called
+   * classAt().
+   *
+   * If the Nth frame down the stack was not create by a method
+   * invocation, return null.
+   *
+   * It is not necessary to call <code>fillInStackTrace()</code> with
+   * a size greater than N before calling this method; if the current
+   * stack trace is insufficiently large, it will be expanded as
+   * required.  This requires some caution if
+   * <code>fillInStackTrace()</code> is called from a different
+   * invocation to the one that calls <code>classAt()</code>.
+   * classAt() will not call <code>fillInStackTrace()</code> unless N
+   * is greater than the current length.
+   *
+   */
+  native String methodAt(int n);
+
+  /**
+   * Return the length of this stack trace.
+   *
+   */
+  int length ()
+  {
+    return len;
+  }
+
+  private static native void update();
+  private static MethodRef methodAtAddress(RawData addr)
+  {
+    update();
+    synchronized (map)
+      {
+	return (MethodRef) map.get (addr);
+      }
+  }
+
+  gnu.gcj.RawData stackTraceAddrs()
+  {
+    return addrs;
+  }
+  
+  private native void fillInStackTrace(int n, int offset);
+
+  private static native MethodRef getCompiledMethodRef(RawData addr);
+  private static IdentityHashMap map = new IdentityHashMap();
+
+  private gnu.gcj.RawData addrs;
+  private int len;
+}
Index: java/lang/VMThrowable.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/VMThrowable.java,v
retrieving revision 1.2
diff -u -r1.2 VMThrowable.java
--- java/lang/VMThrowable.java	3 Dec 2002 13:50:04 -0000	1.2
+++ java/lang/VMThrowable.java	10 Aug 2003 20:19:48 -0000
@@ -38,7 +38,6 @@
 package java.lang;
 
 import gnu.gcj.runtime.NameFinder;
-import gnu.gcj.runtime.StackTrace;
 
 /**
  * VM dependent state and support methods Throwable.
@@ -51,7 +50,7 @@
  */
 final class VMThrowable
 {
-  private gnu.gcj.runtime.StackTrace trace;
+  private StackTrace trace;
 
   /**
    * Private contructor, create VMThrowables with fillInStackTrace();
@@ -77,7 +76,7 @@
     if (trace_enabled)
       {
 	state = new VMThrowable ();
-	state.trace = new gnu.gcj.runtime.StackTrace(128);
+	state.trace = new StackTrace(128);
       }
     return state;
   }
Index: java/lang/natClass.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClass.cc,v
retrieving revision 1.63
diff -u -r1.63 natClass.cc
--- java/lang/natClass.cc	21 Jul 2003 01:54:05 -0000	1.63
+++ java/lang/natClass.cc	10 Aug 2003 20:19:49 -0000
@@ -47,8 +47,8 @@
 #include <java/lang/RuntimePermission.h>
 #include <java/lang/System.h>
 #include <java/lang/SecurityManager.h>
+#include <java/lang/StackTrace.h>
 #include <java/lang/StringBuffer.h>
-#include <gnu/gcj/runtime/StackTrace.h>
 #include <gcj/method.h>
 #include <gnu/gcj/runtime/MethodRef.h>
 #include <gnu/gcj/RawData.h>
@@ -92,8 +92,8 @@
 java::lang::Class::forName (jstring className)
 {
   java::lang::ClassLoader *loader = NULL;
-  gnu::gcj::runtime::StackTrace *t 
-    = new gnu::gcj::runtime::StackTrace(4);
+  java::lang::StackTrace *t 
+    = new java::lang::StackTrace(4);
   java::lang::Class *klass = NULL;
   try
     {
@@ -116,8 +116,8 @@
   java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
   if (s != NULL)
     {
-      gnu::gcj::runtime::StackTrace *t 
-	= new gnu::gcj::runtime::StackTrace(4);
+      java::lang::StackTrace *t 
+	= new java::lang::StackTrace(4);
       Class *caller = NULL;
       ClassLoader *caller_loader = NULL;
       try
Index: java/lang/natRuntime.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natRuntime.cc,v
retrieving revision 1.39
diff -u -r1.39 natRuntime.cc
--- java/lang/natRuntime.cc	8 Aug 2003 16:26:00 -0000	1.39
+++ java/lang/natRuntime.cc	10 Aug 2003 20:19:49 -0000
@@ -29,7 +29,7 @@
 #include <java/lang/Process.h>
 #include <java/lang/ConcreteProcess.h>
 #include <java/lang/ClassLoader.h>
-#include <gnu/gcj/runtime/StackTrace.h>
+#include <java/lang/StackTrace.h>
 #include <java/lang/ArrayIndexOutOfBoundsException.h>
 
 #include <jni.h>
@@ -165,7 +165,7 @@
     {
       ClassLoader *sys = ClassLoader::getSystemClassLoader();
       ClassLoader *look = NULL;
-      gnu::gcj::runtime::StackTrace *t = new gnu::gcj::runtime::StackTrace(10);
+      java::lang::StackTrace *t = new java::lang::StackTrace(10);
       try
       	{
 	  for (int i = 0; i < 10; ++i)
Index: java/lang/natStackTrace.cc
===================================================================
RCS file: java/lang/natStackTrace.cc
diff -N java/lang/natStackTrace.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ java/lang/natStackTrace.cc	10 Aug 2003 20:19:49 -0000
@@ -0,0 +1,197 @@
+// natStackTrace.cc - native helper methods for Throwable
+
+/* Copyright (C) 2000, 2002, 2003  Free Software Foundation, Inc
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+/**
+ * @author Andrew Haley <aph@cygnus.com>
+ * @author Mark Wielaard <mark@klomp.org>
+ *
+ * Native helper methods for VM specific Throwable support.
+ */
+
+#include <config.h>
+#include <platform.h>
+
+#include <string.h>
+
+#include <jvm.h>
+#include <gcj/cni.h>
+#include <gnu/gcj/RawData.h>
+#include <java/lang/Object.h>
+#include <java-threads.h>
+#include <java/lang/MethodRef.h>
+#include <java/lang/StackTrace.h>
+#include <java/lang/Thread.h>
+#include <java-interp.h>
+#include <java/util/IdentityHashMap.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.h>
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+
+#include <unistd.h>
+
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+
+#include <unwind.h>
+
+
+// Fill in this stack trace with MAXLEN elements starting at offset.
+void
+java::lang::StackTrace::fillInStackTrace (jint maxlen, jint offset)
+{
+#ifdef HAVE_BACKTRACE
+  offset += 1;
+  void *_p[maxlen + offset];
+  len = backtrace (_p, maxlen + offset) - offset;
+  void **p = _p + offset;
+  _Jv_frame_info *frame;
+  if (len > 0)
+    {
+#ifdef INTERPRETER
+      extern void _Jv_StartOfInterpreter (void);
+      extern void _Jv_EndOfInterpreter (void);
+
+      java::lang::Thread *thread = java::lang::Thread::currentThread();
+      _Jv_MethodChain *interp_frame
+	= (thread ? reinterpret_cast<_Jv_MethodChain *> (thread->interp_frame)
+	   : NULL);
+#endif // INTERPRETER
+
+      frame = (_Jv_frame_info *) _Jv_Malloc (len * sizeof (_Jv_frame_info));
+      for (int n = 0; n < len; n++)
+	{
+	  frame[n].addr = p[n];
+#ifdef INTERPRETER
+	  if (p[n] >= &_Jv_StartOfInterpreter && p[n] <= &_Jv_EndOfInterpreter)
+	    {
+	      frame[n].interp = (void *) interp_frame->self;
+	      interp_frame = interp_frame->next;
+	    }
+	  else
+	    frame[n].interp = 0;
+#endif // INTERPRETER
+	}
+    }
+  else
+    frame = NULL;
+
+  addrs = reinterpret_cast<gnu::gcj::RawData *> (frame);
+#else // HAVE_BACKTRACE
+  (void)maxlen;
+  (void)offset;
+#endif // HAVE_BACKTRACE
+}
+
+/* Obtain the next power-of-2 of some integer.  */
+static inline jint
+nextpowerof2 (jint n)
+{
+  n |= (n >> 1);
+  n |= (n >> 2);
+  n |= (n >> 4);
+  n |= (n >> 8);
+  n |= (n >> 16);
+  return n+1;
+}
+
+#define GET_FRAME(N)						\
+({								\
+  if ((N) >= len)						\
+    fillInStackTrace (nextpowerof2 (N), 1);			\
+  if ((N) < 0 || (N) >= len)					\
+    throw new ::java::lang::ArrayIndexOutOfBoundsException ();	\
+								\
+  _Jv_frame_info *frame = (_Jv_frame_info *)addrs;		\
+  &frame[N];							\
+})
+
+java::lang::MethodRef *
+java::lang::StackTrace::getCompiledMethodRef (gnu::gcj::RawData *addr)
+{
+  void *p = _Unwind_FindEnclosingFunction (addr);
+  return java::lang::StackTrace::methodAtAddress ((gnu::gcj::RawData *)p);
+}
+
+java::lang::Class *
+java::lang::StackTrace::classAt (jint n)
+{
+  _Jv_frame_info *frame = GET_FRAME (n);
+
+#ifdef INTERPRETER
+  if (frame->interp)
+    {
+      _Jv_InterpMethod *meth
+	= reinterpret_cast<_Jv_InterpMethod *> (frame->interp);
+      return meth->defining_class;
+    }
+#endif // INTERPRETER
+  
+  java::lang::MethodRef *ref 
+    = getCompiledMethodRef ((gnu::gcj::RawData *)frame->addr);
+  if (ref)
+    return ref->klass;
+  else
+    return NULL;
+}
+
+java::lang::String*
+java::lang::StackTrace::methodAt (jint n)
+{
+  _Jv_frame_info *frame = GET_FRAME (n);
+  _Jv_Method *meth = NULL;
+
+#ifdef INTERPRETER
+  if (frame->interp)
+    {
+      meth
+	= reinterpret_cast<_Jv_InterpMethod *> (frame->interp)
+	->get_method();
+    }
+#endif // INTERPRETER
+  
+  if (! meth)
+    {
+      java::lang::MethodRef *ref
+	= getCompiledMethodRef ((gnu::gcj::RawData *)frame->addr);
+      if (ref)
+	meth = (_Jv_Method *)ref->method;
+    }
+
+  return meth 
+    ? _Jv_NewStringUtf8Const (meth->name)
+    : NULL ;
+}
+
+void
+java::lang::StackTrace::update(void)
+{
+  jclass klass;
+
+  while ((klass = _Jv_PopClass ()))
+    {
+      for (int i=0; i<klass->method_count; i++)
+	{
+	  JvSynchronize sync (map);
+	  _Jv_Method *meth = &(klass->methods[i]);
+	  if (meth->ncode) // i.e. if p is not abstract
+	    {
+	      java::lang::MethodRef *ref
+		= new java::lang::MethodRef 
+		((gnu::gcj::RawData *)meth, klass);
+	      map->put ((java::lang::Object*)(meth->ncode), ref);
+	    }
+	}
+    }
+}
+
+
Index: java/lang/natVMSecurityManager.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natVMSecurityManager.cc,v
retrieving revision 1.3
diff -u -r1.3 natVMSecurityManager.cc
--- java/lang/natVMSecurityManager.cc	18 Jun 2003 14:13:59 -0000	1.3
+++ java/lang/natVMSecurityManager.cc	10 Aug 2003 20:19:49 -0000
@@ -16,13 +16,13 @@
 #include <java/lang/SecurityManager.h>
 #include <java/lang/ClassLoader.h>
 #include <java/lang/Class.h>
-#include <gnu/gcj/runtime/StackTrace.h>
+#include <java/lang/StackTrace.h>
 
 JArray<jclass> *
 java::lang::VMSecurityManager::getClassContext ()
 {
   JArray<jclass> *result = NULL;
-  gnu::gcj::runtime::StackTrace *t = new gnu::gcj::runtime::StackTrace();
+  java::lang::StackTrace *t = new java::lang::StackTrace();
   if (t)
     {
       int maxlen = t->length();
Index: java/lang/reflect/natArray.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/reflect/natArray.cc,v
retrieving revision 1.12
diff -u -r1.12 natArray.cc
--- java/lang/reflect/natArray.cc	21 Jul 2003 01:54:06 -0000	1.12
+++ java/lang/reflect/natArray.cc	10 Aug 2003 20:19:49 -0000
@@ -54,8 +54,8 @@
   if (ndims == 1)
     return newInstance (componentType, dims[0]);
 
-  gnu::gcj::runtime::StackTrace *t 
-    = new gnu::gcj::runtime::StackTrace(4);
+  java::lang::StackTrace *t 
+    = new java::lang::StackTrace(4);
   Class *caller = NULL;
   ClassLoader *caller_loader = NULL;
   try
Index: java/lang/reflect/natConstructor.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/reflect/natConstructor.cc,v
retrieving revision 1.9
diff -u -r1.9 natConstructor.cc
--- java/lang/reflect/natConstructor.cc	21 Jul 2003 01:54:06 -0000	1.9
+++ java/lang/reflect/natConstructor.cc	10 Aug 2003 20:19:49 -0000
@@ -48,8 +48,8 @@
   if (parameter_types == NULL)
     getType ();
 
-  gnu::gcj::runtime::StackTrace *t 
-    = new gnu::gcj::runtime::StackTrace(4);
+  java::lang::StackTrace *t 
+    = new java::lang::StackTrace(4);
   Class *caller = NULL;
   try
     {
Index: java/lang/reflect/natField.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/reflect/natField.cc,v
retrieving revision 1.14
diff -u -r1.14 natField.cc
--- java/lang/reflect/natField.cc	5 Aug 2003 20:06:57 -0000	1.14
+++ java/lang/reflect/natField.cc	10 Aug 2003 20:19:49 -0000
@@ -58,8 +58,8 @@
   // have the compiler insert the caller as a hidden argument in some
   // calls.  However, we never implemented that, so we have to find
   // the caller by hand instead.
-  gnu::gcj::runtime::StackTrace *t 
-    = new gnu::gcj::runtime::StackTrace(7);
+  java::lang::StackTrace *t 
+    = new java::lang::StackTrace(7);
   try
     {
       // We want to skip all the frames on the stack from this class.
Index: java/lang/reflect/natMethod.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/reflect/natMethod.cc,v
retrieving revision 1.32
diff -u -r1.32 natMethod.cc
--- java/lang/reflect/natMethod.cc	21 Jul 2003 01:54:06 -0000	1.32
+++ java/lang/reflect/natMethod.cc	10 Aug 2003 20:19:50 -0000
@@ -143,8 +143,8 @@
   if (parameter_types == NULL)
     getType ();
 
-  gnu::gcj::runtime::StackTrace *t 
-    = new gnu::gcj::runtime::StackTrace(4);
+  java::lang::StackTrace *t 
+    = new java::lang::StackTrace(4);
   Class *caller = NULL;
   try
     {
Index: java/util/natResourceBundle.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/util/natResourceBundle.cc,v
retrieving revision 1.7
diff -u -r1.7 natResourceBundle.cc
--- java/util/natResourceBundle.cc	21 Jan 2003 21:16:46 -0000	1.7
+++ java/util/natResourceBundle.cc	10 Aug 2003 20:19:50 -0000
@@ -17,12 +17,12 @@
 #include <java/lang/ClassLoader.h>
 #include <java/lang/Class.h>
 #include <java/lang/ArrayIndexOutOfBoundsException.h>
-#include <gnu/gcj/runtime/StackTrace.h>
+#include <java/lang/StackTrace.h>
 
 java::lang::ClassLoader *
 java::util::ResourceBundle::getCallingClassLoader ()
 {
-  gnu::gcj::runtime::StackTrace *t = new gnu::gcj::runtime::StackTrace(6);
+  java::lang::StackTrace *t = new java::lang::StackTrace(6);
   try
     {
       /* Frame 0 is this method, frame 1 is getBundle, so starting at

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