Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions src/hotspot/share/gc/shared/stringdedup/stringDedupProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
#include "memory/iterator.hpp"
#include "nmt/memTag.hpp"
#include "oops/access.inline.hpp"
#include "runtime/atomicAccess.hpp"
#include "runtime/cpuTimeCounters.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/mutexLocker.hpp"
Expand All @@ -46,17 +45,17 @@

OopStorage* StringDedup::Processor::_storages[2] = {};

StringDedup::StorageUse* volatile StringDedup::Processor::_storage_for_requests = nullptr;
DeferredStatic<Atomic<StringDedup::StorageUse*>> StringDedup::Processor::_storage_for_requests{};
StringDedup::StorageUse* StringDedup::Processor::_storage_for_processing = nullptr;

void StringDedup::Processor::initialize_storage() {
assert(_storages[0] == nullptr, "storage already created");
assert(_storages[1] == nullptr, "storage already created");
assert(_storage_for_requests == nullptr, "storage already created");
assert(_storage_for_processing == nullptr, "storage already created");
_storages[0] = OopStorageSet::create_weak("StringDedup Requests0 Weak", mtStringDedup);
_storages[1] = OopStorageSet::create_weak("StringDedup Requests1 Weak", mtStringDedup);
_storage_for_requests = new StorageUse(_storages[0]);
auto sfr = new StorageUse(_storages[0]); // Work around lack of std::forward.
_storage_for_requests.initialize(sfr);
_storage_for_processing = new StorageUse(_storages[1]);
}

Expand All @@ -75,15 +74,15 @@ void StringDedup::Processor::wait_for_requests() const {
{
ThreadBlockInVM tbivm(_thread);
MonitorLocker ml(StringDedup_lock, Mutex::_no_safepoint_check_flag);
OopStorage* storage = AtomicAccess::load(&_storage_for_requests)->storage();
OopStorage* storage = _storage_for_requests->load_relaxed()->storage();
while ((storage->allocation_count() == 0) &&
!Table::is_dead_entry_removal_needed()) {
ml.wait();
}
}
// Swap the request and processing storage objects.
log_trace(stringdedup)("swapping request storages");
_storage_for_processing = AtomicAccess::xchg(&_storage_for_requests, _storage_for_processing);
_storage_for_processing = _storage_for_requests->exchange(_storage_for_processing);
GlobalCounter::write_synchronize();
// Wait for the now current processing storage object to no longer be used
// by an in-progress GC. Again here, the num-dead notification from the
Expand All @@ -99,7 +98,7 @@ void StringDedup::Processor::wait_for_requests() const {
}

StringDedup::StorageUse* StringDedup::Processor::storage_for_requests() {
return StorageUse::obtain(&_storage_for_requests);
return StorageUse::obtain(_storage_for_requests.get());
}

void StringDedup::Processor::yield() const {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -27,7 +27,9 @@

#include "gc/shared/stringdedup/stringDedup.hpp"
#include "memory/allocation.hpp"
#include "runtime/atomic.hpp"
#include "services/cpuTimeUsage.hpp"
#include "utilities/deferredStatic.hpp"
#include "utilities/macros.hpp"

class JavaThread;
Expand All @@ -51,7 +53,7 @@ class StringDedup::Processor : public CHeapObj<mtGC> {
NONCOPYABLE(Processor);

static OopStorage* _storages[2];
static StorageUse* volatile _storage_for_requests;
static DeferredStatic<Atomic<StorageUse*>> _storage_for_requests;
Copy link
Member

Choose a reason for hiding this comment

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

What is the reason for the DeferredStatic?

Is it just for the init once semantics and asserts?

Is this a style we should adapt more broadly for our init once static variables?

static StorageUse* _storage_for_processing;

JavaThread* _thread;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
*/

#include "gc/shared/stringdedup/stringDedupStorageUse.hpp"
#include "runtime/atomicAccess.hpp"
#include "runtime/javaThread.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalCounter.inline.hpp"
Expand All @@ -34,18 +33,18 @@ StringDedup::StorageUse::StorageUse(OopStorage* storage) :
{}

bool StringDedup::StorageUse::is_used_acquire() const {
return AtomicAccess::load_acquire(&_use_count) > 0;
return _use_count.load_acquire() > 0;
}

StringDedup::StorageUse*
StringDedup::StorageUse::obtain(StorageUse* volatile* ptr) {
StringDedup::StorageUse::obtain(Atomic<StorageUse*>* ptr) {
GlobalCounter::CriticalSection cs(Thread::current());
StorageUse* storage = AtomicAccess::load(ptr);
AtomicAccess::inc(&storage->_use_count);
StorageUse* storage = ptr->load_relaxed();
storage->_use_count.add_then_fetch(1u);
return storage;
}

void StringDedup::StorageUse::relinquish() {
size_t result = AtomicAccess::sub(&_use_count, size_t(1));
assert(result != SIZE_MAX, "use count underflow");
size_t result = _use_count.fetch_then_sub(1u);
assert(result != 0, "use count underflow");
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -27,6 +27,7 @@

#include "gc/shared/stringdedup/stringDedup.hpp"
#include "memory/allocation.hpp"
#include "runtime/atomic.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"

Expand All @@ -35,7 +36,7 @@ class OopStorage;
// Manage access to one of the OopStorage objects used for requests.
class StringDedup::StorageUse : public CHeapObj<mtStringDedup> {
OopStorage* const _storage;
volatile size_t _use_count;
Atomic<size_t> _use_count;

NONCOPYABLE(StorageUse);

Expand All @@ -48,7 +49,7 @@ class StringDedup::StorageUse : public CHeapObj<mtStringDedup> {
bool is_used_acquire() const;

// Get the current requests object, and increment its in-use count.
static StorageUse* obtain(StorageUse* volatile* ptr);
static StorageUse* obtain(Atomic<StorageUse*>* ptr);

// Discard a prior "obtain" request, decrementing the in-use count, and
// permitting the deduplication thread to start processing if needed.
Expand Down