Commit eec87542 by Hans Boehm Committed by Hans Boehm

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
parent abf80f8f
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> 2001-12-12 Matthias Klose <doko@debian.org>
* Make-lang.in: JAVA_INSTALL_NAME, JAVA_CROSS_NAME: Remove * Make-lang.in: JAVA_INSTALL_NAME, JAVA_CROSS_NAME: Remove
......
...@@ -694,6 +694,13 @@ add_method_1 (handle_class, access_flags, name, function_type) ...@@ -694,6 +694,13 @@ add_method_1 (handle_class, access_flags, name, function_type)
TREE_CHAIN (fndecl) = TYPE_METHODS (handle_class); TREE_CHAIN (fndecl) = TYPE_METHODS (handle_class);
TYPE_METHODS (handle_class) = fndecl; 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_PUBLIC) METHOD_PUBLIC (fndecl) = 1;
if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1; if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1;
if (access_flags & ACC_PRIVATE) if (access_flags & ACC_PRIVATE)
...@@ -1374,6 +1381,7 @@ get_dispatch_table (type, this_class_addr) ...@@ -1374,6 +1381,7 @@ get_dispatch_table (type, this_class_addr)
tree list = NULL_TREE; tree list = NULL_TREE;
int nvirtuals = TREE_VEC_LENGTH (vtable); int nvirtuals = TREE_VEC_LENGTH (vtable);
int arraysize; int arraysize;
tree gc_descr;
for (i = nvirtuals; --i >= 0; ) for (i = nvirtuals; --i >= 0; )
{ {
...@@ -1415,15 +1423,17 @@ get_dispatch_table (type, this_class_addr) ...@@ -1415,15 +1423,17 @@ get_dispatch_table (type, this_class_addr)
using the Boehm GC we sometimes stash a GC type descriptor using the Boehm GC we sometimes stash a GC type descriptor
there. We set the PURPOSE to NULL_TREE not to interfere (reset) there. We set the PURPOSE to NULL_TREE not to interfere (reset)
the emitted byte count during the output to the assembly file. */ the emitted byte count during the output to the assembly file. */
for (j = 1; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j) /* With TARGET_VTABLE_USES_DESCRIPTORS, we only add one extra
list = tree_cons (NULL_TREE, null_pointer_node, list); fake "function descriptor". It's first word is the is the class
list = tree_cons (NULL_TREE, get_boehm_type_descriptor (type), list); pointer, and subsequent words (usually one) contain the GC descriptor.
In all other cases, we reserve two extra vtable slots. */
for (j = 1; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j) gc_descr = get_boehm_type_descriptor (type);
list = tree_cons (NULL_TREE, null_pointer_node, list); 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); 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) if (TARGET_VTABLE_USES_DESCRIPTORS)
arraysize *= TARGET_VTABLE_USES_DESCRIPTORS; arraysize *= TARGET_VTABLE_USES_DESCRIPTORS;
return build (CONSTRUCTOR, return build (CONSTRUCTOR,
......
...@@ -586,6 +586,7 @@ java_init_decl_processing () ...@@ -586,6 +586,7 @@ java_init_decl_processing ()
instinit_identifier_node = get_identifier ("instinit$"); instinit_identifier_node = get_identifier ("instinit$");
void_signature_node = get_identifier ("()V"); void_signature_node = get_identifier ("()V");
length_identifier_node = get_identifier ("length"); length_identifier_node = get_identifier ("length");
finalize_identifier_node = get_identifier ("finalize");
this_identifier_node = get_identifier ("this"); this_identifier_node = get_identifier ("this");
super_identifier_node = get_identifier ("super"); super_identifier_node = get_identifier ("super");
continue_identifier_node = get_identifier ("continue"); continue_identifier_node = get_identifier ("continue");
...@@ -729,6 +730,11 @@ java_init_decl_processing () ...@@ -729,6 +730,11 @@ java_init_decl_processing ()
build_function_type (ptr_type_node, t), build_function_type (ptr_type_node, t),
0, NOT_BUILT_IN, NULL); 0, NOT_BUILT_IN, NULL);
DECL_IS_MALLOC (alloc_object_node) = 1; 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); t = tree_cons (NULL_TREE, ptr_type_node, endlink);
soft_initclass_node = builtin_function ("_Jv_InitClass", soft_initclass_node = builtin_function ("_Jv_InitClass",
......
...@@ -1131,15 +1131,31 @@ build_address_of (value) ...@@ -1131,15 +1131,31 @@ build_address_of (value)
return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (value)), 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 static void
expand_java_NEW (type) expand_java_NEW (type)
tree 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)) if (! CLASS_LOADED_P (type))
load_class (type, 1); load_class (type, 1);
safe_layout_class (type); safe_layout_class (type);
push_value (build (CALL_EXPR, promote_type (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), tree_cons (NULL_TREE, build_class_ref (type),
build_tree_list (NULL_TREE, build_tree_list (NULL_TREE,
size_in_bytes (type))), size_in_bytes (type))),
...@@ -1849,9 +1865,12 @@ build_invokevirtual (dtable, method) ...@@ -1849,9 +1865,12 @@ build_invokevirtual (dtable, method)
= build_pointer_type (nativecode_ptr_type_node); = build_pointer_type (nativecode_ptr_type_node);
tree method_index = convert (sizetype, DECL_VINDEX (method)); tree method_index = convert (sizetype, DECL_VINDEX (method));
/* Add one to skip "class" field of dtable, and one to skip unused if (TARGET_VTABLE_USES_DESCRIPTORS)
vtable entry (for C++ compatibility). */ /* Add one to skip bogus descriptor for class and GC descriptor. */
method_index = size_binop (PLUS_EXPR, method_index, size_int (2)); 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, method_index = size_binop (MULT_EXPR, method_index,
TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node)); TYPE_SIZE_UNIT (nativecode_ptr_ptr_type_node));
......
...@@ -60,6 +60,7 @@ struct JCF; ...@@ -60,6 +60,7 @@ struct JCF;
RESOLVE_PACKAGE_NAME_P (in EXPR_WITH_FILE_LOCATION) RESOLVE_PACKAGE_NAME_P (in EXPR_WITH_FILE_LOCATION)
SWITCH_HAS_DEFAULT (in SWITCH_EXPR) SWITCH_HAS_DEFAULT (in SWITCH_EXPR)
ZIP_FILE_P (in TREE_LIST in current_file_list) 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) 4: IS_A_COMMAND_LINE_FILENAME_P (in IDENTIFIER_NODE)
RESOLVE_TYPE_NAME_P (in EXPR_WITH_FILE_LOCATION) RESOLVE_TYPE_NAME_P (in EXPR_WITH_FILE_LOCATION)
CALL_USING_SUPER (in CALL_EXPR) CALL_USING_SUPER (in CALL_EXPR)
...@@ -290,6 +291,7 @@ enum java_tree_index ...@@ -290,6 +291,7 @@ enum java_tree_index
JTI_FINIT_LEG_IDENTIFIER_NODE, JTI_FINIT_LEG_IDENTIFIER_NODE,
JTI_VOID_SIGNATURE_NODE, JTI_VOID_SIGNATURE_NODE,
JTI_LENGTH_IDENTIFIER_NODE, JTI_LENGTH_IDENTIFIER_NODE,
JTI_FINALIZE_IDENTIFIER_NODE,
JTI_THIS_IDENTIFIER_NODE, JTI_THIS_IDENTIFIER_NODE,
JTI_SUPER_IDENTIFIER_NODE, JTI_SUPER_IDENTIFIER_NODE,
JTI_CONTINUE_IDENTIFIER_NODE, JTI_CONTINUE_IDENTIFIER_NODE,
...@@ -334,6 +336,7 @@ enum java_tree_index ...@@ -334,6 +336,7 @@ enum java_tree_index
JTI_THROW_NODE, JTI_THROW_NODE,
JTI_ALLOC_OBJECT_NODE, JTI_ALLOC_OBJECT_NODE,
JTI_ALLOC_NO_FINALIZER_NODE,
JTI_SOFT_INSTANCEOF_NODE, JTI_SOFT_INSTANCEOF_NODE,
JTI_SOFT_CHECKCAST_NODE, JTI_SOFT_CHECKCAST_NODE,
JTI_SOFT_INITCLASS_NODE, JTI_SOFT_INITCLASS_NODE,
...@@ -485,6 +488,8 @@ extern tree java_global_trees[JTI_MAX]; ...@@ -485,6 +488,8 @@ extern tree java_global_trees[JTI_MAX];
java_global_trees[JTI_VOID_SIGNATURE_NODE] /* "()V" */ java_global_trees[JTI_VOID_SIGNATURE_NODE] /* "()V" */
#define length_identifier_node \ #define length_identifier_node \
java_global_trees[JTI_LENGTH_IDENTIFIER_NODE] /* "length" */ java_global_trees[JTI_LENGTH_IDENTIFIER_NODE] /* "length" */
#define finalize_identifier_node \
java_global_trees[JTI_FINALIZE_IDENTIFIER_NODE] /* "finalize" */
#define this_identifier_node \ #define this_identifier_node \
java_global_trees[JTI_THIS_IDENTIFIER_NODE] /* "this" */ java_global_trees[JTI_THIS_IDENTIFIER_NODE] /* "this" */
#define super_identifier_node \ #define super_identifier_node \
...@@ -569,6 +574,8 @@ extern tree java_global_trees[JTI_MAX]; ...@@ -569,6 +574,8 @@ extern tree java_global_trees[JTI_MAX];
java_global_trees[JTI_THROW_NODE] java_global_trees[JTI_THROW_NODE]
#define alloc_object_node \ #define alloc_object_node \
java_global_trees[JTI_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 \ #define soft_instanceof_node \
java_global_trees[JTI_SOFT_INSTANCEOF_NODE] java_global_trees[JTI_SOFT_INSTANCEOF_NODE]
#define soft_checkcast_node \ #define soft_checkcast_node \
...@@ -1163,6 +1170,7 @@ extern void java_debug_context PARAMS ((void)); ...@@ -1163,6 +1170,7 @@ extern void java_debug_context PARAMS ((void));
extern void safe_layout_class PARAMS ((tree)); extern void safe_layout_class PARAMS ((tree));
extern tree get_boehm_type_descriptor 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 unsigned long java_hash_hash_tree_node PARAMS ((hash_table_key));
extern bool java_hash_compare_tree_node PARAMS ((hash_table_key, extern bool java_hash_compare_tree_node PARAMS ((hash_table_key,
hash_table_key)); hash_table_key));
...@@ -1421,6 +1429,10 @@ extern tree *type_map; ...@@ -1421,6 +1429,10 @@ extern tree *type_map;
already checked (for redifitions, etc, see java_check_regular_methods.) */ already checked (for redifitions, etc, see java_check_regular_methods.) */
#define CLASS_METHOD_CHECKED_P(EXPR) TREE_LANG_FLAG_2 (EXPR) #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 */ /* True if EXPR (a WFL in that case) resolves into an expression name */
#define RESOLVE_EXPRESSION_NAME_P(WFL) TREE_LANG_FLAG_0 (WFL) #define RESOLVE_EXPRESSION_NAME_P(WFL) TREE_LANG_FLAG_0 (WFL)
......
...@@ -10662,6 +10662,8 @@ patch_invoke (patch, method, args) ...@@ -10662,6 +10662,8 @@ patch_invoke (patch, method, args)
{ {
tree class = DECL_CONTEXT (method); tree class = DECL_CONTEXT (method);
tree c1, saved_new, size, new; tree c1, saved_new, size, new;
tree alloc_node;
if (flag_emit_class_files || flag_emit_xref) if (flag_emit_class_files || flag_emit_xref)
{ {
TREE_TYPE (patch) = build_pointer_type (class); TREE_TYPE (patch) = build_pointer_type (class);
...@@ -10670,8 +10672,11 @@ patch_invoke (patch, method, args) ...@@ -10670,8 +10672,11 @@ patch_invoke (patch, method, args)
if (!TYPE_SIZE (class)) if (!TYPE_SIZE (class))
safe_layout_class (class); safe_layout_class (class);
size = size_in_bytes (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), 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), tree_cons (NULL_TREE, build_class_ref (class),
build_tree_list (NULL_TREE, build_tree_list (NULL_TREE,
size_in_bytes (class))), size_in_bytes (class))),
......
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