Skip to content

Commit f86b870

Browse files
committed
Unreleated test that was added during a backport to version 25 and should be in master as well.
1 parent ebbfefe commit f86b870

File tree

1 file changed

+128
-0
lines changed
  • truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot

1 file changed

+128
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.truffle.api.test.polyglot;
42+
43+
import org.graalvm.polyglot.Context;
44+
import org.junit.Test;
45+
46+
import com.oracle.truffle.api.Assumption;
47+
import com.oracle.truffle.api.CallTarget;
48+
import com.oracle.truffle.api.CompilerDirectives;
49+
import com.oracle.truffle.api.frame.VirtualFrame;
50+
import com.oracle.truffle.api.nodes.RootNode;
51+
import com.oracle.truffle.tck.tests.TruffleTestAssumptions;
52+
53+
/**
54+
* Test that {@link CompilerDirectives#transferToInterpreter()} does not trigger deopt cycle
55+
* detection. The test first deopts "deopt cycle detection threshold"-times using
56+
* {@link CompilerDirectives#transferToInterpreterAndInvalidate()}. This does not trigger the
57+
* detection, because it is not enabled. Then it uses
58+
* {@link CompilerDirectives#transferToInterpreter()} to deopt, explicitly invalidates the code and
59+
* deopts repeatedly again. This must not trigger the deopt cycle detection.
60+
*/
61+
public class GR68545Test {
62+
private static final int DEOPT_CYCLE_DETECTION_THRESHOLD = 15;
63+
64+
static class AlwaysDeoptNoInvalidate extends RootNode {
65+
66+
@CompilerDirectives.CompilationFinal private Assumption assumption = Assumption.create("Test assumption");
67+
68+
AlwaysDeoptNoInvalidate() {
69+
super(null);
70+
}
71+
72+
@CompilerDirectives.TruffleBoundary
73+
static void boundaryMethod() {
74+
75+
}
76+
77+
@Override
78+
public Object execute(VirtualFrame frame) {
79+
if (assumption.isValid()) {
80+
int arg = (int) frame.getArguments()[0];
81+
int threshold = 15;
82+
if (arg < threshold) {
83+
CompilerDirectives.transferToInterpreterAndInvalidate();
84+
}
85+
// call boundary method to prevent compiler from moving the following deoptimization
86+
// up
87+
boundaryMethod();
88+
CompilerDirectives.transferToInterpreter();
89+
}
90+
return null;
91+
}
92+
93+
@Override
94+
public String getName() {
95+
return "AlwaysDeoptNoInvalidate";
96+
}
97+
98+
@Override
99+
public String toString() {
100+
return getName();
101+
}
102+
}
103+
104+
@Test
105+
public void testAlwaysDeoptNoInvalidate() {
106+
TruffleTestAssumptions.assumeOptimizingRuntime();
107+
TruffleTestAssumptions.assumeDeoptLoopDetectionAvailable();
108+
try (Context context = Context.newBuilder().allowExperimentalOptions(true) //
109+
.option("engine.CompilationFailureAction", "Throw") //
110+
.option("engine.BackgroundCompilation", "false") //
111+
.option("engine.CompileImmediately", "true") //
112+
.option("compiler.DeoptCycleDetectionThreshold", String.valueOf(DEOPT_CYCLE_DETECTION_THRESHOLD)).build()) {
113+
context.enter();
114+
AlwaysDeoptNoInvalidate alwaysDeoptNoInvalidate = new AlwaysDeoptNoInvalidate();
115+
CallTarget callTarget = alwaysDeoptNoInvalidate.getCallTarget();
116+
for (int i = 0; i < DEOPT_CYCLE_DETECTION_THRESHOLD; i++) {
117+
callTarget.call(i);
118+
}
119+
callTarget.call(DEOPT_CYCLE_DETECTION_THRESHOLD);
120+
alwaysDeoptNoInvalidate.assumption.invalidate("Test reason");
121+
alwaysDeoptNoInvalidate.assumption = Assumption.create();
122+
callTarget.call(DEOPT_CYCLE_DETECTION_THRESHOLD + 1);
123+
for (int i = 0; i < 100; i++) {
124+
callTarget.call(DEOPT_CYCLE_DETECTION_THRESHOLD + 2 + i);
125+
}
126+
}
127+
}
128+
}

0 commit comments

Comments
 (0)