27
27
import org .truffleruby .core .thread .ThreadManager ;
28
28
import org .truffleruby .core .thread .ThreadManager .BlockingAction ;
29
29
import org .truffleruby .language .SafepointAction ;
30
+ import org .truffleruby .language .arguments .ArgumentsDescriptor ;
31
+ import org .truffleruby .language .arguments .EmptyArgumentsDescriptor ;
30
32
import org .truffleruby .language .control .BreakException ;
31
33
import org .truffleruby .language .control .DynamicReturnException ;
32
34
import org .truffleruby .language .control .ExitException ;
@@ -120,11 +122,12 @@ private void fiberMain(RubyContext context, RubyFiber fiber, RubyProc block, Nod
120
122
121
123
FiberMessage lastMessage = null ;
122
124
try {
123
- final Object [] args = handleMessage (fiber , message , currentNode );
125
+ var descriptorAndArgs = handleMessage (fiber , message , currentNode );
124
126
fiber .status = FiberStatus .RESUMED ;
125
- final Object result = ProcOperations .rootCall (block , args );
127
+ final Object result = ProcOperations .rootCall (block , descriptorAndArgs . descriptor , descriptorAndArgs . args );
126
128
127
- lastMessage = new FiberResumeMessage (FiberOperation .YIELD , fiber , new Object []{ result });
129
+ lastMessage = new FiberResumeMessage (FiberOperation .YIELD , fiber ,
130
+ EmptyArgumentsDescriptor .INSTANCE , new Object []{ result });
128
131
129
132
// Handlers in the same order as in ThreadManager
130
133
} catch (KillException | ExitException | RaiseException e ) {
@@ -220,13 +223,14 @@ private void assertNotEntered(String reason) {
220
223
}
221
224
222
225
@ TruffleBoundary
223
- private Object [] handleMessage (RubyFiber fiber , FiberMessage message , Node currentNode ) {
226
+ private DescriptorAndArgs handleMessage (RubyFiber fiber , FiberMessage message , Node currentNode ) {
224
227
// Written as a loop to not grow the stack when processing guest safepoints
225
228
while (message instanceof FiberSafepointMessage ) {
226
229
final FiberSafepointMessage safepointMessage = (FiberSafepointMessage ) message ;
227
230
safepointMessage .action .run (fiber .rubyThread , currentNode );
228
231
final RubyFiber sendingFiber = safepointMessage .sendingFiber ;
229
- message = resumeAndWait (fiber , sendingFiber , FiberOperation .TRANSFER , SAFEPOINT_ARGS , currentNode );
232
+ message = resumeAndWait (fiber , sendingFiber , FiberOperation .TRANSFER ,
233
+ EmptyArgumentsDescriptor .INSTANCE , SAFEPOINT_ARGS , currentNode );
230
234
}
231
235
232
236
if (message instanceof FiberShutdownMessage ) {
@@ -252,21 +256,22 @@ private Object[] handleMessage(RubyFiber fiber, FiberMessage message, Node curre
252
256
throw new RaiseException (context , (RubyException ) resumeMessage .getArgs ()[0 ]);
253
257
}
254
258
255
- return resumeMessage .getArgs ();
259
+ return resumeMessage .getDescriptorAndArgs ();
256
260
} else {
257
261
throw CompilerDirectives .shouldNotReachHere ();
258
262
}
259
263
}
260
264
261
265
/** Send a resume message to a fiber by posting into its message queue. Doesn't explicitly notify the Java thread
262
266
* (although the queue implementation may) and doesn't wait for the message to be received. */
263
- private void resume (RubyFiber fromFiber , RubyFiber fiber , FiberOperation operation , Object ... args ) {
264
- addToMessageQueue (fiber , new FiberResumeMessage (operation , fromFiber , args ));
267
+ private void resume (RubyFiber fromFiber , RubyFiber fiber , FiberOperation operation ,
268
+ ArgumentsDescriptor descriptor , Object ... args ) {
269
+ addToMessageQueue (fiber , new FiberResumeMessage (operation , fromFiber , descriptor , args ));
265
270
}
266
271
267
272
@ TruffleBoundary
268
- public Object [] transferControlTo (RubyFiber fromFiber , RubyFiber toFiber , FiberOperation operation , Object [] args ,
269
- Node currentNode ) {
273
+ public DescriptorAndArgs transferControlTo (RubyFiber fromFiber , RubyFiber toFiber , FiberOperation operation ,
274
+ ArgumentsDescriptor descriptor , Object [] args , Node currentNode ) {
270
275
assert fromFiber .resumingFiber == null ;
271
276
if (operation == FiberOperation .RESUME ) {
272
277
fromFiber .resumingFiber = toFiber ;
@@ -280,7 +285,7 @@ public Object[] transferControlTo(RubyFiber fromFiber, RubyFiber toFiber, FiberO
280
285
if (fromFiber .status == FiberStatus .RESUMED ) {
281
286
fromFiber .status = FiberStatus .SUSPENDED ;
282
287
}
283
- final FiberMessage message = resumeAndWait (fromFiber , toFiber , operation , args , currentNode );
288
+ final FiberMessage message = resumeAndWait (fromFiber , toFiber , operation , descriptor , args , currentNode );
284
289
return handleMessage (fromFiber , message , currentNode );
285
290
}
286
291
@@ -294,13 +299,13 @@ public Object[] transferControlTo(RubyFiber fromFiber, RubyFiber toFiber, FiberO
294
299
* @param fromFiber the current fiber which will soon be suspended
295
300
* @param toFiber the fiber we resume or transfer to */
296
301
@ TruffleBoundary
297
- private FiberMessage resumeAndWait (RubyFiber fromFiber , RubyFiber toFiber , FiberOperation operation , Object [] args ,
298
- Node currentNode ) {
302
+ private FiberMessage resumeAndWait (RubyFiber fromFiber , RubyFiber toFiber , FiberOperation operation ,
303
+ ArgumentsDescriptor descriptor , Object [] args , Node currentNode ) {
299
304
final TruffleContext truffleContext = context .getEnv ().getContext ();
300
305
final FiberMessage message = context
301
306
.getThreadManager ()
302
307
.leaveAndEnter (truffleContext , currentNode , () -> {
303
- resume (fromFiber , toFiber , operation , args );
308
+ resume (fromFiber , toFiber , operation , descriptor , args );
304
309
return waitMessage (fromFiber , currentNode );
305
310
});
306
311
fromFiber .rubyThread .setCurrentFiber (fromFiber );
@@ -441,18 +446,34 @@ public String getFiberDebugInfo(RubyThread rubyThread) {
441
446
}
442
447
}
443
448
449
+ public static final class DescriptorAndArgs {
450
+ public final ArgumentsDescriptor descriptor ;
451
+ public final Object [] args ;
452
+
453
+ public DescriptorAndArgs (ArgumentsDescriptor descriptor , Object [] args ) {
454
+ this .descriptor = descriptor ;
455
+ this .args = args ;
456
+ }
457
+ }
458
+
444
459
public interface FiberMessage {
445
460
}
446
461
447
462
private static class FiberResumeMessage implements FiberMessage {
448
463
449
464
private final FiberOperation operation ;
450
465
private final RubyFiber sendingFiber ;
466
+ private final ArgumentsDescriptor descriptor ;
451
467
private final Object [] args ;
452
468
453
- public FiberResumeMessage (FiberOperation operation , RubyFiber sendingFiber , Object [] args ) {
469
+ public FiberResumeMessage (
470
+ FiberOperation operation ,
471
+ RubyFiber sendingFiber ,
472
+ ArgumentsDescriptor descriptor ,
473
+ Object [] args ) {
454
474
this .operation = operation ;
455
475
this .sendingFiber = sendingFiber ;
476
+ this .descriptor = descriptor ;
456
477
this .args = args ;
457
478
}
458
479
@@ -464,10 +485,17 @@ public RubyFiber getSendingFiber() {
464
485
return sendingFiber ;
465
486
}
466
487
488
+ public ArgumentsDescriptor getDescriptor () {
489
+ return descriptor ;
490
+ }
491
+
467
492
public Object [] getArgs () {
468
493
return args ;
469
494
}
470
495
496
+ public DescriptorAndArgs getDescriptorAndArgs () {
497
+ return new DescriptorAndArgs (descriptor , args );
498
+ }
471
499
}
472
500
473
501
private static class FiberSafepointMessage implements FiberMessage {
0 commit comments