Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8064457

Introduce compressed oops mode "disjoint base" and improve compressed heap handling.



    • Enhancement
    • Resolution: Fixed
    • P4
    • 9
    • None
    • hotspot
    • None
    • b47



        This change introduces a new compressed oop mode "disjoint base" for heaps with base != 0.
        Currently, if the heap can not
        be allocated at a location where the end of the heap is smaller than OopEncodingHeapMax,
        all decode and encode operations must add/subtract the heap base. On x86, this can
        be handled in the powerful memory operands of this platform. On PPC (and other platforms)
        two instructions and two cycles are needed to decode an oop: shift and add/sub.

        In disjoint base mode, this can be reduced to one cycle on the critical path. This accounts
        for 2% jvm98 performance on PPC64.

        The disjoint base mode chooses the heap base so that it contains only bits
        at the positions 36-64. This way, the shifted compressed oop can be merged with an 'or'
        operation with the heap base. On PPC a shift-and-or operation exist. Thus, an oop
        can be decoded with one cycle in the critical path from a load operation to
        the use of the oop.

                   "heap based" "disjoint base"

        cycle 1: r1 = load r1 = load; r2 = rHeapBase
        cycle 2: r2 = r1 << 3 r3 = r2 | (r1 << 3)
        cycle 3: r3 = r1 + rHeapBase

        Encodes can be performed with a single shift. There is no need for a null check,
        as the lower 35 bits are not touched when subtracting the base, so the sub can
        be omitted.

        For the disjoint base mode, the noaccess prefix must be handled a bit differently.
        Subtracting a single page from the start of the heap results in a heap base that
        is not disjoint.

        PrintCompressedOopsMode prints the following text in disjoint base and heap based mode:

        heap address: 0x0000000800200000, size: 32 MB, Compressed Oops mode: Non-zero disjoint base: 0x0000000800000000, Oop shift amount: 3
        heap address: 0x00000011c0000000, size: 32 MB, Compressed Oops mode: Non-zero based: 0x00000011bfe00000, Oop shift amount: 3

        Further the change cleans up the 3 tries to get a heap for the existing modes unscaled, zerobased
        and heapbased. So far, this happens in a 3-fold if-cascade calling preferred_heap_base.
        The operation of preferred_heap_base isn't very obvious, as, e.g., it can return addresses for unscaled
        mode if called with argument ZeroBasedNarrowOop. Not always the best heap is found. Adding a new mode
        makes it even more complicated.

        The new code checks more addresses, only calling into the os layer to find a region where the
        heap could be allocated. This increases the probability of finding a heap in the lower regions.
        It then only once calls into the VirtualSpace constructor. To assure no overhead is imposed on
        the platforms supported by Oracle, the number of tries can be adapted by HeapSearchSteps which
        is set to 1 by default.

        This new algorithm makes it possible to find zero based heaps on Solaris 5.11.
        Also, it finds unscaled and zero based heaps on AIX.

        This change also simplifies handling of setting narrow_oop_use_implicit_null_checks(). Before, this
        was set in two places before allocating the heap. Now it's set right where the noaccess_prefix
        is protected. PrintCompressedOopsMode is extended to print when it's off.

        To more efficiently run expensive tests in various compressed oop modes, we set a property
        with the mode the VM is running in. So far it's called "com.sap.vm.test.compressedOopsMode"
        better suggestions are welcome (and necessary I guess). Our long running tests that are
        supposed to run in a dedicated compressed oop mode check this property and abort themselves
        if it's not the expected mode.

        This change contains a fix for platforms where the page at address 0 is not read protected.
        In this case, we want that matcher::gen_narrow_oop_implicit_null_checks() returns true.

        The change also adapts the corresponding tests.


          Issue Links



                goetz Goetz Lindenmaier
                goetz Goetz Lindenmaier
                0 Vote for this issue
                2 Start watching this issue