[multiple changes]
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. From-SVN: r113532
This commit is contained in:
parent
a7285117b4
commit
b2ed63b4aa
10 changed files with 143 additions and 4 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
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.
|
||||
|
||||
2006-05-04 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
PR libgcj/26861:
|
||||
|
|
|
@ -297,6 +297,8 @@ public:
|
|||
JArray<jclass> *getClasses (void);
|
||||
|
||||
java::lang::ClassLoader *getClassLoader (void);
|
||||
private:
|
||||
java::lang::ClassLoader *getClassLoader (jclass caller);
|
||||
public:
|
||||
// This is an internal method that circumvents the usual security
|
||||
// checks when getting the class loader.
|
||||
|
|
|
@ -111,6 +111,14 @@ public final class Class implements Serializable
|
|||
public static native Class forName (String className)
|
||||
throws ClassNotFoundException;
|
||||
|
||||
// A private internal method that is called by compiler-generated code.
|
||||
private static Class forName (String className, Class caller)
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
return forName(className, true, caller.getClassLoader());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Use the specified classloader to load and link a class. If the loader
|
||||
* is null, this uses the bootstrap class loader (provide the security
|
||||
|
@ -185,6 +193,9 @@ public final class Class implements Serializable
|
|||
*/
|
||||
public native ClassLoader getClassLoader ();
|
||||
|
||||
// A private internal method that is called by compiler-generated code.
|
||||
private final native ClassLoader getClassLoader (Class caller);
|
||||
|
||||
/**
|
||||
* If this is an array, get the Class representing the type of array.
|
||||
* Examples: "[[Ljava.lang.String;" would return "[Ljava.lang.String;", and
|
||||
|
|
|
@ -115,9 +115,19 @@ java::lang::Class::getClassLoader (void)
|
|||
if (s != NULL)
|
||||
{
|
||||
jclass caller = _Jv_StackTrace::GetCallingClass (&Class::class$);
|
||||
ClassLoader *caller_loader = NULL;
|
||||
if (caller)
|
||||
caller_loader = caller->getClassLoaderInternal();
|
||||
return getClassLoader (caller);
|
||||
}
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
java::lang::ClassLoader *
|
||||
java::lang::Class::getClassLoader (jclass caller)
|
||||
{
|
||||
java::lang::SecurityManager *s = java::lang::System::getSecurityManager();
|
||||
if (s != NULL)
|
||||
{
|
||||
ClassLoader *caller_loader = caller->getClassLoaderInternal();
|
||||
|
||||
// If the caller has a non-null class loader, and that loader
|
||||
// is not this class' loader or an ancestor thereof, then do a
|
||||
|
|
|
@ -762,6 +762,11 @@ _Jv_NewMultiArray (jclass type, jint dimensions, jint *sizes)
|
|||
jobject
|
||||
_Jv_NewMultiArray (jclass array_type, jint dimensions, ...)
|
||||
{
|
||||
// Creating an array of an unresolved type is impossible. So we throw
|
||||
// the NoClassDefFoundError.
|
||||
if (_Jv_IsPhantomClass(array_type))
|
||||
throw new java::lang::NoClassDefFoundError(array_type->getName());
|
||||
|
||||
va_list args;
|
||||
jint sizes[dimensions];
|
||||
va_start (args, dimensions);
|
||||
|
|
Loading…
Add table
Reference in a new issue