133
133
import com .oracle .graal .python .builtins .objects .common .HashingStorageNodes .HashingStorageIteratorKeyHash ;
134
134
import com .oracle .graal .python .builtins .objects .common .HashingStorageNodes .HashingStorageIteratorNext ;
135
135
import com .oracle .graal .python .builtins .objects .common .HashingStorageNodes .HashingStorageIteratorValue ;
136
- import com .oracle .graal .python .builtins .objects .common .HashingStorageNodes .HashingStorageLen ;
137
136
import com .oracle .graal .python .builtins .objects .common .HashingStorageNodes .HashingStorageSetItemWithHash ;
138
- import com .oracle .graal .python .builtins .objects .common .HashingStorageNodesFactory .HashingStorageSetItemWithHashNodeGen ;
139
137
import com .oracle .graal .python .builtins .objects .common .SequenceNodes .GetObjectArrayNode ;
140
138
import com .oracle .graal .python .builtins .objects .common .SequenceStorageNodes ;
141
139
import com .oracle .graal .python .builtins .objects .common .SequenceStorageNodes .GetInternalObjectArrayNode ;
155
153
import com .oracle .graal .python .builtins .objects .object .ObjectBuiltins ;
156
154
import com .oracle .graal .python .builtins .objects .object .ObjectBuiltinsFactory ;
157
155
import com .oracle .graal .python .builtins .objects .object .PythonObject ;
156
+ import com .oracle .graal .python .builtins .objects .referencetype .PReferenceType ;
158
157
import com .oracle .graal .python .builtins .objects .str .StringBuiltins .IsIdentifierNode ;
159
158
import com .oracle .graal .python .builtins .objects .str .StringUtils ;
160
159
import com .oracle .graal .python .builtins .objects .superobject .SuperObject ;
@@ -806,31 +805,51 @@ static TruffleString getQualName(Node inliningTarget, PythonAbstractNativeObject
806
805
}
807
806
808
807
@ GenerateUncached
809
- @ GenerateInline
810
808
@ GenerateCached (false )
811
809
public abstract static class GetSubclassesNode extends PNodeWithContext {
812
-
813
- public abstract PDict execute (Node inliningTarget , Object clazz );
810
+ abstract PDict execute (Node inliningTarget , Object clazz );
814
811
815
812
public static PDict executeUncached (Object clazz ) {
816
813
return GetSubclassesNodeGen .getUncached ().execute (null , clazz );
817
814
}
818
815
819
- protected static void unsafeAddSubclass ( Object base , Object subclass ) {
820
- long hash = ObjectBuiltins . HashNode . hash ( subclass );
816
+ protected static void addSubclass ( PythonAbstractClass base , PythonManagedClass subclass ) {
817
+ CompilerAsserts . neverPartOfCompilation ( );
821
818
PDict dict = executeUncached (base );
822
819
HashingStorage storage = dict .getDictStorage ();
823
- HashingStorageSetItemWithHash setItem = HashingStorageSetItemWithHashNodeGen .getUncached ();
824
- storage = setItem .execute (null , null , storage , subclass , hash , subclass );
820
+ Object weakref = PFactory .createReferenceType (PythonLanguage .get (null ), subclass );
821
+ if (!(storage instanceof EconomicMapStorage )) {
822
+ assert storage == EmptyStorage .INSTANCE : "Unexpected storage type!" ;
823
+ storage = EconomicMapStorage .create ();
824
+ }
825
+ ((EconomicMapStorage ) storage ).putUncached (weakref , weakref );
825
826
dict .setDictStorage (storage );
826
827
}
827
828
828
- protected static void unsafeRemoveSubclass (Object base , Object subclass ) {
829
- long hash = ObjectBuiltins .HashNode .hash (subclass );
829
+ static final class RemoveSubclassValue extends HashingStorageForEachCallback <PythonManagedClass > {
830
+ @ Override
831
+ public final PythonManagedClass execute (Frame frame , Node inliningTarget , HashingStorage storage , HashingStorageIterator it , PythonManagedClass toRemove ) {
832
+ if (toRemove == null ) {
833
+ return null ;
834
+ }
835
+ Object value = HashingStorageIteratorValue .executeUncached (storage , it );
836
+ if (value instanceof PReferenceType pref ) {
837
+ Object subclassValue = pref .getObject ();
838
+ if (subclassValue == toRemove ) {
839
+ pref .clearRef ();
840
+ return null ;
841
+ }
842
+ }
843
+ return toRemove ;
844
+ }
845
+ }
846
+
847
+ protected static void removeSubclass (PythonAbstractClass base , PythonManagedClass subclass ) {
848
+ CompilerAsserts .neverPartOfCompilation ();
830
849
PDict dict = executeUncached (base );
831
850
HashingStorage storage = dict .getDictStorage ();
832
- if (storage instanceof EconomicMapStorage ems ) {
833
- HashingStorageDelItem . executeUncachedWithHash ( ems , subclass , hash );
851
+ if (storage instanceof EconomicMapStorage ) {
852
+ HashingStorageForEach . executeUncached ( storage , new RemoveSubclassValue (), subclass );
834
853
} else {
835
854
assert storage == EmptyStorage .INSTANCE : "Unexpected storage type!" ;
836
855
}
@@ -842,30 +861,26 @@ static PDict doPythonClass(PythonManagedClass obj) {
842
861
}
843
862
844
863
@ Specialization
845
- static PDict doPythonClass (Node inliningTarget , PythonBuiltinClassType obj ) {
846
- return PythonContext .get (inliningTarget ).lookupType (obj ).getSubClasses ();
864
+ static PDict doPythonClass (PythonBuiltinClassType obj ) {
865
+ return PythonContext .get (null ).lookupType (obj ).getSubClasses ();
847
866
}
848
867
849
868
@ Specialization
850
- static PDict doNativeClass (Node inliningTarget , PythonAbstractNativeObject obj ,
851
- @ Cached (inline = false ) CStructAccess .ReadObjectNode getTpSubclassesNode ,
852
- @ Cached InlinedExactClassProfile profile ) {
869
+ static PDict doNativeClass (PythonAbstractNativeObject obj ,
870
+ @ Cached (inline = false ) CStructAccess .ReadObjectNode getTpSubclassesNode ) {
853
871
Object tpSubclasses = getTpSubclassesNode .readFromObj (obj , PyTypeObject__tp_subclasses );
854
-
855
- Object profiled = profile .profile (inliningTarget , tpSubclasses );
872
+ Object profiled = tpSubclasses ;
856
873
if (profiled instanceof PDict dict ) {
857
874
return dict ;
858
875
}
859
- CompilerDirectives .transferToInterpreterAndInvalidate ();
860
- throw new IllegalStateException ("invalid subclasses dict " + profiled .getClass ().getName ());
876
+ throw CompilerDirectives .shouldNotReachHere ("invalid subclasses dict " + profiled .getClass ().getName ());
861
877
}
862
878
}
863
879
864
880
@ GenerateUncached
865
- @ GenerateInline (true )
866
- @ GenerateCached (true )
881
+ @ GenerateInline (false )
882
+ @ GenerateCached (false )
867
883
public abstract static class GetSubclassesAsArrayNode extends Node {
868
-
869
884
private static final PythonAbstractClass [] EMPTY = new PythonAbstractClass [0 ];
870
885
871
886
abstract PythonAbstractClass [] execute (Node inliningTarget , Object clazz );
@@ -874,43 +889,29 @@ public static PythonAbstractClass[] executeUncached(Object clazz) {
874
889
return GetSubclassesAsArrayNodeGen .getUncached ().execute (null , clazz );
875
890
}
876
891
877
- static final class PythonAbstractClassList {
878
- final PythonAbstractClass [] subclasses ;
879
- int i ;
880
-
881
- PythonAbstractClassList (PythonAbstractClass [] subclasses ) {
882
- this .subclasses = subclasses ;
883
- this .i = 0 ;
884
- }
885
-
886
- void add (PythonAbstractClass clazz ) {
887
- subclasses [i ++] = clazz ;
888
- }
889
- }
890
-
891
892
@ GenerateUncached
892
- @ GenerateInline (true )
893
- abstract static class EachSubclassAdd extends HashingStorageForEachCallback <PythonAbstractClassList > {
894
-
893
+ @ GenerateCached (false )
894
+ abstract static class EachSubclassAdd extends HashingStorageForEachCallback <ArrayList <PythonAbstractClass >> {
895
895
@ Override
896
- public abstract PythonAbstractClassList execute (Frame frame , Node inliningTarget , HashingStorage storage , HashingStorageIterator it , PythonAbstractClassList subclasses );
896
+ public abstract ArrayList < PythonAbstractClass > execute (Frame frame , Node inliningTarget , HashingStorage storage , HashingStorageIterator it , ArrayList < PythonAbstractClass > subclasses );
897
897
898
898
@ Specialization
899
- static PythonAbstractClassList doIt (Node inliningTarget , HashingStorage storage , HashingStorageIterator it , PythonAbstractClassList subclasses ,
899
+ static ArrayList < PythonAbstractClass > doIt (Node inliningTarget , HashingStorage storage , HashingStorageIterator it , ArrayList < PythonAbstractClass > subclasses ,
900
900
@ Cached HashingStorageIteratorValue itValue ) {
901
901
Object value = itValue .execute (inliningTarget , storage , it );
902
- subclasses .add (PythonAbstractClass .cast (value ));
902
+ PythonAbstractClass clazz = PythonAbstractClass .cast (((PReferenceType ) value ).getObject ());
903
+ if (clazz != null ) {
904
+ subclasses .add (clazz );
905
+ }
903
906
return subclasses ;
904
907
}
905
908
}
906
909
907
910
@ Specialization
908
- static PythonAbstractClass [] doTpSubclasses (Node inliningTarget , Object object ,
909
- @ Cached GetSubclassesNode getSubclassesNode ,
911
+ static PythonAbstractClass [] doTpSubclasses (PythonAbstractClass object ,
910
912
@ Cached EachSubclassAdd eachNode ,
911
- @ Cached HashingStorageLen dictLen ,
912
913
@ Cached HashingStorageForEach forEachNode ) {
913
- PDict subclasses = getSubclassesNode . execute ( inliningTarget , object );
914
+ PDict subclasses = GetSubclassesNode . executeUncached ( object );
914
915
if (subclasses == null ) {
915
916
return EMPTY ;
916
917
}
@@ -920,10 +921,9 @@ static PythonAbstractClass[] doTpSubclasses(Node inliningTarget, Object object,
920
921
return EMPTY ;
921
922
}
922
923
923
- int size = dictLen .execute (inliningTarget , storage );
924
- PythonAbstractClassList list = new PythonAbstractClassList (new PythonAbstractClass [size ]);
925
- forEachNode .execute (null , inliningTarget , storage , eachNode , list );
926
- return list .subclasses ;
924
+ ArrayList <PythonAbstractClass > list = new ArrayList <>();
925
+ forEachNode .execute (null , null , storage , eachNode , list );
926
+ return list .toArray (EMPTY );
927
927
}
928
928
}
929
929
0 commit comments