8282621: G1: G1SegmentedArray remove unnecessary template parameter

Reviewed-by: kbarrett, tschatzl
This commit is contained in:
Ivan Walulya 2022-03-07 15:05:42 +00:00
parent 104e3cb24b
commit e544e354a4
5 changed files with 70 additions and 97 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2022, 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
@ -30,10 +30,9 @@
#include "runtime/atomic.hpp"
#include "utilities/ostream.hpp"
template <class Slot>
G1CardSetAllocator<Slot>::G1CardSetAllocator(const char* name,
const G1CardSetAllocOptions* alloc_options,
G1CardSetFreeList* free_segment_list) :
G1CardSetAllocator::G1CardSetAllocator(const char* name,
const G1CardSetAllocOptions* alloc_options,
G1CardSetFreeList* free_segment_list) :
_segmented_array(alloc_options, free_segment_list),
_free_slots_list(name, &_segmented_array)
{
@ -41,26 +40,38 @@ G1CardSetAllocator<Slot>::G1CardSetAllocator(const char* name,
assert(slot_size >= sizeof(G1CardSetContainer), "Slot instance size %u for allocator %s too small", slot_size, name);
}
template <class Slot>
G1CardSetAllocator<Slot>::~G1CardSetAllocator() {
G1CardSetAllocator::~G1CardSetAllocator() {
drop_all();
}
template <class Slot>
void G1CardSetAllocator<Slot>::free(Slot* slot) {
void G1CardSetAllocator::free(void* slot) {
assert(slot != nullptr, "precondition");
slot->~Slot();
_free_slots_list.release(slot);
}
template <class Slot>
void G1CardSetAllocator<Slot>::drop_all() {
void G1CardSetAllocator::drop_all() {
_free_slots_list.reset();
_segmented_array.drop_all();
}
template <class Slot>
void G1CardSetAllocator<Slot>::print(outputStream* os) {
size_t G1CardSetAllocator::mem_size() const {
return sizeof(*this) +
_segmented_array.num_segments() * sizeof(G1CardSetSegment) +
_segmented_array.num_available_slots() * _segmented_array.slot_size();
}
size_t G1CardSetAllocator::wasted_mem_size() const {
uint num_wasted_slots = _segmented_array.num_available_slots() -
_segmented_array.num_allocated_slots() -
(uint)_free_slots_list.pending_count();
return num_wasted_slots * _segmented_array.slot_size();
}
uint G1CardSetAllocator::num_segments() const {
return _segmented_array.num_segments();
}
void G1CardSetAllocator::print(outputStream* os) {
uint num_allocated_slots = _segmented_array.num_allocated_slots();
uint num_available_slots = _segmented_array.num_available_slots();
uint highest = _segmented_array.first_array_segment() != nullptr
@ -82,13 +93,13 @@ void G1CardSetAllocator<Slot>::print(outputStream* os) {
G1CardSetMemoryManager::G1CardSetMemoryManager(G1CardSetConfiguration* config,
G1CardSetFreePool* free_list_pool) : _config(config) {
_allocators = NEW_C_HEAP_ARRAY(G1CardSetAllocator<G1CardSetContainer>,
_allocators = NEW_C_HEAP_ARRAY(G1CardSetAllocator,
_config->num_mem_object_types(),
mtGC);
for (uint i = 0; i < num_mem_object_types(); i++) {
new (&_allocators[i]) G1CardSetAllocator<G1CardSetContainer>(_config->mem_object_type_name_str(i),
_config->mem_object_alloc_options(i),
free_list_pool->free_list(i));
new (&_allocators[i]) G1CardSetAllocator(_config->mem_object_type_name_str(i),
_config->mem_object_alloc_options(i),
free_list_pool->free_list(i));
}
}
@ -106,7 +117,7 @@ G1CardSetMemoryManager::~G1CardSetMemoryManager() {
void G1CardSetMemoryManager::free(uint type, void* value) {
assert(type < num_mem_object_types(), "must be");
_allocators[type].free((G1CardSetContainer*)value);
_allocators[type].free(value);
}
void G1CardSetMemoryManager::flush() {
@ -127,9 +138,8 @@ size_t G1CardSetMemoryManager::mem_size() const {
for (uint i = 0; i < num_mem_object_types(); i++) {
result += _allocators[i].mem_size();
}
return sizeof(*this) -
(sizeof(G1CardSetAllocator<G1CardSetContainer>) * num_mem_object_types()) +
result;
return sizeof(*this) + result -
(sizeof(G1CardSetAllocator) * num_mem_object_types());
}
size_t G1CardSetMemoryManager::wasted_mem_size() const {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2022, 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
@ -62,37 +62,12 @@ typedef G1SegmentedArraySegment<mtGCCardSet> G1CardSetSegment;
typedef G1SegmentedArrayFreeList<mtGCCardSet> G1CardSetFreeList;
// Arena-like allocator for (card set) heap memory objects (Slot slots).
// Arena-like allocator for (card set) heap memory objects.
//
// Allocation and deallocation in the first phase on G1CardSetContainer basis
// may occur by multiple threads at once.
//
// Allocation occurs from an internal free list of G1CardSetContainers first,
// only then trying to bump-allocate from the current G1CardSetSegment. If there is
// none, this class allocates a new G1CardSetSegment (allocated from the C heap,
// asking the G1CardSetAllocOptions instance about sizes etc) and uses that one.
//
// The SegmentStack free list is a linked list of G1CardSetContainers
// within all G1CardSetSegment instances allocated so far. It uses a separate
// pending list and global synchronization to avoid the ABA problem when the
// user frees a memory object.
//
// The class also manages a few counters for statistics using atomic operations.
// Their values are only consistent within each other with extra global
// synchronization.
//
// Since it is expected that every CardSet (and in extension each region) has its
// own set of allocators, there is intentionally no padding between them to save
// memory.
template <class Slot>
// Allocation occurs from an internal free list of objects first. If the free list is
// empty then tries to allocate from the G1SegmentedArray.
class G1CardSetAllocator {
// G1CardSetSegment management.
typedef G1SegmentedArray<Slot, mtGCCardSet> SegmentedArray;
// G1CardSetContainer slot management within the G1CardSetSegments allocated
// by this allocator.
SegmentedArray _segmented_array;
G1SegmentedArray<mtGCCardSet> _segmented_array;
FreeListAllocator _free_slots_list;
public:
@ -101,27 +76,18 @@ public:
G1CardSetFreeList* free_segment_list);
~G1CardSetAllocator();
Slot* allocate();
void free(Slot* slot);
void* allocate();
void free(void* slot);
// Deallocate all segments to the free segment list and reset this allocator. Must
// be called in a globally synchronized area.
void drop_all();
size_t mem_size() const {
return sizeof(*this) +
_segmented_array.num_segments() * sizeof(G1CardSetSegment) +
_segmented_array.num_available_slots() * _segmented_array.slot_size();
}
size_t mem_size() const;
size_t wasted_mem_size() const {
uint num_wasted_slots = _segmented_array.num_available_slots() -
_segmented_array.num_allocated_slots() -
(uint)_free_slots_list.pending_count();
return num_wasted_slots * _segmented_array.slot_size();
}
size_t wasted_mem_size() const;
inline uint num_segments() { return _segmented_array.num_segments(); }
uint num_segments() const;
void print(outputStream* os);
};
@ -131,7 +97,7 @@ typedef G1SegmentedArrayFreePool<mtGCCardSet> G1CardSetFreePool;
class G1CardSetMemoryManager : public CHeapObj<mtGCCardSet> {
G1CardSetConfiguration* _config;
G1CardSetAllocator<G1CardSetContainer>* _allocators;
G1CardSetAllocator* _allocators;
uint num_mem_object_types() const;
public:

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2022, 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
@ -26,16 +26,13 @@
#define SHARE_GC_G1_G1CARDSETMEMORY_INLINE_HPP
#include "gc/g1/g1CardSetMemory.hpp"
#include "gc/g1/g1CardSetContainers.hpp"
#include "gc/g1/g1CardSetContainers.inline.hpp"
#include "gc/g1/g1SegmentedArray.inline.hpp"
#include "utilities/globalCounter.inline.hpp"
#include "utilities/ostream.hpp"
#include "gc/g1/g1CardSetContainers.inline.hpp"
#include "utilities/globalCounter.inline.hpp"
template <class Slot>
Slot* G1CardSetAllocator<Slot>::allocate() {
Slot* slot = ::new (_free_slots_list.allocate()) Slot();
inline void* G1CardSetAllocator::allocate() {
void* slot = _free_slots_list.allocate();
assert(slot != nullptr, "must be");
return slot;
}

View File

@ -181,7 +181,7 @@ public:
// The class also manages a few counters for statistics using atomic operations.
// Their values are only consistent within each other with extra global
// synchronization.
template <class Slot, MEMFLAGS flag>
template <MEMFLAGS flag>
class G1SegmentedArray : public FreeListConfig {
// G1SegmentedArrayAllocOptions provides parameters for allocation segment
// sizing and expansion.

View File

@ -115,8 +115,8 @@ void G1SegmentedArrayFreeList<flag>::free_all() {
Atomic::sub(&_mem_size, mem_size_freed, memory_order_relaxed);
}
template <class Slot, MEMFLAGS flag>
G1SegmentedArraySegment<flag>* G1SegmentedArray<Slot, flag>::create_new_segment(G1SegmentedArraySegment<flag>* const prev) {
template <MEMFLAGS flag>
G1SegmentedArraySegment<flag>* G1SegmentedArray<flag>::create_new_segment(G1SegmentedArraySegment<flag>* const prev) {
// Take an existing segment if available.
G1SegmentedArraySegment<flag>* next = _free_segment_list->get();
if (next == nullptr) {
@ -125,7 +125,7 @@ G1SegmentedArraySegment<flag>* G1SegmentedArray<Slot, flag>::create_new_segment(
next = new G1SegmentedArraySegment<flag>(slot_size(), num_slots, prev);
} else {
assert(slot_size() == next->slot_size() ,
"Mismatch %d != %d Slot %zu", slot_size(), next->slot_size(), sizeof(Slot));
"Mismatch %d != %d", slot_size(), next->slot_size());
next->reset(prev);
}
@ -148,14 +148,14 @@ G1SegmentedArraySegment<flag>* G1SegmentedArray<Slot, flag>::create_new_segment(
}
}
template <class Slot, MEMFLAGS flag>
uint G1SegmentedArray<Slot, flag>::slot_size() const {
template <MEMFLAGS flag>
uint G1SegmentedArray<flag>::slot_size() const {
return _alloc_options->slot_size();
}
template <class Slot, MEMFLAGS flag>
G1SegmentedArray<Slot, flag>::G1SegmentedArray(const G1SegmentedArrayAllocOptions* alloc_options,
G1SegmentedArrayFreeList<flag>* free_segment_list) :
template <MEMFLAGS flag>
G1SegmentedArray<flag>::G1SegmentedArray(const G1SegmentedArrayAllocOptions* alloc_options,
G1SegmentedArrayFreeList<flag>* free_segment_list) :
_alloc_options(alloc_options),
_first(nullptr),
_last(nullptr),
@ -167,13 +167,13 @@ G1SegmentedArray<Slot, flag>::G1SegmentedArray(const G1SegmentedArrayAllocOption
assert(_free_segment_list != nullptr, "precondition!");
}
template <class Slot, MEMFLAGS flag>
G1SegmentedArray<Slot, flag>::~G1SegmentedArray() {
template <MEMFLAGS flag>
G1SegmentedArray<flag>::~G1SegmentedArray() {
drop_all();
}
template <class Slot, MEMFLAGS flag>
void G1SegmentedArray<Slot, flag>::drop_all() {
template <MEMFLAGS flag>
void G1SegmentedArray<flag>::drop_all() {
G1SegmentedArraySegment<flag>* cur = Atomic::load_acquire(&_first);
if (cur != nullptr) {
@ -209,8 +209,8 @@ void G1SegmentedArray<Slot, flag>::drop_all() {
_num_allocated_slots = 0;
}
template <class Slot, MEMFLAGS flag>
void* G1SegmentedArray<Slot, flag>::allocate() {
template <MEMFLAGS flag>
void* G1SegmentedArray<flag>::allocate() {
assert(slot_size() > 0, "instance size not set.");
G1SegmentedArraySegment<flag>* cur = Atomic::load_acquire(&_first);
@ -219,7 +219,7 @@ void* G1SegmentedArray<Slot, flag>::allocate() {
}
while (true) {
Slot* slot = (Slot*)cur->get_new_slot();
void* slot = cur->get_new_slot();
if (slot != nullptr) {
Atomic::inc(&_num_allocated_slots, memory_order_relaxed);
guarantee(is_aligned(slot, _alloc_options->slot_alignment()),
@ -232,8 +232,8 @@ void* G1SegmentedArray<Slot, flag>::allocate() {
}
}
template <class Slot, MEMFLAGS flag>
inline uint G1SegmentedArray<Slot, flag>::num_segments() const {
template <MEMFLAGS flag>
inline uint G1SegmentedArray<flag>::num_segments() const {
return Atomic::load(&_num_segments);
}
@ -251,17 +251,17 @@ public:
}
};
template <class Slot, MEMFLAGS flag>
uint G1SegmentedArray<Slot, flag>::calculate_length() const {
template <MEMFLAGS flag>
uint G1SegmentedArray<flag>::calculate_length() const {
LengthClosure<flag> closure;
iterate_segments(closure);
return closure.length();
}
#endif
template <class Slot, MEMFLAGS flag>
template <MEMFLAGS flag>
template <typename SegmentClosure>
void G1SegmentedArray<Slot, flag>::iterate_segments(SegmentClosure& closure) const {
void G1SegmentedArray<flag>::iterate_segments(SegmentClosure& closure) const {
G1SegmentedArraySegment<flag>* cur = Atomic::load_acquire(&_first);
assert((cur != nullptr) == (_last != nullptr),