summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/java/ChangeLog62
-rw-r--r--gcc/java/class.c191
-rw-r--r--gcc/java/constants.c12
-rw-r--r--gcc/java/decl.c105
-rw-r--r--gcc/java/except.c48
-rw-r--r--gcc/java/expr.c46
-rw-r--r--gcc/java/java-tree.h78
-rw-r--r--gcc/java/jcf-parse.c32
-rw-r--r--gcc/java/lang.c23
-rw-r--r--gcc/java/parse.y30
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 ();
}
}