[concurrency-interest] DirectByteBuffers and reachabilityFence
gil at azul.com
Wed Dec 9 21:15:49 EST 2015
> On Dec 9, 2015, at 12:08 PM, Andrew Haley <aph at redhat.com> wrote:
> On 12/09/2015 07:30 PM, Gil Tene wrote:
>>> On Dec 9, 2015, at 10:40 AM, Andrew Haley <aph at redhat.com> wrote:
>>> On 12/09/2015 05:53 PM, Gil Tene wrote:
>>>> My take on this would be to change the JLS and JVM spec to state
>>>> that 'this' remains reachable until after the last instruction of
>>>> every instance method. Period. This would basically equate to
>>>> placing an implicit reachability fence at all exist points of every
>>>> instance method (I.e. The equivalent of a try...finally). The "nice״
>>>> thing about such an implicit reachability fence is that it does not
>>>> really defeat any optimizations, as it only serves to extend the
>>>> lifetime of an oop (so potentially pressing slightly harder on the
>>>> register allocator). IMO this would auto-magically fix lots of
>>>> current rarely occurring bugs (like those on DBB, but also in user
>>>> code), and prevent many future ones.
>>> Mmmm. That's what I said!
>> So we agree. At least for classes with finalizers in them. But since what you said was:
>>> … I have in the past argued that methods of classes with finalizers
>>> should automagically extend the lifetime of the "this" object.
>> And what I am saying is that ALL instance methods should have
>> this quality (not just the ones in classes with finalizers). We may still
>> have a gap (or maybe that gap is gone now).
> Ah, yes we do.
>> My point is that this reachability race has nothing (specific) to do with
>> finalizers or finalization, and applies just as much to things that cannot
>> be easily detectable from a class's qualities (like having a finalizer).
>> Therefore any solution that only addresses finalizers seems insufficient.
> Possibly so, yes, given that there is nothing special about "this".
> I take your point.
I actually do think that 'this' is special. And that the specific mishandling of
'this' by the current spec and implementations is responsible for a ton
of lurking races like the ones in DBB.get() and put(). Wile I see a separate
need for things like explicit reachability fences in other cases (not 'this'
related), I think for 'this' the fundamental problem can be stated this way:
"It is fundamentally surprising behavior for an instance to become
unreachable while code in one of its instance methods is still executing."
This is the root of all these current could-access-a-freed-buffer in DBB. It
is also the root of many simple finalizer issues (though not all). And it is
probably a common root for many patterns that access memory at
an address stored in a long field of an instance. Any solution where you
were going to use reachabilityFence(this) (as opposed to some other
field or local variable) is an indication of this problem.
Stopping this surprising behavior from happening would reliably eliminate
any freeing races with things accessed via private instance fields (e.g.
unsafe accesses to addresses stored in private long fields, or i/o access
via fds stored in private long fields, or other id-based access). And since
most of those things tend to be idiomatically kept private, the coverage
we'd get is pretty good.
Stopping the surprising behavior can simply be achieved by adhering
(and promising) something this:
"[regardless of other reachability] An object instance is reachable if
any code in any of its instance methods is executing".
This basically translates to "'this' remains reachable until after the last instruction
of each instance method."
It also means that an explicit reachability fence on 'this' will never be
needed. Explicit reachability fences will only make sense on fields or
local variables, but never on 'this'. So for
> What would this do to objects which don't escape? I presume that
> there would be no need to extend their lifetimes, and the usual
> "as if" rule would apply.
I don't think this has any effect on escape analysis. By definition, EA cannot
apply to 'this' by definition within an instance method, simply because an
instance method never allocates 'this'. Outside of the instance method there
is no effect on EA because 'this' is not required to remain reachable beyond the
last instruction in any of its instance methods (including when they are inlined).
-------------- next part --------------
A non-text attachment was scrubbed...
Size: 842 bytes
Desc: Message signed with OpenPGP using GPGMail
More information about the Concurrency-interest