Commit af434fa7 by Andrew Haley Committed by Andrew Haley

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
parent 5950a3ac
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> 2004-05-10 Andrew Pinski <pinskia@physics.uc.edu>
* parse.y (check_pkg_class_access): Add new argument * parse.y (check_pkg_class_access): Add new argument
......
...@@ -476,6 +476,7 @@ set_super_info (int access_flags, tree this_class, ...@@ -476,6 +476,7 @@ set_super_info (int access_flags, tree this_class,
if (super_class) if (super_class)
total_supers++; total_supers++;
TYPE_VFIELD (this_class) = TYPE_VFIELD (object_type_node);
TYPE_BINFO_BASETYPES (this_class) = make_tree_vec (total_supers); TYPE_BINFO_BASETYPES (this_class) = make_tree_vec (total_supers);
if (super_class) if (super_class)
{ {
...@@ -1249,13 +1250,13 @@ make_method_value (tree mdecl) ...@@ -1249,13 +1250,13 @@ make_method_value (tree mdecl)
tree class_decl; tree class_decl;
#define ACC_TRANSLATED 0x4000 #define ACC_TRANSLATED 0x4000
int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED; int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
class_decl = DECL_CONTEXT (mdecl); class_decl = DECL_CONTEXT (mdecl);
/* For interfaces, the index field contains the dispatch index. */ /* For interfaces, the index field contains the dispatch index. */
if (CLASS_INTERFACE (TYPE_NAME (class_decl))) if (CLASS_INTERFACE (TYPE_NAME (class_decl)))
index = build_int_2 (get_interface_method_index (mdecl, class_decl), 0); index = build_int_2 (get_interface_method_index (mdecl, class_decl), 0);
else if (!flag_indirect_dispatch && DECL_VINDEX (mdecl) != NULL_TREE) else if (!flag_indirect_dispatch && get_method_index (mdecl) != NULL_TREE)
index = DECL_VINDEX (mdecl); index = get_method_index (mdecl);
else else
index = integer_minus_one_node; index = integer_minus_one_node;
...@@ -1343,10 +1344,12 @@ get_dispatch_vector (tree type) ...@@ -1343,10 +1344,12 @@ get_dispatch_vector (tree type)
for (method = TYPE_METHODS (type); method != NULL_TREE; for (method = TYPE_METHODS (type); method != NULL_TREE;
method = TREE_CHAIN (method)) method = TREE_CHAIN (method))
if (DECL_VINDEX (method) != NULL_TREE {
&& host_integerp (DECL_VINDEX (method), 0)) tree method_index = get_method_index (method);
TREE_VEC_ELT (vtable, tree_low_cst (DECL_VINDEX (method), 0)) if (method_index != NULL_TREE
= method; && host_integerp (method_index, 0))
TREE_VEC_ELT (vtable, tree_low_cst (method_index, 0)) = method;
}
} }
return vtable; return vtable;
...@@ -1425,6 +1428,42 @@ get_dispatch_table (tree type, tree this_class_addr) ...@@ -1425,6 +1428,42 @@ get_dispatch_table (tree type, tree this_class_addr)
arraysize), list); 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 static int
supers_all_compiled (tree type) supers_all_compiled (tree type)
{ {
...@@ -2201,8 +2240,9 @@ layout_class_method (tree this_class, tree super_class, ...@@ -2201,8 +2240,9 @@ layout_class_method (tree this_class, tree super_class,
method_sig); method_sig);
if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method)) if (super_method != NULL_TREE && ! METHOD_PRIVATE (super_method))
{ {
DECL_VINDEX (method_decl) = DECL_VINDEX (super_method); tree method_index = get_method_index (super_method);
if (DECL_VINDEX (method_decl) == NULL_TREE set_method_index (method_decl, method_index);
if (method_index == NULL_TREE
&& !CLASS_FROM_SOURCE_P (this_class)) && !CLASS_FROM_SOURCE_P (this_class))
error ("%Jnon-static method '%D' overrides static method", error ("%Jnon-static method '%D' overrides static method",
method_decl, method_decl); method_decl, method_decl);
...@@ -2212,7 +2252,7 @@ layout_class_method (tree this_class, tree super_class, ...@@ -2212,7 +2252,7 @@ layout_class_method (tree this_class, tree super_class,
&& ! CLASS_FINAL (TYPE_NAME (this_class)) && ! CLASS_FINAL (TYPE_NAME (this_class))
&& dtable_count) && 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 = fold (build (PLUS_EXPR, integer_type_node,
dtable_count, integer_one_node)); dtable_count, integer_one_node));
} }
......
...@@ -638,6 +638,9 @@ java_init_decl_processing (void) ...@@ -638,6 +638,9 @@ java_init_decl_processing (void)
otable_ptr_type = build_pointer_type (otable_type); otable_ptr_type = build_pointer_type (otable_type);
PUSH_FIELD (object_type_node, field, "vtable", dtable_ptr_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. /* 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 There is an unresolved issue here, which is whether the vtable
should be marked by the GC. */ should be marked by the GC. */
......
...@@ -1905,18 +1905,13 @@ build_invokevirtual (tree dtable, tree method) ...@@ -1905,18 +1905,13 @@ build_invokevirtual (tree dtable, tree method)
} }
else else
{ {
method_index = convert (sizetype, DECL_VINDEX (method)); /* We fetch the DECL_VINDEX field directly here, rather than
using get_method_index(). DECL_VINDEX is the true offset
if (TARGET_VTABLE_USES_DESCRIPTORS) from the vtable base to a method, regrdless of any extra
/* Add one to skip bogus descriptor for class and GC descriptor. */ words inserted at the start of the vtable. */
method_index = size_binop (PLUS_EXPR, method_index, size_int (1)); method_index = DECL_VINDEX (method);
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, method_index = size_binop (MULT_EXPR, method_index,
TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node)); TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
if (TARGET_VTABLE_USES_DESCRIPTORS) if (TARGET_VTABLE_USES_DESCRIPTORS)
method_index = size_binop (MULT_EXPR, method_index, method_index = size_binop (MULT_EXPR, method_index,
size_int (TARGET_VTABLE_USES_DESCRIPTORS)); size_int (TARGET_VTABLE_USES_DESCRIPTORS));
......
...@@ -1238,6 +1238,8 @@ extern int enclosing_context_p (tree, tree); ...@@ -1238,6 +1238,8 @@ extern int enclosing_context_p (tree, tree);
extern void complete_start_java_method (tree); extern void complete_start_java_method (tree);
extern tree build_result_decl (tree); extern tree build_result_decl (tree);
extern void emit_handlers (void); 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 make_class_data (tree);
extern void register_class (void); extern void register_class (void);
extern int alloc_name_constant (int, tree); extern int alloc_name_constant (int, tree);
......
...@@ -4037,6 +4037,11 @@ create_class (int flags, tree id, tree super, tree interfaces) ...@@ -4037,6 +4037,11 @@ create_class (int flags, tree id, tree super, tree interfaces)
CLASS_COMPLETE_P (decl) = 1; CLASS_COMPLETE_P (decl) = 1;
add_superinterfaces (decl, interfaces); 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 /* Add the private this$<n> field, Replicate final locals still in
scope as private final fields mangled like val$<local_name>. scope as private final fields mangled like val$<local_name>.
This doesn't not occur for top level (static) inner classes. */ This doesn't not occur for top level (static) inner classes. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment