Skip to content

Commit 1882eef

Browse files
committed
[GR-38039] Use stricter JVMTI thread state definitions for espresso thread states. Enforce thread transitions where needed.
1 parent 04ea917 commit 1882eef

26 files changed

+686
-208
lines changed

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import static com.oracle.truffle.espresso.classfile.bytecode.Bytecodes.PUTSTATIC;
4949
import static com.oracle.truffle.espresso.classfile.bytecode.Bytecodes.RET;
5050
import static com.oracle.truffle.espresso.classfile.bytecode.Bytecodes.RETURN;
51+
import static com.oracle.truffle.espresso.threads.ThreadState.IN_ESPRESSO;
5152

5253
import java.io.PrintStream;
5354
import java.lang.invoke.VarHandle;
@@ -126,7 +127,6 @@
126127
import com.oracle.truffle.espresso.nodes.methodhandle.MethodHandleIntrinsicNode;
127128
import com.oracle.truffle.espresso.runtime.EspressoContext;
128129
import com.oracle.truffle.espresso.runtime.EspressoException;
129-
import com.oracle.truffle.espresso.runtime.EspressoThreadLocalState;
130130
import com.oracle.truffle.espresso.runtime.MethodHandleIntrinsics;
131131
import com.oracle.truffle.espresso.runtime.staticobject.StaticObject;
132132
import com.oracle.truffle.espresso.shared.meta.ErrorType;
@@ -136,6 +136,7 @@
136136
import com.oracle.truffle.espresso.shared.resolver.ResolvedCall;
137137
import com.oracle.truffle.espresso.shared.vtable.PartialMethod;
138138
import com.oracle.truffle.espresso.substitutions.JavaType;
139+
import com.oracle.truffle.espresso.threads.Transition;
139140
import com.oracle.truffle.espresso.vm.InterpreterToVM;
140141
import com.oracle.truffle.espresso.vm.VM.EspressoStackElement;
141142

@@ -485,9 +486,7 @@ public boolean isJavaLangObjectInit() {
485486
*/
486487
@TruffleBoundary
487488
public Object invokeWithConversions(Object self, Object... args) {
488-
EspressoThreadLocalState tls = getLanguage().getThreadLocalState();
489-
// Impossible to call from guest code, so what is above is illegal for continuations.
490-
tls.blockContinuationSuspension();
489+
Transition transition = Transition.transition(IN_ESPRESSO, this);
491490
try {
492491
getLanguage().clearPendingException();
493492
assert args.length == SignatureSymbols.parameterCount(getParsedSignature());
@@ -509,7 +508,7 @@ public Object invokeWithConversions(Object self, Object... args) {
509508
}
510509
return getMeta().toHostBoxed(getCallTarget().call(filteredArgs));
511510
} finally {
512-
tls.unblockContinuationSuspension();
511+
transition.restore(this);
513512
}
514513
}
515514

@@ -521,17 +520,15 @@ public Object invokeWithConversions(Object self, Object... args) {
521520
*/
522521
@TruffleBoundary
523522
public Object invokeDirect(Object... args) {
524-
EspressoThreadLocalState tls = getLanguage().getThreadLocalState();
525-
// Impossible to call from guest code, so what is above is illegal for continuations.
526-
tls.blockContinuationSuspension();
523+
Transition transition = Transition.transition(IN_ESPRESSO, this);
527524
try {
528525
getLanguage().clearPendingException();
529526
assert !isStatic();
530527
assert args.length == SignatureSymbols.parameterCount(getParsedSignature()) + 1;
531528
assert getDeclaringKlass().isAssignableFrom(((StaticObject) args[0]).getKlass());
532529
return getCallTarget().call(args);
533530
} finally {
534-
tls.unblockContinuationSuspension();
531+
transition.restore(this);
535532
}
536533
}
537534

@@ -550,17 +547,15 @@ public static Object call(ResolvedCall<Klass, Method, Field> resolved, Object...
550547

551548
@TruffleBoundary
552549
public Object invokeDirectStatic(Object... args) {
553-
EspressoThreadLocalState tls = getLanguage().getThreadLocalState();
554-
// Impossible to call from guest code, so what is above is illegal for continuations.
555-
tls.blockContinuationSuspension();
550+
Transition transition = Transition.transition(IN_ESPRESSO, this);
556551
try {
557552
getLanguage().clearPendingException();
558553
assert isStatic();
559554
assert args.length == SignatureSymbols.parameterCount(getParsedSignature());
560555
getDeclaringKlass().safeInitialize();
561556
return getCallTarget().call(args);
562557
} finally {
563-
tls.unblockContinuationSuspension();
558+
transition.restore(this);
564559
}
565560
}
566561

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/ObjectKlass.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -400,8 +400,6 @@ private void actualInit() {
400400
}
401401
}
402402

403-
var tls = getContext().getLanguage().getThreadLocalState();
404-
tls.blockContinuationSuspension();
405403
try {
406404
if (!isInterface()) {
407405
/*
@@ -425,7 +423,7 @@ private void actualInit() {
425423
// Next, execute the class or interface initialization method of C.
426424
Method clinit = getClassInitializer();
427425
if (clinit != null) {
428-
clinit.getCallTarget().call();
426+
clinit.invokeDirectStatic();
429427
}
430428
} catch (EspressoException e) {
431429
setErroneousInitialization();
@@ -438,8 +436,6 @@ private void actualInit() {
438436
e.printStackTrace();
439437
setErroneousInitialization();
440438
throw e;
441-
} finally {
442-
tls.unblockContinuationSuspension();
443439
}
444440
checkErroneousInitialization();
445441
initState = INITIALIZED;
@@ -1536,7 +1532,7 @@ private void markForReResolution(List<ParserField> addedFields, List<ObjectKlass
15361532

15371533
// used by some plugins during klass redefinition
15381534
public void reRunClinit() {
1539-
getClassInitializer().getCallTarget().call();
1535+
getClassInitializer().invokeDirectStatic();
15401536
}
15411537

15421538
private static void checkCopyMethods(KlassVersion klassVersion, Method method, Method.MethodVersion[][] table, Method.SharedRedefinitionContent content) {

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@
371371
import com.oracle.truffle.espresso.shared.resolver.FieldAccessType;
372372
import com.oracle.truffle.espresso.shared.resolver.ResolvedCall;
373373
import com.oracle.truffle.espresso.substitutions.standard.Target_java_lang_invoke_MethodHandleNatives.SiteTypes;
374+
import com.oracle.truffle.espresso.threads.ThreadState;
374375
import com.oracle.truffle.espresso.vm.InterpreterToVM;
375376
import com.oracle.truffle.espresso.vm.continuation.HostFrameRecord;
376377
import com.oracle.truffle.espresso.vm.continuation.UnwindContinuationException;
@@ -723,6 +724,7 @@ public Object execute(VirtualFrame frame) {
723724
private Object executeBodyFromBCI(VirtualFrame frame, int startBCI, int startTop, int startStatementIndex,
724725
boolean isOSR, boolean resumeContinuation) {
725726
CompilerAsserts.partialEvaluationConstant(startBCI);
727+
assert ThreadState.currentThreadInEspresso(getContext());
726728
final InstrumentationSupport instrument = this.instrumentation;
727729
int statementIndex = startStatementIndex;
728730
boolean skipLivenessActions = instrument != null;

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/IntrinsicSubstitutorNode.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.oracle.truffle.espresso.meta.EspressoError;
3636
import com.oracle.truffle.espresso.runtime.EspressoThreadLocalState;
3737
import com.oracle.truffle.espresso.substitutions.JavaSubstitution;
38+
import com.oracle.truffle.espresso.threads.ThreadState;
3839
import com.oracle.truffle.espresso.vm.VM;
3940

4041
@ExportLibrary(NodeLibrary.class)
@@ -70,6 +71,8 @@ Object execute(VirtualFrame frame) {
7071
EspressoThreadLocalState tls = getContext().getLanguage().getThreadLocalState();
7172
tls.blockContinuationSuspension();
7273
try {
74+
// We consider substitutions non-native, as they are in Espresso's control.
75+
assert ThreadState.currentThreadInEspresso(getContext());
7376
return substitution.invoke(frame.getArguments());
7477
} finally {
7578
tls.unblockContinuationSuspension();

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/NativeMethodNode.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
*/
2323
package com.oracle.truffle.espresso.nodes;
2424

25+
import static com.oracle.truffle.espresso.threads.ThreadState.IN_NATIVE;
26+
2527
import com.oracle.truffle.api.CompilerDirectives;
2628
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
2729
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -50,6 +52,7 @@
5052
import com.oracle.truffle.espresso.meta.EspressoError;
5153
import com.oracle.truffle.espresso.runtime.EspressoException;
5254
import com.oracle.truffle.espresso.runtime.staticobject.StaticObject;
55+
import com.oracle.truffle.espresso.threads.Transition;
5356
import com.oracle.truffle.espresso.vm.VM;
5457

5558
/**
@@ -106,11 +109,10 @@ private Object[] preprocessArgs(JNIHandles handles, Object[] args) {
106109

107110
@Override
108111
public Object execute(VirtualFrame frame) {
112+
NATIVE_METHOD_CALLS.inc();
109113
JNIHandles handles = getContext().getHandles();
110114
int nativeFrame = handles.pushFrame();
111-
NATIVE_METHOD_CALLS.inc();
112-
var tls = getLanguage().getThreadLocalState();
113-
tls.blockContinuationSuspension(); // Can't unwind through native frames.
115+
Transition transition = Transition.transition(IN_NATIVE, this);
114116
try {
115117
Object[] nativeArgs = preprocessArgs(handles, frame.getArguments());
116118
Object result = executeNative.execute(boundNative, nativeArgs);
@@ -119,7 +121,7 @@ public Object execute(VirtualFrame frame) {
119121
CompilerDirectives.transferToInterpreterAndInvalidate();
120122
throw EspressoError.shouldNotReachHere(e);
121123
} finally {
122-
tls.unblockContinuationSuspension();
124+
transition.restore(this);
123125
handles.popFramesIncluding(nativeFrame);
124126
}
125127
}

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/commands/AddPathToBindingsCache.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@
2828
import com.oracle.truffle.espresso.impl.Method;
2929
import com.oracle.truffle.espresso.impl.ObjectKlass;
3030
import com.oracle.truffle.espresso.meta.EspressoError;
31+
import com.oracle.truffle.espresso.nodes.EspressoNode;
3132
import com.oracle.truffle.espresso.nodes.interop.LookupDeclaredMethod;
3233
import com.oracle.truffle.espresso.nodes.interop.LookupDeclaredMethodNodeGen;
3334
import com.oracle.truffle.espresso.runtime.EspressoContext;
3435
import com.oracle.truffle.espresso.runtime.staticobject.StaticObject;
36+
import com.oracle.truffle.espresso.threads.ThreadState;
37+
import com.oracle.truffle.espresso.threads.Transition;
3538

3639
public final class AddPathToBindingsCache {
3740
static final String NEW_FILE = "<init>/(Ljava/lang/String;)V";
@@ -61,13 +64,18 @@ public AddPathToBindingsCache(EspressoContext context) {
6164
addUrl = DirectCallNode.create(doLookup(loader.getKlass(), ADD_URL, lookup).getCallTargetForceInit());
6265
}
6366

64-
public void execute(StaticObject path) {
65-
StaticObject file = fileKlass.allocateInstance();
66-
newFile.call(file, path);
67+
public void execute(StaticObject path, EspressoNode location) {
68+
Transition transition = Transition.transition(ThreadState.IN_ESPRESSO, location);
69+
try {
70+
StaticObject file = fileKlass.allocateInstance();
71+
newFile.call(file, path);
6772

68-
Object uri = toUri.call(file);
69-
Object url = toUrl.call(uri);
70-
addUrl.call(loader, url);
73+
Object uri = toUri.call(file);
74+
Object url = toUrl.call(uri);
75+
addUrl.call(loader, url);
76+
} finally {
77+
transition.restore(location);
78+
}
7179
}
7280

7381
private static Method doLookup(Klass klass, String key, LookupDeclaredMethod lookup) {

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/commands/AddPathToBindingsNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ protected void addPath(Object[] args,
5050
@Bind("getContext()") EspressoContext context,
5151
@CachedLibrary(limit = "1") InteropLibrary lib) throws UnsupportedTypeException, ArityException {
5252
StaticObject guestPath = getGuestPath(args, context, lib);
53-
context.getLazyCaches().getAddPathToBindingsCache().execute(guestPath);
53+
context.getLazyCaches().getAddPathToBindingsCache().execute(guestPath, this);
5454
}
5555

5656
@ExportLibrary(InteropLibrary.class)

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/commands/ReferenceProcessCache.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
import com.oracle.truffle.espresso.runtime.EspressoContext;
4040
import com.oracle.truffle.espresso.runtime.EspressoException;
4141
import com.oracle.truffle.espresso.runtime.staticobject.StaticObject;
42+
import com.oracle.truffle.espresso.threads.ThreadState;
43+
import com.oracle.truffle.espresso.threads.Transition;
4244

4345
public final class ReferenceProcessCache extends EspressoNode {
4446
/*
@@ -84,9 +86,14 @@ public void execute() {
8486
if (context.multiThreadingEnabled()) {
8587
throw throwIllegalStateException("Manual reference processing was requested, but the context is not in single-threaded mode.");
8688
}
87-
context.triggerDrain();
88-
processPendingReferences();
89-
processFinalizers();
89+
Transition transition = Transition.transition(ThreadState.IN_ESPRESSO, this);
90+
try {
91+
context.triggerDrain();
92+
processPendingReferences();
93+
processFinalizers();
94+
} finally {
95+
transition.restore(this);
96+
}
9097
}
9198

9299
private void processPendingReferences() {

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/interop/InvokeEspressoNode.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
*/
2323
package com.oracle.truffle.espresso.nodes.interop;
2424

25+
import static com.oracle.truffle.espresso.threads.ThreadState.IN_ESPRESSO;
26+
2527
import com.oracle.truffle.api.CallTarget;
2628
import com.oracle.truffle.api.dsl.Cached;
2729
import com.oracle.truffle.api.dsl.GenerateUncached;
@@ -41,9 +43,9 @@
4143
import com.oracle.truffle.espresso.nodes.EspressoNode;
4244
import com.oracle.truffle.espresso.nodes.bytecodes.InitCheck;
4345
import com.oracle.truffle.espresso.runtime.EspressoException;
44-
import com.oracle.truffle.espresso.runtime.EspressoThreadLocalState;
4546
import com.oracle.truffle.espresso.runtime.InteropUtils;
4647
import com.oracle.truffle.espresso.runtime.staticobject.StaticObject;
48+
import com.oracle.truffle.espresso.threads.Transition;
4749

4850
@GenerateUncached
4951
public abstract class InvokeEspressoNode extends EspressoNode {
@@ -59,8 +61,7 @@ public final Object execute(Method method, Object receiver, Object[] arguments,
5961
}
6062
EspressoLanguage language = getLanguage();
6163
Meta meta = getMeta();
62-
EspressoThreadLocalState tls = language.getThreadLocalState();
63-
tls.blockContinuationSuspension();
64+
Transition transition = Transition.transition(IN_ESPRESSO, this);
6465
try {
6566
Object result = executeMethod(resolutionSeed, receiver, arguments, argsConverted);
6667
/*
@@ -74,7 +75,7 @@ public final Object execute(Method method, Object receiver, Object[] arguments,
7475
*/
7576
throw InteropUtils.unwrapExceptionBoundary(language, e, meta);
7677
} finally {
77-
tls.unblockContinuationSuspension();
78+
transition.restore(this);
7879
}
7980
}
8081

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/interop/LookupAndInvokeKnownMethodNode.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
*/
2323
package com.oracle.truffle.espresso.nodes.interop;
2424

25+
import static com.oracle.truffle.espresso.threads.ThreadState.IN_ESPRESSO;
26+
2527
import com.oracle.truffle.api.CompilerDirectives;
2628
import com.oracle.truffle.api.dsl.Cached;
2729
import com.oracle.truffle.api.dsl.GenerateUncached;
@@ -35,6 +37,7 @@
3537
import com.oracle.truffle.espresso.nodes.EspressoNode;
3638
import com.oracle.truffle.espresso.runtime.dispatch.staticobject.EspressoInterop;
3739
import com.oracle.truffle.espresso.runtime.staticobject.StaticObject;
40+
import com.oracle.truffle.espresso.threads.Transition;
3841

3942
/**
4043
* This node is a shortcut for implementing behaviors that require doing a virtual/interface lookup
@@ -98,7 +101,12 @@ Object doInterfaceCachedNoArg(StaticObject receiver, Method resolutionSeed, Obje
98101
@Cached("interfaceLookup(receiver, resolutionSeed)") Method m,
99102
@Cached("create(m.getCallTarget())") DirectCallNode callNode) {
100103
assert 0 == arguments.length;
101-
return callNode.call(receiver);
104+
Transition transition = Transition.transition(IN_ESPRESSO, this);
105+
try {
106+
return callNode.call(receiver);
107+
} finally {
108+
transition.restore(this);
109+
}
102110
}
103111

104112
@Specialization(guards = {"resolutionSeed == cachedSeed", "cachedSeed.getParameterCount() == 0", "!cachedSeed.getDeclaringKlass().isInterface()",
@@ -109,7 +117,12 @@ Object doVirtualCachedNoArg(StaticObject receiver, Method resolutionSeed, Object
109117
@Cached("virtualLookup(receiver, resolutionSeed)") Method m,
110118
@Cached("create(m.getCallTarget())") DirectCallNode callNode) {
111119
assert 0 == arguments.length;
112-
return callNode.call(receiver);
120+
Transition transition = Transition.transition(IN_ESPRESSO, this);
121+
try {
122+
return callNode.call(receiver);
123+
} finally {
124+
transition.restore(this);
125+
}
113126
}
114127

115128
@Specialization(guards = {"resolutionSeed == cachedSeed", "cachedSeed.getDeclaringKlass().isInterface()", "receiver.getKlass() == cachedKlass"}, limit = "LIMIT")

0 commit comments

Comments
 (0)