diff options
author | Sebastien Hertz <shertz@google.com> | 2015-04-08 14:10:48 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-04-08 14:10:48 +0000 |
commit | 6d2abdec770d947de3e80be66f1d758e4f160a93 (patch) | |
tree | 95bdc03b68fb72f689d6740fcd7bad358bbfeb19 | |
parent | ecf184f7714cd6eeb38c2da78e4f028b50c6c699 (diff) | |
parent | 8a7069b744f3197c541a304eaa18a3dc915d870e (diff) | |
download | apache-harmony-6d2abdec770d947de3e80be66f1d758e4f160a93.tar.gz |
am 8a7069b7: Merge "Test exception handling during deoptimization"
* commit '8a7069b744f3197c541a304eaa18a3dc915d870e':
Test exception handling during deoptimization
3 files changed, 232 insertions, 0 deletions
diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Deoptimization/DeoptimizationWithExceptionHandlingDebuggee.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Deoptimization/DeoptimizationWithExceptionHandlingDebuggee.java new file mode 100644 index 0000000..57723c3 --- /dev/null +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Deoptimization/DeoptimizationWithExceptionHandlingDebuggee.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.jpda.tests.jdwp.Deoptimization; + +import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; +import org.apache.harmony.jpda.tests.share.SyncDebuggee; + +/** + * Debuggee for DeoptimizationWithExceptionHandlingTest. + */ +public class DeoptimizationWithExceptionHandlingDebuggee extends SyncDebuggee { + public static final int SUCCESS_RESULT = 1; + public static final int FAILURE_RESULT = 0; + + public static void main(String[] args) { + runDebuggee(DeoptimizationWithExceptionHandlingDebuggee.class); + } + + public void run() { + logWriter.println("--> DeoptimizationWithExceptionHandlingDebuggee started"); + synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_READY); + + // Wait for test setup + synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); + + int result = runTest(); + logWriter.println("Result == " + result); + + // Send result to test. + synchronizer.sendMessage(Integer.toString(result)); + + logWriter.println("--> DeoptimizationWithExceptionHandlingDebuggee finished"); + } + + /** + * This method will catch the NullPointerException after deoptimization happened. + */ + private static int runTest() { + int result = FAILURE_RESULT; + try { + runBreakpointMethodThenThrowNPE(); + result = FAILURE_RESULT; + } catch (NullPointerException e) { + result = SUCCESS_RESULT; + } + return result; + } + + /** + * This method will throw a NullPointerException after deoptimization happened. + */ + private static void runBreakpointMethodThenThrowNPE() { + runBreakpointMethod(); + throw new NullPointerException(); + } + + /** + * This method will be the starting point of stack deoptimization. + */ + private static void runBreakpointMethod() { + breakpointMethod(); + } + + private static void breakpointMethod() { + System.out.println("breakpointMethod"); + } + +} diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Deoptimization/DeoptimizationWithExceptionHandlingTest.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Deoptimization/DeoptimizationWithExceptionHandlingTest.java new file mode 100644 index 0000000..24e1aca --- /dev/null +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/jdwp/Deoptimization/DeoptimizationWithExceptionHandlingTest.java @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.jpda.tests.jdwp.Deoptimization; + +import org.apache.harmony.jpda.tests.framework.jdwp.EventPacket; +import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; +import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent; +import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; +import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase; +import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; + +public class DeoptimizationWithExceptionHandlingTest extends JDWPSyncTestCase { + + @Override + protected String getDebuggeeClassName() { + return DeoptimizationWithExceptionHandlingDebuggee.class.getName(); + } + + /** + * This tests checks we properly handle exception event when we fully + * deoptimize the stack. + * We first set a BREAKPOINT event to suspend the debuggee. Once we + * hit the breakpoint, we set a METHOD_ENTRY event on the debuggee class + * to cause a full deoptimization of the stack and resume it. + * Finally, we wait for the debuggee to send us the result of the test + * (an integer as a string) and check this is the expected result. + */ + public void testDeoptimizationWithExceptionHandling_001() { + logWriter.println("testDeoptimizationWithExceptionHandling_001 starts"); + runTestDeoptimizationWithExceptionHandling(false); + logWriter.println("testDeoptimizationWithExceptionHandling_001 ends"); + } + + /** + * This tests checks we properly handle exception event when we fully + * deoptimize the stack and are able to receive EXCEPTION event for the + * thrown exception. + * We first set a BREAKPOINT event to suspend the debuggee. Once we + * hit the breakpoint, we set a METHOD_ENTRY event on the debuggee class + * to cause a full deoptimization of the stack and an EXCEPTION event + * to check we do suspend the debuggee for the thrown exception, and + * we resume the debuggee. + * Then we wait for the EXCEPTION event to be posted and resume the + * debuggee again. + * Finally, we wait for the debuggee to send us the result of the test + * (an integer as a string) and check this is the expected result. + */ + public void testDeoptimizationWithExceptionHandling_002() { + logWriter.println("testDeoptimizationWithExceptionHandling_002 starts"); + runTestDeoptimizationWithExceptionHandling(true); + logWriter.println("testDeoptimizationWithExceptionHandling_002 ends"); + } + + private void runTestDeoptimizationWithExceptionHandling(boolean withExceptionEvent) { + // Suspend debuggee on a breakpoint. + stopOnBreakpoint(); + + // Request MethodEntry event to cause full deoptimization of the debuggee. + installMethodEntry(); + + int exceptionRequestID = -1; + if (withExceptionEvent) { + // Request Exception event to test we suspend for this event during deoptimization. + exceptionRequestID = requestExceptionEvent(); + } + + // Resume the debuggee from the breakpoint. + debuggeeWrapper.vmMirror.resume(); + + if (exceptionRequestID != -1) { + // Wait for the Exception event. + waitForExceptionEvent(exceptionRequestID); + + // Resume the debuggee from the exception. + debuggeeWrapper.vmMirror.resume(); + } + + // Wait for result from debuggee + String resultAsString = synchronizer.receiveMessage(); + int result = Integer.parseInt(resultAsString); + + assertEquals("Incorrect result", + DeoptimizationWithExceptionHandlingDebuggee.SUCCESS_RESULT, result); + } + + private void stopOnBreakpoint() { + // Wait for debuggee to start. + synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); + + long debuggeeClassID = getClassIDBySignature(getDebuggeeClassSignature()); + int requestID = debuggeeWrapper.vmMirror.setBreakpointAtMethodBegin(debuggeeClassID, + "breakpointMethod"); + + // Continue debuggee. + synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); + + // Wait for breakpoint. + debuggeeWrapper.vmMirror.waitForBreakpoint(requestID); + + // Remove breakpoint. + debuggeeWrapper.vmMirror.clearBreakpoint(requestID); + } + + private void installMethodEntry() { + ReplyPacket replyPacket = debuggeeWrapper.vmMirror.setMethodEntry(getDebuggeeClassName()); + replyPacket.getNextValueAsInt(); // unused 'requestID' + assertAllDataRead(replyPacket); + } + + private int requestExceptionEvent() { + final String exceptionClassSignature = "Ljava/lang/NullPointerException;"; + ReplyPacket replyPacket = + debuggeeWrapper.vmMirror.setException(exceptionClassSignature, true, false); + int requestID = replyPacket.getNextValueAsInt(); + assertAllDataRead(replyPacket); + return requestID; + } + + private void waitForExceptionEvent(int requestID) { + final byte eventKind = JDWPConstants.EventKind.EXCEPTION; + EventPacket event = debuggeeWrapper.vmMirror.receiveCertainEvent(eventKind); + + ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(event); + assertNotNull("Expected an exception event", parsedEvents); + assertEquals("Expected only one event", 1, parsedEvents.length); + assertEquals("Not the excepted event", requestID, parsedEvents[0].getRequestID()); + + // Clear the event + debuggeeWrapper.vmMirror.clearEvent(eventKind, requestID); + } +} diff --git a/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java b/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java index bcb1864..ce2d2f1 100644 --- a/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java +++ b/jdwp/src/test/java/org/apache/harmony/jpda/tests/share/AllTests.java @@ -70,6 +70,7 @@ public class AllTests { suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.ClassType.SetValues002Test.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.ClassType.SetValuesTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.ClassType.SuperClassTest.class); + suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.Deoptimization.DeoptimizationWithExceptionHandlingTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.EventModifiers.CountModifierTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.EventModifiers.InstanceOnlyModifierTest.class); suite.addTestSuite(org.apache.harmony.jpda.tests.jdwp.EventModifiers.ThreadOnlyModifierTest.class); |