aboutsummaryrefslogtreecommitdiff
path: root/gcc/java
diff options
context:
space:
mode:
authorHans Boehm <Hans_Boehm@hp.com>2001-12-14 19:01:02 +0000
committerHans Boehm <hboehm@gcc.gnu.org>2001-12-14 19:01:02 +0000
commiteec875422f79e536fcde443bfe8c0a01b260deb2 (patch)
treedef86bbb77acbb0823471cf90f10ce49709dfe9d /gcc/java
parentabf80f8ff8818e104126e16df6bfcc97587a9cce (diff)
downloadgcc-eec875422f79e536fcde443bfe8c0a01b260deb2.zip
gcc-eec875422f79e536fcde443bfe8c0a01b260deb2.tar.gz
gcc-eec875422f79e536fcde443bfe8c0a01b260deb2.tar.bz2
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
Diffstat (limited to 'gcc/java')
-rw-r--r--gcc/java/ChangeLog18
-rw-r--r--gcc/java/class.c24
-rw-r--r--gcc/java/decl.c6
-rw-r--r--gcc/java/expr.c27
-rw-r--r--gcc/java/java-tree.h12
-rw-r--r--gcc/java/parse.y7
6 files changed, 82 insertions, 12 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 96edf32..3654cff 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -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
diff --git a/gcc/java/class.c b/gcc/java/class.c
index f328806..5695aba 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -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,
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 0b1e016..17b3607 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -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",
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index f865d95..ef1a139 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -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));
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 63c08d7..9d11bf6 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -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)
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index 80c60fd..4dae766 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -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))),