--- old/src/hotspot/share/gc/g1/heapRegionType.hpp 2017-09-26 23:51:57.471796695 +0900 +++ new/src/hotspot/share/gc/g1/heapRegionType.hpp 2017-09-26 23:51:57.243795771 +0900 @@ -32,6 +32,8 @@ assert(is_valid((tag)), "invalid HR type: %u", (uint) (tag)) class HeapRegionType VALUE_OBJ_CLASS_SPEC { +friend class VMStructs; + private: // We encode the value of the heap region type so the generation can be // determined quickly. The tag is split into two parts: --- old/src/hotspot/share/gc/g1/vmStructs_g1.hpp 2017-09-26 23:51:57.975798737 +0900 +++ new/src/hotspot/share/gc/g1/vmStructs_g1.hpp 2017-09-26 23:51:57.772797914 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, 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,6 +35,10 @@ static_field(HeapRegion, GrainBytes, size_t) \ static_field(HeapRegion, LogOfHRGrainBytes, int) \ \ + nonstatic_field(HeapRegion, _type, HeapRegionType) \ + \ + nonstatic_field(HeapRegionType, _tag, HeapRegionType::Tag volatile) \ + \ nonstatic_field(G1ContiguousSpace, _top, HeapWord* volatile) \ \ nonstatic_field(G1HeapRegionTable, _base, address) \ @@ -67,9 +71,16 @@ #define VM_INT_CONSTANTS_G1(declare_constant, declare_constant_with_value) \ + declare_constant(HeapRegionType::FreeTag) \ + declare_constant(HeapRegionType::YoungMask) \ + declare_constant(HeapRegionType::HumongousMask) \ + declare_constant(HeapRegionType::PinnedMask) \ + declare_constant(HeapRegionType::OldMask) -#define VM_TYPES_G1(declare_type, declare_toplevel_type) \ +#define VM_TYPES_G1(declare_type, \ + declare_toplevel_type, \ + declare_integer_type) \ \ declare_toplevel_type(G1HeapRegionTable) \ \ @@ -81,9 +92,12 @@ declare_toplevel_type(HeapRegionSetBase) \ declare_toplevel_type(G1MonitoringSupport) \ declare_toplevel_type(PtrQueue) \ + declare_toplevel_type(HeapRegionType) \ \ declare_toplevel_type(G1CollectedHeap*) \ declare_toplevel_type(HeapRegion*) \ declare_toplevel_type(G1MonitoringSupport*) \ + \ + declare_integer_type(HeapRegionType::Tag volatile) #endif // SHARE_VM_GC_G1_VMSTRUCTS_G1_HPP --- old/src/hotspot/share/runtime/vmStructs.cpp 2017-09-26 23:51:58.498800855 +0900 +++ new/src/hotspot/share/runtime/vmStructs.cpp 2017-09-26 23:51:58.280799972 +0900 @@ -3009,7 +3009,8 @@ VM_TYPES_PARNEW(GENERATE_VM_TYPE_ENTRY) VM_TYPES_G1(GENERATE_VM_TYPE_ENTRY, - GENERATE_TOPLEVEL_VM_TYPE_ENTRY) + GENERATE_TOPLEVEL_VM_TYPE_ENTRY, + GENERATE_INTEGER_VM_TYPE_ENTRY) #endif // INCLUDE_ALL_GCS #if INCLUDE_TRACE @@ -3207,6 +3208,7 @@ VM_TYPES_PARNEW(CHECK_VM_TYPE_ENTRY) VM_TYPES_G1(CHECK_VM_TYPE_ENTRY, + CHECK_SINGLE_ARG_VM_TYPE_NO_OP, CHECK_SINGLE_ARG_VM_TYPE_NO_OP); #endif // INCLUDE_ALL_GCS --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java 2017-09-26 23:51:59.150803497 +0900 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java 2017-09-26 23:51:58.941802650 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2017, 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,6 +35,7 @@ import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.gc.parallel.*; import sun.jvm.hotspot.gc.shared.*; +import sun.jvm.hotspot.gc.g1.*; import sun.jvm.hotspot.interpreter.*; import sun.jvm.hotspot.memory.*; import sun.jvm.hotspot.oops.*; @@ -1078,6 +1079,26 @@ } } + } else if (collHeap instanceof G1CollectedHeap) { + G1CollectedHeap heap = (G1CollectedHeap)collHeap; + HeapRegion region = heap.hrm().addrToRegion(handle); + + if (region.isFree()) { + anno = "Free "; + bad = false; + } else if (region.isYoung()) { + anno = "Young "; + bad = false; + } else if (region.isHumongous()) { + anno = "Humongous "; + bad = false; + } else if (region.isPinned()) { + anno = "Pinned "; + bad = false; + } else if (region.isOld()) { + anno = "Old "; + bad = false; + } } else if (collHeap instanceof ParallelScavengeHeap) { ParallelScavengeHeap heap = (ParallelScavengeHeap) collHeap; if (heap.youngGen().isIn(handle)) { --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java 2017-09-26 23:51:59.738805879 +0900 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java 2017-09-26 23:51:59.489804870 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, 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 @@ -87,7 +87,7 @@ return hrm().length(); } - private HeapRegionManager hrm() { + public HeapRegionManager hrm() { Address hrmAddr = addr.addOffsetTo(hrmFieldOffset); return (HeapRegionManager) VMObjectFactory.newObject(HeapRegionManager.class, hrmAddr); --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1HeapRegionTable.java 2017-09-26 23:52:00.288808107 +0900 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1HeapRegionTable.java 2017-09-26 23:52:00.076807248 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, 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,7 @@ import java.util.Observer; import sun.jvm.hotspot.debugger.Address; +import sun.jvm.hotspot.debugger.OopHandle; import sun.jvm.hotspot.runtime.VM; import sun.jvm.hotspot.runtime.VMObject; import sun.jvm.hotspot.runtime.VMObjectFactory; @@ -36,6 +37,7 @@ import sun.jvm.hotspot.types.CIntegerField; import sun.jvm.hotspot.types.Type; import sun.jvm.hotspot.types.TypeDataBase; +import sun.jvm.hotspot.utilities.Assert; // Mirror class for G1HeapRegionTable. It's essentially an index -> HeapRegion map. @@ -132,4 +134,14 @@ public G1HeapRegionTable(Address addr) { super(addr); } + + public HeapRegion getByAddress(Address addr) { + if (Assert.ASSERTS_ENABLED) { + Assert.that(addr instanceof OopHandle, "addr should be OopHandle"); + } + + long biasedIndex = addr.asLongValue() >>> shiftBy(); + return new HeapRegion(addr.addOffsetToAsOopHandle( + biasedIndex * HeapRegion.getPointerSize())); + } } --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegion.java 2017-09-26 23:52:00.812810230 +0900 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegion.java 2017-09-26 23:52:00.585809311 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, 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,13 +29,16 @@ import java.util.Observable; import java.util.Observer; import sun.jvm.hotspot.debugger.Address; +import sun.jvm.hotspot.debugger.OopHandle; import sun.jvm.hotspot.gc.shared.CompactibleSpace; import sun.jvm.hotspot.memory.MemRegion; import sun.jvm.hotspot.runtime.VM; +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; +import sun.jvm.hotspot.utilities.Assert; // Mirror class for HeapRegion. Currently we don't actually include // any of its fields but only iterate over it. @@ -44,6 +47,10 @@ // static int GrainBytes; static private CIntegerField grainBytesField; static private AddressField topField; + private static long typeFieldOffset; + private static long pointerSize; + + private HeapRegionType type; static { VM.registerVMInitializedObserver(new Observer() { @@ -54,11 +61,13 @@ } static private synchronized void initialize(TypeDataBase db) { - Type type = db.lookupType("HeapRegion"); + Type t = db.lookupType("HeapRegion"); - grainBytesField = type.getCIntegerField("GrainBytes"); - topField = type.getAddressField("_top"); + grainBytesField = t.getCIntegerField("GrainBytes"); + topField = t.getAddressField("_top"); + typeFieldOffset = t.getField("_type").getOffset(); + pointerSize = db.lookupType("HeapRegion*").getSize(); } static public long grainBytes() { @@ -67,6 +76,14 @@ public HeapRegion(Address addr) { super(addr); + + if (Assert.ASSERTS_ENABLED) { + Assert.that(addr instanceof OopHandle, "addr should be OopHandle"); + } + + Address typeAddr = addr.addOffsetToAsOopHandle(typeFieldOffset); + type = (HeapRegionType)VMObjectFactory.newObject( + HeapRegionType.class, typeAddr); } public Address top() { @@ -89,4 +106,28 @@ public long free() { return end().minus(top()); } + + public boolean isFree() { + return type.isFree(); + } + + public boolean isYoung() { + return type.isYoung(); + } + + public boolean isHumongous() { + return type.isHumongous(); + } + + public boolean isPinned() { + return type.isPinned(); + } + + public boolean isOld() { + return type.isOld(); + } + + public static long getPointerSize() { + return pointerSize; + } } --- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionManager.java 2017-09-26 23:52:01.384812548 +0900 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionManager.java 2017-09-26 23:52:01.153811612 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, 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 @@ -85,4 +85,8 @@ public HeapRegionManager(Address addr) { super(addr); } + + public HeapRegion addrToRegion(Address addr) { + return regions().getByAddress(addr); + } } --- /dev/null 2017-09-26 23:34:53.308187500 +0900 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionType.java 2017-09-26 23:52:01.681813751 +0900 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2017, 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.g1; + +import java.util.Observable; +import java.util.Observer; +import sun.jvm.hotspot.debugger.Address; +import sun.jvm.hotspot.runtime.VM; +import sun.jvm.hotspot.runtime.VMObject; +import sun.jvm.hotspot.types.CIntegerField; +import sun.jvm.hotspot.types.Type; +import sun.jvm.hotspot.types.TypeDataBase; + +// Mirror class for HeapRegionType. Currently we don't actually include +// any of its fields but only iterate over it. + +public class HeapRegionType extends VMObject { + + private static int freeTag; + + private static int youngMask; + + private static int humongousMask; + + private static int pinnedMask; + + private static int oldMask; + + private static CIntegerField tagField; + + private int tag; + + static { + VM.registerVMInitializedObserver(new Observer() { + public void update(Observable o, Object data) { + initialize(VM.getVM().getTypeDataBase()); + } + }); + } + + private static synchronized void initialize(TypeDataBase db) { + Type type = db.lookupType("HeapRegionType"); + + tagField = type.getCIntegerField("_tag"); + + youngMask = db.lookupIntConstant("HeapRegionType::YoungMask"); + humongousMask = db.lookupIntConstant("HeapRegionType::HumongousMask"); + oldMask = db.lookupIntConstant("HeapRegionType::OldMask"); + } + + public boolean isFree() { + return tagField.getValue(addr) == freeTag; + } + + public boolean isYoung() { + return (tagField.getValue(addr) & youngMask) != 0; + } + + public boolean isHumongous() { + return (tagField.getValue(addr) & humongousMask) != 0; + } + + public boolean isPinned() { + return (tagField.getValue(addr) & pinnedMask) != 0; + } + + public boolean isOld() { + return (tagField.getValue(addr) & oldMask) != 0; + } + + public HeapRegionType(Address addr) { + super(addr); + } +}