Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8357911

JFR: Fix subtle xor method tagging bug

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 25
    • 22, 23, 24, 25
    • hotspot
    • None
    • jfr
    • 22
    • master

      JDK-8211238 added a means to tag a method with a meta-bit (TRANSIENT_BIT) that counts towards a Method* considered "in-use".

      With JDK-8328610, we'll introduce yet another meta-bit (STICKY_BIT) that will also count towards a Method* considered "in-use"

      This results in the following "in-use" predicate for Method*'s:

      #define METHOD_FLAG_USED_PREVIOUS_EPOCH(method) (METHOD_FLAG_PREDICATE(method, (STICKY_BIT | TRANSIENT_BIT | PREVIOUS_EPOCH_BIT)))

      STICKY_BIT and TRANSIENT_BIT are in the higher-order meta-bits, while PREVIOUS_EPOCH_BIT is the low-order "user bit".

      The clearing of tag bits looks like this for a Method*:

      template <>
      class ClearArtifact<const Method*> {
       public:
       bool operator()(const Method* method) {
       assert(METHOD_FLAG_USED_PREVIOUS_EPOCH(method), "invariant");
       CLEAR_SERIALIZED_METHOD(method);
       assert(METHOD_IS_NOT_SERIALIZED(method), "invariant");
       assert(METHOD_IS_NOT_LEAKP(method), "invariant");
       assert(METHOD_IS_NOT_TRANSIENT(method), "invariant");
       SET_PREVIOUS_EPOCH_METHOD_CLEARED_BIT(method);
       CLEAR_PREVIOUS_EPOCH_METHOD_FLAG(method);
       assert(IS_THIS_EPOCH_METHOD_CLEARED_BIT_SET(method), "invariant");
       assert(IS_PREVIOUS_EPOCH_METHOD_CLEARED_BIT_SET(method), "invariant");
       return true;
       }

      // CLEAR_SERIALIZED_METHOD uses an AND mask to clear the following meta-bits: SERIALIZED_BIT | TRANSIENT_BIT | LEAKP_BIT

      // CLEAR_PREVIOUS_EPOCH_METHOD_FLAG(Method) instead uses an XOR cas to clear the PREVIOUS_EPOCH_BIT.

      The problem here is with this last macro, especially as we move towards letting meta-bits also denote "in-use".

      This is because CLEAR_PREVIOUS_EPOCH_METHOD_FLAG(Method) assumes PREVIOUS_EPOCH_BIT to be set.

      Let's say the Method* is considered in use only because its TRANSIENT_BIT meta-bit is set.

      What happens when an XOR is used to clear something that is 0? 1 XOR 0 == 1.

      I.e., CLEAR_PREVIOUS_EPOCH_METHOD_FLAG(Method) sets the PREVIOUS_EPOCH_BIT, rather than clearing it, in cases where the PREVIOUS_EPOCH_BIT is not set.

            mgronlun Markus Grönlund
            mgronlun Markus Grönlund
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: