public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Symbol visibility for gcj
@ 2007-03-23 18:47 Andrew Haley
  2007-03-23 19:34 ` David Daney
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Andrew Haley @ 2007-03-23 18:47 UTC (permalink / raw)
  To: gcc-patches, java-patches

[-- Attachment #1: message body text --]
[-- Type: text/plain, Size: 4218 bytes --]

This changes the symbol export rules for gcj-built DSOs.  We no longer
output symbols for:

private static methods
private static fields
private classes
vtables (except java.lang.Class)
class$$ fields

This reduces the number of symbols in libgcj.so from 87509 to 66209, a
saving of 20%.

I've attached the list of symbols that are no longer emitted.  

I don't believe it should cause any problems, but it is possible that
this will break some code that was using CNI to access private symbols
inside a DSO.  I don't think we care about that.

Andrew.



2007-03-23  Andrew Haley  <aph@redhat.com>

	* jvgenmain.c (main): Change main to use class$, not class$$.
	(do_mangle_classname): Likewise.
	* class.c (hide): New function.
	(add_field): Hide everything that shouldn't be visible outside a
	DSO.
	(build_static_class_ref): Likewise.
	(build_classdollar_field): Likewise.
	(make_class_data): Likewise.
	(layout_class_method): Likewise.
	
Index: class.c
===================================================================
--- class.c	(revision 123084)
+++ class.c	(working copy)
@@ -691,6 +691,13 @@
   return fntype;
 }
 
+static void
+hide (tree decl)
+{
+  DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+  DECL_VISIBILITY_SPECIFIED (decl) = 1;
+}
+
 tree
 add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
 {
@@ -801,6 +808,10 @@
       /* Always make field externally visible.  This is required so
 	 that native methods can always access the field.  */
       TREE_PUBLIC (field) = 1;
+      /* Hide everything that shouldn't be visible outside a DSO.  */
+      if (flag_indirect_classes
+	  || (FIELD_PRIVATE (field)))
+	hide (field);
       /* Considered external unless we are compiling it into this
 	 object file.  */
       DECL_EXTERNAL (field) = (is_compiled_class (class) != 2);
@@ -958,7 +969,11 @@
       decl = build_decl (VAR_DECL, decl_name, class_type_node);
       TREE_STATIC (decl) = 1;
       if (! flag_indirect_classes)
-	TREE_PUBLIC (decl) = 1;
+	{
+	  TREE_PUBLIC (decl) = 1;
+	  if (CLASS_PRIVATE (TYPE_NAME (type)))
+	    hide (decl);
+	}
       DECL_IGNORED_P (decl) = 1;
       DECL_ARTIFICIAL (decl) = 1;
       if (is_compiled_class (type) == 1)
@@ -997,6 +1012,7 @@
       TREE_CONSTANT (decl) = 1;
       TREE_READONLY (decl) = 1;
       TREE_PUBLIC (decl) = 1;
+      hide (decl);
       DECL_IGNORED_P (decl) = 1;
       DECL_ARTIFICIAL (decl) = 1;
       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
@@ -1684,6 +1700,10 @@
 
       TREE_PUBLIC (dtable_decl) = 1;
       DECL_INITIAL (dtable_decl) = dtable;
+      /* The only dispatch table exported from a DSO is the dispatch
+	 table for java.lang.Class.  */
+      if (DECL_NAME (type_decl) != id_class)
+	hide (dtable_decl);
       if (! flag_indirect_classes)
 	rest_of_decl_compilation (dtable_decl, 1, 0);
       /* Maybe we're compiling Class as the first class.  If so, set
@@ -2553,6 +2573,10 @@
 
   TREE_PUBLIC (method_decl) = 1;
 
+  if (flag_indirect_classes
+      || (METHOD_PRIVATE (method_decl) && METHOD_STATIC (method_decl)))
+    hide (method_decl);
+
   /* Considered external unless it is being compiled into this object
      file, or it was already flagged as external.  */
   if (!DECL_EXTERNAL (method_decl))
Index: jvgenmain.c
===================================================================
--- jvgenmain.c	(revision 123084)
+++ jvgenmain.c	(working copy)
@@ -143,8 +143,8 @@
     fprintf (stream, "   JvRunMainName (\"%s\", argc, argv);\n", classname);
   else
     {
-      fprintf (stream, "   extern void *%s;\n", mangled_classname);
-      fprintf (stream, "   JvRunMain (%s, argc, argv);\n", mangled_classname);
+      fprintf (stream, "   extern char %s;\n", mangled_classname);
+      fprintf (stream, "   JvRunMain (&%s, argc, argv);\n", mangled_classname);
     }
   fprintf (stream, "}\n");
   if (stream != stdout && fclose (stream) != 0)
@@ -176,7 +176,7 @@
 	count++;
     }
   append_gpp_mangled_name (&ptr [-count], count);
-  obstack_grow (mangle_obstack, "7class$$E", strlen ("7class$$E"));
+  obstack_grow (mangle_obstack, "6class$E", strlen ("6class$E"));
   obstack_1grow (mangle_obstack, '\0');
   return obstack_finish (mangle_obstack);
 }



[-- Attachment #2: nosyms.gz --]
[-- Type: application/octet-stream, Size: 102151 bytes --]

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

* Re: Symbol visibility for gcj
  2007-03-23 18:47 Symbol visibility for gcj Andrew Haley
@ 2007-03-23 19:34 ` David Daney
  2007-03-23 19:37   ` Andrew Haley
  2007-03-24  0:09 ` Mark Wielaard
  2007-03-29 16:18 ` Andrew Haley
  2 siblings, 1 reply; 7+ messages in thread
From: David Daney @ 2007-03-23 19:34 UTC (permalink / raw)
  To: Andrew Haley; +Cc: gcc-patches, java-patches

Andrew Haley wrote:
> This changes the symbol export rules for gcj-built DSOs.  We no longer
> output symbols for:
> 
> private static methods
> private static fields
> private classes
> vtables (except java.lang.Class)
> class$$ fields
> 
> This reduces the number of symbols in libgcj.so from 87509 to 66209, a
> saving of 20%.

Does that really matter?  I suppose it might reduce the number of pages 
that are faulted in when the dynamic linker is working because the 
interesting symbols would be spread across fewer pages.

How does your change affect the number of relocations in libgcj.so or 
the values returned by size?

David Daney

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

* Re: Symbol visibility for gcj
  2007-03-23 19:34 ` David Daney
@ 2007-03-23 19:37   ` Andrew Haley
  0 siblings, 0 replies; 7+ messages in thread
From: Andrew Haley @ 2007-03-23 19:37 UTC (permalink / raw)
  To: David Daney; +Cc: gcc-patches, java-patches

David Daney writes:
 > Andrew Haley wrote:
 > > This changes the symbol export rules for gcj-built DSOs.  We no longer
 > > output symbols for:
 > > 
 > > private static methods
 > > private static fields
 > > private classes
 > > vtables (except java.lang.Class)
 > > class$$ fields
 > > 
 > > This reduces the number of symbols in libgcj.so from 87509 to 66209, a
 > > saving of 20%.
 > 
 > Does that really matter?  I suppose it might reduce the number of pages 
 > that are faulted in when the dynamic linker is working because the 
 > interesting symbols would be spread across fewer pages.

Right, and the size of the file, etc, etc.

 > How does your change affect the number of relocations in libgcj.so

There's a small reduction, less than 1%.

 > or the values returned by size?

Sorry?

Andrew.

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

* Re: Symbol visibility for gcj
  2007-03-23 18:47 Symbol visibility for gcj Andrew Haley
  2007-03-23 19:34 ` David Daney
@ 2007-03-24  0:09 ` Mark Wielaard
  2007-03-24  0:47   ` David Daney
  2007-03-24 16:59   ` Andrew Haley
  2007-03-29 16:18 ` Andrew Haley
  2 siblings, 2 replies; 7+ messages in thread
From: Mark Wielaard @ 2007-03-24  0:09 UTC (permalink / raw)
  To: Andrew Haley; +Cc: gcc-patches, java-patches

On Fri, 2007-03-23 at 18:18 +0000, Andrew Haley wrote:
> I don't believe it should cause any problems, but it is possible that
> this will break some code that was using CNI to access private symbols
> inside a DSO.  I don't think we care about that.

For CNI we seem to treat package private members as visible. Is using
package private members from CNI still supported/will it be kept
supported, or should such usage be turned into java protected members?

Cheers,

Mark

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

* Re: Symbol visibility for gcj
  2007-03-24  0:09 ` Mark Wielaard
@ 2007-03-24  0:47   ` David Daney
  2007-03-24 16:59   ` Andrew Haley
  1 sibling, 0 replies; 7+ messages in thread
From: David Daney @ 2007-03-24  0:47 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: Andrew Haley, gcc-patches, java-patches

Mark Wielaard wrote:
> On Fri, 2007-03-23 at 18:18 +0000, Andrew Haley wrote:
>> I don't believe it should cause any problems, but it is possible that
>> this will break some code that was using CNI to access private symbols
>> inside a DSO.  I don't think we care about that.
> 
> For CNI we seem to treat package private members as visible. Is using
> package private members from CNI still supported/will it be kept
> supported, or should such usage be turned into java protected members?
> 

There is no C++ equivalent to java's package private IIRC, so there 
seems to be no alternative to making them public in CNI.

Trying to access private members from CNI raises C++ protection errors, 
so it should be safe to make them invisible as you would get a compile 
time error if you tried to use them.

David Daney

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

* Re: Symbol visibility for gcj
  2007-03-24  0:09 ` Mark Wielaard
  2007-03-24  0:47   ` David Daney
@ 2007-03-24 16:59   ` Andrew Haley
  1 sibling, 0 replies; 7+ messages in thread
From: Andrew Haley @ 2007-03-24 16:59 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: gcc-patches, java-patches

Mark Wielaard writes:
 > On Fri, 2007-03-23 at 18:18 +0000, Andrew Haley wrote:
 > > I don't believe it should cause any problems, but it is possible that
 > > this will break some code that was using CNI to access private symbols
 > > inside a DSO.  I don't think we care about that.
 > 
 > For CNI we seem to treat package private members as visible. Is using
 > package private members from CNI still supported/will it be kept
 > supported, or should such usage be turned into java protected members?

I haven't done anything about package private, so accessing package
private members from outside a DSO will still work after this patch.
Whether this *should* be supported, I don't know...

Andrew.

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

* Re: Symbol visibility for gcj
  2007-03-23 18:47 Symbol visibility for gcj Andrew Haley
  2007-03-23 19:34 ` David Daney
  2007-03-24  0:09 ` Mark Wielaard
@ 2007-03-29 16:18 ` Andrew Haley
  2 siblings, 0 replies; 7+ messages in thread
From: Andrew Haley @ 2007-03-29 16:18 UTC (permalink / raw)
  To: gcc-patches, java-patches

Andrew Haley writes:
 > This changes the symbol export rules for gcj-built DSOs.  We no longer
 > output symbols for:
 > 
 > private static methods
 > private static fields
 > private classes
 > vtables (except java.lang.Class)
 > class$$ fields
 > 
 > This reduces the number of symbols in libgcj.so from 87509 to 66209, a
 > saving of 20%.
 > 
 > I've attached the list of symbols that are no longer emitted.  
 > 
 > I don't believe it should cause any problems, but it is possible that
 > this will break some code that was using CNI to access private symbols
 > inside a DSO.  I don't think we care about that.

Well, it did cause problems.  Here is a better, more subtle patch.

Andrew.


2007-03-29  Andrew Haley  <aph@redhat.com>

        * jvgenmain.c (main): Change main to use class$, not class$$.
        (do_mangle_classname): Likewise.
        * class.c (hide): New function.
        (add_field): Hide everything that shouldn't be visible outside a
        DSO.
        (build_static_class_ref): Likewise.
        (build_classdollar_field): Likewise.
        (make_class_data): Likewise.
        (layout_class_method): Likewise.
        * expr.c (special_method_p): New function.

Index: gcc/java/class.c
===================================================================
--- gcc/java/class.c	(revision 122746)
+++ gcc/java/class.c	(working copy)
@@ -689,6 +688,13 @@
   return fntype;
 }
 
+static void
+hide (tree decl)
+{
+  DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+  DECL_VISIBILITY_SPECIFIED (decl) = 1;
+}
+
 tree
 add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
 {
@@ -799,6 +805,10 @@
       /* Always make field externally visible.  This is required so
 	 that native methods can always access the field.  */
       TREE_PUBLIC (field) = 1;
+      /* Hide everything that shouldn't be visible outside a DSO.  */
+      if (flag_indirect_classes
+	  || (FIELD_PRIVATE (field)))
+	hide (field);
       /* Considered external unless we are compiling it into this
 	 object file.  */
       DECL_EXTERNAL (field) = (is_compiled_class (class) != 2);
@@ -956,7 +966,11 @@
       decl = build_decl (VAR_DECL, decl_name, class_type_node);
       TREE_STATIC (decl) = 1;
       if (! flag_indirect_classes)
-	TREE_PUBLIC (decl) = 1;
+	{
+	  TREE_PUBLIC (decl) = 1;
+	  if (CLASS_PRIVATE (TYPE_NAME (type)))
+	    hide (decl);
+	}
       DECL_IGNORED_P (decl) = 1;
       DECL_ARTIFICIAL (decl) = 1;
       if (is_compiled_class (type) == 1)
@@ -995,6 +1009,7 @@
       TREE_CONSTANT (decl) = 1;
       TREE_READONLY (decl) = 1;
       TREE_PUBLIC (decl) = 1;
+      hide (decl);
       DECL_IGNORED_P (decl) = 1;
       DECL_ARTIFICIAL (decl) = 1;
       MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
@@ -1640,6 +1655,10 @@
 
       TREE_PUBLIC (dtable_decl) = 1;
       DECL_INITIAL (dtable_decl) = dtable;
+      /* The only dispatch table exported from a DSO is the dispatch
+	 table for java.lang.Class.  */
+      if (DECL_NAME (type_decl) != id_class)
+	hide (dtable_decl);
       if (! flag_indirect_classes)
 	rest_of_decl_compilation (dtable_decl, 1, 0);
       /* Maybe we're compiling Class as the first class.  If so, set
@@ -2509,6 +2528,12 @@
 
   TREE_PUBLIC (method_decl) = 1;
 
+  if (flag_indirect_classes
+      || (METHOD_PRIVATE (method_decl) && METHOD_STATIC (method_decl)
+	  && ! METHOD_NATIVE (method_decl)
+	  && ! special_method_p (method_decl)))
+    hide (method_decl);
+
   /* Considered external unless it is being compiled into this object
      file, or it was already flagged as external.  */
   if (!DECL_EXTERNAL (method_decl))
Index: gcc/java/jvgenmain.c
===================================================================
--- gcc/java/jvgenmain.c	(revision 122746)
+++ gcc/java/jvgenmain.c	(working copy)
@@ -143,8 +143,8 @@
     fprintf (stream, "   JvRunMainName (\"%s\", argc, argv);\n", classname);
   else
     {
-      fprintf (stream, "   extern void *%s;\n", mangled_classname);
-      fprintf (stream, "   JvRunMain (%s, argc, argv);\n", mangled_classname);
+      fprintf (stream, "   extern char %s;\n", mangled_classname);
+      fprintf (stream, "   JvRunMain (&%s, argc, argv);\n", mangled_classname);
     }
   fprintf (stream, "}\n");
   if (stream != stdout && fclose (stream) != 0)
@@ -176,7 +176,7 @@
 	count++;
     }
   append_gpp_mangled_name (&ptr [-count], count);
-  obstack_grow (mangle_obstack, "7class$$E", strlen ("7class$$E"));
+  obstack_grow (mangle_obstack, "6class$E", strlen ("6class$E"));
   obstack_1grow (mangle_obstack, '\0');
   return obstack_finish (mangle_obstack);
 }
Index: gcc/java/expr.c
===================================================================
--- gcc/java/expr.c	(revision 122746)
+++ gcc/java/expr.c	(working copy)
@@ -2121,6 +2121,25 @@
 
    {NULL, NULL, NULL, NULL, 0, NULL}};
 
+/* True if this method is special, i.e. it's a private method that
+   should be exported fro a DSO.  */
+
+bool
+special_method_p (tree candidate_method)
+{
+  tree context = DECL_NAME (TYPE_NAME (DECL_CONTEXT (candidate_method)));
+  tree method = DECL_NAME (candidate_method);
+  rewrite_rule *p;
+
+  for (p = rules; p->classname; p++)
+    {
+      if (get_identifier (p->classname) == context
+	  && get_identifier (p->method) == method)
+	return true;
+    }
+  return false;
+}
+
 /* Scan the rules list for replacements for *METHOD_P and replace the
    args accordingly.  If the rewrite results in an access to a private
    method, update SPECIAL.*/
Index: gcc/java/java-tree.h
===================================================================
--- gcc/java/java-tree.h	(revision 122746)
+++ gcc/java/java-tree.h	(working copy)
@@ -1171,6 +1171,7 @@
 extern void initialize_builtins (void);
 
 extern tree lookup_name (tree);
+extern bool special_method_p (tree);
 extern void maybe_rewrite_invocation (tree *, tree *, tree *, tree *);
 extern tree build_known_method_ref (tree, tree, tree, tree, tree, tree);
 extern tree build_class_init (tree, tree);

-- 
Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SL4 1TE, UK
Registered in England and Wales No. 3798903

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

end of thread, other threads:[~2007-03-29 16:07 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-23 18:47 Symbol visibility for gcj Andrew Haley
2007-03-23 19:34 ` David Daney
2007-03-23 19:37   ` Andrew Haley
2007-03-24  0:09 ` Mark Wielaard
2007-03-24  0:47   ` David Daney
2007-03-24 16:59   ` Andrew Haley
2007-03-29 16:18 ` Andrew Haley

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).