8195613: [SA] HotSpotTypeDataBase.readVMLongConstants truncates values to int
authorjgeorge
Tue, 15 May 2018 02:47:40 +0530
changeset 50107 300e4a88c400
parent 50106 24151f48582b
child 50108 2e9dc3f896c8
8195613: [SA] HotSpotTypeDataBase.readVMLongConstants truncates values to int Summary: Avoid truncation to int while reading in long constants from vmStructs. Modify ClhsdbLongConstant.java for truncation testing. Reviewed-by: dholmes, sspitsyn, cjplummer
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java
test/hotspot/jtreg/serviceability/sa/ClhsdbLongConstant.java
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java	Mon May 14 21:56:07 2018 +0200
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java	Tue May 15 02:47:40 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -563,7 +563,7 @@
       nameAddr = entryAddr.getAddressAt(longConstantEntryNameOffset);
       if (nameAddr != null) {
         String name = CStringUtilities.getString(nameAddr);
-        int value = (int) entryAddr.getCIntegerAt(longConstantEntryValueOffset, C_INT64_SIZE, true);
+        long value = entryAddr.getCIntegerAt(longConstantEntryValueOffset, C_INT64_SIZE, true);
 
         // Be a little resilient
         Long oldValue = lookupLongConstant(name, false);
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbLongConstant.java	Mon May 14 21:56:07 2018 +0200
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbLongConstant.java	Tue May 15 02:47:40 2018 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -71,7 +71,14 @@
             unExpStrMap.put("longConstant jtreg::test", List.of(
                     "Error: java.lang.RuntimeException: No long constant named"));
 
-            test.run(theApp.getPid(), cmds, expStrMap, unExpStrMap);
+            String longConstantOutput = test.run(theApp.getPid(), cmds, expStrMap, unExpStrMap);
+
+            if (longConstantOutput == null) {
+                // Output could be null due to attach permission issues
+                // and if we are skipping this.
+                return;
+            }
+            checkForTruncation(longConstantOutput);
         } catch (Exception ex) {
             throw new RuntimeException("Test ERROR " + ex, ex);
         } finally {
@@ -79,4 +86,41 @@
         }
         System.out.println("Test PASSED");
     }
+
+    private static void checkForTruncation(String longConstantOutput) throws Exception {
+
+        // Expected values obtained from the hash_mask_in_place definition in markOop.hpp
+
+        // Expected output snippet is of the form (on x64-64):
+        // ...
+        // longConstant VM_Version::CPU_SHA 17179869184
+        // longConstant markOopDesc::biased_lock_bits 1
+        // longConstant markOopDesc::age_shift 3
+        // longConstant markOopDesc::hash_mask_in_place 549755813632
+        // ...
+
+        checkLongValue("markOopDesc::hash_mask_in_place",
+                       longConstantOutput,
+                       Platform.is64bit() ? 549755813632L: 4294967168L);
+
+        String arch = System.getProperty("os.arch");
+        if (arch.equals("amd64") || arch.equals("i386") || arch.equals("x86")) {
+            // Expected value obtained from the CPU_SHA definition in vm_version_x86.hpp
+            checkLongValue("VM_Version::CPU_SHA",
+                           longConstantOutput,
+                           17179869184L);
+        }
+    }
+
+    private static void checkLongValue(String constName, String longConstantOutput,
+                                       long checkValue) throws Exception {
+
+        String[] snippets = longConstantOutput.split(constName);
+        String[] words = snippets[1].split("\\R");
+        long readValue = Long.parseLong(words[0].trim());
+        if (readValue != checkValue) {
+            throw new Exception ("Reading " + constName + ". Expected " + checkValue +
+                                 ". Obtained " + readValue + " instead.");
+        }
+    }
 }