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:
parent
abf80f8ff8
commit
eec875422f
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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",
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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))),
|
||||
|
Loading…
Reference in New Issue
Block a user