JDK-8237542 : JMapHeapConfigTest.java doesn't work with negative jlong values
  • Type: Bug
  • Component: hotspot
  • Sub-Component: svc-agent
  • Affected Version: 14
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-01-20
  • Updated: 2023-08-31
  • Resolved: 2023-08-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 22
22 b13Fixed
Related Reports
Relates :  
Description
The test tries to match -XX:+PrintFlagsFinal with the output of jhsdb -jmap --pid <pid> --heap. This fails when running ZGC, which leaves the MaxNewSize set to (size_t)-1.

$ ../build/fastdebug/jdk/bin/jhsdb jmap --pid 1550 --heap
Attaching to process ID 1550, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 15-internal+0-2020-01-20-0958066.stefank...

using thread-local object allocation.
ZGC with 20 thread(s)

Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 32210157568 (30718.0MB)
   NewSize                  = 1363144 (1.2999954223632812MB)
   MaxNewSize               = 17592186044415 MB
   OldSize                  = 5452592 (5.1999969482421875MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

and:
$ ../build/fastdebug/jdk/bin/java -XX:+PrintFlagsFinal -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -cp /localhome/tests/ HelloSleep 2>&1 | grep MaxNewSize
   size_t MaxNewSize                               = 18446744073709551615                      {product} {default}

HeapSummary.printValMB looks like this:
   private static final double FACTOR = 1024*1024;                                                                                                                                            
   private void printValMB(String title, long value) {                                                                                                                                        
      if (value < 0) {                                                                                                                                                                        
        System.out.println(alignment + title +   (value >>> 20)  + " MB");                                                                                                                    
      } else {                                                                                                                                                                                
        double mb = value/FACTOR;                                                                                                                                                             
        System.out.println(alignment + title + value + " (" + mb + "MB)");                                                                                                                    
      }                                                                                                                                                                                       
   } 

And when the value is negative we get a line that looks like this:
MaxNewSize               = 17592186044415 MB

The test then tries to compare 17592186044415 with 18446744073709551615.

Repro:
make -C ../build/fastdebug test TEST=sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java JTREG="VM_OPTIONS=-XX:+UnlockExperimentalVMOptions -XX:+UseZGC"


Comments
Changeset: 8a5db6ba Author: Chris Plummer <cjplummer@openjdk.org> Date: 2023-08-25 23:16:02 +0000 URL: https://git.openjdk.org/jdk/commit/8a5db6bab343cdea667ea4b0e985574f75332d3e
25-08-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/15368 Date: 2023-08-21 19:25:25 +0000
21-08-2023

From jmap we have: MaxNewSize = 17592186044415 MB Which is 0xfffffffffff (11 f's) and from -XX:+PrintFlagsFinal we have: size_t MaxNewSize = 18446744073709551615 {product} {default} Which is 0xffffffffffffffff (16 f's). It's clear from printValMB() why we are only getting 11 f's instead of 16: private static final double FACTOR = 1024*1024; private void printValMB(String title, long value) { if (value < 0) { System.out.println(alignment + title + (value >>> 20) + " MB"); } else { double mb = value/FACTOR; System.out.println(alignment + title + value + " (" + mb + "MB)"); } The question is, why is the >>> 20 being done? Note 20 bits correlates to FACTOR being 2^20, so it looks like this is an attempt to divide by FACTOR when the high bit of the value is set. But the test failure is actually because when value is negative, it's unsigned value is not also printed out like it is in the else clause above. So you end up with: MaxNewSize = 17592186044415 MB Instead of: MaxNewSize = 18446744073709551615 (17592186044415 MB) So the test fails to find 18446744073709551615 in the output. The >>> 20 isn't wrong and could actually have been used in the else part also. The real problem is the not also printing out the unmodified value like the else part does. This change came from the following bug fix: JDK-6718125 - SA: jmap prints negative value for MaxNewSize So I think we need to find a way to print what appears to be negative values as unsigned longs. JDK-6718125 provides a hint as to how to do this: "java.lang.Long has toUnsignedString() method but it is a private API so we mayhave to write our own method to print this as unsigned long value. " This was never actually done, but toUnsignedString() is now public, so possibly could be leveraged.
18-08-2023

It looks like this issue was discovered while implementing changes for the following CR: JDK-8237111 - LingeredApp should be started with getTestJavaOpts I assumed JDK-8237111 resulted the test launching LingeredApp with ZGC, and that caused the problem to reproduce. As a result of this discovery, JDK-8237111 deactivated the test code that reproduces the issue: // Test can't deal with negative jlongs: // ignoring MaxMetaspaceSize // ignoring MaxNewSize
18-08-2023

I looks like we don't even run the sun/tools/jhsdb tests with ZGC. Thus at the moment this test is not even problem listed.
30-07-2021