This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Java: Bogus vtable index in debug info
- From: Andrew Haley <aph at redhat dot com>
- To: java-patches at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Cc: Jeff Johnston <jjohnstn at redhat dot com>
- Date: Wed, 5 May 2004 11:17:22 +0100
- Subject: Java: Bogus vtable index in debug info
Jeff Johnston has explained to me that we're outputting incorrect
debug info for vtable offsets.
There are usually (let's ignore TARGET_VTABLE_USES_DESCRIPTORS for a
moment) two words at the start of a vtable, one for "class$" and one
for the gc descriptor. A method's DECL_VINDEX currently doesn't allow
for the additional offset of these words, so when we generate code to
invoke a method we add 2 to DECL_VINDEX to get the method's true
vtable offset.
But gdb doesn't know about these two dummy words, and it really
shouldn't need to.
This patch fixes DECL_VINDEX in the compiler so that it points to the
real offset. All the pointer adjustment is inside two new functions,
get_method_index() and set_method_index(), which should be used
everywhere except at the point where a method invocation is generated.
There's no ABI change here: it's just a change to the compiler internals.
Passed full bootstrap & regression tests.
Andrew.
2004-05-05 Andrew Haley <aph@redhat.com>
* 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.
Index: gcc/java/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/class.c,v
retrieving revision 1.182
diff -c -2 -p -r1.182 class.c
*** gcc/java/class.c 20 Apr 2004 01:38:42 -0000 1.182
--- gcc/java/class.c 5 May 2004 10:15:41 -0000
*************** make_method_value (tree mdecl)
*** 1250,1260 ****
#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
index = integer_minus_one_node;
--- 1250,1260 ----
#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 && get_method_index (mdecl) != NULL_TREE)
! index = get_method_index (mdecl);
else
index = integer_minus_one_node;
*************** get_dispatch_vector (tree type)
*** 1344,1351 ****
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;
}
--- 1344,1353 ----
for (method = TYPE_METHODS (type); method != NULL_TREE;
method = TREE_CHAIN (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;
! }
}
*************** get_dispatch_table (tree type, tree this
*** 1426,1429 ****
--- 1428,1467 ----
}
+
+ /* 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)
*************** layout_class_method (tree this_class, tr
*** 2202,2207 ****
if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method))
{
! DECL_VINDEX (method_decl) = DECL_VINDEX (super_method);
! if (DECL_VINDEX (method_decl) == NULL_TREE
&& !CLASS_FROM_SOURCE_P (this_class))
error ("%Jnon-static method '%D' overrides static method",
--- 2240,2246 ----
if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method))
{
! 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",
*************** layout_class_method (tree this_class, tr
*** 2213,2217 ****
&& dtable_count)
{
! DECL_VINDEX (method_decl) = dtable_count;
dtable_count = fold (build (PLUS_EXPR, integer_type_node,
dtable_count, integer_one_node));
--- 2252,2256 ----
&& dtable_count)
{
! set_method_index (method_decl, dtable_count);
dtable_count = fold (build (PLUS_EXPR, integer_type_node,
dtable_count, integer_one_node));
Index: gcc/java/expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.188
diff -c -2 -p -r1.188 expr.c
*** gcc/java/expr.c 16 Apr 2004 16:27:13 -0000 1.188
--- gcc/java/expr.c 5 May 2004 10:15:42 -0000
*************** build_invokevirtual (tree dtable, tree m
*** 1906,1921 ****
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));
!
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,
--- 1906,1916 ----
else
{
! /* 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,
Index: gcc/java/java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.198
diff -c -2 -p -r1.198 java-tree.h
*** gcc/java/java-tree.h 14 Apr 2004 17:45:12 -0000 1.198
--- gcc/java/java-tree.h 5 May 2004 10:15:42 -0000
*************** extern void complete_start_java_method (
*** 1239,1242 ****
--- 1239,1244 ----
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);