public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [vta/trunk] stabilize Java JNI function types
@ 2007-11-12 20:09 Alexandre Oliva
  2007-11-12 20:33 ` Andrew Haley
  0 siblings, 1 reply; 3+ messages in thread
From: Alexandre Oliva @ 2007-11-12 20:09 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1447 bytes --]

Using type uids for hashing requires us to make sure that
canonicalizing a type always gets us the type with the same uid.
Unfortunately, if a type is garbage collected in between uses, we
won't canonicalize to it any more, and will instead use a new type.
If the canonicalization could have avoided the creation of other
types, this will also have the effect of getting TYPE_UIDs out of sync
between the compilations with or without garbage collection of that
type.  If they do get out of sync, we often get changes to Java UTF8
sections.

As it turns out, the Java front-end builds types to hold the proper
type of a JNI method implementation, but only uses it in code, and
so the type can quickly get garbage collected.

With as simple a change as using that type for the meth variable that
holds the pointer to that implementation, we keep the type around such
that other methods with the same signature get the same canonical
type, regardless of garbage collection.

As an additional benefit, the variable gets the correct static type in
debug information, rather than a generic pointer type.

Ok for trunk?  This is the last patch I needed to get
make bootstrap-debug &&
make prepare-bootstrap4-debug-lib-novta &&
make bootstrap4-debug &&
rm compare3-debug && make compare3-debug

to pass, i.e., all target libraries compiled with
-fvar-tracking-assignments and with -fno-var-tracking-assignments
compared identically, on x86_64-linux-gnu.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: gcc-stabilize-java-jnitypes-gc.patch --]
[-- Type: text/x-patch, Size: 2588 bytes --]

for  gcc/java/ChangeLog.vta
from  Alexandre Oliva  <aoliva@redhat.com>

	* expr.c (build_jni_stub): Use the computed jni func type for
	variable meth.

Index: gcc/java/expr.c
===================================================================
--- gcc/java/expr.c.orig	2007-11-11 20:36:03.000000000 -0200
+++ gcc/java/expr.c	2007-11-11 20:59:33.000000000 -0200
@@ -2651,17 +2651,6 @@ build_jni_stub (tree method)
       TREE_CHAIN (env_var) = res_var;
     }
 
-  meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
-  TREE_STATIC (meth_var) = 1;
-  TREE_PUBLIC (meth_var) = 0;
-  DECL_EXTERNAL (meth_var) = 0;
-  DECL_CONTEXT (meth_var) = method;
-  DECL_ARTIFICIAL (meth_var) = 1;
-  DECL_INITIAL (meth_var) = null_pointer_node;
-  TREE_USED (meth_var) = 1;
-  chainon (env_var, meth_var);
-  build_result_decl (method);
-
   method_args = DECL_ARGUMENTS (method);
   block = build_block (env_var, NULL_TREE, method_args, NULL_TREE);
   TREE_SIDE_EFFECTS (block) = 1;
@@ -2725,23 +2714,35 @@ build_jni_stub (tree method)
 
   jni_func_type = build_pointer_type (tem);
 
-  jnifunc = build3 (COND_EXPR, ptr_type_node,
+  meth_var = build_decl (VAR_DECL, get_identifier ("meth"), jni_func_type);
+  TREE_STATIC (meth_var) = 1;
+  TREE_PUBLIC (meth_var) = 0;
+  DECL_EXTERNAL (meth_var) = 0;
+  DECL_CONTEXT (meth_var) = method;
+  DECL_ARTIFICIAL (meth_var) = 1;
+  DECL_INITIAL (meth_var) = null_pointer_node;
+  TREE_USED (meth_var) = 1;
+  chainon (env_var, meth_var);
+  build_result_decl (method);
+
+  jnifunc = build3 (COND_EXPR, jni_func_type,
 		    build2 (NE_EXPR, boolean_type_node,
 			    meth_var, build_int_cst (TREE_TYPE (meth_var), 0)),
 		    meth_var,
-		    build2 (MODIFY_EXPR, ptr_type_node, meth_var,
-			    build_call_nary (ptr_type_node,
-					     build_address_of
-					       (soft_lookupjnimethod_node),
-					     4,
-					     jniarg0, jniarg1,
-					     jniarg2, jniarg3)));
+		    build2 (MODIFY_EXPR, jni_func_type, meth_var,
+			    build1
+			    (NOP_EXPR, jni_func_type,
+			     build_call_nary (ptr_type_node,
+					      build_address_of
+					      (soft_lookupjnimethod_node),
+					      4,
+					      jniarg0, jniarg1,
+					      jniarg2, jniarg3))));
 
   /* Now we make the actual JNI call via the resulting function
      pointer.    */
   call = build_call_list (TREE_TYPE (TREE_TYPE (method)),
-			  build1 (NOP_EXPR, jni_func_type, jnifunc),
-			  args);
+			  jnifunc, args);
 
   /* If the JNI call returned a result, capture it here.  If we had to
      unwrap JNI object results, we would do that here.  */

[-- Attachment #3: Type: text/plain, Size: 249 bytes --]


-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
FSF Latin America Board Member         http://www.fsfla.org/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [vta/trunk] stabilize Java JNI function types
  2007-11-12 20:09 [vta/trunk] stabilize Java JNI function types Alexandre Oliva
@ 2007-11-12 20:33 ` Andrew Haley
  2007-11-26  9:27   ` Alexandre Oliva
  0 siblings, 1 reply; 3+ messages in thread
From: Andrew Haley @ 2007-11-12 20:33 UTC (permalink / raw)
  To: Alexandre Oliva; +Cc: gcc-patches

Alexandre Oliva writes:
 > Using type uids for hashing requires us to make sure that
 > canonicalizing a type always gets us the type with the same uid.
 > Unfortunately, if a type is garbage collected in between uses, we
 > won't canonicalize to it any more, and will instead use a new type.
 > If the canonicalization could have avoided the creation of other
 > types, this will also have the effect of getting TYPE_UIDs out of sync
 > between the compilations with or without garbage collection of that
 > type.  If they do get out of sync, we often get changes to Java UTF8
 > sections.
 > 
 > As it turns out, the Java front-end builds types to hold the proper
 > type of a JNI method implementation, but only uses it in code, and
 > so the type can quickly get garbage collected.
 > 
 > With as simple a change as using that type for the meth variable that
 > holds the pointer to that implementation, we keep the type around such
 > that other methods with the same signature get the same canonical
 > type, regardless of garbage collection.
 > 
 > As an additional benefit, the variable gets the correct static type in
 > debug information, rather than a generic pointer type.
 > 
 > Ok for trunk?  This is the last patch I needed to get
 > make bootstrap-debug &&
 > make prepare-bootstrap4-debug-lib-novta &&
 > make bootstrap4-debug &&
 > rm compare3-debug && make compare3-debug
 > 
 > to pass, i.e., all target libraries compiled with
 > -fvar-tracking-assignments and with -fno-var-tracking-assignments
 > compared identically, on x86_64-linux-gnu.
 > 
 > for  gcc/java/ChangeLog.vta
 > from  Alexandre Oliva  <aoliva@redhat.com>
 > 
 > 	* expr.c (build_jni_stub): Use the computed jni func type for
 > 	variable meth.
 > 

Ok, if you include a comment in the source explaining why you do this.

Andrew.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [vta/trunk] stabilize Java JNI function types
  2007-11-12 20:33 ` Andrew Haley
@ 2007-11-26  9:27   ` Alexandre Oliva
  0 siblings, 0 replies; 3+ messages in thread
From: Alexandre Oliva @ 2007-11-26  9:27 UTC (permalink / raw)
  To: Andrew Haley; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 256 bytes --]

On Nov 12, 2007, Andrew Haley <aph-gcc@littlepinkcloud.COM> wrote:

>> * expr.c (build_jni_stub): Use the computed jni func type for
>> variable meth.

> Ok, if you include a comment in the source explaining why you do this.

Here's what I've checked in.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: gcc-stabilize-java-jnitypes-gc.patch --]
[-- Type: text/x-patch, Size: 2925 bytes --]

for  gcc/java/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* expr.c (build_jni_stub): Use the computed jni func type for
	variable meth.

Index: gcc/java/expr.c
===================================================================
--- gcc/java/expr.c.orig	2007-11-25 02:54:58.000000000 -0200
+++ gcc/java/expr.c	2007-11-25 03:09:27.000000000 -0200
@@ -2651,17 +2651,6 @@ build_jni_stub (tree method)
       TREE_CHAIN (env_var) = res_var;
     }
 
-  meth_var = build_decl (VAR_DECL, get_identifier ("meth"), ptr_type_node);
-  TREE_STATIC (meth_var) = 1;
-  TREE_PUBLIC (meth_var) = 0;
-  DECL_EXTERNAL (meth_var) = 0;
-  DECL_CONTEXT (meth_var) = method;
-  DECL_ARTIFICIAL (meth_var) = 1;
-  DECL_INITIAL (meth_var) = null_pointer_node;
-  TREE_USED (meth_var) = 1;
-  chainon (env_var, meth_var);
-  build_result_decl (method);
-
   method_args = DECL_ARGUMENTS (method);
   block = build_block (env_var, NULL_TREE, method_args, NULL_TREE);
   TREE_SIDE_EFFECTS (block) = 1;
@@ -2725,23 +2714,40 @@ build_jni_stub (tree method)
 
   jni_func_type = build_pointer_type (tem);
 
-  jnifunc = build3 (COND_EXPR, ptr_type_node,
+  /* Use the actual function type, rather than a generic pointer type,
+     such that this decl keeps the actual pointer type from being
+     garbage-collected.  If it is, we end up using canonical types
+     with different uids for equivalent function types, and this in
+     turn causes utf8 identifiers and output order to vary.  */
+  meth_var = build_decl (VAR_DECL, get_identifier ("meth"), jni_func_type);
+  TREE_STATIC (meth_var) = 1;
+  TREE_PUBLIC (meth_var) = 0;
+  DECL_EXTERNAL (meth_var) = 0;
+  DECL_CONTEXT (meth_var) = method;
+  DECL_ARTIFICIAL (meth_var) = 1;
+  DECL_INITIAL (meth_var) = null_pointer_node;
+  TREE_USED (meth_var) = 1;
+  chainon (env_var, meth_var);
+  build_result_decl (method);
+
+  jnifunc = build3 (COND_EXPR, jni_func_type,
 		    build2 (NE_EXPR, boolean_type_node,
 			    meth_var, build_int_cst (TREE_TYPE (meth_var), 0)),
 		    meth_var,
-		    build2 (MODIFY_EXPR, ptr_type_node, meth_var,
-			    build_call_nary (ptr_type_node,
-					     build_address_of
-					       (soft_lookupjnimethod_node),
-					     4,
-					     jniarg0, jniarg1,
-					     jniarg2, jniarg3)));
+		    build2 (MODIFY_EXPR, jni_func_type, meth_var,
+			    build1
+			    (NOP_EXPR, jni_func_type,
+			     build_call_nary (ptr_type_node,
+					      build_address_of
+					      (soft_lookupjnimethod_node),
+					      4,
+					      jniarg0, jniarg1,
+					      jniarg2, jniarg3))));
 
   /* Now we make the actual JNI call via the resulting function
      pointer.    */
   call = build_call_list (TREE_TYPE (TREE_TYPE (method)),
-			  build1 (NOP_EXPR, jni_func_type, jnifunc),
-			  args);
+			  jnifunc, args);
 
   /* If the JNI call returned a result, capture it here.  If we had to
      unwrap JNI object results, we would do that here.  */

[-- Attachment #3: Type: text/plain, Size: 249 bytes --]


-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
FSF Latin America Board Member         http://www.fsfla.org/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-11-26  6:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-12 20:09 [vta/trunk] stabilize Java JNI function types Alexandre Oliva
2007-11-12 20:33 ` Andrew Haley
2007-11-26  9:27   ` Alexandre Oliva

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).