Skip to content


Browse files Browse the repository at this point in the history
8275704: Metaspace::contains() should be threadsafe
Backport-of: d9b0138d7d02ceddc5d9c73908177f0b0d2e7c54
  • Loading branch information
tstuefe committed Jan 30, 2023
1 parent b22bce8 commit 4a9bd23
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
12 changes: 8 additions & 4 deletions src/hotspot/share/memory/metaspace/virtualSpaceList.cpp
Expand Up @@ -34,6 +34,7 @@
#include "memory/metaspace/metaspaceCommon.hpp"
#include "memory/metaspace/virtualSpaceList.hpp"
#include "memory/metaspace/virtualSpaceNode.hpp"
#include "runtime/atomic.hpp"
#include "runtime/mutexLocker.hpp"

namespace metaspace {
Expand Down Expand Up @@ -74,8 +75,10 @@ VirtualSpaceList::VirtualSpaceList(const char* name, ReservedSpace rs, CommitLim

VirtualSpaceList::~VirtualSpaceList() {
// Note: normally, there is no reason ever to delete a vslist since they are
// global objects, but for gtests it makes sense to allow this.
// Delete every single mapping in this list.
// Please note that this only gets executed during gtests under controlled
// circumstances, so we do not have any concurrency issues here. The "real"
// lists in metaspace are immortal.
VirtualSpaceNode* vsn = _first_node;
VirtualSpaceNode* vsn2 = vsn;
while (vsn != NULL) {
Expand All @@ -96,7 +99,7 @@ void VirtualSpaceList::create_new_node() {
&_reserved_words_counter, &_committed_words_counter);
_first_node = vsn;
Atomic::release_store(&_first_node, vsn);

Expand Down Expand Up @@ -186,7 +189,8 @@ void VirtualSpaceList::verify() const {

// Returns true if this pointer is contained in one of our nodes.
bool VirtualSpaceList::contains(const MetaWord* p) const {
const VirtualSpaceNode* vsn = _first_node;
// Note: needs to work without locks.
const VirtualSpaceNode* vsn = Atomic::load_acquire(&_first_node);
while (vsn != NULL) {
if (vsn->contains(p)) {
return true;
Expand Down
18 changes: 14 additions & 4 deletions src/hotspot/share/memory/metaspace/virtualSpaceList.hpp
Expand Up @@ -40,22 +40,32 @@ namespace metaspace {
class Metachunk;
class FreeChunkListVector;

// VirtualSpaceList manages a single (if its non-expandable) or
// a series of (if its expandable) virtual memory regions used
// VirtualSpaceList manages a series of virtual memory regions used
// for metaspace.
// Internally it holds a list of nodes (VirtualSpaceNode) each
// managing a single contiguous memory region. The first node of
// this list is the current node and used for allocation of new
// root chunks.
// The list will only ever grow, never shrink. It will be immortal,
// never to be destroyed.
// The list will only be modified under lock protection, but may be
// read concurrently without lock.
// The list may be prevented from expanding beyond a single node -
// in that case it degenerates to a one-node-list (used for
// class space).

class VirtualSpaceList : public CHeapObj<mtClass> {

// Name
const char* const _name;

// Head of the list.
VirtualSpaceNode* _first_node;
// Head of the list (last added).
VirtualSpaceNode* volatile _first_node;

// Number of nodes (kept for statistics only).
IntCounter _nodes_counter;
Expand Down

1 comment on commit 4a9bd23

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.