<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,<br>
      <br>
      here is an updated version of the patch. In summary, changes to
      the previous version are:<br>
      <br>
      1) Adapt NmethodSweepFraction based on the code cache size:<br>
      &nbsp;&nbsp;&nbsp; Before the patch, NmethodSweepFraction was defined as a
      constant value.<br>
      &nbsp;&nbsp;&nbsp; I.e., NmethodSweepFraction was 16 for a code cache size of 32m
      as well as a <br>
      &nbsp;&nbsp;&nbsp; code cache size of 256m. This seems unreasonable, since
      NmethodSweepFraction<br>
      &nbsp;&nbsp;&nbsp; was originally introduce to keep the time spent in the sweeper
      (note that sweeping <br>
      &nbsp;&nbsp;&nbsp; was originally done at safepoints) at a reasonable level. <br>
      &nbsp;&nbsp;&nbsp; The patch adapts NmethodSweepFraction to the
      ReservedCodeCacheSize. I.e., <br>
      &nbsp;&nbsp;&nbsp; each sweep operation roughly&nbsp; covers 16m of the code cache.<br>
      <br>
      2) The parameter NmethodSweepFraction is replaced by a function
      that computes the<br>
      &nbsp;&nbsp;&nbsp; NmethodSweepFraction based on the code cache size. See
      'sweeper.cpp' for a detailed<br>
      &nbsp;&nbsp;&nbsp; description<br>
      <br>
      3) The initial hotness counter depends on the code cache size.
      More specifically, the initial<br>
      &nbsp;&nbsp;&nbsp; hotness counter is 2*ReservedCodeCacheSize. As a result, a
      method stays longer in the<br>
      &nbsp;&nbsp;&nbsp; code cache if ReservedCodeCacheSize is larger. <br>
      <br>
      4) Newly compiled methods are guaranteed to not be evicted by the
      sweeper for 10 <br>
      &nbsp;&nbsp;&nbsp; sweep cycles. This ensures the newly compiled methods are not
      immediately made<br>
      &nbsp;&nbsp;&nbsp; not entrant after compialtion.<br>
      <br>
      5) The hotness counter is reset EVERY TIME active methods are
      scanned. In the previous version<br>
      &nbsp;&nbsp;&nbsp; the hotness counter was only reset after a full sweep cycle of
      the code cache. Resetting the <br>
      &nbsp;&nbsp; hotness counter more frequently provides a better hotness
      coverage of methods.<br>
      <br>
      6) Methods are flushed in blocks of 1m. The algorithm computes the
      average hotness of a <br>
      &nbsp;&nbsp;&nbsp; a nmethod block and evicts the entire block. This should
      reduce fragmentation.<br>
      <br>
      Please let me know what you think about these changes. Performance
      results can be found at:<br>
      <meta http-equiv="content-type" content="text/html;
        charset=ISO-8859-1">
      <a href="https://bugs.openjdk.java.net/browse/JDK-8020151">https://bugs.openjdk.java.net/browse/JDK-8020151</a><br>
      I will continuously provide more results.<br>
      <br>
      Here is the new webrev:<br>
      <meta http-equiv="content-type" content="text/html;
        charset=ISO-8859-1">
      <a href="http://cr.openjdk.java.net/%7Eanoll/8020151/webrev.01/">http://cr.openjdk.java.net/~anoll/8020151/webrev.01/</a><br>
      <br>
      Best,<br>
      Albert<br>
      &nbsp;&nbsp; <br>
      <br>
      On 22.08.2013 15:16, Albert Noll wrote:<br>
    </div>
    <blockquote cite="mid:52160F35.2050604@oracle.com" type="cite">
      <meta content="text/html; charset=ISO-8859-1"
        http-equiv="Content-Type">
      <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>
    </blockquote>
    <br>
  </body>
</html>