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

Improve object array chunking test in G1's copy_to_survivor_space

    Details

    • Type: Enhancement
    • Status: Open
    • Priority: P4
    • Resolution: Unresolved
    • Affects Version/s: hs25, 8
    • Fix Version/s: tbd
    • Component/s: hotspot
    • Subcomponent:
      gc
    • Understanding:
      Fix Understood

      Backports

        Description

        All collectors including G1 treat object arrays special if they exceed a size of ParGCArrayScanChunk . Instead of pushing all elements of the object array on the work stack, the collectors only push part of it and the object array again with an indication that part of it still needs to be scanned.

        In the respective copy_to_survivor_space() methods, there is always a check whether this chunking is done or not. In case of G1 this check is relatively costly, while it has been optimized better in others.

        E.g. in g1CollectedHeap.cpp, copy_to_survivor_space()

            if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) {
              [... do chunking... ]
            } else {
              [ ... regular processing... ]
            }

        a slightly faster variant switches the two predicates, and replaces the arrayOop(obj)->length() with the "word_sz" variable we already retrieved anyway.

        I.e.

            if (word_sz >= ParGCArrayScanChunk && obj->is_objArray()) {

        additionally it's better to have the size check predicate first, as it is even more excluding than the other.

        Another particularity that should be fixed is the use of ParGCArrayScanChunk: it's a global that is typically located far away from the ParCopyClosure code, requiring extra pages etc. to be loaded in. VTune runs indicate that this is a relatively big issue (lots of cycles spent on this and surrounding instructions), as the G1 collector code is already touching too many places.

        The recommendation here is to put a copy of ParGCArrayScanChunk into a member variable of G1ParCopyClosure. This fixes this issue.

        I.e.

              if (word_sz >= _local_pargc_array_scan_chunk_sz && obj->is_objArray()) {


        There is a minor wrinkle with putting just ParGCArrayScanChunk into _local_pargc_array_scan_chunk_sz and comparing it with word_sz. Word_sz contains a slightly larger value than the original arrayOop(obj)->length(). Word_sz is the entire object size, while the arrayOop::length() call returns the number of elements in the array.

        Using the local _local_pargc_array_scan_chunk_sz this can be accounted for if needed.

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  Unassigned
                  Reporter:
                  tschatzl Thomas Schatzl
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  3 Start watching this issue

                  Dates

                  • Created:
                    Updated: