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

Having a #define JVMTI_LATEST_VERSION would be good for cross-version agents

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • None
    • hotspot
    • None


      bool HeapMonitor::Supported(jvmtiEnv *jvmti) {
        jvmtiCapabilities caps;
        memset(&caps, 0, sizeof(caps));
        if (jvmti->GetPotentialCapabilities(&caps) != JVMTI_ERROR_NONE) {
          LOG(WARNING) << "Failed to get potential capabilities, disabling the heap "
                       << "sampling monitor";
          return false;
        }

        return caps.can_generate_sampled_object_alloc_events
            && caps.can_generate_garbage_collection_events;
      }


      For pre-JDK11, you would have a compilation error so you would have to do something like:


      bool HeapMonitor::Supported(jvmtiEnv *jvmti) {
      #ifdef ENABLE_HEAP_SAMPLING
        jvmtiCapabilities caps;
        memset(&caps, 0, sizeof(caps));
        if (jvmti->GetPotentialCapabilities(&caps) != JVMTI_ERROR_NONE) {
          LOG(WARNING) << "Failed to get potential capabilities, disabling the heap "
                       << "sampling monitor";
          return false;
        }

        return caps.can_generate_sampled_object_alloc_events
            && caps.can_generate_garbage_collection_events;
      #else
        return false;
      #endif
      }

      But now you need to know at compile time which JVMTI version is being used to define that macro... So things get pretty messy in the agent code for handling various JDK versions.

      #if do not play nice with enums, so the idea is to have something like:


      enum {
          JVMTI_VERSION_1 = 0x30010000,
          JVMTI_VERSION_1_0 = 0x30010000,
          JVMTI_VERSION_1_1 = 0x30010100,
          JVMTI_VERSION_1_2 = 0x30010200,
          JVMTI_VERSION_9 = 0x30090000,
          JVMTI_VERSION_11 = 0x300B0000,

          JVMTI_VERSION = 0x30000000 + (11 * 0x10000) + (0 * 0x100) + 0 /* version: 11.0.0 */
      };

      #define JVMTI_LATEST_VERSION (0x30000000 + (11 * 0x10000) + (0 * 0x100) + 0 /* version: 11.0.0 */)

      Special note: this would not work:
      #define JVMTI_LATEST_VERSION JVMTI_VERSION

      Because the macro will get preprocessed into an enum, it won't be able to be used at compilation time correctly. We really need a full explicit literal number for the define.

      Also note that this technically means that agents will be playing with the actual format and numeric versioning numbering to do something like:

      // Our own agent versioning numbering system so that we can #if with it.
      #define JVMTI_VERSION_11 0x300B0000

      #if JVMTI_LATEST_VERSION >= JVMTI_VERSION_11


      An alternative would be to modify the enum into #defines but it is not sure what are the ramifications of that, ie who is using the enum for type checking.

            Unassigned Unassigned
            jcbeyler Jean Christophe Beyler
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: