4040 */
4141package com .oracle .graal .python .nodes .object ;
4242
43- import com .oracle .graal .python .PythonLanguage ;
4443import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
4544import com .oracle .graal .python .builtins .objects .object .PythonObject ;
4645import com .oracle .graal .python .builtins .objects .type .LazyPythonClass ;
4746import com .oracle .graal .python .builtins .objects .type .PythonAbstractClass ;
4847import com .oracle .graal .python .builtins .objects .type .PythonBuiltinClass ;
4948import com .oracle .graal .python .runtime .exception .PException ;
50- import com .oracle .truffle .api .Assumption ;
5149import com .oracle .truffle .api .CompilerDirectives ;
5250import 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 ;
5651
5752public final class IsBuiltinClassProfile {
5853 @ CompilationFinal private boolean isBuiltinType ;
@@ -62,101 +57,34 @@ public final class IsBuiltinClassProfile {
6257 @ CompilationFinal private boolean match ;
6358 @ CompilationFinal private boolean noMatch ;
6459
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 ();
9161
9262 /* private constructor */
93- private IsBuiltinClassProfile (Assumption singleContextAssumption ) {
94- this .singleContextAssumption = singleContextAssumption ;
63+ private IsBuiltinClassProfile () {
9564 }
9665
9766 public static IsBuiltinClassProfile create () {
98- return new IsBuiltinClassProfile (PythonLanguage . getCurrent (). singleContextAssumption );
67+ return new IsBuiltinClassProfile ();
9968 }
10069
10170 public static IsBuiltinClassProfile getUncached () {
10271 return UNCACHED ;
10372 }
10473
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-
14674 public boolean profileIsAnyBuiltinObject (PythonObject object ) {
147- return profileIsAnyBuiltinClass (getLazyPythonClass (object ));
75+ return profileIsAnyBuiltinClass (object . getLazyPythonClass ());
14876 }
14977
15078 public boolean profileIsOtherBuiltinObject (PythonObject object , PythonBuiltinClassType type ) {
151- return profileIsOtherBuiltinClass (getLazyPythonClass (object ), type );
79+ return profileIsOtherBuiltinClass (object . getLazyPythonClass (), type );
15280 }
15381
15482 public boolean profileException (PException object , PythonBuiltinClassType type ) {
155- return profileClass (getLazyPythonClass ( object .getExceptionObject ()), type );
83+ return profileClass (object .getExceptionObject (). getLazyPythonClass ( ), type );
15684 }
15785
15886 public boolean profileObject (PythonObject object , PythonBuiltinClassType type ) {
159- return profileClass (getLazyPythonClass (object ), type );
87+ return profileClass (object . getLazyPythonClass (), type );
16088
16189 }
16290
0 commit comments