Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/ReferringObject.java
40948 views
/*1* Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22package nsk.share;2324import java.lang.ref.PhantomReference;25import java.lang.ref.ReferenceQueue;26import java.lang.ref.SoftReference;27import java.lang.ref.WeakReference;2829/*30* This class create/delete reference with given type.31*32* Supported reference types are:33* - strong34* - soft35* - weak36* - phantom37* - jni local38* - jni global39* - jni weak40*/41public class ReferringObject42{43static44{45System.loadLibrary("JNIreferences");46}4748public final static int maxJNIGlobalReferences = 1000;49public final static int maxJNIWeakReferences = 1000;5051private Object reference;5253private String referenceType;5455//used for storing jni global and jni weak references56private int referenceIndex;5758public ReferringObject(Object object, String referenceType)59{60this.referenceType = referenceType;6162if(referenceType.equals(ObjectInstancesManager.STRONG_REFERENCE))63{64createStrongReference(object);65}66else67if(referenceType.equals(ObjectInstancesManager.SOFT_REFERENCE))68{69createSoftReference(object);70}71else72if(referenceType.equals(ObjectInstancesManager.WEAK_REFERENCE))73{74createWeakReference(object);75}76else77if(referenceType.equals(ObjectInstancesManager.PHANTOM_REFERENCE))78{79createPhantomReference(object);80}81else82if(referenceType.equals(ObjectInstancesManager.JNI_GLOBAL_REFERENCE))83{84createJNIGlobalReference(object);85}86else87if(referenceType.equals(ObjectInstancesManager.JNI_LOCAL_REFERENCE))88{89createJNILocalReference(object);90}91else92if(referenceType.equals(ObjectInstancesManager.JNI_WEAK_REFERENCE))93{94createJNIWeakReference(object);95}96else97throw new IllegalArgumentException("Invalid reference type: " + referenceType);98}99100public void delete()101{102if(referenceType == null)103{104throw new TestBug("Reference type is null");105}106107if(referenceType.equals(ObjectInstancesManager.SOFT_REFERENCE))108{109if(reference == null)110{111throw new TestBug("Reference is null for SoftReference");112}113114if(((SoftReference)reference).get() == null)115{116// throw new TestBug("Test execution error: SoftReference was collected");117}118}119else120if(referenceType.equals(ObjectInstancesManager.WEAK_REFERENCE))121{122if(reference == null)123{124throw new TestBug("Reference is null for WeakReference");125}126127if(((WeakReference)reference).get() == null)128{129// throw new TestBug("Test execution error: WeakReference was collected");130}131}132else133if(referenceType.equals(ObjectInstancesManager.PHANTOM_REFERENCE))134{135if(reference == null)136{137throw new TestBug("Reference is null for PhantomReference");138}139}140else141if(referenceType.equals(ObjectInstancesManager.JNI_GLOBAL_REFERENCE))142{143deleteJNIGlobalReferenceNative(referenceIndex);144}145else146if(referenceType.equals(ObjectInstancesManager.JNI_LOCAL_REFERENCE))147{148deleteJNILocalReference();149}150else151if(referenceType.equals(ObjectInstancesManager.JNI_WEAK_REFERENCE))152{153try {154deleteJNIWeakReferenceNative(referenceIndex);155} catch (Throwable t)156{157158}159}160161reference = null;162}163164private void createStrongReference(Object object)165{166reference = object;167}168169private void createSoftReference(Object object)170{171reference = new SoftReference<Object>(object);172}173174private void createWeakReference(Object object)175{176reference = new WeakReference<Object>(object);177}178179private void createPhantomReference(Object object)180{181reference = new PhantomReference<Object>(object, new ReferenceQueue<Object>());182}183184private void createJNIGlobalReference(Object object)185{186referenceIndex = createJNIGlobalReferenceNative(object, maxJNIGlobalReferences);187188if(referenceIndex < 0)189{190throw new TestBug("Error on creation of JNI_Global reference, Possible number of JNI_Global references exceeded max available value!");191}192}193194/*195* Since jni local reference valid only for duration of native method call, to create jni local reference196* special thread is created which enter in native method, create jni local reference and wait197*/198private void createJNILocalReference(Object object)199{200this.reference = object;201202jniLocalReferenceThread = new JNILocalReferenceThread();203jniLocalReferenceThread.start();204205// wait till JNI local reference will be created206jniLocalReferenceThread.createWhicket.waitFor();207208reference = null;209}210211private void deleteJNILocalReference()212{213// notify JNI method that JNI local reference is not needed any more and could be released214jniLocalReferenceThread.deleteWhicket.unlock();215216try217{218jniLocalReferenceThread.join(1000 * 60 * 2);219220if(jniLocalReferenceThread.isAlive())221{222throw new TestBug("JNI_Local_Reference thread can't finish execution");223}224}225catch(InterruptedException e)226{227throw new TestBug("deleteJNILocalReference was interrupted");228}229}230231private void createJNIWeakReference(Object object)232{233referenceIndex = createJNIWeakReferenceNative(object, maxJNIWeakReferences);234235if(referenceIndex < 0)236{237throw new TestBug("Error on creation of JNI_Weak reference. Possible number of JNI_Weak references exceeded max available value!");238}239}240241class JNILocalReferenceThread242extends Thread243{244Wicket createWhicket = new Wicket();245Wicket deleteWhicket = new Wicket();246247public void run()248{249createJNILocalReferenceNative(reference, createWhicket, deleteWhicket);250}251}252253private JNILocalReferenceThread jniLocalReferenceThread;254255private native int createJNIGlobalReferenceNative(Object object, int maxJNIGlobalReferences);256257private native void deleteJNIGlobalReferenceNative(int index);258259private native void createJNILocalReferenceNative(Object object, Wicket createWhicket, Wicket deleteWhicket);260261private native int createJNIWeakReferenceNative(Object object, int maxJNIWeakReferences);262263private native void deleteJNIWeakReferenceNative(int index);264}265266267