This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: Get libffi closures to cope with SELinux execmem/execmod


Thanks for the clarification.

I still think this is really ugly in principle, but I'm now inclined to
agree that we need such a mechanism.  (This is not a statement about
Alexandre's implementation, which is quite clever and clean.)

I'll try to restate the problem, yet again:

We have an object O1 which is finalizable, and indirectly points to O2.
O2 is the last member of class P, and the representation of class P
includes a resource R that must be explicitly reclaimed when P is
collected.  (Which presumably happens when P's class loader is also
collected?)  Thus R has a finalizer.  O1 sometimes resurrects itself
from its finalizer.  (Or it might resurrect some other object on the
chain to O2; it doesn't matter.)  Since Java finalization is unordered,
R may be finalized, even though it will be needed again after O1
resurrects itself.

The way the GC was originally designed, this should be impossible
because R won't be considered for finalization after O1 has run.

More generally, the GC internally provides a facility that allows every
finalizable object to declare which fields it might need for the
finalizer to run correctly, and anything reachable from those fields
will still be intact while the finalizer is run and after a possible
resurrection.  But this doesn't work here because O1 is a Java object,
and R is a libgcj internal object.

Similarly, for a Java object to be able to correctly resurrect itself,
it generally needs to ensure that all indirectly referenced objects are
reachable through some other path.  But O1 might happen to know that,
for example, it doesn't refer to any Java finalizable objects.  Or it
might even be buggy.  We can't crash the runtime in either case.

Thus we need a way for R to protect itself without cooperation from O1,
which we don't control.  Alexandre's patch does that by allowing objects
to declare themselves to not be finalizable while reachable from other
finalizable objects, overriding other instructions to finalize objects
out of order.

The reasons I don't feel enthusiastic about including this:

- It doesn't fit well with the GCs original design.  It feels like a
hack on the interface, even more so than the Java finalization
extension.

- It also feels like an admission of failure for the Java design.
JSR133 finally legitimized the technique of enforcing Java finalizer
ordering by having an object A whose finalizer depends on B put B into a
reachable container, and having it removed by A's finalizer.  This is a
somewhat less efficient way to enforce ordering of the kind the
collector always supported, at least internally, i.e. a finalizable
object declares what fields the finalizer depends on.  This argues that
that mechanism isn't sufficient.  But I think there is no way to do
something vaguely analogous to what Alexandre is proposing from Java.
Hence we're essentially saying that we can't eat our own dog food
because it's not good enough.  (There's a bit of an argument that this
issue is specific to the runtime, but I don't think it's really
convincing.)

In spite of all of that, I'm OK with also putting this into the upstream
GC tree.

Hans

> -----Original Message-----
> From: Alexandre Oliva [mailto:aoliva@redhat.com] 
> Sent: Friday, January 26, 2007 11:27 PM
> To: Boehm, Hans
> Cc: Andrew Haley; green@redhat.com; gcc-patches@gcc.gnu.org; 
> java-patches@gcc.gnu.org
> Subject: Re: Get libffi closures to cope with SELinux execmem/execmod
> 
> On Jan 26, 2007, "Boehm, Hans" <hans.boehm@hp.com> wrote:
> 
> > f) Register all Java finalizable objects with a finalize_mark_proc 
> > that traces the class, but nothing else?
> 
> This won't work.  Consider that O1 is not an instance of P, 
> but rather an instance of a subclass, or even an instance of 
> an unrelated class whose constructor instantiates P.  At the 
> point you start requiring special semantics in finalizable 
> objects, you need to apply it to every object and class 
> reachable from them, and then you violate the Java 
> requirements or you still don't get the normal finalization 
> semantics for objects in the frontier between Java 
> finalization and normal finalization.
> 
> > This effectively states that object finalizers need the 
> corresponding 
> > classes to stay around until the object finalizer has completed.
> 
> It would be just a (failed) hack to try to work around a real 
> problem in boehm-gc.
> 
> Basically, the current implementation doesn't offer the 
> documented semantics at all when there are Java objects 
> involved, and I'm convinced there's no way to offer the 
> proper semantics without the new primitive I've added.  The 
> only doubt in my mind is whether it needs to be a separate 
> primitive, or if we should fix the behavior of the existing 
> primitive as to adopt the fixed semantics when Java 
> finalization semantics are in use.
> 
> -- 
> 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}
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]