3789983e89
Reviewed-by: darcy, ihse
308 lines
8.6 KiB
Java
308 lines
8.6 KiB
Java
/*
|
|
* Copyright (c) 2001, 2015, 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 4467564
|
|
* @summary Test the popping of frames in synchronous context
|
|
* (that is, when stopped at an event)
|
|
* @author Robert Field
|
|
*
|
|
* @run build TestScaffold VMConnection TargetListener TargetAdapter
|
|
* @run compile -g PopSynchronousTest.java
|
|
* @run driver PopSynchronousTest
|
|
*/
|
|
import com.sun.jdi.*;
|
|
import com.sun.jdi.event.*;
|
|
import com.sun.jdi.request.*;
|
|
|
|
import java.util.*;
|
|
|
|
/********** target program **********/
|
|
|
|
class PopSynchronousTarg {
|
|
static String s;
|
|
static PopSynchronousTarg sole;
|
|
|
|
synchronized void a(int y, boolean w) {
|
|
if (y == 6 && w) {
|
|
s += "@";
|
|
} else {
|
|
s += " aArgFail ";
|
|
}
|
|
}
|
|
String b(String h) {
|
|
if (h.equals("yo")) {
|
|
s += "[";
|
|
} else {
|
|
s += " bArgFail ";
|
|
}
|
|
a(6, true);
|
|
s += "]";
|
|
return s;
|
|
}
|
|
long c() {
|
|
s += "<";
|
|
synchronized (s) {
|
|
b("yo");
|
|
}
|
|
s += ">";
|
|
return 17;
|
|
}
|
|
static void p() {
|
|
s += "(";
|
|
if (sole.c() != 17) {
|
|
s += " cReturnFail ";
|
|
}
|
|
s += ")";
|
|
}
|
|
static void report() {
|
|
}
|
|
public static void main(String[] args){
|
|
s = new String();
|
|
sole = new PopSynchronousTarg();
|
|
for (int i = 0; i < 100; ++i) {
|
|
p();
|
|
// System.out.println(s);
|
|
report();
|
|
}
|
|
}
|
|
}
|
|
|
|
/********** test program **********/
|
|
|
|
public class PopSynchronousTest extends TestScaffold {
|
|
ReferenceType targetClass;
|
|
ThreadReference mainThread;
|
|
int stateIndex = 0;
|
|
String expected = "";
|
|
static final String[] calls = {"a", "b", "c", "p", "main"};
|
|
static final int popMax = calls.length - 1;
|
|
static final String[] states =
|
|
{"main-i", "p-e", "p-i", "c-e", "c-i", "b-e", "b-i", "a-e", "a-l", "b-l", "c-l", "p-l", "main-r", "report-e"};
|
|
static final String[] output =
|
|
{"", "", "(", "", "<", "", "[", "", "@", "]", ">", ")", "", ""};
|
|
|
|
|
|
PopSynchronousTest (String args[]) {
|
|
super(args);
|
|
}
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
new PopSynchronousTest(args).startTests();
|
|
}
|
|
|
|
|
|
/********** test assist **********/
|
|
|
|
StackFrame frameFor(String methodName) throws Exception {
|
|
Iterator it = mainThread.frames().iterator();
|
|
|
|
while (it.hasNext()) {
|
|
StackFrame frame = (StackFrame)it.next();
|
|
if (frame.location().method().name().equals(methodName)) {
|
|
return frame;
|
|
}
|
|
}
|
|
failure("FAIL: " + methodName + " not on stack");
|
|
return null;
|
|
}
|
|
|
|
String actual() throws Exception {
|
|
Field field = targetClass.fieldByName("s");
|
|
StringReference sr = (StringReference)(targetClass.getValue(field));
|
|
return sr.value();
|
|
}
|
|
|
|
void checkExpected() throws Exception {
|
|
if (!actual().equals(expected)) {
|
|
failure("FAIL: expected value: " + expected +
|
|
" got: " + actual());
|
|
}
|
|
}
|
|
|
|
int methodIndex(String methodName) {
|
|
for (int i = 0; i < popMax; ++i) {
|
|
if (methodName.equals(calls[i])) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
boolean isTop(String methodName) throws Exception {
|
|
return mainThread.frame(0).location().method().name().equals(methodName);
|
|
}
|
|
|
|
void checkTop(String methodName, boolean atStart) throws Exception {
|
|
Location loc = mainThread.frame(0).location();
|
|
Method meth = loc.method();
|
|
String name = meth.name();
|
|
if (!isTop(methodName)) {
|
|
failure("FAIL: expected " + methodName +
|
|
" at top of stack, instead: " + name);
|
|
} else if ((meth.location().codeIndex() == loc.codeIndex()) != atStart) {
|
|
failure("FAIL: not at expect position: " + loc.codeIndex());
|
|
}
|
|
}
|
|
|
|
void checkState() throws Exception {
|
|
String name = states[stateIndex];
|
|
int dash = name.indexOf('-');
|
|
String methodName = name.substring(0,dash);
|
|
String posName = name.substring(dash+1);
|
|
checkTop(methodName, posName.equals("e"));
|
|
checkExpected();
|
|
}
|
|
|
|
void incrementState() {
|
|
stateIndex = (stateIndex + 1) % (states.length);
|
|
}
|
|
|
|
void resetState(String stateName) {
|
|
for (int i=0; i < states.length; ++i) {
|
|
if (states[i].equals(stateName)) {
|
|
stateIndex = i;
|
|
return;
|
|
}
|
|
}
|
|
failure("TEST FAILURE: cannot find state: " + stateName);
|
|
}
|
|
|
|
void resetExpected() throws Exception {
|
|
println("Current value: " + actual());
|
|
Field field = targetClass.fieldByName("s");
|
|
expected = "";
|
|
((ClassType)targetClass).setValue(field, vm().mirrorOf(expected));
|
|
}
|
|
|
|
void stateTo(String stateName) {
|
|
do {
|
|
incrementState();
|
|
expected += output[stateIndex];
|
|
} while(!states[stateIndex].equals(stateName));
|
|
}
|
|
|
|
void resumeTo(String methodName) throws Exception {
|
|
List meths = targetClass.methodsByName(methodName);
|
|
Method meth = (Method)(meths.get(0));
|
|
resumeTo(meth.location());
|
|
stateTo(methodName + "-e");
|
|
checkState();
|
|
}
|
|
|
|
void pop(String methodName) throws Exception {
|
|
mainThread.popFrames(frameFor(methodName));
|
|
resetState(methodName + "-e");
|
|
--stateIndex;
|
|
checkState();
|
|
}
|
|
|
|
void reenter(String methodName) throws Exception {
|
|
pop(methodName);
|
|
stepIntoInstruction(mainThread);
|
|
incrementState();
|
|
checkState();
|
|
}
|
|
|
|
/********** test core **********/
|
|
|
|
protected void runTests() throws Exception {
|
|
/*
|
|
* Get to the top of main()
|
|
* to determine targetClass and mainThread
|
|
*/
|
|
BreakpointEvent bpe = startToMain("PopSynchronousTarg");
|
|
targetClass = bpe.location().declaringType();
|
|
mainThread = bpe.thread();
|
|
|
|
/*
|
|
* Testing
|
|
*/
|
|
|
|
/* individual tests */
|
|
for (int i = 0; i < popMax; ++i) {
|
|
String from = calls[i];
|
|
for (int j = i; j < popMax; ++j) {
|
|
String to = calls[j];
|
|
String prev = calls[j+1];
|
|
println("TEST pop from '" + from + "' to '" + to + "'");
|
|
resumeTo(from);
|
|
reenter(to);
|
|
resumeTo("report");
|
|
resetExpected();
|
|
}
|
|
}
|
|
|
|
/* sequential tests */
|
|
|
|
println("TEST pop a b c p");
|
|
resumeTo("a");
|
|
pop("a");
|
|
pop("b");
|
|
pop("c");
|
|
pop("p");
|
|
resumeTo("report");
|
|
resetExpected();
|
|
|
|
println("TEST pop a c p");
|
|
resumeTo("a");
|
|
pop("a");
|
|
pop("c");
|
|
pop("p");
|
|
resumeTo("report");
|
|
resetExpected();
|
|
|
|
println("TEST stress a");
|
|
resumeTo("a");
|
|
for (int i = 0; i < 100; ++i) {
|
|
reenter("a");
|
|
}
|
|
resumeTo("report");
|
|
resetExpected();
|
|
|
|
println("TEST stress c");
|
|
resumeTo("c");
|
|
for (int i = 0; i < 100; ++i) {
|
|
reenter("c");
|
|
}
|
|
resumeTo("report");
|
|
resetExpected();
|
|
|
|
/*
|
|
* we are done, get rid of target
|
|
*/
|
|
vm().dispose();
|
|
|
|
/*
|
|
* deal with results of test
|
|
* if anything has called failure("foo") testFailed will be true
|
|
*/
|
|
if (!testFailed) {
|
|
println("PopSynchronousTest: passed");
|
|
} else {
|
|
throw new Exception("PopSynchronousTest: failed");
|
|
}
|
|
}
|
|
}
|