diff options
-rw-r--r-- | gcc/java/ChangeLog | 62 | ||||
-rw-r--r-- | gcc/java/class.c | 191 | ||||
-rw-r--r-- | gcc/java/constants.c | 12 | ||||
-rw-r--r-- | gcc/java/decl.c | 105 | ||||
-rw-r--r-- | gcc/java/except.c | 48 | ||||
-rw-r--r-- | gcc/java/expr.c | 46 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 78 | ||||
-rw-r--r-- | gcc/java/jcf-parse.c | 32 | ||||
-rw-r--r-- | gcc/java/lang.c | 23 | ||||
-rw-r--r-- | gcc/java/parse.y | 30 |
10 files changed, 412 insertions, 215 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 2fa7728ebde..a0cee422c35 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -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. diff --git a/gcc/java/class.c b/gcc/java/class.c index 6c772e0a808..bf9f79ef280 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -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; } diff --git a/gcc/java/constants.c b/gcc/java/constants.c index 8a1fe1bb4ea..d97e8c07e80 100644 --- a/gcc/java/constants.c +++ b/gcc/java/constants.c @@ -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; diff --git a/gcc/java/decl.c b/gcc/java/decl.c index 46bb2248b6d..1ce2ad324c2 100644 --- a/gcc/java/decl.c +++ b/gcc/java/decl.c @@ -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); diff --git a/gcc/java/except.c b/gcc/java/except.c index c0fa800c262..c5c7dcf27f4 100644 --- a/gcc/java/except.c +++ b/gcc/java/except.c @@ -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 (); } diff --git a/gcc/java/expr.c b/gcc/java/expr.c index 533b88c39b3..82c110b50c9 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -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 (); } diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index 88be2a03441..7da5055ad6c 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -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) diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c index a3fa2124f82..32140920676 100644 --- a/gcc/java/jcf-parse.c +++ b/gcc/java/jcf-parse.c @@ -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)) { diff --git a/gcc/java/lang.c b/gcc/java/lang.c index c2494daacea..2f68f7c0453 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -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; } diff --git a/gcc/java/parse.y b/gcc/java/parse.y index c8b4596a587..20e6f9add99 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -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 (); } } |