--- old/src/hotspot/share/gc/z/vmStructs_z.cpp 2019-02-14 18:20:28.872218018 +0100 +++ new/src/hotspot/share/gc/z/vmStructs_z.cpp 2019-02-14 18:20:28.356218022 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, 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,6 +26,7 @@ ZGlobalsForVMStructs::ZGlobalsForVMStructs() : _ZGlobalPhase(&ZGlobalPhase), + _ZGlobalSeqNum(&ZGlobalSeqNum), _ZAddressGoodMask(&ZAddressGoodMask), _ZAddressBadMask(&ZAddressBadMask), _ZAddressWeakBadMask(&ZAddressWeakBadMask), --- old/src/hotspot/share/gc/z/vmStructs_z.hpp 2019-02-14 18:20:29.460218014 +0100 +++ new/src/hotspot/share/gc/z/vmStructs_z.hpp 2019-02-14 18:20:28.996218017 +0100 @@ -42,6 +42,8 @@ uint32_t* _ZGlobalPhase; + uint32_t* _ZGlobalSeqNum; + uintptr_t* _ZAddressGoodMask; uintptr_t* _ZAddressBadMask; uintptr_t* _ZAddressWeakBadMask; @@ -55,6 +57,7 @@ #define VM_STRUCTS_ZGC(nonstatic_field, volatile_nonstatic_field, static_field) \ static_field(ZGlobalsForVMStructs, _instance_p, ZGlobalsForVMStructs*) \ nonstatic_field(ZGlobalsForVMStructs, _ZGlobalPhase, uint32_t*) \ + nonstatic_field(ZGlobalsForVMStructs, _ZGlobalSeqNum, uint32_t*) \ nonstatic_field(ZGlobalsForVMStructs, _ZAddressGoodMask, uintptr_t*) \ nonstatic_field(ZGlobalsForVMStructs, _ZAddressBadMask, uintptr_t*) \ nonstatic_field(ZGlobalsForVMStructs, _ZAddressWeakBadMask, uintptr_t*) \ @@ -67,7 +70,10 @@ nonstatic_field(ZHeap, _pagetable, ZPageTable) \ \ nonstatic_field(ZPage, _type, const uint8_t) \ + nonstatic_field(ZPage, _seqnum, uint32_t) \ nonstatic_field(ZPage, _virtual, const ZVirtualMemory) \ + volatile_nonstatic_field(ZPage, _top, uintptr_t) \ + volatile_nonstatic_field(ZPage, _refcount, uint32_t) \ nonstatic_field(ZPage, _forwarding, ZForwardingTable) \ \ nonstatic_field(ZPageAllocator, _physical, ZPhysicalMemoryManager) \ @@ -101,6 +107,7 @@ declare_constant(ZAddressOffsetShift) \ declare_constant(ZAddressOffsetBits) \ declare_constant(ZAddressOffsetMask) \ + declare_constant(ZAddressOffsetMax) \ declare_constant(ZAddressSpaceStart) #define VM_TYPES_ZGC(declare_type, declare_toplevel_type, declare_integer_type) \ --- old/src/hotspot/share/gc/z/zCollectedHeap.cpp 2019-02-14 18:20:30.052218009 +0100 +++ new/src/hotspot/share/gc/z/zCollectedHeap.cpp 2019-02-14 18:20:29.588218013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, 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 @@ -118,10 +118,6 @@ return is_in(p); } -void ZCollectedHeap::fill_with_dummy_object(HeapWord* start, HeapWord* end, bool zap) { - // Does nothing, not a parsable heap -} - HeapWord* ZCollectedHeap::allocate_new_tlab(size_t min_size, size_t requested_size, size_t* actual_size) { const size_t size_in_bytes = ZUtils::words_to_bytes(align_object_size(requested_size)); const uintptr_t addr = _heap.alloc_tlab(size_in_bytes); --- old/src/hotspot/share/gc/z/zCollectedHeap.hpp 2019-02-14 18:20:30.648218005 +0100 +++ new/src/hotspot/share/gc/z/zCollectedHeap.hpp 2019-02-14 18:20:30.184218009 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, 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 @@ -75,8 +75,6 @@ virtual bool is_in(const void* p) const; virtual bool is_in_closed_subset(const void* p) const; - virtual void fill_with_dummy_object(HeapWord* start, HeapWord* end, bool zap); - virtual HeapWord* mem_allocate(size_t size, bool* gc_overhead_limit_was_exceeded); virtual MetaWord* satisfy_failed_metadata_allocation(ClassLoaderData* loader_data, size_t size, --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZAddress.java 2019-02-14 18:20:31.300218000 +0100 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZAddress.java 2019-02-14 18:20:30.784218004 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, 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 @@ -61,7 +61,7 @@ value |= ZGlobals.ZAddressSpaceStart; } - return ZOop.to_address(value); + return ZUtils.longToAddress(value); } static Address good(Address value) { --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZAddressRangeMapForPageTable.java 2019-02-14 18:20:31.904217996 +0100 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZAddressRangeMapForPageTable.java 2019-02-14 18:20:31.440217999 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, 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 @@ -54,15 +54,38 @@ return mapField.getValue(addr); } + public long size() { + return ZGlobals.ZAddressOffsetMax >> AddressRangeShift; + } + private long index_for_addr(Address addr) { long index = ZAddress.offset(addr) >> AddressRangeShift; return index; } + Address at(long index) { + return map().getAddressAt(index * VM.getVM().getBytesPerLong()); + } + Address get(Address addr) { long index = index_for_addr(addr); + return at(index); + } - return map().getAddressAt(index * VM.getVM().getBytesPerLong()); + public class Iterator { + private long next = 0; + + boolean hasNext() { + return next < size(); + } + + Address next() { + if (next >= size()) { + throw new RuntimeException("OOIBE"); + } + + return at(next++); + } } } --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZCollectedHeap.java 2019-02-14 18:20:32.504217991 +0100 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZCollectedHeap.java 2019-02-14 18:20:32.032217995 +0100 @@ -25,6 +25,7 @@ package sun.jvm.hotspot.gc.z; import java.io.PrintStream; +import java.util.Iterator; import sun.jvm.hotspot.debugger.Address; import sun.jvm.hotspot.debugger.OopHandle; @@ -121,9 +122,11 @@ @Override public void liveRegionsIterate(LiveRegionsClosure closure) { - // Operation (currently) not supported with ZGC. Print - // a warning and leave the list of live regions empty. - System.err.println("Warning: Operation not supported with ZGC"); + Iterator iter = heap().pageTable().activePagesIterator(); + while (iter.hasNext()) { + ZPage page = iter.next(); + closure.doLiveRegions(page); + } } @Override --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZExternalBitMap.java 2019-02-14 18:20:33.140217987 +0100 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZExternalBitMap.java 2019-02-14 18:20:32.632217990 +0100 @@ -47,7 +47,7 @@ throw new RuntimeException("Not a Z offset: " + zOffset); } - ZPage page = pageTable.get(ZOop.to_address(zOffset)); + ZPage page = pageTable.get(ZUtils.longToAddress(zOffset)); if (page == null) { throw new RuntimeException("Address not in pageTable: " + zOffset); } --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZGlobals.java 2019-02-14 18:20:33.800217982 +0100 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZGlobals.java 2019-02-14 18:20:33.268217986 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, 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 @@ -54,6 +54,7 @@ // Pointer part of address public static long ZAddressOffsetBits; public static long ZAddressOffsetMask; + public static long ZAddressOffsetMax; // Address space start/end/size public static long ZAddressSpaceStart; @@ -84,6 +85,7 @@ ZAddressOffsetBits = db.lookupLongConstant("ZAddressOffsetBits").longValue(); ZAddressOffsetMask = db.lookupLongConstant("ZAddressOffsetMask").longValue(); + ZAddressOffsetMax = db.lookupLongConstant("ZAddressOffsetMax").longValue(); ZAddressSpaceStart = db.lookupLongConstant("ZAddressSpaceStart").longValue(); } @@ -96,6 +98,10 @@ return instance().ZGlobalPhase(); } + public static int ZGlobalSeqNum() { + return instance().ZGlobalSeqNum(); + } + public static long ZAddressGoodMask() { return instance().ZAddressGoodMask(); } --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZGlobalsForVMStructs.java 2019-02-14 18:20:34.392217977 +0100 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZGlobalsForVMStructs.java 2019-02-14 18:20:33.924217981 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, 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 @@ -33,6 +33,7 @@ class ZGlobalsForVMStructs extends VMObject { private static AddressField ZGlobalPhaseField; + private static AddressField ZGlobalSeqNumField; private static AddressField ZAddressGoodMaskField; private static AddressField ZAddressBadMaskField; private static AddressField ZAddressWeakBadMaskField; @@ -47,6 +48,7 @@ Type type = db.lookupType("ZGlobalsForVMStructs"); ZGlobalPhaseField = type.getAddressField("_ZGlobalPhase"); + ZGlobalSeqNumField = type.getAddressField("_ZGlobalSeqNum"); ZAddressGoodMaskField = type.getAddressField("_ZAddressGoodMask"); ZAddressBadMaskField = type.getAddressField("_ZAddressBadMask"); ZAddressWeakBadMaskField = type.getAddressField("_ZAddressWeakBadMask"); @@ -62,6 +64,10 @@ return ZGlobalPhaseField.getValue(addr).getJIntAt(0); } + int ZGlobalSeqNum() { + return ZGlobalSeqNumField.getValue(addr).getJIntAt(0); + } + long ZAddressGoodMask() { return ZAddressGoodMaskField.getValue(addr).getJLongAt(0); } --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZOop.java 2019-02-14 18:20:35.036217973 +0100 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZOop.java 2019-02-14 18:20:34.524217976 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, 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,23 +26,9 @@ import sun.jvm.hotspot.debugger.Address; import sun.jvm.hotspot.debugger.OopHandle; -import sun.jvm.hotspot.runtime.VM; class ZOop { - private static final long MSB = ~0L ^ (~0L >>> 1); - - private static Address msbAddress() { - return VM.getVM().getUniverse().heap().start().orWithMask(MSB).andWithMask(MSB); - } - - static Address to_address(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 Address to_address(OopHandle oop) { - return to_address(ZAddress.as_long(oop)); + return ZUtils.longToAddress(ZAddress.as_long(oop)); } } --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPage.java 2019-02-14 18:20:35.672217968 +0100 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPage.java 2019-02-14 18:20:35.168217972 +0100 @@ -24,17 +24,29 @@ package sun.jvm.hotspot.gc.z; +import java.util.ArrayList; +import java.util.List; + import sun.jvm.hotspot.debugger.Address; +import sun.jvm.hotspot.debugger.OopHandle; +import sun.jvm.hotspot.gc.shared.LiveRegionsProvider; +import sun.jvm.hotspot.memory.MemRegion; +import sun.jvm.hotspot.oops.Oop; +import sun.jvm.hotspot.oops.UnknownOopException; 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 ZPage extends VMObject { +public class ZPage extends VMObject implements LiveRegionsProvider { private static CIntegerField typeField; + private static CIntegerField seqnumField; private static long virtualFieldOffset; + private static AddressField topField; + private static CIntegerField refcountField; private static long forwardingFieldOffset; static { @@ -45,7 +57,10 @@ Type type = db.lookupType("ZPage"); typeField = type.getCIntegerField("_type"); + seqnumField = type.getCIntegerField("_seqnum"); virtualFieldOffset = type.getField("_virtual").getOffset(); + topField = type.getAddressField("_top"); + refcountField = type.getCIntegerField("_refcount"); forwardingFieldOffset = type.getField("_forwarding").getOffset(); } @@ -57,12 +72,40 @@ return typeField.getJByte(addr); } + private int seqnum() { + return seqnumField.getJInt(addr); + } + private ZVirtualMemory virtual() { - return (ZVirtualMemory)VMObjectFactory.newObject(ZVirtualMemory.class, addr.addOffsetTo(virtualFieldOffset)); + return VMObjectFactory.newObject(ZVirtualMemory.class, addr.addOffsetTo(virtualFieldOffset)); + } + + private Address top() { + 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 (ZForwardingTable)VMObjectFactory.newObject(ZForwardingTable.class, addr.addOffsetTo(forwardingFieldOffset)); + 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(); } long start() { @@ -98,7 +141,6 @@ return ZAddress.good(from); } - long object_alignment_shift() { if (type() == ZGlobals.ZPageTypeSmall) { return ZGlobals.ZObjectAlignmentSmallShift(); @@ -109,4 +151,94 @@ return ZGlobals.ZObjectAlignmentLargeShift; } } + + long objectAlignmentSize() { + return 1 << object_alignment_shift(); + } + + public boolean is_active() { + return refcount() != 0; + } + + private long getObjectSize(Address good) { + OopHandle handle = good.addOffsetToAsOopHandle(0); + Oop obj = null; + + try { + obj = VM.getVM().getObjectHeap().newOop(handle); + } catch (UnknownOopException exp) { + throw new RuntimeException(" UnknownOopException " + exp); + } + + return VM.getVM().alignUp(obj.getObjectSize(), objectAlignmentSize()); + } + + private void addNotRelocatedRegions(List 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 getLiveRegions() { + List res = new ArrayList<>(); + + 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); + + res.add(new MemRegion(start, end)); + } + + return res; + } } --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPageTable.java 2019-02-14 18:20:36.268217964 +0100 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPageTable.java 2019-02-14 18:20:35.804217967 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, 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 @@ -24,6 +24,8 @@ 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; @@ -63,4 +65,112 @@ boolean is_relocating(Address o) { return getEntry(o).relocating(); } + + private class ZPagesIterator implements Iterator { + private ZAddressRangeMapForPageTable.Iterator mapIter; + private ZPage next; + + ZPagesIterator() { + mapIter = map().new Iterator(); + positionToNext(); + } + + private ZPage positionToNext() { + ZPage current = next; + + // Find next + ZPage found = null; + while (mapIter.hasNext()) { + ZPageTableEntry entry = new ZPageTableEntry(mapIter.next()); + if (!entry.isEmpty()) { + ZPage page = entry.page(); + // Medium pages have repeated entries for all covered slots, + // therefore we need to compare against the current page. + if (page != null && !page.equals(current)) { + found = page; + break; + } + } + } + + next = found; + + return current; + } + + @Override + public boolean hasNext() { + return next != null; + } + + @Override + public ZPage next() { + return positionToNext(); + } + + @Override + public void remove() { + /* not supported */ + } + } + + abstract class ZPageFilter { + public abstract boolean accept(ZPage page); + } + + class ZPagesFilteredIterator implements Iterator { + private ZPage next; + private ZPagesIterator iter = new ZPagesIterator(); + private ZPageFilter filter; + + ZPagesFilteredIterator(ZPageFilter filter) { + this.filter = filter; + positionToNext(); + } + + public ZPage positionToNext() { + ZPage current = next; + + // Find next + ZPage found = null; + while (iter.hasNext()) { + ZPage page = iter.next(); + if (filter.accept(page)) { + found = page; + break; + } + } + + next = found; + + return current; + } + + @Override + public boolean hasNext() { + return next != null; + } + + @Override + public ZPage next() { + return positionToNext(); + } + + @Override + public void remove() { + /* not supported */ + } + } + + public Iterator iterator() { + return new ZPagesIterator(); + } + + public Iterator activePagesIterator() { + return new ZPagesFilteredIterator(new ZPageFilter() { + public boolean accept(ZPage page) { + return page.is_active(); + } + }); + } } --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPageTableEntry.java 2019-02-14 18:20:36.900217959 +0100 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPageTableEntry.java 2019-02-14 18:20:36.400217963 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, 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 @@ -35,10 +35,18 @@ } ZPage page() { - return (ZPage)VMObjectFactory.newObject(ZPage.class, entry.andWithMask(~1L)); + return (ZPage)VMObjectFactory.newObject(ZPage.class, zPageBits()); + } + + private Address zPageBits() { + return entry.andWithMask(~1L); } boolean relocating() { return (entry.asLongValue() & 1) == 1; } + + boolean isEmpty() { + return entry == null || zPageBits() == null; + } } --- /dev/null 2019-02-14 11:31:37.500399000 +0100 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZUtils.java 2019-02-14 18:20:37.028217958 +0100 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018, 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 + * 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; + +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) { + // 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)); + } +}