45
45
import com .oracle .graal .python .PythonLanguage ;
46
46
import com .oracle .truffle .api .Assumption ;
47
47
import com .oracle .truffle .api .CompilerAsserts ;
48
+ import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
48
49
import com .oracle .truffle .api .Truffle ;
49
50
import com .oracle .truffle .api .dsl .Cached ;
50
51
import com .oracle .truffle .api .dsl .Cached .Exclusive ;
51
52
import com .oracle .truffle .api .dsl .Specialization ;
52
53
import com .oracle .truffle .api .interop .TruffleObject ;
53
54
import com .oracle .truffle .api .library .ExportLibrary ;
54
55
import com .oracle .truffle .api .library .ExportMessage ;
56
+ import com .oracle .truffle .api .nodes .InvalidAssumptionException ;
55
57
56
58
@ ExportLibrary (PythonNativeWrapperLibrary .class )
57
59
public abstract class PythonNativeWrapper implements TruffleObject {
@@ -98,6 +100,11 @@ public final void setRefCount(long refCount) {
98
100
this .refCount = refCount ;
99
101
}
100
102
103
+ @ TruffleBoundary
104
+ public static void invalidateAssumption (Assumption handleValidAssumption ) {
105
+ handleValidAssumption .invalidate ("releasing handle for native wrapper" );
106
+ }
107
+
101
108
public final Assumption getHandleValidAssumption () {
102
109
return handleValidAssumption ;
103
110
}
@@ -122,6 +129,15 @@ protected static WeakReference<PythonNativeWrapper> weak(PythonNativeWrapper wra
122
129
return new WeakReference <>(wrapper );
123
130
}
124
131
132
+ protected static WeakReference <Assumption > weakAssumption (PythonNativeWrapper wrapper ) {
133
+ Assumption handleValidAssumption = wrapper .getHandleValidAssumption ();
134
+ // The assumption only exists if the wrapper was used in a cache at some point.
135
+ if (handleValidAssumption != null ) {
136
+ return new WeakReference <>(handleValidAssumption );
137
+ }
138
+ return null ;
139
+ }
140
+
125
141
@ ExportMessage (name = "getDelegate" )
126
142
protected static class GetDelegate {
127
143
@ Specialization (guards = {"isEq(cachedWrapper.get(), wrapper)" , "!isEq(delegate.get(), null)" }, assumptions = "singleContextAssumption()" )
@@ -148,10 +164,16 @@ protected void setDelegate(Object delegate) {
148
164
149
165
@ ExportMessage (name = "getNativePointer" )
150
166
protected static class GetNativePointer {
151
- @ Specialization (guards = {"isEq(cachedWrapper.get(), wrapper)" , "!isEq(nativePointer.get(), null)" }, assumptions = "singleContextAssumption()" )
167
+ @ Specialization (guards = {"isEq(cachedWrapper.get(), wrapper)" , "!isEq(nativePointer.get(), null)" }, assumptions = "singleContextAssumption()" , //
168
+ rewriteOn = InvalidAssumptionException .class )
152
169
protected static Object getCachedPtr (@ SuppressWarnings ("unused" ) PythonNativeWrapper wrapper ,
153
170
@ Exclusive @ SuppressWarnings ("unused" ) @ Cached ("weak(wrapper)" ) WeakReference <PythonNativeWrapper > cachedWrapper ,
154
- @ Exclusive @ Cached ("wrapper.getNativePointerPrivate()" ) WeakReference <Object > nativePointer ) {
171
+ @ Exclusive @ Cached ("weakAssumption(wrapper)" ) WeakReference <Assumption > cachedAssumption ,
172
+ @ Exclusive @ Cached ("wrapper.getNativePointerPrivate()" ) WeakReference <Object > nativePointer ) throws InvalidAssumptionException {
173
+ if (cachedAssumption != null ) {
174
+ // as long as the wrapper exists, the assumption will also exist
175
+ cachedAssumption .get ().check ();
176
+ }
155
177
return nativePointer .get ();
156
178
}
157
179
@@ -176,16 +198,27 @@ public void setNativePointer(Object nativePointer) {
176
198
177
199
@ ExportMessage (name = "isNative" )
178
200
protected static class IsNative {
179
- @ Specialization (guards = {"isEq(cachedWrapper.get(), wrapper)" , "!isEq(nativePointer.get(), null)" }, assumptions = "singleContextAssumption()" )
201
+ @ Specialization (guards = {"isEq(cachedWrapper.get(), wrapper)" , "!isEq(nativePointer.get(), null)" }, assumptions = "singleContextAssumption()" , //
202
+ rewriteOn = InvalidAssumptionException .class )
180
203
protected static boolean isCachedNative (@ SuppressWarnings ("unused" ) PythonNativeWrapper wrapper ,
181
204
@ Exclusive @ SuppressWarnings ("unused" ) @ Cached ("weak(wrapper)" ) WeakReference <PythonNativeWrapper > cachedWrapper ,
182
- @ Exclusive @ SuppressWarnings ("unused" ) @ Cached ("wrapper.getNativePointerPrivate()" ) WeakReference <Object > nativePointer ) {
205
+ @ Exclusive @ Cached ("weakAssumption(wrapper)" ) WeakReference <Assumption > cachedAssumption ,
206
+ @ Exclusive @ SuppressWarnings ("unused" ) @ Cached ("wrapper.getNativePointerPrivate()" ) WeakReference <Object > nativePointer ) throws InvalidAssumptionException {
207
+ if (cachedAssumption != null ) {
208
+ // as long as the wrapper exists, the assumption will also exist
209
+ cachedAssumption .get ().check ();
210
+ }
183
211
return true ;
184
212
}
185
213
186
214
@ Specialization (replaces = "isCachedNative" )
187
215
protected static boolean isNative (PythonNativeWrapper wrapper ) {
188
- return wrapper .nativePointer != null ;
216
+ if (wrapper .nativePointer != null ) {
217
+ Assumption handleValidAssumption = wrapper .getHandleValidAssumption ();
218
+ // If an assumption exists, it must be valid
219
+ return handleValidAssumption == null || handleValidAssumption .isValid ();
220
+ }
221
+ return false ;
189
222
}
190
223
}
191
224
}
0 commit comments