aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2006-03-07 14:13:09 +0000
committerAndrew Haley <aph@redhat.com>2006-03-07 14:13:09 +0000
commitcb0e335406b63bbe1176a4cf0f7681de795c0a88 (patch)
tree30bcbf8989f494313f2afdc8db024653be927d14
parente9597daa742f2eca1491f36b909accaece64f2b0 (diff)
2006-03-07 Andrew Haley <aph@redhat.com>
* jvgenmain.c: If flag_indirect_classes, generate access to _class$_<classname>. * mangle.c (java_mangle_decl): Mangle record types too. * jvspec.c: Allow -findirect-classes. * constants.c (build_ref_from_constant_pool): If flag_indirect_classes, build a constant ref via the class, not directly. * decl.c (constants_field_decl_node, constants_data_field_decl_node): New variables. (java_init_decl_processing): Initialize them. * class.c (build_static_class_ref): New function. (build_class_ref): Change direct ref to class to indirect ref to _class$_<classname>. (build_class_ref): Call build_static_class_ref. (make_field_value): If flag_indirect_classes, don't create a pointer to a field. (make_class_data): Call build_static_class_ref instead of build_class_ref. (register_class): If flag_indirect_classes, just push current_class instead of generating a class ref. (emit_indirect_register_classes): Nw function. (emit_register_classes): If flag_indirect_classes, call emit_indirect_register_classes. 2006-03-07 Andrew Haley <aph@redhat.com> * include/execution.h (do_allocate_static_fields): Allocate the static fields. * java/lang/Class.h (_Jv_NewClassFromInitializer): Declare * java/lang/natClassLoader.cc (_Jv_NewClassFromInitializer): New function. * boehm.cc (_Jv_InitGC): Return if gc is already initialized. * gnu/gcj/runtime/natSharedLibLoader.cc (_Jv_GC_has_static_roots): New function. 2006-03-07 Andrew Haley <aph@redhat.com> * dyn_load.c (GC_has_static_roots): Declare. (GC_register_dynlib_callback): Call GC_has_static_roots. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcj/gcj-abi-experimental-branch@111806 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--boehm-gc/ChangeLog5
-rw-r--r--boehm-gc/dyn_load.c7
-rw-r--r--gcc/java/ChangeLog26
-rw-r--r--gcc/java/Make-lang.in6
-rw-r--r--gcc/java/class.c137
-rw-r--r--gcc/java/config-lang.in2
-rw-r--r--gcc/java/constants.c23
-rw-r--r--gcc/java/decl.c6
-rw-r--r--gcc/java/java-expr.c2
-rw-r--r--gcc/java/java-tree.h7
-rw-r--r--gcc/java/jvgenmain.c66
-rw-r--r--gcc/java/jvspec.c2
-rw-r--r--gcc/java/lang.opt4
-rw-r--r--gcc/java/mangle.c3
-rw-r--r--libjava/ChangeLog11
-rw-r--r--libjava/boehm.cc6
-rw-r--r--libjava/gnu/gcj/runtime/natSharedLibLoader.cc28
-rw-r--r--libjava/include/execution.h20
-rw-r--r--libjava/java/lang/Class.h3
-rw-r--r--libjava/java/lang/natClassLoader.cc38
20 files changed, 352 insertions, 50 deletions
diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog
index 81bf9f6112f..3ba8ebbe488 100644
--- a/boehm-gc/ChangeLog
+++ b/boehm-gc/ChangeLog
@@ -1,3 +1,8 @@
+2006-03-07 Andrew Haley <aph@redhat.com>
+
+ * dyn_load.c (GC_has_static_roots): Declare.
+ (GC_register_dynlib_callback): Call GC_has_static_roots.
+
2006-02-09 Tom Tromey <tromey@redhat.com>
* pthread_support.c: Conditionally include dlfcn.h.
diff --git a/boehm-gc/dyn_load.c b/boehm-gc/dyn_load.c
index 749bf824681..ae1dc76a7d9 100644
--- a/boehm-gc/dyn_load.c
+++ b/boehm-gc/dyn_load.c
@@ -390,6 +390,9 @@ GC_bool GC_register_main_static_data()
/* Thus we also treat it as a weak symbol. */
#define HAVE_DL_ITERATE_PHDR
+int (*GC_has_static_roots)(struct dl_phdr_info * info, size_t size, void *ptr)
+ __attribute__((weak));
+
static int GC_register_dynlib_callback(info, size, ptr)
struct dl_phdr_info * info;
size_t size;
@@ -411,6 +414,10 @@ static int GC_register_dynlib_callback(info, size, ptr)
{
if( !(p->p_flags & PF_W) ) break;
start = ((char *)(p->p_vaddr)) + info->dlpi_addr;
+
+ if (GC_has_static_roots && !GC_has_static_roots(info, size, start))
+ break;
+
GC_add_roots_inner(start, start + p->p_memsz, TRUE);
}
break;
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 3a36b6b766b..763389e1132 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,29 @@
+2006-03-07 Andrew Haley <aph@redhat.com>
+
+ * jvgenmain.c: If flag_indirect_classes, generate access to
+ _class$_<classname>.
+ * mangle.c (java_mangle_decl): Mangle record types too.
+ * jvspec.c: Allow -findirect-classes.
+ * constants.c (build_ref_from_constant_pool): If
+ flag_indirect_classes, build a constant ref via the class, not
+ directly.
+ * decl.c (constants_field_decl_node,
+ constants_data_field_decl_node): New variables.
+ (java_init_decl_processing): Initialize them.
+ * class.c (build_static_class_ref): New function.
+ (build_class_ref): Change direct ref to class to indirect ref to
+ _class$_<classname>.
+ (build_class_ref): Call build_static_class_ref.
+ (make_field_value): If flag_indirect_classes, don't create a
+ pointer to a field.
+ (make_class_data): Call build_static_class_ref instead of
+ build_class_ref.
+ (register_class): If flag_indirect_classes, just push
+ current_class instead of generating a class ref.
+ (emit_indirect_register_classes): Nw function.
+ (emit_register_classes): If flag_indirect_classes, call
+ emit_indirect_register_classes.
+
2006-02-20 Andrew Haley <aph@redhat.com>
* jcf-parse.c (parse_class_file): Set input_location from
diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in
index 8cecf4f702a..afbc8a10258 100644
--- a/gcc/java/Make-lang.in
+++ b/gcc/java/Make-lang.in
@@ -98,7 +98,7 @@ $(srcdir)/java/keyword.h: $(srcdir)/java/keyword.gperf
gt-java-parse.h : s-gtype ; @true
# Executables built by this Makefile:
-JAVA_OBJS = java/parse.o java/class.o java/decl.o java/expr.o \
+JAVA_OBJS = java/parse.o java/class.o java/decl.o java/java-expr.o \
java/constants.o java/lang.o java/typeck.o java/except.o \
java/verify-glue.o java/verify-impl.o \
java/zextract.o java/jcf-io.o java/win32-host.o java/jcf-parse.o java/mangle.o \
@@ -313,10 +313,10 @@ java/decl.o: java/decl.c $(CONFIG_H) $(JAVA_TREE_H) $(RTL_H) java/jcf.h \
java/except.o: java/except.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h real.h \
$(RTL_H) java/javaop.h java/java-opcodes.h except.h java/java-except.h \
toplev.h $(SYSTEM_H) coretypes.h $(TM_H) function.h
-java/expr.o: java/expr.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h real.h \
+java/java-expr.o: java/java-expr.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h real.h \
$(RTL_H) $(EXPR_H) java/javaop.h java/java-opcodes.h except.h \
java/java-except.h java/java-except.h java/parse.h toplev.h \
- $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) gt-java-expr.h target.h
+ $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) gt-java-java-expr.h target.h
java/jcf-depend.o: java/jcf-depend.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) java/jcf.h
java/jcf-parse.o: java/jcf-parse.c $(CONFIG_H) $(JAVA_TREE_H) flags.h \
diff --git a/gcc/java/class.c b/gcc/java/class.c
index e3eed983345..b8814ce6063 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -944,6 +944,38 @@ build_indirect_class_ref (tree type)
return convert (promote_type (class_ptr_type), cl);
}
+static tree
+build_static_class_ref (tree type)
+{
+ tree decl_name, decl, ref;
+ if (TYPE_SIZE (type) == error_mark_node)
+ return null_pointer_node;
+ decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)),
+ "", '/', '/', ".class");
+ decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
+ if (decl == NULL_TREE)
+ {
+ decl = build_decl (VAR_DECL, decl_name, class_type_node);
+ TREE_STATIC (decl) = 1;
+// if (! flag_indirect_classes)
+ TREE_PUBLIC (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ if (is_compiled_class (type) == 1)
+ DECL_EXTERNAL (decl) = 1;
+ MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
+ DECL_CLASS_FIELD_P (decl) = 1;
+ DECL_CONTEXT (decl) = type;
+
+ /* ??? We want to preserve the DECL_CONTEXT we set just above,
+ that that means not calling pushdecl_top_level. */
+ IDENTIFIER_GLOBAL_VALUE (decl_name) = decl;
+ }
+
+ ref = build1 (ADDR_EXPR, class_ptr_type, decl);
+ return ref;
+}
+
/* Build a reference to the class TYPE.
Also handles primitive types and array types. */
@@ -953,7 +985,7 @@ build_class_ref (tree type)
int is_compiled = is_compiled_class (type);
if (is_compiled)
{
- tree ref, decl_name, decl;
+ tree ref, decl;
if (TREE_CODE (type) == POINTER_TYPE)
type = TREE_TYPE (type);
@@ -962,17 +994,27 @@ build_class_ref (tree type)
&& TREE_CODE (type) == RECORD_TYPE)
return build_indirect_class_ref (type);
- if (TREE_CODE (type) == RECORD_TYPE)
+ if (flag_indirect_classes
+ && type == output_class)
{
- if (TYPE_SIZE (type) == error_mark_node)
- return null_pointer_node;
- decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)),
- "", '/', '/', ".class");
+ tree decl_name = mangled_classname ("_class$_", output_class);
decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
if (decl == NULL_TREE)
{
- decl = build_decl (VAR_DECL, decl_name, class_type_node);
+ decl
+ = build_decl (VAR_DECL, decl_name,
+ (build_type_variant
+ (build_pointer_type
+ (build_type_variant (class_type_node,
+ /* const */ 1, 0)),
+ /* const */ 1, 0)));
+// decl
+// = build_decl (VAR_DECL, decl_name,
+// build_pointer_type
+// (build_type_variant (class_type_node,
+// /* const */ 1, 0)));
TREE_STATIC (decl) = 1;
+ TREE_INVARIANT (decl) = 1;
TREE_PUBLIC (decl) = 1;
DECL_IGNORED_P (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
@@ -981,15 +1023,18 @@ build_class_ref (tree type)
MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
DECL_CLASS_FIELD_P (decl) = 1;
DECL_CONTEXT (decl) = type;
-
- /* ??? We want to preserve the DECL_CONTEXT we set just above,
- that that means not calling pushdecl_top_level. */
IDENTIFIER_GLOBAL_VALUE (decl_name) = decl;
+ pushdecl_top_level (decl);
}
- }
+ return decl;
+ }
+
+ if (TREE_CODE (type) == RECORD_TYPE)
+ return build_static_class_ref (type);
else
{
const char *name;
+ tree decl_name;
char buffer[25];
if (flag_emit_class_files)
{
@@ -1287,16 +1332,22 @@ make_field_value (tree fdecl)
PUSH_FIELD_VALUE (finit, "accflags", build_int_cst (NULL_TREE, flags));
PUSH_FIELD_VALUE (finit, "bsize", TYPE_SIZE_UNIT (TREE_TYPE (fdecl)));
- PUSH_FIELD_VALUE
- (finit, "info",
- build_constructor_from_list (field_info_union_node,
- build_tree_list
- ((FIELD_STATIC (fdecl)
- ? TREE_CHAIN (TYPE_FIELDS (field_info_union_node))
- : TYPE_FIELDS (field_info_union_node)),
- (FIELD_STATIC (fdecl)
- ? build_address_of (fdecl)
- : byte_position (fdecl)))));
+ {
+ tree field_address = integer_zero_node;
+ if (! flag_indirect_classes && FIELD_STATIC (fdecl))
+ field_address = build_address_of (fdecl);
+
+ PUSH_FIELD_VALUE
+ (finit, "info",
+ build_constructor_from_list (field_info_union_node,
+ build_tree_list
+ ((FIELD_STATIC (fdecl)
+ ? TREE_CHAIN (TYPE_FIELDS (field_info_union_node))
+ : TYPE_FIELDS (field_info_union_node)),
+ (FIELD_STATIC (fdecl)
+ ? field_address
+ : byte_position (fdecl)))));
+ }
FINISH_RECORD_CONSTRUCTOR (finit);
return finit;
@@ -1577,7 +1628,7 @@ make_class_data (tree type)
tree dtable_start_offset = build_int_cst (NULL_TREE,
2 * POINTER_SIZE / BITS_PER_UNIT);
- this_class_addr = build_class_ref (type);
+ this_class_addr = build_static_class_ref (type);
decl = TREE_OPERAND (this_class_addr, 0);
/* Build Field array. */
@@ -1601,7 +1652,8 @@ make_class_data (tree type)
if (initial != NULL_TREE
&& TREE_TYPE (initial) == string_ptr_type_node)
DECL_INITIAL (field) = NULL_TREE;
- rest_of_decl_compilation (field, 1, 1);
+ if (! flag_indirect_classes)
+ rest_of_decl_compilation (field, 1, 1);
DECL_INITIAL (field) = initial;
}
else
@@ -2406,10 +2458,41 @@ register_class (void)
if (!registered_class)
registered_class = VEC_alloc (tree, gc, 8);
- node = TREE_OPERAND (build_class_ref (current_class), 0);
+ if (flag_indirect_classes)
+ node = current_class;
+ else
+ node = TREE_OPERAND (build_class_ref (current_class), 0);
VEC_safe_push (tree, gc, registered_class, node);
}
+/* Emit a function that calls _Jv_NewClassFromInitializer for every
+ class. */
+
+static void
+emit_indirect_register_classes (tree *list_p)
+{
+ tree klass, t, register_class_fn;
+ int i;
+
+ t = build_function_type_list (class_ptr_type, class_ptr_type, NULL);
+ t = build_decl (FUNCTION_DECL,
+ get_identifier ("_Jv_NewClassFromInitializer"), t);
+ TREE_PUBLIC (t) = 1;
+ DECL_EXTERNAL (t) = 1;
+ register_class_fn = t;
+
+ for (i = 0; VEC_iterate (tree, registered_class, i, klass); ++i)
+ {
+ output_class = current_class = klass;
+ t = build_static_class_ref (klass);
+ t = tree_cons (NULL, t, NULL);
+ t = build_function_call_expr (register_class_fn, t);
+ t = build2 (MODIFY_EXPR, class_ptr_type, build_class_ref (klass),
+ t);
+ append_to_statement_list (t, list_p);
+ }
+}
+
/* Emit something to register classes at start-up time.
The preferred mechanism is through the .jcr section, which contain
@@ -2426,6 +2509,12 @@ emit_register_classes (tree *list_p)
if (registered_class == NULL)
return;
+ if (flag_indirect_classes)
+ {
+ emit_indirect_register_classes (list_p);
+ return;
+ }
+
/* TARGET_USE_JCR_SECTION defaults to 1 if SUPPORTS_WEAK and
TARGET_ASM_NAMED_SECTION, else 0. Some targets meet those conditions
but lack suitable crtbegin/end objects or linker support. These
diff --git a/gcc/java/config-lang.in b/gcc/java/config-lang.in
index d046c66fcaf..cd7414a2903 100644
--- a/gcc/java/config-lang.in
+++ b/gcc/java/config-lang.in
@@ -36,7 +36,7 @@ compilers="jc1\$(exeext) jvgenmain\$(exeext)"
stagestuff="jc1\$(exeext) gcj\$(exeext) jvgenmain\$(exeext) gcjh\$(exeext) gjnih\$(exeext) jv-scan\$(exeext) jcf-dump\$(exeext)"
-gtfiles="\$(srcdir)/java/java-tree.h \$(srcdir)/java/jcf.h \$(srcdir)/java/lex.h \$(srcdir)/java/parse.h \$(srcdir)/java/builtins.c \$(srcdir)/java/class.c \$(srcdir)/java/constants.c \$(srcdir)/java/decl.c \$(srcdir)/java/expr.c \$(srcdir)/java/jcf-parse.c \$(srcdir)/java/jcf-write.c \$(srcdir)/java/lang.c \$(srcdir)/java/mangle.c \$(srcdir)/java/parse.y \$(srcdir)/java/resource.c"
+gtfiles="\$(srcdir)/java/java-tree.h \$(srcdir)/java/jcf.h \$(srcdir)/java/lex.h \$(srcdir)/java/parse.h \$(srcdir)/java/builtins.c \$(srcdir)/java/class.c \$(srcdir)/java/constants.c \$(srcdir)/java/decl.c \$(srcdir)/java/java-expr.c \$(srcdir)/java/jcf-parse.c \$(srcdir)/java/jcf-write.c \$(srcdir)/java/lang.c \$(srcdir)/java/mangle.c \$(srcdir)/java/parse.y \$(srcdir)/java/resource.c"
target_libs=${libgcj_saved}
lang_dirs="zlib fastjar"
diff --git a/gcc/java/constants.c b/gcc/java/constants.c
index 5d2f6785356..2f4c0530035 100644
--- a/gcc/java/constants.c
+++ b/gcc/java/constants.c
@@ -458,8 +458,29 @@ build_ref_from_constant_pool (int index)
{
tree d = build_constant_data_ref ();
tree i = build_int_cst (NULL_TREE, index);
- return build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i,
+ if (flag_indirect_classes)
+ {
+ tree decl = build_class_ref (output_class);
+ tree klass = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (decl)),
+ decl);
+ tree constants = build3 (COMPONENT_REF,
+ TREE_TYPE (constants_field_decl_node), klass,
+ constants_field_decl_node,
+ NULL_TREE);
+ tree data = build3 (COMPONENT_REF,
+ TREE_TYPE (constants_data_field_decl_node),
+ constants,
+ constants_data_field_decl_node,
+ NULL_TREE);
+ data = fold_convert (build_pointer_type (TREE_TYPE (d)), data);
+ d = build1 (INDIRECT_REF, TREE_TYPE (d), data);
+ /* FIXME: These should be cached. */
+ TREE_INVARIANT (d) = 1;
+ }
+ d = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (d)), d, i,
NULL_TREE, NULL_TREE);
+ TREE_INVARIANT (d) = 1;
+ return d;
}
/* Build an initializer for the constants field of the current constant pool.
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 06da90bff73..34160186453 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -123,6 +123,10 @@ static GTY(()) tree pending_local_decls;
/* The decl for "_Jv_ResolvePoolEntry". */
tree soft_resolvepoolentry_node;
+tree constants_field_decl_node;
+
+tree constants_data_field_decl_node;
+
#if defined(DEBUG_JAVA_BINDING_LEVELS)
int binding_depth = 0;
int is_class_level = 0;
@@ -883,6 +887,7 @@ java_init_decl_processing (void)
PUSH_FIELD (constants_type_node, field, "size", unsigned_int_type_node);
PUSH_FIELD (constants_type_node, field, "tags", ptr_type_node);
PUSH_FIELD (constants_type_node, field, "data", ptr_type_node);
+ constants_data_field_decl_node = field;
FINISH_RECORD (constants_type_node);
build_decl (TYPE_DECL, get_identifier ("constants"), constants_type_node);
@@ -924,6 +929,7 @@ java_init_decl_processing (void)
PUSH_FIELD (class_type_node, field, "accflags", access_flags_type_node);
PUSH_FIELD (class_type_node, field, "superclass", class_ptr_type);
PUSH_FIELD (class_type_node, field, "constants", constants_type_node);
+ constants_field_decl_node = field;
PUSH_FIELD (class_type_node, field, "methods", method_ptr_type_node);
PUSH_FIELD (class_type_node, field, "method_count", short_type_node);
PUSH_FIELD (class_type_node, field, "vtable_method_count", short_type_node);
diff --git a/gcc/java/java-expr.c b/gcc/java/java-expr.c
index 785ccc485bf..107d28a6313 100644
--- a/gcc/java/java-expr.c
+++ b/gcc/java/java-expr.c
@@ -3635,4 +3635,4 @@ promote_arguments (void)
}
}
-#include "gt-java-expr.h"
+#include "gt-java-java-expr.h"
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index d421b514a46..2fe1ce814e3 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -208,6 +208,9 @@ extern int flag_check_references;
initialization optimization should be performed. */
extern int flag_optimize_sci;
+/* Generate instances of Class at runtime. */
+extern int flag_indirect_classes;
+
/* When nonzero, use offset tables for virtual method calls
in order to improve binary compatibility. */
extern int flag_indirect_dispatch;
@@ -267,6 +270,10 @@ extern GTY(()) tree java_lang_cloneable_identifier_node;
extern GTY(()) tree java_io_serializable_identifier_node;
extern GTY(()) tree gcj_abi_version;
+extern GTY(()) tree constants_field_decl_node;
+
+extern GTY(()) tree constants_data_field_decl_node;
+
enum java_tree_index
{
JTI_PROMOTED_BYTE_TYPE_NODE,
diff --git a/gcc/java/jvgenmain.c b/gcc/java/jvgenmain.c
index f3402798e55..79c97760bc4 100644
--- a/gcc/java/jvgenmain.c
+++ b/gcc/java/jvgenmain.c
@@ -42,6 +42,8 @@ struct obstack *mangle_obstack = &name_obstack;
static void usage (const char *) ATTRIBUTE_NORETURN;
+int flag_indirect_classes = 0;
+
static void
usage (const char *name)
{
@@ -56,7 +58,7 @@ main (int argc, char **argv)
char *classname, *p;
FILE *stream;
const char *mangled_classname;
- int i, last_arg;
+ int i, last_arg, first_arg;
/* Unlock the stdio streams. */
unlock_std_streams ();
@@ -66,7 +68,15 @@ main (int argc, char **argv)
if (argc < 2)
usage (argv[0]);
- for (i = 1; i < argc; ++i)
+ if (strcmp (argv[1], "-findirect-classes") == 0)
+ {
+ flag_indirect_classes = 1;
+ first_arg = 2;
+ }
+ else
+ first_arg = 1;
+
+ for (i = first_arg; i < argc; ++i)
{
if (! strncmp (argv[i], "-D", 2))
{
@@ -106,11 +116,11 @@ main (int argc, char **argv)
else
stream = stdout;
- /* At this point every element of ARGV from 1 to LAST_ARG is a `-D'
- option. Process them appropriately. */
+ /* At this point every element of ARGV from FIRST_ARG to LAST_ARG is
+ a `-D' option. Process them appropriately. */
fprintf (stream, "extern const char **_Jv_Compiler_Properties;\n");
fprintf (stream, "static const char *props[] =\n{\n");
- for (i = 1; i < last_arg; ++i)
+ for (i = first_arg; i < last_arg; ++i)
{
const char *p;
fprintf (stream, " \"");
@@ -127,11 +137,19 @@ main (int argc, char **argv)
}
fprintf (stream, " 0\n};\n\n");
- fprintf (stream, "extern int %s;\n", mangled_classname);
fprintf (stream, "int main (int argc, const char **argv)\n");
fprintf (stream, "{\n");
fprintf (stream, " _Jv_Compiler_Properties = props;\n");
- fprintf (stream, " JvRunMain (&%s, argc, argv);\n", mangled_classname);
+ if (flag_indirect_classes)
+ {
+ fprintf (stream, " extern void *%s;\n", mangled_classname);
+ fprintf (stream, " JvRunMain (%s, argc, argv);\n", mangled_classname);
+ }
+ else
+ {
+ fprintf (stream, " extern int %s;\n", mangled_classname);
+ fprintf (stream, " JvRunMain (&%s, argc, argv);\n", mangled_classname);
+ }
fprintf (stream, "}\n");
if (stream != stdout && fclose (stream) != 0)
{
@@ -149,20 +167,34 @@ do_mangle_classname (const char *string)
const char *ptr;
int count = 0;
- obstack_grow (&name_obstack, "_ZN", 3);
-
- for (ptr = string; *ptr; ptr++ )
+ if (flag_indirect_classes)
{
- if (ptr[0] == '.')
+ obstack_grow (&name_obstack, "_class$_", strlen ("_class$_"));
+ for (ptr = string; *ptr; ptr++ )
{
- append_gpp_mangled_name (&ptr [-count], count);
- count = 0;
+ if (*ptr == '.')
+ obstack_1grow (mangle_obstack, '_');
+ else
+ obstack_1grow (mangle_obstack, *ptr);
}
- else
- count++;
}
- append_gpp_mangled_name (&ptr [-count], count);
- obstack_grow (mangle_obstack, "6class$E", 8);
+ else
+ {
+ obstack_grow (&name_obstack, "_ZN", 3);
+
+ for (ptr = string; *ptr; ptr++ )
+ {
+ if (*ptr == '.')
+ {
+ append_gpp_mangled_name (ptr - count, count);
+ count = 0;
+ }
+ else
+ count++;
+ }
+ append_gpp_mangled_name (ptr - count, count);
+ obstack_grow (mangle_obstack, "6class$E", 8);
+ }
obstack_1grow (mangle_obstack, '\0');
return obstack_finish (mangle_obstack);
}
diff --git a/gcc/java/jvspec.c b/gcc/java/jvspec.c
index 63f49ff74b3..a48ff56919b 100644
--- a/gcc/java/jvspec.c
+++ b/gcc/java/jvspec.c
@@ -58,7 +58,7 @@ int lang_specific_extra_outfiles = 0;
int shared_libgcc = 1;
static const char jvgenmain_spec[] =
- "jvgenmain %{D*} %b %m.i |\n\
+ "jvgenmain %{findirect-classes} %{D*} %b %m.i |\n\
cc1 %m.i %1 \
%{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a*}\
%{g*} %{O*} \
diff --git a/gcc/java/lang.opt b/gcc/java/lang.opt
index 001a4a75f9d..5dcba5695c5 100644
--- a/gcc/java/lang.opt
+++ b/gcc/java/lang.opt
@@ -146,6 +146,10 @@ fhash-synchronization
Java Var(flag_hash_synchronization)
Assume the runtime uses a hash table to map an object to its synchronization structure
+findirect-classes
+Java Var(flag_indirect_classes)
+Generate instances of Class at runtime
+
findirect-dispatch
Java Var(flag_indirect_dispatch)
Use offset tables for virtual method calls
diff --git a/gcc/java/mangle.c b/gcc/java/mangle.c
index a99bfe5b56c..f9b379221d2 100644
--- a/gcc/java/mangle.c
+++ b/gcc/java/mangle.c
@@ -79,6 +79,9 @@ static GTY(()) tree atms;
void
java_mangle_decl (tree decl)
{
+ if (TREE_CODE (decl) == RECORD_TYPE)
+ mangle_type (decl);
+
/* A copy of the check from the beginning of lhd_set_decl_assembler_name.
Only FUNCTION_DECLs and VAR_DECLs for variables with static storage
duration need a real DECL_ASSEMBLER_NAME. */
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 8e092cf7bfd..6d6c7dcaf2f 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,14 @@
+2006-03-07 Andrew Haley <aph@redhat.com>
+
+ * include/execution.h (do_allocate_static_fields): Allocate the
+ static fields.
+ * java/lang/Class.h (_Jv_NewClassFromInitializer): Declare
+ * java/lang/natClassLoader.cc (_Jv_NewClassFromInitializer): New
+ function.
+ * boehm.cc (_Jv_InitGC): Return if gc is already initialized.
+ * gnu/gcj/runtime/natSharedLibLoader.cc (_Jv_GC_has_static_roots):
+ New function.
+
2006-02-15 Matthias Klose <doko@debian.org>
* gnu/java/nio/charset, gnu/java/net/protocol/file,
diff --git a/libjava/boehm.cc b/libjava/boehm.cc
index 7066e286b49..716362aef49 100644
--- a/libjava/boehm.cc
+++ b/libjava/boehm.cc
@@ -468,6 +468,12 @@ void
_Jv_InitGC (void)
{
int proc;
+ static bool gc_initialized;
+
+ if (gc_initialized)
+ return;
+
+ gc_initialized = 1;
// Ignore pointers that do not point to the start of an object.
GC_all_interior_pointers = 0;
diff --git a/libjava/gnu/gcj/runtime/natSharedLibLoader.cc b/libjava/gnu/gcj/runtime/natSharedLibLoader.cc
index 90ed1d72d68..4970240019e 100644
--- a/libjava/gnu/gcj/runtime/natSharedLibLoader.cc
+++ b/libjava/gnu/gcj/runtime/natSharedLibLoader.cc
@@ -21,6 +21,7 @@ details. */
#ifdef HAVE_DLOPEN
#include <dlfcn.h>
+#include <link.h>
/* Only used during dlopen, while having a lock on Class.class. */
static java::lang::ClassLoader *curLoader;
@@ -29,6 +30,33 @@ static gnu::gcj::runtime::SharedLibHelper *curHelper;
typedef void (*ClassHookFunc) (jclass);
typedef void (*CoreHookFunc) (_Jv_core_chain *);
+static int
+_Jv_GC_has_static_roots (struct dl_phdr_info * info, size_t size, void *ptr)
+{
+ static const char suffix[] = "libgcj.so.7";
+ const char *name = info->dlpi_name;
+
+ fprintf (stderr, "%p: lib %s ", ptr, name);
+
+ if (strlen (name) <= strlen (suffix))
+ goto defaul;
+
+ // If a DSO name ends with SUFFIX, it has GC roots.
+ if (strcmp (name + strlen (name) - strlen (suffix),
+ suffix) == 0)
+ {
+ fprintf (stderr, "registered\n");
+ return 1;
+ }
+
+ defaul:
+ fprintf (stderr, "not registered\n");
+ return 0;
+}
+
+int (*GC_has_static_roots)(struct dl_phdr_info * info, size_t size, void *ptr)
+ = _Jv_GC_has_static_roots;
+
void
_Jv_sharedlib_register_hook (jclass cls)
{
diff --git a/libjava/include/execution.h b/libjava/include/execution.h
index 88189f6449e..fe141e91ec9 100644
--- a/libjava/include/execution.h
+++ b/libjava/include/execution.h
@@ -55,9 +55,25 @@ struct _Jv_CompiledEngine : public _Jv_ExecutionEngine
return NULL;
}
- static void do_allocate_static_fields (jclass, int, int)
+ static void do_allocate_static_fields (jclass klass,
+ int pointer_size,
+ int other_size)
{
- // Compiled classes don't need this.
+ // Splitting the allocations here lets us scan reference fields
+ // and avoid scanning non-reference fields.
+ char *reference_fields = (char *) _Jv_AllocRawObj (pointer_size);
+ char *non_reference_fields = (char *) _Jv_AllocBytes (other_size);
+
+ for (int i = 0; i < klass->field_count; i++)
+ {
+ _Jv_Field *field = &klass->fields[i];
+
+ if ((field->flags & java::lang::reflect::Modifier::STATIC) == 0)
+ continue;
+
+ char *base = field->isRef() ? reference_fields : non_reference_fields;
+ field->u.addr = base + field->u.boffset;
+ }
}
static void do_create_ncode (jclass)
diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h
index 787e2638b2b..b697f14123c 100644
--- a/libjava/java/lang/Class.h
+++ b/libjava/java/lang/Class.h
@@ -39,6 +39,8 @@ extern "Java"
// We declare these here to avoid including gcj/cni.h.
extern "C" void _Jv_InitClass (jclass klass);
+extern "C" jclass _Jv_NewClassFromInitializer
+ (const jclass class_initializer);
extern "C" void _Jv_RegisterClasses (const jclass *classes);
extern "C" void _Jv_RegisterClasses_Counted (const jclass *classes,
size_t count);
@@ -427,6 +429,7 @@ private:
int method_idx);
friend void ::_Jv_InitClass (jclass klass);
+ friend java::lang::Class* ::_Jv_NewClassFromInitializer (const jclass class_initializer);
friend _Jv_Method* ::_Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
_Jv_Utf8Const*, jclass *);
diff --git a/libjava/java/lang/natClassLoader.cc b/libjava/java/lang/natClassLoader.cc
index fa6f201db46..b82096cd979 100644
--- a/libjava/java/lang/natClassLoader.cc
+++ b/libjava/java/lang/natClassLoader.cc
@@ -184,6 +184,44 @@ _Jv_RegisterClasses_Counted (const jclass * classes, size_t count)
}
}
+jclass
+_Jv_NewClassFromInitializer (const jclass class_initializer)
+{
+ _Jv_InitGC ();
+ jclass new_class = (jclass)_Jv_AllocObj (sizeof *new_class,
+ &java::lang::Class::class$);
+ memcpy ((void*)new_class, (void*)class_initializer, sizeof *new_class);
+
+ if (_Jv_CheckABIVersion ((unsigned long) new_class->next_or_version))
+ {
+ jsize count = new_class->field_count;
+ if (count)
+ {
+ new_class->fields
+ = (_Jv_Field*) _Jv_AllocRawObj (count * sizeof (_Jv_Field));
+ memcpy ((void*)new_class->fields,
+ (void*)class_initializer->fields,
+ count * sizeof (_Jv_Field));
+ }
+
+ count = new_class->constants.size;
+ if (count)
+ {
+ new_class->constants.data
+ = (_Jv_word*) _Jv_AllocRawObj (count * sizeof (_Jv_word));
+ memcpy ((void*)new_class->constants.data,
+ (void*)class_initializer->constants.data,
+ count * sizeof (_Jv_word));
+ }
+
+ (*_Jv_RegisterClassHook) (new_class);
+ }
+
+ return new_class;
+}
+
+
+
void
_Jv_RegisterClassHookDefault (jclass klass)
{