40
40
*/
41
41
package com .oracle .graal .python .nodes .object ;
42
42
43
- import com .oracle .graal .python .PythonLanguage ;
44
43
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
45
44
import com .oracle .graal .python .builtins .objects .object .PythonObject ;
46
45
import com .oracle .graal .python .builtins .objects .type .LazyPythonClass ;
47
46
import com .oracle .graal .python .builtins .objects .type .PythonAbstractClass ;
48
47
import com .oracle .graal .python .builtins .objects .type .PythonBuiltinClass ;
49
48
import com .oracle .graal .python .runtime .exception .PException ;
50
- import com .oracle .truffle .api .Assumption ;
51
49
import com .oracle .truffle .api .CompilerDirectives ;
52
50
import com .oracle .truffle .api .CompilerDirectives .CompilationFinal ;
53
- import com .oracle .truffle .api .nodes .ExplodeLoop ;
54
- import com .oracle .truffle .api .nodes .ExplodeLoop .LoopExplosionKind ;
55
- import com .oracle .truffle .api .object .Shape ;
56
51
57
52
public final class IsBuiltinClassProfile {
58
53
@ CompilationFinal private boolean isBuiltinType ;
@@ -62,101 +57,34 @@ public final class IsBuiltinClassProfile {
62
57
@ CompilationFinal private boolean match ;
63
58
@ CompilationFinal private boolean noMatch ;
64
59
65
- // n.b.: (tfel) We store the python class as a Shape property on the
66
- // DynamicObject representing the Python-level object. Thus, accessing the
67
- // python class incurs an indirection that we'd like to avoid if
68
- // possible. We use this cache to avoid the indirection. In the single
69
- // context case, we just cache all classes, in the multi-context case, we
70
- // only cache classes if they are builtin types that are shared across
71
- // contexts.
72
- private final Assumption singleContextAssumption ;
73
- private static final int CLASS_CACHE_SIZE = 3 ;
74
- @ CompilationFinal (dimensions = 1 ) private ClassCache [] classCache = new ClassCache [CLASS_CACHE_SIZE ];
75
- @ CompilationFinal private boolean cacheUsedInSingleContext = false ;
76
-
77
- private static final class ClassCache {
78
- private final LazyPythonClass klass ;
79
- private final Shape shape ;
80
-
81
- ClassCache (Shape shape , LazyPythonClass klass ) {
82
- this .shape = shape ;
83
- this .klass = klass ;
84
- }
85
- }
86
-
87
- private static final IsBuiltinClassProfile UNCACHED = new IsBuiltinClassProfile (null );
88
- static {
89
- UNCACHED .classCache = null ;
90
- }
60
+ private static final IsBuiltinClassProfile UNCACHED = new IsBuiltinClassProfile ();
91
61
92
62
/* private constructor */
93
- private IsBuiltinClassProfile (Assumption singleContextAssumption ) {
94
- this .singleContextAssumption = singleContextAssumption ;
63
+ private IsBuiltinClassProfile () {
95
64
}
96
65
97
66
public static IsBuiltinClassProfile create () {
98
- return new IsBuiltinClassProfile (PythonLanguage . getCurrent (). singleContextAssumption );
67
+ return new IsBuiltinClassProfile ();
99
68
}
100
69
101
70
public static IsBuiltinClassProfile getUncached () {
102
71
return UNCACHED ;
103
72
}
104
73
105
- @ ExplodeLoop (kind = LoopExplosionKind .FULL_EXPLODE_UNTIL_RETURN )
106
- private LazyPythonClass getLazyPythonClass (PythonObject object ) {
107
- if (classCache != null ) {
108
- // we're still caching
109
- if (!(singleContextAssumption != null && singleContextAssumption .isValid ()) && cacheUsedInSingleContext ) {
110
- // we previously used this cache in a single context, now we're
111
- // in a multi-context mode. Reset the cache.
112
- CompilerDirectives .transferToInterpreterAndInvalidate ();
113
- cacheUsedInSingleContext = false ;
114
- classCache = new ClassCache [CLASS_CACHE_SIZE ];
115
- }
116
- for (int i = 0 ; i < classCache .length ; i ++) {
117
- ClassCache cache = classCache [i ];
118
- if (cache == null ) {
119
- CompilerDirectives .transferToInterpreterAndInvalidate ();
120
- Shape shape = object .getStorage ().getShape ();
121
- LazyPythonClass klass = PythonObject .getLazyPythonClass (shape .getObjectType ());
122
- if (klass instanceof PythonBuiltinClassType ) {
123
- classCache [i ] = new ClassCache (shape , klass );
124
- } else if (singleContextAssumption != null && singleContextAssumption .isValid ()) {
125
- // we're caching a non-builtin type, so if we switch to
126
- // a multi-context, the cache needs to be flushed.
127
- cacheUsedInSingleContext = true ;
128
- classCache [i ] = new ClassCache (shape , klass );
129
- } else {
130
- classCache = null ;
131
- }
132
- return klass ;
133
- } else if (cache .shape == object .getStorage ().getShape ()) {
134
- return cache .klass ;
135
- }
136
- }
137
- }
138
- if (classCache != null ) {
139
- // cache overflow, revert to generic access
140
- CompilerDirectives .transferToInterpreterAndInvalidate ();
141
- classCache = null ;
142
- }
143
- return object .getLazyPythonClass ();
144
- }
145
-
146
74
public boolean profileIsAnyBuiltinObject (PythonObject object ) {
147
- return profileIsAnyBuiltinClass (getLazyPythonClass (object ));
75
+ return profileIsAnyBuiltinClass (object . getLazyPythonClass ());
148
76
}
149
77
150
78
public boolean profileIsOtherBuiltinObject (PythonObject object , PythonBuiltinClassType type ) {
151
- return profileIsOtherBuiltinClass (getLazyPythonClass (object ), type );
79
+ return profileIsOtherBuiltinClass (object . getLazyPythonClass (), type );
152
80
}
153
81
154
82
public boolean profileException (PException object , PythonBuiltinClassType type ) {
155
- return profileClass (getLazyPythonClass ( object .getExceptionObject ()), type );
83
+ return profileClass (object .getExceptionObject (). getLazyPythonClass ( ), type );
156
84
}
157
85
158
86
public boolean profileObject (PythonObject object , PythonBuiltinClassType type ) {
159
- return profileClass (getLazyPythonClass (object ), type );
87
+ return profileClass (object . getLazyPythonClass (), type );
160
88
161
89
}
162
90
0 commit comments