8218734: SA: Incorrect and raw loads of OopHandles

Reviewed-by: eosterlund, coleenp, jgeorge
This commit is contained in:
Stefan Karlsson 2019-02-19 10:02:42 +01:00
parent 797122c227
commit 5f5c6362d9
7 changed files with 103 additions and 29 deletions

View File

@ -36,6 +36,7 @@
// future uses for read barriers.
class OopHandle {
friend class VMStructs;
private:
oop* _obj;

View File

@ -332,6 +332,7 @@ typedef PaddedEnd<ObjectMonitor> PaddedObjectMonitor;
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 @@ typedef PaddedEnd<ObjectMonitor> PaddedObjectMonitor;
declare_oop_type(oop) \
declare_oop_type(narrowOop) \
declare_oop_type(typeArrayOop) \
declare_oop_type(OopHandle) \
\
declare_toplevel_type(OopHandle) \
\
/*************************************/ \
/* MethodOop-related data structures */ \

View File

@ -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 @@ public class ClassLoaderData extends VMObject {
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 class ClassLoaderData extends VMObject {
}
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() {

View File

@ -83,6 +83,10 @@ public abstract class CollectedHeap extends VMObject {
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();

View File

@ -80,11 +80,9 @@ public class ZCollectedHeap extends CollectedHeap {
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 @@ public class ZCollectedHeap extends CollectedHeap {
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);

View File

@ -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 @@ public class Klass extends Metadata implements ClassConstants {
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 class Klass extends Metadata implements ClassConstants {
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 @@ public class Klass extends Metadata implements ClassConstants {
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; }

View File

@ -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;
}
}