changeset 249:d5a88a5981b0

Bug 3437: Add support for JDK 9 Version-String Scheme (JEP 223) Reviewed-by: yasuenag https://github.com/HeapStats/heapstats/pull/118
author KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp>
date Tue, 15 Aug 2017 11:53:26 +0900
parents 3c68803ba91b
children 09cbd56eb921
files ChangeLog agent/src/heapstats-engines/jvmInfo.cpp agent/src/heapstats-engines/jvmInfo.hpp agent/src/heapstats-engines/libmain.cpp agent/test/oome/OOME.java
diffstat 5 files changed, 48 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Aug 02 16:02:28 2017 +0900
+++ b/ChangeLog	Tue Aug 15 11:53:26 2017 +0900
@@ -1,3 +1,7 @@
+2017-08-15 KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp>
+
+	* Bug 3437: Add support for JDK 9 Version-String Scheme (JEP 223)
+
 2017-08-02 KUBOTA Yuji <kubota.yuji@lab.ntt.co.jp>
 
 	* Bug 3430: Fix potential error when conflict between VMDeath and class loading
--- a/agent/src/heapstats-engines/jvmInfo.cpp	Wed Aug 02 16:02:28 2017 +0900
+++ b/agent/src/heapstats-engines/jvmInfo.cpp	Tue Aug 15 11:53:26 2017 +0900
@@ -136,66 +136,48 @@
   } else {
     logger->printDebugMsg("HotSpot version: %s", versionStr);
 
+    /*
+     * Version-String Scheme has changed since JDK 9 (JEP223).
+     * afterJDK9 means whether this version is after JDK 9(1) or not(0).
+     * major means hotspot version until JDK 8, jdk major version since JDK 9.
+     * minor means jdk minor version in every JDK.
+     * build means build version in every JDK.
+     * security means security version which has introduced since JDK 9.
+     *
+     * NOT support Early Access because the binaries do not archive.
+     * See also: https://bugs.openjdk.java.net/browse/JDK-8061493
+     */
+    unsigned char afterJDK9 = 0;
     unsigned char major = 0;
     unsigned char minor = 0;
-    unsigned char micro = 0;
     unsigned char build = 0;
+    unsigned char security = 0;
     int result = 0;
 
-    /* Parse version string. */
+    /* Parse version string of JDK 8 and older. */
     result = sscanf(versionStr, "%hhu.%hhu-b%hhu", &major, &minor, &build);
-    /*
-     * We expect to get 3 values (major, minor, build) from sscanf() at first.
-     */
     if (result != 3) {
-      /* After JDK-8030011: Update Hotspot version string output */
-      result = sscanf(versionStr, "%hhu.%hhu.%hhu", &major, &minor, &micro);
-      char *build_str = strrchr(versionStr, 'b');
-      if (likely(build_str != NULL)) {
-        result += sscanf(build_str, "b%hhu", &build);
-      }
-
       /*
-       * We expect to get 4 values (major, minor, micro, build) from sscanf().
-       * This versioning equals to JDK version.
+       * Parse version string of JDK 9+ GA.
+       * GA release does not include minor and security.
        */
-      if (unlikely(result != 4)) {
-        /*
-         * Support JDK 9 EA
-         * See https://bugs.openjdk.java.net/browse/JDK-8061493
-         */
-#if USE_PCRE
-        TPCRERegex versionRegex("^(\\d+)-ea\\+(\\d+)$", 9);
-#else
-        TCPPRegex versionRegex("^(\\d+)-ea\\+(\\d+)$");
-#endif
-        if (versionRegex.find(versionStr)) {
-          char *minorStr = versionRegex.group(1);
-          char *buildStr = versionRegex.group(2);
+      result = sscanf(versionStr, "%hhu+%hhu", &major, &build);
 
-          major = 1;
-          minor = (unsigned char)atoi(minorStr);
-          micro = 0;
-          build = (unsigned char)atoi(buildStr);
-
-          free(minorStr);
-          free(buildStr);
-        } else {
+      if (likely(result != 2)) {
+        /* Parse version string of JDK 9 GA (Minor #1) and later */
+        result = sscanf(versionStr, "%hhu.%hhu.%hhu+%hhu", &major, &minor,
+            &security, &build);
+        if (unlikely(result != 4)) {
           logger->printCritMsg("Unsupported JVM version: %s", versionStr);
           jvmti->Deallocate((unsigned char *)versionStr);
           return false;
         }
       }
-
-      /*
-       * Latest HS version is "25".
-       * So I add 25 to major.
-       */
-      major += 25;
+      afterJDK9 = 1;
     }
 
     jvmti->Deallocate((unsigned char *)versionStr);
-    _hsVersion = MAKE_HS_VERSION(major, minor, micro, build);
+    _hsVersion = MAKE_HS_VERSION(afterJDK9, major, minor, security, build);
   }
 
   return true;
--- a/agent/src/heapstats-engines/jvmInfo.hpp	Wed Aug 02 16:02:28 2017 +0900
+++ b/agent/src/heapstats-engines/jvmInfo.hpp	Tue Aug 15 11:53:26 2017 +0900
@@ -28,10 +28,10 @@
 #include <stddef.h>
 
 /*!
- *  * \brief Make HotSpot version
- *   */
-#define MAKE_HS_VERSION(major, minor, micro, build) \
-  (((major) << 24) | ((minor) << 16) | ((micro) << 8) | (build))
+ * \brief Make HotSpot version
+ */
+#define MAKE_HS_VERSION(afterJDK9, major, minor, micro, build) \
+  (((afterJDK9) << 30) | ((major) << 24) | ((minor) << 16) | ((micro) << 8) | (build))
 
 /*!
  * \brief JVM performance header info.
@@ -310,7 +310,7 @@
    */
   inline bool isAfterCR7046558(void) {
     // hs22.0-b03
-    return (this->_hsVersion >= MAKE_HS_VERSION(22, 0, 0, 3));
+    return (this->_hsVersion >= MAKE_HS_VERSION(0, 22, 0, 0, 3));
   }
 
   /*!
@@ -320,7 +320,7 @@
    */
   inline bool isAfterCR7017732(void) {
     // hs21.0-b06
-    return (this->_hsVersion >= MAKE_HS_VERSION(21, 0, 0, 6));
+    return (this->_hsVersion >= MAKE_HS_VERSION(0, 21, 0, 0, 6));
   }
 
   /*!
@@ -332,7 +332,7 @@
    */
   inline bool isAfterCR6964458(void) {
     // hs25.0-b01
-    return (this->_hsVersion >= MAKE_HS_VERSION(25, 0, 0, 1));
+    return (this->_hsVersion >= MAKE_HS_VERSION(0, 25, 0, 0, 1));
   }
 
   /*!
@@ -343,7 +343,7 @@
    */
   inline bool isAfterCR8000213(void) {
     // hs25.0-b04
-    return (this->_hsVersion >= MAKE_HS_VERSION(25, 0, 0, 4));
+    return (this->_hsVersion >= MAKE_HS_VERSION(0, 25, 0, 0, 4));
   }
 
   /*!
@@ -353,7 +353,7 @@
    */
   inline bool isAfterCR8027746(void) {
     // hs25.20-b02
-    return (this->_hsVersion >= MAKE_HS_VERSION(25, 20, 0, 2));
+    return (this->_hsVersion >= MAKE_HS_VERSION(0, 25, 20, 0, 2));
   }
 
   /*!
@@ -364,7 +364,7 @@
    */
   inline bool isAfterCR8049421(void) {
     // hs25.40-b05
-    return (this->_hsVersion >= MAKE_HS_VERSION(25, 40, 0, 5));
+    return (this->_hsVersion >= MAKE_HS_VERSION(0, 25, 40, 0, 5));
   }
 
   /*!
@@ -373,7 +373,7 @@
    */
   inline bool isAfterCR8004883(void) {
     // hs25.0-b14
-    return (this->_hsVersion >= MAKE_HS_VERSION(25, 0, 0, 14));
+    return (this->_hsVersion >= MAKE_HS_VERSION(0, 25, 0, 0, 14));
   }
 
   /*!
@@ -384,7 +384,7 @@
    */
   inline bool isAfterCR8003424(void) {
     // hs25.0-b46
-    return (this->_hsVersion >= MAKE_HS_VERSION(25, 0, 0, 46));
+    return (this->_hsVersion >= MAKE_HS_VERSION(0, 25, 0, 0, 46));
   }
 
   /*!
@@ -394,14 +394,14 @@
    */
   inline bool isAfterCR8015107(void) {
     // hs25.0-b51
-    return (this->_hsVersion >= MAKE_HS_VERSION(25, 0, 0, 51));
+    return (this->_hsVersion >= MAKE_HS_VERSION(0, 25, 0, 0, 51));
   }
 
   /*!
    * \brief Running on JDK 9 or not.
    */
   inline bool isAfterJDK9(void) {
-    return (this->_hsVersion >= MAKE_HS_VERSION(26, 0, 0, 0));
+    return (this->_hsVersion >= MAKE_HS_VERSION(1, 9, 0, 0, 0));
   }
 
   /*!
--- a/agent/src/heapstats-engines/libmain.cpp	Wed Aug 02 16:02:28 2017 +0900
+++ b/agent/src/heapstats-engines/libmain.cpp	Tue Aug 15 11:53:26 2017 +0900
@@ -552,10 +552,6 @@
     return GET_LOW_LEVEL_INFO_FAILED;
   }
 
-  if (!jvmInfo->setHSVersion(*jvmti)) {
-    return GET_LOW_LEVEL_INFO_FAILED;
-  }
-
   /* Initialize configuration */
   conf = new TConfiguration(jvmInfo);
 
@@ -574,6 +570,11 @@
   logger->setLogLevel(conf->LogLevel()->get());
   logger->setLogFile(conf->LogFile()->get());
 
+  /* Parse JDK Version */
+  if (!jvmInfo->setHSVersion(*jvmti)) {
+    return GET_LOW_LEVEL_INFO_FAILED;
+  }
+
   /* Show package information. */
   logger->printInfoMsg(PACKAGE_STRING);
   logger->printInfoMsg(
--- a/agent/test/oome/OOME.java	Wed Aug 02 16:02:28 2017 +0900
+++ b/agent/test/oome/OOME.java	Tue Aug 15 11:53:26 2017 +0900
@@ -3,7 +3,7 @@
 
 public class OOME{
   public static void main(String[] args){
-    List<byte[]> list = new ArrayList<>();
+    List<byte[]> list = new ArrayList<byte[]>();
 
     while(true){
       list.add(new byte[1024*1024]);