--- old/test/hotspot/jtreg/ProblemList-graal.txt 2018-11-07 16:35:07.000000000 -0800 +++ new/test/hotspot/jtreg/ProblemList-graal.txt 2018-11-07 16:35:06.000000000 -0800 @@ -109,16 +109,6 @@ 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 --- old/test/hotspot/jtreg/vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance001.java 2018-11-07 16:35:08.000000000 -0800 +++ new/test/hotspot/jtreg/vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance001.java 2018-11-07 16:35:08.000000000 -0800 @@ -148,9 +148,23 @@ 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 @@ //-------------------------------------------------- test summary section //------------------------------------------------- standard end section + debuggee.resume(); pipe.println("quit"); log2("waiting for the debuggee to finish ..."); debuggee.waitFor(); --- old/test/hotspot/jtreg/vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance002.java 2018-11-07 16:35:09.000000000 -0800 +++ new/test/hotspot/jtreg/vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance002.java 2018-11-07 16:35:09.000000000 -0800 @@ -145,9 +145,23 @@ 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 @@ //-------------------------------------------------- test summary section //------------------------------------------------- standard end section + debuggee.resume(); pipe.println("quit"); log2("waiting for the debuggee to finish ..."); debuggee.waitFor(); --- old/test/hotspot/jtreg/vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance003.java 2018-11-07 16:35:10.000000000 -0800 +++ new/test/hotspot/jtreg/vmTestbase/nsk/jdi/ArrayType/newInstance/newinstance003.java 2018-11-07 16:35:10.000000000 -0800 @@ -144,9 +144,23 @@ 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 @@ //-------------------------------------------------- test summary section //------------------------------------------------- standard end section - + debuggee.resume(); pipe.println("quit"); log2("waiting for the debuggee to finish ..."); debuggee.waitFor(); --- old/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/instances/instances002/instances002.java 2018-11-07 16:35:12.000000000 -0800 +++ new/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/instances/instances002/instances002.java 2018-11-07 16:35:11.000000000 -0800 @@ -109,8 +109,22 @@ 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 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 @@ 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 --- old/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/instances/instances003/instances003.java 2018-11-07 16:35:13.000000000 -0800 +++ new/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/instances/instances003/instances003.java 2018-11-07 16:35:12.000000000 -0800 @@ -62,6 +62,7 @@ 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 @@ // 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 @@ checkDebugeeAnswer_instanceCounts(className, createInstanceCount, objectsToFilter); ReferenceType referenceType = debuggee.classByName(className); - List instances = HeapwalkingDebugger.filterObjectReferrence(objectsToFilter, referenceType.instances(0)); + List 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 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 @@ instances.get(i).enableCollection(); } + pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_INSTANCES + ":" + className + ":" + createInstanceCount); if (!isDebuggeeReady()) @@ -183,4 +196,13 @@ 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); + + } } --- old/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/HeapwalkingDebuggee.java 2018-11-07 16:35:14.000000000 -0800 +++ new/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/HeapwalkingDebuggee.java 2018-11-07 16:35:14.000000000 -0800 @@ -197,6 +197,21 @@ 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;