@@ -2786,7 +2786,7 @@ static EmptySequenceStorage doEmpty(EmptySequenceStorage s, @SuppressWarnings("u
27862786
27872787 @ Specialization (limit = "MAX_BASIC_STORAGES" , guards = "s.getClass() == cachedClass" )
27882788 static BasicSequenceStorage doManaged (Node inliningTarget , BasicSequenceStorage s , int cap ,
2789- @ Shared @ Cached PRaiseNode .Lazy raiseNode ,
2789+ @ Cached PRaiseNode .Lazy raiseNode ,
27902790 @ Cached ("s.getClass()" ) Class <? extends BasicSequenceStorage > cachedClass ) {
27912791 try {
27922792 BasicSequenceStorage profiled = cachedClass .cast (s );
@@ -2799,37 +2799,82 @@ static BasicSequenceStorage doManaged(Node inliningTarget, BasicSequenceStorage
27992799
28002800 @ Specialization
28012801 @ 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 ) {
28112870 int newCapacity ;
28122871 try {
28132872 newCapacity = Math .max (16 , PythonUtils .multiplyExact (cap , 2 ));
28142873 } catch (OverflowException e ) {
28152874 newCapacity = cap ;
28162875 }
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 ;
28312877 }
2832- return s ;
28332878 }
28342879 }
28352880
0 commit comments