108
108
import org .truffleruby .language .objects .MetaClassNode ;
109
109
import org .truffleruby .language .objects .WriteObjectFieldNode ;
110
110
import org .truffleruby .language .supercall .CallSuperMethodNode ;
111
- import org .truffleruby .language .yield .CallBlockNode ;
112
111
import org .truffleruby .parser .IdentifierType ;
113
112
114
113
import com .oracle .truffle .api .CompilerDirectives ;
@@ -167,6 +166,8 @@ private static long getNativeStringCapacity(Pointer pointer) {
167
166
public abstract static class CallWithCExtLockAndFrameNode extends PrimitiveArrayArgumentsNode {
168
167
169
168
@ Child protected CallWithCExtLockNode callCextNode = CallWithCExtLockNodeFactory .create (RubyNode .EMPTY_ARRAY );
169
+ @ Child protected MarkingServiceNodes .RunMarkOnExitNode runMarksNode = MarkingServiceNodes .RunMarkOnExitNode
170
+ .create ();
170
171
171
172
@ Specialization
172
173
protected Object callWithCExtLockAndFrame (
@@ -175,7 +176,11 @@ protected Object callWithCExtLockAndFrame(
175
176
final boolean keywordsGiven = RubyArguments .getDescriptor (frame ) instanceof KeywordArgumentsDescriptor ;
176
177
extensionStack .push (keywordsGiven , specialVariables , block );
177
178
try {
178
- return callCextNode .execute (receiver , argsArray );
179
+ try {
180
+ return callCextNode .execute (receiver , argsArray );
181
+ } finally {
182
+ runMarksNode .execute (extensionStack );
183
+ }
179
184
} finally {
180
185
extensionStack .pop ();
181
186
}
@@ -185,13 +190,17 @@ protected Object callWithCExtLockAndFrame(
185
190
@ Primitive (name = "call_with_c_mutex_and_frame_and_unwrap" )
186
191
public abstract static class CallWithCExtLockAndFrameAndUnwrapNode extends PrimitiveArrayArgumentsNode {
187
192
193
+ @ Child protected MarkingServiceNodes .RunMarkOnExitNode runMarksNode = MarkingServiceNodes .RunMarkOnExitNode
194
+ .create ();
195
+
188
196
@ Specialization (limit = "getCacheLimit()" )
189
197
protected Object callWithCExtLockAndFrame (
190
198
VirtualFrame frame , Object receiver , RubyArray argsArray , Object specialVariables , Object block ,
191
199
@ CachedLibrary ("receiver" ) InteropLibrary receivers ,
192
200
@ Cached ArrayToObjectArrayNode arrayToObjectArrayNode ,
193
201
@ Cached TranslateInteropExceptionNode translateInteropExceptionNode ,
194
202
@ Cached ConditionProfile ownedProfile ,
203
+ @ Cached MarkingServiceNodes .RunMarkOnExitNode runMarksNode ,
195
204
@ Cached UnwrapNode unwrapNode ) {
196
205
final ExtensionCallStack extensionStack = getLanguage ().getCurrentFiber ().extensionCallStack ;
197
206
final boolean keywordsGiven = RubyArguments .getDescriptor (frame ) instanceof KeywordArgumentsDescriptor ;
@@ -210,13 +219,18 @@ protected Object callWithCExtLockAndFrame(
210
219
return unwrapNode .execute (
211
220
InteropNodes .execute (receiver , args , receivers , translateInteropExceptionNode ));
212
221
} finally {
222
+ runMarksNode .execute (extensionStack );
213
223
if (!owned ) {
214
224
MutexOperations .unlockInternal (lock );
215
225
}
216
226
}
217
227
} else {
218
- return unwrapNode
219
- .execute (InteropNodes .execute (receiver , args , receivers , translateInteropExceptionNode ));
228
+ try {
229
+ return unwrapNode .execute (
230
+ InteropNodes .execute (receiver , args , receivers , translateInteropExceptionNode ));
231
+ } finally {
232
+ runMarksNode .execute (extensionStack );
233
+ }
220
234
}
221
235
222
236
} finally {
@@ -361,6 +375,18 @@ protected Object publicSendWithoutLock(
361
375
}
362
376
}
363
377
378
+ @ Primitive (name = "cext_mark_object_on_call_exit" )
379
+ public abstract static class MarkObjectOnCallExit extends PrimitiveArrayArgumentsNode {
380
+
381
+ @ Specialization
382
+ protected Object markOnCallExit (Object object ,
383
+ @ Cached WrapNode wrapNode ,
384
+ @ Cached MarkingServiceNodes .QueueForMarkOnExitNode markOnExitNode ) {
385
+ markOnExitNode .execute (wrapNode .execute (object ));
386
+ return nil ;
387
+ }
388
+ }
389
+
364
390
@ CoreMethod (names = "cext_start_new_handle_block" , onSingleton = true )
365
391
public abstract static class StartNewHandleBlockNode extends CoreMethodArrayArgumentsNode {
366
392
@ Specialization
@@ -1677,6 +1703,7 @@ public abstract static class NewMarkerList extends CoreMethodArrayArgumentsNode
1677
1703
protected Object createNewMarkList (RubyDynamicObject object ,
1678
1704
@ CachedLibrary ("object" ) DynamicObjectLibrary objectLibrary ) {
1679
1705
getContext ().getMarkingService ().startMarking (
1706
+ getLanguage ().getCurrentThread ().getCurrentFiber ().extensionCallStack ,
1680
1707
(Object []) objectLibrary .getOrDefault (object , Layouts .MARKED_OBJECTS_IDENTIFIER , null ));
1681
1708
return nil ;
1682
1709
}
@@ -1692,7 +1719,8 @@ protected Object addToMarkList(Object markedObject,
1692
1719
ValueWrapper wrappedValue = toWrapperNode .execute (markedObject );
1693
1720
if (wrappedValue != null ) {
1694
1721
noExceptionProfile .enter ();
1695
- getContext ().getMarkingService ().addMark (wrappedValue );
1722
+ getContext ().getMarkingService ()
1723
+ .addMark (getLanguage ().getCurrentThread ().getCurrentFiber ().extensionCallStack , wrappedValue );
1696
1724
}
1697
1725
// We do nothing here if the handle cannot be resolved. If we are marking an object
1698
1726
// which is only reachable via weak refs then the handles of objects it is itself
@@ -1729,29 +1757,12 @@ protected Object setMarkList(RubyDynamicObject structOwner,
1729
1757
writeMarkedNode .execute (
1730
1758
structOwner ,
1731
1759
Layouts .MARKED_OBJECTS_IDENTIFIER ,
1732
- getContext ().getMarkingService ().finishMarking ());
1760
+ getContext ().getMarkingService ()
1761
+ .finishMarking (getLanguage ().getCurrentThread ().getCurrentFiber ().extensionCallStack ));
1733
1762
return nil ;
1734
1763
}
1735
1764
}
1736
1765
1737
- @ CoreMethod (names = "define_marker" , onSingleton = true , required = 2 )
1738
- public abstract static class CreateMarkerNode extends CoreMethodArrayArgumentsNode {
1739
-
1740
- @ TruffleBoundary
1741
- @ Specialization
1742
- protected Object createMarker (RubyDynamicObject object , RubyProc marker ) {
1743
- /* The code here has to be a little subtle. The marker must be associated with the object it will act on,
1744
- * but the lambda must not capture the object (and prevent garbage collection). So the marking function is a
1745
- * lambda that will take the object as an argument 'o' which will be provided when the marking function is
1746
- * called by the marking service. */
1747
- getContext ()
1748
- .getMarkingService ()
1749
- .addMarker (object , (o ) -> CallBlockNode .getUncached ().yield (marker , o ));
1750
- return nil ;
1751
- }
1752
-
1753
- }
1754
-
1755
1766
@ CoreMethod (names = "rb_thread_check_ints" , onSingleton = true , required = 0 )
1756
1767
public abstract static class CheckThreadInterrupt extends CoreMethodArrayArgumentsNode {
1757
1768
0 commit comments