summaryrefslogtreecommitdiff
path: root/gcc/java
diff options
context:
space:
mode:
authoraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>2006-05-04 18:44:53 +0000
committeraph <aph@138bc75d-0d04-0410-961f-82ee72b054a4>2006-05-04 18:44:53 +0000
commitecc74eeaa9039b5cca365292229f95e4ff0df24b (patch)
tree53c5cc5b6cfb9186e5f76d34fc5fec1124c7e943 /gcc/java
parentbbfdda8b30845a74660e87202c4bcc24e4c25e2f (diff)
downloadgcc-ecc74eeaa9039b5cca365292229f95e4ff0df24b.tar.gz
2006-05-04 Andrew Haley <aph@redhat.com>
* class.c (make_field_value): Always build_address_of fdecl if there is an initializer. 2006-05-03 Andrew Haley <aph@redhat.com> PR libgcj/27352 * expr.c (maybe_rewrite_invocation): New function. (rewrite_arglist_getclass): Likewise. (rules): New. (expand_invoke): Call maybe_rewrite_invocation. * parse.y (patch_invoke): Likewise. * java-tree.h: (maybe_rewrite_invocation): New function. 2006-05-03 Andrew Haley <aph@redhat.com> PR libgcj/27352 * java/lang/Class.java (getClassLoader(Class)): New. forName(String, Class): New. * java/lang/natClass.cc (getClassLoader(Class)): New. 2006-05-02 Andrew Haley <aph@redhat.com> * prims.cc (_Jv_NewMultiArray): Check for phantom class. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@113532 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java')
-rw-r--r--gcc/java/ChangeLog15
-rw-r--r--gcc/java/class.c3
-rw-r--r--gcc/java/expr.c82
-rw-r--r--gcc/java/java-tree.h1
-rw-r--r--gcc/java/parse.y1
5 files changed, 101 insertions, 1 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 2ce57c0fdc1..93deeb2f78f 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,18 @@
+2006-05-04 Andrew Haley <aph@redhat.com>
+
+ * class.c (make_field_value): Always build_address_of fdecl if
+ there is an initializer.
+
+2006-05-03 Andrew Haley <aph@redhat.com>
+
+ PR libgcj/27352
+ * expr.c (maybe_rewrite_invocation): New function.
+ (rewrite_arglist_getclass): Likewise.
+ (rules): New.
+ (expand_invoke): Call maybe_rewrite_invocation.
+ * parse.y (patch_invoke): Likewise.
+ * java-tree.h: (maybe_rewrite_invocation): New function.
+
2006-04-21 Andrew Haley <aph@redhat.com>
* lang.c (java_init): Handle flag_indirect_classes.
diff --git a/gcc/java/class.c b/gcc/java/class.c
index fe52e67d4ac..590925d3ab2 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -1344,7 +1344,8 @@ make_field_value (tree fdecl)
{
tree field_address = integer_zero_node;
- if (! flag_indirect_classes && FIELD_STATIC (fdecl))
+ if ((DECL_INITIAL (fdecl) || ! flag_indirect_classes)
+ && FIELD_STATIC (fdecl))
field_address = build_address_of (fdecl);
PUSH_FIELD_VALUE
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index 1cd405a6bb7..b2e03fc862e 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -2020,6 +2020,86 @@ build_class_init (tree clas, tree expr)
return init;
}
+
+
+/* Rewrite expensive calls that require stack unwinding at runtime to
+ cheaper alternatives. The logic here performs thse
+ transformations:
+
+ java.lang.Class.forName("foo") -> java.lang.Class.forName("foo", class$)
+ java.lang.Class.getClassLoader() -> java.lang.Class.getClassLoader(class$)
+
+*/
+
+typedef struct
+{
+ const char *classname;
+ const char *method;
+ const char *signature;
+ const char *new_signature;
+ int flags;
+ tree (*rewrite_arglist) (tree arglist);
+} rewrite_rule;
+
+/* Add this.class to the end of an arglist. */
+
+static tree
+rewrite_arglist_getclass (tree arglist)
+{
+ return chainon (arglist,
+ tree_cons (NULL_TREE, build_class_ref (output_class), NULL_TREE));
+}
+
+static rewrite_rule rules[] =
+ {{"java.lang.Class", "getClassLoader", "()Ljava/lang/ClassLoader;",
+ "(Ljava/lang/Class;)Ljava/lang/ClassLoader;",
+ ACC_FINAL|ACC_PRIVATE, rewrite_arglist_getclass},
+ {"java.lang.Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;",
+ "(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
+ ACC_FINAL|ACC_PRIVATE|ACC_STATIC, rewrite_arglist_getclass},
+ {NULL, NULL, NULL, NULL, 0, NULL}};
+
+/* Scan the rules list for replacements for *METHOD_P and replace the
+ args accordingly. */
+
+void
+maybe_rewrite_invocation (tree *method_p, tree *arg_list_p,
+ tree *method_signature_p)
+{
+ tree context = DECL_NAME (TYPE_NAME (DECL_CONTEXT (*method_p)));
+ rewrite_rule *p;
+ for (p = rules; p->classname; p++)
+ {
+ if (get_identifier (p->classname) == context)
+ {
+ tree method = DECL_NAME (*method_p);
+ if (get_identifier (p->method) == method
+ && get_identifier (p->signature) == *method_signature_p)
+ {
+ tree maybe_method
+ = lookup_java_method (DECL_CONTEXT (*method_p),
+ method,
+ get_identifier (p->new_signature));
+ if (! maybe_method && ! flag_verify_invocations)
+ {
+ maybe_method
+ = add_method (DECL_CONTEXT (*method_p), p->flags,
+ method, get_identifier (p->new_signature));
+ DECL_EXTERNAL (maybe_method) = 1;
+ }
+ *method_p = maybe_method;
+ gcc_assert (*method_p);
+ *arg_list_p = p->rewrite_arglist (*arg_list_p);
+ *method_signature_p = get_identifier (p->new_signature);
+
+ break;
+ }
+ }
+ }
+}
+
+
+
tree
build_known_method_ref (tree method, tree method_type ATTRIBUTE_UNUSED,
tree self_type, tree method_signature ATTRIBUTE_UNUSED,
@@ -2394,6 +2474,8 @@ expand_invoke (int opcode, int method_ref_index, int nargs ATTRIBUTE_UNUSED)
arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));
flush_quick_stack ();
+ maybe_rewrite_invocation (&method, &arg_list, &method_signature);
+
func = NULL_TREE;
if (opcode == OPCODE_invokestatic)
func = build_known_method_ref (method, method_type, self_type,
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 03a7ea2c142..de826b9c52d 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -1241,6 +1241,7 @@ extern tree check_for_builtin (tree, tree);
extern void initialize_builtins (void);
extern tree lookup_name (tree);
+extern void maybe_rewrite_invocation (tree *, tree *, tree *);
extern tree build_known_method_ref (tree, tree, tree, tree, tree);
extern tree build_class_init (tree, tree);
extern int attach_init_test_initialization_flags (void **, void *);
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index 118c66f8221..a606d87869e 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -11066,6 +11066,7 @@ patch_invoke (tree patch, tree method, tree args)
case INVOKE_STATIC:
{
tree signature = build_java_signature (TREE_TYPE (method));
+ maybe_rewrite_invocation (&method, &args, &signature);
func = build_known_method_ref (method, TREE_TYPE (method),
DECL_CONTEXT (method),
signature, args);