Skip to content

Commit 032dc13

Browse files
committed
[GR-54688] Implement gc.callbacks mechanism to make dask benchmark run
1 parent eeb4595 commit 032dc13

File tree

1 file changed

+59
-4
lines changed

1 file changed

+59
-4
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GcModuleBuiltins.java

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,41 @@
3636
import com.oracle.graal.python.builtins.objects.PNone;
3737
import com.oracle.graal.python.builtins.objects.cext.PythonNativeObject;
3838
import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions;
39+
import com.oracle.graal.python.builtins.objects.function.PKeyword;
3940
import com.oracle.graal.python.builtins.objects.list.PList;
41+
import com.oracle.graal.python.builtins.objects.module.PythonModule;
4042
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
43+
import com.oracle.graal.python.lib.PyIterNextNode;
44+
import com.oracle.graal.python.lib.PyObjectGetAttr;
45+
import com.oracle.graal.python.lib.PyObjectGetIter;
46+
import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode;
4147
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
4248
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
4349
import com.oracle.graal.python.runtime.GilNode;
4450
import com.oracle.graal.python.runtime.PythonContext;
4551
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
4652
import com.oracle.graal.python.util.PythonUtils;
4753
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
54+
import com.oracle.truffle.api.dsl.Bind;
4855
import com.oracle.truffle.api.dsl.Cached;
4956
import com.oracle.truffle.api.dsl.Fallback;
5057
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
5158
import com.oracle.truffle.api.dsl.NodeFactory;
5259
import com.oracle.truffle.api.dsl.Specialization;
60+
import com.oracle.truffle.api.frame.VirtualFrame;
61+
import com.oracle.truffle.api.nodes.Node;
62+
import com.oracle.truffle.api.strings.TruffleString;
5363

5464
@CoreFunctions(defineModule = "gc")
5565
public final class GcModuleBuiltins extends PythonBuiltins {
5666

67+
private static final TruffleString CALLBACKS = PythonUtils.tsLiteral("callbacks");
68+
private static final TruffleString START = PythonUtils.tsLiteral("start");
69+
private static final TruffleString STOP = PythonUtils.tsLiteral("stop");
70+
private static final TruffleString GENERATION = PythonUtils.tsLiteral("generation");
71+
private static final TruffleString COLLECTED = PythonUtils.tsLiteral("collected");
72+
private static final TruffleString UNCOLLECTABLE = PythonUtils.tsLiteral("uncollectable");
73+
5774
@Override
5875
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
5976
return GcModuleBuiltinsFactory.getFactories();
@@ -63,16 +80,54 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
6380
public void initialize(Python3Core core) {
6481
addBuiltinConstant("DEBUG_LEAK", 0);
6582
addBuiltinConstant("DEBUG_UNCOLLECTABLE", 0);
83+
addBuiltinConstant("DEBUG_UNCOLLECTABLE", 0);
84+
addBuiltinConstant(CALLBACKS, PythonObjectFactory.getUncached().createList());
6685
super.initialize(core);
6786
}
6887

69-
@Builtin(name = "collect", minNumOfPositionalArgs = 0, maxNumOfPositionalArgs = 1)
88+
@Builtin(name = "collect", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, declaresExplicitSelf = true)
7089
@GenerateNodeFactory
7190
abstract static class GcCollectNode extends PythonBuiltinNode {
7291
@Specialization
73-
@TruffleBoundary
74-
int collect(@SuppressWarnings("unused") Object level,
92+
static int collect(VirtualFrame frame, PythonModule self, @SuppressWarnings("unused") Object level,
93+
@Bind("this") Node inliningTarget,
94+
@Cached PyObjectGetAttr getAttr,
95+
@Cached PyObjectGetIter getIter,
96+
@Cached(neverDefault = true) PyIterNextNode next,
97+
@Cached PythonObjectFactory factory,
98+
@Cached CallBinaryMethodNode call,
7599
@Cached GilNode gil) {
100+
Object callbacks = getAttr.execute(frame, inliningTarget, self, CALLBACKS);
101+
Object iter = getIter.execute(frame, inliningTarget, callbacks);
102+
Object cb = next.execute(frame, iter);
103+
TruffleString phase = null;
104+
Object info = null;
105+
if (cb != null) {
106+
phase = START;
107+
info = factory.createDict(new PKeyword[]{
108+
new PKeyword(GENERATION, 2),
109+
new PKeyword(COLLECTED, 0),
110+
new PKeyword(UNCOLLECTABLE, 0),
111+
});
112+
do {
113+
call.executeObject(frame, cb, phase, info);
114+
} while ((cb = next.execute(frame, iter)) != null);
115+
}
116+
try {
117+
return javaCollect(inliningTarget, gil);
118+
} finally {
119+
if (phase != null) {
120+
phase = STOP;
121+
iter = getIter.execute(frame, inliningTarget, callbacks);
122+
while ((cb = next.execute(frame, iter)) != null) {
123+
call.executeObject(frame, cb, phase, info);
124+
}
125+
}
126+
}
127+
}
128+
129+
@TruffleBoundary
130+
static int javaCollect(Node inliningTarget, GilNode gil) {
76131
gil.release(true);
77132
try {
78133
PythonUtils.forceFullGC();
@@ -85,7 +140,7 @@ int collect(@SuppressWarnings("unused") Object level,
85140
gil.acquire();
86141
}
87142
// collect some weak references now
88-
PythonContext.triggerAsyncActions(this);
143+
PythonContext.triggerAsyncActions(inliningTarget);
89144
CApiTransitions.pollReferenceQueue();
90145
return 0;
91146
}

0 commit comments

Comments
 (0)