1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package org.apache.harmony.jpda.tests.jdwp.Deoptimization; 20 21 import org.apache.harmony.jpda.tests.framework.jdwp.EventPacket; 22 import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants; 23 import org.apache.harmony.jpda.tests.framework.jdwp.ParsedEvent; 24 import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket; 25 import org.apache.harmony.jpda.tests.jdwp.share.JDWPSyncTestCase; 26 import org.apache.harmony.jpda.tests.share.JPDADebuggeeSynchronizer; 27 28 public class DeoptimizationWithExceptionHandlingTest extends JDWPSyncTestCase { 29 30 @Override getDebuggeeClassName()31 protected String getDebuggeeClassName() { 32 return DeoptimizationWithExceptionHandlingDebuggee.class.getName(); 33 } 34 35 /** 36 * This tests checks we properly handle exception event when we fully 37 * deoptimize the stack. 38 * We first set a BREAKPOINT event to suspend the debuggee. Once we 39 * hit the breakpoint, we set a METHOD_ENTRY event on the debuggee class 40 * to cause a full deoptimization of the stack and resume it. 41 * Finally, we wait for the debuggee to send us the result of the test 42 * (an integer as a string) and check this is the expected result. 43 */ testDeoptimizationWithExceptionHandling_001()44 public void testDeoptimizationWithExceptionHandling_001() { 45 logWriter.println("testDeoptimizationWithExceptionHandling_001 starts"); 46 runTestDeoptimizationWithExceptionHandling(false); 47 logWriter.println("testDeoptimizationWithExceptionHandling_001 ends"); 48 } 49 50 /** 51 * This tests checks we properly handle exception event when we fully 52 * deoptimize the stack and are able to receive EXCEPTION event for the 53 * thrown exception. 54 * We first set a BREAKPOINT event to suspend the debuggee. Once we 55 * hit the breakpoint, we set a METHOD_ENTRY event on the debuggee class 56 * to cause a full deoptimization of the stack and an EXCEPTION event 57 * to check we do suspend the debuggee for the thrown exception, and 58 * we resume the debuggee. 59 * Then we wait for the EXCEPTION event to be posted and resume the 60 * debuggee again. 61 * Finally, we wait for the debuggee to send us the result of the test 62 * (an integer as a string) and check this is the expected result. 63 */ testDeoptimizationWithExceptionHandling_002()64 public void testDeoptimizationWithExceptionHandling_002() { 65 logWriter.println("testDeoptimizationWithExceptionHandling_002 starts"); 66 runTestDeoptimizationWithExceptionHandling(true); 67 logWriter.println("testDeoptimizationWithExceptionHandling_002 ends"); 68 } 69 runTestDeoptimizationWithExceptionHandling(boolean withExceptionEvent)70 private void runTestDeoptimizationWithExceptionHandling(boolean withExceptionEvent) { 71 // Suspend debuggee on a breakpoint. 72 stopOnBreakpoint(); 73 74 // Request MethodEntry event to cause full deoptimization of the debuggee. 75 installMethodEntry(); 76 77 int exceptionRequestID = -1; 78 if (withExceptionEvent) { 79 // Request Exception event to test we suspend for this event during deoptimization. 80 exceptionRequestID = requestExceptionEvent(); 81 } 82 83 // Resume the debuggee from the breakpoint. 84 debuggeeWrapper.vmMirror.resume(); 85 86 if (exceptionRequestID != -1) { 87 // Wait for the Exception event. 88 waitForExceptionEvent(exceptionRequestID); 89 90 // Resume the debuggee from the exception. 91 debuggeeWrapper.vmMirror.resume(); 92 } 93 94 // Wait for result from debuggee 95 String resultAsString = synchronizer.receiveMessage(); 96 int result = Integer.parseInt(resultAsString); 97 98 assertEquals("Incorrect result", 99 DeoptimizationWithExceptionHandlingDebuggee.SUCCESS_RESULT, result); 100 } 101 stopOnBreakpoint()102 private void stopOnBreakpoint() { 103 // Wait for debuggee to start. 104 synchronizer.receiveMessage(JPDADebuggeeSynchronizer.SGNL_READY); 105 106 long debuggeeClassID = getClassIDBySignature(getDebuggeeClassSignature()); 107 int requestID = debuggeeWrapper.vmMirror.setBreakpointAtMethodBegin(debuggeeClassID, 108 "breakpointMethod"); 109 110 // Continue debuggee. 111 synchronizer.sendMessage(JPDADebuggeeSynchronizer.SGNL_CONTINUE); 112 113 // Wait for breakpoint. 114 debuggeeWrapper.vmMirror.waitForBreakpoint(requestID); 115 116 // Remove breakpoint. 117 debuggeeWrapper.vmMirror.clearBreakpoint(requestID); 118 } 119 installMethodEntry()120 private void installMethodEntry() { 121 ReplyPacket replyPacket = debuggeeWrapper.vmMirror.setMethodEntry(getDebuggeeClassName()); 122 replyPacket.getNextValueAsInt(); // unused 'requestID' 123 assertAllDataRead(replyPacket); 124 } 125 requestExceptionEvent()126 private int requestExceptionEvent() { 127 final String exceptionClassSignature = "Ljava/lang/NullPointerException;"; 128 ReplyPacket replyPacket = 129 debuggeeWrapper.vmMirror.setException(exceptionClassSignature, true, false); 130 int requestID = replyPacket.getNextValueAsInt(); 131 assertAllDataRead(replyPacket); 132 return requestID; 133 } 134 waitForExceptionEvent(int requestID)135 private void waitForExceptionEvent(int requestID) { 136 final byte eventKind = JDWPConstants.EventKind.EXCEPTION; 137 EventPacket event = debuggeeWrapper.vmMirror.receiveCertainEvent(eventKind); 138 139 ParsedEvent[] parsedEvents = ParsedEvent.parseEventPacket(event); 140 assertNotNull("Expected an exception event", parsedEvents); 141 assertEquals("Expected only one event", 1, parsedEvents.length); 142 assertEquals("Not the excepted event", requestID, parsedEvents[0].getRequestID()); 143 144 // Clear the event 145 debuggeeWrapper.vmMirror.clearEvent(eventKind, requestID); 146 } 147 } 148