<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    Hi,<br>
    <br>
    Thanks for the insight.<br>
    <br>
    I'd like to note that I'm not concerned about the reachability of
    the Reference object itself (program code takes care of that - for
    example in Cleaner API it hooks Reference objects into a
    doubly-linked list exactly for them to stay reachable until
    discovered by GC and enqueued by ReferenceHandler thread into the
    associated ReferenceQueue). I'm merely interested in the
    reachability of the referent until the Reference (and any possible
    Reference subclass constructor) fully constructs the Reference
    instance.<br>
    <br>
    The situation where this would manifest as a malfunction is
    improbable (as the referent is usually passed to other parts of code
    too and is reachable from elsewhere for some time). But in case it
    isn't, the following is possible:<br>
    <br>
        Reference(T referent, ReferenceQueue<? super T> queue) {<br>
            this.referent = referent;<br>
            // - safepoint with GC happens, 'referent' is found
    weakly-reachable, 'this' Reference is hooked on the pending chain<br>
            // - ReferenceHandler thread unhooks 'this' from pending
    chain and tries to enqueue it, but this.queue is still null<br>
            // - BANG! NPE in Referencehandler thread which terminates
    it!<br>
            this.queue = (queue == null) ? ReferenceQueue.NULL : queue;<br>
        } <br>
    <br>
    A pre-requisite for above scenario is a safepoint between
    "this.referent = referent" and "this.queue = ...". In interpreter,
    safepoint check is after every bytecode instruction right? But in
    Interpreter, I think arguments are also kept on the stack and are
    therefore reachable at least until the end of constructor. How
    probable is a safepoint between those two statements in JIT-ed code?
    Maybe the Reference constructor itself is not in danger because it
    is very trivial, but what about subclasses that must do their own
    part of initialization too (for example Cleaner API discussed on
    core-libs-dev)?<br>
    <br>
    Regards, Peter<br>
    <br>
    <div class="moz-cite-prefix">On 10/22/2015 12:25 AM, Vitaly
      Davidovich wrote:<br>
    </div>
    <blockquote
cite="mid:CAHjP37FD24s9GuJhcf90HqDppuFZhCX5rrcUXTS7qROs7BjxSw@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span
            style="font-size:12.8000001907349px">Yes, if runtime stripes
            that instance before it is exposed anywhere<br>
          </span><span style="font-size:12.8000001907349px">(e.g.
            scalarizes the weakref)</span></blockquote>
        <div><br>
        </div>
        If you look at escape analysis code (<a moz-do-not-send="true"
href="http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/file/a60bd3d34158/src/share/vm/opto/escape.cpp#l803">http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/file/a60bd3d34158/src/share/vm/opto/escape.cpp#l803</a>),
        Reference and subclasses get special treatment and marked as
        GlobalEscape.</div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Wed, Oct 21, 2015 at 1:08 PM,
          Aleksey Shipilev <span dir="ltr"><<a
              moz-do-not-send="true"
              href="mailto:aleksey.shipilev@oracle.com" target="_blank"><a class="moz-txt-link-abbreviated" href="mailto:aleksey.shipilev@oracle.com">aleksey.shipilev@oracle.com</a></a>></span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex"><span
              class="">On 10/21/2015 06:53 PM, Andrew Haley wrote:<br>
              > On 10/21/2015 04:44 PM, Aleksey Shipilev wrote:<br>
              >> Of course, this does not tell another (scary)
              part of the story, what if<br>
              >> the Reference itself is not discovered as strong
              ref by GC, e.g. when it<br>
              >> isn't published on heap, or scalarized by
              compiler, etc.<br>
              >> reachabilityFence, as currently implemented,
              extends the "liveness"<br>
              >> scope of the local variable, but does not convey
              anything special to the<br>
              >> GC/runtime otherwise.<br>
              ><br>
              > If the Reference itself is not reachable from a
              strong root then the<br>
              > Reference is dead so we don't care what happens to
              it.  But if the<br>
              > Reference is put on a reachable ReferenceQueue, then
              it's fine.<br>
              <br>
            </span>Yes, if runtime stripes that instance before it is
            exposed anywhere<br>
            (e.g. scalarizes the weakref), or those references are dead
            (e.g. the<br>
            weakref is buried somewhere deep in garbage subgraph, and
            purged on<br>
            sweep), then everything goes awry.<br>
            <br>
            But the thing is, a WeakReference is put on ReferenceQueue
            by the GC<br>
            itself. In the object graph, ReferenceQueue does not
            normally reference<br>
            weakrefs back. Before enqueueing the reference GC has to
            first discover<br>
            that WeakReference -- but from where? In other words,
            "registering" on a<br>
            reachable RefQueue does not make weakref to be reachable.<br>
            <br>
            Case in point:<br>
            <br>
            public class WhereIsWaldo {<br>
            <br>
                public static void main(String... args) throws Exception
            {<br>
                    for (int c = 0; true; c++) {<br>
                        new WhereIsWaldo().work(c);<br>
                    }<br>
                }<br>
            <br>
                final ReferenceQueue<Object> rq = new
            ReferenceQueue<>();<br>
            <br>
                void work(int id) throws Exception {<br>
                    hideWaldo(id);<br>
                    findWaldo(id);<br>
                }<br>
            <br>
                WeakReference<Object> gwr;<br>
            <br>
                void hideWaldo(int id) {<br>
                    // Does not work, d'uh<br>
                    new WeakReference<>(new Object(), rq);<br>
            <br>
                    // Does not work either :(<br>
                    WeakReference<Object> wr =<br>
                       new WeakReference<>(new Object(), rq);<br>
            <br>
                    // This also does not help... once you leave the
            method,<br>
                    // the weakref is gone.<br>
                    Reference.reachabilityFence(wr);<br>
            <br>
                    // This one helps, makes Waldo reachable<br>
                    // gwr = wr;<br>
                }<br>
            <br>
                void findWaldo(int id) throws Exception {<br>
                    while (Thread.currentThread().isAlive()) {<br>
                        System.gc();<br>
                        Reference ref = rq.remove(1000);<br>
                        if (ref != null) {<br>
                            return;<br>
                        } else {<br>
                            System.out.println("Where's Waldo #" + id +
            "?");<br>
                        }<br>
                    }<br>
                }<br>
            }<br>
            <br>
            <br>
            Thanks,<br>
            -Aleksey<br>
            <br>
          </blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <br>
  </body>
</html>