This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[BC ABI] Fix generation of type verification assertions
- From: Andrew Haley <aph at redhat dot com>
- To: java-patches at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Fri, 3 Sep 2004 15:35:09 +0100
- Subject: [BC ABI] Fix generation of type verification assertions
- References: <16693.51543.912185.241005@cuddles.cambridge.redhat.com><16693.58779.110358.885898@cuddles.cambridge.redhat.com>
We were generating a ton of inappropriate verify assertions. This
strips them back to that ones that we need.
Mostly, this is just a workaround until we merge in the verifier from
the libgcj runtime.
Andrew.
2004-09-03 Andrew Haley <aph@redhat.com>
* class.c (finish_class): Nullify TYPE_VERIFY_METHOD.
* lang.c (java_post_options): Force flag_verify_invocations if
we're not using indirect dispatch.
* expr.c (pop_type_0): Move test for interfaces before call to
can_widen_reference_to().
(build_signature_for_libgcj): Remove generation of canonical array
type.
(add_type_assertion): Canonicalize both arrays.
Don't assert that type X can be assigned to Object.
Don't assert that type X an be assigned to type X.
Don't assert that Object can be assigned to type X.
(can_widen_reference_to): Warn whenever we generate an assertion.
(process_jvm_instruction): Use throwable_type_node for the type of
an exception class.
Index: class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/class.c,v
retrieving revision 1.180.2.10
diff -p -2 -c -r1.180.2.10 class.c
*** class.c 27 Aug 2004 19:31:40 -0000 1.180.2.10
--- class.c 3 Sep 2004 14:32:59 -0000
*************** make_class_data (tree type)
*** 1795,1799 ****
verify_method)
: null_pointer_node);
! PUSH_FIELD_VALUE (cons, "verify" , verify_method_ref);
}
PUSH_FIELD_VALUE (cons, "hack_signers", null_pointer_node);
--- 1795,1800 ----
verify_method)
: null_pointer_node);
! PUSH_FIELD_VALUE (cons, "verify" , verify_method_ref);
! TYPE_VERIFY_METHOD (type) = NULL;
}
PUSH_FIELD_VALUE (cons, "hack_signers", null_pointer_node);
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/expr.c,v
retrieving revision 1.185.2.10
diff -p -2 -c -r1.185.2.10 expr.c
*** expr.c 1 Sep 2004 13:10:48 -0000 1.185.2.10
--- expr.c 3 Sep 2004 14:33:00 -0000
*************** pop_type_0 (tree type, char **messagep)
*** 345,350 ****
else if (t == ptr_type_node) /* Special case for null reference. */
return type;
- else if (can_widen_reference_to (t, type))
- return t;
/* This is a kludge, but matches what Sun's verifier does.
It can be tricked, but is safe as long as type errors
--- 345,348 ----
*************** pop_type_0 (tree type, char **messagep)
*** 352,355 ****
--- 350,355 ----
else if (CLASS_INTERFACE (TYPE_NAME (TREE_TYPE (type))))
return object_ptr_type_node;
+ else if (can_widen_reference_to (t, type))
+ return t;
}
*************** build_signature_for_libgcj (tree type)
*** 425,430 ****
tree sig, ref;
- if (TYPE_ARRAY_P (type))
- type = build_java_array_type (TYPE_ARRAY_ELEMENT (type), -1);
sig = build_java_signature (type);
ref = build_utf8_ref (unmangle_classname (IDENTIFIER_POINTER (sig),
--- 425,428 ----
*************** add_type_assertion (tree source_type, tr
*** 444,447 ****
--- 442,461 ----
tree arg;
+ if (TYPE_ARRAY_P (source_type))
+ source_type = build_java_array_type (TYPE_ARRAY_ELEMENT (source_type), -1);
+ if (TYPE_ARRAY_P (target_type))
+ target_type = build_java_array_type (TYPE_ARRAY_ELEMENT (target_type), -1);
+
+ if (target_type == object_type_node)
+ return;
+
+ if (source_type == target_type)
+ return;
+
+ // FIXME: This is just a placeholder for merged types. We need to
+ // do something more real than this.
+ if (source_type == object_type_node)
+ return;
+
if (! verify_method)
{
*************** can_widen_reference_to (tree source_type
*** 520,531 ****
However, we could do something more optimal. */
if (! flag_verify_invocations)
- add_type_assertion (source_type, target_type);
-
- if (TYPE_DUMMY (source_type) || TYPE_DUMMY (target_type))
{
if (!quiet_flag)
warning ("assert: %s is assign compatible with %s",
xstrdup (lang_printable_name (target_type, 0)),
xstrdup (lang_printable_name (source_type, 0)));
return 1;
}
--- 534,550 ----
However, we could do something more optimal. */
if (! flag_verify_invocations)
{
+ add_type_assertion (source_type, target_type);
+
if (!quiet_flag)
warning ("assert: %s is assign compatible with %s",
xstrdup (lang_printable_name (target_type, 0)),
xstrdup (lang_printable_name (source_type, 0)));
+ /* Punt everything to runtime. */
+ return 1;
+ }
+
+ if (TYPE_DUMMY (source_type) || TYPE_DUMMY (target_type))
+ {
return 1;
}
*************** process_jvm_instruction (int PC, const u
*** 3177,3181 ****
if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
{
! tree type = pop_type (ptr_type_node);
push_value (build_exception_object_ref (type));
}
--- 3196,3200 ----
if (instruction_bits [PC] & BCODE_EXCEPTION_TARGET)
{
! tree type = pop_type (promote_type (throwable_type_node));
push_value (build_exception_object_ref (type));
}
Index: lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/lang.c,v
retrieving revision 1.151.2.2
diff -p -2 -c -r1.151.2.2 lang.c
*** lang.c 20 May 2004 23:32:51 -0000 1.151.2.2
--- lang.c 3 Sep 2004 14:33:00 -0000
*************** java_post_options (const char **pfilenam
*** 741,744 ****
--- 741,749 ----
}
+ /* An absolute requirement: if we're not using indirect dispatch, we
+ must always verify everything. */
+ if (! flag_indirect_dispatch)
+ flag_verify_invocations = true;
+
/* Open input file. */
Index: verify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/verify.c,v
retrieving revision 1.59.10.3
diff -p -2 -c -r1.59.10.3 verify.c
*** verify.c 17 Aug 2004 13:42:19 -0000 1.59.10.3
--- verify.c 3 Sep 2004 14:33:01 -0000
*************** static tree
*** 125,136 ****
defer_merging (tree type1, tree type2)
{
! if (TYPE_DUMMY (type1) || TYPE_DUMMY (type2))
! {
! if (! quiet_flag)
! warning ("assert: cannot merge types %s and %s",
! xstrdup (lang_printable_name (type1, 0)),
! xstrdup (lang_printable_name (type2, 0)));
! }
!
return object_ptr_type_node;
--- 125,131 ----
defer_merging (tree type1, tree type2)
{
! // FIXME: This is just a placeholder until we replace the verifier
! // altogether. We really need to ouput a type assertion for all of
! // the types, every time they are used.
return object_ptr_type_node;