JDK-8306832 : Metaspace: deallocate should not adjust up the deallocated size
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 17,20,21
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2023-04-25
  • Updated: 2023-05-16
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.
Other
tbdUnresolved
Related Reports
Relates :  
Description
When deallocating memory to metaspace, we wrongly adjust the returned size before adding the block to the freeblocks:

```
// Prematurely returns a metaspace allocation to the _block_freelists
// because it is not needed anymore (requires CLD lock to be active).
void MetaspaceArena::deallocate_locked(MetaWord* p, size_t word_size) {
  assert_lock_strong(lock());
  // At this point a current chunk must exist since we only deallocate if we did allocate before.
  assert(current_chunk() != nullptr, "stray deallocation?");
  assert(is_valid_area(p, word_size),
         "Pointer range not part of this Arena and cannot be deallocated: (" PTR_FORMAT ".." PTR_FORMAT ").",
         p2i(p), p2i(p + word_size));

  UL2(trace, "deallocating " PTR_FORMAT ", word size: " SIZE_FORMAT ".",
      p2i(p), word_size);

  size_t raw_word_size = get_raw_word_size_for_requested_word_size(word_size);  <<<<<<
  add_allocation_to_fbl(p, raw_word_size);

  DEBUG_ONLY(verify_locked();)
}
```

The block size is adjusted in get_raw_word_size_for_requested_word_size to fit the size of a freeblocks block, which is 2 words. Therefore, if the caller wanted to return a single word, we would now possibly overwrite the following block, or it would overwrite the next slot in the freeblocks binlist.

This is purely theoretical as long as the user just deallocates whatever blocks he retrieved from metaspace since the allocation path does the same adjustment. The original intent was to mimic what the metaspace does on the allocation path (e.g. if user were to request 1 word, it would silently get 2, and if he would return the 1 word back via deallocate, we would correct this to hold 2 since we know better what we allocated internally). It becomes dangerous when one tries to deallocate parts of another block, as I attempt with Lilliput.
Comments
On second thought, maybe this is alright and works as intended, since this is the official deallocate path, companion to the official allocation path, which also does this size adjustment. So we do the size adjustment on the deallocation in the assumption that the block had been originally allocated via the official allocation path. Because we want to salvage the whole space. Only matters for 1-word-sized blocks, which may not exist anyway. Have to mull over this a bit more.
25-04-2023