parse.y (create_class): Set TYPE_VFIELD.

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.

From-SVN: r81672
This commit is contained in:
Andrew Haley 2004-05-10 16:21:08 +00:00 committed by Andrew Haley
parent 5950a3ac27
commit af434fa7a1
6 changed files with 81 additions and 20 deletions

View File

@ -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

View File

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

View File

@ -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. */

View File

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

View File

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

View File

@ -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. */