class.c (get_dispatch_table): Fix java vtable layout for TARGET_VTABLE_USES_DESCRIPTORS.

* class.c (get_dispatch_table): Fix java vtable layout
	for TARGET_VTABLE_USES_DESCRIPTORS.
	* decl.c (java_init_decl_processing): Initialize
	alloc_no_finalizer_node, finalize_identifier_node.
	* expr.c (class_has_finalize_method): New function.
	(expand_java_NEW): Generate calls for finalizer-free allocation.
	(build_invokevirtual): Fix java vtable layout for
	TARGET_VTABLE_USES_DESCRIPTORS.
	* java-tree.h (enum java_tree_index): New entries:
	JTI_ALLOC_NO_FINALIZER_NODE, JTI_FINALIZE_IDENTIFIER_NODE.
	(alloc_no_finalizer_node, finalize_deintifier_node): New macros.
	(class_has_finalize_method): declare.
	(HAS_FINALIZER_P): New macro.
	* parse.y (patch_invoke): Generate calls for finalizer-free
	allocation.

From-SVN: r48004
This commit is contained in:
Hans Boehm 2001-12-14 19:01:02 +00:00 committed by Hans Boehm
parent abf80f8ff8
commit eec875422f
6 changed files with 82 additions and 12 deletions

View File

@ -1,3 +1,21 @@
2001-12-14 Hans Boehm <Hans_Boehm@hp.com>
* class.c (get_dispatch_table): Fix java vtable layout
for TARGET_VTABLE_USES_DESCRIPTORS.
* decl.c (java_init_decl_processing): Initialize
alloc_no_finalizer_node, finalize_identifier_node.
* expr.c (class_has_finalize_method): New function.
(expand_java_NEW): Generate calls for finalizer-free allocation.
(build_invokevirtual): Fix java vtable layout for
TARGET_VTABLE_USES_DESCRIPTORS.
* java-tree.h (enum java_tree_index): New entries:
JTI_ALLOC_NO_FINALIZER_NODE, JTI_FINALIZE_IDENTIFIER_NODE.
(alloc_no_finalizer_node, finalize_deintifier_node): New macros.
(class_has_finalize_method): declare.
(HAS_FINALIZER_P): New macro.
* parse.y (patch_invoke): Generate calls for finalizer-free
allocation.
2001-12-12 Matthias Klose <doko@debian.org>
* Make-lang.in: JAVA_INSTALL_NAME, JAVA_CROSS_NAME: Remove

View File

@ -694,6 +694,13 @@ add_method_1 (handle_class, access_flags, name, function_type)
TREE_CHAIN (fndecl) = TYPE_METHODS (handle_class);
TYPE_METHODS (handle_class) = fndecl;
/* Notice that this is a finalizer and update the class type
accordingly. This is used to optimize instance allocation. */
if (name == finalize_identifier_node
&& TREE_TYPE (function_type) == void_type_node
&& TREE_VALUE (TYPE_ARG_TYPES (function_type)) == void_type_node)
HAS_FINALIZER_P (handle_class) = 1;
if (access_flags & ACC_PUBLIC) METHOD_PUBLIC (fndecl) = 1;
if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1;
if (access_flags & ACC_PRIVATE)
@ -1374,6 +1381,7 @@ get_dispatch_table (type, this_class_addr)
tree list = NULL_TREE;
int nvirtuals = TREE_VEC_LENGTH (vtable);
int arraysize;
tree gc_descr;
for (i = nvirtuals; --i >= 0; )
{
@ -1415,15 +1423,17 @@ get_dispatch_table (type, this_class_addr)
using the Boehm GC we sometimes stash a GC type descriptor
there. We set the PURPOSE to NULL_TREE not to interfere (reset)
the emitted byte count during the output to the assembly file. */
for (j = 1; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j)
list = tree_cons (NULL_TREE, null_pointer_node, list);
list = tree_cons (NULL_TREE, get_boehm_type_descriptor (type), list);
for (j = 1; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j)
list = tree_cons (NULL_TREE, null_pointer_node, list);
/* With TARGET_VTABLE_USES_DESCRIPTORS, we only add one extra
fake "function descriptor". It's first word is the is the class
pointer, and subsequent words (usually one) contain the GC descriptor.
In all other cases, we reserve two extra vtable slots. */
gc_descr = get_boehm_type_descriptor (type);
list = tree_cons (NULL_TREE, gc_descr, list);
for (j = 1; j < TARGET_VTABLE_USES_DESCRIPTORS-1; ++j)
list = tree_cons (NULL_TREE, gc_descr, list);
list = tree_cons (integer_zero_node, this_class_addr, list);
arraysize = nvirtuals + 2;
arraysize = (TARGET_VTABLE_USES_DESCRIPTORS? nvirtuals + 1 : nvirtuals + 2);
if (TARGET_VTABLE_USES_DESCRIPTORS)
arraysize *= TARGET_VTABLE_USES_DESCRIPTORS;
return build (CONSTRUCTOR,

View File

@ -586,6 +586,7 @@ java_init_decl_processing ()
instinit_identifier_node = get_identifier ("instinit$");
void_signature_node = get_identifier ("()V");
length_identifier_node = get_identifier ("length");
finalize_identifier_node = get_identifier ("finalize");
this_identifier_node = get_identifier ("this");
super_identifier_node = get_identifier ("super");
continue_identifier_node = get_identifier ("continue");
@ -729,6 +730,11 @@ java_init_decl_processing ()
build_function_type (ptr_type_node, t),
0, NOT_BUILT_IN, NULL);
DECL_IS_MALLOC (alloc_object_node) = 1;
alloc_no_finalizer_node =
builtin_function ("_Jv_AllocObjectNoFinalizer",
build_function_type (ptr_type_node, t),
0, NOT_BUILT_IN, NULL);
DECL_IS_MALLOC (alloc_no_finalizer_node) = 1;
t = tree_cons (NULL_TREE, ptr_type_node, endlink);
soft_initclass_node = builtin_function ("_Jv_InitClass",

View File

@ -1131,15 +1131,31 @@ build_address_of (value)
return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), value);
}
bool class_has_finalize_method (type)
tree type;
{
tree super = CLASSTYPE_SUPER (type);
if (super == NULL_TREE)
return false; /* Every class with a real finalizer inherits */
/* from java.lang.Object. */
else
return HAS_FINALIZER_P (type) || class_has_finalize_method (super);
}
static void
expand_java_NEW (type)
tree type;
{
tree alloc_node;
alloc_node = (class_has_finalize_method (type) ? alloc_object_node
: alloc_no_finalizer_node);
if (! CLASS_LOADED_P (type))
load_class (type, 1);
safe_layout_class (type);
push_value (build (CALL_EXPR, promote_type (type),
build_address_of (alloc_object_node),
build_address_of (alloc_node),
tree_cons (NULL_TREE, build_class_ref (type),
build_tree_list (NULL_TREE,
size_in_bytes (type))),
@ -1849,9 +1865,12 @@ build_invokevirtual (dtable, method)
= build_pointer_type (nativecode_ptr_type_node);
tree method_index = convert (sizetype, DECL_VINDEX (method));
/* Add one to skip "class" field of dtable, and one to skip unused
vtable entry (for C++ compatibility). */
method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
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));

View File

@ -60,6 +60,7 @@ struct JCF;
RESOLVE_PACKAGE_NAME_P (in EXPR_WITH_FILE_LOCATION)
SWITCH_HAS_DEFAULT (in SWITCH_EXPR)
ZIP_FILE_P (in TREE_LIST in current_file_list)
HAS_FINALIZER (in RECORD_TYPE)
4: IS_A_COMMAND_LINE_FILENAME_P (in IDENTIFIER_NODE)
RESOLVE_TYPE_NAME_P (in EXPR_WITH_FILE_LOCATION)
CALL_USING_SUPER (in CALL_EXPR)
@ -290,6 +291,7 @@ enum java_tree_index
JTI_FINIT_LEG_IDENTIFIER_NODE,
JTI_VOID_SIGNATURE_NODE,
JTI_LENGTH_IDENTIFIER_NODE,
JTI_FINALIZE_IDENTIFIER_NODE,
JTI_THIS_IDENTIFIER_NODE,
JTI_SUPER_IDENTIFIER_NODE,
JTI_CONTINUE_IDENTIFIER_NODE,
@ -334,6 +336,7 @@ enum java_tree_index
JTI_THROW_NODE,
JTI_ALLOC_OBJECT_NODE,
JTI_ALLOC_NO_FINALIZER_NODE,
JTI_SOFT_INSTANCEOF_NODE,
JTI_SOFT_CHECKCAST_NODE,
JTI_SOFT_INITCLASS_NODE,
@ -485,6 +488,8 @@ extern tree java_global_trees[JTI_MAX];
java_global_trees[JTI_VOID_SIGNATURE_NODE] /* "()V" */
#define length_identifier_node \
java_global_trees[JTI_LENGTH_IDENTIFIER_NODE] /* "length" */
#define finalize_identifier_node \
java_global_trees[JTI_FINALIZE_IDENTIFIER_NODE] /* "finalize" */
#define this_identifier_node \
java_global_trees[JTI_THIS_IDENTIFIER_NODE] /* "this" */
#define super_identifier_node \
@ -569,6 +574,8 @@ extern tree java_global_trees[JTI_MAX];
java_global_trees[JTI_THROW_NODE]
#define alloc_object_node \
java_global_trees[JTI_ALLOC_OBJECT_NODE]
#define alloc_no_finalizer_node \
java_global_trees[JTI_ALLOC_NO_FINALIZER_NODE]
#define soft_instanceof_node \
java_global_trees[JTI_SOFT_INSTANCEOF_NODE]
#define soft_checkcast_node \
@ -1163,6 +1170,7 @@ extern void java_debug_context PARAMS ((void));
extern void safe_layout_class PARAMS ((tree));
extern tree get_boehm_type_descriptor PARAMS ((tree));
extern bool class_has_finalize_method PARAMS ((tree));
extern unsigned long java_hash_hash_tree_node PARAMS ((hash_table_key));
extern bool java_hash_compare_tree_node PARAMS ((hash_table_key,
hash_table_key));
@ -1421,6 +1429,10 @@ extern tree *type_map;
already checked (for redifitions, etc, see java_check_regular_methods.) */
#define CLASS_METHOD_CHECKED_P(EXPR) TREE_LANG_FLAG_2 (EXPR)
/* True if TYPE (a TREE_TYPE denoting a class type) was found to
feature a finalizer method. */
#define HAS_FINALIZER_P(EXPR) TREE_LANG_FLAG_3 (EXPR)
/* True if EXPR (a WFL in that case) resolves into an expression name */
#define RESOLVE_EXPRESSION_NAME_P(WFL) TREE_LANG_FLAG_0 (WFL)

View File

@ -10662,6 +10662,8 @@ patch_invoke (patch, method, args)
{
tree class = DECL_CONTEXT (method);
tree c1, saved_new, size, new;
tree alloc_node;
if (flag_emit_class_files || flag_emit_xref)
{
TREE_TYPE (patch) = build_pointer_type (class);
@ -10670,8 +10672,11 @@ patch_invoke (patch, method, args)
if (!TYPE_SIZE (class))
safe_layout_class (class);
size = size_in_bytes (class);
alloc_node =
(class_has_finalize_method (class) ? alloc_object_node
: alloc_no_finalizer_node);
new = build (CALL_EXPR, promote_type (class),
build_address_of (alloc_object_node),
build_address_of (alloc_node),
tree_cons (NULL_TREE, build_class_ref (class),
build_tree_list (NULL_TREE,
size_in_bytes (class))),