59ac4c2629
Reviewed-by: sspitsyn, erikj
286 lines
9.7 KiB
Java
286 lines
9.7 KiB
Java
/*
|
|
* Copyright (c) 2006, 2018, 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 nsk.jvmti.unit.FollowReferences;
|
|
|
|
import java.lang.ref.*;
|
|
import java.lang.reflect.*;
|
|
|
|
// 2 superinterfaces
|
|
// (Henri Cartier-Bresson, Alex Webb and Bruno Barbey are famous photographers)
|
|
interface Cartier {
|
|
public static final int c21 = 21;
|
|
static final int c22 = 22;
|
|
}
|
|
|
|
interface Bresson {
|
|
public static final int c21 = 21;
|
|
static final int c22 = 22;
|
|
}
|
|
|
|
class HenriCartierBresson implements Cartier, Bresson {
|
|
private final int c31 = 31;
|
|
protected final int c32 = 32;
|
|
public final int c33 = 33;
|
|
}
|
|
|
|
class AlexWebb extends HenriCartierBresson {
|
|
public static final int aw = 50;
|
|
}
|
|
|
|
public class FollowRefObjects {
|
|
|
|
static final int ARRAY_SIZE = 3;
|
|
|
|
// This array has to be up-to-date with the jvmtiHeapReferenceKind enum
|
|
// TODO: auto-generate
|
|
static final int JVMTI_HEAP_REFERENCE_CLASS = 1;
|
|
static final int JVMTI_HEAP_REFERENCE_FIELD = 2;
|
|
static final int JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT = 3;
|
|
static final int JVMTI_HEAP_REFERENCE_CLASS_LOADER = 4;
|
|
static final int JVMTI_HEAP_REFERENCE_SIGNERS = 5;
|
|
static final int JVMTI_HEAP_REFERENCE_PROTECTION_DOMAIN = 6;
|
|
static final int JVMTI_HEAP_REFERENCE_INTERFACE = 7;
|
|
static final int JVMTI_HEAP_REFERENCE_STATIC_FIELD = 8;
|
|
static final int JVMTI_HEAP_REFERENCE_CONSTANT_POOL = 9;
|
|
static final int JVMTI_HEAP_REFERENCE_SUPERCLASS = 10;
|
|
static final int JVMTI_HEAP_REFERENCE_JNI_GLOBAL = 21;
|
|
static final int JVMTI_HEAP_REFERENCE_SYSTEM_CLASS = 22;
|
|
static final int JVMTI_HEAP_REFERENCE_MONITOR = 23;
|
|
static final int JVMTI_HEAP_REFERENCE_STACK_LOCAL = 24;
|
|
static final int JVMTI_HEAP_REFERENCE_JNI_LOCAL = 25;
|
|
static final int JVMTI_HEAP_REFERENCE_THREAD = 26;
|
|
static final int JVMTI_HEAP_REFERENCE_OTHER = 27;
|
|
|
|
public boolean[] _boolArr;
|
|
public byte[] _byteArr;
|
|
public short[] _shortArr;
|
|
public int[] _intArr;
|
|
public long[] _longArr;
|
|
public float[] _floatArr;
|
|
public double[] _doubleArr;
|
|
|
|
public String[] _strArr;
|
|
public Object[] _objArr;
|
|
public Object[][] _objArrArr;
|
|
|
|
// This class obtained through the reflection API
|
|
class FRHandler implements InvocationHandler {
|
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public SoftReference<Object> _softRef;
|
|
public Object _softReferree;
|
|
|
|
public WeakReference<Object> _weakRef;
|
|
public Object _weakReferree;
|
|
|
|
public PhantomReference<Object> _phantomRef;
|
|
public Object _phantomReferree;
|
|
|
|
public FollowRefObjects _selfRef1, _selfRef2, _selfRef3;
|
|
|
|
public Thread _thread;
|
|
|
|
public ClassLoader _classLoader;
|
|
public Object _loadedObject;
|
|
|
|
// Circular list
|
|
class NextRef {
|
|
Object _next;
|
|
}
|
|
|
|
public NextRef[] _nextRef;
|
|
|
|
class BrunoBarbey extends HenriCartierBresson {
|
|
public static final int bb = 60;
|
|
}
|
|
|
|
public AlexWebb _aw;
|
|
public BrunoBarbey _bb;
|
|
|
|
public Class _reflectClass;
|
|
public Cartier _cartierInAMirror;
|
|
|
|
/** Create references */
|
|
public void createObjects() {
|
|
|
|
resetCurTag();
|
|
tag(this, "this");
|
|
|
|
// A plenty of array kinds
|
|
_boolArr = new boolean[ARRAY_SIZE]; tag(_boolArr, "_boolArr");
|
|
_byteArr = new byte[ARRAY_SIZE]; tag(_byteArr, "_byteArr");
|
|
_shortArr = new short[ARRAY_SIZE]; tag(_shortArr, "_shortArr");
|
|
_intArr = new int[ARRAY_SIZE]; tag(_intArr, "_intArr");
|
|
_longArr = new long[ARRAY_SIZE]; tag(_longArr, "_longArr");
|
|
_floatArr = new float[ARRAY_SIZE]; tag(_floatArr, "_floatArr");
|
|
_doubleArr = new double[ARRAY_SIZE]; tag(_doubleArr, "_doubleArr");
|
|
|
|
_objArrArr = new Object[ARRAY_SIZE][ARRAY_SIZE]; tag(_objArrArr, "_objArrArr");
|
|
|
|
// Multiple references to the same object
|
|
_objArr = new Object[ARRAY_SIZE]; tag(_objArr, "_objArr");
|
|
_objArr[0] = new Object(); tag(_objArr[0], "_objArr[0]");
|
|
_objArr[1] = _objArr[2] = _objArr[0];
|
|
|
|
// Multiple references to myself
|
|
_selfRef1 = _selfRef2 = _selfRef3 = this;
|
|
|
|
// Circular linked list
|
|
_nextRef = new NextRef[2]; tag(_nextRef, "_nextRef");
|
|
_nextRef[0] = new NextRef(); tag(_nextRef[0], "_nextRef[0]");
|
|
_nextRef[1] = new NextRef(); tag(_nextRef[1], "_nextRef[1]");
|
|
_nextRef[0]._next = _nextRef[1];
|
|
_nextRef[1]._next = _nextRef[0];
|
|
|
|
// Strings
|
|
_strArr = new String[ARRAY_SIZE]; tag(_strArr, "_strArr");
|
|
_strArr[0] = "CTAKAH OT CAXAPA HE TPECHET"; tag(_strArr[0], "_strArr[0]"); // ASCII characters
|
|
_strArr[1] = "?????? ?? ??????? ???????!"; tag(_strArr[1], "_strArr[1]"); // Russian characters
|
|
_strArr[2] = getClass().getCanonicalName(); tag(_strArr[2], "_strArr[2]"); // Copy some existing string
|
|
|
|
// A proxy class created by reflection API
|
|
_reflectClass = java.lang.reflect.Proxy.getProxyClass(
|
|
getClass().getClassLoader(),
|
|
new Class[] { Cartier.class});
|
|
tag(_reflectClass, "_reflectClass");
|
|
|
|
_cartierInAMirror = (Cartier) java.lang.reflect.Proxy.newProxyInstance(
|
|
getClass().getClassLoader(),
|
|
new Class[] { Cartier.class },
|
|
new FRHandler());
|
|
tag(_cartierInAMirror, "_cartierInAMirror");
|
|
|
|
// Soft, Weak, Phantom References
|
|
_softRef = new SoftReference<Object>(_softReferree = new Object());
|
|
tag(_softRef, "_softRef"); tag(_softReferree, "_softReferree");
|
|
|
|
_weakRef = new WeakReference<Object>(_weakReferree = new Object());
|
|
tag(_weakRef, "_weakRef"); tag(_weakReferree, "_weakReferree");
|
|
|
|
_phantomRef = new PhantomReference<Object>(_phantomReferree = new Object(), null);
|
|
tag(_phantomRef, "_phantomRef"); tag(_phantomReferree, "_phantomReferree");
|
|
|
|
_thread = new Thread(); tag(_thread, "_thread");
|
|
|
|
_classLoader = new java.net.URLClassLoader(new java.net.URL[] {});
|
|
tag(_classLoader, "_classLoader");
|
|
|
|
try {
|
|
_loadedObject = _classLoader.loadClass("java/lang/SecurityManager");
|
|
tag(_loadedObject, "_loadedObject");
|
|
} catch ( ClassNotFoundException e ) {}
|
|
|
|
_aw = new AlexWebb(); tag(_aw, "_aw");
|
|
_bb = new BrunoBarbey(); tag(_bb, "_bb");
|
|
|
|
// TODO:
|
|
// - Security Manager,
|
|
// - Signers
|
|
//
|
|
// Kinds of references left to the agent:
|
|
// - stack references,
|
|
// - monitor references,
|
|
// - JNI local, weak global and global references
|
|
}
|
|
|
|
/** Set all reference fields to null */
|
|
|
|
public void dropObjects() {
|
|
|
|
_boolArr = null;
|
|
_byteArr = null;
|
|
_shortArr = null;
|
|
_intArr = null;
|
|
_longArr = null;
|
|
_floatArr = null;
|
|
_doubleArr = null;
|
|
|
|
_objArrArr = null;
|
|
|
|
// Multiple references to the same object
|
|
_objArr = null;
|
|
|
|
// Multiple references to myself
|
|
_selfRef1 = _selfRef2 = _selfRef3 = null;
|
|
|
|
// Circular linked list
|
|
_nextRef = null;
|
|
|
|
// Strings
|
|
_strArr = null;
|
|
|
|
// A proxy class created by reflection API
|
|
_reflectClass = null;
|
|
_cartierInAMirror = null;
|
|
|
|
// Soft, Weak, Phantom References
|
|
_softRef = null;
|
|
_softReferree = null;
|
|
_weakRef = null;
|
|
_weakReferree = null;
|
|
_phantomRef = null;
|
|
_phantomReferree = null;
|
|
|
|
_thread = null;
|
|
|
|
_classLoader = null;
|
|
_loadedObject = null;
|
|
|
|
_aw = null;
|
|
_bb = null;
|
|
}
|
|
|
|
private long _curTag;
|
|
|
|
private void resetCurTag() {
|
|
_curTag = 1; // 0 == no tag, so start from 1
|
|
resetTags();
|
|
}
|
|
|
|
private void tag(Object o)
|
|
{
|
|
setTag(o, _curTag++, "(" + ((o == null) ? "null" : o.getClass().getCanonicalName()) + ")");
|
|
}
|
|
|
|
private void tag(Object o, String fieldName)
|
|
{
|
|
setTag(o, _curTag++, fieldName + "(" + ((o == null) ? "null" : o.getClass().getCanonicalName()) + ")");
|
|
}
|
|
|
|
// A shortcut
|
|
private void ref(Object from, Object to, int jvmtiRefKind, int count)
|
|
{
|
|
addRefToVerify(from, to, jvmtiRefKind, count);
|
|
}
|
|
|
|
public static native void resetTags();
|
|
public static native boolean setTag(Object o, long tag, String sInfo);
|
|
public static native long getTag(Object o);
|
|
|
|
public static native void resetRefsToVerify();
|
|
public static native boolean addRefToVerify(Object from, Object to, int jvmtiRefKind, int count);
|
|
}
|