@@ -2786,7 +2786,7 @@ static EmptySequenceStorage doEmpty(EmptySequenceStorage s, @SuppressWarnings("u
2786
2786
2787
2787
@ Specialization (limit = "MAX_BASIC_STORAGES" , guards = "s.getClass() == cachedClass" )
2788
2788
static BasicSequenceStorage doManaged (Node inliningTarget , BasicSequenceStorage s , int cap ,
2789
- @ Shared @ Cached PRaiseNode .Lazy raiseNode ,
2789
+ @ Cached PRaiseNode .Lazy raiseNode ,
2790
2790
@ Cached ("s.getClass()" ) Class <? extends BasicSequenceStorage > cachedClass ) {
2791
2791
try {
2792
2792
BasicSequenceStorage profiled = cachedClass .cast (s );
@@ -2799,37 +2799,82 @@ static BasicSequenceStorage doManaged(Node inliningTarget, BasicSequenceStorage
2799
2799
2800
2800
@ Specialization
2801
2801
@ InliningCutoff
2802
- static NativeSequenceStorage doNativeByte (Node inliningTarget , NativeSequenceStorage s , int cap ,
2803
- @ CachedLibrary (limit = "1" ) InteropLibrary lib ,
2804
- @ Cached (inline = false ) CStructAccess .AllocateNode alloc ,
2805
- @ Cached (inline = false ) CStructAccess .ReadByteNode read ,
2806
- @ Cached (inline = false ) CStructAccess .WriteByteNode write ,
2807
- @ Cached (inline = false ) CStructAccess .FreeNode free ,
2808
- @ Shared @ Cached PRaiseNode .Lazy raiseNode ) {
2809
- int capacity = s .getCapacity ();
2810
- if (cap > capacity ) {
2802
+ static NativeSequenceStorage doNative (NativeSequenceStorage s , int cap ,
2803
+ @ Cached (inline = false ) EnsureCapacityNativeNode helper ) {
2804
+ return helper .execute (s , cap );
2805
+ }
2806
+
2807
+ @ GenerateInline (false )
2808
+ @ GenerateUncached
2809
+ abstract static class EnsureCapacityNativeNode extends Node {
2810
+ abstract NativeSequenceStorage execute (NativeSequenceStorage s , int cap );
2811
+
2812
+ @ Specialization
2813
+ static NativeByteSequenceStorage doNativeByte (NativeByteSequenceStorage s , int cap ,
2814
+ @ Bind ("this" ) Node inliningTarget ,
2815
+ @ Shared @ CachedLibrary (limit = "2" ) InteropLibrary lib ,
2816
+ @ Shared @ Cached CStructAccess .AllocateNode alloc ,
2817
+ @ Shared @ Cached CStructAccess .FreeNode free ,
2818
+ @ Shared @ Cached PRaiseNode .Lazy raiseNode ,
2819
+ @ Cached CStructAccess .ReadByteNode read ,
2820
+ @ Cached CStructAccess .WriteByteNode write ) {
2821
+ int oldCapacity = s .getCapacity ();
2822
+ if (cap > oldCapacity ) {
2823
+ int newCapacity = computeNewCapacity (cap );
2824
+ Object oldMem = s .getPtr ();
2825
+ Object newMem = alloc .alloc (newCapacity );
2826
+ if (lib .isNull (newMem )) {
2827
+ throw raiseNode .get (inliningTarget ).raise (MemoryError );
2828
+ }
2829
+ // TODO: turn this into a memcpy
2830
+ for (long i = 0 ; i < oldCapacity ; i ++) {
2831
+ write .writeArrayElement (newMem , i , read .readArrayElement (oldMem , i ));
2832
+ }
2833
+ free .free (oldMem );
2834
+ s .setPtr (newMem );
2835
+ s .setCapacity (newCapacity );
2836
+ }
2837
+ return s ;
2838
+ }
2839
+
2840
+ @ Specialization
2841
+ static NativeObjectSequenceStorage doNativeObject (NativeObjectSequenceStorage s , int cap ,
2842
+ @ Bind ("this" ) Node inliningTarget ,
2843
+ @ Shared @ CachedLibrary (limit = "2" ) InteropLibrary lib ,
2844
+ @ Shared @ Cached CStructAccess .AllocateNode alloc ,
2845
+ @ Shared @ Cached CStructAccess .FreeNode free ,
2846
+ @ Shared @ Cached PRaiseNode .Lazy raiseNode ,
2847
+ @ Cached CStructAccess .ReadPointerNode read ,
2848
+ @ Cached CStructAccess .WritePointerNode write ) {
2849
+ int oldCapacity = s .getCapacity ();
2850
+ if (cap > oldCapacity ) {
2851
+ int newCapacity = computeNewCapacity (cap );
2852
+ Object oldMem = s .getPtr ();
2853
+ long bytes = newCapacity * 8 ;
2854
+ Object newMem = alloc .alloc (bytes );
2855
+ if (lib .isNull (newMem )) {
2856
+ throw raiseNode .get (inliningTarget ).raise (MemoryError );
2857
+ }
2858
+ // TODO: turn this into a memcpy
2859
+ for (long i = 0 ; i < oldCapacity ; i ++) {
2860
+ write .writeArrayElement (newMem , i , read .readArrayElement (oldMem , i ));
2861
+ }
2862
+ free .free (oldMem );
2863
+ s .setPtr (newMem );
2864
+ s .setCapacity (newCapacity );
2865
+ }
2866
+ return s ;
2867
+ }
2868
+
2869
+ private static int computeNewCapacity (int cap ) {
2811
2870
int newCapacity ;
2812
2871
try {
2813
2872
newCapacity = Math .max (16 , PythonUtils .multiplyExact (cap , 2 ));
2814
2873
} catch (OverflowException e ) {
2815
2874
newCapacity = cap ;
2816
2875
}
2817
- Object mem = s .getPtr ();
2818
- long elementSize = s instanceof NativeByteSequenceStorage ? 1 : CStructAccess .POINTER_SIZE ;
2819
- long bytes = elementSize * newCapacity ;
2820
- Object newMem = alloc .alloc (bytes );
2821
- if (lib .isNull (newMem )) {
2822
- throw raiseNode .get (inliningTarget ).raise (MemoryError );
2823
- }
2824
- // TODO: turn this into a memcpy
2825
- for (long i = 0 ; i < capacity * elementSize ; i ++) {
2826
- write .writeArrayElement (newMem , i , read .readArrayElement (mem , i ));
2827
- }
2828
- free .free (mem );
2829
- s .setPtr (newMem );
2830
- s .setCapacity (newCapacity );
2876
+ return newCapacity ;
2831
2877
}
2832
- return s ;
2833
2878
}
2834
2879
}
2835
2880
0 commit comments