blob: 052107303207146c4be59bbb6aa40e79f62a6670 [file] [log] [blame]
/*
* Copyright (c) 2007, 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.
*/
/*
* @test
*
* @summary converted from VM Testbase nsk/jdi/ObjectReference/referringObjects/referringObjects001.
* VM Testbase keywords: [quick, jpda, jdi, feature_jdk6_jpda, vm6]
* VM Testbase readme:
* DESCRIPTION
* Test checks behaviour of ReferenceType.instances, VirtualMachine.instanceCounts, ObjectReference.referringObjects
* in cases when object is reacheable via following types of references:
* - strong
* - soft
* - weak
* - phantom
* - jni local
* - jni global
* - jni weak
* Test is executed for following sublcasses of ObjectReference: StringReference, ThreadReference, ClassLoaderReference, ArrayReference.
* The test scenario is following:
* - Debugger VM
* for refererence_type in <Strong, JNI_Local_Ref, JNI_Global_Ref, JNI_Weak_Ref, PhantomReference, SoftReference, WeakReference>
* do
* - initiate creation of referring objects of type 'refererence_type'
* - check the number of referrers and instances is correct
* - initiate deletion of some referreres(making them unreachable)
* - check the number of referrers and instances is correct
* done
* - Debugger VM
* create references of all possible types to single object, ObjectReference.referringObjects should return only
* referrers with supported type(Strong, PhantomReference, SoftReference, WeakReference)
*
* @requires vm.gc != "Z"
* @requires !vm.graal.enabled
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @build nsk.jdi.ObjectReference.referringObjects.referringObjects001.referringObjects001
* nsk.share.jdi.TestClass1
* @run main/othervm/native PropertyResolvingWrapper
* nsk.jdi.ObjectReference.referringObjects.referringObjects001.referringObjects001
* -verbose
* -arch=${os.family}-${os.simpleArch}
* -waittime=5
* -debugee.vmkind=java
* -transport.address=dynamic
* "-debugee.vmkeys=-Xmx128M ${test.vm.opts} ${test.java.opts}"
*/
package nsk.jdi.ObjectReference.referringObjects.referringObjects001;
import java.io.PrintStream;
import java.util.*;
import nsk.share.*;
import nsk.share.jdi.*;
import com.sun.jdi.*;
import nsk.share.jpda.AbstractDebuggeeTest;
public class referringObjects001 extends HeapwalkingDebugger {
public static void main(String argv[]) {
System.exit(run(argv, System.out) + Consts.JCK_STATUS_BASE);
}
public static int run(String argv[], PrintStream out) {
return new referringObjects001().runIt(argv, out);
}
protected String debuggeeClassName() {
return nsk.share.jdi.HeapwalkingDebuggee.class.getName();
}
// test given class with all references types
protected void testClass(String className) {
log.display("Test ObjectReference for class: " + className);
// force GC in debuggee VM to avoid collection of weak references during test execution
forceGC();
for (String referrerType : ObjectInstancesManager.allReferenceTypes) {
testReferrerType(referrerType, className);
if (ObjectInstancesManager.isWeak(referrerType)) {
resetStatusIfGC();
}
}
int createInstanceCount = 10;
List<ObjectReference> objectsToFilter = getObjectReferences(className, vm);
// create instances reachable via all types of references
pipe.println(HeapwalkingDebuggee.COMMAND_CREATE_ALL_TYPE_REFERENCES + ":" + className + ":" + createInstanceCount);
if (!isDebuggeeReady())
return;
// ObjectReference.referringObjects should include only supported types of references
checkDebugeeAnswer_instances_referringObjects(objectsToFilter, className, createInstanceCount, true,
HeapwalkingDebuggee.includedIntoReferrersCountTypes.size());
for (int i = 0; i < ObjectInstancesManager.allReferenceTypes.size(); i++) {
pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_REFERRERS + ":" + className + ":" + 1);
if (!isDebuggeeReady())
return;
}
}
protected void testReferrerType(String referrerType, String className) {
// can't check number of referrers for objects that was created in debugee VM
// before debugger command (for example primitive type arrays), so we should filter such objects
List<ObjectReference> objectsToFilter = HeapwalkingDebugger.getObjectReferences(className, vm);
boolean includedInReferrersCount = HeapwalkingDebuggee.isIncludedIntoReferrersCount(referrerType);
boolean includedInInstancesCount = HeapwalkingDebuggee.isIncludedIntoInstancesCount(referrerType);
int createInstanceCount = 4;
int referrerCount = 10;
// create 'createInstanceCount' instances with 'referrerCount' referrers
pipe.println(HeapwalkingDebuggee.COMMAND_CREATE_INSTANCES + ":" + className + ":" + createInstanceCount + ":" + referrerCount + ":"
+ referrerType);
int expectedInstanceCount;
if (includedInInstancesCount)
expectedInstanceCount = createInstanceCount;
else
expectedInstanceCount = 0;
// Note! This test is broken, in the sense that it incorrectly assumes
// that no GC can happen before it walks the heap. In practice, it seems
// to only affect this test when using ZGC. However, this test will also
// fail when using other GCs if an explicit GC is done here.
checkDebugeeAnswer_instanceCounts(className, expectedInstanceCount, objectsToFilter);
checkDebugeeAnswer_instances_referringObjects(objectsToFilter, className, expectedInstanceCount, includedInReferrersCount, referrerCount);
// delete half of referrers
int deleteCount = referrerCount / 2;
pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_REFERRERS + ":" + className + ":" + deleteCount);
referrerCount -= deleteCount;
if (includedInInstancesCount)
expectedInstanceCount = createInstanceCount;
else
expectedInstanceCount = 0;
checkDebugeeAnswer_instanceCounts(className, expectedInstanceCount, objectsToFilter);
checkDebugeeAnswer_instances_referringObjects(objectsToFilter, className, expectedInstanceCount, includedInReferrersCount, referrerCount);
// delete half of instances
deleteCount = createInstanceCount / 2;
pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_INSTANCES + ":" + className + ":" + deleteCount);
createInstanceCount -= deleteCount;
if (includedInInstancesCount)
expectedInstanceCount = createInstanceCount;
else
expectedInstanceCount = 0;
checkDebugeeAnswer_instanceCounts(className, expectedInstanceCount, objectsToFilter);
checkDebugeeAnswer_instances_referringObjects(objectsToFilter, className, expectedInstanceCount, includedInReferrersCount, referrerCount);
// delete all referrers (make object unreachable)
deleteCount = referrerCount;
pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_REFERRERS + ":" + className + ":" + deleteCount);
referrerCount = 0;
createInstanceCount = 0;
expectedInstanceCount = 0;
checkDebugeeAnswer_instanceCounts(className, expectedInstanceCount, objectsToFilter);
checkDebugeeAnswer_instances_referringObjects(objectsToFilter, className, expectedInstanceCount, includedInReferrersCount, referrerCount);
}
protected void checkDebugeeAnswer_instances_referringObjects(List<ObjectReference> objectsToFilter, String className, int expectedInstances,
boolean checkReferrers, int expectedReferrers) {
try {
ReferenceType referenceType = debuggee.classByName(className);
if (checkReferrers) {
List<ObjectReference> objectReferrences = HeapwalkingDebugger.filterObjectReferrence(objectsToFilter, referenceType.instances(0));
// used for non-strict check
int correctObjectsFound = 0;
for (ObjectReference objectReference : objectReferrences) {
int referrerCount = objectReference.referringObjects(0).size();
if (strictCheck(className)) {
if (referrerCount != expectedReferrers) {
setSuccess(false);
log.complain("List with wrong size was returned by ObjectReference.referringObjects: " + referrerCount + ", expected: "
+ expectedReferrers);
}
} else {
if (referrerCount == expectedReferrers) {
correctObjectsFound++;
}
}
}
if (!strictCheck(className)) {
if (correctObjectsFound != expectedInstances) {
setSuccess(false);
log.complain("List with wrong size was returned by ObjectReference.referringObjects, expected: " + expectedReferrers);
}
}
}
} catch (Throwable t) {
log.complain("Unexpected exception:");
t.printStackTrace(log.getOutStream());
}
}
protected void doTest() {
String[] testClassNames = { "java.lang.String", "nsk.share.jdi.TestClass1", "boolean[]",
"float[]" };
for (String className : testClassNames) {
testClass(className);
}
}
}