8203174: [Graal] JDI tests fail with Unexpected exception: com.sun.jdi.ObjectCollectedException

Reviewed-by: sspitsyn, cjplummer
This commit is contained in:
Daniil Titov 2018-11-15 09:56:49 -08:00
parent 898b4d83c0
commit 52bee8fe04
7 changed files with 114 additions and 22 deletions
test/hotspot/jtreg
ProblemList-graal.txt
vmTestbase/nsk
jdi
ArrayType/newInstance
ReferenceType/instances
instances002
instances003
share/jdi

@ -107,16 +107,6 @@ vmTestbase/nsk/jdi/ThreadReference/forceEarlyReturn/forceEarlyReturn009/forceEar
vmTestbase/nsk/jdi/ThreadReference/forceEarlyReturn/forceEarlyReturn007/TestDescription.java 8195600 generic-all
vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance001/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance002/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance003/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/ReferenceType/instances/instances002/instances002.java 8203174 generic-all
vmTestbase/nsk/jdi/ReferenceType/instances/instances003/instances003.java 8203174 generic-all
vmTestbase/nsk/jdi/stress/MonitorEvents/MonitorEvents002/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/stress/serial/heapwalking001/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/stress/serial/heapwalking002/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/stress/serial/mixed002/TestDescription.java 8203174 generic-all
vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses026/TestDescription.java 8195627 generic-all
vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses028/TestDescription.java 8195627 generic-all
vmTestbase/nsk/jdi/VirtualMachine/redefineClasses/redefineclasses030/TestDescription.java 8195627 generic-all

@ -148,9 +148,23 @@ public class newinstance001 {
log1(" TESTING BEGINS");
for (int i = 0; ; i++) {
pipe.println("newcheck");
pipe.println("newcheck");
// There are potentially other non-test Java threads allocating objects and triggering
// GC's so we need to suspend the target VM to avoid the objects created in the test
// from being accidentally GC'ed. However, we need the target VM temporary resumed
// while reading its response. Below we resume the target VM (if required) and suspend
// it only after pipe.readln() returns.
// On the first iteration the target VM is not suspended yet.
if (i > 0) {
debuggee.resume();
}
line = pipe.readln();
// Suspending target VM to prevent other non-test Java threads from triggering GCs.
debuggee.suspend();
if (line.equals("checkend")) {
log2(" : returned string is 'checkend'");
break ;
@ -359,6 +373,7 @@ public class newinstance001 {
//-------------------------------------------------- test summary section
//------------------------------------------------- standard end section
debuggee.resume();
pipe.println("quit");
log2("waiting for the debuggee to finish ...");
debuggee.waitFor();

@ -145,9 +145,23 @@ public class newinstance002 {
log1(" TESTING BEGINS");
for (int i = 0; ; i++) {
pipe.println("newcheck");
pipe.println("newcheck");
// There are potentially other non-test Java threads allocating objects and triggering
// GC's so we need to suspend the target VM to avoid the objects created in the test
// from being accidentally GC'ed. However, we need the target VM temporary resumed
// while reading its response. Below we resume the target VM (if required) and suspend
// it only after pipe.readln() returns.
// On the first iteration the target VM is not suspended yet.
if (i > 0) {
debuggee.resume();
}
line = pipe.readln();
// Suspending target VM to prevent other non-test Java threads from triggering GCs.
debuggee.suspend();
if (line.equals("checkend")) {
log2(" : returned string is 'checkend'");
break ;
@ -232,6 +246,7 @@ public class newinstance002 {
//-------------------------------------------------- test summary section
//------------------------------------------------- standard end section
debuggee.resume();
pipe.println("quit");
log2("waiting for the debuggee to finish ...");
debuggee.waitFor();

@ -144,9 +144,23 @@ public class newinstance003 {
log1(" TESTING BEGINS");
for (int i = 0; ; i++) {
pipe.println("newcheck");
pipe.println("newcheck");
// There are potentially other non-test Java threads allocating objects and triggering
// GC's so we need to suspend the target VM to avoid the objects created in the test
// from being accidentally GC'ed. However, we need the target VM temporary resumed
// while reading its response. Below we resume the target VM (if required) and suspend
// it only after pipe.readln() returns.
// On the first iteration the target VM is not suspended yet.
if (i > 0) {
debuggee.resume();
}
line = pipe.readln();
// Suspending target VM to prevent other non-test Java threads from triggering GCs.
debuggee.suspend();
if (line.equals("checkend")) {
log2(" : returned string is 'checkend'");
break ;
@ -228,7 +242,7 @@ public class newinstance003 {
//-------------------------------------------------- test summary section
//------------------------------------------------- standard end section
debuggee.resume();
pipe.println("quit");
log2("waiting for the debuggee to finish ...");
debuggee.waitFor();

@ -109,8 +109,22 @@ public class instances002 extends HeapwalkingDebugger {
log.complain("Unexpected reference type: " + referenceType.getClass().getName() + ", expected is ArrayType");
return;
}
// There are potentially other non-test Java threads allocating objects and triggering GC's.
debuggee.suspend();
baseInstances = referenceType.instances(0).size();
List<ObjectReference> baseReferences = new LinkedList<>();
// We need to call disableCollection() on each object returned by referenceType.instances()
// to deal with the case when GC was triggered before the suspend. Otherwise, these objects can
// be potentially collected.
for (ObjectReference objRef : referenceType.instances(0)) {
try {
objRef.disableCollection();
baseReferences.add(objRef);
} catch (ObjectCollectedException e) {
// skip this reference
}
}
baseInstances = baseReferences.size();
int createInstanceCount = 100;
int arraySize = 1;
@ -129,8 +143,15 @@ public class instances002 extends HeapwalkingDebugger {
checkDebugeeAnswer_instances(className, createInstanceCount + baseInstances);
for (ArrayReference arrayReference : objectReferences)
for (ArrayReference arrayReference : objectReferences) {
arrayReference.enableCollection();
}
for (ObjectReference baseRef : baseReferences) {
baseRef.enableCollection();
}
debuggee.resume();
}
// test method ClassType.newInstance

@ -62,6 +62,7 @@ package nsk.jdi.ReferenceType.instances.instances003;
import java.io.PrintStream;
import java.util.*;
import com.sun.jdi.ObjectCollectedException;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
@ -122,9 +123,10 @@ public class instances003 extends HeapwalkingDebugger {
// create temporary strong references to prevent the weakly referred instances being GCed
// during the time between creating them and disabling collection on them
boolean useTempStrongReference = needTempStongReference(referrerType);
pipe.println(HeapwalkingDebuggee.COMMAND_CREATE_INSTANCES + ":" + className + ":" + createInstanceCount +
":" + referrerCount + ":" + referrerType +
(referrerType.equals(ObjectInstancesManager.WEAK_REFERENCE) ? "|" + ObjectInstancesManager.STRONG_REFERENCE : ""));
":" + referrerCount + ":" + referrerType +
(useTempStrongReference ? "|" + ObjectInstancesManager.STRONG_REFERENCE : ""));
// 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
@ -135,14 +137,24 @@ public class instances003 extends HeapwalkingDebugger {
checkDebugeeAnswer_instanceCounts(className, createInstanceCount, objectsToFilter);
ReferenceType referenceType = debuggee.classByName(className);
List<ObjectReference> instances = HeapwalkingDebugger.filterObjectReferrence(objectsToFilter, referenceType.instances(0));
List<ObjectReference> allInstances = HeapwalkingDebugger.filterObjectReferrence(objectsToFilter, referenceType.instances(0));
for (ObjectReference or : instances) {
or.disableCollection();
// There are potentially other non-test Java threads allocating objects and triggering GC's.
// We need to call disableCollection() on each object returned by referenceType.instances()
// to deal with the case when GC was triggered. Otherwise, these objects can
// be potentially collected.
List<ObjectReference> instances = new LinkedList<>();
for (ObjectReference objRef : allInstances) {
try {
objRef.disableCollection();
instances.add(objRef);
} catch (ObjectCollectedException ex) {
// skip this references
}
}
// remove the temporary strong references so the weak references can be properly tested
if (referrerType.equals(ObjectInstancesManager.WEAK_REFERENCE)) {
if (useTempStrongReference) {
pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_REFERRERS + ":" + className + ":" + referrerCount + ":" + ObjectInstancesManager.STRONG_REFERENCE);
if (!isDebuggeeReady()) {
return;
@ -157,6 +169,7 @@ public class instances003 extends HeapwalkingDebugger {
instances.get(i).enableCollection();
}
pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_INSTANCES + ":" + className + ":" + createInstanceCount);
if (!isDebuggeeReady())
@ -183,4 +196,13 @@ public class instances003 extends HeapwalkingDebugger {
testClass(className, referenceType);
}
}
private static boolean needTempStongReference(String referenceType) {
return ObjectInstancesManager.WEAK_REFERENCE.equals(referenceType) ||
ObjectInstancesManager.JNI_WEAK_REFERENCE.equals(referenceType) ||
ObjectInstancesManager.PHANTOM_REFERENCE.equals(referenceType) ||
ObjectInstancesManager.SOFT_REFERENCE.equals(referenceType);
}
}

@ -197,6 +197,21 @@ public class HeapwalkingDebuggee extends AbstractJDIDebuggee {
if (className.equals("byte[]"))
return false;
if (className.equals("boolean[]"))
return false;
if (className.equals("float[]"))
return false;
if (className.equals("long[]"))
return false;
if (className.equals("int[]"))
return false;
if (className.equals("double[]"))
return false;
if (className.equals("java.lang.Thread")) {
if (otherThreadPresent)
return false;