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
--- 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.");
+ }
+ }
}