@@ -6395,33 +6395,35 @@ abstract static class InternalSwitchEncodingNode extends AbstractInternalNode {
6395
6395
6396
6396
abstract TruffleString execute (Node node , AbstractTruffleString a , Encoding targetEncoding , TranscodingErrorHandler errorHandler );
6397
6397
6398
- @ Specialization (guards = "a.isCompatibleToIntl(targetEncoding)" )
6399
- static TruffleString compatibleImmutable (TruffleString a , @ SuppressWarnings ("unused" ) Encoding targetEncoding , @ SuppressWarnings ("unused" ) TranscodingErrorHandler errorHandler ) {
6400
- assert !a .isJavaString ();
6401
- return a ;
6402
- }
6403
-
6404
- @ Specialization (guards = "a.isCompatibleToIntl(targetEncoding)" )
6405
- static TruffleString compatibleMutable (Node node , MutableTruffleString a , Encoding targetEncoding , @ SuppressWarnings ("unused" ) TranscodingErrorHandler errorHandler ,
6406
- @ Cached InternalAsTruffleStringNode asTruffleStringNode ) {
6407
- return asTruffleStringNode .execute (node , a , targetEncoding );
6408
- }
6409
-
6410
- @ Specialization (guards = "!a.isCompatibleToIntl(targetEncoding)" )
6411
- static TruffleString transCode (Node node , TruffleString a , Encoding targetEncoding , TranscodingErrorHandler errorHandler ,
6398
+ @ Specialization
6399
+ static TruffleString immutable (Node node , TruffleString a , Encoding targetEncoding , TranscodingErrorHandler errorHandler ,
6412
6400
@ Cached @ Shared TStringInternalNodes .GetPreciseCodeRangeNode getPreciseCodeRangeNode ,
6413
- @ Cached InlinedConditionProfile preciseCodeRangeIsCompatibleProfile ,
6401
+ @ Cached InlinedConditionProfile isCompatibleProfile ,
6402
+ @ Cached InlinedConditionProfile noOpProfile ,
6403
+ @ Cached InlinedConditionProfile mustCompactProfile ,
6404
+ @ Cached InlinedConditionProfile compact10Profile ,
6405
+ @ Cached InlinedConditionProfile compact20Profile ,
6414
6406
@ Exclusive @ Cached InlinedConditionProfile cacheHit ,
6415
6407
@ Cached ToIndexableNode toIndexableNode ,
6416
6408
@ Cached @ Shared TStringInternalNodes .TransCodeNode transCodeNode ) {
6417
- if (a .isEmpty ()) {
6418
- return targetEncoding .getEmpty ();
6409
+ final boolean isCompatible ;
6410
+ final int preciseCodeRangeA ;
6411
+ if (isCompatibleProfile .profile (node , a .isCompatibleToIntl (targetEncoding ))) {
6412
+ isCompatible = true ;
6413
+ preciseCodeRangeA = a .codeRange ();
6414
+ } else {
6415
+ Encoding encodingA = Encoding .get (a .encoding ());
6416
+ preciseCodeRangeA = getPreciseCodeRangeNode .execute (node , a , encodingA );
6417
+ isCompatible = a .isCodeRangeCompatibleTo (preciseCodeRangeA , targetEncoding );
6419
6418
}
6420
- Encoding encodingA = Encoding . get ( a . encoding ()) ;
6421
- int preciseCodeRangeA = getPreciseCodeRangeNode . execute (node , a , encodingA );
6422
- if ( preciseCodeRangeIsCompatibleProfile . profile ( node , a . isCodeRangeCompatibleTo ( preciseCodeRangeA , targetEncoding ))) {
6419
+ final boolean mustCompact = a . stride () > targetEncoding . naturalStride ;
6420
+ if ( noOpProfile . profile (node , isCompatible && ! mustCompact )) {
6421
+ assert ! a . isJavaString ();
6423
6422
return a ;
6424
6423
}
6424
+ if (a .isEmpty ()) {
6425
+ return targetEncoding .getEmpty ();
6426
+ }
6425
6427
TruffleString cur = a .next ;
6426
6428
assert !a .isJavaString ();
6427
6429
if (cur != null ) {
@@ -6433,13 +6435,40 @@ static TruffleString transCode(Node node, TruffleString a, Encoding targetEncodi
6433
6435
return cur ;
6434
6436
}
6435
6437
}
6436
- TruffleString transCoded = transCodeNode .execute (node , a , toIndexableNode .execute (node , a , a .data ()), a .codePointLength (), preciseCodeRangeA , targetEncoding , errorHandler );
6438
+ final TruffleString transCoded ;
6439
+ if (mustCompactProfile .profile (node , isCompatible && mustCompact )) {
6440
+ final Object arrayA = a .data ();
6441
+ assert arrayA instanceof NativePointer ;
6442
+ final int offsetA = a .offset ();
6443
+ final int strideA = a .stride ();
6444
+ final int offset = 0 ;
6445
+ final int lengthA = a .length ();
6446
+ final int stride = Stride .fromCodeRangeUTF16 (preciseCodeRangeA );
6447
+ final byte [] array = new byte [lengthA << stride ];
6448
+ if (compact10Profile .profile (node , strideA == 1 && stride == 0 )) {
6449
+ TStringOps .arraycopyWithStride (node , arrayA , offsetA , 1 , 0 , array , offset , 0 , 0 , lengthA );
6450
+ } else if (compact20Profile .profile (node , strideA == 2 && stride == 0 )) {
6451
+ TStringOps .arraycopyWithStride (node , arrayA , offsetA , 2 , 0 , array , offset , 0 , 0 , lengthA );
6452
+ } else {
6453
+ assert strideA == 2 && stride == 1 ;
6454
+ TStringOps .arraycopyWithStride (node , arrayA , offsetA , 2 , 0 , array , offset , 1 , 0 , lengthA );
6455
+ }
6456
+ transCoded = TruffleString .createFromArray (array , offset , lengthA , stride , targetEncoding , a .codePointLength (), preciseCodeRangeA , false );
6457
+ } else {
6458
+ transCoded = transCodeNode .execute (node , a , toIndexableNode .execute (node , a , a .data ()), a .codePointLength (), preciseCodeRangeA , targetEncoding , errorHandler );
6459
+ }
6437
6460
if (!transCoded .isCacheHead ()) {
6438
6461
a .cacheInsert (transCoded );
6439
6462
}
6440
6463
return transCoded ;
6441
6464
}
6442
6465
6466
+ @ Specialization (guards = "a.isCompatibleToIntl(targetEncoding)" )
6467
+ static TruffleString compatibleMutable (Node node , MutableTruffleString a , Encoding targetEncoding , @ SuppressWarnings ("unused" ) TranscodingErrorHandler errorHandler ,
6468
+ @ Cached InternalAsTruffleStringNode asTruffleStringNode ) {
6469
+ return asTruffleStringNode .execute (node , a , targetEncoding );
6470
+ }
6471
+
6443
6472
@ Specialization (guards = "!a.isCompatibleToIntl(targetEncoding)" )
6444
6473
static TruffleString transCodeMutable (Node node , MutableTruffleString a , Encoding targetEncoding , TranscodingErrorHandler errorHandler ,
6445
6474
@ Cached TStringInternalNodes .GetCodePointLengthNode getCodePointLengthNode ,
0 commit comments