8187403: [Unknown generation] is shown in Stack Memory on HSDB
authorysuenaga
Sat, 07 Oct 2017 22:45:12 +0900
changeset 47602 d4380ee1cbe9
parent 47601 f9ace8da5e9c
child 47603 f5f98c9f1884
8187403: [Unknown generation] is shown in Stack Memory on HSDB Reviewed-by: sspitsyn, jgeorge
src/hotspot/share/gc/g1/heapRegionType.hpp
src/hotspot/share/gc/g1/vmStructs_g1.hpp
src/hotspot/share/runtime/vmStructs.cpp
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1HeapRegionTable.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegion.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionManager.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionType.java
--- a/src/hotspot/share/gc/g1/heapRegionType.hpp	Sat Oct 07 22:42:35 2017 +0900
+++ b/src/hotspot/share/gc/g1/heapRegionType.hpp	Sat Oct 07 22:45:12 2017 +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:
--- a/src/hotspot/share/gc/g1/vmStructs_g1.hpp	Sat Oct 07 22:42:35 2017 +0900
+++ b/src/hotspot/share/gc/g1/vmStructs_g1.hpp	Sat Oct 07 22:45:12 2017 +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
--- a/src/hotspot/share/runtime/vmStructs.cpp	Sat Oct 07 22:42:35 2017 +0900
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Sat Oct 07 22:45:12 2017 +0900
@@ -3013,7 +3013,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
@@ -3211,6 +3212,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
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java	Sat Oct 07 22:42:35 2017 +0900
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HSDB.java	Sat Oct 07 22:45:12 2017 +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().getByAddress(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)) {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java	Sat Oct 07 22:42:35 2017 +0900
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1CollectedHeap.java	Sat Oct 07 22:45:12 2017 +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);
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1HeapRegionTable.java	Sat Oct 07 22:42:35 2017 +0900
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/G1HeapRegionTable.java	Sat Oct 07 22:45:12 2017 +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,13 @@
     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()));
+    }
 }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegion.java	Sat Oct 07 22:42:35 2017 +0900
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegion.java	Sat Oct 07 22:45:12 2017 +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() {
@@ -58,7 +65,9 @@
 
         grainBytesField = type.getCIntegerField("GrainBytes");
         topField = type.getAddressField("_top");
+        typeFieldOffset = type.getField("_type").getOffset();
 
+        pointerSize = db.lookupType("HeapRegion*").getSize();
     }
 
     static public long grainBytes() {
@@ -67,6 +76,13 @@
 
     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 +105,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;
+    }
 }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionManager.java	Sat Oct 07 22:42:35 2017 +0900
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionManager.java	Sat Oct 07 22:45:12 2017 +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 getByAddress(Address addr) {
+      return regions().getByAddress(addr);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/g1/HeapRegionType.java	Sat Oct 07 22:45:12 2017 +0900
@@ -0,0 +1,92 @@
+/*
+ * 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");
+
+        freeTag = db.lookupIntConstant("HeapRegionType::FreeTag");
+        youngMask = db.lookupIntConstant("HeapRegionType::YoungMask");
+        humongousMask = db.lookupIntConstant("HeapRegionType::HumongousMask");
+        pinnedMask = db.lookupIntConstant("HeapRegionType::PinnedMask");
+        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);
+    }
+}