/* * 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 _softRef; public Object _softReferree; public WeakReference _weakRef; public Object _weakReferree; public PhantomReference _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(_softReferree = new Object()); tag(_softRef, "_softRef"); tag(_softReferree, "_softReferree"); _weakRef = new WeakReference(_weakReferree = new Object()); tag(_weakRef, "_weakRef"); tag(_weakReferree, "_weakReferree"); _phantomRef = new PhantomReference(_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); }