mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-14 18:03:44 +00:00
8285984: G1: Use standard idiom for inlined payload in G1MonotonicArena::Segment
Reviewed-by: aboldtch, tschatzl
This commit is contained in:
parent
3c6ef5e27a
commit
bf726e8217
@ -34,7 +34,7 @@ G1MonotonicArena::Segment::Segment(uint slot_size, uint num_slots, Segment* next
|
||||
_next(next),
|
||||
_next_allocate(0),
|
||||
_mem_tag(mem_tag) {
|
||||
_bottom = ((char*) this) + header_size();
|
||||
guarantee(is_aligned(this, SegmentPayloadMaxAlignment), "Make sure Segments are always created at correctly aligned memory");
|
||||
}
|
||||
|
||||
G1MonotonicArena::Segment* G1MonotonicArena::Segment::create_segment(uint slot_size,
|
||||
|
||||
@ -110,9 +110,10 @@ protected:
|
||||
void deallocate(void* slot) override { ShouldNotReachHere(); }
|
||||
};
|
||||
|
||||
static constexpr uint SegmentPayloadMaxAlignment = 8;
|
||||
// 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 {
|
||||
class alignas(SegmentPayloadMaxAlignment) G1MonotonicArena::Segment {
|
||||
const uint _slot_size;
|
||||
const uint _num_slots;
|
||||
Segment* volatile _next;
|
||||
@ -122,16 +123,15 @@ class G1MonotonicArena::Segment {
|
||||
uint volatile _next_allocate;
|
||||
const MemTag _mem_tag;
|
||||
|
||||
char* _bottom; // Actual data.
|
||||
// Do not add class member variables beyond this point
|
||||
|
||||
static size_t header_size() { return align_up(sizeof(Segment), DEFAULT_PADDING_SIZE); }
|
||||
static size_t header_size() { return align_up(sizeof(Segment), SegmentPayloadMaxAlignment); }
|
||||
|
||||
static size_t payload_size(uint slot_size, uint num_slots) {
|
||||
// The cast (size_t) is required to guard against overflow wrap around.
|
||||
return (size_t)slot_size * num_slots;
|
||||
// The cast is required to guard against overflow wrap around.
|
||||
return static_cast<size_t>(slot_size) * num_slots;
|
||||
}
|
||||
|
||||
void* payload(size_t octet) { return &reinterpret_cast<char*>(this)[header_size() + octet]; }
|
||||
|
||||
size_t payload_size() const { return payload_size(_slot_size, _num_slots); }
|
||||
|
||||
NONCOPYABLE(Segment);
|
||||
@ -156,7 +156,7 @@ public:
|
||||
_next_allocate = 0;
|
||||
assert(next != this, " loop condition");
|
||||
set_next(next);
|
||||
memset((void*)_bottom, 0, payload_size());
|
||||
memset(payload(0), 0, payload_size());
|
||||
}
|
||||
|
||||
uint slot_size() const { return _slot_size; }
|
||||
@ -179,6 +179,7 @@ public:
|
||||
bool is_full() const { return _next_allocate >= _num_slots; }
|
||||
};
|
||||
|
||||
static_assert(alignof(G1MonotonicArena::Segment) >= SegmentPayloadMaxAlignment, "assert alignment of Segment (and indirectly its payload)");
|
||||
|
||||
// Set of (free) Segments. The assumed usage is that allocation
|
||||
// to it and removal of segments is strictly separate, but every action may be
|
||||
@ -235,6 +236,7 @@ public:
|
||||
assert(_initial_num_slots > 0, "Must be");
|
||||
assert(_max_num_slots > 0, "Must be");
|
||||
assert(_slot_alignment > 0, "Must be");
|
||||
assert(SegmentPayloadMaxAlignment % _slot_alignment == 0, "ensure that _slot_alignment is a divisor of SegmentPayloadMaxAlignment");
|
||||
}
|
||||
|
||||
virtual uint next_num_slots(uint prev_num_slots) const {
|
||||
|
||||
@ -39,7 +39,7 @@ inline void* G1MonotonicArena::Segment::allocate_slot() {
|
||||
if (result >= _num_slots) {
|
||||
return nullptr;
|
||||
}
|
||||
void* r = _bottom + (size_t)result * _slot_size;
|
||||
void* r = payload(static_cast<size_t>(result) * _slot_size);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user