diff options
-rw-r--r-- | gcc/java/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/java/class.c | 60 | ||||
-rw-r--r-- | gcc/java/decl.c | 3 | ||||
-rw-r--r-- | gcc/java/expr.c | 15 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 2 | ||||
-rw-r--r-- | gcc/java/parse.y | 5 |
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. */ |