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

PLAB reallocation might result in failure to allocate object in that recently allocated PLAB

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: 9
    • Fix Version/s: 9
    • Component/s: hotspot
    • Subcomponent:
      gc
    • Resolved In Build:
      b81

      Backports

        Description

        During fixing of related problems I noticed that it is possible that when trying to allocate a new PLAB for a given allocation, the allocator algorithm may return a buffer that is too small for the object, resulting in premature evacuation failure.

        The problem occurs because when allocating a new PLAB, not all memory is actually usable for allocation within the PLAB, but only the buffer size minus an alignment reserve.

        This situation is asserted, so it seems to occur rarely (and is ignored in product mode).

        Here is some commented code.

        HeapWord* G1ParGCAllocator::allocate_slow(GCAllocPurpose purpose, size_t word_sz, AllocationContext_t context) {
          HeapWord* obj = NULL;
          size_t gclab_word_size = _g1h->desired_plab_sz(purpose);
          if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
            G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose, context);
            add_to_alloc_buffer_waste(alloc_buf->words_remaining());
            alloc_buf->retire(false /* end_of_gc */, false /* retain */);

            HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size, context);

            ^^---- allocate a buffer of gclab_word_size

            if (buf == NULL) {
              return NULL; // Let caller handle allocation failure.
            }
            // Otherwise.
            alloc_buf->set_word_size(gclab_word_size);
            alloc_buf->set_buf(buf);

            obj = alloc_buf->allocate(word_sz);

           ^^---- try to allocate word_sz in the PLAB. Since there actually is only plab_word_sz - ParGCAllocBuffer::AlignmentReserve space for allocation, allocation may actually fail.

            assert(obj != NULL, "buffer was definitely big enough...");
          } else {
            obj = _g1h->par_allocate_during_gc(purpose, word_sz, context);
          }
          return obj;
        }

          Attachments

            Issue Links

              Activity

                People

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

                  Dates

                  • Created:
                    Updated:
                    Resolved: