OSDN Git Service

2006-05-04 Andrew Haley <aph@redhat.com>
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 4 May 2006 18:44:53 +0000 (18:44 +0000)
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 4 May 2006 18:44:53 +0000 (18:44 +0000)
        * class.c (make_field_value): Always build_address_of fdecl if
        there is an initializer.

2006-05-03  Andrew Haley  <aph@redhat.com>

        PR libgcj/27352
        * expr.c (maybe_rewrite_invocation): New function.
        (rewrite_arglist_getclass): Likewise.
        (rules): New.
        (expand_invoke): Call maybe_rewrite_invocation.
        * parse.y (patch_invoke): Likewise.
        * java-tree.h: (maybe_rewrite_invocation): New function.

2006-05-03  Andrew Haley  <aph@redhat.com>

        PR libgcj/27352
        * java/lang/Class.java (getClassLoader(Class)): New.
        forName(String, Class): New.
        * java/lang/natClass.cc (getClassLoader(Class)): New.

2006-05-02  Andrew Haley  <aph@redhat.com>

        * prims.cc (_Jv_NewMultiArray): Check for phantom class.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@113532 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/java/ChangeLog
gcc/java/class.c
gcc/java/expr.c
gcc/java/java-tree.h
gcc/java/parse.y
libjava/ChangeLog
libjava/java/lang/Class.h
libjava/java/lang/Class.java
libjava/java/lang/natClass.cc
libjava/prims.cc

index 2ce57c0..93deeb2 100644 (file)
@@ -1,3 +1,18 @@
+2006-05-04  Andrew Haley  <aph@redhat.com>
+
+       * class.c (make_field_value): Always build_address_of fdecl if
+       there is an initializer.
+
+2006-05-03  Andrew Haley  <aph@redhat.com>
+
+       PR libgcj/27352
+       * expr.c (maybe_rewrite_invocation): New function.
+       (rewrite_arglist_getclass): Likewise.
+       (rules): New.
+       (expand_invoke): Call maybe_rewrite_invocation.
+       * parse.y (patch_invoke): Likewise.
+       * java-tree.h: (maybe_rewrite_invocation): New function.
+
 2006-04-21  Andrew Haley  <aph@redhat.com>
 
        * lang.c (java_init): Handle flag_indirect_classes.
index fe52e67..590925d 100644 (file)
@@ -1344,7 +1344,8 @@ make_field_value (tree fdecl)
 
   {
     tree field_address = integer_zero_node;
-    if (! flag_indirect_classes && FIELD_STATIC (fdecl))
+    if ((DECL_INITIAL (fdecl) || ! flag_indirect_classes) 
+       && FIELD_STATIC (fdecl))
       field_address = build_address_of (fdecl);
 
     PUSH_FIELD_VALUE
index 1cd405a..b2e03fc 100644 (file)
@@ -2020,6 +2020,86 @@ build_class_init (tree clas, tree expr)
   return init;
 }
 
+\f
+
+/* Rewrite expensive calls that require stack unwinding at runtime to
+   cheaper alternatives.  The logic here performs thse
+   transformations:
+
+   java.lang.Class.forName("foo") -> java.lang.Class.forName("foo", class$)
+   java.lang.Class.getClassLoader() -> java.lang.Class.getClassLoader(class$)
+
+*/
+
+typedef struct
+{
+  const char *classname;
+  const char *method;
+  const char *signature;
+  const char *new_signature;
+  int flags;
+  tree (*rewrite_arglist) (tree arglist);
+} rewrite_rule;
+
+/* Add this.class to the end of an arglist.  */
+
+static tree 
+rewrite_arglist_getclass (tree arglist)
+{
+  return chainon (arglist, 
+                 tree_cons (NULL_TREE, build_class_ref (output_class), NULL_TREE));
+}
+
+static rewrite_rule rules[] =
+  {{"java.lang.Class", "getClassLoader", "()Ljava/lang/ClassLoader;", 
+    "(Ljava/lang/Class;)Ljava/lang/ClassLoader;", 
+    ACC_FINAL|ACC_PRIVATE, rewrite_arglist_getclass},
+   {"java.lang.Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;",
+    "(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
+    ACC_FINAL|ACC_PRIVATE|ACC_STATIC, rewrite_arglist_getclass},
+   {NULL, NULL, NULL, NULL, 0, NULL}};
+
+/* Scan the rules list for replacements for *METHOD_P and replace the
+   args accordingly.  */
+
+void
+maybe_rewrite_invocation (tree *method_p, tree *arg_list_p, 
+                         tree *method_signature_p)
+{
+  tree context = DECL_NAME (TYPE_NAME (DECL_CONTEXT (*method_p)));
+  rewrite_rule *p;
+  for (p = rules; p->classname; p++)
+    {
+      if (get_identifier (p->classname) == context)
+       {
+         tree method = DECL_NAME (*method_p);
+         if (get_identifier (p->method) == method
+             && get_identifier (p->signature) == *method_signature_p)
+           {
+             tree maybe_method
+               = lookup_java_method (DECL_CONTEXT (*method_p),
+                                     method,
+                                     get_identifier (p->new_signature));
+             if (! maybe_method && ! flag_verify_invocations)
+               {
+                 maybe_method
+                   = add_method (DECL_CONTEXT (*method_p), p->flags, 
+                                 method, get_identifier (p->new_signature));
+                 DECL_EXTERNAL (maybe_method) = 1;
+               }
+             *method_p = maybe_method;
+             gcc_assert (*method_p);
+             *arg_list_p = p->rewrite_arglist (*arg_list_p);
+             *method_signature_p = get_identifier (p->new_signature);
+
+             break;
+           }
+       }
+    }
+}
+
+\f
+
 tree
 build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
                        tree self_type, tree method_signature ATTRIBUTE_UNUSED,
@@ -2394,6 +2474,8 @@ expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
   arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
   flush_quick_stack ();
 
+  maybe_rewrite_invocation (&method, &arg_list, &method_signature);
+
   func = NULL_TREE;
   if (opcode == OPCODE_invokestatic)
     func = build_known_method_ref (method, method_type, self_type,
index 03a7ea2..de826b9 100644 (file)
@@ -1241,6 +1241,7 @@ extern tree check_for_builtin (tree, tree);
 extern void initialize_builtins (void);
 
 extern tree lookup_name (tree);
+extern void maybe_rewrite_invocation (tree *, tree *, tree *);
 extern tree build_known_method_ref (tree, tree, tree, tree, tree);
 extern tree build_class_init (tree, tree);
 extern int attach_init_test_initialization_flags (void **, void *);
index 118c66f..a606d87 100644 (file)
@@ -11066,6 +11066,7 @@ patch_invoke (tree patch, tree method, tree args)
        case INVOKE_STATIC:
          {
            tree signature = build_java_signature (TREE_TYPE (method));
+           maybe_rewrite_invocation (&method, &args, &signature);
            func = build_known_method_ref (method, TREE_TYPE (method),
                                           DECL_CONTEXT (method),
                                           signature, args);
index 161adfc..19c06e1 100644 (file)
@@ -1,3 +1,14 @@
+2006-05-03  Andrew Haley  <aph@redhat.com>
+
+       PR libgcj/27352
+       * java/lang/Class.java (getClassLoader(Class)): New.
+       forName(String, Class): New.
+       * java/lang/natClass.cc (getClassLoader(Class)): New.
+       
+2006-05-02  Andrew Haley  <aph@redhat.com>
+
+       * prims.cc (_Jv_NewMultiArray): Check for phantom class.
+
 2006-05-04  Tom Tromey  <tromey@redhat.com>
 
        PR libgcj/26861:
index 7221294..f6ca3de 100644 (file)
@@ -297,6 +297,8 @@ public:
   JArray<jclass> *getClasses (void);
 
   java::lang::ClassLoader *getClassLoader (void);
+private:
+  java::lang::ClassLoader *getClassLoader (jclass caller);
 public:
   // This is an internal method that circumvents the usual security
   // checks when getting the class loader.
index 60ca457..66b85c7 100644 (file)
@@ -111,6 +111,14 @@ public final class Class implements Serializable
   public static native Class forName (String className)
     throws ClassNotFoundException;
 
+  // A private internal method that is called by compiler-generated code.
+  private static Class forName (String className, Class caller)
+    throws ClassNotFoundException
+  {
+    return forName(className, true, caller.getClassLoader());
+  }
+
+
   /**
    * Use the specified classloader to load and link a class. If the loader
    * is null, this uses the bootstrap class loader (provide the security
@@ -185,6 +193,9 @@ public final class Class implements Serializable
    */
   public native ClassLoader getClassLoader ();
   
+  // A private internal method that is called by compiler-generated code.
+  private final native ClassLoader getClassLoader (Class caller);
+  
   /**
    * If this is an array, get the Class representing the type of array.
    * Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and
index d888350..8870889 100644 (file)
@@ -115,9 +115,19 @@ java::lang::Class::getClassLoader (void)
   if (s != NULL)
     {
       jclass caller = _Jv_StackTrace::GetCallingClass (&Class::class$);
-      ClassLoader *caller_loader = NULL;
-      if (caller)
-       caller_loader = caller->getClassLoaderInternal();
+      return getClassLoader (caller);
+   }
+
+  return loader;
+}
+
+java::lang::ClassLoader *
+java::lang::Class::getClassLoader (jclass caller)
+{
+  java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
+  if (s != NULL)
+    {
+      ClassLoader *caller_loader = caller->getClassLoaderInternal();
 
       // If the caller has a non-null class loader, and that loader
       // is not this class' loader or an ancestor thereof, then do a
index 5e016c9..e0cdc0a 100644 (file)
@@ -762,6 +762,11 @@ _Jv_NewMultiArray (jclass type, jint dimensions, jint *sizes)
 jobject
 _Jv_NewMultiArray (jclass array_type, jint dimensions, ...)
 {
+  // Creating an array of an unresolved type is impossible. So we throw
+  // the NoClassDefFoundError.
+  if (_Jv_IsPhantomClass(array_type))
+    throw new java::lang::NoClassDefFoundError(array_type->getName());
+
   va_list args;
   jint sizes[dimensions];
   va_start (args, dimensions);