Skip to content

Commit d01f9b0

Browse files
committed
Refactor of rb_block handling.
1 parent f5bde7e commit d01f9b0

File tree

5 files changed

+45
-47
lines changed

5 files changed

+45
-47
lines changed

lib/truffle/truffle/cext.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,7 @@ def rb_funcallv(recv, meth, args)
962962

963963
def rb_funcall(recv, meth, n, *args)
964964
# see #call_with_thread_locally_stored_block
965-
thread_local_block = Thread.current[:__C_BLOCK__]
965+
thread_local_block = Thread.current[:__C_BLOCK__]
966966
Thread.current[:__C_BLOCK__] = nil
967967
recv.__send__(meth, *args, &thread_local_block)
968968
ensure

lib/truffle/truffle/cext_ruby.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def rb_define_method(mod, name, function, argc)
3030
end
3131

3232
# Using raw execute instead of #call here to avoid argument conversion
33-
Truffle::CExt.push_preserving_frame
33+
Truffle::CExt.push_extension_call_frame(block)
3434
begin
3535
# We must call explicitly with the block argument if given
3636
# here so that the `rb_block_*` functions will be able to find
@@ -41,7 +41,7 @@ def rb_define_method(mod, name, function, argc)
4141
Truffle::CExt.rb_tr_unwrap(Truffle.invoke_primitive(:call_with_c_mutex, function, args))
4242
end
4343
ensure
44-
Truffle::CExt.pop_preserving_frame
44+
Truffle::CExt.pop_extension_call_frame
4545
end
4646
end
4747

@@ -51,19 +51,27 @@ def rb_define_method(mod, name, function, argc)
5151
private
5252

5353
def rb_iterate_call_block(callback, block_arg, callback_arg, &block)
54-
rb_tr_unwrap(Truffle.invoke_primitive(:call_with_c_mutex, callback, [rb_tr_wrap(block_arg), rb_tr_wrap(callback_arg)]))
54+
Truffle::CExt.push_extension_call_frame(block)
55+
begin
56+
rb_tr_unwrap(Truffle.invoke_primitive(:call_with_c_mutex, callback, [rb_tr_wrap(block_arg), rb_tr_wrap(callback_arg)]))
57+
ensure
58+
Truffle::CExt.pop_extension_call_frame
59+
end
5560
end
5661

5762
def call_with_thread_locally_stored_block(function, *args, &block)
5863
# MRI puts the block to a thread local th->passed_block and later rb_funcall reads it,
5964
# we have to do the same
6065
# TODO (pitr-ch 14-Dec-2017): This is fixed just for rb_iterate with a rb_funcall in it combination
66+
6167
previous_block = Thread.current[:__C_BLOCK__]
68+
Truffle::CExt.push_extension_call_frame(block)
6269
begin
6370
Thread.current[:__C_BLOCK__] = block
6471
rb_tr_unwrap(Truffle.invoke_primitive(:call_with_c_mutex, function, args.map! { |arg| Truffle::CExt.rb_tr_wrap(arg) }, &block))
6572
ensure
6673
Thread.current[:__C_BLOCK__] = previous_block
74+
Truffle::CExt.pop_extension_call_frame
6775
end
6876
end
6977

src/main/java/org/truffleruby/cext/CExtNodes.java

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -590,31 +590,11 @@ public DynamicObject rbStrResize(DynamicObject string, int newByteLength,
590590
@CoreMethod(names = "rb_block_proc", onSingleton = true)
591591
public abstract static class BlockProcNode extends CoreMethodArrayArgumentsNode {
592592

593-
// TODO (pitr-ch 04-Dec-2017): needs optimising
594-
@TruffleBoundary
595593
@Specialization
596-
public DynamicObject blockProc() {
597-
return Truffle.getRuntime().iterateFrames(frameInstance -> {
598-
final Node callNode = frameInstance.getCallNode();
599-
600-
if (callNode != null) {
601-
final RootNode rootNode = callNode.getRootNode();
602-
// Skip Ruby frames in cext.rb file since they are implementing methods which are implemented
603-
// with C in MRI, and therefore are also implicitly skipped when when looking up the block passed
604-
// to a C API function.
605-
if (rootNode instanceof RubyRootNode &&
606-
rootNode.getSourceSection().isAvailable() &&
607-
!rootNode.getSourceSection().getSource().getName().endsWith("truffle/cext.rb")) {
608-
609-
final DynamicObject block = RubyArguments.getBlock(frameInstance.getFrame(FrameAccess.READ_ONLY));
610-
return block == null ? nil() : block;
611-
}
612-
}
613-
614-
return null;
615-
});
594+
public DynamicObject block(VirtualFrame frame,
595+
@Cached("create()") MarkingServiceNodes.GetMarkerThreadLocalDataNode getDataNode) {
596+
return getDataNode.execute(frame).getExtensionCallStack().getBlock();
616597
}
617-
618598
}
619599

620600
@CoreMethod(names = "rb_check_frozen", onSingleton = true, required = 1)
@@ -1520,24 +1500,24 @@ protected void addObjectToMarkingService(DynamicObject object, DynamicObject mar
15201500
}
15211501
}
15221502

1523-
@CoreMethod(names = "push_preserving_frame", onSingleton = true, required = 0)
1503+
@CoreMethod(names = "push_extension_call_frame", onSingleton = true, required = 1)
15241504
public abstract static class PushPreservingFrame extends CoreMethodArrayArgumentsNode {
15251505

15261506
@Specialization
1527-
public DynamicObject pushFrame(VirtualFrame frame,
1507+
public DynamicObject pushFrame(VirtualFrame frame, DynamicObject block,
15281508
@Cached("create()") MarkingServiceNodes.GetMarkerThreadLocalDataNode getDataNode) {
1529-
getDataNode.execute(frame).getPreservationStack().push();
1509+
getDataNode.execute(frame).getExtensionCallStack().push(block);
15301510
return nil();
15311511
}
15321512
}
15331513

1534-
@CoreMethod(names = "pop_preserving_frame", onSingleton = true, required = 0)
1514+
@CoreMethod(names = "pop_extension_call_frame", onSingleton = true, required = 0)
15351515
public abstract static class PopPreservingFrame extends CoreMethodArrayArgumentsNode {
15361516

15371517
@Specialization
15381518
public DynamicObject popFrame(VirtualFrame frame,
15391519
@Cached("create()") MarkingServiceNodes.GetMarkerThreadLocalDataNode getDataNode) {
1540-
getDataNode.execute(frame).getPreservationStack().pop();
1520+
getDataNode.execute(frame).getExtensionCallStack().pop();
15411521
return nil();
15421522
}
15431523
}

src/main/java/org/truffleruby/core/MarkingService.java

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -126,19 +126,19 @@ public void runAllMarkers() {
126126

127127
public static class MarkerThreadLocalData {
128128
private final MarkerKeptObjects keptObjects;
129-
private final MarkerStack preservationStack;
129+
private final ExtensionCallStack extensionCallStack;
130130

131131
public MarkerThreadLocalData(MarkingService service) {
132-
this.preservationStack = new MarkerStack();
132+
this.extensionCallStack = new ExtensionCallStack(service.context.getCoreLibrary().getNil());
133133
this.keptObjects = new MarkerKeptObjects(service);
134134
}
135135

136136
public MarkerKeptObjects getKeptObjects() {
137137
return keptObjects;
138138
}
139139

140-
public MarkerStack getPreservationStack() {
141-
return preservationStack;
140+
public ExtensionCallStack getExtensionCallStack() {
141+
return extensionCallStack;
142142
}
143143
}
144144

@@ -226,28 +226,38 @@ public void keepObjects(MarkerKeptObjects otherObjects) {
226226

227227
}
228228

229-
protected static class MarkerStackEntry {
230-
protected final MarkerStackEntry previous;
231-
protected final ArrayList<Object> entries = new ArrayList<>();
229+
protected static class ExtensionCallStackEntry {
230+
protected final ExtensionCallStackEntry previous;
231+
protected final ArrayList<Object> preservedObjects = new ArrayList<>();
232+
protected final DynamicObject block;
232233

233-
protected MarkerStackEntry(MarkerStackEntry previous) {
234+
protected ExtensionCallStackEntry(ExtensionCallStackEntry previous, DynamicObject block) {
234235
this.previous = previous;
236+
this.block = block;
235237
}
236238
}
237239

238-
public static class MarkerStack {
239-
protected MarkerStackEntry current = new MarkerStackEntry(null);
240+
public static class ExtensionCallStack {
241+
protected ExtensionCallStackEntry current;
240242

241-
public ArrayList<Object> get() {
242-
return current.entries;
243+
public ExtensionCallStack(DynamicObject block) {
244+
current = new ExtensionCallStackEntry(null, block);
245+
}
246+
247+
public ArrayList<Object> getKeptObjects() {
248+
return current.preservedObjects;
243249
}
244250

245251
public void pop() {
246252
current = current.previous;
247253
}
248254

249-
public void push() {
250-
current = new MarkerStackEntry(current);
255+
public void push(DynamicObject block) {
256+
current = new ExtensionCallStackEntry(current, block);
257+
}
258+
259+
public DynamicObject getBlock() {
260+
return current.block;
251261
}
252262
}
253263

src/main/java/org/truffleruby/core/MarkingServiceNodes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static abstract class KeepAliveNode extends RubyBaseNode {
2929
public void keepObjectAlive(VirtualFrame frame, Object object,
3030
@Cached("create()") GetMarkerThreadLocalDataNode getThreadLocalDataNode) {
3131
MarkerThreadLocalData data = getThreadLocalDataNode.execute(frame);
32-
addToList(data.getPreservationStack().get(), object);
32+
addToList(data.getExtensionCallStack().getKeptObjects(), object);
3333
data.getKeptObjects().keepObject(object);
3434
}
3535

0 commit comments

Comments
 (0)