Skip to content

Commit 13ee3a5

Browse files
committed
[GR-51302] RData/RTypedData finalizers should use a wrapper
PullRequest: truffleruby/4115
2 parents 2e95271 + d06b0e3 commit 13ee3a5

File tree

2 files changed

+13
-42
lines changed

2 files changed

+13
-42
lines changed

lib/truffle/truffle/cext.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,6 +1728,10 @@ def rb_data_typed_object_wrap(ruby_class, data, data_type, mark, free, size)
17281728
object
17291729
end
17301730

1731+
def run_data_finalizer(function, data)
1732+
Primitive.call_with_c_mutex_and_frame POINTER_TO_VOID_WRAPPER, [function, data], nil, nil
1733+
end
1734+
17311735
def run_marker(obj)
17321736
Primitive.array_mark_store(obj) if Primitive.array_store_native?(obj)
17331737

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

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,18 @@
1010
package org.truffleruby.core;
1111

1212
import java.lang.ref.ReferenceQueue;
13-
import java.util.concurrent.locks.ReentrantLock;
1413

14+
import com.oracle.truffle.api.interop.InteropException;
1515
import org.truffleruby.RubyContext;
1616
import org.truffleruby.RubyLanguage;
17-
import org.truffleruby.core.MarkingService.ExtensionCallStack;
18-
import org.truffleruby.core.mutex.MutexOperations;
1917
import org.truffleruby.language.Nil;
2018
import org.truffleruby.language.RubyBaseRootNode;
2119
import org.truffleruby.language.backtrace.InternalRootNode;
2220

2321
import com.oracle.truffle.api.CallTarget;
2422
import com.oracle.truffle.api.CompilerDirectives;
2523
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
26-
import com.oracle.truffle.api.interop.ArityException;
2724
import com.oracle.truffle.api.interop.InteropLibrary;
28-
import com.oracle.truffle.api.interop.UnsupportedMessageException;
29-
import com.oracle.truffle.api.interop.UnsupportedTypeException;
30-
import com.oracle.truffle.api.profiles.ConditionProfile;
3125
import com.oracle.truffle.api.frame.VirtualFrame;
3226

3327
/** C-ext data finalizers are implemented with phantom references and reference queues, and are run in a dedicated Ruby
@@ -40,10 +34,8 @@ public final class DataObjectFinalizationService
4034
public static final class DataObjectFinalizerRootNode extends RubyBaseRootNode implements InternalRootNode {
4135

4236
@Child private InteropLibrary callNode;
43-
private final ConditionProfile ownedProfile = ConditionProfile.create();
4437

45-
public DataObjectFinalizerRootNode(
46-
RubyLanguage language) {
38+
public DataObjectFinalizerRootNode(RubyLanguage language) {
4739
super(language, RubyLanguage.EMPTY_FRAME_DESCRIPTOR, null);
4840

4941
callNode = InteropLibrary.getFactory().createDispatched(1);
@@ -55,41 +47,17 @@ public Object execute(VirtualFrame frame) {
5547
}
5648

5749
public Object execute(DataObjectFinalizerReference ref) {
58-
if (getContext().getOptions().CEXT_LOCK) {
59-
final ReentrantLock lock = getContext().getCExtensionsLock();
60-
boolean owned = ownedProfile.profile(lock.isHeldByCurrentThread());
61-
62-
if (!owned) {
63-
MutexOperations.lockInternal(getContext(), lock, this);
64-
}
50+
if (!getContext().isFinalizing()) {
6551
try {
66-
runFinalizer(ref);
67-
} finally {
68-
if (!owned) {
69-
MutexOperations.unlockInternal(lock);
70-
}
52+
callNode.invokeMember(getContext().getCoreLibrary().truffleCExtModule, "run_data_finalizer",
53+
ref.finalizerCFunction, ref.dataStruct);
54+
} catch (InteropException e) {
55+
throw CompilerDirectives.shouldNotReachHere(e);
7156
}
72-
} else {
73-
runFinalizer(ref);
7457
}
7558
return Nil.INSTANCE;
7659
}
7760

78-
private void runFinalizer(DataObjectFinalizerReference ref) throws Error {
79-
try {
80-
if (!getContext().isFinalizing()) {
81-
final ExtensionCallStack stack = getLanguage().getCurrentFiber().extensionCallStack;
82-
stack.push(false, stack.getSpecialVariables(), stack.getBlock());
83-
try {
84-
callNode.execute(ref.finalizerCFunction, ref.dataStruct);
85-
} finally {
86-
stack.pop();
87-
}
88-
}
89-
} catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) {
90-
throw CompilerDirectives.shouldNotReachHere("Data holder finalization on invalid object");
91-
}
92-
}
9361
}
9462

9563
private final CallTarget callTarget;
@@ -127,8 +95,7 @@ protected void processReference(RubyContext context, RubyLanguage language,
12795
}
12896

12997
@TruffleBoundary
130-
protected void processReferenceInternal(RubyContext context, RubyLanguage language,
131-
DataObjectFinalizerReference ref) {
132-
callTarget.call(new Object[]{ ref });
98+
void processReferenceInternal(RubyContext context, RubyLanguage language, DataObjectFinalizerReference ref) {
99+
callTarget.call(ref);
133100
}
134101
}

0 commit comments

Comments
 (0)