Skip to content

Commit 3b4d71d

Browse files
committed
[GR-38296] [GR-65175] Remove deprecated OSR frame transfer.
PullRequest: graal/21068
2 parents 8097e82 + 70144c0 commit 3b4d71d

File tree

10 files changed

+32
-171
lines changed

10 files changed

+32
-171
lines changed

substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleBaseFeature.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ static <T> T invokeStaticMethod(String className, String methodName, Collection<
300300
static boolean isStaticMethodPresent(String className, String methodName, Collection<Class<?>> parameterTypes) {
301301
try {
302302
Class<?> clazz = Class.forName(className);
303-
Method method = ReflectionUtil.lookupMethod(clazz, methodName, parameterTypes.toArray(new Class<?>[0]));
303+
Method method = ReflectionUtil.lookupMethod(true, clazz, methodName, parameterTypes.toArray(new Class<?>[0]));
304304
return method != null;
305305
} catch (ReflectiveOperationException e) {
306306
throw VMError.shouldNotReachHere(e);

substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleFeature.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -444,12 +444,16 @@ public void beforeAnalysis(BeforeAnalysisAccess access) {
444444
/* Ensure org.graalvm.polyglot.io.IOHelper.IMPL is initialized. */
445445
((BeforeAnalysisAccessImpl) access).ensureInitialized("org.graalvm.polyglot.io.IOHelper");
446446

447-
/* Support for deprecated bytecode osr frame transfer: GR-38296 */
448-
config.registerSubtypeReachabilityHandler((acc, klass) -> {
449-
/* Pass known reachable classes to the initializer: it will decide there what to do. */
450-
TruffleBaseFeature.invokeStaticMethod("com.oracle.truffle.runtime.BytecodeOSRRootNode", "initializeClassUsingDeprecatedFrameTransfer",
451-
Collections.singleton(Class.class), klass);
452-
}, BytecodeOSRNode.class);
447+
/* Support for deprecated bytecode osr frame transfer: GR-65788 */
448+
if (TruffleBaseFeature.isStaticMethodPresent("com.oracle.truffle.runtime.BytecodeOSRRootNode", "initializeClassUsingDeprecatedFrameTransfer", Collections.singleton(Class.class))) {
449+
config.registerSubtypeReachabilityHandler((acc, klass) -> {
450+
/*
451+
* Pass known reachable classes to the initializer: it will decide there what to do.
452+
*/
453+
TruffleBaseFeature.invokeStaticMethod("com.oracle.truffle.runtime.BytecodeOSRRootNode", "initializeClassUsingDeprecatedFrameTransfer",
454+
Collections.singleton(Class.class), klass);
455+
}, BytecodeOSRNode.class);
456+
}
453457
}
454458

455459
static class TruffleAllowInliningPredicate {

truffle/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ This changelog summarizes major changes between Truffle versions relevant to lan
2929
* GR-64594 Bytecode DSL: Builder instances now have a `toString()` implementation that prints current operations as well as the instructions that have been already emitted. This should make it easier to debug problems with builder usage.
3030
* GR-64594 Bytecode DSL: Added `@GenerateBytecode(..., additionalAssertions=true)` to enable additional assertions for Bytecode DSL implementation bugs. This feature can also be enabled with `-A.truffle.dsl.AdditionalAssertions=true` at Java source compile time. These assertions are intentionally disabled by default, as they can lead to slow-downs even when assertions are disabled.
3131
* GR-65428 JDK specific optimizations when building Truffle languages with native-image are now enabled by default, even if the truffle-enterprise.jar is not provided on the class or module-path.
32+
* GR-38296 Removed the deprecated `BytecodeOSRNode.copyIntoOSRFrame` hook that does not declare a `targetMetadata` parameter.
33+
3234

3335
## Version 24.2.0
3436
* GR-60636 Truffle now stops compiling when the code cache fills up on HotSpot. A warning is printed when that happens.

truffle/src/com.oracle.truffle.api/snapshot.sigtest

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,8 +1166,6 @@ meth public static boolean pollOSRBackEdge(com.oracle.truffle.api.nodes.Bytecode
11661166
meth public static boolean pollOSRBackEdge(com.oracle.truffle.api.nodes.BytecodeOSRNode,int)
11671167
meth public static java.lang.Object tryOSR(com.oracle.truffle.api.nodes.BytecodeOSRNode,int,java.lang.Object,java.lang.Runnable,com.oracle.truffle.api.frame.VirtualFrame)
11681168
meth public static java.lang.Object tryOSR(com.oracle.truffle.api.nodes.BytecodeOSRNode,long,java.lang.Object,java.lang.Runnable,com.oracle.truffle.api.frame.VirtualFrame)
1169-
meth public void copyIntoOSRFrame(com.oracle.truffle.api.frame.VirtualFrame,com.oracle.truffle.api.frame.VirtualFrame,int)
1170-
anno 0 java.lang.Deprecated(boolean forRemoval=false, java.lang.String since="22.2")
11711169
meth public void copyIntoOSRFrame(com.oracle.truffle.api.frame.VirtualFrame,com.oracle.truffle.api.frame.VirtualFrame,int,java.lang.Object)
11721170
meth public void copyIntoOSRFrame(com.oracle.truffle.api.frame.VirtualFrame,com.oracle.truffle.api.frame.VirtualFrame,long,java.lang.Object)
11731171
meth public void prepareOSR(int)

truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,13 +1227,6 @@ public final FrameExtensions getFrameExtensionsUnsafe() {
12271227
*/
12281228
public abstract void onOSRNodeReplaced(BytecodeOSRNode osrNode, Node oldNode, Node newNode, CharSequence reason);
12291229

1230-
/**
1231-
* Same as {@link #transferOSRFrame(BytecodeOSRNode, Frame, Frame, long, Object)}, but
1232-
* fetches the target metadata.
1233-
*/
1234-
// Support for deprecated frame transfer: GR-38296
1235-
public abstract void transferOSRFrame(BytecodeOSRNode osrNode, Frame source, Frame target, long bytecodeTarget);
1236-
12371230
/**
12381231
* Transfers state from the {@code source} frame into the {@code target} frame. This method
12391232
* should only be used inside OSR code. The frames must have the same layout as the frame
@@ -1243,6 +1236,8 @@ public final FrameExtensions getFrameExtensionsUnsafe() {
12431236
* @param source the frame to transfer state from
12441237
* @param target the frame to transfer state into
12451238
* @param bytecodeTarget the target location OSR executes from (e.g., bytecode index).
1239+
* @param targetMetadata Additional metadata associated with this {@code target} for the
1240+
* default frame transfer behavior.
12461241
*/
12471242
public abstract void transferOSRFrame(BytecodeOSRNode osrNode, Frame source, Frame target, long bytecodeTarget, Object targetMetadata);
12481243

truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultRuntimeAccessor.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,6 @@ public void onOSRNodeReplaced(BytecodeOSRNode osrNode, Node oldNode, Node newNod
154154
// do nothing
155155
}
156156

157-
@Override
158-
// Support for deprecated frame transfer: GR-38296
159-
public void transferOSRFrame(BytecodeOSRNode osrNode, Frame source, Frame target, long bytecodeTarget) {
160-
throw new UnsupportedOperationException();
161-
}
162-
163157
@Override
164158
public void transferOSRFrame(BytecodeOSRNode osrNode, Frame source, Frame target, long bytecodeTarget, Object targetMetadata) {
165159
throw new UnsupportedOperationException();

truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/BytecodeOSRNode.java

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -171,20 +171,6 @@ default Object executeOSR(VirtualFrame osrFrame, long target, Object interpreter
171171
*/
172172
void setOSRMetadata(Object osrMetadata);
173173

174-
/**
175-
* Note that if this method is implemented, the
176-
* {@link #copyIntoOSRFrame(VirtualFrame, VirtualFrame, int, Object) preferred one} will not be
177-
* used.
178-
*
179-
* @since 21.3
180-
* @deprecated since 22.2
181-
* @see #copyIntoOSRFrame(VirtualFrame, VirtualFrame, int, Object)
182-
*/
183-
@Deprecated(since = "22.2")
184-
default void copyIntoOSRFrame(VirtualFrame osrFrame, VirtualFrame parentFrame, int target) {
185-
NodeAccessor.RUNTIME.transferOSRFrame(this, parentFrame, osrFrame, target);
186-
}
187-
188174
/**
189175
* Copies the contents of the {@code parentFrame} into the {@code osrFrame} used to execute OSR.
190176
* By default, performs a slot-wise copy of the frame.

truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/BytecodeOSRMetadata.java

Lines changed: 14 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
* <p>
6868
* Performance note: We do not require the metadata field to be {@code volatile}. As long as the
6969
* field is initialized under double-checked locking (as is done in
70-
* {@link OptimizedRuntimeSupport#pollBytecodeOSRBackEdge}, all threads will observe the same
70+
* {@link OptimizedRuntimeSupport#pollBytecodeOSRBackEdge}), all threads will observe the same
7171
* metadata instance. The JMM guarantees that the instance's final fields will be safely initialized
7272
* before it is published; the non-final + non-volatile fields (e.g., the back edge counter) may not
7373
* be, but we tolerate this inaccuracy in order to avoid volatile accesses in the hot path.
@@ -139,9 +139,7 @@ private OptimizedCallTarget getCurrentlyCompiling() {
139139

140140
// Lazily initialized state. Most nodes with back-edges will not trigger compilation, so we
141141
// defer initialization of some fields until they're actually used.
142-
static final class LazyState //
143-
// Support for deprecated frame transfer: GR-38296
144-
extends FinalCompilationListMap {
142+
static final class LazyState {
145143

146144
private final Map<Long, OptimizedCallTarget> compilationMap;
147145
@CompilationFinal private FrameDescriptor frameDescriptor;
@@ -153,19 +151,14 @@ static final class LazyState //
153151
this.frameDescriptor = null;
154152
}
155153

156-
private void push(long target, OptimizedCallTarget callTarget, OsrEntryDescription entry) {
154+
private void push(long target, OptimizedCallTarget callTarget) {
157155
compilationMap.put(target, callTarget);
158-
// Support for deprecated frame transfer: GR-38296
159-
put(target, entry);
160156
}
161157

162158
private void doClear() {
163159
compilationMap.clear();
164-
// We might be disabling OSR while doing an OSR call. Keep around the data necessary to
165-
// transfer from and restore the parent frame.
166-
// In particular, we must keep alive:
167-
// - The frame descriptor
168-
// - (GR-38296) The map from target to entry description.
160+
// We might be disabling OSR while doing an OSR call. Do not clear the frame descriptor,
161+
// in case we need it to transfer from and restore the parent frame.
169162
}
170163
}
171164

@@ -195,8 +188,7 @@ private void updateFrameSlots(FrameWithoutBoxing frame, OsrEntryDescription osrE
195188
LazyState state = getLazyState();
196189
((Node) osrNode).atomic(() -> {
197190
if (state.frameDescriptor == null) {
198-
FrameDescriptor frameDescriptor = frame.getFrameDescriptor();
199-
state.frameDescriptor = frameDescriptor;
191+
state.frameDescriptor = frame.getFrameDescriptor();
200192
}
201193
if (osrEntry != null) {
202194
// The concrete frame can have different tags from the descriptor (e.g., when a slot
@@ -259,9 +251,8 @@ Object tryOSR(long target, Object interpreterState, Runnable beforeTransfer, Vir
259251
callTarget = ((Node) osrNode).atomic(() -> {
260252
OptimizedCallTarget lockedTarget = state.compilationMap.get(target);
261253
if (lockedTarget == null) {
262-
OsrEntryDescription entryDescription = new OsrEntryDescription();
263-
lockedTarget = createOSRTarget(target, interpreterState, parentFrame.getFrameDescriptor(), entryDescription);
264-
state.push(target, lockedTarget, entryDescription);
254+
lockedTarget = createOSRTarget(target, interpreterState, parentFrame.getFrameDescriptor());
255+
state.push(target, lockedTarget);
265256
if (stage == FRESH_STAGE) {
266257
// First attempt at compilation gets a free pass
267258
requestOSRCompilation(target, lockedTarget, (FrameWithoutBoxing) parentFrame);
@@ -372,10 +363,9 @@ private void resetCounter() {
372363
* Creates an OSR call target at the given dispatch target and requests compilation. The node's
373364
* AST lock should be held when this is invoked.
374365
*/
375-
private OptimizedCallTarget createOSRTarget(long target, Object interpreterState, FrameDescriptor frameDescriptor, Object frameEntryState) {
366+
private OptimizedCallTarget createOSRTarget(long target, Object interpreterState, FrameDescriptor frameDescriptor) {
376367
TruffleLanguage<?> language = OptimizedRuntimeAccessor.NODES.getLanguage(((Node) osrNode).getRootNode());
377-
return (OptimizedCallTarget) new BytecodeOSRRootNode(language, frameDescriptor, osrNode, target, interpreterState, frameEntryState).getCallTarget();
378-
368+
return (OptimizedCallTarget) new BytecodeOSRRootNode(language, frameDescriptor, osrNode, target, interpreterState, new OsrEntryDescription()).getCallTarget();
379369
}
380370

381371
private void requestOSRCompilation(long target, OptimizedCallTarget callTarget, FrameWithoutBoxing frame) {
@@ -431,7 +421,7 @@ private static OsrEntryDescription getEntryCacheFromCallTarget(OptimizedCallTarg
431421
* Transfer state from {@code source} to {@code target}. Can be used to transfer state into an
432422
* OSR frame.
433423
*/
434-
public void transferFrame(FrameWithoutBoxing source, FrameWithoutBoxing target, long bytecodeTarget, Object targetMetadata) {
424+
public void transferFrame(FrameWithoutBoxing source, FrameWithoutBoxing target, Object targetMetadata) {
435425
LazyState state = getLazyState();
436426
CompilerAsserts.partialEvaluationConstant(state);
437427
// The frames should use the same descriptor.
@@ -445,7 +435,6 @@ public void transferFrame(FrameWithoutBoxing source, FrameWithoutBoxing target,
445435
CompilerDirectives.transferToInterpreterAndInvalidate();
446436
throw new IllegalArgumentException("Wrong usage of targetMetadata during OSR frame transfer.");
447437
}
448-
assert targetMetadata == state.get(bytecodeTarget); // GR-38296
449438

450439
OsrEntryDescription description = (OsrEntryDescription) targetMetadata;
451440
CompilerAsserts.partialEvaluationConstant(description);
@@ -460,9 +449,9 @@ public void transferFrame(FrameWithoutBoxing source, FrameWithoutBoxing target,
460449
/**
461450
* Transfer state from {@code source} to {@code target}. Can be used to transfer state from an
462451
* OSR frame to a parent frame. Overall less efficient than its
463-
* {@link #transferFrame(FrameWithoutBoxing, FrameWithoutBoxing, long, Object) counterpart},
464-
* mainly due to not being able to speculate on the source tags: While entering bytecode OSR is
465-
* done through specific entry points (likely back edges), returning could be done from anywhere
452+
* {@link #transferFrame(FrameWithoutBoxing, FrameWithoutBoxing, Object) counterpart}, mainly
453+
* due to not being able to speculate on the source tags: While entering bytecode OSR is done
454+
* through specific entry points (likely back edges), returning could be done from anywhere
466455
* within a method body (through regular returns, or exception thrown).
467456
*
468457
* While we could theoretically have the same mechanism as on entries (caching encountered
@@ -712,49 +701,4 @@ public void clear() {
712701
static final class OsrEntryDescription {
713702
@CompilationFinal(dimensions = 1) private byte[] indexedFrameTags;
714703
}
715-
716-
// Support for deprecated frame transfer: GR-38296
717-
private abstract static class FinalCompilationListMap {
718-
private static final class Cell {
719-
final Cell next;
720-
final long target;
721-
final OsrEntryDescription entry;
722-
723-
Cell(long target, OsrEntryDescription entry, Cell next) {
724-
this.next = next;
725-
this.target = target;
726-
this.entry = entry;
727-
}
728-
}
729-
730-
@CompilationFinal //
731-
volatile Cell head = null;
732-
733-
@ExplodeLoop
734-
public final OsrEntryDescription get(long target) {
735-
Cell cur = head;
736-
while (cur != null) {
737-
if (cur.target == target) {
738-
return cur.entry;
739-
}
740-
cur = cur.next;
741-
}
742-
return null;
743-
}
744-
745-
public final void put(long target, OsrEntryDescription value) {
746-
CompilerDirectives.transferToInterpreterAndInvalidate();
747-
synchronized (this) {
748-
assert get(target) == null;
749-
head = new Cell(target, value, head);
750-
}
751-
}
752-
753-
public final void clear() {
754-
CompilerDirectives.transferToInterpreterAndInvalidate();
755-
synchronized (this) {
756-
head = null;
757-
}
758-
}
759-
}
760704
}

truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/BytecodeOSRRootNode.java

Lines changed: 2 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,6 @@
4040
*/
4141
package com.oracle.truffle.runtime;
4242

43-
import java.lang.reflect.Method;
44-
import java.util.Map;
45-
import java.util.concurrent.ConcurrentHashMap;
46-
47-
import org.graalvm.nativeimage.ImageInfo;
48-
4943
import com.oracle.truffle.api.CompilerDirectives;
5044
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
5145
import com.oracle.truffle.api.Truffle;
@@ -68,9 +62,6 @@ final class BytecodeOSRRootNode extends BaseOSRRootNode {
6862
this.interpreterState = interpreterState;
6963
this.seenMaterializedFrame = materializeCalled(frameDescriptor);
7064
this.entryTagsCache = entryTagsCache;
71-
72-
// Support for deprecated frame transfer: GR-38296
73-
this.usesDeprecatedFrameTransfer = checkUsesDeprecatedFrameTransfer(bytecodeOSRNode.getClass());
7465
}
7566

7667
private static boolean materializeCalled(FrameDescriptor frameDescriptor) {
@@ -101,15 +92,7 @@ public Object executeOSR(VirtualFrame frame) {
10192
// required to prevent the materialized frame from getting out of sync during OSR.
10293
return osrNode.executeOSR(parentFrame, target, interpreterState);
10394
} else {
104-
if (usesDeprecatedFrameTransfer) { // Support for deprecated frame transfer: GR-38296
105-
int intTarget = (int) target;
106-
if (intTarget != target) {
107-
throw CompilerDirectives.shouldNotReachHere("long target cannot be used with deprecated frame transfer");
108-
}
109-
osrNode.copyIntoOSRFrame(frame, parentFrame, intTarget);
110-
} else {
111-
osrNode.copyIntoOSRFrame(frame, parentFrame, target, entryTagsCache);
112-
}
95+
osrNode.copyIntoOSRFrame(frame, parentFrame, target, entryTagsCache);
11396
try {
11497
return osrNode.executeOSR(frame, target, interpreterState);
11598
} finally {
@@ -128,47 +111,10 @@ public String toString() {
128111
return ((Node) loopNode).getRootNode().toString() + "<OSR@" + target + ">";
129112
}
130113

131-
// GR-38296
132-
/* Deprecated frame transfer handling below */
133-
134-
private static final Map<Class<?>, Boolean> usesDeprecatedTransferClasses = new ConcurrentHashMap<>();
135-
136-
private final boolean usesDeprecatedFrameTransfer;
137-
138-
/**
139-
* Detects usage of deprecated frame transfer, and directs the frame transfer path accordingly
140-
* later. When removing the support for this deprecation, constructs used and paths related are
141-
* marked with the comment "Support for deprecated frame transfer" and a reference to GR-38296.
142-
*/
143-
private static boolean usesDeprecatedFrameTransfer(Class<?> osrNodeClass) {
144-
try {
145-
Method m = osrNodeClass.getMethod("copyIntoOSRFrame", VirtualFrame.class, VirtualFrame.class, int.class);
146-
return m.getDeclaringClass() != BytecodeOSRNode.class;
147-
} catch (NoSuchMethodException e) {
148-
return false;
149-
}
150-
}
151-
152-
private static boolean checkUsesDeprecatedFrameTransfer(Class<?> osrNodeClass) {
153-
if (ImageInfo.inImageRuntimeCode()) {
154-
// this must have been pre-computed
155-
return usesDeprecatedTransferClasses.get(osrNodeClass);
156-
} else {
157-
return usesDeprecatedTransferClasses.computeIfAbsent(osrNodeClass, BytecodeOSRRootNode::usesDeprecatedFrameTransfer);
158-
}
159-
}
160-
161114
// Called by truffle feature to initialize the map at build time.
162115
@SuppressWarnings("unused")
163116
private static boolean initializeClassUsingDeprecatedFrameTransfer(Class<?> subType) {
164-
if (subType.isInterface()) {
165-
return false;
166-
}
167-
if (usesDeprecatedTransferClasses.containsKey(subType)) {
168-
return false;
169-
}
170-
// Eagerly initialize result.
171-
usesDeprecatedTransferClasses.put(subType, usesDeprecatedFrameTransfer(subType));
117+
// empty method implementation for backward-compatibility with SVM: GR-65788
172118
return true;
173119
}
174120

0 commit comments

Comments
 (0)