Skip to content

Commit 2cf0de1

Browse files
committed
[GR-43903] Implement warning if assumptions are used without bound cached guard; Fix Truffle DSL guards that do not bind dynamic values are no longer just asserted on the fast-path.
PullRequest: graal/13744
2 parents 886d817 + dd1f91d commit 2cf0de1

File tree

72 files changed

+1256
-147
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1256
-147
lines changed

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

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import com.oracle.truffle.api.dsl.Cached.Exclusive;
4343
import com.oracle.truffle.api.dsl.Cached.Shared;
4444
import com.oracle.truffle.api.dsl.Fallback;
45+
import com.oracle.truffle.api.dsl.Idempotent;
4546
import com.oracle.truffle.api.dsl.Specialization;
4647
import com.oracle.truffle.api.exception.AbstractTruffleException;
4748
import com.oracle.truffle.api.interop.ArityException;
@@ -706,6 +707,7 @@ public final boolean isArray() {
706707
}
707708

708709
@Override
710+
@Idempotent
709711
public final boolean isInterface() {
710712
// conflict between ModifiersProvider and KlassRef interfaces,
711713
// so chose the default implementation in ModifiersProvider.

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

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import com.oracle.truffle.api.CompilerDirectives;
5656
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
5757
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
58+
import com.oracle.truffle.api.dsl.Idempotent;
5859
import com.oracle.truffle.api.interop.TruffleObject;
5960
import com.oracle.truffle.api.source.Source;
6061
import com.oracle.truffle.api.source.SourceSection;
@@ -551,6 +552,7 @@ public Klass resolveReturnKlass() {
551552
getDeclaringKlass().protectionDomain());
552553
}
553554

555+
@Idempotent
554556
public int getParameterCount() {
555557
return Signatures.parameterCount(getParsedSignature());
556558
}
@@ -1161,6 +1163,7 @@ public byte[] getCode() {
11611163
return code;
11621164
}
11631165

1166+
@Idempotent
11641167
public Method getMethod() {
11651168
return Method.this;
11661169
}

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/meta/ModifiersProvider.java

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828

2929
import java.lang.reflect.Modifier;
3030

31+
import com.oracle.truffle.api.dsl.Idempotent;
32+
3133
/**
3234
* A Java element (i.e., a class, interface, field or method) that is described by a set of Java
3335
* language {@linkplain #getModifiers() modifiers}.
@@ -138,6 +140,7 @@ default boolean isNative() {
138140
/**
139141
* @see Modifier#isAbstract(int)
140142
*/
143+
@Idempotent
141144
default boolean isAbstract() {
142145
return Modifier.isAbstract(getModifiers());
143146
}

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

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323
package com.oracle.truffle.espresso.nodes;
2424

25+
import com.oracle.truffle.api.dsl.Idempotent;
2526
import com.oracle.truffle.api.nodes.Node;
2627
import com.oracle.truffle.api.nodes.NodeInfo;
2728
import com.oracle.truffle.espresso.EspressoLanguage;
@@ -53,21 +54,25 @@ public final EspressoLanguage getLanguage() {
5354
}
5455

5556
@Override
57+
@Idempotent
5658
public final Names getNames() {
5759
return getLanguage().getNames();
5860
}
5961

6062
@Override
63+
@Idempotent
6164
public final Types getTypes() {
6265
return getLanguage().getTypes();
6366
}
6467

6568
@Override
69+
@Idempotent
6670
public final Signatures getSignatures() {
6771
return getLanguage().getSignatures();
6872
}
6973

7074
@Override
75+
@Idempotent
7176
public final Meta getMeta() {
7277
return getContext().getMeta();
7378
}

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/bytecodes/InstanceOf.java

+2-12
Original file line numberDiff line numberDiff line change
@@ -251,17 +251,12 @@ protected AssumptionGuardedValue<ObjectKlass> readSingleImplementor() {
251251
return getContext().getClassHierarchyOracle().readSingleImplementor(superType);
252252
}
253253

254-
@Specialization(guards = "checkAssumption(noImplementors, maybeSubtype)", limit = "1")
254+
@Specialization(guards = "noImplementors.isValid()")
255255
public boolean doNoImplementors(@SuppressWarnings("unused") Klass maybeSubtype,
256256
@SuppressWarnings("unused") @Cached("getNoImplementorsAssumption().getAssumption()") Assumption noImplementors) {
257257
return false;
258258
}
259259

260-
protected static boolean checkAssumption(Assumption noImplementors, @SuppressWarnings("unused") Klass maybeSubtype) {
261-
// GR-43903: prevent the dsl from removing the guard in the fast-path
262-
return noImplementors.isValid();
263-
}
264-
265260
/**
266261
* If {@code superType} has a single implementor (itself if {@code superType} is a concrete
267262
* class or a single concrete child, if {@code superType} is an abstract class),
@@ -305,17 +300,12 @@ protected AssumptionGuardedValue<ObjectKlass> readSingleImplementor() {
305300
return getContext().getClassHierarchyOracle().readSingleImplementor(superType);
306301
}
307302

308-
@Specialization(guards = "checkAssumption(noImplementors, maybeSubtype)", limit = "1")
303+
@Specialization(guards = "noImplementors.isValid()")
309304
public boolean doNoImplementors(@SuppressWarnings("unused") Klass maybeSubtype,
310305
@SuppressWarnings("unused") @Cached("getNoImplementorsAssumption().getAssumption()") Assumption noImplementors) {
311306
return false;
312307
}
313308

314-
protected static boolean checkAssumption(Assumption noImplementors, @SuppressWarnings("unused") Klass maybeSubtype) {
315-
// GR-43903: prevent the dsl from removing the guard in the fast-path
316-
return noImplementors.isValid();
317-
}
318-
319309
@Specialization(assumptions = "maybeSingleImplementor.hasValue()", guards = "implementor != null", replaces = "doNoImplementors")
320310
public boolean doSingleImplementor(ObjectKlass maybeSubtype,
321311
@SuppressWarnings("unused") @Cached("readSingleImplementor()") AssumptionGuardedValue<ObjectKlass> maybeSingleImplementor,

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/helper/AbstractGetFieldNode.java

+9
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import com.oracle.truffle.api.dsl.Bind;
2626
import com.oracle.truffle.api.dsl.Cached;
27+
import com.oracle.truffle.api.dsl.Idempotent;
2728
import com.oracle.truffle.api.dsl.Specialization;
2829
import com.oracle.truffle.api.frame.VirtualFrame;
2930
import com.oracle.truffle.api.interop.InteropLibrary;
@@ -144,6 +145,7 @@ int doForeign(StaticObject receiver,
144145
}
145146
}
146147

148+
@Idempotent
147149
boolean isValueField(Meta meta) {
148150
return getField() == meta.java_lang_Integer_value;
149151
}
@@ -198,6 +200,7 @@ boolean doForeign(StaticObject receiver,
198200
}
199201
}
200202

203+
@Idempotent
201204
boolean isValueField(Meta meta) {
202205
return getField() == meta.java_lang_Boolean_value;
203206
}
@@ -257,6 +260,7 @@ char doForeign(StaticObject receiver,
257260
}
258261
}
259262

263+
@Idempotent
260264
boolean isValueField(Meta meta) {
261265
return getField() == meta.java_lang_Character_value;
262266
}
@@ -311,6 +315,7 @@ short doForeign(StaticObject receiver,
311315
}
312316
}
313317

318+
@Idempotent
314319
boolean isValueField(Meta meta) {
315320
return getField() == meta.java_lang_Short_value;
316321
}
@@ -365,6 +370,7 @@ byte doForeign(StaticObject receiver,
365370
}
366371
}
367372

373+
@Idempotent
368374
boolean isValueField(Meta meta) {
369375
return getField() == meta.java_lang_Byte_value;
370376
}
@@ -419,6 +425,7 @@ long doForeign(StaticObject receiver,
419425
}
420426
}
421427

428+
@Idempotent
422429
boolean isValueField(Meta meta) {
423430
return getField() == meta.java_lang_Long_value;
424431
}
@@ -473,6 +480,7 @@ float doForeign(StaticObject receiver,
473480
}
474481
}
475482

483+
@Idempotent
476484
boolean isValueField(Meta meta) {
477485
return getField() == meta.java_lang_Float_value;
478486
}
@@ -527,6 +535,7 @@ public int getField(VirtualFrame frame, BytecodeNode root, StaticObject receiver
527535
}
528536
}
529537

538+
@Idempotent
530539
boolean isValueField(Meta meta) {
531540
return getField() == meta.java_lang_Double_value;
532541
}

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/methodhandle/MethodHandleIntrinsicNode.java

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
package com.oracle.truffle.espresso.nodes.methodhandle;
2525

26+
import com.oracle.truffle.api.dsl.Idempotent;
2627
import com.oracle.truffle.espresso.impl.Method;
2728
import com.oracle.truffle.espresso.meta.JavaKind;
2829
import com.oracle.truffle.espresso.nodes.EspressoNode;
@@ -48,6 +49,7 @@ public Method getMethod() {
4849
return method;
4950
}
5051

52+
@Idempotent
5153
public boolean inliningEnabled() {
5254
return getContext().getEspressoEnv().InlineMethodHandle;
5355
}

sulong/projects/com.oracle.truffle.llvm.nativemode/src/com/oracle/truffle/llvm/nativemode/runtime/WellKnownNFIFunctionNode.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2020, 2023, Oracle and/or its affiliates.
33
*
44
* All rights reserved.
55
*
@@ -58,7 +58,7 @@ Object getFunction() {
5858
return ctxExt.getCachedWellKnownFunction(function).getBoundSignature();
5959
}
6060

61-
@Specialization(assumptions = "singleContextAssumption()")
61+
@Specialization(guards = "isSingleContext($node)")
6262
@GenerateAOT.Exclude
6363
Object doCached(Object[] args,
6464
@Cached("getFunction()") Object cachedFunction,

sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/LLVMFunction.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2019, 2023, Oracle and/or its affiliates.
33
*
44
* All rights reserved.
55
*
@@ -32,6 +32,7 @@
3232
import com.oracle.truffle.api.Assumption;
3333
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
3434
import com.oracle.truffle.api.Truffle;
35+
import com.oracle.truffle.api.dsl.Idempotent;
3536
import com.oracle.truffle.llvm.runtime.IDGenerater.BitcodeID;
3637
import com.oracle.truffle.llvm.runtime.LLVMFunctionCode.Function;
3738
import com.oracle.truffle.llvm.runtime.debug.scope.LLVMSourceLocation;
@@ -122,6 +123,7 @@ public Assumption getFixedCodeAssumption() {
122123
return fixedCodeAssumption;
123124
}
124125

126+
@Idempotent
125127
public LLVMFunctionCode getFixedCode() {
126128
return fixedCode;
127129
}

sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/LLVMFunctionCode.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2019, 2023, Oracle and/or its affiliates.
33
*
44
* All rights reserved.
55
*
@@ -39,6 +39,7 @@
3939
import com.oracle.truffle.api.Truffle;
4040
import com.oracle.truffle.api.dsl.Fallback;
4141
import com.oracle.truffle.api.dsl.GenerateUncached;
42+
import com.oracle.truffle.api.dsl.Idempotent;
4243
import com.oracle.truffle.api.dsl.Specialization;
4344
import com.oracle.truffle.api.frame.VirtualFrame;
4445
import com.oracle.truffle.api.interop.InteropLibrary;
@@ -366,11 +367,13 @@ public void resolveIfLazyLLVMIRFunction() {
366367
}
367368
}
368369

370+
@Idempotent
369371
public boolean isLLVMIRFunction() {
370372
final LLVMFunctionCode.Function currentFunction = getFunction();
371373
return currentFunction instanceof LLVMFunctionCode.LLVMIRFunction || currentFunction instanceof LLVMFunctionCode.LazyLLVMIRFunction;
372374
}
373375

376+
@Idempotent
374377
public boolean isIntrinsicFunctionSlowPath() {
375378
CompilerAsserts.neverPartOfCompilation();
376379
return isIntrinsicFunction(ResolveFunctionNodeGen.getUncached());
@@ -380,6 +383,7 @@ public boolean isIntrinsicFunction(LLVMFunctionCode.ResolveFunctionNode resolve)
380383
return resolve.execute(getFunction(), this) instanceof LLVMFunctionCode.IntrinsicFunction;
381384
}
382385

386+
@Idempotent
383387
public boolean isNativeFunctionSlowPath() {
384388
CompilerAsserts.neverPartOfCompilation();
385389
return isNativeFunction(ResolveFunctionNodeGen.getUncached());

sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/LLVMFunctionDescriptor.java

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2016, 2023, Oracle and/or its affiliates.
33
*
44
* All rights reserved.
55
*
@@ -29,12 +29,12 @@
2929
*/
3030
package com.oracle.truffle.llvm.runtime;
3131

32-
import com.oracle.truffle.api.Assumption;
3332
import com.oracle.truffle.api.CompilerAsserts;
3433
import com.oracle.truffle.api.CompilerDirectives;
3534
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
3635
import com.oracle.truffle.api.dsl.Cached;
3736
import com.oracle.truffle.api.dsl.Cached.Exclusive;
37+
import com.oracle.truffle.api.dsl.ImportStatic;
3838
import com.oracle.truffle.api.dsl.Specialization;
3939
import com.oracle.truffle.api.interop.InteropLibrary;
4040
import com.oracle.truffle.api.interop.UnsupportedMessageException;
@@ -172,9 +172,10 @@ boolean isExecutable() {
172172
}
173173

174174
@ExportMessage
175+
@ImportStatic(LLVMLanguage.class)
175176
static class Execute {
176177

177-
@Specialization(limit = "5", guards = "self == cachedSelf", assumptions = "singleContextAssumption()")
178+
@Specialization(limit = "5", guards = {"self == cachedSelf", "isSingleContext($node)"})
178179
static Object doDescriptor(@SuppressWarnings("unused") LLVMFunctionDescriptor self, Object[] args,
179180
@Cached("self") @SuppressWarnings("unused") LLVMFunctionDescriptor cachedSelf,
180181
@Cached("createCall(cachedSelf)") DirectCallNode call) {
@@ -200,10 +201,6 @@ protected static DirectCallNode createCall(LLVMFunctionDescriptor self) {
200201
return callNode;
201202
}
202203

203-
protected static Assumption singleContextAssumption() {
204-
return LLVMLanguage.get(null).singleContextAssumption;
205-
}
206-
207204
}
208205

209206
@ExportMessage

sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/LLVMGetStackFromThreadNode.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2023, Oracle and/or its affiliates.
33
*
44
* All rights reserved.
55
*
@@ -59,7 +59,7 @@ protected LLVMStack getStack(LLVMThreadingStack threadingStack, Thread cachedThr
5959
* @param currentThread
6060
* @see #executeWithTarget(LLVMThreadingStack, Thread)
6161
*/
62-
@Specialization(limit = "3", guards = "currentThread == cachedThread", assumptions = "singleContextAssumption()")
62+
@Specialization(limit = "3", guards = {"currentThread == cachedThread", "isSingleContext($node)"})
6363
protected LLVMStack cached(LLVMThreadingStack stack, Thread currentThread,
6464
@Cached("currentThread") @SuppressWarnings("unused") Thread cachedThread,
6565
@Cached("getStack(stack, cachedThread)") LLVMStack cachedStack) {

sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/LLVMLanguage.java

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2016, 2023, Oracle and/or its affiliates.
33
*
44
* All rights reserved.
55
*
@@ -49,6 +49,7 @@
4949
import com.oracle.truffle.api.Truffle;
5050
import com.oracle.truffle.api.TruffleLanguage;
5151
import com.oracle.truffle.api.debug.DebuggerTags;
52+
import com.oracle.truffle.api.dsl.Idempotent;
5253
import com.oracle.truffle.api.dsl.Specialization;
5354
import com.oracle.truffle.api.frame.VirtualFrame;
5455
import com.oracle.truffle.api.instrumentation.ProvidedTags;
@@ -115,7 +116,8 @@ public class LLVMLanguage extends TruffleLanguage<LLVMContext> {
115116

116117
public static final String ID = "llvm";
117118
static final String NAME = "LLVM";
118-
public final Assumption singleContextAssumption = Truffle.getRuntime().createAssumption("Only a single context is active");
119+
120+
@CompilationFinal public boolean singleContext;
119121

120122
@CompilationFinal private Configuration activeConfiguration = null;
121123

@@ -810,10 +812,16 @@ protected void disposeThread(LLVMContext context, Thread thread) {
810812
@Override
811813
protected void initializeMultipleContexts() {
812814
super.initializeMultipleContexts();
813-
singleContextAssumption.invalidate();
815+
singleContext = false;
814816
}
815817

816818
public RootCallTarget createCachedCallTarget(Class<?> key, Function<LLVMLanguage, RootNode> create) {
817819
return cachedCallTargets.computeIfAbsent(key, k -> create.apply(LLVMLanguage.this).getCallTarget());
818820
}
821+
822+
@Idempotent
823+
public static boolean isSingleContext(Node node) {
824+
return LLVMLanguage.get(node).singleContext;
825+
}
826+
819827
}

0 commit comments

Comments
 (0)