/* * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, 2022, Huawei Technologies Co., Ltd. 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
// A G1MonotonicArena extends the FreeListConfig, memory // blocks allocated from the OS are managed as a linked-list of Segments. // // Implementation details as below: // // Allocation arena for (card set, or ...) heap memory objects (Slot slots). // // Actual allocation from the C heap occurs as memory blocks called Segments. // The allocation pattern for these Segments is assumed to be strictly two-phased: // // - in the first phase, Segments are allocated from the C heap (or a free // list given at initialization time). This allocation may occur in parallel. This // typically corresponds to a single mutator phase, but may extend over multiple. // // - in the second phase, Segments are added in bulk to the free list. // This is typically done during a GC pause. // // Some third party is responsible for giving back memory from the free list to // the operating system. // // Allocation and deallocation in the first phase basis may occur by multiple threads concurrently. // // The class also manages a few counters for statistics using atomic operations. // Their values are only consistent within each other with extra global // synchronization. class G1MonotonicArena : public FreeListConfig { public: class AllocOptions; class Segment; class SegmentFreeList; private: // AllocOptions provides parameters for Segment sizing and expansion. const AllocOptions* _alloc_options;
Segment* volatile _first; // The (start of the) list of all segments.
Segment* _last; // The last segment of the list of all segments. volatile uint _num_segments; // Number of assigned segments to this allocator. volatile size_t _mem_size; // Memory used by all segments.
SegmentFreeList* _segment_free_list; // The global free segment list to preferentially // get new segments from.
volatile uint _num_total_slots; // Number of slots available in all segments (allocated + not yet used). volatile uint _num_allocated_slots; // Number of total slots allocated ever (including free and pending).
// Deallocate all segments to the free segment list and reset this allocator. Must // be called in a globally synchronized area. void drop_all();
uint num_segments() const;
template<typename SegmentClosure> void iterate_segments(SegmentClosure& closure) const; protected: void* allocate() override; // We do not deallocate individual slots void deallocate(void* slot) override { ShouldNotReachHere(); }
};
// A single segment/arena containing _num_slots blocks of memory of _slot_size. // Segments can be linked together using a singly linked list. class G1MonotonicArena::Segment { const uint _slot_size; const uint _num_slots;
Segment* volatile _next; // Index into the next free slot to allocate into. Full if equal (or larger) // to _num_slots (can be larger because we atomically increment this value and // check only afterwards if the allocation has been successful).
uint volatile _next_allocate; const MEMFLAGS _mem_flag;
char* _bottom; // Actual data. // Do not add class member variables beyond this point
// Set of (free) Segments. The assumed usage is that allocation // to it and removal of segments is strictly separate, but every action may be // performed by multiple threads concurrently. // Counts and memory usage are current on a best-effort basis if accessed concurrently. class G1MonotonicArena::SegmentFreeList { static Segment* volatile* next_ptr(Segment& segment) { return segment.next_addr();
} using SegmentStack = LockFreeStack<Segment, &SegmentFreeList::next_ptr>;
// Configuration for G1MonotonicArena, e.g slot size, slot number of next Segment. class G1MonotonicArena::AllocOptions {
protected: const MEMFLAGS _mem_flag; const uint _slot_size; const uint _initial_num_slots; // Defines a limit to the number of slots in the segment const uint _max_num_slots; const uint _slot_alignment;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.