JDK-8145221 : Use trampolines for i2i and i2c entries in Methods that are stored in CDS archive
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2015-12-11
  • Updated: 2024-11-06
  • Resolved: 2016-04-08
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 9
9 b116Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
(This is an alternative proposal than JDK-8026297).

When a CDS-archived class is loaded, the following 4 fields are unconditionally modified for every Method in this class:

Method::_i2i_entry
Method::_from_interpreted_entry
Method::_from_compiled_entry
Method::_adapter

This causes a lot of copy-on-write on the Methods. If we can avoid these modifications, more data in the "RW" section of the CDS archive can be shared across processes.

The proposal is to change the first 3 fields into trampoline calls. E.g.,

Method::_i2i_entry points to a function F at a fixed location inside the CDS archive's "MC" section. In turn, F contains an unconditional branch to the real destination of the i2i entry.

For the 4th field, the proposal is

  union {
    AdapterHandlerEntry* _adapter;
    AdapterHandlerEntry** _adapter_trampoline;
  };

  AdapterHandlerEntry* adapter() {
    if (is_shared()) {
      return *_adapter_trampoline;
    } else {
      return _adapter;
    }
  }

_adapter_trampoline points to a fixed location A inside the CDS archive's "MD" section. In turn, A points to the real location of the AdapterHandlerEntry.

When the class is loaded, the contents of F and A will be modified, but the contents of the Method no longer need to be modified.

With this change, Method::_adapter can be moved to ConstMethod, since it never changes for archived Methods.

We can also move Method::i2i_entry to ConstMethod. However, I am not sure about the performance impact, so this will be done in a separate RFE (JDK-8145234).

Comments
URL: http://hg.openjdk.java.net/jdk9/jdk9/hotspot/rev/c04ff0bb5b8e User: lana Date: 2016-04-27 18:46:27 +0000
27-04-2016

URL: http://hg.openjdk.java.net/jdk9/hs-rt/hotspot/rev/c04ff0bb5b8e User: ccheung Date: 2016-04-08 23:09:42 +0000
08-04-2016

Refworkload ran with -Xint on macosx 10 iterations. No significant performance degradation is found. https://bugs.openjdk.java.net/secure/attachment/57093/macosx_xint_results2.txt
12-02-2016

Refworkload on solaris/sparcv9 10 iterations. No significant performance degradation is found. https://bugs.openjdk.java.net/secure/attachment/57092/sparcv9_results.txt
12-02-2016

I ran refworkload on linux/x64with 10 iterations. No significant performance difference is found. See attachment: https://bugs.openjdk.java.net/secure/attachment/56503/refworkload_linux_x64.txt
19-01-2016

After moving Method::_adapter to ConstMethod, the default CDS archive's RW data is reduced by about 1.4%. Method old = 3,027,344 bytes Method new = 2,753,568 bytes ConstMethod old = 3,832,744 bytes ConstMethod new = 4,106,520 bytes All read-only old = 7,084,304 bytes All read-only new = 7,358,080 bytes All read-write old = 11,466,541 bytes (61.8% total) All read-write new = 11,204,861 bytes (60.4% total = -1.4%)
11-12-2015

I have implemented a prototype based on JDK9. I wrote a test program that uses ClassLoader.loadClass() to load every archived class (using $JAVA_HOME/lib/classlist). Here are the statistics of the "RW" section of the mapped CDS archive: BEFORE: 801000000-801a43000 rw-p 006c3000 08:01 16709446 /jdk/bld/adapter/images/jdk/lib/amd64/server/classes.jsa Size: 10508 kB Rss: 9908 kB Pss: 9908 kB Shared_Clean: 0 kB Shared_Dirty: 0 kB Private_Clean: 336 kB Private_Dirty: 9572 kB Referenced: 9604 kB Anonymous: 9572 kB AnonHugePages: 0 kB Swap: 0 kB KernelPageSize: 4 kB MMUPageSize: 4 kB Locked: 0 kB AFTER 801000000-801a43000 rw-p 006c3000 08:01 16704847 /jdk/bld/adapter/images/jdk/lib/amd64/hotspot/classes.jsa Size: 10508 kB Rss: 9892 kB Pss: 9892 kB Shared_Clean: 0 kB Shared_Dirty: 0 kB Private_Clean: 1428 kB Private_Dirty: 8464 kB Referenced: 9892 kB Anonymous: 8464 kB AnonHugePages: 0 kB Swap: 0 kB KernelPageSize: 4 kB MMUPageSize: 4 kB Locked: 0 kB You can see the Private_Clean size has increased from 336 kB to 1428 kB. This is the size of the "RW" section that has been read by the JVM process but not modified. The prototype allocates extra memory in the MC and MD sections (for the "F" and "A" objects in the Description of this RFE). The MC section has increased 8KB and the MD section has increased 4KB. NOTES: [1] the prototype has not moved _adapter from Method to ConstMethod [2] the "clean" size changes is not meant to be representative of real world applications. It merely shows that the effect of using trampolines can be measured.
11-12-2015