Commit 621ae65d by Andrew Haley Committed by Andrew Haley

lang.c (java_init): Handle flag_indirect_classes.

2006-04-21  Andrew Haley  <aph@redhat.com>

        * lang.c (java_init): Handle flag_indirect_classes.
        * jvgenmain.c: Use "class$$" instead of "class$".
        * mangle.c (java_mangle_decl): Accept RECORD_TYPEs sw well as
        DECLs.
        (mangle_class_field): Special case "class$$" as well as "class$".
        * constants.c (build_ref_from_constant_pool): If
        flag_indirect_classes, generate a ref into the heap.
        * decl.c (constants_field_decl_node,
        constants_data_field_decl_node): New.
        * class.c (build_static_class_ref): New.
        (build_classdollar_field): Factor out from build_class_ref().
        (make_field_value): Handle static fields in heap.
        (make_class_data): Make sure we get a static ref to class.
        Make class initializer const if flag_indirect_classes.
        (register_class): Build a class_ref for initialization if
        flag_indirect_classes.
        (emit_indirect_register_classes): New.

2006-04-21  Andrew Haley  <aph@redhat.com>

        * include/execution.h (struct _Jv_CompiledEngine): Define for
        compiled classes.
        * java/lang/natClassLoader.cc (_Jv_RegisterClasses): Call
        _Jv_RegisterLibForGc.
        (_Jv_RegisterClasses_Counted): Likewise.
        (_Jv_NewClassFromInitializer): New.
        (_Jv_RegisterNewClasses): New.
        * sources.am: Regenerate.
        * boehm.cc (_Jv_GC_has_static_roots): new.
        (_Jv_InitGC): Call GC_register_has_static_roots_callback.
        (filename_node, find_file, _Jv_print_gc_store, new_node,
        _Jv_GC_has_static_roots, _Jv_RegisterLibForGc): New.
        * scripts/makemake.tcl: Add -fno-indirect-classes.
        * Makefile.in: Regenerate.
        * link.cc (resolve_pool_entry): Allocate constant pool.
        Allocate fields.

From-SVN: r113224
parent 5204d06d
2006-04-21 Andrew Haley <aph@redhat.com>
* lang.c (java_init): Handle flag_indirect_classes.
* jvgenmain.c: Use "class$$" instead of "class$".
* mangle.c (java_mangle_decl): Accept RECORD_TYPEs sw well as
DECLs.
(mangle_class_field): Special case "class$$" as well as "class$".
* constants.c (build_ref_from_constant_pool): If
flag_indirect_classes, generate a ref into the heap.
* decl.c (constants_field_decl_node,
constants_data_field_decl_node): New.
* class.c (build_static_class_ref): New.
(build_classdollar_field): Factor out from build_class_ref().
(make_field_value): Handle static fields in heap.
(make_class_data): Make sure we get a static ref to class.
Make class initializer const if flag_indirect_classes.
(register_class): Build a class_ref for initialization if
flag_indirect_classes.
(emit_indirect_register_classes): New.
2006-04-08 Kazu Hirata <kazu@codesourcery.com> 2006-04-08 Kazu Hirata <kazu@codesourcery.com>
* expr.c, gjavah.c: Fix comment typos. * expr.c, gjavah.c: Fix comment typos.
......
...@@ -953,39 +953,25 @@ build_indirect_class_ref (tree type) ...@@ -953,39 +953,25 @@ build_indirect_class_ref (tree type)
return convert (promote_type (class_ptr_type), cl); return convert (promote_type (class_ptr_type), cl);
} }
/* Build a reference to the class TYPE. static tree
Also handles primitive types and array types. */ build_static_class_ref (tree type)
tree
build_class_ref (tree type)
{ {
int is_compiled = is_compiled_class (type); tree decl_name, decl, ref;
if (is_compiled)
{
tree ref, decl_name, decl;
if (TREE_CODE (type) == POINTER_TYPE)
type = TREE_TYPE (type);
if (flag_indirect_dispatch
&& type != output_class
&& TREE_CODE (type) == RECORD_TYPE)
return build_indirect_class_ref (type);
if (TREE_CODE (type) == RECORD_TYPE)
{
if (TYPE_SIZE (type) == error_mark_node) if (TYPE_SIZE (type) == error_mark_node)
return null_pointer_node; return null_pointer_node;
decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)), decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)),
"", '/', '/', ".class"); "", '/', '/', ".class$$");
decl = IDENTIFIER_GLOBAL_VALUE (decl_name); decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
if (decl == NULL_TREE) if (decl == NULL_TREE)
{ {
decl = build_decl (VAR_DECL, decl_name, class_type_node); decl = build_decl (VAR_DECL, decl_name, class_type_node);
TREE_STATIC (decl) = 1; TREE_STATIC (decl) = 1;
if (! flag_indirect_classes)
TREE_PUBLIC (decl) = 1; TREE_PUBLIC (decl) = 1;
DECL_IGNORED_P (decl) = 1; DECL_IGNORED_P (decl) = 1;
DECL_ARTIFICIAL (decl) = 1; DECL_ARTIFICIAL (decl) = 1;
if (is_compiled == 1) if (is_compiled_class (type) == 1)
DECL_EXTERNAL (decl) = 1; DECL_EXTERNAL (decl) = 1;
MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl); MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
DECL_CLASS_FIELD_P (decl) = 1; DECL_CLASS_FIELD_P (decl) = 1;
...@@ -995,10 +981,70 @@ build_class_ref (tree type) ...@@ -995,10 +981,70 @@ build_class_ref (tree type)
that that means not calling pushdecl_top_level. */ that that means not calling pushdecl_top_level. */
IDENTIFIER_GLOBAL_VALUE (decl_name) = decl; IDENTIFIER_GLOBAL_VALUE (decl_name) = decl;
} }
ref = build1 (ADDR_EXPR, class_ptr_type, decl);
return ref;
}
static tree
build_classdollar_field (tree type)
{
tree decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)),
"", '/', '/', ".class$");
tree decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
if (decl == NULL_TREE)
{
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)));
TREE_STATIC (decl) = 1;
TREE_INVARIANT (decl) = 1;
TREE_CONSTANT (decl) = 1;
TREE_READONLY (decl) = 1;
TREE_PUBLIC (decl) = 1;
DECL_IGNORED_P (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
IDENTIFIER_GLOBAL_VALUE (decl_name) = decl;
DECL_CLASS_FIELD_P (decl) = 1;
DECL_CONTEXT (decl) = type;
} }
return decl;
}
/* Build a reference to the class TYPE.
Also handles primitive types and array types. */
tree
build_class_ref (tree type)
{
int is_compiled = is_compiled_class (type);
if (is_compiled)
{
tree ref, decl;
if (TREE_CODE (type) == POINTER_TYPE)
type = TREE_TYPE (type);
if (flag_indirect_dispatch
&& type != output_class
&& TREE_CODE (type) == RECORD_TYPE)
return build_indirect_class_ref (type);
if (type == output_class && flag_indirect_classes)
return build_classdollar_field (type);
if (TREE_CODE (type) == RECORD_TYPE)
return build_static_class_ref (type);
else else
{ {
const char *name; const char *name;
tree decl_name;
char buffer[25]; char buffer[25];
if (flag_emit_class_files) if (flag_emit_class_files)
{ {
...@@ -1296,6 +1342,11 @@ make_field_value (tree fdecl) ...@@ -1296,6 +1342,11 @@ make_field_value (tree fdecl)
PUSH_FIELD_VALUE (finit, "accflags", build_int_cst (NULL_TREE, flags)); 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, "bsize", TYPE_SIZE_UNIT (TREE_TYPE (fdecl)));
{
tree field_address = integer_zero_node;
if (! flag_indirect_classes && FIELD_STATIC (fdecl))
field_address = build_address_of (fdecl);
PUSH_FIELD_VALUE PUSH_FIELD_VALUE
(finit, "info", (finit, "info",
build_constructor_from_list (field_info_union_node, build_constructor_from_list (field_info_union_node,
...@@ -1304,8 +1355,9 @@ make_field_value (tree fdecl) ...@@ -1304,8 +1355,9 @@ make_field_value (tree fdecl)
? TREE_CHAIN (TYPE_FIELDS (field_info_union_node)) ? TREE_CHAIN (TYPE_FIELDS (field_info_union_node))
: TYPE_FIELDS (field_info_union_node)), : TYPE_FIELDS (field_info_union_node)),
(FIELD_STATIC (fdecl) (FIELD_STATIC (fdecl)
? build_address_of (fdecl) ? field_address
: byte_position (fdecl))))); : byte_position (fdecl)))));
}
FINISH_RECORD_CONSTRUCTOR (finit); FINISH_RECORD_CONSTRUCTOR (finit);
return finit; return finit;
...@@ -1599,7 +1651,7 @@ make_class_data (tree type) ...@@ -1599,7 +1651,7 @@ make_class_data (tree type)
tree dtable_start_offset = build_int_cst (NULL_TREE, tree dtable_start_offset = build_int_cst (NULL_TREE,
2 * POINTER_SIZE / BITS_PER_UNIT); 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); decl = TREE_OPERAND (this_class_addr, 0);
if (supers_all_compiled (type) && ! CLASS_INTERFACE (type_decl) if (supers_all_compiled (type) && ! CLASS_INTERFACE (type_decl)
...@@ -1613,6 +1665,7 @@ make_class_data (tree type) ...@@ -1613,6 +1665,7 @@ make_class_data (tree type)
DECL_ARTIFICIAL (dtable_decl) = 1; DECL_ARTIFICIAL (dtable_decl) = 1;
DECL_IGNORED_P (dtable_decl) = 1; DECL_IGNORED_P (dtable_decl) = 1;
TREE_PUBLIC (dtable_decl) = 1; TREE_PUBLIC (dtable_decl) = 1;
if (! flag_indirect_classes)
rest_of_decl_compilation (dtable_decl, 1, 0); rest_of_decl_compilation (dtable_decl, 1, 0);
if (type == class_type_node) if (type == class_type_node)
class_dtable_decl = dtable_decl; class_dtable_decl = dtable_decl;
...@@ -1958,8 +2011,21 @@ make_class_data (tree type) ...@@ -1958,8 +2011,21 @@ make_class_data (tree type)
if (flag_hash_synchronization && POINTER_SIZE < 64) if (flag_hash_synchronization && POINTER_SIZE < 64)
DECL_ALIGN (decl) = 64; DECL_ALIGN (decl) = 64;
if (flag_indirect_classes)
{
TREE_READONLY (decl) = 1;
TREE_CONSTANT (DECL_INITIAL (decl)) = 1;
}
rest_of_decl_compilation (decl, 1, 0); rest_of_decl_compilation (decl, 1, 0);
{
tree classdollar_field = build_classdollar_field (type);
if (!flag_indirect_classes)
DECL_INITIAL (classdollar_field) = build_static_class_ref (type);
rest_of_decl_compilation (classdollar_field, 1, 0);
}
TYPE_OTABLE_DECL (type) = NULL_TREE; TYPE_OTABLE_DECL (type) = NULL_TREE;
TYPE_ATABLE_DECL (type) = NULL_TREE; TYPE_ATABLE_DECL (type) = NULL_TREE;
TYPE_CTABLE_DECL (type) = NULL_TREE; TYPE_CTABLE_DECL (type) = NULL_TREE;
...@@ -2465,10 +2531,65 @@ register_class (void) ...@@ -2465,10 +2531,65 @@ register_class (void)
if (!registered_class) if (!registered_class)
registered_class = VEC_alloc (tree, gc, 8); registered_class = VEC_alloc (tree, gc, 8);
if (flag_indirect_classes)
node = current_class;
else
node = TREE_OPERAND (build_class_ref (current_class), 0); node = TREE_OPERAND (build_class_ref (current_class), 0);
VEC_safe_push (tree, gc, registered_class, node); 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;
tree init = NULL_TREE;
int size = VEC_length (tree, registered_class) * 2 + 1;
tree class_array_type
= build_prim_array_type (ptr_type_node, size);
tree cdecl = build_decl (VAR_DECL, get_identifier ("_Jv_CLS"),
class_array_type);
tree reg_class_list;
for (i = 0; VEC_iterate (tree, registered_class, i, klass); ++i)
{
init = tree_cons (NULL_TREE,
fold_convert (ptr_type_node,
build_static_class_ref (klass)), init);
init = tree_cons
(NULL_TREE,
fold_convert (ptr_type_node,
build_address_of (build_classdollar_field (klass))),
init);
}
init = tree_cons (NULL_TREE, integer_zero_node, init);
DECL_INITIAL (cdecl) = build_constructor_from_list (class_array_type,
nreverse (init));
TREE_CONSTANT (DECL_INITIAL (cdecl)) = 1;
TREE_STATIC (cdecl) = 1;
DECL_ARTIFICIAL (cdecl) = 1;
DECL_IGNORED_P (cdecl) = 1;
TREE_READONLY (cdecl) = 1;
TREE_CONSTANT (cdecl) = 1;
rest_of_decl_compilation (cdecl, 1, 0);
reg_class_list = fold_convert (ptr_type_node, build_address_of (cdecl));
t = build_function_type_list (void_type_node,
build_pointer_type (ptr_type_node), NULL);
t = build_decl (FUNCTION_DECL,
get_identifier ("_Jv_RegisterNewClasses"), t);
TREE_PUBLIC (t) = 1;
DECL_EXTERNAL (t) = 1;
register_class_fn = t;
t = tree_cons (NULL, reg_class_list, NULL);
t = build_function_call_expr (register_class_fn, t);
append_to_statement_list (t, list_p);
}
/* Emit something to register classes at start-up time. /* Emit something to register classes at start-up time.
The preferred mechanism is through the .jcr section, which contain The preferred mechanism is through the .jcr section, which contain
...@@ -2485,6 +2606,12 @@ emit_register_classes (tree *list_p) ...@@ -2485,6 +2606,12 @@ emit_register_classes (tree *list_p)
if (registered_class == NULL) if (registered_class == NULL)
return; return;
if (flag_indirect_classes)
{
emit_indirect_register_classes (list_p);
return;
}
/* TARGET_USE_JCR_SECTION defaults to 1 if SUPPORTS_WEAK and /* TARGET_USE_JCR_SECTION defaults to 1 if SUPPORTS_WEAK and
TARGET_ASM_NAMED_SECTION, else 0. Some targets meet those conditions TARGET_ASM_NAMED_SECTION, else 0. Some targets meet those conditions
but lack suitable crtbegin/end objects or linker support. These but lack suitable crtbegin/end objects or linker support. These
......
...@@ -458,8 +458,29 @@ build_ref_from_constant_pool (int index) ...@@ -458,8 +458,29 @@ build_ref_from_constant_pool (int index)
{ {
tree d = build_constant_data_ref (); tree d = build_constant_data_ref ();
tree i = build_int_cst (NULL_TREE, index); 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); NULL_TREE, NULL_TREE);
TREE_INVARIANT (d) = 1;
return d;
} }
/* Build an initializer for the constants field of the current constant pool. /* Build an initializer for the constants field of the current constant pool.
......
...@@ -123,6 +123,12 @@ static GTY(()) tree pending_local_decls; ...@@ -123,6 +123,12 @@ static GTY(()) tree pending_local_decls;
/* The decl for "_Jv_ResolvePoolEntry". */ /* The decl for "_Jv_ResolvePoolEntry". */
tree soft_resolvepoolentry_node; tree soft_resolvepoolentry_node;
/* The decl for the .constants field of an instance of Class. */
tree constants_field_decl_node;
/* The decl for the .data field of an instance of Class. */
tree constants_data_field_decl_node;
#if defined(DEBUG_JAVA_BINDING_LEVELS) #if defined(DEBUG_JAVA_BINDING_LEVELS)
int binding_depth = 0; int binding_depth = 0;
int is_class_level = 0; int is_class_level = 0;
...@@ -883,6 +889,7 @@ java_init_decl_processing (void) ...@@ -883,6 +889,7 @@ java_init_decl_processing (void)
PUSH_FIELD (constants_type_node, field, "size", unsigned_int_type_node); 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, "tags", ptr_type_node);
PUSH_FIELD (constants_type_node, field, "data", ptr_type_node); PUSH_FIELD (constants_type_node, field, "data", ptr_type_node);
constants_data_field_decl_node = field;
FINISH_RECORD (constants_type_node); FINISH_RECORD (constants_type_node);
build_decl (TYPE_DECL, get_identifier ("constants"), constants_type_node); build_decl (TYPE_DECL, get_identifier ("constants"), constants_type_node);
...@@ -924,6 +931,7 @@ java_init_decl_processing (void) ...@@ -924,6 +931,7 @@ java_init_decl_processing (void)
PUSH_FIELD (class_type_node, field, "accflags", access_flags_type_node); 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, "superclass", class_ptr_type);
PUSH_FIELD (class_type_node, field, "constants", constants_type_node); 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, "methods", method_ptr_type_node);
PUSH_FIELD (class_type_node, field, "method_count", short_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); PUSH_FIELD (class_type_node, field, "vtable_method_count", short_type_node);
......
...@@ -208,6 +208,9 @@ extern int flag_check_references; ...@@ -208,6 +208,9 @@ extern int flag_check_references;
initialization optimization should be performed. */ initialization optimization should be performed. */
extern int flag_optimize_sci; 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 /* When nonzero, use offset tables for virtual method calls
in order to improve binary compatibility. */ in order to improve binary compatibility. */
extern int flag_indirect_dispatch; extern int flag_indirect_dispatch;
...@@ -270,6 +273,12 @@ extern GTY(()) tree java_lang_cloneable_identifier_node; ...@@ -270,6 +273,12 @@ extern GTY(()) tree java_lang_cloneable_identifier_node;
extern GTY(()) tree java_io_serializable_identifier_node; extern GTY(()) tree java_io_serializable_identifier_node;
extern GTY(()) tree gcj_abi_version; extern GTY(()) tree gcj_abi_version;
/* The decl for the .constants field of an instance of Class. */
extern GTY(()) tree constants_field_decl_node;
/* The decl for the .data field of an instance of Class. */
extern GTY(()) tree constants_data_field_decl_node;
enum java_tree_index enum java_tree_index
{ {
JTI_PROMOTED_BYTE_TYPE_NODE, JTI_PROMOTED_BYTE_TYPE_NODE,
......
...@@ -127,11 +127,11 @@ main (int argc, char **argv) ...@@ -127,11 +127,11 @@ main (int argc, char **argv)
} }
fprintf (stream, " 0\n};\n\n"); 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, "int main (int argc, const char **argv)\n");
fprintf (stream, "{\n"); fprintf (stream, "{\n");
fprintf (stream, " _Jv_Compiler_Properties = props;\n"); fprintf (stream, " _Jv_Compiler_Properties = props;\n");
fprintf (stream, " JvRunMain (&%s, argc, argv);\n", mangled_classname); fprintf (stream, " extern void *%s;\n", mangled_classname);
fprintf (stream, " JvRunMain (%s, argc, argv);\n", mangled_classname);
fprintf (stream, "}\n"); fprintf (stream, "}\n");
if (stream != stdout && fclose (stream) != 0) if (stream != stdout && fclose (stream) != 0)
{ {
...@@ -153,16 +153,16 @@ do_mangle_classname (const char *string) ...@@ -153,16 +153,16 @@ do_mangle_classname (const char *string)
for (ptr = string; *ptr; ptr++ ) for (ptr = string; *ptr; ptr++ )
{ {
if (ptr[0] == '.') if (*ptr == '.')
{ {
append_gpp_mangled_name (&ptr [-count], count); append_gpp_mangled_name (ptr - count, count);
count = 0; count = 0;
} }
else else
count++; count++;
} }
append_gpp_mangled_name (&ptr [-count], count); append_gpp_mangled_name (&ptr [-count], count);
obstack_grow (mangle_obstack, "6class$E", 8); obstack_grow (mangle_obstack, "7class$$E", strlen ("7class$$E"));
obstack_1grow (mangle_obstack, '\0'); obstack_1grow (mangle_obstack, '\0');
return obstack_finish (mangle_obstack); return obstack_finish (mangle_obstack);
} }
...@@ -368,6 +368,9 @@ java_init (void) ...@@ -368,6 +368,9 @@ java_init (void)
if (flag_indirect_dispatch) if (flag_indirect_dispatch)
always_initialize_class_p = true; always_initialize_class_p = true;
if (!flag_indirect_dispatch)
flag_indirect_classes = false;
/* Force minimum function alignment if g++ uses the least significant /* Force minimum function alignment if g++ uses the least significant
bit of function pointers to store the virtual bit. This is required bit of function pointers to store the virtual bit. This is required
to keep vtables compatible. */ to keep vtables compatible. */
......
...@@ -146,6 +146,10 @@ fhash-synchronization ...@@ -146,6 +146,10 @@ fhash-synchronization
Java Var(flag_hash_synchronization) Java Var(flag_hash_synchronization)
Assume the runtime uses a hash table to map an object to its synchronization structure Assume the runtime uses a hash table to map an object to its synchronization structure
findirect-classes
Java Var(flag_indirect_classes) Init(1)
Generate instances of Class at runtime
findirect-dispatch findirect-dispatch
Java Var(flag_indirect_dispatch) Java Var(flag_indirect_dispatch)
Use offset tables for virtual method calls Use offset tables for virtual method calls
......
...@@ -79,6 +79,9 @@ static GTY(()) tree atms; ...@@ -79,6 +79,9 @@ static GTY(()) tree atms;
void void
java_mangle_decl (tree decl) 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. /* 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 Only FUNCTION_DECLs and VAR_DECLs for variables with static storage
duration need a real DECL_ASSEMBLER_NAME. */ duration need a real DECL_ASSEMBLER_NAME. */
...@@ -99,7 +102,7 @@ java_mangle_decl (tree decl) ...@@ -99,7 +102,7 @@ java_mangle_decl (tree decl)
{ {
if (DECL_CLASS_FIELD_P (decl)) if (DECL_CLASS_FIELD_P (decl))
{ {
mangle_class_field (DECL_CONTEXT (decl)); mangle_class_field (decl);
break; break;
} }
else if (DECL_VTABLE_P (decl)) else if (DECL_VTABLE_P (decl))
...@@ -130,10 +133,14 @@ java_mangle_decl (tree decl) ...@@ -130,10 +133,14 @@ java_mangle_decl (tree decl)
/* Beginning of the helper functions */ /* Beginning of the helper functions */
static void static void
mangle_class_field (tree type) mangle_class_field (tree decl)
{ {
tree type = DECL_CONTEXT (decl);
mangle_record_type (type, /* for_pointer = */ 0); mangle_record_type (type, /* for_pointer = */ 0);
if (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE)
MANGLE_RAW_STRING ("6class$"); MANGLE_RAW_STRING ("6class$");
else
MANGLE_RAW_STRING ("7class$$");
obstack_1grow (mangle_obstack, 'E'); obstack_1grow (mangle_obstack, 'E');
} }
......
2006-04-21 Andrew Haley <aph@redhat.com>
* include/execution.h (struct _Jv_CompiledEngine): Define for
compiled classes.
* java/lang/natClassLoader.cc (_Jv_RegisterClasses): Call
_Jv_RegisterLibForGc.
(_Jv_RegisterClasses_Counted): Likewise.
(_Jv_NewClassFromInitializer): New.
(_Jv_RegisterNewClasses): New.
* sources.am: Regenerate.
* boehm.cc (_Jv_GC_has_static_roots): new.
(_Jv_InitGC): Call GC_register_has_static_roots_callback.
(filename_node, find_file, _Jv_print_gc_store, new_node,
_Jv_GC_has_static_roots, _Jv_RegisterLibForGc): New.
* scripts/makemake.tcl: Add -fno-indirect-classes.
* Makefile.in: Regenerate.
* link.cc (resolve_pool_entry): Allocate constant pool.
Allocate fields.
2006-04-22 Andreas Tobler <a.tobler@schweiz.ch> 2006-04-22 Andreas Tobler <a.tobler@schweiz.ch>
* configure.ac: Weaken the check for MMAP. * configure.ac: Weaken the check for MMAP.
......
...@@ -8448,7 +8448,7 @@ lib-gnu-awt-xlib.la: $(lib_gnu_awt_xlib_la_OBJECTS) $(lib_gnu_awt_xlib_la_DEPEND ...@@ -8448,7 +8448,7 @@ lib-gnu-awt-xlib.la: $(lib_gnu_awt_xlib_la_OBJECTS) $(lib_gnu_awt_xlib_la_DEPEND
gnu-CORBA.lo: $(gnu_CORBA_source_files) gnu-CORBA.lo: $(gnu_CORBA_source_files)
@find classpath/lib/gnu/CORBA -name '*.class' > gnu-CORBA.list @find classpath/lib/gnu/CORBA -name '*.class' > gnu-CORBA.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-CORBA.lo @gnu-CORBA.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-CORBA.lo @gnu-CORBA.list
@rm -f gnu-CORBA.list @rm -f gnu-CORBA.list
gnu/awt.list: $(gnu_awt_source_files) gnu/awt.list: $(gnu_awt_source_files)
...@@ -8683,22 +8683,22 @@ gnu/java/awt/peer.list: $(gnu_java_awt_peer_source_files) ...@@ -8683,22 +8683,22 @@ gnu/java/awt/peer.list: $(gnu_java_awt_peer_source_files)
gnu-java-awt-peer-gtk.lo: $(gnu_java_awt_peer_gtk_source_files) gnu-java-awt-peer-gtk.lo: $(gnu_java_awt_peer_gtk_source_files)
@find classpath/lib/gnu/java/awt/peer/gtk -name '*.class' > gnu-java-awt-peer-gtk.list @find classpath/lib/gnu/java/awt/peer/gtk -name '*.class' > gnu-java-awt-peer-gtk.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-java-awt-peer-gtk.lo @gnu-java-awt-peer-gtk.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-java-awt-peer-gtk.lo @gnu-java-awt-peer-gtk.list
@rm -f gnu-java-awt-peer-gtk.list @rm -f gnu-java-awt-peer-gtk.list
gnu-java-awt-peer-qt.lo: $(gnu_java_awt_peer_qt_source_files) gnu-java-awt-peer-qt.lo: $(gnu_java_awt_peer_qt_source_files)
@find classpath/lib/gnu/java/awt/peer/qt -name '*.class' > gnu-java-awt-peer-qt.list @find classpath/lib/gnu/java/awt/peer/qt -name '*.class' > gnu-java-awt-peer-qt.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-java-awt-peer-qt.lo @gnu-java-awt-peer-qt.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-java-awt-peer-qt.lo @gnu-java-awt-peer-qt.list
@rm -f gnu-java-awt-peer-qt.list @rm -f gnu-java-awt-peer-qt.list
gnu-java-awt-peer-swing.lo: $(gnu_java_awt_peer_swing_source_files) gnu-java-awt-peer-swing.lo: $(gnu_java_awt_peer_swing_source_files)
@find classpath/lib/gnu/java/awt/peer/swing -name '*.class' > gnu-java-awt-peer-swing.list @find classpath/lib/gnu/java/awt/peer/swing -name '*.class' > gnu-java-awt-peer-swing.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-java-awt-peer-swing.lo @gnu-java-awt-peer-swing.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-java-awt-peer-swing.lo @gnu-java-awt-peer-swing.list
@rm -f gnu-java-awt-peer-swing.list @rm -f gnu-java-awt-peer-swing.list
gnu-java-beans.lo: $(gnu_java_beans_source_files) gnu-java-beans.lo: $(gnu_java_beans_source_files)
@find classpath/lib/gnu/java/beans -name '*.class' > gnu-java-beans.list @find classpath/lib/gnu/java/beans -name '*.class' > gnu-java-beans.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-java-beans.lo @gnu-java-beans.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-java-beans.lo @gnu-java-beans.list
@rm -f gnu-java-beans.list @rm -f gnu-java-beans.list
gnu/java/io.list: $(gnu_java_io_source_files) gnu/java/io.list: $(gnu_java_io_source_files)
...@@ -9393,7 +9393,7 @@ gnu/javax/net/ssl/provider.list: $(gnu_javax_net_ssl_provider_source_files) ...@@ -9393,7 +9393,7 @@ gnu/javax/net/ssl/provider.list: $(gnu_javax_net_ssl_provider_source_files)
gnu-javax-rmi.lo: $(gnu_javax_rmi_source_files) gnu-javax-rmi.lo: $(gnu_javax_rmi_source_files)
@find classpath/lib/gnu/javax/rmi -name '*.class' > gnu-javax-rmi.list @find classpath/lib/gnu/javax/rmi -name '*.class' > gnu-javax-rmi.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-javax-rmi.lo @gnu-javax-rmi.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-javax-rmi.lo @gnu-javax-rmi.list
@rm -f gnu-javax-rmi.list @rm -f gnu-javax-rmi.list
gnu/javax/security/auth.list: $(gnu_javax_security_auth_source_files) gnu/javax/security/auth.list: $(gnu_javax_security_auth_source_files)
...@@ -9428,7 +9428,7 @@ gnu/javax/security/auth/login.list: $(gnu_javax_security_auth_login_source_files ...@@ -9428,7 +9428,7 @@ gnu/javax/security/auth/login.list: $(gnu_javax_security_auth_login_source_files
gnu-javax-sound-midi.lo: $(gnu_javax_sound_midi_source_files) gnu-javax-sound-midi.lo: $(gnu_javax_sound_midi_source_files)
@find classpath/lib/gnu/javax/sound/midi -name '*.class' > gnu-javax-sound-midi.list @find classpath/lib/gnu/javax/sound/midi -name '*.class' > gnu-javax-sound-midi.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-javax-sound-midi.lo @gnu-javax-sound-midi.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-javax-sound-midi.lo @gnu-javax-sound-midi.list
@rm -f gnu-javax-sound-midi.list @rm -f gnu-javax-sound-midi.list
gnu/javax/swing/text/html/parser.list: $(gnu_javax_swing_text_html_parser_source_files) gnu/javax/swing/text/html/parser.list: $(gnu_javax_swing_text_html_parser_source_files)
...@@ -9483,7 +9483,7 @@ gnu/regexp.list: $(gnu_regexp_source_files) ...@@ -9483,7 +9483,7 @@ gnu/regexp.list: $(gnu_regexp_source_files)
gnu-xml.lo: $(gnu_xml_source_files) gnu-xml.lo: $(gnu_xml_source_files)
@find classpath/lib/gnu/xml -name '*.class' > gnu-xml.list @find classpath/lib/gnu/xml -name '*.class' > gnu-xml.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-xml.lo @gnu-xml.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-xml.lo @gnu-xml.list
@rm -f gnu-xml.list @rm -f gnu-xml.list
java/applet.list: $(java_applet_source_files) java/applet.list: $(java_applet_source_files)
...@@ -9998,7 +9998,7 @@ javax/crypto/spec.list: $(javax_crypto_spec_source_files) ...@@ -9998,7 +9998,7 @@ javax/crypto/spec.list: $(javax_crypto_spec_source_files)
javax-imageio.lo: $(javax_imageio_source_files) javax-imageio.lo: $(javax_imageio_source_files)
@find classpath/lib/javax/imageio -name '*.class' > javax-imageio.list @find classpath/lib/javax/imageio -name '*.class' > javax-imageio.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o javax-imageio.lo @javax-imageio.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o javax-imageio.lo @javax-imageio.list
@rm -f javax-imageio.list @rm -f javax-imageio.list
javax/management.list: $(javax_management_source_files) javax/management.list: $(javax_management_source_files)
...@@ -10123,7 +10123,7 @@ javax/print/event.list: $(javax_print_event_source_files) ...@@ -10123,7 +10123,7 @@ javax/print/event.list: $(javax_print_event_source_files)
javax-rmi.lo: $(javax_rmi_source_files) javax-rmi.lo: $(javax_rmi_source_files)
@find classpath/lib/javax/rmi -name '*.class' > javax-rmi.list @find classpath/lib/javax/rmi -name '*.class' > javax-rmi.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o javax-rmi.lo @javax-rmi.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o javax-rmi.lo @javax-rmi.list
@rm -f javax-rmi.list @rm -f javax-rmi.list
javax/security/auth.list: $(javax_security_auth_source_files) javax/security/auth.list: $(javax_security_auth_source_files)
...@@ -10438,7 +10438,7 @@ javax/transaction/xa.list: $(javax_transaction_xa_source_files) ...@@ -10438,7 +10438,7 @@ javax/transaction/xa.list: $(javax_transaction_xa_source_files)
javax-xml.lo: $(javax_xml_source_files) javax-xml.lo: $(javax_xml_source_files)
@find classpath/lib/javax/xml -name '*.class' > javax-xml.list @find classpath/lib/javax/xml -name '*.class' > javax-xml.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o javax-xml.lo @javax-xml.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o javax-xml.lo @javax-xml.list
@rm -f javax-xml.list @rm -f javax-xml.list
org/ietf/jgss.list: $(org_ietf_jgss_source_files) org/ietf/jgss.list: $(org_ietf_jgss_source_files)
...@@ -10453,22 +10453,22 @@ org/ietf/jgss.list: $(org_ietf_jgss_source_files) ...@@ -10453,22 +10453,22 @@ org/ietf/jgss.list: $(org_ietf_jgss_source_files)
org-omg.lo: $(org_omg_source_files) org-omg.lo: $(org_omg_source_files)
@find classpath/lib/org/omg -name '*.class' > org-omg.list @find classpath/lib/org/omg -name '*.class' > org-omg.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o org-omg.lo @org-omg.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o org-omg.lo @org-omg.list
@rm -f org-omg.list @rm -f org-omg.list
org-relaxng.lo: $(org_relaxng_source_files) org-relaxng.lo: $(org_relaxng_source_files)
@find classpath/lib/org/relaxng -name '*.class' > org-relaxng.list @find classpath/lib/org/relaxng -name '*.class' > org-relaxng.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o org-relaxng.lo @org-relaxng.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o org-relaxng.lo @org-relaxng.list
@rm -f org-relaxng.list @rm -f org-relaxng.list
org-w3c.lo: $(org_w3c_source_files) org-w3c.lo: $(org_w3c_source_files)
@find classpath/lib/org/w3c -name '*.class' > org-w3c.list @find classpath/lib/org/w3c -name '*.class' > org-w3c.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o org-w3c.lo @org-w3c.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o org-w3c.lo @org-w3c.list
@rm -f org-w3c.list @rm -f org-w3c.list
org-xml.lo: $(org_xml_source_files) org-xml.lo: $(org_xml_source_files)
@find classpath/lib/org/xml -name '*.class' > org-xml.list @find classpath/lib/org/xml -name '*.class' > org-xml.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o org-xml.lo @org-xml.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o org-xml.lo @org-xml.list
@rm -f org-xml.list @rm -f org-xml.list
$(generic_header_files): %.h: classpath/lib/%.class $(generic_header_files): %.h: classpath/lib/%.class
......
...@@ -32,6 +32,13 @@ details. */ ...@@ -32,6 +32,13 @@ details. */
#undef PACKAGE_TARNAME #undef PACKAGE_TARNAME
#undef PACKAGE_VERSION #undef PACKAGE_VERSION
#ifdef HAVE_DLFCN_H
#undef _GNU_SOURCE
#define _GNU_SOURCE
#include <dlfcn.h>
#include <link.h>
#endif
extern "C" extern "C"
{ {
#include <gc_config.h> #include <gc_config.h>
...@@ -64,6 +71,8 @@ static int array_kind_x; ...@@ -64,6 +71,8 @@ static int array_kind_x;
// Freelist used for Java arrays. // Freelist used for Java arrays.
static void **array_free_list; static void **array_free_list;
static int _Jv_GC_has_static_roots (const char *filename, void *, size_t);
// This is called by the GC during the mark phase. It marks a Java // This is called by the GC during the mark phase. It marks a Java
...@@ -468,10 +477,21 @@ void ...@@ -468,10 +477,21 @@ void
_Jv_InitGC (void) _Jv_InitGC (void)
{ {
int proc; 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. // Ignore pointers that do not point to the start of an object.
GC_all_interior_pointers = 0; GC_all_interior_pointers = 0;
#ifdef HAVE_DLFCN_H
// Tell the collector to ask us before scanning DSOs.
GC_register_has_static_roots_callback (_Jv_GC_has_static_roots);
#endif
// Configure the collector to use the bitmap marking descriptors that we // Configure the collector to use the bitmap marking descriptors that we
// stash in the class vtable. // stash in the class vtable.
// We always use mark proc descriptor 0, since the compiler knows // We always use mark proc descriptor 0, since the compiler knows
...@@ -559,3 +579,98 @@ _Jv_GCCanReclaimSoftReference (jobject) ...@@ -559,3 +579,98 @@ _Jv_GCCanReclaimSoftReference (jobject)
// For now, always reclaim soft references. FIXME. // For now, always reclaim soft references. FIXME.
return true; return true;
} }
#ifdef HAVE_DLFCN_H
// We keep a store of the filenames of DSOs that need to be
// conservatively scanned by the garbage collector. During collection
// the gc calls _Jv_GC_has_static_roots() to see if the data segment
// of a DSO should be scanned.
typedef struct filename_node
{
char *name;
struct filename_node *link;
} filename_node;
#define FILENAME_STORE_SIZE 17
static filename_node *filename_store[FILENAME_STORE_SIZE];
// Find a filename in filename_store.
static filename_node **
find_file (const char *filename)
{
int index = strlen (filename) % FILENAME_STORE_SIZE;
filename_node **node = &filename_store[index];
while (*node)
{
if (strcmp ((*node)->name, filename) == 0)
return node;
node = &(*node)->link;
}
return node;
}
// Print the store of filenames of DSOs that need collection.
void
_Jv_print_gc_store (void)
{
for (int i = 0; i < FILENAME_STORE_SIZE; i++)
{
filename_node *node = filename_store[i];
while (node)
{
fprintf (stderr, "%s\n", node->name);
node = node->link;
}
}
}
// Create a new node in the store of libraries to collect.
static filename_node *
new_node (const char *filename)
{
filename_node *node = (filename_node*)_Jv_Malloc (sizeof (filename_node));
node->name = (char *)_Jv_Malloc (strlen (filename) + 1);
node->link = NULL;
strcpy (node->name, filename);
return node;
}
// Nonzero if the gc should scan this lib.
static int
_Jv_GC_has_static_roots (const char *filename, void *, size_t)
{
if (filename == NULL || strlen (filename) == 0)
// No filename; better safe than sorry.
return 1;
filename_node **node = find_file (filename);
if (*node)
return 1;
return 0;
}
#endif
// Register the DSO that contains p for collection.
void
_Jv_RegisterLibForGc (const void *p __attribute__ ((__unused__)))
{
#ifdef HAVE_DLFCN_H
Dl_info info;
if (dladdr (p, &info) != 0)
{
filename_node **node = find_file (info.dli_fname);
if (! *node)
*node = new_node (info.dli_fname);
}
#endif
}
...@@ -19,6 +19,7 @@ extern "C" ...@@ -19,6 +19,7 @@ extern "C"
{ {
void *_Jv_MarkObj (void *, void *, void *, void *); void *_Jv_MarkObj (void *, void *, void *, void *);
void *_Jv_MarkArray (void *, void *, void *, void *); void *_Jv_MarkArray (void *, void *, void *, void *);
void _Jv_RegisterLibForGc (const void *);
} }
// Enough stuff to inline _Jv_AllocObj. Ugly. // Enough stuff to inline _Jv_AllocObj. Ugly.
......
...@@ -55,9 +55,25 @@ struct _Jv_CompiledEngine : public _Jv_ExecutionEngine ...@@ -55,9 +55,25 @@ struct _Jv_CompiledEngine : public _Jv_ExecutionEngine
return NULL; 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) static void do_create_ncode (jclass)
......
...@@ -39,6 +39,9 @@ extern "Java" ...@@ -39,6 +39,9 @@ extern "Java"
// We declare these here to avoid including gcj/cni.h. // We declare these here to avoid including gcj/cni.h.
extern "C" void _Jv_InitClass (jclass klass); extern "C" void _Jv_InitClass (jclass klass);
extern "C" jclass _Jv_NewClassFromInitializer
(const jclass class_initializer);
extern "C" void _Jv_RegisterNewClasses (void **classes);
extern "C" void _Jv_RegisterClasses (const jclass *classes); extern "C" void _Jv_RegisterClasses (const jclass *classes);
extern "C" void _Jv_RegisterClasses_Counted (const jclass *classes, extern "C" void _Jv_RegisterClasses_Counted (const jclass *classes,
size_t count); size_t count);
...@@ -286,7 +289,7 @@ public: ...@@ -286,7 +289,7 @@ public:
JArray<jclass> *getClasses (void); JArray<jclass> *getClasses (void);
java::lang::ClassLoader *getClassLoader (void); java::lang::ClassLoader *getClassLoader (void);
public:
// This is an internal method that circumvents the usual security // This is an internal method that circumvents the usual security
// checks when getting the class loader. // checks when getting the class loader.
java::lang::ClassLoader *getClassLoaderInternal (void) java::lang::ClassLoader *getClassLoaderInternal (void)
...@@ -427,6 +430,8 @@ private: ...@@ -427,6 +430,8 @@ private:
int method_idx); int method_idx);
friend void ::_Jv_InitClass (jclass klass); friend void ::_Jv_InitClass (jclass klass);
friend java::lang::Class* ::_Jv_NewClassFromInitializer (const jclass class_initializer);
friend void _Jv_RegisterNewClasses (void **classes);
friend _Jv_Method* ::_Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *, friend _Jv_Method* ::_Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
_Jv_Utf8Const*, jclass *); _Jv_Utf8Const*, jclass *);
......
...@@ -45,14 +45,17 @@ details. */ ...@@ -45,14 +45,17 @@ details. */
#include <gnu/gcj/runtime/BootClassLoader.h> #include <gnu/gcj/runtime/BootClassLoader.h>
#include <gnu/gcj/runtime/SystemClassLoader.h> #include <gnu/gcj/runtime/SystemClassLoader.h>
#undef _GNU_SOURCE
#define _GNU_SOURCE
#include <dlfcn.h>
#include <link.h>
// Size of local hash table. // Size of local hash table.
#define HASH_LEN 1013 #define HASH_LEN 1013
// Hash function for Utf8Consts. // Hash function for Utf8Consts.
#define HASH_UTF(Utf) ((Utf)->hash16() % HASH_LEN) #define HASH_UTF(Utf) ((Utf)->hash16() % HASH_LEN)
static jclass loaded_classes[HASH_LEN];
// This records classes which will be registered with the system class // This records classes which will be registered with the system class
// loader when it is initialized. // loader when it is initialized.
static jclass system_class_list; static jclass system_class_list;
...@@ -62,6 +65,8 @@ static jclass system_class_list; ...@@ -62,6 +65,8 @@ static jclass system_class_list;
// no longer pay attention to the system abi flag. // no longer pay attention to the system abi flag.
#define SYSTEM_LOADER_INITIALIZED ((jclass) -1) #define SYSTEM_LOADER_INITIALIZED ((jclass) -1)
static jclass loaded_classes[HASH_LEN];
// This is the root of a linked list of classes // This is the root of a linked list of classes
static jclass stack_head; static jclass stack_head;
...@@ -164,6 +169,8 @@ _Jv_UnregisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader) ...@@ -164,6 +169,8 @@ _Jv_UnregisterInitiatingLoader (jclass klass, java::lang::ClassLoader *loader)
void void
_Jv_RegisterClasses (const jclass *classes) _Jv_RegisterClasses (const jclass *classes)
{ {
_Jv_RegisterLibForGc (classes);
for (; *classes; ++classes) for (; *classes; ++classes)
{ {
jclass klass = *classes; jclass klass = *classes;
...@@ -178,6 +185,9 @@ void ...@@ -178,6 +185,9 @@ void
_Jv_RegisterClasses_Counted (const jclass * classes, size_t count) _Jv_RegisterClasses_Counted (const jclass * classes, size_t count)
{ {
size_t i; size_t i;
_Jv_RegisterLibForGc (classes);
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
jclass klass = classes[i]; jclass klass = classes[i];
...@@ -187,6 +197,41 @@ _Jv_RegisterClasses_Counted (const jclass * classes, size_t count) ...@@ -187,6 +197,41 @@ _Jv_RegisterClasses_Counted (const jclass * classes, size_t count)
} }
} }
// Create a class on the heap from an initializer struct.
jclass
_Jv_NewClassFromInitializer (const jclass class_initializer)
{
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))
(*_Jv_RegisterClassHook) (new_class);
return new_class;
}
// Called by compiler-generated code at DSO initialization. CLASSES
// is an array of pairs: the first item of each pair is a pointer to
// the initialized data that is a class initializer in a DSO, and the
// second is a pointer to a class reference.
// _Jv_NewClassFromInitializer() creates the new class (on the Java
// heap) and we write the address of the new class into the address
// pointed to by the second word.
void
_Jv_RegisterNewClasses (void **classes)
{
_Jv_InitGC ();
jclass initializer;
while ((initializer = (jclass)*classes++))
{
jclass *class_ptr = (jclass *)*classes++;
*class_ptr = _Jv_NewClassFromInitializer (initializer);
}
}
void void
_Jv_RegisterClassHookDefault (jclass klass) _Jv_RegisterClassHookDefault (jclass klass)
{ {
...@@ -389,6 +434,12 @@ static _Jv_IDispatchTable *array_idt = NULL; ...@@ -389,6 +434,12 @@ static _Jv_IDispatchTable *array_idt = NULL;
static jshort array_depth = 0; static jshort array_depth = 0;
static jclass *array_ancestors = NULL; static jclass *array_ancestors = NULL;
static jclass interfaces[] =
{
&java::lang::Cloneable::class$,
&java::io::Serializable::class$
};
// Create a class representing an array of ELEMENT and store a pointer to it // Create a class representing an array of ELEMENT and store a pointer to it
// in element->arrayclass. LOADER is the ClassLoader which _initiated_ the // in element->arrayclass. LOADER is the ClassLoader which _initiated_ the
// instantiation of this array. ARRAY_VTABLE is the vtable to use for the new // instantiation of this array. ARRAY_VTABLE is the vtable to use for the new
...@@ -464,11 +515,6 @@ _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader, ...@@ -464,11 +515,6 @@ _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
array_class->element_type = element; array_class->element_type = element;
// Register our interfaces. // Register our interfaces.
static jclass interfaces[] =
{
&java::lang::Cloneable::class$,
&java::io::Serializable::class$
};
array_class->interfaces = interfaces; array_class->interfaces = interfaces;
array_class->interface_count = sizeof interfaces / sizeof interfaces[0]; array_class->interface_count = sizeof interfaces / sizeof interfaces[0];
......
...@@ -21,6 +21,12 @@ details. */ ...@@ -21,6 +21,12 @@ details. */
#include <java-interp.h> #include <java-interp.h>
// Set GC_DEBUG before including gc.h!
#ifdef LIBGCJ_GC_DEBUG
# define GC_DEBUG
#endif
#include <gc.h>
#include <jvm.h> #include <jvm.h>
#include <gcj/cni.h> #include <gcj/cni.h>
#include <string.h> #include <string.h>
...@@ -265,6 +271,21 @@ _Jv_Linker::resolve_pool_entry (jclass klass, int index, bool lazy) ...@@ -265,6 +271,21 @@ _Jv_Linker::resolve_pool_entry (jclass klass, int index, bool lazy)
{ {
using namespace java::lang::reflect; using namespace java::lang::reflect;
if (GC_base (klass) && klass->constants.data
&& ! GC_base (klass->constants.data))
{
jsize count = klass->constants.size;
if (count)
{
_Jv_word* constants
= (_Jv_word*) _Jv_AllocRawObj (count * sizeof (_Jv_word));
memcpy ((void*)constants,
(void*)klass->constants.data,
count * sizeof (_Jv_word));
klass->constants.data = constants;
}
}
_Jv_Constants *pool = &klass->constants; _Jv_Constants *pool = &klass->constants;
if ((pool->tags[index] & JV_CONSTANT_ResolvedFlag) != 0) if ((pool->tags[index] & JV_CONSTANT_ResolvedFlag) != 0)
...@@ -1893,6 +1914,21 @@ _Jv_Linker::wait_for_state (jclass klass, int state) ...@@ -1893,6 +1914,21 @@ _Jv_Linker::wait_for_state (jclass klass, int state)
java::lang::Thread *save = klass->thread; java::lang::Thread *save = klass->thread;
klass->thread = self; klass->thread = self;
// Allocate memory for static fields and constants.
if (GC_base (klass) && klass->fields && ! GC_base (klass->fields))
{
jsize count = klass->field_count;
if (count)
{
_Jv_Field* fields
= (_Jv_Field*) _Jv_AllocRawObj (count * sizeof (_Jv_Field));
memcpy ((void*)fields,
(void*)klass->fields,
count * sizeof (_Jv_Field));
klass->fields = fields;
}
}
// Print some debugging info if requested. Interpreted classes are // Print some debugging info if requested. Interpreted classes are
// handled in defineclass, so we only need to handle the two // handled in defineclass, so we only need to handle the two
// pre-compiled cases here. // pre-compiled cases here.
......
...@@ -224,7 +224,7 @@ proc emit_bc_rule {package} { ...@@ -224,7 +224,7 @@ proc emit_bc_rule {package} {
set omit "| grep -v $exclusion_map($package)" set omit "| grep -v $exclusion_map($package)"
} }
puts "\t@find classpath/lib/$package -name '*.class'${omit} > $tname" puts "\t@find classpath/lib/$package -name '*.class'${omit} > $tname"
puts "\t\$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o $loname @$tname" puts "\t\$(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o $loname @$tname"
puts "\t@rm -f $tname" puts "\t@rm -f $tname"
puts "" puts ""
......
...@@ -164,7 +164,7 @@ classpath/gnu/CORBA/typecodes/StringTypeCode.java ...@@ -164,7 +164,7 @@ classpath/gnu/CORBA/typecodes/StringTypeCode.java
gnu-CORBA.lo: $(gnu_CORBA_source_files) gnu-CORBA.lo: $(gnu_CORBA_source_files)
@find classpath/lib/gnu/CORBA -name '*.class' > gnu-CORBA.list @find classpath/lib/gnu/CORBA -name '*.class' > gnu-CORBA.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-CORBA.lo @gnu-CORBA.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-CORBA.lo @gnu-CORBA.list
@rm -f gnu-CORBA.list @rm -f gnu-CORBA.list
gnu_awt_source_files = \ gnu_awt_source_files = \
...@@ -772,7 +772,7 @@ classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java ...@@ -772,7 +772,7 @@ classpath/gnu/java/awt/peer/gtk/GtkWindowPeer.java
gnu-java-awt-peer-gtk.lo: $(gnu_java_awt_peer_gtk_source_files) gnu-java-awt-peer-gtk.lo: $(gnu_java_awt_peer_gtk_source_files)
@find classpath/lib/gnu/java/awt/peer/gtk -name '*.class' > gnu-java-awt-peer-gtk.list @find classpath/lib/gnu/java/awt/peer/gtk -name '*.class' > gnu-java-awt-peer-gtk.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-java-awt-peer-gtk.lo @gnu-java-awt-peer-gtk.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-java-awt-peer-gtk.lo @gnu-java-awt-peer-gtk.list
@rm -f gnu-java-awt-peer-gtk.list @rm -f gnu-java-awt-peer-gtk.list
gnu_java_awt_peer_qt_source_files = \ gnu_java_awt_peer_qt_source_files = \
...@@ -822,7 +822,7 @@ classpath/gnu/java/awt/peer/qt/QtWindowPeer.java ...@@ -822,7 +822,7 @@ classpath/gnu/java/awt/peer/qt/QtWindowPeer.java
gnu-java-awt-peer-qt.lo: $(gnu_java_awt_peer_qt_source_files) gnu-java-awt-peer-qt.lo: $(gnu_java_awt_peer_qt_source_files)
@find classpath/lib/gnu/java/awt/peer/qt -name '*.class' > gnu-java-awt-peer-qt.list @find classpath/lib/gnu/java/awt/peer/qt -name '*.class' > gnu-java-awt-peer-qt.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-java-awt-peer-qt.lo @gnu-java-awt-peer-qt.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-java-awt-peer-qt.lo @gnu-java-awt-peer-qt.list
@rm -f gnu-java-awt-peer-qt.list @rm -f gnu-java-awt-peer-qt.list
gnu_java_awt_peer_swing_source_files = \ gnu_java_awt_peer_swing_source_files = \
...@@ -843,7 +843,7 @@ classpath/gnu/java/awt/peer/swing/SwingWindowPeer.java ...@@ -843,7 +843,7 @@ classpath/gnu/java/awt/peer/swing/SwingWindowPeer.java
gnu-java-awt-peer-swing.lo: $(gnu_java_awt_peer_swing_source_files) gnu-java-awt-peer-swing.lo: $(gnu_java_awt_peer_swing_source_files)
@find classpath/lib/gnu/java/awt/peer/swing -name '*.class' > gnu-java-awt-peer-swing.list @find classpath/lib/gnu/java/awt/peer/swing -name '*.class' > gnu-java-awt-peer-swing.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-java-awt-peer-swing.lo @gnu-java-awt-peer-swing.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-java-awt-peer-swing.lo @gnu-java-awt-peer-swing.list
@rm -f gnu-java-awt-peer-swing.list @rm -f gnu-java-awt-peer-swing.list
gnu_java_beans_source_files = \ gnu_java_beans_source_files = \
...@@ -932,7 +932,7 @@ classpath/gnu/java/beans/encoder/elements/StringReference.java ...@@ -932,7 +932,7 @@ classpath/gnu/java/beans/encoder/elements/StringReference.java
gnu-java-beans.lo: $(gnu_java_beans_source_files) gnu-java-beans.lo: $(gnu_java_beans_source_files)
@find classpath/lib/gnu/java/beans -name '*.class' > gnu-java-beans.list @find classpath/lib/gnu/java/beans -name '*.class' > gnu-java-beans.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-java-beans.lo @gnu-java-beans.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-java-beans.lo @gnu-java-beans.list
@rm -f gnu-java-beans.list @rm -f gnu-java-beans.list
gnu_java_io_source_files = \ gnu_java_io_source_files = \
...@@ -2833,7 +2833,7 @@ classpath/gnu/javax/rmi/CORBA/ValueHandlerDelegateImpl.java ...@@ -2833,7 +2833,7 @@ classpath/gnu/javax/rmi/CORBA/ValueHandlerDelegateImpl.java
gnu-javax-rmi.lo: $(gnu_javax_rmi_source_files) gnu-javax-rmi.lo: $(gnu_javax_rmi_source_files)
@find classpath/lib/gnu/javax/rmi -name '*.class' > gnu-javax-rmi.list @find classpath/lib/gnu/javax/rmi -name '*.class' > gnu-javax-rmi.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-javax-rmi.lo @gnu-javax-rmi.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-javax-rmi.lo @gnu-javax-rmi.list
@rm -f gnu-javax-rmi.list @rm -f gnu-javax-rmi.list
gnu_javax_security_auth_source_files = \ gnu_javax_security_auth_source_files = \
...@@ -2902,7 +2902,7 @@ classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java ...@@ -2902,7 +2902,7 @@ classpath/gnu/javax/sound/midi/dssi/DSSISynthesizer.java
gnu-javax-sound-midi.lo: $(gnu_javax_sound_midi_source_files) gnu-javax-sound-midi.lo: $(gnu_javax_sound_midi_source_files)
@find classpath/lib/gnu/javax/sound/midi -name '*.class' > gnu-javax-sound-midi.list @find classpath/lib/gnu/javax/sound/midi -name '*.class' > gnu-javax-sound-midi.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-javax-sound-midi.lo @gnu-javax-sound-midi.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-javax-sound-midi.lo @gnu-javax-sound-midi.list
@rm -f gnu-javax-sound-midi.list @rm -f gnu-javax-sound-midi.list
gnu_javax_swing_text_html_parser_source_files = \ gnu_javax_swing_text_html_parser_source_files = \
...@@ -3448,7 +3448,7 @@ classpath/gnu/xml/xpath/XPathTokenizer.java ...@@ -3448,7 +3448,7 @@ classpath/gnu/xml/xpath/XPathTokenizer.java
gnu-xml.lo: $(gnu_xml_source_files) gnu-xml.lo: $(gnu_xml_source_files)
@find classpath/lib/gnu/xml -name '*.class' > gnu-xml.list @find classpath/lib/gnu/xml -name '*.class' > gnu-xml.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o gnu-xml.lo @gnu-xml.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o gnu-xml.lo @gnu-xml.list
@rm -f gnu-xml.list @rm -f gnu-xml.list
java_applet_source_files = \ java_applet_source_files = \
...@@ -5420,7 +5420,7 @@ classpath/javax/imageio/stream/MemoryCacheImageOutputStream.java ...@@ -5420,7 +5420,7 @@ classpath/javax/imageio/stream/MemoryCacheImageOutputStream.java
javax-imageio.lo: $(javax_imageio_source_files) javax-imageio.lo: $(javax_imageio_source_files)
@find classpath/lib/javax/imageio -name '*.class' > javax-imageio.list @find classpath/lib/javax/imageio -name '*.class' > javax-imageio.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o javax-imageio.lo @javax-imageio.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o javax-imageio.lo @javax-imageio.list
@rm -f javax-imageio.list @rm -f javax-imageio.list
javax_management_source_files = \ javax_management_source_files = \
...@@ -5860,7 +5860,7 @@ classpath/javax/rmi/PortableRemoteObject.java ...@@ -5860,7 +5860,7 @@ classpath/javax/rmi/PortableRemoteObject.java
javax-rmi.lo: $(javax_rmi_source_files) javax-rmi.lo: $(javax_rmi_source_files)
@find classpath/lib/javax/rmi -name '*.class' > javax-rmi.list @find classpath/lib/javax/rmi -name '*.class' > javax-rmi.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o javax-rmi.lo @javax-rmi.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o javax-rmi.lo @javax-rmi.list
@rm -f javax-rmi.list @rm -f javax-rmi.list
javax_security_auth_source_files = \ javax_security_auth_source_files = \
...@@ -7051,7 +7051,7 @@ classpath/javax/xml/xpath/XPathVariableResolver.java ...@@ -7051,7 +7051,7 @@ classpath/javax/xml/xpath/XPathVariableResolver.java
javax-xml.lo: $(javax_xml_source_files) javax-xml.lo: $(javax_xml_source_files)
@find classpath/lib/javax/xml -name '*.class' > javax-xml.list @find classpath/lib/javax/xml -name '*.class' > javax-xml.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o javax-xml.lo @javax-xml.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o javax-xml.lo @javax-xml.list
@rm -f javax-xml.list @rm -f javax-xml.list
org_ietf_jgss_source_files = \ org_ietf_jgss_source_files = \
...@@ -7615,7 +7615,7 @@ classpath/org/omg/stub/java/rmi/_Remote_Stub.java ...@@ -7615,7 +7615,7 @@ classpath/org/omg/stub/java/rmi/_Remote_Stub.java
org-omg.lo: $(org_omg_source_files) org-omg.lo: $(org_omg_source_files)
@find classpath/lib/org/omg -name '*.class' > org-omg.list @find classpath/lib/org/omg -name '*.class' > org-omg.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o org-omg.lo @org-omg.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o org-omg.lo @org-omg.list
@rm -f org-omg.list @rm -f org-omg.list
org_relaxng_source_files = \ org_relaxng_source_files = \
...@@ -7632,7 +7632,7 @@ classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/StreamingValidat ...@@ -7632,7 +7632,7 @@ classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/StreamingValidat
org-relaxng.lo: $(org_relaxng_source_files) org-relaxng.lo: $(org_relaxng_source_files)
@find classpath/lib/org/relaxng -name '*.class' > org-relaxng.list @find classpath/lib/org/relaxng -name '*.class' > org-relaxng.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o org-relaxng.lo @org-relaxng.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o org-relaxng.lo @org-relaxng.list
@rm -f org-relaxng.list @rm -f org-relaxng.list
org_w3c_source_files = \ org_w3c_source_files = \
...@@ -7785,7 +7785,7 @@ classpath/external/w3c_dom/org/w3c/dom/xpath/XPathResult.java ...@@ -7785,7 +7785,7 @@ classpath/external/w3c_dom/org/w3c/dom/xpath/XPathResult.java
org-w3c.lo: $(org_w3c_source_files) org-w3c.lo: $(org_w3c_source_files)
@find classpath/lib/org/w3c -name '*.class' > org-w3c.list @find classpath/lib/org/w3c -name '*.class' > org-w3c.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o org-w3c.lo @org-w3c.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o org-w3c.lo @org-w3c.list
@rm -f org-w3c.list @rm -f org-w3c.list
org_xml_source_files = \ org_xml_source_files = \
...@@ -7828,7 +7828,7 @@ classpath/external/sax/org/xml/sax/helpers/XMLReaderFactory.java ...@@ -7828,7 +7828,7 @@ classpath/external/sax/org/xml/sax/helpers/XMLReaderFactory.java
org-xml.lo: $(org_xml_source_files) org-xml.lo: $(org_xml_source_files)
@find classpath/lib/org/xml -name '*.class' > org-xml.list @find classpath/lib/org/xml -name '*.class' > org-xml.list
$(LTGCJCOMPILE) -fjni -findirect-dispatch -c -o org-xml.lo @org-xml.list $(LTGCJCOMPILE) -fjni -findirect-dispatch -fno-indirect-classes -c -o org-xml.lo @org-xml.list
@rm -f org-xml.list @rm -f org-xml.list
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment