/* * Copyright (c) 2022 SAP SE. 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. *
*/
enum TestCaseVariants {
NO_VARIANT, // Exception
THROW_HANDLED_EXCEPTION,
THROW_UNHANDLED_EXCEPTION, // Synchronization
ALLOC_MONITOR, // There are values on the expression stack that are not call parameters
EXPR_STACK_NOT_EMPTY,
}
publicstaticvoid runTests() {
System.out.println("$$$0 Running test cases with the following settings:");
System.out.println("compLevel=" + compLevel);
System.out.println("callSystemGC=" + triggerGCAfterYield);
System.out.println();
WB.deoptimizeAll();
boolean all = compPolicySelection == 0; if (compPolicySelection == 1 || all)
runTests(new CompilationPolicy(7 /*warmup*/, COMP_NONE, COMP_NONE /*Cont. pattern*/)); if (compPolicySelection == 2 || all)
runTests(new CompilationPolicy(7 /*warmup*/, 1 /* length comp. window */)); if (compPolicySelection == 3 || all)
runTests(new CompilationPolicy(7 /*warmup*/, 2 /* length comp. window */)); if (compPolicySelection == 4 || all)
runTests(new CompilationPolicy(7 /*warmup*/, 3 /* length comp. window */)); if (compPolicySelection == 5 || all)
runTests(new CompilationPolicy(7 /*warmup*/, COMP_ALL, CONT_METHS /*Cont. pattern*/)); if (compPolicySelection >= 6) thrownew Error("CompilationPolicy with number " + compPolicySelection + " does not exist");
}
publicstaticvoid runTests(CompilationPolicy compPolicy) {
System.out.println("$$$1 Running test cases with the following policy:");
compPolicy.print(); System.out.println();
new ContinuationRunYieldRunTest().runTestCase(3, compPolicy); new Continuation3Frames(TestCaseVariants.NO_VARIANT).runTestCase(4, compPolicy); new Continuation3Frames(TestCaseVariants.THROW_HANDLED_EXCEPTION).runTestCase(4, compPolicy); new Continuation3Frames(TestCaseVariants.THROW_UNHANDLED_EXCEPTION).runTestCase(4, compPolicy); new Continuation3Frames(TestCaseVariants.ALLOC_MONITOR).runTestCase(4, compPolicy); new Continuation3Frames(TestCaseVariants.EXPR_STACK_NOT_EMPTY).runTestCase(4, compPolicy); new ContinuationRunYieldRunTest().runTestCase( 1, compPolicy); new ContinuationYieldEnlargeStackYield().runTestCase(1, compPolicy); new ContinuationYieldReduceStackYield().runTestCase(1, compPolicy); new ContinuationCompiledFramesWithStackArgs_3c0().runTestCase(1, compPolicy); new ContinuationCompiledFramesWithStackArgs_3c4().runTestCase(1, compPolicy); new ContinuationCompiledFramesWithStackArgs().runTestCase(1, compPolicy); new ContinuationDeepRecursion().runTestCase(3, compPolicy); new ContinuationDeepRecursionStackargs().runTestCase(3, compPolicy);
}
// Control which frames are compiled/interpreted when calling Continuation.yield() // With COMP_WINDOW the methods in the window are supposed to be compiled and others // are interpreted. With DEOPT_WINDOW vice versa. // The methods that are subject to the CompilationPolicy are set with setMethods(). // Their order has to correspond to the stack order when calling yield(). publicstaticclass CompilationPolicy { publicint warmupIterations; public Pattern methodPattern; public Pattern contMethPattern;
public CompWindowMode compWindowMode; publicint winPos; publicint winLen;
/** * Base class for test cases
*/ publicstaticabstractclass TestCaseBase implements Runnable { publicint yieldCalls; publicint warmUpCount; public CompilationPolicy compPolicy; publicfinal TestCaseVariants testVariant;
public TestCaseBase() {
testVariant = TestCaseVariants.NO_VARIANT;
}
public TestCaseBase(TestCaseVariants excBehav) { this.testVariant = excBehav;
}
publicvoid log_dontjit(String m) { if (warmUpCount > 0) {
System.out.print("[" + warmUpCount + "] ");
}
System.out.println(m);
}
publicvoid runTestCase(int yieldCalls, CompilationPolicy compPolicy) { this.yieldCalls = yieldCalls;
log_dontjit(">>>> Executing test case " + getClass().getName() + " (yieldCalls=" + yieldCalls + ", " + "testVariant=" + testVariant + ")");
init(compPolicy); try {
log_dontjit("Warm-up test case");
setup_dontjit(true/* for warmup */); for(warmUpCount = 1; warmUpCount <= compPolicy.warmupIterations(); warmUpCount++) {
testEntry_dontinline();
}
warmUpCount = 0;
log_dontjit("Warm-up test case DONE");
setup_dontjit(false/* for warmup */); do {
compPolicy.compileMethods(); do {
log_dontjit("Running test case (Reresolve Call Sites)");
testEntry_dontinline();
log_dontjit("Running test case DONE (Reresolve Call Sites)");
} while(compPolicy.compileMethods());
log_dontjit("Running test case BEGIN");
testEntry_dontinline();
log_dontjit("Running test case DONE");
} while(compPolicy.shiftWindow());
} finally {
log_dontjit("<<<< Finished test case " + getClass().getName()); log_dontjit();
}
}
publicvoid setup_dontjit(boolean warmup) {
}
publicvoid init(CompilationPolicy compPolicy) { this.compPolicy = compPolicy;
ArrayList<Method> selectedMethods = new ArrayList<Method>();
Pattern p = compPolicy.methodPattern; if (p != COMP_NONE) { Class<? extends TestCaseBase> c = getClass();
Method methods[] = c.getDeclaredMethods(); for (Method meth : methods) { if (p == COMP_ALL || p.matcher(meth.getName()).matches()) { if (!meth.getName().contains("dontjit")) {
selectedMethods.add(meth);
}
}
}
}
p = compPolicy.contMethPattern; if (compPolicy.contMethPattern != COMP_NONE) { Class<?> c = Continuation.class;
Method methods[] = c .getDeclaredMethods(); for (Method meth : methods) { if (p.matcher(meth.getName()).matches()) {
selectedMethods.add(meth);
}
}
} // Sort in caller/callee order
selectedMethods.sort(new Comparator<Method>() {
@Override publicint compare(Method m1, Method m2) {
String n1 = m1.getName();
String n2 = m2.getName(); // log_dontjit("n1=" + n1 + " n2=" + n2); int p1 = -1; int p2 = -1; int i = n1.indexOf("ord"); if (i >= 0) {
p1 = Integer.parseInt(n1.substring(i + 3, i + 6));
}
i = n2.indexOf("ord"); if (i >= 0) {
p2 = Integer.parseInt(n2.substring(i + 3, i + 6));
} if (p1 < 0) p1 = getScoreKnownMethods(n1); if (p2 < 0) p2 = getScoreKnownMethods(n2);
assertFalse(p1 == -1 || p2 == -1, "Cannot compare " + n1 + " with " + n2); return p1 - p2;
}
privateint getScoreKnownMethods(String n) { int p = -1; if (n.equals("enter")) p = 20; // Continuation.enter if (n.equals("enter0")) p = 30; // Continuation.enter0 if (n.equals("run")) p = 50; // Called by Continuation.enter0 if (n.equals("yield")) p = 1000; // caller of yield0 if (n.equals("yield0")) p = 2000; // top frame return p;
}
});
compPolicy.setMethods(selectedMethods.toArray(new Method[selectedMethods.size()]));
}
publicvoid testEntry_dontinline() {
Continuation cont = new Continuation(THE_SCOPE, this); do { try {
cont.run();
} catch (UnhandledException e) {
log_dontjit("Exc: " + e);
} if (triggerGCAfterYield) WB.youngGC();
checkFrames_dontjit(cont);
} while (!cont.isDone());
}
publicvoid checkFrames_dontjit(Continuation cont) {
} // Override in subclass as appropriate
@Override publicvoid run() {
fail("Should not call TestCaseBase::run");
}
/** * Yield, make continuation (stack) larger, yield again.
*/ publicstaticclass ContinuationYieldEnlargeStackYield extends TestCaseBase {
@Override publicvoid run() {
log_dontjit("Continuation running on thread " + Thread.currentThread());
Continuation.yield(THE_SCOPE);
log_dontjit("Back from 1st yield. Now call a method to make the stack larger.");
ord101_callYieldWithLargerStackAgain_dontinline();
}
privatevoid ord101_callYieldWithLargerStackAgain_dontinline() {
log_dontjit("Now there's a new frame on stack. Call yield again.");
Continuation.yield(THE_SCOPE);
log_dontjit("Back again after 2nd yield.");
}
}
/** * Yield, make continuation (stack) larger, yield again.
*/ publicstaticclass ContinuationYieldReduceStackYield extends TestCaseBase {
@Override publicvoid run() {
log_dontjit("Continuation running on thread " + Thread.currentThread());
ord101_methodWithFirstYield_dontinline();
log_dontjit("The frame of ord101_methodWithFirstYield_dontinline has been removed now. Call yield again.");
Continuation.yield(THE_SCOPE);
log_dontjit("Back again after 2nd yield.");
}
publicvoid ord101_methodWithFirstYield_dontinline() {
Continuation.yield(THE_SCOPE);
log_dontjit("Back from 1st yield. Now return to reduce stack size.");
}
}
publiclong ord101_recurse_dontinline(int depth, long l1, long l2, long
l3, long l4, long l5, long l6, long l7, long l8, long l9, long
l10, long l11) { if (depth >= limit) {
log_dontjit("yield at depth " + depth);
ord102_yield_dontinline(0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11);
log_dontjit("After yield at depth " + depth); return l1 + l2 + l3 + l4 + l5 + l6 + l7 + l8 + l9 + l10 + l11;
} long res = ord101_recurse_dontinline(depth + 1, l1, l2, l3, l4, l5,
l6, l7, l8, l9, l10, l11); if (res != l1 + l2 + l3 + l4 + l5 + l6 + l7 + l8 + l9 + l10 + l11) { thrownew Error();
} if (depth == yield1_depth || depth == yield2_depth) {
log_dontjit("yield at depth " + depth); long res1 = ord102_yield_dontinline(0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11); if (res1 != l1 + l2 + l3 + l4 + l5 + l6 + l7 + l8 + l9 + l10 + l11) { thrownew Error();
}
log_dontjit("After yield at depth " + depth);
} return res;
}
// Add a few frames before yield publiclong ord102_yield_dontinline(int depth, long l1, long l2, long l3, long l4, long l5, long l6, long l7, long l8, long l9, long l10, long l11) { if (depth >= 2) {
Continuation.yield(THE_SCOPE); return l1 + l2 + l3 + l4 + l5 + l6 + l7 + l8 + l9 + l10 + l11;
} long res = ord102_yield_dontinline(depth + 1, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11); if (res != l1 + l2 + l3 + l4 + l5 + l6 + l7 + l8 + l9 + l10 + l11) { thrownew Error();
} return res;
}
}
/** * Freeze/thaw compiled frame with a few stack arguments * icj is a call with i incoming stack parameters and j outgoing stack parameters.
*/ publicstaticclass ContinuationCompiledFramesWithStackArgs_3c0 extends TestCaseBase { publicint yieldCount;
@Override publicvoid run() {
log_dontjit("Continuation running on thread " + Thread.currentThread());
yieldCount = 0; long result = ord101_testMethod_dontinline();
assertEQ(result, 136L);
}
publiclong ord102_testMethod_dontinline(long a1, long a2, long a3, long
a4, long a5, long a6, long a7, long a8, long a9, long a10, long a11) { long res = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11
+ i12 + i13 + i14 + i15 + i16;
log_dontjit("Yield #" + yieldCount);
log_dontjit("ord109_testMethod_dontinline res=" + res);
Continuation.yield(THE_SCOPE);
log_dontjit("a/y ord109_testMethod_dontinline res=" + res);
log_dontjit("/Yield #" + yieldCount++); return res;
}
}
/** * Freeze/thaw compiled frame with a few stack arguments, incoming _and_ outgoing * icj is a call with i incoming stack parameters and j outgoing stack parameters.
*/ publicstaticclass ContinuationCompiledFramesWithStackArgs_3c4 extends TestCaseBase { publicint yieldCount;
@Override publicvoid run() {
log_dontjit("Continuation running on thread " + Thread.currentThread());
yieldCount = 0; long result = ord101_testMethod_dontinline();
assertEQ(result, 136L);
}
publiclong ord102_testMethod_dontinline(long a1, long a2, long a3, long
a4, long a5, long a6, long a7, long a8, long a9, long a10, long a11, long a12, long a13, long a14) { long res = ord103_testMethod_dontinline(a1, a2, a3, a4, a5, a6, a7, a8,
a9, a10, a11, a12, a13, a14, i15);
log_dontjit("Yield #" + yieldCount);
log_dontjit("ord109_testMethod_dontinline res=" + res);
Continuation.yield(THE_SCOPE);
log_dontjit("a/y ord109_testMethod_dontinline res=" + res);
log_dontjit("/Yield #" + yieldCount++); return res;
}
publiclong ord103_testMethod_dontinline(long a1, long a2, long a3, long
a4, long a5, long a6, long a7, long a8, long a9, long a10, long a11, long a12, long a13, long a14, long a15) { long res = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + a11
+ a12 + a13 + a14 + a15 + i16;
log_dontjit("Yield #" + yieldCount);
log_dontjit("ord109_testMethod_dontinline res=" + res);
Continuation.yield(THE_SCOPE);
log_dontjit("a/y ord109_testMethod_dontinline res=" + res);
log_dontjit("/Yield #" + yieldCount++); return res;
}
}
/** * Freeze/thaw compiled frame with many stack arguments
*/ publicstaticclass ContinuationCompiledFramesWithStackArgs extends TestCaseBase { publicint yieldCount;
@Override publicvoid run() {
log_dontjit("Continuation running on thread " + Thread.currentThread());
yieldCount = 0; long result = ord101_testMethod_dontinline(i1);
assertEQ(result, 136L);
}
publiclong ord102_testMethod_dontinline(long a1, long a2) { long res = ord103_testMethod_dontinline(a1, a2, i3);
log_dontjit("Yield #" + yieldCount);
Continuation.yield(THE_SCOPE);
log_dontjit("/Yield #" + yieldCount++); return res;
}
publiclong ord103_testMethod_dontinline(long a1, long a2, long a3) { long res = ord104_testMethod_dontinline(a1, a2, a3, i4);
log_dontjit("Yield #" + yieldCount);
Continuation.yield(THE_SCOPE);
log_dontjit("/Yield #" + yieldCount++); return res;
}
publiclong ord104_testMethod_dontinline(long a1, long a2, long a3, long a4) { long res = ord105_testMethod_dontinline(a1, a2, a3, a4, i5);
log_dontjit("Yield #" + yieldCount);
Continuation.yield(THE_SCOPE);
log_dontjit("/Yield #" + yieldCount++); return res;
}
publiclong ord105_testMethod_dontinline(long a1, long a2, long a3, long a4, long a5) { long res = ord106_testMethod_dontinline(a1, a2, a3, a4, a5, i6);
log_dontjit("Yield #" + yieldCount);
Continuation.yield(THE_SCOPE);
log_dontjit("/Yield #" + yieldCount++); return res;
}
publiclong ord106_testMethod_dontinline(long a1, long a2, long a3, long a4, long a5, long a6) { long res = ord107_testMethod_dontinline(a1, a2, a3, a4, a5, a6, i7);
log_dontjit("Yield #" + yieldCount);
Continuation.yield(THE_SCOPE);
log_dontjit("/Yield #" + yieldCount++); return res;
}
publiclong ord107_testMethod_dontinline(long a1, long a2, long a3, long
a4, long a5, long a6, long a7) { long res = ord108_testMethod_dontinline(a1, a2, a3, a4, a5, a6, a7, i8);
log_dontjit("Yield #" + yieldCount);
log_dontjit("ord108_testMethod_dontinline res=" + res);
Continuation.yield(THE_SCOPE);
log_dontjit("a/y ord108_testMethod_dontinline res=" + res);
log_dontjit("/Yield #" + yieldCount++); return res;
}
publiclong ord108_testMethod_dontinline(long a1, long a2, long a3, long
a4, long a5, long a6, long a7, long a8) { long res = ord109_testMethod_dontinline(a1, a2, a3, a4, a5, a6, a7, a8, i9);
log_dontjit("Yield #" + yieldCount);
log_dontjit("ord109_testMethod_dontinline res=" + res);
Continuation.yield(THE_SCOPE);
log_dontjit("a/y ord109_testMethod_dontinline res=" + res);
log_dontjit("/Yield #" + yieldCount++); return res;
}
publiclong ord109_testMethod_dontinline(long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { long res = ord110_testMethod_dontinline(a1, a2, a3, a4, a5, a6, a7, a8, a9, i10);
Continuation.yield(THE_SCOPE); return res;
}
publiclong ord110_testMethod_dontinline(long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9, long a10) { long res = ord111_testMethod_dontinline(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, i11);
log_dontjit("Yield #" + yieldCount); Continuation.yield(THE_SCOPE); log_dontjit("/Yield #" + yieldCount++); return res;
}
publiclong ord111_testMethod_dontinline(long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9, long a10, long a11) { long res = ord112_testMethod_dontinline(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, i12);
log_dontjit("Yield #" + yieldCount);
Continuation.yield(THE_SCOPE);
log_dontjit("/Yield #" + yieldCount++); return res;
}
publiclong ord112_testMethod_dontinline(long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9, long a10, long a11, long a12) { long res = ord113_testMethod_dontinline(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, i13);
log_dontjit("Yield #" + yieldCount);
Continuation.yield(THE_SCOPE);
log_dontjit("/Yield #" + yieldCount++); return res;
}
publiclong ord113_testMethod_dontinline(long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9, long a10, long a11, long a12, long a13) { long res = ord114_testMethod_dontinline(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, i14);
log_dontjit("Yield #" + yieldCount);
Continuation.yield(THE_SCOPE);
log_dontjit("/Yield #" + yieldCount++); return res;
}
publiclong ord114_testMethod_dontinline(long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9, long a10, long a11, long a12, long a13, long a14) { long res = ord115_testMethod_dontinline(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, i15);
log_dontjit("Yield #" + yieldCount);
Continuation.yield(THE_SCOPE);
log_dontjit("/Yield #" + yieldCount++); return res;
}
publiclong ord115_testMethod_dontinline(long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9, long a10, long a11, long a12, long a13, long a14, long a15) { long res = ord116_testMethod_dontinline(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, i16);
log_dontjit("Yield #" + yieldCount);
Continuation.yield(THE_SCOPE);
log_dontjit("/Yield #" + yieldCount++); return res;
}
publiclong ord116_testMethod_dontinline(long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9, long a10, long a11, long a12, long a13, long a14, long a15, long a16) { long res = a2 + a4 + a6 + a8 + a10 + a12 + a14 + a16;
log_dontjit("Yield #" + yieldCount);
Continuation.yield(THE_SCOPE);
log_dontjit("/Yield #" + yieldCount++);
res += a1 + a3 + a5 + a7 + a9 + a11 + a13 + a15; return res;
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.