08855df46a
Reviewed-by: vlivanov, erikj, mseledtsov, gthornbr
233 lines
9.2 KiB
Java
233 lines
9.2 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.share;
|
|
|
|
import java.util.*;
|
|
|
|
/*
|
|
* Class create/delete instances with given reference type and given referrers number
|
|
*/
|
|
public class ObjectInstancesManager
|
|
{
|
|
public static String STRONG_REFERENCE = "STRONG";
|
|
public static String WEAK_REFERENCE = "WEAK";
|
|
public static String SOFT_REFERENCE = "SOFT";
|
|
public static String PHANTOM_REFERENCE = "PHANTOM";
|
|
public static String JNI_GLOBAL_REFERENCE = "JNI_GLOBAL";
|
|
public static String JNI_LOCAL_REFERENCE = "JNI_LOCAL";
|
|
public static String JNI_WEAK_REFERENCE = "JNI_WEAK";
|
|
|
|
// used to create references of all types
|
|
private static String USE_ALL_REFERENCE_TYPES = "ALL_REFERENCE_TYPES";
|
|
|
|
private Map<String, Collection<ReferringObjectSet>> instances = new TreeMap<String, Collection<ReferringObjectSet>>();
|
|
|
|
public static Set<String> primitiveArrayClassNames = new HashSet<String>();
|
|
|
|
static
|
|
{
|
|
primitiveArrayClassNames.add("boolean[]");
|
|
primitiveArrayClassNames.add("byte[]");
|
|
primitiveArrayClassNames.add("char[]");
|
|
primitiveArrayClassNames.add("int[]");
|
|
primitiveArrayClassNames.add("long[]");
|
|
primitiveArrayClassNames.add("float[]");
|
|
primitiveArrayClassNames.add("double[]");
|
|
}
|
|
|
|
|
|
public static Set<String> allReferenceTypes = new HashSet<String>();
|
|
|
|
static
|
|
{
|
|
allReferenceTypes.add(ObjectInstancesManager.STRONG_REFERENCE);
|
|
allReferenceTypes.add(ObjectInstancesManager.WEAK_REFERENCE);
|
|
allReferenceTypes.add(ObjectInstancesManager.SOFT_REFERENCE);
|
|
allReferenceTypes.add(ObjectInstancesManager.PHANTOM_REFERENCE);
|
|
allReferenceTypes.add(ObjectInstancesManager.JNI_GLOBAL_REFERENCE);
|
|
allReferenceTypes.add(ObjectInstancesManager.JNI_LOCAL_REFERENCE);
|
|
allReferenceTypes.add(ObjectInstancesManager.JNI_WEAK_REFERENCE);
|
|
}
|
|
|
|
public static boolean isWeak(String type) {
|
|
return !(type.equals(ObjectInstancesManager.JNI_GLOBAL_REFERENCE)
|
|
|| type.equals(ObjectInstancesManager.JNI_LOCAL_REFERENCE)
|
|
|| type.equals(ObjectInstancesManager.STRONG_REFERENCE));
|
|
|
|
}
|
|
|
|
public static Log log;
|
|
|
|
public ObjectInstancesManager(Log log)
|
|
{
|
|
ObjectInstancesManager.log = log;
|
|
}
|
|
|
|
// delete a given number of referrers
|
|
public void deleteReferrers(String className, int referrersCount, Set<String> referrerTypes)
|
|
{
|
|
Collection<ReferringObjectSet> objectInstances;
|
|
|
|
objectInstances = instances.get(className);
|
|
|
|
if(objectInstances == null)
|
|
{
|
|
log.display("Error command 'deleteObjectInstances' is requsted: instances of class " + className + " was not created");
|
|
System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_FAILED);
|
|
return;
|
|
}
|
|
|
|
Iterator<ReferringObjectSet> iterator = objectInstances.iterator();
|
|
|
|
while(iterator.hasNext())
|
|
{
|
|
ReferringObjectSet debugeeObjectReference = iterator.next();
|
|
if (referrerTypes.isEmpty() || referrerTypes.contains(debugeeObjectReference.getReferenceType())) {
|
|
debugeeObjectReference.delete(referrersCount);
|
|
|
|
if(debugeeObjectReference.getReferrerCount() == 0)
|
|
iterator.remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
// delete all object referrers, it is equal to make object unreacheable
|
|
public void deleteAllReferrers(int count, String className)
|
|
{
|
|
Collection<ReferringObjectSet> objectInstances;
|
|
|
|
objectInstances = instances.get(className);
|
|
|
|
if(objectInstances == null)
|
|
{
|
|
throw new TestBug("Command 'deleteObjectInstances' is requsted: instances of class " + className + " was not created");
|
|
}
|
|
|
|
Iterator<ReferringObjectSet> iterator = objectInstances.iterator();
|
|
|
|
if(count == 0)
|
|
count = objectInstances.size();
|
|
|
|
for(int i = 0; i < count; i++)
|
|
{
|
|
ReferringObjectSet debugeeObjectReference = iterator.next();
|
|
debugeeObjectReference.deleteAll();
|
|
|
|
iterator.remove();
|
|
}
|
|
}
|
|
|
|
// create object instance with referrers of all possible types
|
|
public void createAllTypeReferences(String className, int count)
|
|
{
|
|
createReferences(count, className, 1, allReferenceTypes);
|
|
}
|
|
|
|
// create a given number of object instances with given number of referrers
|
|
public void createReferences(int count, String className, int referrerCount, Set<String> referrerTypes)
|
|
{
|
|
Collection<ReferringObjectSet> objectInstances;
|
|
|
|
Class klass = null;
|
|
|
|
if(!primitiveArrayClassNames.contains(className))
|
|
{
|
|
try
|
|
{
|
|
klass = Class.forName(className);
|
|
}
|
|
catch(ClassNotFoundException e)
|
|
{
|
|
log.display("Can't find class: " + className);
|
|
System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_FAILED);
|
|
return;
|
|
}
|
|
}
|
|
|
|
objectInstances = instances.get(className);
|
|
|
|
if(objectInstances == null)
|
|
{
|
|
objectInstances = new ArrayList<ReferringObjectSet>();
|
|
instances.put(className, objectInstances);
|
|
}
|
|
|
|
for(int i = 0; i < count; i++)
|
|
{
|
|
try
|
|
{
|
|
Object instance;
|
|
|
|
if(!primitiveArrayClassNames.contains(className))
|
|
{
|
|
instance = klass.newInstance();
|
|
}
|
|
else
|
|
{
|
|
instance = createPrimitiveTypeArray(className);
|
|
}
|
|
|
|
for(String type : referrerTypes) {
|
|
objectInstances.add(new ReferringObjectSet(instance, referrerCount, type));
|
|
}
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
log.display("Unexpected exception: " + e);
|
|
System.exit(Consts.JCK_STATUS_BASE + Consts.TEST_FAILED);
|
|
}
|
|
}
|
|
}
|
|
|
|
public Object createPrimitiveTypeArray(String typeName)
|
|
{
|
|
int arraySize = 1;
|
|
|
|
if(typeName.equals("boolean[]"))
|
|
return new boolean[arraySize];
|
|
else
|
|
if(typeName.equals("byte[]"))
|
|
return new byte[arraySize];
|
|
else
|
|
if(typeName.equals("char[]"))
|
|
return new char[arraySize];
|
|
else
|
|
if(typeName.equals("int[]"))
|
|
return new int[arraySize];
|
|
else
|
|
if(typeName.equals("long[]"))
|
|
return new long[arraySize];
|
|
else
|
|
if(typeName.equals("float[]"))
|
|
return new float[arraySize];
|
|
else
|
|
if(typeName.equals("double[]"))
|
|
return new double[arraySize];
|
|
else
|
|
{
|
|
throw new TestBug("Invalid primitive type array type name: " + typeName);
|
|
}
|
|
}
|
|
|
|
}
|