8025925: jmap fails with "field _length not found in type HeapRegionSeq"
Summary: The change JDK-7163191 changed the data layout of a class that is referenced by the java code of the SA agent. This fix synchronizes the SA agent with that change.
Reviewed-by: sla, mgerdin
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/G1HeapRegionTable.java Wed Oct 16 11:46:06 2013 +0200
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2013, 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_implementation.g1;
+
+import java.util.Iterator;
+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.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;
+
+// Mirror class for G1HeapRegionTable. It's essentially an index -> HeapRegion map.
+
+public class G1HeapRegionTable extends VMObject {
+ // HeapRegion** _base;
+ static private AddressField baseField;
+ // uint _length;
+ static private CIntegerField lengthField;
+ // HeapRegion** _biased_base
+ static private AddressField biasedBaseField;
+ // size_t _bias
+ static private CIntegerField biasField;
+ // uint _shift_by
+ static private CIntegerField shiftByField;
+
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ static private synchronized void initialize(TypeDataBase db) {
+ Type type = db.lookupType("G1HeapRegionTable");
+
+ baseField = type.getAddressField("_base");
+ lengthField = type.getCIntegerField("_length");
+ biasedBaseField = type.getAddressField("_biased_base");
+ biasField = type.getCIntegerField("_bias");
+ shiftByField = type.getCIntegerField("_shift_by");
+ }
+
+ private HeapRegion at(long index) {
+ Address arrayAddr = baseField.getValue(addr);
+ // Offset of &_base[index]
+ long offset = index * VM.getVM().getAddressSize();
+ Address regionAddr = arrayAddr.getAddressAt(offset);
+ return (HeapRegion) VMObjectFactory.newObject(HeapRegion.class,
+ regionAddr);
+ }
+
+ public long length() {
+ return lengthField.getValue(addr);
+ }
+
+ public long bias() {
+ return biasField.getValue(addr);
+ }
+
+ public long shiftBy() {
+ return shiftByField.getValue(addr);
+ }
+
+ private class HeapRegionIterator implements Iterator<HeapRegion> {
+ private long index;
+ private long length;
+
+ @Override
+ public boolean hasNext() { return index < length; }
+
+ @Override
+ public HeapRegion next() { return at(index++); }
+
+ @Override
+ public void remove() { /* not supported */ }
+
+ HeapRegionIterator(Address addr) {
+ index = 0;
+ length = length();
+ }
+ }
+
+ public Iterator<HeapRegion> heapRegionIterator() {
+ return new HeapRegionIterator(addr);
+ }
+
+ public G1HeapRegionTable(Address addr) {
+ super(addr);
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java Tue Oct 15 14:32:20 2013 +0200
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java Wed Oct 16 11:46:06 2013 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, 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
@@ -37,13 +37,11 @@
import sun.jvm.hotspot.types.Type;
import sun.jvm.hotspot.types.TypeDataBase;
-// Mirror class for HeapRegionSeq. It's essentially an index -> HeapRegion map.
+// Mirror class for HeapRegionSeq. It essentially encapsulates the G1HeapRegionTable.
public class HeapRegionSeq extends VMObject {
- // HeapRegion** _regions;
- static private AddressField regionsField;
- // uint _length;
- static private CIntegerField lengthField;
+ // G1HeapRegionTable _regions
+ static private long regionsFieldOffset;
static {
VM.registerVMInitializedObserver(new Observer() {
@@ -56,44 +54,21 @@
static private synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("HeapRegionSeq");
- regionsField = type.getAddressField("_regions");
- lengthField = type.getCIntegerField("_length");
+ regionsFieldOffset = type.getField("_regions").getOffset();
}
- private HeapRegion at(long index) {
- Address arrayAddr = regionsField.getValue(addr);
- // Offset of &_region[index]
- long offset = index * VM.getVM().getAddressSize();
- Address regionAddr = arrayAddr.getAddressAt(offset);
- return (HeapRegion) VMObjectFactory.newObject(HeapRegion.class,
- regionAddr);
+ private G1HeapRegionTable regions() {
+ Address regionsAddr = addr.addOffsetTo(regionsFieldOffset);
+ return (G1HeapRegionTable) VMObjectFactory.newObject(G1HeapRegionTable.class,
+ regionsAddr);
}
public long length() {
- return lengthField.getValue(addr);
- }
-
- private class HeapRegionIterator implements Iterator<HeapRegion> {
- private long index;
- private long length;
-
- @Override
- public boolean hasNext() { return index < length; }
-
- @Override
- public HeapRegion next() { return at(index++); }
-
- @Override
- public void remove() { /* not supported */ }
-
- HeapRegionIterator(Address addr) {
- index = 0;
- length = length();
- }
+ return regions().length();
}
public Iterator<HeapRegion> heapRegionIterator() {
- return new HeapRegionIterator(addr);
+ return regions().heapRegionIterator();
}
public HeapRegionSeq(Address addr) {