aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/java/ChangeLog16
-rw-r--r--gcc/java/class.c60
-rw-r--r--gcc/java/decl.c3
-rw-r--r--gcc/java/expr.c15
-rw-r--r--gcc/java/java-tree.h2
-rw-r--r--gcc/java/parse.y5
6 files changed, 81 insertions, 20 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 683fa60..25594a3 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,19 @@
+2004-05-10 Andrew Haley <aph@redhat.com>
+
+ * parse.y (create_class): Set TYPE_VFIELD.
+ * decl.c (java_init_decl_processing): Likewise.
+
+ * expr.c (build_invokevirtual): Remove DECL_VINDEX offset adjustment.
+ * class.c (make_method_value): Replace DECL_VINDEX with call to
+ get_method_index().
+ (get_dispatch_vector): Likewise.
+ (layout_class_method): Likewise.
+ Replace set of DECL_VINDEX with call to set_method_index().
+ (set_method_index): New function.
+ (get_method_index): New function.
+ * java-tree.h (set_method_index): New function decl.
+ (get_method_index): New function decl.
+
2004-05-10 Andrew Pinski <pinskia@physics.uc.edu>
* parse.y (check_pkg_class_access): Add new argument
diff --git a/gcc/java/class.c b/gcc/java/class.c
index 4ac4a4f0..530b56f 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -476,6 +476,7 @@ set_super_info (int access_flags, tree this_class,
if (super_class)
total_supers++;
+ TYPE_VFIELD (this_class) = TYPE_VFIELD (object_type_node);
TYPE_BINFO_BASETYPES (this_class) = make_tree_vec (total_supers);
if (super_class)
{
@@ -1249,13 +1250,13 @@ make_method_value (tree mdecl)
tree class_decl;
#define ACC_TRANSLATED 0x4000
int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
-
+
class_decl = DECL_CONTEXT (mdecl);
/* For interfaces, the index field contains the dispatch index. */
if (CLASS_INTERFACE (TYPE_NAME (class_decl)))
index = build_int_2 (get_interface_method_index (mdecl, class_decl), 0);
- else if (!flag_indirect_dispatch && DECL_VINDEX (mdecl) != NULL_TREE)
- index = DECL_VINDEX (mdecl);
+ else if (!flag_indirect_dispatch && get_method_index (mdecl) != NULL_TREE)
+ index = get_method_index (mdecl);
else
index = integer_minus_one_node;
@@ -1343,10 +1344,12 @@ get_dispatch_vector (tree type)
for (method = TYPE_METHODS (type); method != NULL_TREE;
method = TREE_CHAIN (method))
- if (DECL_VINDEX (method) != NULL_TREE
- && host_integerp (DECL_VINDEX (method), 0))
- TREE_VEC_ELT (vtable, tree_low_cst (DECL_VINDEX (method), 0))
- = method;
+ {
+ tree method_index = get_method_index (method);
+ if (method_index != NULL_TREE
+ && host_integerp (method_index, 0))
+ TREE_VEC_ELT (vtable, tree_low_cst (method_index, 0)) = method;
+ }
}
return vtable;
@@ -1425,6 +1428,42 @@ get_dispatch_table (tree type, tree this_class_addr)
arraysize), list);
}
+
+/* Set the method_index for a method decl. */
+void
+set_method_index (tree decl, tree method_index)
+{
+ method_index = fold (convert (sizetype, method_index));
+
+ if (TARGET_VTABLE_USES_DESCRIPTORS)
+ /* Add one to skip bogus descriptor for class and GC descriptor. */
+ method_index = size_binop (PLUS_EXPR, method_index, size_int (1));
+ else
+ /* Add 1 to skip "class" field of dtable, and 1 to skip GC descriptor. */
+ method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
+
+ DECL_VINDEX (decl) = method_index;
+}
+
+/* Get the method_index for a method decl. */
+tree
+get_method_index (tree decl)
+{
+ tree method_index = DECL_VINDEX (decl);
+
+ if (! method_index)
+ return NULL;
+
+ if (TARGET_VTABLE_USES_DESCRIPTORS)
+ /* Sub one to skip bogus descriptor for class and GC descriptor. */
+ method_index = size_binop (MINUS_EXPR, method_index, size_int (1));
+ else
+ /* Sub 1 to skip "class" field of dtable, and 1 to skip GC descriptor. */
+ method_index = size_binop (MINUS_EXPR, method_index, size_int (2));
+
+ return method_index;
+}
+
static int
supers_all_compiled (tree type)
{
@@ -2201,8 +2240,9 @@ layout_class_method (tree this_class, tree super_class,
method_sig);
if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method))
{
- DECL_VINDEX (method_decl) = DECL_VINDEX (super_method);
- if (DECL_VINDEX (method_decl) == NULL_TREE
+ tree method_index = get_method_index (super_method);
+ set_method_index (method_decl, method_index);
+ if (method_index == NULL_TREE
&& !CLASS_FROM_SOURCE_P (this_class))
error ("%Jnon-static method '%D' overrides static method",
method_decl, method_decl);
@@ -2212,7 +2252,7 @@ layout_class_method (tree this_class, tree super_class,
&& ! CLASS_FINAL (TYPE_NAME (this_class))
&& dtable_count)
{
- DECL_VINDEX (method_decl) = dtable_count;
+ set_method_index (method_decl, dtable_count);
dtable_count = fold (build (PLUS_EXPR, integer_type_node,
dtable_count, integer_one_node));
}
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 87204235..047c0af 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -638,6 +638,9 @@ java_init_decl_processing (void)
otable_ptr_type = build_pointer_type (otable_type);
PUSH_FIELD (object_type_node, field, "vtable", dtable_ptr_type);
+ DECL_FCONTEXT (field) = object_type_node;
+ TYPE_VFIELD (object_type_node) = field;
+
/* This isn't exactly true, but it is what we have in the source.
There is an unresolved issue here, which is whether the vtable
should be marked by the GC. */
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 839480b..11f6c94 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -1905,18 +1905,13 @@ build_invokevirtual (tree dtable, tree method)
}
else
{
- method_index = convert (sizetype, DECL_VINDEX (method));
-
- if (TARGET_VTABLE_USES_DESCRIPTORS)
- /* Add one to skip bogus descriptor for class and GC descriptor. */
- method_index = size_binop (PLUS_EXPR, method_index, size_int (1));
- else
- /* Add 1 to skip "class" field of dtable, and 1 to skip GC descriptor. */
- method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
-
+ /* We fetch the DECL_VINDEX field directly here, rather than
+ using get_method_index(). DECL_VINDEX is the true offset
+ from the vtable base to a method, regrdless of any extra
+ words inserted at the start of the vtable. */
+ method_index = DECL_VINDEX (method);
method_index = size_binop (MULT_EXPR, method_index,
TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
-
if (TARGET_VTABLE_USES_DESCRIPTORS)
method_index = size_binop (MULT_EXPR, method_index,
size_int (TARGET_VTABLE_USES_DESCRIPTORS));
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 8a9f9a9..faad727 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -1238,6 +1238,8 @@ extern int enclosing_context_p (tree, tree);
extern void complete_start_java_method (tree);
extern tree build_result_decl (tree);
extern void emit_handlers (void);
+extern void set_method_index (tree decl, tree method_index);
+extern tree get_method_index (tree decl);
extern void make_class_data (tree);
extern void register_class (void);
extern int alloc_name_constant (int, tree);
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index 0649dbe..3212dda 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -4037,6 +4037,11 @@ create_class (int flags, tree id, tree super, tree interfaces)
CLASS_COMPLETE_P (decl) = 1;
add_superinterfaces (decl, interfaces);
+ /* TYPE_VFIELD' is a compiler-generated field used to point to
+ virtual function tables. In gcj, every class has a common base
+ virtual function table in java.lang.object. */
+ TYPE_VFIELD (TREE_TYPE (decl)) = TYPE_VFIELD (object_type_node);
+
/* Add the private this$<n> field, Replicate final locals still in
scope as private final fields mangled like val$<local_name>.
This doesn't not occur for top level (static) inner classes. */