36
36
import com .oracle .graal .python .builtins .objects .PNone ;
37
37
import com .oracle .graal .python .builtins .objects .cext .PythonNativeObject ;
38
38
import com .oracle .graal .python .builtins .objects .cext .capi .transitions .CApiTransitions ;
39
+ import com .oracle .graal .python .builtins .objects .function .PKeyword ;
39
40
import com .oracle .graal .python .builtins .objects .list .PList ;
41
+ import com .oracle .graal .python .builtins .objects .module .PythonModule ;
40
42
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 ;
41
47
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
42
48
import com .oracle .graal .python .nodes .function .PythonBuiltinNode ;
43
49
import com .oracle .graal .python .runtime .GilNode ;
44
50
import com .oracle .graal .python .runtime .PythonContext ;
45
51
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
46
52
import com .oracle .graal .python .util .PythonUtils ;
47
53
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
54
+ import com .oracle .truffle .api .dsl .Bind ;
48
55
import com .oracle .truffle .api .dsl .Cached ;
49
56
import com .oracle .truffle .api .dsl .Fallback ;
50
57
import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
51
58
import com .oracle .truffle .api .dsl .NodeFactory ;
52
59
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 ;
53
63
54
64
@ CoreFunctions (defineModule = "gc" )
55
65
public final class GcModuleBuiltins extends PythonBuiltins {
56
66
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
+
57
74
@ Override
58
75
protected List <? extends NodeFactory <? extends PythonBuiltinBaseNode >> getNodeFactories () {
59
76
return GcModuleBuiltinsFactory .getFactories ();
@@ -63,16 +80,54 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
63
80
public void initialize (Python3Core core ) {
64
81
addBuiltinConstant ("DEBUG_LEAK" , 0 );
65
82
addBuiltinConstant ("DEBUG_UNCOLLECTABLE" , 0 );
83
+ addBuiltinConstant ("DEBUG_UNCOLLECTABLE" , 0 );
84
+ addBuiltinConstant (CALLBACKS , PythonObjectFactory .getUncached ().createList ());
66
85
super .initialize (core );
67
86
}
68
87
69
- @ Builtin (name = "collect" , minNumOfPositionalArgs = 0 , maxNumOfPositionalArgs = 1 )
88
+ @ Builtin (name = "collect" , minNumOfPositionalArgs = 1 , maxNumOfPositionalArgs = 2 , declaresExplicitSelf = true )
70
89
@ GenerateNodeFactory
71
90
abstract static class GcCollectNode extends PythonBuiltinNode {
72
91
@ 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 ,
75
99
@ 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 ) {
76
131
gil .release (true );
77
132
try {
78
133
PythonUtils .forceFullGC ();
@@ -85,7 +140,7 @@ int collect(@SuppressWarnings("unused") Object level,
85
140
gil .acquire ();
86
141
}
87
142
// collect some weak references now
88
- PythonContext .triggerAsyncActions (this );
143
+ PythonContext .triggerAsyncActions (inliningTarget );
89
144
CApiTransitions .pollReferenceQueue ();
90
145
return 0 ;
91
146
}
0 commit comments