8218734: SA: Incorrect and raw loads of OopHandles
authorstefank
Tue, 19 Feb 2019 10:02:42 +0100
changeset 53811 935d31867930
parent 53810 d52887bc636f
child 53812 1199185efca1
8218734: SA: Incorrect and raw loads of OopHandles Reviewed-by: eosterlund, coleenp, jgeorge
src/hotspot/share/oops/oopHandle.hpp
src/hotspot/share/runtime/vmStructs.cpp
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/classfile/ClassLoaderData.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeap.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZCollectedHeap.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/VMOopHandle.java
--- a/src/hotspot/share/oops/oopHandle.hpp	Tue Feb 19 10:02:00 2019 +0100
+++ b/src/hotspot/share/oops/oopHandle.hpp	Tue Feb 19 10:02:42 2019 +0100
@@ -36,6 +36,7 @@
 // future uses for read barriers.
 
 class OopHandle {
+  friend class VMStructs;
 private:
   oop* _obj;
 
--- a/src/hotspot/share/runtime/vmStructs.cpp	Tue Feb 19 10:02:00 2019 +0100
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Tue Feb 19 10:02:42 2019 +0100
@@ -332,6 +332,7 @@
   unchecked_nonstatic_field(Symbol,            _body,                                         sizeof(u1)) /* NOTE: no type */        \
   nonstatic_field(Symbol,                      _body[0],                                      u1)                                    \
   nonstatic_field(TypeArrayKlass,              _max_length,                                   jint)                                  \
+  nonstatic_field(OopHandle,                   _obj,                                          oop*)                                  \
                                                                                                                                      \
   /***********************/                                                                                                          \
   /* Constant Pool Cache */                                                                                                          \
@@ -1299,7 +1300,8 @@
   declare_oop_type(oop)                                                   \
   declare_oop_type(narrowOop)                                             \
   declare_oop_type(typeArrayOop)                                          \
-  declare_oop_type(OopHandle)                                             \
+                                                                          \
+  declare_toplevel_type(OopHandle)                                        \
                                                                           \
   /*************************************/                                 \
   /* MethodOop-related data structures */                                 \
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/classfile/ClassLoaderData.java	Tue Feb 19 10:02:00 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/classfile/ClassLoaderData.java	Tue Feb 19 10:02:42 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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,7 +24,6 @@
 
 package sun.jvm.hotspot.classfile;
 
-import java.io.PrintStream;
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.memory.*;
 import sun.jvm.hotspot.runtime.*;
@@ -42,14 +41,14 @@
 
   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
     Type type      = db.lookupType("ClassLoaderData");
-    classLoaderField = type.getAddressField("_class_loader");
+    classLoaderFieldOffset = type.getAddressField("_class_loader").getOffset();
     nextField = type.getAddressField("_next");
     klassesField = new MetadataField(type.getAddressField("_klasses"), 0);
     isUnsafeAnonymousField = new CIntField(type.getCIntegerField("_is_unsafe_anonymous"), 0);
     dictionaryField = type.getAddressField("_dictionary");
   }
 
-  private static AddressField   classLoaderField;
+  private static long classLoaderFieldOffset;
   private static AddressField nextField;
   private static MetadataField  klassesField;
   private static CIntField isUnsafeAnonymousField;
@@ -72,13 +71,9 @@
   }
 
   public Oop getClassLoader() {
-    Address handle = classLoaderField.getValue(getAddress());
-    if (handle != null) {
-      // Load through the handle
-      OopHandle refs = handle.getOopHandleAt(0);
-      return (Instance)VM.getVM().getObjectHeap().newOop(refs);
-    }
-    return null;
+    Address addr = getAddress().addOffsetTo(classLoaderFieldOffset);
+    VMOopHandle vmOopHandle = VMObjectFactory.newObject(VMOopHandle.class, addr);
+    return vmOopHandle.resolve();
   }
 
   public boolean getisUnsafeAnonymous() {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeap.java	Tue Feb 19 10:02:00 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/shared/CollectedHeap.java	Tue Feb 19 10:02:42 2019 +0100
@@ -83,6 +83,10 @@
       return handle.getOopHandleAt(offset);
   }
 
+  public OopHandle oop_load_in_native(Address addr) {
+      return addr.getOopHandleAt(0);
+  }
+
   public void print() { printOn(System.out); }
   public void printOn(PrintStream tty) {
     MemRegion mr = reservedRegion();
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZCollectedHeap.java	Tue Feb 19 10:02:00 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZCollectedHeap.java	Tue Feb 19 10:02:42 2019 +0100
@@ -80,11 +80,9 @@
         return heap().used();
     }
 
-    public OopHandle oop_load_at(OopHandle handle, long offset) {
-        assert(!VM.getVM().isCompressedOopsEnabled());
+
 
-        Address oopAddress = handle.getAddressAt(offset);
-
+    private OopHandle oop_load_barrier(Address oopAddress) {
         oopAddress = ZBarrier.weak_barrier(oopAddress);
         if (oopAddress == null) {
             return null;
@@ -93,6 +91,23 @@
         return oopAddress.addOffsetToAsOopHandle(0);
     }
 
+    @Override
+    public OopHandle oop_load_at(OopHandle handle, long offset) {
+        assert(!VM.getVM().isCompressedOopsEnabled());
+
+        Address oopAddress = handle.getAddressAt(offset);
+
+        return oop_load_barrier(oopAddress);
+    }
+
+    // addr can be either in heap or in native
+    @Override
+    public OopHandle oop_load_in_native(Address addr) {
+        Address oopAddress = addr.getAddressAt(0);
+
+        return oop_load_barrier(oopAddress);
+    }
+
     public String oopAddressDescription(OopHandle handle) {
         Address origOop = ZOop.to_address(handle);
         Address loadBarrieredOop = ZBarrier.weak_barrier(origOop);
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java	Tue Feb 19 10:02:00 2019 +0100
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java	Tue Feb 19 10:02:42 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -51,7 +51,7 @@
 
   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
     Type type    = db.lookupType("Klass");
-    javaMirror   = type.getAddressField("_java_mirror");
+    javaMirrorFieldOffset = type.getField("_java_mirror").getOffset();
     superField   = new MetadataField(type.getAddressField("_super"), 0);
     layoutHelper = new IntField(type.getJIntField("_layout_helper"), 0);
     name         = type.getAddressField("_name");
@@ -89,7 +89,7 @@
   public boolean isArrayKlass()        { return false; }
 
   // Fields
-  private static AddressField   javaMirror;
+  private static long javaMirrorFieldOffset;
   private static MetadataField  superField;
   private static IntField layoutHelper;
   private static AddressField  name;
@@ -101,23 +101,15 @@
   private static CIntField vtableLen;
   private static AddressField classLoaderData;
 
-  private Address getValue(AddressField field) {
-    return addr.getAddressAt(field.getOffset());
-  }
-
   protected Symbol getSymbol(AddressField field) {
     return Symbol.create(addr.getAddressAt(field.getOffset()));
   }
 
   // Accessors for declared fields
   public Instance getJavaMirror() {
-    Address handle = javaMirror.getValue(getAddress());
-    if (handle != null) {
-      // Load through the handle
-      OopHandle refs = handle.getOopHandleAt(0);
-      return (Instance)VM.getVM().getObjectHeap().newOop(refs);
-    }
-    return null;
+    Address addr = getAddress().addOffsetTo(javaMirrorFieldOffset);
+    VMOopHandle vmOopHandle = VMObjectFactory.newObject(VMOopHandle.class, addr);
+    return vmOopHandle.resolve();
   }
   public Klass    getSuper()            { return (Klass)    superField.getValue(this);   }
   public Klass    getJavaSuper()        { return null;  }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/VMOopHandle.java	Tue Feb 19 10:02:42 2019 +0100
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 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
+ * 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.oops;
+
+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.types.AddressField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+public class VMOopHandle extends VMObject {
+    private static AddressField objField;
+
+    static {
+        VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
+    }
+
+    private static synchronized void initialize(TypeDataBase db) {
+        Type type = db.lookupType("OopHandle");
+
+        objField = type.getAddressField("_obj");
+    }
+
+    public VMOopHandle(Address addr) {
+        super(addr);
+    }
+
+    public Address getObj() {
+        return objField.getValue(addr);
+    }
+
+    public Instance resolve() {
+        Address handle = getObj();
+        if (handle != null) {
+          // Load through the handle
+          OopHandle refs = VM.getVM().getUniverse().heap().oop_load_in_native(handle);
+          return (Instance)VM.getVM().getObjectHeap().newOop(refs);
+        }
+        return null;
+    }
+}