blob: 2c09e462830dacbfdaf01ca21c1d84049cb5943f [file] [log] [blame]
/*
* 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);
}