This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: java: suppress java.lang.Object constructor
- To: java-patches at gcc dot gnu dot org
- Subject: PATCH: java: suppress java.lang.Object constructor
- From: Jeff Sturm <jsturm at one-point dot com>
- Date: Thu, 12 Jul 2001 10:21:17 -0400 (EDT)
- cc: gcc-patches at gcc dot gnu dot org
This patch prevents adding the implicit call to super's constructor in
classes derived from java.lang.Object. It's a simple and
straightforward optimization since java.lang.Object's constructor is an
empty function. (Note that someday when gcj has a real inliner this
special case should be unnecessary.)
The simplest patch didn't work because dropping super() has the unexpected
side effect of preventing calls to finit$. The logic in
patch_method_invocation is a little twisted IMHO so I've cleaned it up a
bit, handling finit$ similar to instance initializers.
Allocation times should improve slightly. In particular, for classes with
no constructors, e.g.:
class Point {
int x, y;
}
the constructors are completely eliminated at -O3 in which case the
trivial constructor is inlined. (My view is that all Java constructors
should be DECL_INLINE which I'll address in another patch. Then we'll get
the same benefit at -O2.) With this I observed a 5% improvement in
GCBench.
Tested on mainline with alphapca56-unknown-linux-gnu.
Jeff
2001-07-12 Jeff Sturm <jsturm@one-point.com>
* parse.y (build_super_invocation): Suppress call when super
is java.lang.Object.
(build_finit_invocation): New function.
(fix_constructors): Use it.
(patch_method_invocation): Don't build finit$ invocation here.
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.293
diff -u -p -r1.293 parse.y
--- parse.y 2001/07/05 22:33:44 1.293
+++ parse.y 2001/07/12 12:07:01
@@ -230,6 +230,7 @@ static void purge_unchecked_exceptions P
static void check_throws_clauses PARAMS ((tree, tree, tree));
static void finish_method_declaration PARAMS ((tree));
static tree build_super_invocation PARAMS ((tree));
+static tree build_finit_invocation PARAMS ((tree));
static int verify_constructor_circularity PARAMS ((tree, tree));
static char *constructor_circularity_msg PARAMS ((tree, tree));
static tree build_this_super_qualified_invocation PARAMS ((int, tree, tree,
@@ -8511,7 +8512,7 @@ fix_constructors (mdecl)
tree mdecl;
{
tree body = DECL_FUNCTION_BODY (mdecl);
- tree thisn_assign, compound = NULL_TREE;
+ tree thisn_assign, finit, compound = NULL_TREE;
tree class_type = DECL_CONTEXT (mdecl);
if (DECL_FIXED_CONSTRUCTOR_P (mdecl))
@@ -8551,8 +8552,13 @@ fix_constructors (mdecl)
of that. */
java_method_add_stmt (mdecl, build_super_invocation (mdecl));
- /* Insert the instance initializer block right here, after the
- super invocation. */
+ /* Insert the call to finit$, if any, before instance
+ initializers. */
+ if ((finit = build_finit_invocation (mdecl)))
+ java_method_add_stmt (mdecl, finit);
+
+ /* Insert the instance initializer block right here, after
+ finit$. */
add_instance_initializer (mdecl);
end_artificial_method_body (mdecl);
@@ -8605,8 +8611,12 @@ fix_constructors (mdecl)
TREE_OPERAND (found_call, 0));
TREE_OPERAND (found_call, 0) = empty_stmt_node;
}
-
- /* Insert the instance initializer block right after. */
+
+ /* Insert any finit$ invocation after super. */
+ if (!invokes_this && (finit = build_finit_invocation (mdecl)))
+ compound = add_stmt_to_compound (compound, NULL_TREE, finit);
+
+ /* Insert the instance initializer block after finit$. */
if (!invokes_this && (ii = build_instance_initializer (mdecl)))
compound = add_stmt_to_compound (compound, NULL_TREE, ii);
@@ -10164,25 +10174,6 @@ patch_method_invocation (patch, primary,
if (ret_decl)
*ret_decl = list;
patch = patch_invoke (patch, list, args);
- if (is_super_init && CLASS_HAS_FINIT_P (current_class))
- {
- tree finit_parms, finit_call;
-
- /* Prepare to pass hidden parameters to finit$, if any. */
- finit_parms = build_alias_initializer_parameter_list
- (AIPL_FUNCTION_FINIT_INVOCATION, current_class, NULL_TREE, NULL);
-
- finit_call =
- build_method_invocation (build_wfl_node (finit_identifier_node),
- finit_parms);
-
- /* Generate the code used to initialize fields declared with an
- initialization statement and build a compound statement along
- with the super constructor invocation. */
- patch = build (COMPOUND_EXPR, void_type_node, patch,
- java_complete_tree (finit_call));
- CAN_COMPLETE_NORMALLY (patch) = 1;
- }
return patch;
}
@@ -12068,7 +12059,11 @@ static tree
build_super_invocation (mdecl)
tree mdecl;
{
- if (DECL_CONTEXT (mdecl) == object_type_node)
+ /* Don't attempt to invoke a super constructor if we're compiling
+ java.lang.Object. Also don't bother if we're deriving from
+ java.lang.Object since its constructor does nothing. */
+ if (DECL_CONTEXT (mdecl) == object_type_node
+ || CLASSTYPE_SUPER (DECL_CONTEXT (mdecl)) == object_type_node)
return empty_stmt_node;
else
{
@@ -12083,6 +12078,28 @@ build_super_invocation (mdecl)
a = tree_cons (NULL_TREE, build_wfl_node (TREE_PURPOSE (t)), a);
}
return build_method_invocation (super_wfl, a);
+ }
+}
+
+/* Build a finit$ invocation. */
+
+static tree
+build_finit_invocation (mdecl)
+ tree mdecl;
+{
+ if (!CLASS_HAS_FINIT_P (DECL_CONTEXT (mdecl)))
+ return empty_stmt_node;
+ else
+ {
+ tree finit_wfl = build_wfl_node (finit_identifier_node);
+ tree finit_parms;
+
+ /* Prepare to pass hidden parameters to finit$, if any. */
+ finit_parms = build_alias_initializer_parameter_list
+ (AIPL_FUNCTION_FINIT_INVOCATION, DECL_CONTEXT (mdecl),
+ NULL_TREE, NULL);
+
+ return build_method_invocation (finit_wfl, finit_parms);
}
}