8266957: SA has not followed JDK-8220587 and JDK-8224965

Reviewed-by: cjplummer, sspitsyn
This commit is contained in:
Yasumasa Suenaga 2021-06-05 00:07:04 +00:00
parent 6ff978ac16
commit 7e41ca3da8
23 changed files with 608 additions and 241 deletions

@ -28,6 +28,8 @@ ZGlobalsForVMStructs::ZGlobalsForVMStructs() :
_ZGlobalPhase(&ZGlobalPhase),
_ZGlobalSeqNum(&ZGlobalSeqNum),
_ZAddressOffsetMask(&ZAddressOffsetMask),
_ZAddressMetadataMask(&ZAddressMetadataMask),
_ZAddressMetadataFinalizable(&ZAddressMetadataFinalizable),
_ZAddressGoodMask(&ZAddressGoodMask),
_ZAddressBadMask(&ZAddressBadMask),
_ZAddressWeakBadMask(&ZAddressWeakBadMask),

@ -46,6 +46,8 @@ public:
uint32_t* _ZGlobalSeqNum;
uintptr_t* _ZAddressOffsetMask;
uintptr_t* _ZAddressMetadataMask;
uintptr_t* _ZAddressMetadataFinalizable;
uintptr_t* _ZAddressGoodMask;
uintptr_t* _ZAddressBadMask;
uintptr_t* _ZAddressWeakBadMask;
@ -55,6 +57,7 @@ public:
};
typedef ZGranuleMap<ZPage*> ZGranuleMapForPageTable;
typedef ZGranuleMap<ZForwarding*> ZGranuleMapForForwarding;
typedef ZAttachedArray<ZForwarding, ZForwardingEntry> ZAttachedArrayForForwarding;
#define VM_STRUCTS_ZGC(nonstatic_field, volatile_nonstatic_field, static_field) \
@ -62,6 +65,8 @@ typedef ZAttachedArray<ZForwarding, ZForwardingEntry> ZAttachedArrayForForwardin
nonstatic_field(ZGlobalsForVMStructs, _ZGlobalPhase, uint32_t*) \
nonstatic_field(ZGlobalsForVMStructs, _ZGlobalSeqNum, uint32_t*) \
nonstatic_field(ZGlobalsForVMStructs, _ZAddressOffsetMask, uintptr_t*) \
nonstatic_field(ZGlobalsForVMStructs, _ZAddressMetadataMask, uintptr_t*) \
nonstatic_field(ZGlobalsForVMStructs, _ZAddressMetadataFinalizable, uintptr_t*) \
nonstatic_field(ZGlobalsForVMStructs, _ZAddressGoodMask, uintptr_t*) \
nonstatic_field(ZGlobalsForVMStructs, _ZAddressBadMask, uintptr_t*) \
nonstatic_field(ZGlobalsForVMStructs, _ZAddressWeakBadMask, uintptr_t*) \
@ -72,6 +77,8 @@ typedef ZAttachedArray<ZForwarding, ZForwardingEntry> ZAttachedArrayForForwardin
\
nonstatic_field(ZHeap, _page_allocator, ZPageAllocator) \
nonstatic_field(ZHeap, _page_table, ZPageTable) \
nonstatic_field(ZHeap, _forwarding_table, ZForwardingTable) \
nonstatic_field(ZHeap, _relocate, ZRelocate) \
\
nonstatic_field(ZPage, _type, const uint8_t) \
nonstatic_field(ZPage, _seqnum, uint32_t) \
@ -85,11 +92,19 @@ typedef ZAttachedArray<ZForwarding, ZForwardingEntry> ZAttachedArrayForForwardin
nonstatic_field(ZPageTable, _map, ZGranuleMapForPageTable) \
\
nonstatic_field(ZGranuleMapForPageTable, _map, ZPage** const) \
nonstatic_field(ZGranuleMapForForwarding, _map, ZForwarding** const) \
\
nonstatic_field(ZForwardingTable, _map, ZGranuleMapForForwarding) \
\
nonstatic_field(ZVirtualMemory, _start, const uintptr_t) \
nonstatic_field(ZVirtualMemory, _end, const uintptr_t) \
\
nonstatic_field(ZForwarding, _entries, const ZAttachedArrayForForwarding)
nonstatic_field(ZForwarding, _virtual, const ZVirtualMemory) \
nonstatic_field(ZForwarding, _object_alignment_shift, const size_t) \
volatile_nonstatic_field(ZForwarding, _ref_count, int) \
nonstatic_field(ZForwarding, _entries, const ZAttachedArrayForForwarding) \
nonstatic_field(ZForwardingEntry, _entry, uint64_t) \
nonstatic_field(ZAttachedArrayForForwarding, _length, const size_t)
#define VM_INT_CONSTANTS_ZGC(declare_constant, declare_constant_with_value) \
declare_constant(ZPhaseRelocate) \
@ -112,11 +127,13 @@ typedef ZAttachedArray<ZForwarding, ZForwardingEntry> ZAttachedArrayForForwardin
declare_toplevel_type(ZGlobalsForVMStructs) \
declare_type(ZCollectedHeap, CollectedHeap) \
declare_toplevel_type(ZHeap) \
declare_toplevel_type(ZRelocate) \
declare_toplevel_type(ZPage) \
declare_toplevel_type(ZPageAllocator) \
declare_toplevel_type(ZPageTable) \
declare_toplevel_type(ZAttachedArrayForForwarding) \
declare_toplevel_type(ZGranuleMapForPageTable) \
declare_toplevel_type(ZGranuleMapForForwarding) \
declare_toplevel_type(ZVirtualMemory) \
declare_toplevel_type(ZForwardingTable) \
declare_toplevel_type(ZForwarding) \

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, 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
@ -28,6 +28,8 @@
template <typename ObjectT, typename ArrayT>
class ZAttachedArray {
friend class VMStructs;
private:
const size_t _length;

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, 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
@ -48,6 +48,7 @@
class ZForwardingEntry {
friend struct PrimitiveConversions::Translate<ZForwardingEntry>;
friend class VMStructs;
private:
typedef ZBitField<uint64_t, bool, 0, 1> field_populated;

@ -29,6 +29,8 @@
class ZForwarding;
class ZForwardingTable {
friend class VMStructs;
private:
ZGranuleMap<ZForwarding*> _map;

@ -40,7 +40,7 @@ class ZAddress {
}
static boolean is_weak_bad(Address value) {
return (as_long(value) & ZGlobals.ZAddressWeakBadMask()) != 0;
return (as_long(value) & ZGlobals.ZAddressWeakBadMask()) != 0L;
}
static boolean is_weak_good(Address value) {
@ -62,4 +62,16 @@ class ZAddress {
static Address good_or_null(Address value) {
return is_null(value) ? value : good(value);
}
private static boolean isPowerOf2(long value) {
return (value != 0L) && ((value & (value - 1)) == 0L);
}
static boolean isIn(Address addr) {
long value = as_long(addr);
if (!isPowerOf2(value & ~ZGlobals.ZAddressOffsetMask())) {
return false;
}
return (value & (ZGlobals.ZAddressMetadataMask() & ~ZGlobals.ZAddressMetadataFinalizable())) != 0L;
}
}

@ -0,0 +1,71 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, NTT DATA.
* 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.
*
*/
package sun.jvm.hotspot.gc.z;
import sun.jvm.hotspot.debugger.Address;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.runtime.VMObject;
import sun.jvm.hotspot.runtime.VMObjectFactory;
import sun.jvm.hotspot.types.CIntegerField;
import sun.jvm.hotspot.types.Type;
import sun.jvm.hotspot.types.TypeDataBase;
public class ZAttachedArrayForForwarding extends VMObject {
private static CIntegerField lengthField;
static {
VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
}
static private synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("ZAttachedArrayForForwarding");
lengthField = type.getCIntegerField("_length");
}
public ZAttachedArrayForForwarding(Address addr) {
super(addr);
}
public long length() {
return lengthField.getValue(addr);
}
// ObjectT: ZForwarding
// ArrayT: ZForwardingEntry
//
// template <typename ObjectT, typename ArrayT>
// inline size_t ZAttachedArray<ObjectT, ArrayT>::object_size()
private long objectSize() {
return ZUtils.alignUp(ZForwarding.getSize(), ZForwardingEntry.getSize());
}
// ArrayT* operator()(const ObjectT* obj) const
public ZForwardingEntry get(ZForwarding obj) {
Address o = obj.getAddress().addOffsetTo(objectSize());
return VMObjectFactory.newObject(ZForwardingEntry.class, o);
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, 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
@ -41,14 +41,7 @@ class ZBarrier {
}
private static Address relocate(Address addr) {
ZHeap heap = zheap();
if (heap.is_relocating(addr)) {
// Forward
return heap.relocate_object(addr);
}
// Remap
return ZAddress.good(addr);
return zheap().relocate_object(addr);
}
private static ZHeap zheap() {
@ -57,14 +50,7 @@ class ZBarrier {
}
private static Address remap(Address addr) {
ZHeap heap = zheap();
if (heap.is_relocating(addr)) {
// Forward
return heap.forward_object(addr);
}
// Remap
return ZAddress.good(addr);
return zheap().remapObject(addr);
}
private static Address relocate_or_remap(Address addr) {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, 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
@ -82,7 +82,10 @@ public class ZCollectedHeap extends CollectedHeap {
return heap().used();
}
@Override
public boolean isInReserved(Address a) {
return heap().isIn(a);
}
private OopHandle oop_load_barrier(Address oopAddress) {
oopAddress = ZBarrier.weak_barrier(oopAddress);
@ -106,7 +109,6 @@ public class ZCollectedHeap extends CollectedHeap {
@Override
public OopHandle oop_load_in_native(Address addr) {
Address oopAddress = addr.getAddressAt(0);
return oop_load_barrier(oopAddress);
}

@ -0,0 +1,136 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, NTT DATA.
* 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.
*
*/
package sun.jvm.hotspot.gc.z;
import java.util.Iterator;
import sun.jvm.hotspot.debugger.Address;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.runtime.VMObject;
import sun.jvm.hotspot.runtime.VMObjectFactory;
import sun.jvm.hotspot.types.CIntegerField;
import sun.jvm.hotspot.types.Type;
import sun.jvm.hotspot.types.TypeDataBase;
public class ZForwarding extends VMObject {
private static Type type;
private static long virtualFieldOffset;
private static long entriesFieldOffset;
private static CIntegerField objectAlignmentShiftField;
private static CIntegerField refCountField;
static {
VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
}
static private synchronized void initialize(TypeDataBase db) {
type = db.lookupType("ZForwarding");
virtualFieldOffset = type.getField("_virtual").getOffset();
entriesFieldOffset = type.getField("_entries").getOffset();
objectAlignmentShiftField = type.getCIntegerField("_object_alignment_shift");
refCountField = type.getCIntegerField("_ref_count");
}
public ZForwarding(Address addr) {
super(addr);
}
public static long getSize() {
return type.getSize();
}
private ZVirtualMemory virtual() {
return VMObjectFactory.newObject(ZVirtualMemory.class, addr.addOffsetTo(virtualFieldOffset));
}
private ZAttachedArrayForForwarding entries() {
return VMObjectFactory.newObject(ZAttachedArrayForForwarding.class, addr.addOffsetTo(entriesFieldOffset));
}
public long start() {
return virtual().start();
}
public int objectAlignmentShift() {
return (int)objectAlignmentShiftField.getValue(addr);
}
public boolean retainPage() {
return refCountField.getValue(addr) > 0;
}
private ZForwardingEntry at(long cursor) {
long offset = ZForwardingEntry.getSize() * cursor;
Address entryAddress = entries().get(this).getAddress().addOffsetTo(offset);
return VMObjectFactory.newObject(ZForwardingEntry.class, entryAddress);
}
private class ZForwardEntryIterator implements Iterator<ZForwardingEntry> {
private long cursor;
private ZForwardingEntry nextEntry;
public ZForwardEntryIterator(long fromIndex) {
long mask = entries().length() - 1;
long hash = ZHash.uint32_to_uint32(fromIndex);
cursor = hash & mask;
nextEntry = at(cursor);
}
@Override
public boolean hasNext() {
return nextEntry.populated();
}
@Override
public ZForwardingEntry next() {
ZForwardingEntry entry = nextEntry;
long mask = entries().length() - 1;
cursor = (cursor + 1) & mask;
nextEntry = at(cursor);
return entry;
}
public ZForwardingEntry peak() {
return nextEntry;
}
}
public ZForwardingEntry find(long fromIndex) {
ZForwardEntryIterator itr = new ZForwardEntryIterator(fromIndex);
while (itr.hasNext()) {
ZForwardingEntry entry = itr.next();
if (entry.fromIndex() == fromIndex) {
return entry;
}
}
return itr.peak();
}
}

@ -0,0 +1,97 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, NTT DATA.
* 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.
*
*/
package sun.jvm.hotspot.gc.z;
import sun.jvm.hotspot.debugger.Address;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.runtime.VMObject;
import sun.jvm.hotspot.runtime.VMObjectFactory;
import sun.jvm.hotspot.types.CIntegerField;
import sun.jvm.hotspot.types.Type;
import sun.jvm.hotspot.types.TypeDataBase;
public class ZForwardingEntry extends VMObject {
private static Type type;
private static CIntegerField entryField;
static {
VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
}
static private synchronized void initialize(TypeDataBase db) {
type = db.lookupType("ZForwardingEntry");
entryField = type.getCIntegerField("_entry");
}
public static long getSize() {
return type.getSize();
}
public ZForwardingEntry(Address addr) {
super(addr);
}
public long entry() {
return entryField.getValue(addr);
}
// typedef ZBitField<uint64_t, bool, 0, 1> field_populated
private boolean fieldPopulatedDecode(long value) {
long FieldMask = (1L << 1) - 1;
int FieldShift = 1;
int ValueShift = 0;
return (((value >>> FieldShift) & FieldMask) << ValueShift) != 0L;
}
// typedef ZBitField<uint64_t, size_t, 1, 45> field_to_offset;
private long fieldToOffsetDecode(long value) {
long FieldMask = (1L << 45) - 1;
int FieldShift = 1;
int ValueShift = 0;
return ((value >>> FieldShift) & FieldMask) << ValueShift;
}
// typedef ZBitField<uint64_t, size_t, 46, 18> field_from_index;
private long fieldFromIndexDecode(long value) {
long FieldMask = (1L << 18) - 1;
int FieldShift = 46;
int ValueShift = 0;
return ((value >>> FieldShift) & FieldMask) << ValueShift;
}
public boolean populated() {
return fieldPopulatedDecode(entry());
}
public long toOffset() {
return fieldToOffsetDecode(entry());
}
public long fromIndex() {
return fieldFromIndexDecode(entry());
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, 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
@ -27,14 +27,14 @@ package sun.jvm.hotspot.gc.z;
import sun.jvm.hotspot.debugger.Address;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.runtime.VMObject;
import sun.jvm.hotspot.runtime.VMObjectFactory;
import sun.jvm.hotspot.types.AddressField;
import sun.jvm.hotspot.types.CIntegerField;
import sun.jvm.hotspot.types.Type;
import sun.jvm.hotspot.types.TypeDataBase;
public class ZForwardingTable extends VMObject {
private static AddressField tableField;
private static CIntegerField sizeField;
private static long mapFieldOffset;
static {
VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
@ -43,75 +43,18 @@ public class ZForwardingTable extends VMObject {
static private synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("ZForwardingTable");
tableField = type.getAddressField("_table");
sizeField = type.getCIntegerField("_size");
mapFieldOffset = type.getAddressField("_map").getOffset();
}
public ZForwardingTable(Address addr) {
super(addr);
}
Address table() {
return tableField.getAddress(addr);
private ZGranuleMapForForwarding map() {
return VMObjectFactory.newObject(ZGranuleMapForForwarding.class, addr.addOffsetTo(mapFieldOffset));
}
long size() {
return sizeField.getJLong(addr);
}
ZForwardingTableEntry at(ZForwardingTableCursor cursor) {
return new ZForwardingTableEntry(table().getAddressAt(cursor._value * VM.getVM().getBytesPerLong()));
}
ZForwardingTableEntry first(long from_index, ZForwardingTableCursor cursor) {
long mask = size() - 1;
long hash = ZHash.uint32_to_uint32(from_index);
cursor._value = hash & mask;
return at(cursor);
}
ZForwardingTableEntry next(ZForwardingTableCursor cursor) {
long mask = size() - 1;
cursor._value = (cursor._value + 1) & mask;
return at(cursor);
}
ZForwardingTableEntry find(long from_index, ZForwardingTableCursor cursor) {
// 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).
ZForwardingTableEntry entry = first(from_index, cursor);
while (!entry.is_empty()) {
if (entry.from_index() == from_index) {
// Match found, return matching entry
return entry;
}
entry = next(cursor);
}
// Match not found, return empty entry
return entry;
}
ZForwardingTableEntry find(long from_index) {
ZForwardingTableCursor dummy = new ZForwardingTableCursor();
return find(from_index, dummy);
}
void dump() {
long s = size();
long count = 0;
System.out.println("Dumping ZForwardingTable[" + s + "]:");
ZForwardingTableCursor cursor = new ZForwardingTableCursor();
for (long i = 0; i < s; i++) {
cursor._value = i;
ZForwardingTableEntry entry = at(cursor);
if (!entry.is_empty()) {
long hash = ZHash.uint32_to_uint32(entry.from_index());
System.out.println(i + " " + count + " " + entry + " hash: " + hash + " masked_hash: " + (hash & (s - 1)));
count++;
}
}
public ZForwarding get(Address o) {
return VMObjectFactory.newObject(ZForwarding.class, map().get(ZAddress.offset(o)));
}
}

@ -102,6 +102,14 @@ public class ZGlobals {
return instance().ZAddressOffsetMask();
}
public static long ZAddressMetadataMask() {
return instance().ZAddressMetadataMask();
}
public static long ZAddressMetadataFinalizable() {
return instance().ZAddressMetadataFinalizable();
}
public static long ZAddressGoodMask() {
return instance().ZAddressGoodMask();
}

@ -35,6 +35,8 @@ class ZGlobalsForVMStructs extends VMObject {
private static AddressField ZGlobalPhaseField;
private static AddressField ZGlobalSeqNumField;
private static AddressField ZAddressOffsetMaskField;
private static AddressField ZAddressMetadataMaskField;
private static AddressField ZAddressMetadataFinalizableField;
private static AddressField ZAddressGoodMaskField;
private static AddressField ZAddressBadMaskField;
private static AddressField ZAddressWeakBadMaskField;
@ -51,6 +53,8 @@ class ZGlobalsForVMStructs extends VMObject {
ZGlobalPhaseField = type.getAddressField("_ZGlobalPhase");
ZGlobalSeqNumField = type.getAddressField("_ZGlobalSeqNum");
ZAddressOffsetMaskField = type.getAddressField("_ZAddressOffsetMask");
ZAddressMetadataMaskField = type.getAddressField("_ZAddressMetadataMask");
ZAddressMetadataFinalizableField = type.getAddressField("_ZAddressMetadataFinalizable");
ZAddressGoodMaskField = type.getAddressField("_ZAddressGoodMask");
ZAddressBadMaskField = type.getAddressField("_ZAddressBadMask");
ZAddressWeakBadMaskField = type.getAddressField("_ZAddressWeakBadMask");
@ -74,6 +78,14 @@ class ZGlobalsForVMStructs extends VMObject {
return ZAddressOffsetMaskField.getValue(addr).getJLongAt(0);
}
long ZAddressMetadataMask() {
return ZAddressMetadataMaskField.getValue(addr).getJLongAt(0);
}
long ZAddressMetadataFinalizable() {
return ZAddressMetadataFinalizableField.getValue(addr).getJLongAt(0);
}
long ZAddressGoodMask() {
return ZAddressGoodMaskField.getValue(addr).getJLongAt(0);
}

@ -0,0 +1,90 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, NTT DATA.
* 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.
*
*/
package sun.jvm.hotspot.gc.z;
import sun.jvm.hotspot.debugger.Address;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.runtime.VMObject;
import sun.jvm.hotspot.types.AddressField;
import sun.jvm.hotspot.types.Type;
import sun.jvm.hotspot.types.TypeDataBase;
public class ZGranuleMapForForwarding extends VMObject {
private static AddressField mapField;
static {
VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
}
static private synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("ZGranuleMapForForwarding");
mapField = type.getAddressField("_map");
}
public ZGranuleMapForForwarding(Address addr) {
super(addr);
}
private Address map() {
return mapField.getValue(addr);
}
public long size() {
return ZGlobals.ZAddressOffsetMax >> ZGlobals.ZGranuleSizeShift;
}
private long index_for_offset(long offset) {
long index = offset >>> ZGlobals.ZGranuleSizeShift;
return index;
}
Address at(long index) {
return map().getAddressAt(index * VM.getVM().getAddressSize());
}
Address get(long offset) {
long index = index_for_offset(offset);
return at(index);
}
public class Iterator {
private long next = 0;
boolean hasNext() {
return next < size();
}
Address next() {
if (next >= size()) {
throw new RuntimeException("OOIBE");
}
return at(next++);
}
}
}

@ -31,11 +31,11 @@ class ZHash {
static long uint32_to_uint32(long key) {
key = uint32(~key + (key << 15));
key = uint32(key ^ (key >> 12));
key = uint32(key ^ (key >>> 12));
key = uint32(key + (key << 2));
key = uint32(key ^ (key >> 4));
key = uint32(key ^ (key >>> 4));
key = uint32(key * 2057);
key = uint32(key ^ (key >> 16));
key = uint32(key ^ (key >>> 16));
return key;
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2021, 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
@ -39,6 +39,8 @@ public class ZHeap extends VMObject {
private static long pageAllocatorFieldOffset;
private static long pageTableFieldOffset;
private static long forwardingTableFieldOffset;
private static long relocateFieldOffset;
static {
VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
@ -49,6 +51,8 @@ public class ZHeap extends VMObject {
pageAllocatorFieldOffset = type.getAddressField("_page_allocator").getOffset();
pageTableFieldOffset = type.getAddressField("_page_table").getOffset();
forwardingTableFieldOffset = type.getAddressField("_forwarding_table").getOffset();
relocateFieldOffset = type.getAddressField("_relocate").getOffset();
}
public ZHeap(Address addr) {
@ -64,6 +68,14 @@ public class ZHeap extends VMObject {
return (ZPageTable)VMObjectFactory.newObject(ZPageTable.class, addr.addOffsetTo(pageTableFieldOffset));
}
ZForwardingTable forwardingTable() {
return VMObjectFactory.newObject(ZForwardingTable.class, addr.addOffsetTo(forwardingTableFieldOffset));
}
ZRelocate relocate() {
return VMObjectFactory.newObject(ZRelocate.class, addr.addOffsetTo(relocateFieldOffset));
}
public long maxCapacity() {
return pageAllocator().maxCapacity();
}
@ -80,14 +92,30 @@ public class ZHeap extends VMObject {
return pageTable().is_relocating(o);
}
Address forward_object(Address addr) {
ZPage page = pageTable().get(addr);
return page.forward_object(addr);
Address relocate_object(Address addr) {
ZForwarding forwarding = forwardingTable().get(addr);
if (forwarding == null) {
return ZAddress.good(addr);
}
return relocate().relocateObject(forwarding, ZAddress.good(addr));
}
Address relocate_object(Address addr) {
ZPage page = pageTable().get(addr);
return page.relocate_object(addr);
public boolean isIn(Address addr) {
if (ZAddress.isIn(addr)) {
ZPage page = pageTable().get(addr);
if (page != null) {
return page.isIn(addr);
}
}
return false;
}
public Address remapObject(Address o) {
ZForwarding forwarding = forwardingTable().get(addr);
if (forwarding == null) {
return ZAddress.good(o);
}
return relocate().forwardObject(forwarding, ZAddress.good(o));
}
public void printOn(PrintStream tty) {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, 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
@ -29,6 +29,6 @@ import sun.jvm.hotspot.debugger.OopHandle;
class ZOop {
static Address to_address(OopHandle oop) {
return ZUtils.longToAddress(ZAddress.as_long(oop));
return oop;
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, 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
@ -46,8 +46,6 @@ public class ZPage extends VMObject implements LiveRegionsProvider {
private static CIntegerField seqnumField;
private static long virtualFieldOffset;
private static AddressField topField;
private static CIntegerField refcountField;
private static long forwardingFieldOffset;
static {
VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
@ -60,8 +58,6 @@ public class ZPage extends VMObject implements LiveRegionsProvider {
seqnumField = type.getCIntegerField("_seqnum");
virtualFieldOffset = type.getField("_virtual").getOffset();
topField = type.getAddressField("_top");
refcountField = type.getCIntegerField("_refcount");
forwardingFieldOffset = type.getField("_forwarding").getOffset();
}
public ZPage(Address addr) {
@ -84,28 +80,8 @@ public class ZPage extends VMObject implements LiveRegionsProvider {
return topField.getValue(addr);
}
private int refcount() {
// refcount is uint32_t so need to be cautious when using this field.
return refcountField.getJInt(addr);
}
private ZForwardingTable forwarding() {
return VMObjectFactory.newObject(ZForwardingTable.class, addr.addOffsetTo(forwardingFieldOffset));
}
private boolean is_forwarding() {
return forwarding().table() != null;
}
private boolean is_relocatable() {
return is_active() && seqnum() < ZGlobals.ZGlobalSeqNum();
}
private boolean isPageRelocating() {
assert(is_active());
// is_forwarding(): Has a (relocation) forwarding table
// is_relocatable(): Has not been freed yet
return is_forwarding() && is_relocatable();
return seqnum() < ZGlobals.ZGlobalSeqNum();
}
long start() {
@ -116,31 +92,6 @@ public class ZPage extends VMObject implements LiveRegionsProvider {
return virtual().end() - virtual().start();
}
Address forward_object(Address from) {
// Lookup address in forwarding table
long from_offset = ZAddress.offset(from);
long from_index = (from_offset - start()) >> object_alignment_shift();
ZForwardingTableEntry entry = forwarding().find(from_index);
assert(!entry.is_empty());
assert(entry.from_index() == from_index);
return ZAddress.good(entry.to_offset());
}
Address relocate_object(Address from) {
// Lookup address in forwarding table
long from_offset = ZAddress.offset(from);
long from_index = (from_offset - start()) >> object_alignment_shift();
ZForwardingTableEntry entry = forwarding().find(from_index);
if (!entry.is_empty() && entry.from_index() == from_index) {
return ZAddress.good(entry.to_offset());
}
// There's no relocate operation in the SA.
// Mimic object pinning and return the good view of the from object.
return ZAddress.good(from);
}
long object_alignment_shift() {
if (type() == ZGlobals.ZPageTypeSmall) {
return ZGlobals.ZObjectAlignmentSmallShift();
@ -156,8 +107,10 @@ public class ZPage extends VMObject implements LiveRegionsProvider {
return 1 << object_alignment_shift();
}
public boolean is_active() {
return refcount() != 0;
public boolean isIn(Address addr) {
long offset = ZAddress.offset(addr);
// FIXME: it does not consider the sign.
return (offset >= start()) && (offset < top().asLongValue());
}
private long getObjectSize(Address good) {
@ -173,72 +126,16 @@ public class ZPage extends VMObject implements LiveRegionsProvider {
return VM.getVM().alignUp(obj.getObjectSize(), objectAlignmentSize());
}
private void addNotRelocatedRegions(List<MemRegion> regions) {
MemRegion mr = null;
// Some objects have already been forwarded to new locations.
long topValue = top().asLongValue();
for (long offsetValue = start(); offsetValue < topValue;) {
Address from = ZAddress.good(ZUtils.longToAddress(offsetValue));
Address to = relocate_object(from);
long byteSize;
try {
byteSize = getObjectSize(to);
} catch (Exception e) {
// Parsing the ZHeap is inherently unsafe
// when classes have been unloaded. Dead objects
// might have stale Klass pointers, and there's
// no way to get the size of the dead object.
//
// If possible, run with -XX:-ClassUnloading
// to ensure that all Klasses are kept alive.
System.err.println("Unparsable regions found. Skipping: "
+ from
+ " "
+ from.addOffsetTo(topValue - offsetValue));
// Can't proceed further. Just return the collected regions.
return;
}
if (from.equals(to)) {
// Not relocated - add region
if (mr == null) {
mr = new MemRegion(from, 0 /* wordSize */);
regions.add(mr);
}
long wordSize = byteSize / VM.getVM().getBytesPerWord();
mr.setWordSize(mr.wordSize() + wordSize);
} else {
// Forwarded somewhere else, split region.
mr = null;
}
offsetValue += byteSize;
}
}
public List<MemRegion> getLiveRegions() {
List<MemRegion> res = new ArrayList<>();
Address start = ZAddress.good(ZUtils.longToAddress(start()));
if (isPageRelocating()) {
addNotRelocatedRegions(res);
} else {
Address start = ZAddress.good(ZUtils.longToAddress(start()));
// Can't convert top() to a "good" address because it might
// be at the top of the "offset" range, and therefore also
// looks like one of the color bits. Instead use the "good"
// address and add the size.
long size = top().asLongValue() - start();
Address end = start.addOffsetTo(size);
// Can't convert top() to a "good" address because it might
// be at the top of the "offset" range, and therefore also
// looks like one of the color bits. Instead use the "good"
// address and add the size.
long size = top().asLongValue() - start();
Address end = start.addOffsetTo(size);
res.add(new MemRegion(start, end));
}
return res;
return List.of(new MemRegion(start, end));
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, 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
@ -59,7 +59,7 @@ public class ZPageTable extends VMObject {
}
ZPage get(Address o) {
return getEntry(o).page();
return VMObjectFactory.newObject(ZPage.class, map().get(VM.getVM().getDebugger().newAddress(ZAddress.offset(o))));
}
boolean is_relocating(Address o) {
@ -169,7 +169,7 @@ public class ZPageTable extends VMObject {
public Iterator<ZPage> activePagesIterator() {
return new ZPagesFilteredIterator(new ZPageFilter() {
public boolean accept(ZPage page) {
return page.is_active();
return page != null;
}
});
}

@ -0,0 +1,74 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, NTT DATA.
* 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.
*
*/
package sun.jvm.hotspot.gc.z;
import sun.jvm.hotspot.debugger.Address;
import sun.jvm.hotspot.runtime.VM;
import sun.jvm.hotspot.runtime.VMObject;
import sun.jvm.hotspot.types.AddressField;
import sun.jvm.hotspot.types.Type;
import sun.jvm.hotspot.types.TypeDataBase;
public class ZRelocate extends VMObject {
static {
VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
}
static private synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("ZRelocate");
}
public ZRelocate(Address addr) {
super(addr);
}
private long forwardingIndex(ZForwarding forwarding, Address from) {
long fromOffset = ZAddress.offset(from);
return (fromOffset - forwarding.start()) >>> forwarding.objectAlignmentShift();
}
private Address forwardingFind(ZForwarding forwarding, Address from) {
long fromIndex = forwardingIndex(forwarding, from);
ZForwardingEntry entry = forwarding.find(fromIndex);
return entry.populated() ? ZAddress.good(VM.getVM().getDebugger().newAddress(entry.toOffset())) : null;
}
public Address forwardObject(ZForwarding forwarding, Address from) {
return forwardingFind(forwarding, from);
}
public Address relocateObject(ZForwarding forwarding, Address o) {
Address toAddr = forwardingFind(forwarding, o);
if (toAddr != null) {
// Already relocated.
return toAddr;
} else {
// Return original address because it is not yet relocated.
return o;
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, 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
@ -28,16 +28,13 @@ import sun.jvm.hotspot.debugger.Address;
import sun.jvm.hotspot.runtime.VM;
class ZUtils {
private static final long MSB = ~0L ^ (~0L >>> 1);
private static Address msbAddress() {
return VM.getVM().getUniverse().heap().start().orWithMask(MSB).andWithMask(MSB);
static Address longToAddress(long value) {
return VM.getVM().getDebugger().newAddress(value);
}
static Address longToAddress(long value) {
// If the value of an Address becomes 0, null is returned instead of an Address.
// Start with a one-bit address and as a last step, remove that bit.
Address oneAddress = msbAddress();
return oneAddress.orWithMask(value).xorWithMask(ZAddress.as_long(oneAddress));
static long alignUp(long size, long alignment) {
long mask = alignment - 1;
long adjusted = size + mask;
return adjusted & ~mask;
}
}

@ -29,16 +29,6 @@
resourcehogs/serviceability/sa/TestHeapDumpForLargeArray.java 8220624 generic-all
serviceability/sa/CDSJMapClstats.java 8220624 generic-all
serviceability/sa/ClhsdbDumpheap.java 8220624 generic-all
serviceability/sa/ClhsdbFindPC.java#id0 8220624 generic-all
serviceability/sa/ClhsdbFindPC.java#id1 8220624 generic-all
serviceability/sa/ClhsdbFindPC.java#id2 8220624 generic-all
serviceability/sa/ClhsdbFindPC.java#id3 8220624 generic-all
serviceability/sa/ClhsdbInspect.java 8220624 generic-all
serviceability/sa/ClhsdbJhisto.java 8220624 generic-all
serviceability/sa/ClhsdbSymbol.java 8220624 generic-all
serviceability/sa/TestHeapDumpForInvokeDynamic.java 8220624 generic-all
serviceability/sa/TestHeapDumpForLargeArray.java 8220624 generic-all
serviceability/sa/TestJmapCore.java 8220624 generic-all
serviceability/sa/TestJmapCoreMetaspace.java 8267045 generic-all
vmTestbase/jit/escape/AdaptiveBlocking/AdaptiveBlocking001/AdaptiveBlocking001.java 8260303 windows-x64