8221540: ZGC: Reduce width of zForwardingEntry::from_index field

Reviewed-by: stefank, eosterlund
This commit is contained in:
Per Lidén 2019-03-28 19:43:59 +01:00
parent 53c904df4a
commit 7a623e6e46
5 changed files with 33 additions and 33 deletions

@ -58,7 +58,7 @@ void ZForwarding::verify() const {
for (ZForwardingCursor i = 0; i < _entries.length(); i++) {
const ZForwardingEntry entry = at(&i);
if (entry.is_empty()) {
if (!entry.populated()) {
// Skip empty entries
continue;
}

@ -119,9 +119,9 @@ inline ZForwardingEntry ZForwarding::find(uintptr_t from_index) const {
inline ZForwardingEntry ZForwarding::find(uintptr_t from_index, ZForwardingCursor* cursor) const {
// Reading entries in the table races with the atomic CAS done for
// insertion into the table. This is safe because each entry is at
// most updated once (from -1 to something else).
// most updated once (from zero to something else).
ZForwardingEntry entry = first(from_index, cursor);
while (!entry.is_empty()) {
while (entry.populated()) {
if (entry.from_index() == from_index) {
// Match found, return matching entry
return entry;
@ -140,14 +140,14 @@ inline uintptr_t ZForwarding::insert(uintptr_t from_index, uintptr_t to_offset,
for (;;) {
const ZForwardingEntry prev_entry = Atomic::cmpxchg(new_entry, entries() + *cursor, old_entry);
if (prev_entry.is_empty()) {
if (!prev_entry.populated()) {
// Success
return to_offset;
}
// Find next empty or matching entry
ZForwardingEntry entry = at(cursor);
while (!entry.is_empty()) {
while (entry.populated()) {
if (entry.from_index() == from_index) {
// Match found, return already inserted address
return entry.to_offset();

@ -32,40 +32,40 @@
// Forwarding entry layout
// -----------------------
//
// 6 4 4 0
// 3 2 1 0
// +------------------------+-----------------------------------------------+
// |11111111 11111111 111111|11 11111111 11111111 11111111 11111111 11111111|
// +------------------------+-----------------------------------------------+
// | |
// | * 41-0 To Object Offset (42-bits)
// 6 4 4
// 3 6 5 1 0
// +--------------------+--------------------------------------------------+-+
// |11111111 11111111 11|111111 11111111 11111111 11111111 11111111 1111111|1|
// +--------------------+--------------------------------------------------+-+
// | | |
// | | 0-0 Populated Flag (1-bits) *
// | |
// | * 45-1 To Object Offset (45-bits)
// |
// * 63-42 From Object Index (22-bits)
// * 63-46 From Object Index (18-bits)
//
class ZForwardingEntry {
friend struct PrimitiveConversions;
private:
typedef ZBitField<uint64_t, size_t, 0, 42> field_to_offset;
typedef ZBitField<uint64_t, size_t, 42, 22> field_from_index;
typedef ZBitField<uint64_t, bool, 0, 1> field_populated;
typedef ZBitField<uint64_t, size_t, 1, 45> field_to_offset;
typedef ZBitField<uint64_t, size_t, 46, 18> field_from_index;
uint64_t _entry;
static uintptr_t empty() {
return (uintptr_t)-1;
}
public:
ZForwardingEntry() :
_entry(empty()) {}
_entry(0) {}
ZForwardingEntry(size_t from_index, size_t to_offset) :
_entry(field_from_index::encode(from_index) |
field_to_offset::encode(to_offset)) {}
_entry(field_populated::encode(true) |
field_to_offset::encode(to_offset) |
field_from_index::encode(from_index)) {}
bool is_empty() const {
return _entry == empty();
bool populated() const {
return field_populated::decode(_entry);
}
size_t to_offset() const {

@ -88,7 +88,7 @@ uintptr_t ZRelocate::relocate_object_inner(ZForwarding* forwarding, uintptr_t fr
// Lookup forwarding entry
const ZForwardingEntry entry = forwarding->find(from_index, &cursor);
if (entry.from_index() == from_index) {
if (entry.populated() && entry.from_index() == from_index) {
// Already relocated, return new address
return entry.to_offset();
}
@ -150,7 +150,9 @@ uintptr_t ZRelocate::forward_object(ZForwarding* forwarding, uintptr_t from_addr
const uintptr_t from_index = (from_offset - forwarding->start()) >> forwarding->object_alignment_shift();
const ZForwardingEntry entry = forwarding->find(from_index);
assert(entry.populated(), "Should be forwarded");
assert(entry.from_index() == from_index, "Should be forwarded");
return ZAddress::good(entry.to_offset());
}

@ -70,10 +70,8 @@ public:
for (uint32_t i = 0; i < entries_to_check; i++) {
uintptr_t from_index = SequenceToFromIndex::one_to_one(i);
EXPECT_TRUE(forwarding->find(from_index).is_empty()) << CAPTURE2(from_index, size);
EXPECT_FALSE(forwarding->find(from_index).populated()) << CAPTURE2(from_index, size);
}
EXPECT_TRUE(forwarding->find(uintptr_t(-1)).is_empty()) << CAPTURE(size);
}
static void find_full(ZForwarding* forwarding) {
@ -86,7 +84,7 @@ public:
ZForwardingCursor cursor;
ZForwardingEntry entry = forwarding->find(from_index, &cursor);
ASSERT_TRUE(entry.is_empty()) << CAPTURE2(from_index, size);
ASSERT_FALSE(entry.populated()) << CAPTURE2(from_index, size);
forwarding->insert(from_index, from_index, &cursor);
}
@ -96,7 +94,7 @@ public:
uintptr_t from_index = SequenceToFromIndex::one_to_one(i);
ZForwardingEntry entry = forwarding->find(from_index);
ASSERT_FALSE(entry.is_empty()) << CAPTURE2(from_index, size);
ASSERT_TRUE(entry.populated()) << CAPTURE2(from_index, size);
ASSERT_EQ(entry.from_index(), from_index) << CAPTURE(size);
ASSERT_EQ(entry.to_offset(), from_index) << CAPTURE(size);
@ -113,7 +111,7 @@ public:
ZForwardingCursor cursor;
ZForwardingEntry entry = forwarding->find(from_index, &cursor);
ASSERT_TRUE(entry.is_empty()) << CAPTURE2(from_index, size);
ASSERT_FALSE(entry.populated()) << CAPTURE2(from_index, size);
forwarding->insert(from_index, from_index, &cursor);
}
@ -124,7 +122,7 @@ public:
ZForwardingCursor cursor;
ZForwardingEntry entry = forwarding->find(from_index, &cursor);
ASSERT_FALSE(entry.is_empty()) << CAPTURE2(from_index, size);
ASSERT_TRUE(entry.populated()) << CAPTURE2(from_index, size);
ASSERT_EQ(entry.from_index(), from_index) << CAPTURE(size);
ASSERT_EQ(entry.to_offset(), from_index) << CAPTURE(size);
@ -139,7 +137,7 @@ public:
ZForwardingEntry entry = forwarding->find(from_index);
ASSERT_TRUE(entry.is_empty()) << CAPTURE2(from_index, size);
ASSERT_FALSE(entry.populated()) << CAPTURE2(from_index, size);
}
}