OSDN Git Service

2004-01-09 Andrew Haley <aph@redhat.com>
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Jan 2004 17:08:44 +0000 (17:08 +0000)
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 9 Jan 2004 17:08:44 +0000 (17:08 +0000)
PR java/12755:
* parse.y (java_fix_constructors):  Set output_class.
(java_reorder_fields): Likewise.
(java_layout_classes): Likewise.
(java_expand_classes): Generate indirect dispatch tables.
(java_expand_classes): Set output_class.
(java_finish_classes): Likewise.
* lang.c (java_init): Turn on always_initialize_class_p if we're
using indirect dis[atch.
(java_decl_ok_for_sibcall): Use output_class, not current_class.
(java_get_callee_fndecl): Use class local atable.
* jcf-parse.c
(always_initialize_class_p): Decl moved to java-tree.h.
(HANDLE_CLASS_INFO): Set output_class.
(read_class): Likewise.
(parse_class_file): Call gen_indirect_dispatch_tables.
(parse_zip_file_entries): Set output_class.
(java_parse_file): Set output_class.  Don't emit symbol tables.
* java-tree.h (output_class): New.
Remove global declarations for otable, atable, and ctable.
(always_initialize_class_p): moved here from decl.c.
(DECL_OWNER): New.
(TYPE_ATABLE_METHODS, TYPE_ATABLE_SYMS_DECL, TYPE_ATABLE_DECL,
TYPE_OTABLE_METHODS, TYPE_OTABLE_SYMS_DECL, TYPE_OTABLE_DECL,
TYPE_CTABLE_DECL, TYPE_CATCH_CLASSES): New.
(struct lang_type): Add otable_methods, otable_decl,
otable_syms_decl, atable_methods, atable_decl, atable_syms_decl,
ctable_decl, catch_classes, type_to_runtime_map.
* expr.c (build_field_ref): Make otable, atable, and ctable class
local rather than global.
(build_known_method_ref): Likewise.
(build_invokeinterface): Likewise.
(java_expand_expr): Pass runtime type (rather than actual type) to
expand_start_catch.
* except.c (prepare_eh_table_type): Create TYPE_TO_RUNTIME_MAP for
this class.  Look up each class in that map to delete duplicates.
(expand_end_java_handler): Pass runtime type (rather than actual
type) to expand_start_catch.
* decl.c: (always_initialize_class_p): Decl moved to java-tree.h.
(do_nothing): New.
(java_init_decl_processing): Rearrange things.  Remove global
declarations of otable, atable, and ctable.
(java_init_decl_processing): Make lang_eh_runtime_type do_nothing.
(java_expand_body): Set output_class.
* constants.c (build_constant_data_ref): Use output_class, not
current_class.
(alloc_name_constant): Likewise.
* class.c (gen_indirect_dispatch_tables): New.
(build_class_ref): Generate hard reference to superclass, even if
using indirect dispatch.
(build_static_field_ref): Use class local atable.
(make_class_data): Generate hard reference to superclass, even if
using indirect dispatch.
Generate symbolic references to interfaces when using indirect
dispatch.
(make_class_data): Emit otable, atable, and ctable.
Make otable, atable, and ctable class local rather than global.
(emit_catch_table): Make otable, atable, and ctable class local
rather than global.

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

gcc/java/ChangeLog
gcc/java/class.c
gcc/java/constants.c
gcc/java/decl.c
gcc/java/except.c
gcc/java/expr.c
gcc/java/java-tree.h
gcc/java/jcf-parse.c
gcc/java/lang.c
gcc/java/parse.y

index 2fa7728..a0cee42 100644 (file)
@@ -1,3 +1,65 @@
+2004-01-09  Andrew Haley  <aph@redhat.com>
+
+       PR java/12755:
+       * parse.y (java_fix_constructors):  Set output_class.
+       (java_reorder_fields): Likewise.
+       (java_layout_classes): Likewise.
+       (java_expand_classes): Generate indirect dispatch tables.
+       (java_expand_classes): Set output_class.
+       (java_finish_classes): Likewise.
+       * lang.c (java_init): Turn on always_initialize_class_p if we're
+       using indirect dis[atch.
+       (java_decl_ok_for_sibcall): Use output_class, not current_class.
+       (java_get_callee_fndecl): Use class local atable.
+       * jcf-parse.c 
+       (always_initialize_class_p): Decl moved to java-tree.h.
+       (HANDLE_CLASS_INFO): Set output_class.
+       (read_class): Likewise.
+       (parse_class_file): Call gen_indirect_dispatch_tables.
+       (parse_zip_file_entries): Set output_class.
+       (java_parse_file): Set output_class.  Don't emit symbol tables.
+       * java-tree.h (output_class): New.
+       Remove global declarations for otable, atable, and ctable.
+       (always_initialize_class_p): moved here from decl.c.
+       (DECL_OWNER): New.
+       (TYPE_ATABLE_METHODS, TYPE_ATABLE_SYMS_DECL, TYPE_ATABLE_DECL,
+       TYPE_OTABLE_METHODS, TYPE_OTABLE_SYMS_DECL, TYPE_OTABLE_DECL,
+       TYPE_CTABLE_DECL, TYPE_CATCH_CLASSES): New.
+       (struct lang_type): Add otable_methods, otable_decl,
+       otable_syms_decl, atable_methods, atable_decl, atable_syms_decl,
+       ctable_decl, catch_classes, type_to_runtime_map.
+       * expr.c (build_field_ref): Make otable, atable, and ctable class
+       local rather than global.
+       (build_known_method_ref): Likewise.
+       (build_invokeinterface): Likewise.
+       (java_expand_expr): Pass runtime type (rather than actual type) to
+       expand_start_catch.
+       * except.c (prepare_eh_table_type): Create TYPE_TO_RUNTIME_MAP for
+       this class.  Look up each class in that map to delete duplicates.
+       (expand_end_java_handler): Pass runtime type (rather than actual
+       type) to expand_start_catch.
+       * decl.c: (always_initialize_class_p): Decl moved to java-tree.h.
+       (do_nothing): New.
+       (java_init_decl_processing): Rearrange things.  Remove global
+       declarations of otable, atable, and ctable.
+       (java_init_decl_processing): Make lang_eh_runtime_type do_nothing.
+       (java_expand_body): Set output_class.
+       * constants.c (build_constant_data_ref): Use output_class, not
+       current_class.
+       (alloc_name_constant): Likewise.
+       * class.c (gen_indirect_dispatch_tables): New.
+       (build_class_ref): Generate hard reference to superclass, even if
+       using indirect dispatch.
+       (build_static_field_ref): Use class local atable.
+       (make_class_data): Generate hard reference to superclass, even if
+       using indirect dispatch.
+       Generate symbolic references to interfaces when using indirect
+       dispatch.
+       (make_class_data): Emit otable, atable, and ctable.
+       Make otable, atable, and ctable class local rather than global.
+       (emit_catch_table): Make otable, atable, and ctable class local
+       rather than global.
+               
 2003-12-25  Andrew Pinski  <pinskia@physics.uc.edu>
 
        * parse.y (catch_clause_parameter): Fix typo.
index 6c772e0..bf9f79e 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions related to building classes and their related objects.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -42,6 +42,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "ggc.h"
 #include "stdio.h"
 #include "target.h"
+#include "except.h"
 
 /* DOS brain-damage */
 #ifndef O_BINARY
@@ -304,6 +305,83 @@ unmangle_classname (const char *name, int name_length)
   return to_return;
 }
 
+
+/* Given a class, create the DECLs for all its associated indirect dispatch tables.  */
+void
+gen_indirect_dispatch_tables (tree type)
+{
+  const char *typename = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+  {  
+    tree field = NULL;
+    char *buf = alloca (strlen (typename) + strlen ("_catch_classes_"));
+    tree catch_class_type = make_node (RECORD_TYPE);
+
+    sprintf (buf, "_catch_classes_%s", typename);
+    PUSH_FIELD (catch_class_type, field, "address", utf8const_ptr_type);
+    PUSH_FIELD (catch_class_type, field, "classname", ptr_type_node);
+    FINISH_RECORD (catch_class_type);
+    
+    TYPE_CTABLE_DECL (type) 
+      = build_decl (VAR_DECL, get_identifier (buf),
+                   build_array_type (catch_class_type, 0));
+    DECL_EXTERNAL (TYPE_CTABLE_DECL (type)) = 1;
+    TREE_STATIC (TYPE_CTABLE_DECL (type)) = 1;
+    TREE_READONLY (TYPE_CTABLE_DECL (type)) = 1;
+    TREE_CONSTANT (TYPE_CTABLE_DECL (type)) = 1;
+    DECL_IGNORED_P (TYPE_CTABLE_DECL (type)) = 1;
+    pushdecl (TYPE_CTABLE_DECL (type));  
+  }
+
+  if (flag_indirect_dispatch)
+    {
+      {
+       char *buf = alloca (strlen (typename) + strlen ("_otable_syms_"));
+
+       sprintf (buf, "_otable_%s", typename);
+       TYPE_OTABLE_DECL (type) = 
+         build_decl (VAR_DECL, get_identifier (buf), otable_type);
+       DECL_EXTERNAL (TYPE_OTABLE_DECL (type)) = 1;
+       TREE_STATIC (TYPE_OTABLE_DECL (type)) = 1;
+       TREE_READONLY (TYPE_OTABLE_DECL (type)) = 1;
+       TREE_CONSTANT (TYPE_OTABLE_DECL (type)) = 1;
+       DECL_IGNORED_P (TYPE_OTABLE_DECL (type)) = 1;
+       pushdecl (TYPE_OTABLE_DECL (type));  
+       sprintf (buf, "_otable_syms_%s", typename);
+       TYPE_OTABLE_SYMS_DECL (type) = 
+         build_decl (VAR_DECL, get_identifier (buf), symbols_array_type);
+       TREE_STATIC (TYPE_OTABLE_SYMS_DECL (type)) = 1;
+       TREE_CONSTANT (TYPE_OTABLE_SYMS_DECL (type)) = 1;
+       DECL_IGNORED_P(TYPE_OTABLE_SYMS_DECL (type)) = 1;
+       pushdecl (TYPE_OTABLE_SYMS_DECL (type));
+      }
+
+      {
+       char *buf = alloca (strlen (typename) + strlen ("_atable_syms_"));
+       tree decl;
+
+       sprintf (buf, "_atable_%s", typename);
+       TYPE_ATABLE_DECL (type) = decl =
+         build_decl (VAR_DECL, get_identifier (buf), atable_type);
+       DECL_EXTERNAL (decl) = 1;
+       TREE_STATIC (decl) = 1;
+       TREE_READONLY (decl) = 1;
+       TREE_CONSTANT (decl) = 1;
+       DECL_IGNORED_P (decl) = 1;
+       /* Mark the atable as belonging to this class.  */
+       pushdecl (decl);  
+       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
+       DECL_OWNER (decl) = type;
+       sprintf (buf, "_atable_syms_%s", typename);
+       TYPE_ATABLE_SYMS_DECL (type) = 
+         build_decl (VAR_DECL, get_identifier (buf), symbols_array_type);
+       TREE_STATIC (TYPE_ATABLE_SYMS_DECL (type)) = 1;
+       TREE_CONSTANT (TYPE_ATABLE_SYMS_DECL (type)) = 1;
+       DECL_IGNORED_P (TYPE_ATABLE_SYMS_DECL (type)) = 1;
+       pushdecl (TYPE_ATABLE_SYMS_DECL (type));
+      }
+    }
+}
+
 tree
 push_class (tree class_type, tree class_name)
 {
@@ -835,8 +913,13 @@ build_class_ref (tree type)
       if (TREE_CODE (type) == POINTER_TYPE)
        type = TREE_TYPE (type);
 
-      if  (flag_indirect_dispatch 
-          && type != current_class
+      /* FIXME: we really want an indirect reference to our
+        superclass.  However, libgcj assumes that a superclass
+        pointer always points directly to a class.  As a workaround
+        we always emit this hard superclass reference.  */
+      if  (flag_indirect_dispatch
+          && type != output_class
+          && type != CLASSTYPE_SUPER (output_class)
           && TREE_CODE (type) == RECORD_TYPE)
        return build_indirect_class_ref (type);
 
@@ -957,10 +1040,11 @@ build_static_field_ref (tree fdecl)
   if (flag_indirect_dispatch)
     {
       tree table_index 
-       = build_int_2 (get_symbol_table_index (fdecl, &atable_methods), 0);
+       = build_int_2 (get_symbol_table_index 
+                      (fdecl, &TYPE_ATABLE_METHODS (output_class)), 0);
       tree field_address
        = build (ARRAY_REF, build_pointer_type (TREE_TYPE (fdecl)), 
-                atable_decl, table_index);
+                TYPE_ATABLE_DECL (output_class), table_index);
       return fold (build1 (INDIRECT_REF, TREE_TYPE (fdecl), 
                           field_address));
     }
@@ -1435,8 +1519,10 @@ make_class_data (tree type)
   super = CLASSTYPE_SUPER (type);
   if (super == NULL_TREE)
     super = null_pointer_node;
-  else if (! flag_indirect_dispatch
-          && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
+  else if (/* FIXME: we should also test for (!
+             flag_indirect_dispatch) here, but libgcj can't cope with
+             a symbolic reference a superclass in the class data.  */
+          assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
           && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (super)))))
     super = build_class_ref (super);
   else
@@ -1463,13 +1549,15 @@ make_class_data (tree type)
          tree child = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), i);
          tree iclass = BINFO_TYPE (child);
          tree index;
-         if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (iclass)))))
+         if (! flag_indirect_dispatch
+             && (assume_compiled 
+                 (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (iclass))))))
            index = build_class_ref (iclass);
          else
            {
-               int int_index = alloc_class_constant (iclass);
-               index = build_int_2 (int_index, 0);
-               TREE_TYPE (index) = ptr_type_node;
+             int int_index = alloc_class_constant (iclass);
+             index = build_int_2 (int_index, 0);
+             TREE_TYPE (index) = ptr_type_node;
            }
          init = tree_cons (NULL_TREE, index, init); 
        }
@@ -1483,6 +1571,23 @@ make_class_data (tree type)
 
   constant_pool_constructor = build_constants_constructor ();
 
+  if (flag_indirect_dispatch)
+    {
+      TYPE_OTABLE_DECL (type) 
+       = emit_symbol_table 
+       (DECL_NAME (TYPE_OTABLE_DECL (type)), 
+        TYPE_OTABLE_DECL (type), TYPE_OTABLE_METHODS (type), 
+        TYPE_OTABLE_SYMS_DECL (type), integer_type_node);
+       
+      TYPE_ATABLE_DECL (type) 
+       = emit_symbol_table 
+       (DECL_NAME (TYPE_ATABLE_DECL (type)), 
+        TYPE_ATABLE_DECL (type), TYPE_ATABLE_METHODS (type), 
+        TYPE_ATABLE_SYMS_DECL (type), ptr_type_node);
+    }
+  
+  TYPE_CTABLE_DECL (type) = emit_catch_table (type);
+
   START_RECORD_CONSTRUCTOR (temp, object_type_node);
   PUSH_FIELD_VALUE (temp, "vtable",
                    build (PLUS_EXPR, dtable_ptr_type,
@@ -1526,7 +1631,7 @@ make_class_data (tree type)
                      : build (PLUS_EXPR, dtable_ptr_type,
                               build1 (ADDR_EXPR, dtable_ptr_type, dtable_decl),
                               dtable_start_offset));
-  if (otable_methods == NULL_TREE)
+  if (TYPE_OTABLE_METHODS (type) == NULL_TREE)
     {
       PUSH_FIELD_VALUE (cons, "otable", null_pointer_node);
       PUSH_FIELD_VALUE (cons, "otable_syms", null_pointer_node);
@@ -1534,13 +1639,13 @@ make_class_data (tree type)
   else
     {
       PUSH_FIELD_VALUE (cons, "otable",
-                       build1 (ADDR_EXPR, otable_ptr_type, otable_decl));
+                       build1 (ADDR_EXPR, otable_ptr_type, TYPE_OTABLE_DECL (type)));
       PUSH_FIELD_VALUE (cons, "otable_syms",
                        build1 (ADDR_EXPR, symbols_array_ptr_type,
-                               otable_syms_decl));
-      TREE_CONSTANT (otable_decl) = 1;
-    }
-  if (atable_methods == NULL_TREE)
+                               TYPE_OTABLE_SYMS_DECL (type)));
+      TREE_CONSTANT (TYPE_OTABLE_DECL (type)) = 1;
+    } 
+  if (TYPE_ATABLE_METHODS(type) == NULL_TREE)
     {
       PUSH_FIELD_VALUE (cons, "atable", null_pointer_node);
       PUSH_FIELD_VALUE (cons, "atable_syms", null_pointer_node);
@@ -1548,15 +1653,15 @@ make_class_data (tree type)
   else
     {
       PUSH_FIELD_VALUE (cons, "atable",
-                       build1 (ADDR_EXPR, atable_ptr_type, atable_decl));
+                       build1 (ADDR_EXPR, atable_ptr_type, TYPE_ATABLE_DECL (type)));
       PUSH_FIELD_VALUE (cons, "atable_syms",
                        build1 (ADDR_EXPR, symbols_array_ptr_type,
-                               atable_syms_decl));
-      TREE_CONSTANT (atable_decl) = 1;
+                               TYPE_ATABLE_SYMS_DECL (type)));
+      TREE_CONSTANT (TYPE_ATABLE_DECL (type)) = 1;
     }
  
   PUSH_FIELD_VALUE (cons, "catch_classes",
-                   build1 (ADDR_EXPR, ptr_type_node, ctable_decl)); 
+                   build1 (ADDR_EXPR, ptr_type_node, TYPE_CTABLE_DECL (type))); 
   PUSH_FIELD_VALUE (cons, "interfaces", interfaces);
   PUSH_FIELD_VALUE (cons, "loader", null_pointer_node);
   PUSH_FIELD_VALUE (cons, "interface_count", build_int_2 (interface_len, 0));
@@ -1616,6 +1721,8 @@ finish_class (void)
       method = TREE_CHAIN (method);
     }
 
+  java_expand_catch_classes (current_class);
+
   current_function_decl = NULL_TREE;
   make_class_data (current_class);
   register_class ();
@@ -2231,7 +2338,7 @@ tree
 make_catch_class_record (tree catch_class, tree classname)
 {
   tree entry;
-  tree type = TREE_TYPE (TREE_TYPE (ctable_decl));
+  tree type = TREE_TYPE (TREE_TYPE (TYPE_CTABLE_DECL (output_class)));
   START_RECORD_CONSTRUCTOR (entry, type);
   PUSH_FIELD_VALUE (entry, "address", catch_class);
   PUSH_FIELD_VALUE (entry, "classname", classname);
@@ -2241,29 +2348,35 @@ make_catch_class_record (tree catch_class, tree classname)
 
 
 /* Generate the list of Throwable classes that are caught by exception
-   handlers in this compilation.  */
-void 
-emit_catch_table (void)
+   handlers in this class.  */
+tree 
+emit_catch_table (tree this_class)
 {
   tree table, table_size, array_type;
-  catch_classes 
-    = tree_cons (NULL, 
-                make_catch_class_record (null_pointer_node, null_pointer_node),
-                catch_classes);
-  catch_classes = nreverse (catch_classes);
-  catch_classes 
-    = tree_cons (NULL, 
-                make_catch_class_record (null_pointer_node, null_pointer_node),
-                catch_classes);
-  table_size = build_index_type (build_int_2 (list_length (catch_classes), 0));
+  TYPE_CATCH_CLASSES (this_class) =
+    tree_cons (NULL,
+              make_catch_class_record (null_pointer_node, null_pointer_node),
+              TYPE_CATCH_CLASSES (this_class));
+  TYPE_CATCH_CLASSES (this_class) = nreverse (TYPE_CATCH_CLASSES (this_class));
+  TYPE_CATCH_CLASSES (this_class) = 
+    tree_cons (NULL,
+              make_catch_class_record (null_pointer_node, null_pointer_node),
+              TYPE_CATCH_CLASSES (this_class));
+  table_size = 
+    build_index_type (build_int_2 
+                     (list_length (TYPE_CATCH_CLASSES (this_class)), 0));
   array_type 
-    = build_array_type (TREE_TYPE (TREE_TYPE (ctable_decl)), table_size);
-  table = build_decl (VAR_DECL, DECL_NAME (ctable_decl), array_type);
-  DECL_INITIAL (table) = build_constructor (array_type, catch_classes);
+    = build_array_type (TREE_TYPE (TREE_TYPE (TYPE_CTABLE_DECL (this_class))),
+                       table_size);
+  table = 
+    build_decl (VAR_DECL, DECL_NAME (TYPE_CTABLE_DECL (this_class)), array_type);
+  DECL_INITIAL (table) = 
+    build_constructor (array_type, TYPE_CATCH_CLASSES (this_class));
   TREE_STATIC (table) = 1;
   TREE_READONLY (table) = 1;  
+  DECL_IGNORED_P (table) = 1;
   rest_of_decl_compilation (table, NULL, 1, 0);
-  ctable_decl = table;
+  return table;
 }
  
 
index 8a1fe1b..d97e8c0 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle the constant pool of the Java(TM) Virtual Machine.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -351,7 +351,7 @@ cpool_for_class (tree class)
 int
 alloc_name_constant (int tag, tree name)
 {
-  CPool *outgoing_cpool = cpool_for_class (current_class);
+  CPool *outgoing_cpool = cpool_for_class (output_class);
   return find_tree_constant (outgoing_cpool, tag, name);
 }
 
@@ -393,19 +393,19 @@ build_constant_data_ref (void)
 {
   tree cpool_data_ref = NULL_TREE;
 
-  if (TYPE_CPOOL_DATA_REF (current_class))
-    cpool_data_ref = TYPE_CPOOL_DATA_REF (current_class);
+  if (TYPE_CPOOL_DATA_REF (output_class))
+    cpool_data_ref = TYPE_CPOOL_DATA_REF (output_class);
 
   if (cpool_data_ref == NULL_TREE)
     {
       tree decl;
-      tree decl_name = mangled_classname ("_CD_", current_class);
+      tree decl_name = mangled_classname ("_CD_", output_class);
       decl = build_decl (VAR_DECL, decl_name,
                         build_array_type (ptr_type_node,
                                           one_elt_array_domain_type));
       TREE_STATIC (decl) = 1;
       make_decl_rtl (decl, NULL);
-      TYPE_CPOOL_DATA_REF (current_class) = cpool_data_ref
+      TYPE_CPOOL_DATA_REF (output_class) = cpool_data_ref
        = build1 (ADDR_EXPR, ptr_type_node, decl);
     }
   return cpool_data_ref;
index 46bb224..1ce2ad3 100644 (file)
@@ -1,6 +1,6 @@
 /* Process declarations and variables for the GNU compiler for the
    Java(TM) language.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -64,10 +64,6 @@ tree java_lang_cloneable_identifier_node;
 /* Name of the Serializable class.  */
 tree java_io_serializable_identifier_node;
 
-/* Set to nonzero value in order to emit class initialization code
-   before static field references.  */
-extern int always_initialize_class_p;
-
 /* The DECL_MAP is a mapping from (index, type) to a decl node.
    If index < max_locals, it is the index of a local variable.
    if index >= max_locals, then index-max_locals is a stack slot.
@@ -389,6 +385,13 @@ create_primitive_vtable (const char *name)
   return r;
 }
 
+static tree
+do_nothing (tree t)
+{
+  return t;
+}
+
+
 void
 java_init_decl_processing (void)
 {
@@ -538,6 +541,28 @@ java_init_decl_processing (void)
   float_array_vtable = create_primitive_vtable ("float");
   double_array_vtable = create_primitive_vtable ("double");
 
+  one_elt_array_domain_type = build_index_type (integer_one_node);
+  utf8const_type = make_node (RECORD_TYPE);
+  PUSH_FIELD (utf8const_type, field, "hash", unsigned_short_type_node);
+  PUSH_FIELD (utf8const_type, field, "length", unsigned_short_type_node);
+  FINISH_RECORD (utf8const_type);
+  utf8const_ptr_type = build_pointer_type (utf8const_type);
+
+  atable_type = build_array_type (ptr_type_node, 
+                                 one_elt_array_domain_type);
+  TYPE_NONALIASED_COMPONENT (atable_type) = 1;
+  atable_ptr_type = build_pointer_type (atable_type);
+
+  symbol_type = make_node (RECORD_TYPE);
+  PUSH_FIELD (symbol_type, field, "clname", utf8const_ptr_type);
+  PUSH_FIELD (symbol_type, field, "name", utf8const_ptr_type);
+  PUSH_FIELD (symbol_type, field, "signature", utf8const_ptr_type);
+  FINISH_RECORD (symbol_type);
+
+  symbols_array_type = build_array_type (symbol_type, 
+                                        one_elt_array_domain_type);
+  symbols_array_ptr_type = build_pointer_type (symbols_array_type);
+
   /* As you're adding items here, please update the code right after
      this section, so that the filename containing the source code of
      the pre-defined class gets registered correctly. */
@@ -595,12 +620,6 @@ java_init_decl_processing (void)
   /* for lack of a better place to put this stub call */
   init_expr_processing();
 
-  utf8const_type = make_node (RECORD_TYPE);
-  PUSH_FIELD (utf8const_type, field, "hash", unsigned_short_type_node);
-  PUSH_FIELD (utf8const_type, field, "length", unsigned_short_type_node);
-  FINISH_RECORD (utf8const_type);
-  utf8const_ptr_type = build_pointer_type (utf8const_type);
-
   constants_type_node = make_node (RECORD_TYPE);
   PUSH_FIELD (constants_type_node, field, "size", unsigned_int_type_node);
   PUSH_FIELD (constants_type_node, field, "tags", ptr_type_node);
@@ -613,69 +632,10 @@ java_init_decl_processing (void)
   dtable_type = make_node (RECORD_TYPE);
   dtable_ptr_type = build_pointer_type (dtable_type);
 
-  one_elt_array_domain_type = build_index_type (integer_one_node);
   otable_type = build_array_type (integer_type_node, 
                                  one_elt_array_domain_type);
   TYPE_NONALIASED_COMPONENT (otable_type) = 1;
   otable_ptr_type = build_pointer_type (otable_type);
-  atable_type = build_array_type (ptr_type_node, 
-                                 one_elt_array_domain_type);
-  TYPE_NONALIASED_COMPONENT (atable_type) = 1;
-  atable_ptr_type = build_pointer_type (atable_type);
-
-  symbol_type = make_node (RECORD_TYPE);
-  PUSH_FIELD (symbol_type, field, "clname", utf8const_ptr_type);
-  PUSH_FIELD (symbol_type, field, "name", utf8const_ptr_type);
-  PUSH_FIELD (symbol_type, field, "signature", utf8const_ptr_type);
-  FINISH_RECORD (symbol_type);
-
-  symbols_array_type = build_array_type (symbol_type, 
-                                        one_elt_array_domain_type);
-  symbols_array_ptr_type = build_pointer_type (symbols_array_type);
-
-  if (flag_indirect_dispatch)
-    {
-      otable_decl = build_decl (VAR_DECL, get_identifier ("otable"), otable_type);
-      DECL_EXTERNAL (otable_decl) = 1;
-      TREE_STATIC (otable_decl) = 1;
-      TREE_READONLY (otable_decl) = 1;
-      TREE_CONSTANT (otable_decl) = 1;
-      pushdecl (otable_decl);  
-      otable_syms_decl = build_decl (VAR_DECL, get_identifier ("otable_syms"), 
-                                    symbols_array_type);
-      TREE_STATIC (otable_syms_decl) = 1;
-      TREE_CONSTANT (otable_syms_decl) = 1;
-      pushdecl (otable_syms_decl);
-
-      atable_decl = build_decl (VAR_DECL, get_identifier ("atable"), atable_type);
-      DECL_EXTERNAL (atable_decl) = 1;
-      TREE_STATIC (atable_decl) = 1;
-      TREE_READONLY (atable_decl) = 1;
-      TREE_CONSTANT (atable_decl) = 1;
-      pushdecl (atable_decl);  
-      atable_syms_decl = build_decl (VAR_DECL, get_identifier ("atable_syms"), 
-                                    symbols_array_type);
-      TREE_STATIC (atable_syms_decl) = 1;
-      TREE_CONSTANT (atable_syms_decl) = 1;
-      pushdecl (atable_syms_decl);
-    }
-  
-  {  
-    tree catch_class_type = make_node (RECORD_TYPE);
-    PUSH_FIELD (catch_class_type, field, "address", utf8const_ptr_type);
-    PUSH_FIELD (catch_class_type, field, "classname", ptr_type_node);
-    FINISH_RECORD (catch_class_type);
-    
-    ctable_decl 
-      = build_decl (VAR_DECL, get_identifier ("catch_classes"), 
-                   build_array_type 
-                   (catch_class_type, 0));
-    DECL_EXTERNAL (ctable_decl) = 1;
-    TREE_STATIC (ctable_decl) = 1;
-    TREE_READONLY (ctable_decl) = 1;
-    TREE_CONSTANT (ctable_decl) = 1;
-    pushdecl (ctable_decl);  
-  }
 
   PUSH_FIELD (object_type_node, field, "vtable", dtable_ptr_type);
   /* This isn't exactly true, but it is what we have in the source.
@@ -945,12 +905,12 @@ java_init_decl_processing (void)
   eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
                                              ? "__gcj_personality_sj0"
                                              : "__gcj_personality_v0");
-  lang_eh_runtime_type = prepare_eh_table_type;
+
+  lang_eh_runtime_type = do_nothing;
 
   init_jcf_parse ();
     
   initialize_builtins ();
-
   soft_fmod_node = built_in_decls[BUILT_IN_FMOD];
 #if 0
   soft_fmodf_node = built_in_decls[BUILT_IN_FMODF];
@@ -1860,6 +1820,7 @@ java_expand_body (tree fndecl)
 
   current_function_decl = fndecl;
   input_location = DECL_SOURCE_LOCATION (fndecl);
+  output_class = DECL_CONTEXT (current_function_decl);
   current_class = DECL_CONTEXT (fndecl);
 
   timevar_push (TV_EXPAND);
index c0fa800..c5c7dcf 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle exceptions for GNU compiler for the Java(TM) language.
-   Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003
+   Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -312,6 +312,7 @@ tree
 prepare_eh_table_type (tree type)
 {
   tree exp;
+  tree *slot;
   const char *name;
   char *buf;
   tree decl;
@@ -324,8 +325,16 @@ prepare_eh_table_type (tree type)
    * rewritten to point to the appropriate class.  */
 
   if (type == NULL_TREE)
-    exp = NULL_TREE;
-  else if (is_compiled_class (type) && !flag_indirect_dispatch)
+    return NULL_TREE;
+
+  if (TYPE_TO_RUNTIME_MAP (output_class) == NULL)
+    TYPE_TO_RUNTIME_MAP (output_class) = java_treetreehash_create (10, 1);
+  
+  slot = java_treetreehash_new (TYPE_TO_RUNTIME_MAP (output_class), type);
+  if (*slot != NULL)
+    return TREE_VALUE (*slot);
+
+  if (is_compiled_class (type) && !flag_indirect_dispatch)
     {
       name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
       buf = alloca (strlen (name) + 5);
@@ -339,8 +348,6 @@ prepare_eh_table_type (tree type)
       DECL_INITIAL (decl) = build_class_ref (type);
       layout_decl (decl, 0);
       pushdecl (decl);
-      rest_of_decl_compilation (decl, (char*) 0, global_bindings_p (), 0);
-      make_decl_rtl (decl, (char*) 0);
       exp = build1 (ADDR_EXPR, ptr_type_node, decl);
     }
   else
@@ -357,14 +364,37 @@ prepare_eh_table_type (tree type)
       TREE_THIS_VOLATILE (decl) = 0;
       layout_decl (decl, 0);
       pushdecl (decl);
-      rest_of_decl_compilation (decl, (char*) 0, global_bindings_p (), 0);
-      make_decl_rtl (decl, (char*) 0);
       exp = build1 (ADDR_EXPR, build_pointer_type (utf8const_ptr_type), decl);
-      catch_classes = tree_cons (NULL, make_catch_class_record (exp, utf8_ref), catch_classes);
+      TYPE_CATCH_CLASSES (output_class) = 
+       tree_cons (NULL, make_catch_class_record (exp, utf8_ref), 
+                  TYPE_CATCH_CLASSES (output_class));
     }
+
+  *slot = tree_cons (type, exp, NULL_TREE);
+
   return exp;
 }
 
+static int
+expand_catch_class (void **entry, void *x ATTRIBUTE_UNUSED)
+{
+  struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
+  tree decl = TREE_OPERAND (TREE_VALUE ((tree)ite->value), 0);
+  rest_of_decl_compilation (decl, (char*) 0, global_bindings_p (), 0);
+  return true;
+}
+  
+/* For every class in the TYPE_TO_RUNTIME_MAP, expand the
+   corresponding object that is used by the runtime type matcher.  */
+
+void
+java_expand_catch_classes (tree this_class)
+{
+  if (TYPE_TO_RUNTIME_MAP (this_class))
+    htab_traverse 
+      (TYPE_TO_RUNTIME_MAP (this_class),
+       expand_catch_class, NULL);
+}
 
 /* Build a reference to the jthrowable object being carried in the
    exception header.  */
@@ -404,7 +434,7 @@ expand_end_java_handler (struct eh_range *range)
       if (type == NULL)
        type = throwable_type_node;
 
-      expand_start_catch (type);
+      expand_start_catch (prepare_eh_table_type (type));
       expand_goto (TREE_VALUE (handler));
       expand_end_catch ();
     }
index 533b88c..82c110b 100644 (file)
@@ -1,5 +1,5 @@
 /* Process expressions for the GNU compiler for the Java(TM) language.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -1511,17 +1511,18 @@ build_field_ref (tree self_value, tree self_class, tree name)
       if (base_type != TREE_TYPE (self_value))
        self_value = fold (build1 (NOP_EXPR, base_type, self_value));
       if (flag_indirect_dispatch
-         && current_class != self_class)
-       /* FIXME: current_class != self_class is not exactly the right
+         && output_class != self_class)
+       /* FIXME: output_class != self_class is not exactly the right
           test.  What we really want to know is whether self_class is
-          in the same translation unit as current_class.  If it is,
+          in the same translation unit as output_class.  If it is,
           we can make a direct reference.  */
        {
-         tree otable_index 
-           = build_int_2 
-           (get_symbol_table_index (field_decl, &otable_methods), 0);
-         tree field_offset = build (ARRAY_REF, integer_type_node, otable_decl, 
-                                    otable_index);
+         tree otable_index =
+           build_int_2 (get_symbol_table_index 
+                        (field_decl, &TYPE_OTABLE_METHODS (output_class)), 0);
+         tree field_offset = 
+           build (ARRAY_REF, integer_type_node, TYPE_OTABLE_DECL (output_class), 
+                  otable_index);
          tree address 
            = fold (build (PLUS_EXPR, 
                           build_pointer_type (TREE_TYPE (field_decl)),
@@ -1771,10 +1772,12 @@ build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
        }
       else
        {
-         tree table_index = build_int_2 (get_symbol_table_index 
-                                         (method, &atable_methods), 0);
-         func = build (ARRAY_REF,  method_ptr_type_node, atable_decl, 
-                       table_index);
+         tree table_index = 
+           build_int_2 (get_symbol_table_index 
+                        (method, &TYPE_ATABLE_METHODS (output_class)), 0);
+         func = 
+           build (ARRAY_REF,  method_ptr_type_node, 
+                  TYPE_ATABLE_DECL (output_class), table_index);
        }
     }
   else
@@ -1893,8 +1896,10 @@ build_invokevirtual (tree dtable, tree method)
   if (flag_indirect_dispatch)
     {
       otable_index 
-       = build_int_2 (get_symbol_table_index (method, &otable_methods), 0);
-      method_index = build (ARRAY_REF, integer_type_node, otable_decl, 
+       = build_int_2 (get_symbol_table_index 
+                      (method, &TYPE_OTABLE_METHODS (output_class)), 0);
+      method_index = build (ARRAY_REF, integer_type_node, 
+                           TYPE_OTABLE_DECL (output_class), 
                            otable_index);
     }
   else
@@ -1957,9 +1962,12 @@ build_invokeinterface (tree dtable, tree method)
   
   if (flag_indirect_dispatch)
     {
-      otable_index 
-       = build_int_2 (get_symbol_table_index (method, &otable_methods), 0);
-      idx = build (ARRAY_REF, integer_type_node, otable_decl, otable_index);
+      otable_index =
+       build_int_2 (get_symbol_table_index 
+                    (method, &TYPE_OTABLE_METHODS (output_class)), 0);
+      idx = 
+       build (ARRAY_REF, integer_type_node, TYPE_OTABLE_DECL (output_class),
+              otable_index);
     }
   else
     {
@@ -2605,7 +2613,7 @@ java_expand_expr (tree exp, rtx target, enum machine_mode tmode,
          tree decl = BLOCK_EXPR_DECLS (catch);
          tree type = (decl ? TREE_TYPE (TREE_TYPE (decl)) : NULL_TREE);
 
-         expand_start_catch (type);
+         expand_start_catch (prepare_eh_table_type (type));
          expand_expr_stmt (TREE_OPERAND (current, 0));
          expand_end_catch ();
        }
index 88be2a0..7da5055 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions for parsing and type checking for the GNU compiler for
    the Java(TM) language.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -134,10 +134,17 @@ extern int compiling_from_source;
 #define main_class \
   java_global_trees[JTI_MAIN_CLASS]
 
-/* The class we are currently processing. */
+/* The class we use as the base for name resolution.  It's usually the
+   class we're generating code for but sometimes it points to an inner
+   class.  If you really want to know the class we're currently
+   generating code for, use output_class instead.  */
 #define current_class \
   java_global_trees[JTI_CURRENT_CLASS]
 
+/* The class we are currently generating.  Really.  */
+#define output_class \
+  java_global_trees[JTI_OUTPUT_CLASS]
+
 /* List of all class DECLs seen so far.  */
 #define all_class_list \
   java_global_trees[JTI_ALL_CLASS_LIST]
@@ -147,27 +154,13 @@ extern int compiling_from_source;
 
 /* List of virtual decls referred to by this translation unit, used to
    generate virtual method offset symbol table.  */
-#define otable_methods java_global_trees [JTI_OTABLE_METHODS]
-/* List of static decls referred to by this translation unit, used to
-   generate virtual method offset symbol table.  */
-#define atable_methods java_global_trees [JTI_ATABLE_METHODS]
 
 /* The virtual offset table.  This is emitted as uninitialized data of
    the required length, and filled out at run time during class
    linking. */
-#define otable_decl java_global_trees [JTI_OTABLE_DECL]
-/* The static address table.  */
-#define atable_decl java_global_trees [JTI_ATABLE_DECL]
 
 /* The virtual offset symbol table. Used by the runtime to fill out
    the otable. */
-#define otable_syms_decl java_global_trees [JTI_OTABLE_SYMS_DECL]
-/* The static symbol table. Used by the runtime to fill out the
-   otable. */
-#define atable_syms_decl java_global_trees [JTI_ATABLE_SYMS_DECL]
-
-#define ctable_decl java_global_trees [JTI_CTABLE_DECL]
-#define catch_classes java_global_trees [JTI_CATCH_CLASSES]
 
 extern int flag_emit_class_files;
 
@@ -244,6 +237,10 @@ extern const char *current_encoding;
 /* The Java .class file that provides main_class;  the main input file. */
 extern GTY(()) struct JCF * current_jcf;
 
+/* Set to nonzero value in order to emit class initialization code
+   before static field references.  */
+extern int always_initialize_class_p;
+
 typedef struct CPool constant_pool;
 
 #define CONSTANT_ResolvedFlag 16
@@ -413,20 +410,10 @@ enum java_tree_index
 
   JTI_MAIN_CLASS,
   JTI_CURRENT_CLASS,
+  JTI_OUTPUT_CLASS,
   JTI_ALL_CLASS_LIST,
   JTI_ALL_CLASS_FILENAME,
 
-  JTI_OTABLE_METHODS,
-  JTI_OTABLE_DECL,
-  JTI_OTABLE_SYMS_DECL,
-
-  JTI_ATABLE_METHODS,
-  JTI_ATABLE_DECL,
-  JTI_ATABLE_SYMS_DECL,
-
-  JTI_CTABLE_DECL,
-  JTI_CATCH_CLASSES,
-
   JTI_PREDEF_FILENAMES,
 
   JTI_MAX
@@ -923,6 +910,9 @@ union lang_tree_node
 /* The original WFL of a final variable. */
 #define DECL_FIELD_FINAL_WFL(NODE) \
   (DECL_LANG_SPECIFIC(NODE)->u.v.wfl)
+/* The class that's the owner of a dynamic binding table.  */
+#define DECL_OWNER(NODE) \
+  (DECL_LANG_SPECIFIC(NODE)->u.v.owner)
 /* True if NODE is a local variable final. */
 #define LOCAL_FINAL_P(NODE) (DECL_LANG_SPECIFIC (NODE) && DECL_FINAL (NODE))
 /* True if NODE is a final field. */
@@ -1022,6 +1012,7 @@ struct lang_decl_var GTY(())
   tree slot_chain;
   tree am;                     /* Access method for this field (1.1) */
   tree wfl;                    /* Original wfl */
+  tree owner;
   unsigned int final_iud : 1;  /* Final initialized upon declaration */
   unsigned int cif : 1;                /* True: decl is a class initialization flag */
   unsigned int freed;          /* Decl is no longer in scope.  */
@@ -1070,6 +1061,19 @@ struct lang_decl GTY(())
 #define TYPE_STRICTFP(T) (TYPE_LANG_SPECIFIC(T)->strictfp)
 #define TYPE_USES_ASSERTIONS(T) (TYPE_LANG_SPECIFIC(T)->assertions)
 
+#define TYPE_ATABLE_METHODS(T)   (TYPE_LANG_SPECIFIC(T)->atable_methods)
+#define TYPE_ATABLE_SYMS_DECL(T) (TYPE_LANG_SPECIFIC(T)->atable_syms_decl)
+#define TYPE_ATABLE_DECL(T)      (TYPE_LANG_SPECIFIC(T)->atable_decl)
+
+#define TYPE_OTABLE_METHODS(T)   (TYPE_LANG_SPECIFIC(T)->otable_methods)
+#define TYPE_OTABLE_SYMS_DECL(T) (TYPE_LANG_SPECIFIC(T)->otable_syms_decl)
+#define TYPE_OTABLE_DECL(T)      (TYPE_LANG_SPECIFIC(T)->otable_decl)
+
+#define TYPE_CTABLE_DECL(T)      (TYPE_LANG_SPECIFIC(T)->ctable_decl)
+#define TYPE_CATCH_CLASSES(T)    (TYPE_LANG_SPECIFIC(T)->catch_classes)
+
+#define TYPE_TO_RUNTIME_MAP(T)   (TYPE_LANG_SPECIFIC(T)->type_to_runtime_map)
+
 struct lang_type GTY(())
 {
   tree signature;
@@ -1086,6 +1090,21 @@ struct lang_type GTY(())
   tree package_list;           /* List of package names, progressive */
   tree import_list;            /* Imported types, in the CU of this class */
   tree import_demand_list;     /* Imported types, in the CU of this class */
+
+  tree otable_methods;          /* List of static decls referred to by this class.  */
+  tree otable_decl;            /* The static address table.  */
+  tree otable_syms_decl;
+
+  tree atable_methods;          /* List of static decls referred to by this class.  */
+  tree atable_decl;            /* The static address table.  */
+  tree atable_syms_decl;
+
+  tree ctable_decl;             /* The table of classes for the runtime type matcher.  */
+  tree catch_classes;
+
+  htab_t GTY ((param_is (struct treetreehash_entry))) type_to_runtime_map;   
+                                /* The mapping of classes to exception region markers.  */
+
   unsigned pic:1;              /* Private Inner Class. */
   unsigned poic:1;             /* Protected Inner Class. */
   unsigned strictfp:1;         /* `strictfp' class.  */
@@ -1200,6 +1219,7 @@ extern tree build_instanceof (tree, tree);
 extern tree create_label_decl (tree);
 extern void push_labeled_block (tree);
 extern tree prepare_eh_table_type (tree);
+extern void java_expand_catch_classes (tree);
 extern tree build_exception_object_ref (tree);
 extern tree generate_name (void);
 extern void pop_labeled_block (void);
@@ -1322,7 +1342,9 @@ extern void java_expand_body (tree);
 extern int get_symbol_table_index (tree, tree *);
 
 extern tree make_catch_class_record (tree, tree);
-extern void emit_catch_table (void);
+extern tree emit_catch_table (tree);
+
+extern void gen_indirect_dispatch_tables (tree type);
 
 #define DECL_FINAL(DECL) DECL_LANG_FLAG_3 (DECL)
 
index a3fa212..3214092 100644 (file)
@@ -1,5 +1,5 @@
 /* Parser for Java(TM) .class files.
-   Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003
+   Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -72,10 +72,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 
 extern struct obstack temporary_obstack;
 
-/* Set to nonzero value in order to emit class initialization code
-   before static field references.  */
-extern int always_initialize_class_p;
-
 static GTY(()) tree parse_roots[3];
 
 /* The FIELD_DECL for the current field.  */
@@ -153,7 +149,7 @@ set_source_filename (JCF *jcf, int index)
 
 #define HANDLE_CLASS_INFO(ACCESS_FLAGS, THIS, SUPER, INTERFACES_COUNT) \
 { tree super_class = SUPER==0 ? NULL_TREE : get_class_constant (jcf, SUPER); \
-  current_class = give_name_to_class (jcf, THIS); \
+  output_class = current_class = give_name_to_class (jcf, THIS); \
   set_super_info (ACCESS_FLAGS, current_class, super_class, INTERFACES_COUNT);}
 
 #define HANDLE_CLASS_INTERFACE(INDEX) \
@@ -509,7 +505,7 @@ read_class (tree name)
        wfl_operator = build_expr_wfl (NULL_TREE, NULL, 0, 0);
       EXPR_WFL_FILENAME_NODE (wfl_operator) = file;
       input_filename = ggc_strdup (filename);
-      current_class = NULL_TREE;
+      output_class = current_class = NULL_TREE;
       current_function_decl = NULL_TREE;
       if (!HAS_BEEN_ALREADY_PARSED_P (file))
        {
@@ -531,7 +527,7 @@ read_class (tree name)
        {
          java_parser_context_save_global ();
          java_push_parser_context ();
-         current_class = class;
+         output_class = current_class = class;
          input_filename = current_jcf->filename;
          if (JCF_SEEN_IN_ZIP (current_jcf))
            read_zip_member(current_jcf,
@@ -549,7 +545,7 @@ read_class (tree name)
       load_inner_classes (class);
     }
 
-  current_class = save_current_class;
+  output_class = current_class = save_current_class;
   input_location = save_location;
   current_jcf = save_current_jcf;
   return 1;
@@ -709,6 +705,8 @@ parse_class_file (void)
      compiling from class files.  */
   always_initialize_class_p = 1;
 
+  gen_indirect_dispatch_tables (current_class);
+
   java_mark_class_local (current_class);
 
   for (method = TYPE_METHODS (current_class);
@@ -1099,7 +1097,7 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
       input_filename = IDENTIFIER_POINTER (TREE_VALUE (node));
       if (CLASS_FILE_P (node))
        {
-         current_class = TREE_PURPOSE (node);
+         output_class = current_class = TREE_PURPOSE (node);
          current_jcf = TYPE_JCF (current_class);
          layout_class (current_class);
          load_inner_classes (current_class);
@@ -1119,18 +1117,6 @@ java_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
 
       /* Emit the .jcf section.  */
       emit_register_classes ();
-      if (flag_indirect_dispatch)
-       {
-         otable_decl 
-           = emit_symbol_table 
-           (get_identifier ("otable"), 
-            otable_decl, otable_methods, otable_syms_decl, integer_type_node);
-         atable_decl 
-           = emit_symbol_table 
-           (get_identifier ("atable"), 
-            atable_decl, atable_methods, atable_syms_decl, ptr_type_node);
-       }
-      emit_catch_table ();
     }
 
   write_resource_constructor ();
@@ -1201,7 +1187,7 @@ parse_zip_file_entries (void)
            class = lookup_class (get_identifier (class_name));
            FREE (class_name);
            current_jcf = TYPE_JCF (class);
-           current_class = class;
+           output_class = current_class = class;
 
            if (! CLASS_LOADED_P (class))
              {
index c2494da..2f68f7c 100644 (file)
@@ -1,5 +1,5 @@
 /* Java(TM) language-specific utility routines.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -464,6 +464,11 @@ java_init (void)
   if (flag_inline_functions)
     flag_inline_trees = 1;
 
+  /* FIXME: Indirect dispatch isn't yet compatible with static class
+     init optimization.  */
+  if (flag_indirect_dispatch)
+    always_initialize_class_p = true;
+
   /* Force minimum function alignment if g++ uses the least significant
      bit of function pointers to store the virtual bit. This is required
      to keep vtables compatible.  */
@@ -967,11 +972,9 @@ inline_init_test_initialization (void **entry, void *x)
     (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), ite->key);
   if (! h)
     return true;
-
   splay_tree_insert (decl_map,
                     (splay_tree_key) ite->value,
                     (splay_tree_value) h);
-
   return true;
 }
 
@@ -1102,7 +1105,7 @@ java_dump_tree (void *dump_info, tree t)
 static bool
 java_decl_ok_for_sibcall (tree decl)
 {
-  return decl != NULL && DECL_CONTEXT (decl) == current_class;
+  return decl != NULL && DECL_CONTEXT (decl) == output_class;
 }
 
 /* Used by estimate_num_insns.  Estimate number of instructions seen
@@ -1228,7 +1231,7 @@ java_start_inlining (tree fn)
 static tree
 java_get_callee_fndecl (tree call_expr)
 {
-  tree method, table, element;
+  tree method, table, element, atable_methods;
 
   HOST_WIDE_INT index;
 
@@ -1239,10 +1242,14 @@ java_get_callee_fndecl (tree call_expr)
   if (TREE_CODE (method) != ARRAY_REF)
     return NULL;
   table = TREE_OPERAND (method, 0);
-  if (table != atable_decl)
+  if (! DECL_LANG_SPECIFIC(table)
+      || !DECL_OWNER (table) 
+      || TYPE_ATABLE_DECL (DECL_OWNER (table)) != table)
     return NULL;
-  index = TREE_INT_CST_LOW (TREE_OPERAND (method, 1));
 
+  atable_methods = TYPE_ATABLE_METHODS (DECL_OWNER (table));
+  index = TREE_INT_CST_LOW (TREE_OPERAND (method, 1));
+  
   /* FIXME: Replace this for loop with a hash table lookup.  */
   for (element = atable_methods; element; element = TREE_CHAIN (element))
     {
@@ -1257,7 +1264,7 @@ java_get_callee_fndecl (tree call_expr)
        }
       --index;
     }
-  
+
   return NULL;
 }
 
index c8b4596..20e6f9a 100644 (file)
@@ -1,6 +1,6 @@
 /* Source code parsing and tree node generation for the GNU compiler
    for the Java(TM) language.
-   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
    Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
 
@@ -5451,7 +5451,7 @@ java_fix_constructors (void)
       if (CLASS_INTERFACE (TYPE_NAME (class_type)))
        continue;
 
-      current_class = class_type;
+      output_class = current_class = class_type;
       for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
        {
          if (DECL_CONSTRUCTOR_P (decl))
@@ -7575,7 +7575,7 @@ java_reorder_fields (void)
 
   for (current = gclass_list; current; current = TREE_CHAIN (current))
     {
-      current_class = TREE_TYPE (TREE_VALUE (current));
+      output_class = current_class = TREE_TYPE (TREE_VALUE (current));
 
       if (current_class == stop_reordering)
        break;
@@ -7632,7 +7632,7 @@ java_layout_classes (void)
 
   for (current = gclass_list; current; current = TREE_CHAIN (current))
     {
-      current_class = TREE_TYPE (TREE_VALUE (current));
+      output_class = current_class = TREE_TYPE (TREE_VALUE (current));
       layout_class (current_class);
 
       /* Error reported by the caller */
@@ -7696,7 +7696,7 @@ java_complete_expand_methods (tree class_decl)
 {
   tree clinit, decl, first_decl;
 
-  current_class = TREE_TYPE (class_decl);
+  output_class = current_class = TREE_TYPE (class_decl);
 
   /* Pre-expand <clinit> to figure whether we really need it or
      not. If we do need it, we pre-expand the static fields so they're
@@ -9017,6 +9017,15 @@ java_expand_classes (void)
 
   for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
     {
+      tree current;
+      for (current = cur_ctxp->class_list; 
+          current; 
+          current = TREE_CHAIN (current))
+       gen_indirect_dispatch_tables (TREE_TYPE (current));
+    }
+  
+  for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
+    {
       ctxp = cur_ctxp;
       input_filename = ctxp->filename;
       lang_init_source (2);           /* Error msgs have method prototypes */
@@ -9025,7 +9034,6 @@ java_expand_classes (void)
     }
   input_filename = main_input_filename;
 
-
   /* Find anonymous classes and expand their constructor. This extra pass is
      necessary because the constructor itself is only generated when the
      method in which it is defined is expanded. */
@@ -9035,7 +9043,7 @@ java_expand_classes (void)
       ctxp = cur_ctxp;
       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
        {
-         current_class = TREE_TYPE (current);
+         output_class = current_class = TREE_TYPE (current);
          if (ANONYMOUS_CLASS_P (current_class))
            {
              tree d;
@@ -9063,7 +9071,7 @@ java_expand_classes (void)
       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
        {
          tree d;
-         current_class = TREE_TYPE (current);
+         output_class = current_class = TREE_TYPE (current);
          for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
            {
              if (DECL_RESULT (d) == NULL_TREE)
@@ -9094,7 +9102,7 @@ java_expand_classes (void)
              for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
                {
                  tree d;
-                 current_class = TREE_TYPE (current);
+                 output_class = current_class = TREE_TYPE (current);
                  for (d = TYPE_METHODS (current_class); d; d = TREE_CHAIN (d))
                    {
                      if (DECL_RESULT (d) == NULL_TREE)
@@ -9159,7 +9167,7 @@ java_expand_classes (void)
           current;
           current = TREE_CHAIN (current))
        {
-         current_class = TREE_TYPE (TREE_VALUE (current));
+         output_class = current_class = TREE_TYPE (TREE_VALUE (current));
          if (flag_emit_class_files)
            write_classfile (current_class);
          if (flag_emit_xref)
@@ -9180,7 +9188,7 @@ java_finish_classes (void)
       ctxp = cur_ctxp;
       for (current = ctxp->class_list; current; current = TREE_CHAIN (current))
        {
-         current_class = TREE_TYPE (current);
+         output_class = current_class = TREE_TYPE (current);
          finish_class ();
        }
     }