<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">Hi Igor,<br>
      <br>
      thanks again for your comments. You are right. I will run some
      benchmarks to see if removing<br>
      the disconnect logic is feasible or not.<br>
      <br>
      Best,<br>
      Albert<br>
      <br>
      On 22.08.2013 12:39, Igor Veresov wrote:<br>
    </div>
    <blockquote
      cite="mid:979AC378-D393-4219-815B-3E4332FB39BB@gmail.com"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=ISO-8859-1">
      It's worth a try. But the "hotness" logic is probabilistic and
      imprecise - it will notice only methods that are on stack during
      safepoints. Those are going to be pretty narrow snapshots of
      activity. I suspect that for large flat profiles (like enterprise
      apps and friends) you could be missing methods that are rather
      warm in reality, which will cause recompilation oscillations.
      Although if the statistics are allowed to accumulate enough may be
      it's going to work out, an experiment will tell. The patch is a
      good start, the stack sampling, IMO, is totally the right approach
      for filtering out the hot methods.
      <div><br>
      </div>
      <div>The "disconnect" logic on the other hand is sort of precise.
        Although, looking now at the code it's not quite clear to me how
        it works, it doesn't seem to be any patching going on to divert
        the control for the cases when the nmethod is called directly or
        through an IC. So I guess it's not really a full disconnect?
        &nbsp;Anyways, in theory, with some work, we can make the disconnect
        logic to precisely measure the time the method is inactive.
        Which should provide precise information about the warm/cold
        methods.
        <div><br>
        </div>
        <div>
          <div>Btw, also just noticed a bunch of flaws in the
            interaction of the disconnect logic and tiered. The
            nmethod's "reconnection" happens in
            CompileBroker::compile_method(), which firstly will be
            called by tiered only after a rather substantial number of
            invocations in the interpreter (up to 128), and secondly
            will be subject to all the prioritization rules (it probably
            should not), and also we don't check if the comp level of
            the reanimated nmethod matches the request. If the
            disconnect logic is to stay, the interpreter should be able
            to know if the method has saved code and be able to call
            into the runtime immediately to reanimate it.</div>
          <div><br>
          </div>
          <div>igor<br>
            <div><br>
            </div>
            <div>&nbsp;
              <div>
                <div>
                  <div>
                    <div>On Aug 21, 2013, at 10:27 PM, Albert Noll &lt;<a
                        moz-do-not-send="true"
                        href="mailto:albert.noll@oracle.com">albert.noll@oracle.com</a>&gt;
                      wrote:</div>
                    <br class="Apple-interchange-newline">
                    <blockquote type="cite">
                      <meta content="text/html; charset=ISO-8859-1"
                        http-equiv="Content-Type">
                      <div text="#000000" bgcolor="#FFFFFF">
                        <div class="moz-cite-prefix">Hi Igor,<br>
                          <br>
                          thanks for looking at the patch. Actually, I
                          think - just as Vladimir pointed out - that we
                          can get rid of<br>
                          the "disconnect" logic. We now have the
                          hotness of a method and if the code cache
                          fills up, we and<br>
                          we decide to schedule the method for removal,
                          we set it to not_entrant. <br>
                          It seems that adding the method to the list of
                          disconnected methods just buys a little more
                          time until we decide to make the method
                          not-entrant. However, we can have the same
                          effect by setting the&nbsp; threshold differently.<br>
                          <br>
                          What do you think?<br>
                          <br>
                          Best,<br>
                          Albert<br>
                          <br>
                          On 22.08.2013 10:02, Igor Veresov wrote:<br>
                        </div>
                        <blockquote
                          cite="mid:EF238055-6EDD-4C8E-9488-BECA2FE1CA80@gmail.com"
                          type="cite">
                          <meta http-equiv="Content-Type"
                            content="text/html; charset=ISO-8859-1">
                          May be instead of "(_traversals &gt;
                          _last_flush_traversal_id + 2)" we should
                          timestamp a method when it's disconnected, and
                          then use a rule like if a method has been
                          disconnected for k * reverse_free_ratio()
                          seconds then it's ok to kill it. We can also
                          sort the nmethods that pass that filter by the
                          amount of time they were disconnected and
                          select most likely candidates for flushing.
                          This should allow to basically do
                          disconnect/flush in every traversal, which
                          should make things faster. Timestamps would be
                          obtained only once per traversal or something
                          like that. What do you think?
                          <div><br>
                          </div>
                          <div>Pretty cool idea to reverse-prioritize
                            disconnects on hotness.</div>
                          <div><br>
                          </div>
                          <div>igor<br>
                            <div><br>
                              <div>
                                <div>On Aug 21, 2013, at 4:42 AM, Albert
                                  Noll &lt;<a moz-do-not-send="true"
                                    href="mailto:albert.noll@oracle.com">albert.noll@oracle.com</a>&gt;

                                  wrote:</div>
                                <br class="Apple-interchange-newline">
                                <blockquote type="cite">
                                  <meta http-equiv="content-type"
                                    content="text/html;
                                    charset=ISO-8859-1">
                                  <div text="#000000" bgcolor="#FFFFFF">
                                    Hi all,<br>
                                    <br>
                                    could I have reviews for this patch?
                                    Please note<br>
                                    that I do not yet feel very
                                    confident with the sweeper,<br>
                                    so please take a close look.<br>
                                    <br>
                                    jbs:
                                    <meta http-equiv="content-type"
                                      content="text/html;
                                      charset=ISO-8859-1">
                                    <a moz-do-not-send="true"
                                      href="https://jbs.oracle.com/bugs/browse/JDK-8020151">https://jbs.oracle.com/bugs/browse/JDK-8020151</a><br>
                                    webrev:
                                    <meta http-equiv="content-type"
                                      content="text/html;
                                      charset=ISO-8859-1">
                                    <a moz-do-not-send="true"
                                      href="http://cr.openjdk.java.net/%7Eanoll/8020151/webrev.00/">http://cr.openjdk.java.net/~anoll/8020151/webrev.00/</a><br>
                                    <br>
                                    <br>
                                    Many thanks in advance,<br>
                                    Albert<br>
                                    <br>
                                    <br>
                                    Problem: There can be large
                                    performance regressions when the
                                    code cache fills up. There are <br>
                                    several reasons for the performance
                                    regression: First (1), when the code
                                    cache is full and methods <br>
                                    are speculatively disconnected, the
                                    oldest methods (based on compilation
                                    ID) are scheduled for<br>
                                    flushing. This can result in
                                    flushing hot methods. Second (2),
                                    when compilation is disabled due to
                                    a full<br>
                                    code cache, the number of sweeps can
                                    go down. A lower number of sweep
                                    operations results <br>
                                    in slower method flushing.<br>
                                    <br>
                                    Solution:<br>
                                    Introduce a hotness counter that is
                                    set to a particular value (e.g.,
                                    100) when there is an activation<br>
                                    of the method during stack scanning.
                                    The counter is decremented by 1
                                    every time the sweeper <br>
                                    is invoked.<br>
                                    <br>
                                    ad (1):<br>
                                    &nbsp; A VM operation that speculatively
                                    disconnects nmethods, selects the
                                    methods that should be<br>
                                    &nbsp; flushed based on the hotness. For
                                    example, if 50% of the code cache
                                    shall be flushed, we flush <br>
                                    &nbsp; those methods that have not been
                                    active while stack scanning for the
                                    longest time. Note that <br>
                                    &nbsp; while this strategy is more likely
                                    to flush cold methods, it is not
                                    clear to what extent the new <br>
                                    &nbsp; strategy fragments the code cache.<br>
                                    <br>
                                    &nbsp; Changes in
                                    NMethodSweeper::speculative_disconnect_nmethods(bool
                                    is_full)<br>
                                    <br>
                                    ad (2)<br>
                                    &nbsp; Currently, methods are removed
                                    from the code cache if:<br>
                                    &nbsp;&nbsp;&nbsp; a) code cache is full <br>
                                    &nbsp;&nbsp;&nbsp; b) class is unloaded <br>
                                    &nbsp;&nbsp;&nbsp; c) method is replaced by another
                                    version (i.e., compiled with a
                                    different tier) <br>
                                    &nbsp;&nbsp;&nbsp; d) deopt<br>
                                    <br>
                                    &nbsp;&nbsp; The current patch adds a 5-th
                                    possibility to remove a method from
                                    the code cache. <br>
                                    &nbsp;&nbsp; In particular, if a method has
                                    not been active during stack
                                    scanning for a long-enough <br>
                                    &nbsp;&nbsp; amount of time, the method is
                                    removed from the code cache. The
                                    amount of time<br>
                                    &nbsp;&nbsp; required to flush the method
                                    depends on the available space in
                                    the code cache. <br>
                                    &nbsp;&nbsp; <br>
                                    &nbsp;&nbsp; Here is one example: If a method
                                    was seen on a stack the hotness
                                    counter <br>
                                    &nbsp;&nbsp; is set to 100. A sweep operation
                                    takes roughly place every 100ms.
                                    I.e., it takes <br>
                                    &nbsp;&nbsp; 100ms * 100 = 10s until the
                                    hotness counter reaches 0. The
                                    threshold that determines<br>
                                    &nbsp;&nbsp; if a method should be removed
                                    from the code cache is calculated as
                                    follows:<br>
                                    &nbsp;<br>
                                    &nbsp;&nbsp; threshold = -100 +
                                    (CodeCache::reverse_free_ratio() *
                                    NMethodSweepActivity)<br>
                                    <br>
                                    &nbsp;&nbsp;&nbsp; For example, if 25% of the code
                                    cache is free, reverse_free_ratio
                                    returns 4.<br>
                                    &nbsp;&nbsp;&nbsp; The default value of
                                    NMethodSweepActivity is 10. As a
                                    result, threshold = -60.<br>
                                    &nbsp;&nbsp;&nbsp; Consequently, all methods that
                                    have a hotness value smaller than
                                    -60 (which <br>
                                    &nbsp;&nbsp;&nbsp; means they have not been seen on
                                    the stack for 16s) are scheduled to
                                    be flushed<br>
                                    &nbsp;&nbsp;&nbsp; from the code cache. See an
                                    illustration of the threshold as a
                                    function of the available<br>
                                    &nbsp;&nbsp;&nbsp; code cache in threshold.pdf<br>
                                    <br>
                                    &nbsp;&nbsp;&nbsp; Note that NMethodSweepActivity
                                    is a parameter that can be specified
                                    via a -XX<br>
                                    &nbsp;&nbsp;&nbsp; flag.<br>
                                    <br>
                                    Changes in
                                    NMethodSweeper::sweep_code_cache()<br>
                                    <br>
                                    <br>
                                    A very preliminary performance
                                    evaluation looks promising. I used
                                    the DaCapo <br>
                                    benchmarks where a series of
                                    benchmarks is executed in the same
                                    VM instance.<br>
                                    See performance.pdf . The x-axis
                                    shows the benchmarks. Assume we have
                                    2 benchmarks <br>
                                    (BM). The execution sequence is as
                                    follows:<br>
                                    <br>
                                    BM1 (Run 1-1)<br>
                                    BM1 (Run 2-1)<br>
                                    BM2 (Run 1-1)<br>
                                    BM2 (Run 2-1)<br>
                                    <br>
                                    BM1 (Run 1-2)<br>
                                    BM1 (Run 2-2)<br>
                                    BM2 (Run 1-2)<br>
                                    BM2 (Run 2-2)<br>
                                    <br>
                                    <br>
                                    A value larger than 0 on the x-axis
                                    indicates that the version including
                                    the proposed patch is faster.<br>
                                    I.e., the values are calculated as
                                    follows: (T_original / T_with_patch)
                                    - 1. T is the execution time <br>
                                    (wall clock time) of the benchmark.
                                    ReservedCodeCacheSize is set to
                                    50m.&nbsp; I used three runs and <br>
                                    the arithmetic average to compare
                                    the numbers. I know, we need much
                                    more data, however, <br>
                                    I think we can see a trend.<br>
                                    <br>
                                    The current patch does not trigger a
                                    warning that the code cache is full
                                    and compilation has been<br>
                                    disabled.<br>
                                    <br>
                                    Please let me know that you think.<br>
                                  </div>
                                  <span>&lt;threshold.pdf&gt;</span><span>&lt;performance.pdf&gt;</span></blockquote>
                              </div>
                              <br>
                            </div>
                          </div>
                        </blockquote>
                        <br>
                      </div>
                    </blockquote>
                  </div>
                  <br>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>