mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-13 15:09:39 +00:00
8275704: Metaspace::contains() should be threadsafe
Reviewed-by: coleenp, dholmes
This commit is contained in:
parent
9a3e954299
commit
d9b0138d7d
@ -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 {
|
||||
@ -74,8 +75,10 @@ VirtualSpaceList::VirtualSpaceList(const char* name, ReservedSpace rs, CommitLim
|
||||
|
||||
VirtualSpaceList::~VirtualSpaceList() {
|
||||
assert_lock_strong(Metaspace_lock);
|
||||
// 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) {
|
||||
@ -96,7 +99,7 @@ void VirtualSpaceList::create_new_node() {
|
||||
_commit_limiter,
|
||||
&_reserved_words_counter, &_committed_words_counter);
|
||||
vsn->set_next(_first_node);
|
||||
_first_node = vsn;
|
||||
Atomic::release_store(&_first_node, vsn);
|
||||
_nodes_counter.increment();
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user