8282621: G1: G1SegmentedArray remove unnecessary template parameter
Reviewed-by: kbarrett, tschatzl
This commit is contained in:
parent
104e3cb24b
commit
e544e354a4
@ -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 {
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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),
|
||||
|
Loading…
x
Reference in New Issue
Block a user