mirror of
https://github.com/openjdk/jdk.git
synced 2026-06-10 12:37:09 +00:00
add support for diabling gc on returned objects
This commit is contained in:
parent
27f27dac96
commit
afbc5c90b6
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2026, 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
|
||||
@ -3353,4 +3353,7 @@ JDWP "Java(tm) Debug Wire Protocol"
|
||||
"otherwise, all threads started. ")
|
||||
(Constant INVOKE_NONVIRTUAL = 0x02
|
||||
"otherwise, normal virtual invoke (instance methods only)")
|
||||
(Constant INVOKE_DISABLE_COllECTION = 0x04
|
||||
"otherwise, the instance returned (if any) and exception thrown (if any) "
|
||||
"may be collected")
|
||||
)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2024, 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
|
||||
@ -125,6 +125,9 @@ public interface ClassType extends ReferenceType {
|
||||
|
||||
/** Perform method invocation with only the invoking thread resumed */
|
||||
static final int INVOKE_SINGLE_THREADED = 0x1;
|
||||
/** Perform perform the equivalent of ObjectReference.disableCollection() on
|
||||
any ObjectReference returned, including any exception thrown. */
|
||||
static final int INVOKE_DISABLE_COLLECTION = 0x4;
|
||||
|
||||
/**
|
||||
* Invokes the specified static {@link Method} in the
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2026, 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
|
||||
@ -143,6 +143,9 @@ public interface ObjectReference extends Value {
|
||||
static final int INVOKE_SINGLE_THREADED = 0x1;
|
||||
/** Perform non-virtual method invocation */
|
||||
static final int INVOKE_NONVIRTUAL = 0x2;
|
||||
/** Perform perform the equivalent of ObjectReference.disableCollection() on
|
||||
any ObjectReference returned, including any exception thrown. */
|
||||
static final int INVOKE_DISABLE_COLLECTION = 0x4;
|
||||
|
||||
/**
|
||||
* Invokes the specified {@link Method} on this object in the
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2026, 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
|
||||
@ -235,6 +235,19 @@ public final class ClassTypeImpl extends InvokableTypeImpl
|
||||
vm.notifySuspend();
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is a returned Object or an exception Object, make sure GC
|
||||
* is disabled if requested.
|
||||
*/
|
||||
if ((options & INVOKE_DISABLE_COLLECTION) != 0) {
|
||||
// Account for implicit disableCollection() done by the debug agent.
|
||||
if (ret.exception != null) {
|
||||
ret.exception.incrementGcDisableCount();
|
||||
} else {
|
||||
ret.newObject.incrementGcDisableCount();
|
||||
}
|
||||
}
|
||||
|
||||
if (ret.exception != null) {
|
||||
throw new InvocationException(ret.exception);
|
||||
} else {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2026, 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
|
||||
@ -37,6 +37,7 @@ import com.sun.jdi.InterfaceType;
|
||||
import com.sun.jdi.InvalidTypeException;
|
||||
import com.sun.jdi.InvocationException;
|
||||
import com.sun.jdi.Method;
|
||||
import com.sun.jdi.ObjectReference;
|
||||
import com.sun.jdi.ReferenceType;
|
||||
import com.sun.jdi.ThreadReference;
|
||||
import com.sun.jdi.VMCannotBeModifiedException;
|
||||
@ -124,6 +125,22 @@ abstract class InvokableTypeImpl extends ReferenceTypeImpl {
|
||||
if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
|
||||
vm.notifySuspend();
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is a returned Object or an exception Object, make sure GC
|
||||
* is disabled if requested.
|
||||
*/
|
||||
if ((options & ClassType.INVOKE_DISABLE_COLLECTION) != 0) {
|
||||
// Account for implicit disableCollection() done by the debug agent.
|
||||
if (ret.getException() != null) {
|
||||
ret.getException().incrementGcDisableCount();
|
||||
} else {
|
||||
if (ret.getResult() instanceof ObjectReferenceImpl obj) {
|
||||
obj.incrementGcDisableCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret.getException() != null) {
|
||||
throw new InvocationException(ret.getException());
|
||||
} else {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2026, 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
|
||||
@ -424,6 +424,21 @@ public class ObjectReferenceImpl extends ValueImpl
|
||||
vm.notifySuspend();
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is a returned Object or an exception Object, make sure GC
|
||||
* is disabled if requested.
|
||||
*/
|
||||
if ((options & INVOKE_DISABLE_COLLECTION) != 0) {
|
||||
// Account for implicit disableCollection() done by the debug agent.
|
||||
if (ret.exception != null) {
|
||||
ret.exception.incrementGcDisableCount();
|
||||
} else {
|
||||
if (ret.returnValue instanceof ObjectReferenceImpl obj) {
|
||||
obj.incrementGcDisableCount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret.exception != null) {
|
||||
throw new InvocationException(ret.exception);
|
||||
} else {
|
||||
@ -431,6 +446,11 @@ public class ObjectReferenceImpl extends ValueImpl
|
||||
}
|
||||
}
|
||||
|
||||
/* leave synchronized to keep count accurate */
|
||||
synchronized void incrementGcDisableCount() {
|
||||
gcDisableCount++;
|
||||
}
|
||||
|
||||
/* leave synchronized to keep count accurate */
|
||||
public synchronized void disableCollection() {
|
||||
if (gcDisableCount == 0) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2026, 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
|
||||
@ -29,6 +29,7 @@
|
||||
#include "threadControl.h"
|
||||
#include "outStream.h"
|
||||
#include "signature.h"
|
||||
#include "commonRef.h"
|
||||
|
||||
static jrawMonitorID invokerLock;
|
||||
|
||||
@ -726,6 +727,7 @@ invoker_completeInvokeRequest(jthread thread)
|
||||
jint id;
|
||||
InvokeRequest *request;
|
||||
jboolean detached;
|
||||
jbyte options;
|
||||
jboolean mustReleaseReturnValue = JNI_FALSE;
|
||||
|
||||
JDI_ASSERT(thread);
|
||||
@ -752,9 +754,12 @@ invoker_completeInvokeRequest(jthread thread)
|
||||
request->started = JNI_FALSE;
|
||||
request->available = JNI_TRUE; /* For next time around */
|
||||
|
||||
options = request->options;
|
||||
request->options = 0;
|
||||
|
||||
detached = request->detached;
|
||||
if (!detached) {
|
||||
if (request->options & JDWP_INVOKE_OPTIONS(SINGLE_THREADED)) {
|
||||
if (options & JDWP_INVOKE_OPTIONS(SINGLE_THREADED)) {
|
||||
(void)threadControl_suspendThread(thread, JNI_FALSE);
|
||||
} else {
|
||||
(void)threadControl_suspendAll();
|
||||
@ -817,6 +822,32 @@ invoker_completeInvokeRequest(jthread thread)
|
||||
(void)outStream_writeValue(env, &out, tag, returnValue);
|
||||
(void)outStream_writeObjectTag(env, &out, exc);
|
||||
(void)outStream_writeObjectRef(env, &out, exc);
|
||||
|
||||
/*
|
||||
* Pin the returnValue object and exception object if this invoke has
|
||||
* JDWP_INVOKE_OPTIONS(DISABLE_COllECTION) enabled.
|
||||
*/
|
||||
if (options & JDWP_INVOKE_OPTIONS(DISABLE_COllECTION)) {
|
||||
if (mustReleaseReturnValue && returnValue.l != NULL) {
|
||||
jlong id = commonRef_refToID(env, returnValue.l);
|
||||
//tty_message("return id: %ld", id);
|
||||
jvmtiError error = commonRef_pin(id);
|
||||
if (error != JVMTI_ERROR_NONE) {
|
||||
outStream_setError(&out, map2jdwpError(error));
|
||||
}
|
||||
commonRef_release(env, id);
|
||||
}
|
||||
if (exc != NULL) {
|
||||
jlong id = commonRef_refToID(env, exc);
|
||||
//tty_message("exception id: %ld", id);
|
||||
jvmtiError error = commonRef_pin(id);
|
||||
if (error != JVMTI_ERROR_NONE) {
|
||||
outStream_setError(&out, map2jdwpError(error));
|
||||
}
|
||||
commonRef_release(env, id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete potentially saved global references for return value
|
||||
* and exception. This must be done before sending the reply or
|
||||
|
||||
318
test/jdk/com/sun/jdi/InvokeGcDisabledTest.java
Normal file
318
test/jdk/com/sun/jdi/InvokeGcDisabledTest.java
Normal file
@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Copyright (c) 2026, 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
|
||||
* @bug 8311176
|
||||
* @summary Test INVOKE_DISABLE_COLLECTION flag
|
||||
* @library /test/lib
|
||||
* @run build TestScaffold VMConnection TargetListener TargetAdapter jdk.test.whitebox.WhiteBox
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
||||
* @run compile -g InvokeGcDisabledTest.java
|
||||
* @run driver InvokeGcDisabledTest
|
||||
* @run driver InvokeGcDisabledTest stress
|
||||
*/
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.event.*;
|
||||
import com.sun.jdi.request.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import jdk.test.whitebox.WhiteBox;
|
||||
|
||||
/********** target program **********/
|
||||
|
||||
class InvokeGcDisabledTarg {
|
||||
static boolean stressMode = false;
|
||||
|
||||
private static final WhiteBox WB = WhiteBox.getWhiteBox();
|
||||
private static volatile boolean stop = false;
|
||||
|
||||
public static void main(String[] args){
|
||||
System.out.println("Howdy!");
|
||||
if (args.length == 1 && "stress".equals(args[0])) {
|
||||
System.out.println("debuggee stress mode");
|
||||
stressMode = true;
|
||||
}
|
||||
if (stressMode) {
|
||||
Thread gcThread = new Thread(() -> {
|
||||
while (!stop) WB.fullGC();
|
||||
});
|
||||
gcThread.start();
|
||||
}
|
||||
(new InvokeGcDisabledTarg()).sayHi();
|
||||
stop = true;
|
||||
}
|
||||
|
||||
void sayHi() {
|
||||
}
|
||||
|
||||
InvokeGcDisabledTarg() {
|
||||
System.out.println("InvokeGcDisabledTarg::InvokeGcDisabledTarg called");
|
||||
}
|
||||
|
||||
InvokeGcDisabledTarg(boolean ignore) {
|
||||
System.out.println("InvokeGcDisabledTarg::InvokeGcDisabledTarg for exception called");
|
||||
throw new RuntimeException("Exception from debuggee");
|
||||
}
|
||||
|
||||
Object newObject() {
|
||||
System.out.println("InvokeGcDisabledTarg::newObject called");
|
||||
return new Object();
|
||||
}
|
||||
|
||||
static Object staticNewObject() {
|
||||
System.out.println("InvokeGcDisabledTarg::staticNewObject called");
|
||||
return new Object();
|
||||
}
|
||||
|
||||
void throwException() {
|
||||
System.out.println("InvokeGcDisabledTarg::throwException called");
|
||||
throw new RuntimeException("Exception from debuggee");
|
||||
}
|
||||
|
||||
void throwStaticException() {
|
||||
System.out.println("InvokeGcDisabledTarg::throwStaticException called");
|
||||
throw new RuntimeException("Exception from debuggee");
|
||||
}
|
||||
|
||||
void fullGC() {
|
||||
WB.fullGC();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/********** test program **********/
|
||||
|
||||
public class InvokeGcDisabledTest extends TestScaffold {
|
||||
static boolean stressMode = false;
|
||||
ClassType targetClass;
|
||||
ThreadReference mainThread;
|
||||
ObjectReference thisObject;
|
||||
List<Value> emptyArgs;
|
||||
List<Value> booleanArg;
|
||||
|
||||
Method forceDebuggeeGCMethod = null;
|
||||
|
||||
InvokeGcDisabledTest (String args[]) {
|
||||
super(args);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length == 1) {
|
||||
if ("stress".equals(args[0])) {
|
||||
System.out.println("debugger stress mode");
|
||||
stressMode = true;
|
||||
} else {
|
||||
throw new RuntimeException("bad argument: " + args[0]);
|
||||
}
|
||||
}
|
||||
try {
|
||||
new InvokeGcDisabledTest(args).startTests();
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace(System.out);
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
|
||||
/********** test assist **********/
|
||||
|
||||
void forceDebuggeeGC() throws Exception {
|
||||
if (forceDebuggeeGCMethod == null) {
|
||||
forceDebuggeeGCMethod = findMethod(targetClass, "fullGC", "()V");
|
||||
if (forceDebuggeeGCMethod == null) {
|
||||
failure("FAILED: Can't find method: \"fullGC\" for class = " + targetClass);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
println("Forcing debuggee full GC");
|
||||
thisObject.invokeMethod(mainThread, forceDebuggeeGCMethod, emptyArgs, ObjectReference.INVOKE_SINGLE_THREADED);
|
||||
}
|
||||
|
||||
ObjectReference invoke(Method method, InvokeType invokeType, int options, boolean throwsException)
|
||||
throws Exception {
|
||||
Value returnValue = null;
|
||||
options = options | ObjectReference.INVOKE_SINGLE_THREADED;
|
||||
|
||||
try {
|
||||
switch (invokeType) {
|
||||
case VIRTUAL_INVOKE_METHOD:
|
||||
returnValue = thisObject.invokeMethod(mainThread, method, emptyArgs, options);
|
||||
break;
|
||||
case STATIC_INVOKE_METHOD:
|
||||
returnValue = targetClass.invokeMethod(mainThread, method, emptyArgs, options);
|
||||
break;
|
||||
case NEW_INSTANCE:
|
||||
returnValue = targetClass.newInstance(mainThread, method,
|
||||
throwsException ? booleanArg : emptyArgs, options);
|
||||
break;
|
||||
}
|
||||
} catch (InvocationException ie) {
|
||||
if (!throwsException) {
|
||||
ie.printStackTrace();
|
||||
failure("Got Exception: " + ie);
|
||||
throw ie;
|
||||
} else {
|
||||
println("Got expected InvocationException: " + ie.exception());
|
||||
returnValue = ie.exception();
|
||||
}
|
||||
} catch (Exception ee) {
|
||||
ee.printStackTrace();
|
||||
failure("Got Exception: " + ee);
|
||||
throw ee;
|
||||
}
|
||||
println(" return val = " + returnValue);
|
||||
return (ObjectReference)returnValue;
|
||||
}
|
||||
|
||||
void verifyCollected(ObjectReference obj) {
|
||||
println("Verifying object is collected: " + obj);
|
||||
if (!obj.isCollected()) {
|
||||
failure("FAILED: object not collected: " + obj);
|
||||
}
|
||||
}
|
||||
|
||||
void verifyNotCollected(ObjectReference obj) {
|
||||
println("Verifying object is not collected: " + obj);
|
||||
if (obj.isCollected()) {
|
||||
failure("FAILED: object collected: " + obj);
|
||||
}
|
||||
}
|
||||
|
||||
private void testInvoke(String invokeMethod, String methodName, String methodSig, InvokeType invokeType,
|
||||
boolean throwsException, boolean stressMode) throws Exception {
|
||||
ObjectReference obj;
|
||||
Method method = findMethod(targetClass, methodName, methodSig);
|
||||
if (method == null) {
|
||||
failure("FAILED: Can't find method: \"" + methodName + methodSig + "\" for class = " + targetClass);
|
||||
return;
|
||||
}
|
||||
|
||||
println("*************************************************************************");
|
||||
println("* TESTING " + invokeMethod +" on " + targetClass.name() + "." + methodName + methodSig);
|
||||
println("* throwsException=" + throwsException + " stressMode=" + stressMode);
|
||||
println("*************************************************************************");
|
||||
|
||||
if (!stressMode) {
|
||||
// Theoretically this could generate an ObjectCollectedException, but shouldn't
|
||||
// unless we are running in stress mode to trigger a lot of GCs.
|
||||
println("TEST: Verify disableCollection works on allocated object");
|
||||
obj = invoke(method, invokeType, 0, throwsException);
|
||||
obj.disableCollection();
|
||||
forceDebuggeeGC();
|
||||
verifyNotCollected(obj);
|
||||
|
||||
println("TEST: Verify enableCollection allows allocated object to be collected");
|
||||
obj.enableCollection();
|
||||
forceDebuggeeGC();
|
||||
verifyCollected(obj);
|
||||
}
|
||||
|
||||
println("TEST: Verify INVOKE_DISABLE_COLLECTION disables collection of allocated object");
|
||||
obj = invoke(method, invokeType, ObjectReference.INVOKE_DISABLE_COLLECTION, throwsException);
|
||||
forceDebuggeeGC();
|
||||
verifyNotCollected(obj);
|
||||
|
||||
println("TEST: Verify enableCollection allows allocated object to be collected");
|
||||
obj.enableCollection();
|
||||
forceDebuggeeGC();
|
||||
verifyCollected(obj);
|
||||
}
|
||||
|
||||
private enum InvokeType {
|
||||
VIRTUAL_INVOKE_METHOD,
|
||||
STATIC_INVOKE_METHOD,
|
||||
NEW_INSTANCE
|
||||
}
|
||||
|
||||
/********** test core **********/
|
||||
|
||||
protected void runTests() throws Exception {
|
||||
ObjectReference obj;
|
||||
|
||||
enableWhiteBoxAPI(); // Allow debuggee to use WhiteBoxAPI
|
||||
|
||||
BreakpointEvent bpe = startTo("InvokeGcDisabledTarg", "sayHi", "()V");
|
||||
targetClass = (ClassType)bpe.location().declaringType();
|
||||
mainThread = bpe.thread();
|
||||
StackFrame frame = mainThread.frame(0);
|
||||
thisObject = frame.thisObject();
|
||||
|
||||
emptyArgs = new ArrayList(0);
|
||||
booleanArg = Arrays.asList(new Value[]{vm().mirrorOf(true)});
|
||||
|
||||
mainThread.suspend();
|
||||
vm().resume();
|
||||
|
||||
/*
|
||||
* We test 3 invocation APIs to make sure that using the INVOKE_DISABLE_COLLECTION
|
||||
* flag prevents the method result from being collected.
|
||||
* -ObjectReference.invokeMethod(): We don't differentiate between virtual and
|
||||
* non-virtual because it uses the same code paths.
|
||||
* -ClassType.invokeMethod(): Invocation of a static method.
|
||||
* -ClassType.newInstance(): Invocation of a constructor. We don't test
|
||||
* InterfaceType.newInstance() because it uses the same code paths.
|
||||
*
|
||||
* Each of these APIs can throw an InvocationException, which contains an
|
||||
* the ObjectReference of the exception thrown by the debuggee, so we also
|
||||
* need to test each of the above 3 APIs with an exception thrown to make
|
||||
* sure the INVOKE_DISABLE_COLLECTION flag also works on the exception object.
|
||||
*/
|
||||
|
||||
testInvoke("ObjectReference.invokeMethod()",
|
||||
"newObject", "()Ljava/lang/Object;",
|
||||
InvokeType. VIRTUAL_INVOKE_METHOD, false, stressMode);
|
||||
testInvoke("ObjectReference.invokeMethod()",
|
||||
"newObject", "()Ljava/lang/Object;",
|
||||
InvokeType.VIRTUAL_INVOKE_METHOD, true, stressMode);
|
||||
testInvoke("ClassType.invokeMethod()",
|
||||
"staticNewObject", "()Ljava/lang/Object;",
|
||||
InvokeType.STATIC_INVOKE_METHOD,false, stressMode);
|
||||
testInvoke("ClassType.invokeMethod()",
|
||||
"staticNewObject", "()Ljava/lang/Object;",
|
||||
InvokeType.STATIC_INVOKE_METHOD, true, stressMode);
|
||||
testInvoke("ClassType.newInstance()",
|
||||
"<init>", "()V",
|
||||
InvokeType.NEW_INSTANCE, false, stressMode);
|
||||
testInvoke("ClassType.newInstance()",
|
||||
"<init>", "(Z)V",
|
||||
InvokeType.NEW_INSTANCE, true, stressMode);
|
||||
|
||||
/*
|
||||
* resume the target so it can exit.
|
||||
*/
|
||||
mainThread.resume();
|
||||
listenUntilVMDisconnect();
|
||||
|
||||
/*
|
||||
* Deal with results of test.
|
||||
* Of anything has called failure("foo") testFailed will be true.
|
||||
*/
|
||||
if (!testFailed) {
|
||||
println("InvokeGcDisabledTest: passed");
|
||||
} else {
|
||||
throw new Exception("InvokeGcDisabledTest: failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user