This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Re: Java: fixes for -fno-assume-compiled
- From: Jeff Sturm <jsturm at one-point dot com>
- To: Tom Tromey <tromey at redhat dot com>
- Cc: java-patches at gcc dot gnu dot org, <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 23 Dec 2002 15:02:49 -0500 (EST)
- Subject: Re: Java: fixes for -fno-assume-compiled
On 19 Dec 2002, Tom Tromey wrote:
> The runtime side is ok once the unsigned change and Andrew's point
> (about integer type size) is addressed.
Thanks. I've committed both patches as follows.
2002-12-23 Jeff Sturm <jsturm@one-point.com>
* class.c (build_static_field_ref): Check FIELD_FINAL.
* constants.c (alloc_class_constant): Use TYPE_CPOOL_DATA_REF
instead of current_constant_pool_data_ref.
* java-tree.h (current_constant_pool_data_ref): Undefine.
(JTI_CURRENT_CONSTANT_POOL_DATA_REF): Remove.
* jcf-parse.c (init_outgoing_cpool): Don't initialize
current_constant_pool_data_ref.
* except.c (prepare_eh_table_type ): Use DECL_NAME of class type,
not build_internal_class_name.
* parse.y (patch_incomplete_class_ref): Always emit `class$' method.
Use it when class ref isn't certain to be compiled.
Index: class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/class.c,v
retrieving revision 1.140
diff -u -p -r1.140 class.c
--- class.c 16 Dec 2002 18:22:32 -0000 1.140
+++ class.c 23 Dec 2002 19:13:52 -0000
@@ -1076,7 +1076,9 @@ build_static_field_ref (fdecl)
{
tree fclass = DECL_CONTEXT (fdecl);
int is_compiled = is_compiled_class (fclass);
- if (is_compiled)
+
+ /* Allow static final fields to fold to a constant. */
+ if (is_compiled || FIELD_FINAL (fdecl))
{
if (!DECL_RTL_SET_P (fdecl))
{
Index: constants.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/constants.c,v
retrieving revision 1.23
diff -u -p -r1.23 constants.c
--- constants.c 16 Dec 2002 18:22:32 -0000 1.23
+++ constants.c 23 Dec 2002 19:13:53 -0000
@@ -388,10 +388,12 @@ alloc_class_constant (clas)
static tree
build_constant_data_ref ()
{
+ tree cpool_data_ref = NULL_TREE;
+
if (TYPE_CPOOL_DATA_REF (current_class))
- current_constant_pool_data_ref = TYPE_CPOOL_DATA_REF (current_class);
+ cpool_data_ref = TYPE_CPOOL_DATA_REF (current_class);
- else if (current_constant_pool_data_ref == NULL_TREE)
+ if (cpool_data_ref == NULL_TREE)
{
tree decl;
tree decl_name = mangled_classname ("_CD_", current_class);
@@ -400,10 +402,10 @@ build_constant_data_ref ()
one_elt_array_domain_type));
TREE_STATIC (decl) = 1;
make_decl_rtl (decl, NULL);
- TYPE_CPOOL_DATA_REF (current_class) = current_constant_pool_data_ref
+ TYPE_CPOOL_DATA_REF (current_class) = cpool_data_ref
= build1 (ADDR_EXPR, ptr_type_node, decl);
}
- return current_constant_pool_data_ref;
+ return cpool_data_ref;
}
/* Get the pointer value at the INDEX'th element of the constant pool. */
Index: except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/except.c,v
retrieving revision 1.31
diff -u -p -r1.31 except.c
--- except.c 16 Dec 2002 18:22:32 -0000 1.31
+++ except.c 23 Dec 2002 19:13:53 -0000
@@ -336,7 +336,7 @@ prepare_eh_table_type (type)
else
exp = fold (build
(PLUS_EXPR, ptr_type_node,
- build_utf8_ref (build_internal_class_name (type)),
+ build_utf8_ref (DECL_NAME (TYPE_NAME (type))),
size_one_node));
return exp;
}
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.163
diff -u -p -r1.163 java-tree.h
--- java-tree.h 18 Nov 2002 18:13:35 -0000 1.163
+++ java-tree.h 23 Dec 2002 19:13:54 -0000
@@ -399,7 +399,6 @@ enum java_tree_index
JTI_NATIVECODE_PTR_ARRAY_TYPE_NODE,
JTI_WFL_OPERATOR,
- JTI_CURRENT_CONSTANT_POOL_DATA_REF,
JTI_MAIN_CLASS,
JTI_CURRENT_CLASS,
@@ -685,10 +684,6 @@ extern GTY(()) tree java_global_trees[JT
/* They need to be reset before processing each class */
extern struct CPool *outgoing_cpool;
-/* If non-NULL, an ADDR_EXPR referencing a VAR_DECL containing
- the constant data array for the current class. */
-#define current_constant_pool_data_ref \
- java_global_trees[JTI_CURRENT_CONSTANT_POOL_DATA_REF]
#define wfl_operator \
java_global_trees[JTI_WFL_OPERATOR]
Index: jcf-parse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-parse.c,v
retrieving revision 1.125
diff -u -p -r1.125 jcf-parse.c
--- jcf-parse.c 16 Dec 2002 18:22:34 -0000 1.125
+++ jcf-parse.c 23 Dec 2002 19:13:56 -0000
@@ -709,7 +709,6 @@ load_inner_classes (cur_class)
void
init_outgoing_cpool ()
{
- current_constant_pool_data_ref = NULL_TREE;
outgoing_cpool = xmalloc (sizeof (struct CPool));
memset (outgoing_cpool, 0, sizeof (struct CPool));
}
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.407
diff -u -p -r1.407 parse.y
--- parse.y 19 Dec 2002 06:43:12 -0000 1.407
+++ parse.y 23 Dec 2002 19:14:04 -0000
@@ -14073,7 +14073,16 @@ patch_incomplete_class_ref (node)
if (!(ref_type = resolve_type_during_patch (type)))
return error_mark_node;
- if (!flag_emit_class_files || JPRIMITIVE_TYPE_P (ref_type)
+ /* Generate the synthetic static method `class$'. (Previously we
+ deferred this, causing different method tables to be emitted
+ for native code and bytecode.) */
+ if (!TYPE_DOT_CLASS (current_class))
+ build_dot_class_method (current_class);
+
+ /* If we're not emitting class files and we know ref_type is a
+ compiled class, build a direct reference. */
+ if ((! flag_emit_class_files && is_compiled_class (ref_type))
+ || JPRIMITIVE_TYPE_P (ref_type)
|| TREE_CODE (ref_type) == VOID_TYPE)
{
tree dot = build_class_ref (ref_type);
@@ -14084,10 +14093,7 @@ patch_incomplete_class_ref (node)
}
/* If we're emitting class files and we have to deal with non
- primitive types, we invoke (and consider generating) the
- synthetic static method `class$'. */
- if (!TYPE_DOT_CLASS (current_class))
- build_dot_class_method (current_class);
+ primitive types, we invoke the synthetic static method `class$'. */
ref_type = build_dot_class_method_invocation (ref_type);
return java_complete_tree (ref_type);
}
2002-12-23 Jeff Sturm <jsturm@one-point.com>
* exception.cc (PERSONALITY_FUNCTION): Clear least-significant-bit
of catch_type.
* java/lang/natClass.cc (initializeClass): Link vtable, otable,
idt tables after initializing superclass.
* java/lang/natClassLoader.cc (uaddr): New typedef.
(_Jv_PrepareCompiledClass): Resolve superclass, interfaces
if they are constant pool indicies. Don't link vtable, otable yet.
Index: exception.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/exception.cc,v
retrieving revision 1.21
diff -u -p -r1.21 exception.cc
--- exception.cc 6 Apr 2002 04:19:10 -0000 1.21
+++ exception.cc 23 Dec 2002 19:42:22 -0000
@@ -338,7 +338,7 @@ PERSONALITY_FUNCTION (int version,
// The catch_type is either a (java::lang::Class*) or
// is one more than a (Utf8Const*).
if ((size_t)catch_type & 1)
- catch_type = _Jv_FindClass ((Utf8Const*)catch_type - 1, NULL);
+ catch_type = _Jv_FindClass ((Utf8Const*)((size_t)catch_type ^ 1), NULL);
if (_Jv_IsInstanceOf (xh->value, catch_type))
{
Index: java/lang/natClass.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClass.cc,v
retrieving revision 1.58
diff -u -p -r1.58 natClass.cc
--- java/lang/natClass.cc 19 Dec 2002 19:31:54 -0000 1.58
+++ java/lang/natClass.cc 23 Dec 2002 19:42:24 -0000
@@ -758,9 +758,6 @@ java::lang::Class::initializeClass (void
}
}
- if (state <= JV_STATE_LINKED)
- _Jv_PrepareConstantTimeTables (this);
-
// Step 2.
java::lang::Thread *self = java::lang::Thread::currentThread();
// FIXME: `self' can be null at startup. Hence this nasty trick.
@@ -804,6 +801,14 @@ java::lang::Class::initializeClass (void
throw except;
}
}
+
+ _Jv_PrepareConstantTimeTables (this);
+
+ if (vtable == NULL)
+ _Jv_MakeVTable(this);
+
+ if (otable != NULL && otable->state == 0)
+ _Jv_LinkOffsetTable(this);
// Steps 8, 9, 10, 11.
try
Index: java/lang/natClassLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClassLoader.cc,v
retrieving revision 1.56
diff -u -p -r1.56 natClassLoader.cc
--- java/lang/natClassLoader.cc 19 Dec 2002 19:31:54 -0000 1.56
+++ java/lang/natClassLoader.cc 23 Dec 2002 19:42:24 -0000
@@ -178,6 +178,8 @@ java::lang::VMClassLoader::getPrimitiveC
return _Jv_FindClassFromSignature (sig, NULL);
}
+typedef unsigned int uaddr __attribute__ ((mode (pointer)));
+
/** This function does class-preparation for compiled classes.
NOTE: It contains replicated functionality from
_Jv_ResolvePoolEntry, and this is intentional, since that function
@@ -193,6 +195,9 @@ _Jv_PrepareCompiledClass (jclass klass)
klass->state = JV_STATE_LINKED;
_Jv_Constants *pool = &klass->constants;
+
+ // Resolve class constants first, since other constant pool
+ // entries may rely on these.
for (int index = 1; index < pool->size; ++index)
{
if (pool->tags[index] == JV_CONSTANT_Class)
@@ -215,7 +220,22 @@ _Jv_PrepareCompiledClass (jclass klass)
pool->data[index].clazz = found;
pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
}
- else if (pool->tags[index] == JV_CONSTANT_String)
+ }
+
+ // If superclass looks like a constant pool entry,
+ // resolve it now.
+ if ((uaddr) klass->superclass < pool->size)
+ klass->superclass = pool->data[(int) klass->superclass].clazz;
+
+ // Likewise for interfaces.
+ for (int i = 0; i < klass->interface_count; i++)
+ if ((uaddr) klass->interfaces[i] < pool->size)
+ klass->interfaces[i] = pool->data[(int) klass->interfaces[i]].clazz;
+
+ // Resolve the remaining constant pool entries.
+ for (int index = 1; index < pool->size; ++index)
+ {
+ if (pool->tags[index] == JV_CONSTANT_String)
{
jstring str;
@@ -250,12 +270,6 @@ _Jv_PrepareCompiledClass (jclass klass)
#ifdef INTERPRETER
}
#endif /* INTERPRETER */
-
- if (klass->vtable == NULL)
- _Jv_MakeVTable(klass);
-
- if (klass->otable != NULL && klass->otable->state == 0)
- _Jv_LinkOffsetTable(klass);
klass->notifyAll ();