This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]