class.c (get_dispatch_table): Fix java vtable layout for TARGET_VTABLE_USES_DESCRIPTORS.
authorHans Boehm <Hans_Boehm@hp.com>
Fri, 14 Dec 2001 19:01:02 +0000 (19:01 +0000)
committerHans Boehm <hboehm@gcc.gnu.org>
Fri, 14 Dec 2001 19:01:02 +0000 (19:01 +0000)
* 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

gcc/java/ChangeLog
gcc/java/class.c
gcc/java/decl.c
gcc/java/expr.c
gcc/java/java-tree.h
gcc/java/parse.y

index 96edf3246bdc26e7979819e45aaca86220664b1a..3654cff875eba5e8af76b2608ec3f0d59b11f704 100644 (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
index f328806af6d14ec2dfc701d89ae5c6dab9ec39f6..5695aba3e40008305930d6a3abe7870c8e3a560c 100644 (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,
index 0b1e0164116c331e25e8560877aaedd8c36904ec..17b3607a8717aef692257f19566c362c4ceea03a 100644 (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",
index f865d95800894d857189a6cd587202065f6d2645..ef1a13959e1e156e80a5d715e7f016447dfb8e10 100644 (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));
 
index 63c08d7c80d960a36e56f8678312ca7d267688e3..9d11bf6baf12b63a8f3dd655e08a8626582463d4 100644 (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)
 
index 80c60fd570c95b775d118b5031904f85daa86b06..4dae766a695a788e1fde5ee78bee1e805d625f6c 100644 (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))),