<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <br>
    Hi Dima,<br>
    <br>
    <div class="moz-cite-prefix">On 2015-04-27 15:32, Dmitry Fazunenko
      wrote:<br>
    </div>
    <blockquote cite="mid:553E3A7A.4040008@oracle.com" type="cite">
      <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
      Hi Bengt,<br>
      <br>
      Updated variant of fix with all your comments addressed:<br>
      <br>
      <a moz-do-not-send="true" class="moz-txt-link-freetext"
        href="http://cr.openjdk.java.net/%7Edfazunen/8073476/webrev.08/">http://cr.openjdk.java.net/~dfazunen/8073476/webrev.08/</a><br>
    </blockquote>
    <br>
    Thanks! Looks much better.<br>
    <br>
    One small detail. You have changed the behavior of this command
    line:<br>
    <br>
    -XX:+UnlockExperimentalVMOptions -XX:G1LogLevel=""
    -XX:+PrintGCDetails<br>
    <br>
    Before your change this would result in the log level being "finer"
    due to the PrintGCDetails flag. But after your change we will get
    log level None.<br>
    <br>
    It is not an interesting use case in my mind, but an easy fix would
    be to introduce a state variable in G1Log to track whether we should
    look at PrintGC* flags.<br>
    <br>
    So, in G1Log::init() you could do something like:<br>
    <br>
      _log_level_flag_used = G1LogLevel != NULL && G1LogLevel[0]
    != '\0';<br>
      if (_log_level_flag_used) {<br>
        <br>
      } else <br>
        update_level();<br>
      }<br>
    <br>
    <br>
    And update_level() would also look at the stat flag instead of
    checking FLAG_IS_DEFAULT(G1LogLevel). That way init() and
    update_level() would be consistent and we would keep the same
    behavior as before your change.<br>
    <br>
    What do you think?<br>
    <br>
    Thanks,<br>
    Bengt<br>
    <br>
    <br>
    <br>
    <blockquote cite="mid:553E3A7A.4040008@oracle.com" type="cite"> <br>
      Thanks,<br>
      Dima<br>
      <br>
      <br>
      <div class="moz-cite-prefix">On 21.04.2015 16:18, Dmitry Fazunenko
        wrote:<br>
      </div>
      <blockquote cite="mid:55364E19.8010207@oracle.com" type="cite">
        <meta content="text/html; charset=utf-8"
          http-equiv="Content-Type">
        Bengt,<br>
        <br>
        Thanks for your time!<br>
        A have a question inline:<br>
        <br>
        <div class="moz-cite-prefix">On 21.04.2015 15:19, Bengt Rutisson
          wrote:<br>
        </div>
      </blockquote>
      <blockquote cite="mid:55364E19.8010207@oracle.com" type="cite">
        <div class="moz-cite-prefix"> </div>
        <blockquote cite="mid:5536405F.10104@oracle.com" type="cite">
          <meta content="text/html; charset=utf-8"
            http-equiv="Content-Type">
          <br>
          Hi Dima,<br>
          <br>
          <div class="moz-cite-prefix">On 2015-04-21 13:33, Dmitry
            Fazunenko wrote:<br>
          </div>
          <blockquote cite="mid:55363597.3040006@oracle.com" type="cite">
            <meta content="text/html; charset=utf-8"
              http-equiv="Content-Type">
            <tt>Hi Bengt,<br>
              <br>
              This is modified fixed based on your comments:<br>
              <a moz-do-not-send="true" class="moz-txt-link-freetext"
                href="http://cr.openjdk.java.net/%7Edfazunen/8073476/webrev.07/">http://cr.openjdk.java.net/~dfazunen/8073476/webrev.07/</a><br>
              <br>
              Thanks for your assistance and good ideas!<br>
            </tt></blockquote>
          <br>
          Thanks for making these change. Looks much better to me.<br>
          <br>
          A couple of comments:<br>
          <br>
          G1CollectedHeap::do_collection() is only used for full GCs.
          You probably want to add a call to G1Log::update_level() in
          G1CollectedHeap::do_collection_pause_at_safepoint() too to
          make sure that it is called for young GCs as well.<br>
        </blockquote>
        <br>
        agree. good catch!<br>
        <br>
        <blockquote cite="mid:5536405F.10104@oracle.com" type="cite"> <br>
          <br>
          I think it looks odd that G1Log::init() and
          G1Log::update_level() use different guards for when to take
          PrintGC and PrintGCDetails into account.<br>
          <br>
            51 void G1Log::init() {<br>
            52   if (G1LogLevel != NULL && G1LogLevel[0] !=
          '\0')<br>
          <br>
            37 void G1Log::update_level() {<br>
            38   if (FLAG_IS_DEFAULT(G1LogLevel)) {<br>
          <br>
          Is there a difference between (G1LogLevel != NULL &&
          G1LogLevel[0] != '\0') and (FLAG_IS_DEFAULT(G1LogLevel)) ? Can
          we use the same guard in both places?<br>
        </blockquote>
        <br>
        I though about using the same expression in both cases. The
        difference in handling the empty value:  -XX:G1LogLevel= <br>
        So, the question,  how this case should be handled:<br>
        - a warning to be printed out and level set to 'none'<br>
        - treated in the same way as 'none'<br>
        <br>
        <br>
        <blockquote cite="mid:5536405F.10104@oracle.com" type="cite"> <br>
          <br>
          g1Log.hpp:<br>
          <br>
          I don't think this comment helps much:<br>
          <br>
          +  // to be invoked on VM start <br>
             static void init();<br>
          <br>
          The name init() makes it pretty clear to me what the method is
          expected to do. I would just leave the comment out.<br>
        </blockquote>
        I have a bit different vision, but I'm okay to remove the
        comment<br>
        <br>
        <br>
        <blockquote cite="mid:5536405F.10104@oracle.com" type="cite"> <br>
          The comment for update_level() talks about where the method
          should be called instead of what it does. That is normally not
          such a good thing for comments. Better to explain what it does
          so it can be called in all places where it is needed in the
          future.<br>
          <br>
          So instead of:<br>
          <br>
          +  // to be invoked on GC start or flag values change<br>
          +  static void update_level();<br>
          <br>
          I would prefer:<br>
          <br>
          //  Update the log level to reflect runtime changes to
          manageable flags.<br>
        </blockquote>
        agree.<br>
        <br>
        Thanks,<br>
        Dima<br>
        <br>
        <br>
        <blockquote cite="mid:5536405F.10104@oracle.com" type="cite"> <br>
          Thanks,<br>
          Bengt<br>
          <br>
          <blockquote cite="mid:55363597.3040006@oracle.com" type="cite"><tt>
              <br>
              -- Dima<br>
              <br>
              <br>
            </tt>
            <div class="moz-cite-prefix">On 20.04.2015 11:34, Bengt
              Rutisson wrote:<br>
            </div>
            <blockquote cite="mid:5534BA0B.5010906@oracle.com"
              type="cite">
              <meta content="text/html; charset=utf-8"
                http-equiv="Content-Type">
              <br>
              Hi Dima,<br>
              <br>
              <div class="moz-cite-prefix">On 2015-04-17 15:51, Dmitry
                Fazunenko wrote:<br>
              </div>
              <blockquote cite="mid:55310FCF.5030109@oracle.com"
                type="cite">
                <meta content="text/html; charset=utf-8"
                  http-equiv="Content-Type">
                <tt>Bengt,<br>
                  <br>
                  Please find comments inline.<br>
                  <br>
                </tt>
                <div class="moz-cite-prefix">On 17.04.2015 9:43, Bengt
                  Rutisson wrote:<br>
                </div>
                <blockquote cite="mid:5530AB92.2050509@oracle.com"
                  type="cite">
                  <meta content="text/html; charset=utf-8"
                    http-equiv="Content-Type">
                  <br>
                  Hi Dima,<br>
                  <br>
                  <div class="moz-cite-prefix">On 2015-04-16 15:36,
                    Dmitry Fazunenko wrote:<br>
                  </div>
                  <blockquote cite="mid:552FBAF5.1060908@oracle.com"
                    type="cite">
                    <meta content="text/html; charset=utf-8"
                      http-equiv="Content-Type">
                    Hi Bengt,<br>
                    <br>
                    thanks for looking.<br>
                    <br>
                    <div class="moz-cite-prefix">On 16.04.2015 15:42,
                      Bengt Rutisson wrote:<br>
                    </div>
                    <blockquote cite="mid:552FAE22.4020009@oracle.com"
                      type="cite">
                      <meta content="text/html; charset=utf-8"
                        http-equiv="Content-Type">
                      <br>
                      Hello Dima,<br>
                      <br>
                      <div class="moz-cite-prefix">On 2015-04-16 13:40,
                        Dmitry Fazunenko wrote:<br>
                      </div>
                      <blockquote cite="mid:552F9FA8.3030403@oracle.com"
                        type="cite">
                        <meta http-equiv="content-type"
                          content="text/html; charset=utf-8">
                        Hello,<br>
                        <br>
                        Would you review a simple fix in G1.<br>
                        <br>
                        Short description: <br>
                        after introduction G1Log - dynamic changes of
                        PrintGC and PrintGCDetails flag has no effect
                        anymore, because G1Log looks for these flags
                        during initialization only. The fix: sync the
                        log level with the flags values.<br>
                        <br>
                        A huge thanks to Jesper who helped me a lot with
                        my first product fix.<br>
                        <br>
                        Bug: <a moz-do-not-send="true"
                          class="moz-txt-link-freetext"
                          href="https://bugs.openjdk.java.net/browse/JDK-8073476">https://bugs.openjdk.java.net/browse/JDK-8073476</a><br>
                        Webrev: <a moz-do-not-send="true"
                          class="moz-txt-link-freetext"
                          href="http://cr.openjdk.java.net/%7Edfazunen/8073476/webrev.06/">http://cr.openjdk.java.net/~dfazunen/8073476/webrev.06/</a><br>
                      </blockquote>
                      <br>
                      Sorry, but I don't really like the way this is
                      solved. With this approach calling
                      G1GCPhaseTimes::print() suddenly has the side
                      effect that it resets the log level. That's quite
                      unexpected for me. Especially if you consider the
                      code path in G1CollectedHeap::log_gc_footer()
                      where we do this:<br>
                      <br>
                      void G1CollectedHeap::log_gc_footer(double
                      pause_time_sec) {<br>
                        if (!G1Log::fine()) {<br>
                          return;<br>
                        }<br>
                      <br>
                        if (G1Log::finer()) {<br>
                          ...<br>
                         
                      g1_policy()->phase_times()->print(pause_time_sec);<br>
                          ...<br>
                        }<br>
                      <br>
                      If we don't have G1Log::fine() (which is PrintGC)
                      enabled we will never call the print() method and
                      will thus not detect any changes made by the
                      MXBean. If we have G1Log::finer() enabled we enter
                      the logging code, print other things at the
                      "finer" level (which is PrintGCDetails) and then
                      do the call to the print() method where we can
                      suddenly decide that PrintGCDetails no longer is
                      enabled and not do the rest of the logging. So for
                      the same GC we will print some stuff at
                      PrintGCDetails level and some things at another
                      level. Strange.<br>
                    </blockquote>
                    <br>
                    May it's not clear, but the change will have effect
                    only if PrintGC or PrintGCDetails has been changed
                    during execution.<br>
                    Otherwise, the level will not change.<br>
                  </blockquote>
                  <br>
                  I understand that, but what I was saying with the
                  example above is that you will not get the desired
                  effect if you change PrintGC or PrintGCDetails at
                  runtime. If they are disabled, and then turn them on
                  at runtime you will not enter the update code because
                  of this check at the start of the log_gc_footer()
                  method:<br>
                  <br>
                    if (!G1Log::fine()) {<br>
                      return;<br>
                    }<br>
                  <br>
                  <br>
                  Similarly turning them off at runtime will start to
                  have an effect in the middle of a GC. Which is
                  probably not the effect you are looking for.<br>
                </blockquote>
                fine() invokes level(), level() invokes update(), so
                G1::fine() will return the up to date value:<br>
                <br>
                <pre>   inline static bool fine() {
<span class="removed">-    return _level >= LevelFine;</span>
<span class="new">+    return level() >= LevelFine;</span>
   }</pre>
                <br>
                <pre>   static LogLevel level() {
<span class="new">+    // PringGC and PrintGCDetails are dynamic flags</span>
<span class="new">+    // _level should be in sync with the latest values</span>
<span class="new">+    update_level();</span>
     return _level;
   }</pre>
                <br>
              </blockquote>
              Oh, I missed that you had changed fine() to call level().
              This means that all calls to G1Log interface has side
              effects. I don't like that at all.<br>
              <br>
              <blockquote cite="mid:55310FCF.5030109@oracle.com"
                type="cite">
                <blockquote cite="mid:5530AB92.2050509@oracle.com"
                  type="cite"> <br>
                  This is why making the level() getter having the side
                  effect of changing the log level is a bad idea. You
                  have no control over when that happens.<br>
                </blockquote>
                <br>
                It must be up to those who change flags at runtime.<br>
                But the following code should work:<br>
                <br>
                MXBean.set(PrintGC, false);<br>
                System.gc();<br>
                MXBean.set(PrintGC, true);<br>
                <br>
                <blockquote cite="mid:5530AB92.2050509@oracle.com"
                  type="cite"> <br>
                  <blockquote cite="mid:552FBAF5.1060908@oracle.com"
                    type="cite"> <br>
                    To me, it's strange, that when I disable PrintGC in
                    G1 I still seeing gc log messages... <br>
                    Or, I can't turn logging on during execution with
                    G1.<br>
                    This works well for other collectors.<br>
                    <br>
                    Would it make sense to make PrintGC and
                    PrintGCDetails unmanageable in case of g1?<br>
                  </blockquote>
                  <br>
                  I think they can be manageble but their changed states
                  need to be handled more explicitly.<br>
                  <br>
                  <blockquote cite="mid:552FBAF5.1060908@oracle.com"
                    type="cite"> <br>
                    <br>
                    <blockquote cite="mid:552FAE22.4020009@oracle.com"
                      type="cite"> <br>
                      <br>
                      I would prefer to have a hook when the MXBean
                      changes the value and only update the level at
                      that point.<br>
                    </blockquote>
                    <br>
                    Yes, it would be ideal solution. But I haven't found
                    such a mechanism supported. And it's unlikely worth
                    adding just for this case.<br>
                    In my version, the sync will be done more
                    frequently. <br>
                  </blockquote>
                  <br>
                  The sync is done very frequently. Actually way too
                  often in my view.<br>
                </blockquote>
                <blockquote cite="mid:5530AB92.2050509@oracle.com"
                  type="cite"> <br>
                  I would prefer that you investigate the hook in the
                  MXBean change so we know how much work that would be.
                </blockquote>
                <br>
                It was my first intention, but I haven't found a way how
                to implement it.<br>
              </blockquote>
              <br>
              I think what you need to do is to extend the Flag class
              with an update() method and call the method in
              WriteableFlags::set_flag().<br>
              <br>
              <blockquote cite="mid:55310FCF.5030109@oracle.com"
                type="cite"> <br>
                <blockquote cite="mid:5530AB92.2050509@oracle.com"
                  type="cite">If that is not possible I think a better
                  solution is to call G1Log::update_level() *once* at
                  the start of a GC. That way the log level is always
                  consistent throughout the GC.<br>
                </blockquote>
                <br>
                Yes, this is a good idea!<br>
              </blockquote>
              <br>
              Yes, it is much cleaner.<br>
              <br>
              <blockquote cite="mid:55310FCF.5030109@oracle.com"
                type="cite"> <br>
                <blockquote cite="mid:5530AB92.2050509@oracle.com"
                  type="cite"> <br>
                  <blockquote cite="mid:552FBAF5.1060908@oracle.com"
                    type="cite"> <br>
                    <blockquote cite="mid:552FAE22.4020009@oracle.com"
                      type="cite"> <br>
                      Having said that I am not sure that this bug is
                      worth fixing right now. I am currently working on
                      the JEP to make the GC logging use the new unified
                      logging format. That will change all of this and
                      most likely remove the G1Log class all together.
                      So, my suggestion would be to leave this as is for
                      now and instead add the MXBean requirement to the
                      unified logging work.<br>
                    </blockquote>
                    <br>
                    Yes, I'm aware of unified logging and expect that
                    G1Log class will go away someday.<br>
                    But I would like to be able to disable logging in
                    JDK9, to not see GC events occurred at the certain
                    period of time.<br>
                  </blockquote>
                  <br>
                  Can you explain more why this is important to fix
                  right now? Unified logging is targeted for JDK 9.<br>
                </blockquote>
                <br>
                What I heard about unified logging is that there is no
                guarantee that it will happen in JDK9 time frame.<br>
                I need the feature now to develop tests based on
                analysis of logs: I want to start logging not from
                begging, but after some steps.<br>
                <br>
                Will you be okay if G1Log::update_level() is invoked
                once per GC?<br>
              </blockquote>
              <br>
              I would be ok with it, but I'm pretty convinced unified
              logging will make it in to JDK9 so if you can wait for it
              that might be better.<br>
              <br>
              Thanks,<br>
              Bengt<br>
              <br>
              <blockquote cite="mid:55310FCF.5030109@oracle.com"
                type="cite"> <br>
                Thanks,<br>
                Dima<br>
                <br>
                <blockquote cite="mid:5530AB92.2050509@oracle.com"
                  type="cite"> <br>
                  Thanks,<br>
                  Bengt<br>
                  <br>
                  <blockquote cite="mid:552FBAF5.1060908@oracle.com"
                    type="cite"> <br>
                    Thanks,<br>
                    Dima<br>
                    <br>
                    <br>
                    <blockquote cite="mid:552FAE22.4020009@oracle.com"
                      type="cite"> <br>
                      Thanks,<br>
                      Bengt<br>
                      <blockquote cite="mid:552F9FA8.3030403@oracle.com"
                        type="cite"> <br>
                        Testing: <br>
                        I ran manually the test from the bug report to
                        make sure the change fixes the problem.<br>
                        A regression test will be delivered separately
                        as a fix of <a moz-do-not-send="true"
                          id="key-val" rel="4774806"
                          href="https://bugs.openjdk.java.net/browse/JDK-8077056">JDK-8077056</a><br>
                        <br>
                        Thanks,<br>
                        Dima </blockquote>
                      <br>
                    </blockquote>
                    <br>
                  </blockquote>
                  <br>
                </blockquote>
                <br>
              </blockquote>
              <br>
            </blockquote>
            <br>
          </blockquote>
          <br>
        </blockquote>
        <br>
      </blockquote>
      <br>
    </blockquote>
    <br>
  </body>
</html>