8218734: SA: Incorrect and raw loads of OopHandles
Reviewed-by: eosterlund, coleenp, jgeorge
This commit is contained in:
parent
797122c227
commit
5f5c6362d9
@ -36,6 +36,7 @@
|
|||||||
// future uses for read barriers.
|
// future uses for read barriers.
|
||||||
|
|
||||||
class OopHandle {
|
class OopHandle {
|
||||||
|
friend class VMStructs;
|
||||||
private:
|
private:
|
||||||
oop* _obj;
|
oop* _obj;
|
||||||
|
|
||||||
|
@ -332,6 +332,7 @@ typedef PaddedEnd<ObjectMonitor> PaddedObjectMonitor;
|
|||||||
unchecked_nonstatic_field(Symbol, _body, sizeof(u1)) /* NOTE: no type */ \
|
unchecked_nonstatic_field(Symbol, _body, sizeof(u1)) /* NOTE: no type */ \
|
||||||
nonstatic_field(Symbol, _body[0], u1) \
|
nonstatic_field(Symbol, _body[0], u1) \
|
||||||
nonstatic_field(TypeArrayKlass, _max_length, jint) \
|
nonstatic_field(TypeArrayKlass, _max_length, jint) \
|
||||||
|
nonstatic_field(OopHandle, _obj, oop*) \
|
||||||
\
|
\
|
||||||
/***********************/ \
|
/***********************/ \
|
||||||
/* Constant Pool Cache */ \
|
/* Constant Pool Cache */ \
|
||||||
@ -1299,7 +1300,8 @@ typedef PaddedEnd<ObjectMonitor> PaddedObjectMonitor;
|
|||||||
declare_oop_type(oop) \
|
declare_oop_type(oop) \
|
||||||
declare_oop_type(narrowOop) \
|
declare_oop_type(narrowOop) \
|
||||||
declare_oop_type(typeArrayOop) \
|
declare_oop_type(typeArrayOop) \
|
||||||
declare_oop_type(OopHandle) \
|
\
|
||||||
|
declare_toplevel_type(OopHandle) \
|
||||||
\
|
\
|
||||||
/*************************************/ \
|
/*************************************/ \
|
||||||
/* MethodOop-related data structures */ \
|
/* MethodOop-related data structures */ \
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
package sun.jvm.hotspot.classfile;
|
package sun.jvm.hotspot.classfile;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
|
||||||
import sun.jvm.hotspot.debugger.*;
|
import sun.jvm.hotspot.debugger.*;
|
||||||
import sun.jvm.hotspot.memory.*;
|
import sun.jvm.hotspot.memory.*;
|
||||||
import sun.jvm.hotspot.runtime.*;
|
import sun.jvm.hotspot.runtime.*;
|
||||||
@ -42,14 +41,14 @@ public class ClassLoaderData extends VMObject {
|
|||||||
|
|
||||||
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
||||||
Type type = db.lookupType("ClassLoaderData");
|
Type type = db.lookupType("ClassLoaderData");
|
||||||
classLoaderField = type.getAddressField("_class_loader");
|
classLoaderFieldOffset = type.getAddressField("_class_loader").getOffset();
|
||||||
nextField = type.getAddressField("_next");
|
nextField = type.getAddressField("_next");
|
||||||
klassesField = new MetadataField(type.getAddressField("_klasses"), 0);
|
klassesField = new MetadataField(type.getAddressField("_klasses"), 0);
|
||||||
isUnsafeAnonymousField = new CIntField(type.getCIntegerField("_is_unsafe_anonymous"), 0);
|
isUnsafeAnonymousField = new CIntField(type.getCIntegerField("_is_unsafe_anonymous"), 0);
|
||||||
dictionaryField = type.getAddressField("_dictionary");
|
dictionaryField = type.getAddressField("_dictionary");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AddressField classLoaderField;
|
private static long classLoaderFieldOffset;
|
||||||
private static AddressField nextField;
|
private static AddressField nextField;
|
||||||
private static MetadataField klassesField;
|
private static MetadataField klassesField;
|
||||||
private static CIntField isUnsafeAnonymousField;
|
private static CIntField isUnsafeAnonymousField;
|
||||||
@ -72,13 +71,9 @@ public class ClassLoaderData extends VMObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Oop getClassLoader() {
|
public Oop getClassLoader() {
|
||||||
Address handle = classLoaderField.getValue(getAddress());
|
Address addr = getAddress().addOffsetTo(classLoaderFieldOffset);
|
||||||
if (handle != null) {
|
VMOopHandle vmOopHandle = VMObjectFactory.newObject(VMOopHandle.class, addr);
|
||||||
// Load through the handle
|
return vmOopHandle.resolve();
|
||||||
OopHandle refs = handle.getOopHandleAt(0);
|
|
||||||
return (Instance)VM.getVM().getObjectHeap().newOop(refs);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getisUnsafeAnonymous() {
|
public boolean getisUnsafeAnonymous() {
|
||||||
|
@ -83,6 +83,10 @@ public abstract class CollectedHeap extends VMObject {
|
|||||||
return handle.getOopHandleAt(offset);
|
return handle.getOopHandleAt(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OopHandle oop_load_in_native(Address addr) {
|
||||||
|
return addr.getOopHandleAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
public void print() { printOn(System.out); }
|
public void print() { printOn(System.out); }
|
||||||
public void printOn(PrintStream tty) {
|
public void printOn(PrintStream tty) {
|
||||||
MemRegion mr = reservedRegion();
|
MemRegion mr = reservedRegion();
|
||||||
|
@ -80,11 +80,9 @@ public class ZCollectedHeap extends CollectedHeap {
|
|||||||
return heap().used();
|
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);
|
oopAddress = ZBarrier.weak_barrier(oopAddress);
|
||||||
if (oopAddress == null) {
|
if (oopAddress == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -93,6 +91,23 @@ public class ZCollectedHeap extends CollectedHeap {
|
|||||||
return oopAddress.addOffsetToAsOopHandle(0);
|
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) {
|
public String oopAddressDescription(OopHandle handle) {
|
||||||
Address origOop = ZOop.to_address(handle);
|
Address origOop = ZOop.to_address(handle);
|
||||||
Address loadBarrieredOop = ZBarrier.weak_barrier(origOop);
|
Address loadBarrieredOop = ZBarrier.weak_barrier(origOop);
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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 {
|
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
|
||||||
Type type = db.lookupType("Klass");
|
Type type = db.lookupType("Klass");
|
||||||
javaMirror = type.getAddressField("_java_mirror");
|
javaMirrorFieldOffset = type.getField("_java_mirror").getOffset();
|
||||||
superField = new MetadataField(type.getAddressField("_super"), 0);
|
superField = new MetadataField(type.getAddressField("_super"), 0);
|
||||||
layoutHelper = new IntField(type.getJIntField("_layout_helper"), 0);
|
layoutHelper = new IntField(type.getJIntField("_layout_helper"), 0);
|
||||||
name = type.getAddressField("_name");
|
name = type.getAddressField("_name");
|
||||||
@ -89,7 +89,7 @@ public class Klass extends Metadata implements ClassConstants {
|
|||||||
public boolean isArrayKlass() { return false; }
|
public boolean isArrayKlass() { return false; }
|
||||||
|
|
||||||
// Fields
|
// Fields
|
||||||
private static AddressField javaMirror;
|
private static long javaMirrorFieldOffset;
|
||||||
private static MetadataField superField;
|
private static MetadataField superField;
|
||||||
private static IntField layoutHelper;
|
private static IntField layoutHelper;
|
||||||
private static AddressField name;
|
private static AddressField name;
|
||||||
@ -101,23 +101,15 @@ public class Klass extends Metadata implements ClassConstants {
|
|||||||
private static CIntField vtableLen;
|
private static CIntField vtableLen;
|
||||||
private static AddressField classLoaderData;
|
private static AddressField classLoaderData;
|
||||||
|
|
||||||
private Address getValue(AddressField field) {
|
|
||||||
return addr.getAddressAt(field.getOffset());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Symbol getSymbol(AddressField field) {
|
protected Symbol getSymbol(AddressField field) {
|
||||||
return Symbol.create(addr.getAddressAt(field.getOffset()));
|
return Symbol.create(addr.getAddressAt(field.getOffset()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accessors for declared fields
|
// Accessors for declared fields
|
||||||
public Instance getJavaMirror() {
|
public Instance getJavaMirror() {
|
||||||
Address handle = javaMirror.getValue(getAddress());
|
Address addr = getAddress().addOffsetTo(javaMirrorFieldOffset);
|
||||||
if (handle != null) {
|
VMOopHandle vmOopHandle = VMObjectFactory.newObject(VMOopHandle.class, addr);
|
||||||
// Load through the handle
|
return vmOopHandle.resolve();
|
||||||
OopHandle refs = handle.getOopHandleAt(0);
|
|
||||||
return (Instance)VM.getVM().getObjectHeap().newOop(refs);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
public Klass getSuper() { return (Klass) superField.getValue(this); }
|
public Klass getSuper() { return (Klass) superField.getValue(this); }
|
||||||
public Klass getJavaSuper() { return null; }
|
public Klass getJavaSuper() { return null; }
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user