126
126
import org .truffleruby .core .rope .RopeGuards ;
127
127
import org .truffleruby .core .rope .RopeNodes ;
128
128
import org .truffleruby .core .rope .RopeNodes .RepeatNode ;
129
+ import org .truffleruby .core .rope .RopeNodes .SingleByteOptimizableNode ;
129
130
import org .truffleruby .core .rope .RopeOperations ;
130
131
import org .truffleruby .core .rope .SubstringRope ;
131
132
import org .truffleruby .core .string .StringNodesFactory .ByteIndexFromCharIndexNodeGen ;
@@ -433,15 +434,7 @@ public abstract static class CompareNode extends CoreMethodArrayArgumentsNode {
433
434
@ Specialization (guards = "isRubyString(b)" )
434
435
protected int compare (DynamicObject a , DynamicObject b ,
435
436
@ Cached ("createBinaryProfile()" ) ConditionProfile sameRopeProfile ,
436
- @ Cached ("createBinaryProfile()" ) ConditionProfile equalSubsequenceProfile ,
437
- @ Cached ("createBinaryProfile()" ) ConditionProfile equalLengthProfile ,
438
- @ Cached ("createBinaryProfile()" ) ConditionProfile firstStringShorterProfile ,
439
- @ Cached ("createBinaryProfile()" ) ConditionProfile greaterThanProfile ,
440
- @ Cached ("createBinaryProfile()" ) ConditionProfile equalProfile ,
441
- @ Cached ("createBinaryProfile()" ) ConditionProfile notComparableProfile ,
442
- @ Cached ("createBinaryProfile()" ) ConditionProfile encodingIndexGreaterThanProfile ,
443
- @ Cached RopeNodes .BytesNode firstBytesNode ,
444
- @ Cached RopeNodes .BytesNode secondBytesNode ) {
437
+ @ Cached RopeNodes .CompareRopesNode compareNode ) {
445
438
// Taken from org.jruby.RubyString#op_cmp
446
439
447
440
final Rope firstRope = rope (a );
@@ -451,46 +444,7 @@ protected int compare(DynamicObject a, DynamicObject b,
451
444
return 0 ;
452
445
}
453
446
454
- final boolean firstRopeShorter = firstStringShorterProfile
455
- .profile (firstRope .byteLength () < secondRope .byteLength ());
456
- final int memcmpLength ;
457
- if (firstRopeShorter ) {
458
- memcmpLength = firstRope .byteLength ();
459
- } else {
460
- memcmpLength = secondRope .byteLength ();
461
- }
462
-
463
- final byte [] bytes = firstBytesNode .execute (firstRope );
464
- final byte [] otherBytes = secondBytesNode .execute (secondRope );
465
-
466
- final int ret ;
467
- final int cmp = ArrayUtils .memcmp (bytes , 0 , otherBytes , 0 , memcmpLength );
468
- if (equalSubsequenceProfile .profile (cmp == 0 )) {
469
- if (equalLengthProfile .profile (firstRope .byteLength () == secondRope .byteLength ())) {
470
- ret = 0 ;
471
- } else {
472
- if (firstRopeShorter ) {
473
- ret = -1 ;
474
- } else {
475
- ret = 1 ;
476
- }
477
- }
478
- } else {
479
- ret = greaterThanProfile .profile (cmp > 0 ) ? 1 : -1 ;
480
- }
481
-
482
- if (equalProfile .profile (ret == 0 )) {
483
- if (notComparableProfile .profile (!RopeOperations .areComparable (firstRope , secondRope ))) {
484
- if (encodingIndexGreaterThanProfile
485
- .profile (firstRope .getEncoding ().getIndex () > secondRope .getEncoding ().getIndex ())) {
486
- return 1 ;
487
- } else {
488
- return -1 ;
489
- }
490
- }
491
- }
492
-
493
- return ret ;
447
+ return compareNode .execute (firstRope , secondRope );
494
448
}
495
449
496
450
}
@@ -3442,49 +3396,14 @@ protected static boolean indexOutOfBounds(DynamicObject string, int byteIndex) {
3442
3396
@ ImportStatic (StringGuards .class )
3443
3397
public static abstract class StringAreComparableNode extends RubyBaseNode {
3444
3398
3445
- @ Child RopeNodes .CodeRangeNode codeRangeNode = RopeNodes .CodeRangeNode .create ();
3399
+ @ Child RopeNodes .AreComparableRopesNode areComparableRopesNode = RopeNodes .AreComparableRopesNode .create ();
3446
3400
3447
3401
public abstract boolean executeAreComparable (DynamicObject first , DynamicObject second );
3448
3402
3449
- @ Specialization ( guards = "getEncoding(a) == getEncoding(b)" )
3403
+ @ Specialization
3450
3404
protected boolean sameEncoding (DynamicObject a , DynamicObject b ) {
3451
- return true ;
3452
- }
3453
-
3454
- @ Specialization (guards = "isEmpty(a)" )
3455
- protected boolean firstEmpty (DynamicObject a , DynamicObject b ) {
3456
- return true ;
3405
+ return areComparableRopesNode .execute (Layouts .STRING .getRope (a ), Layouts .STRING .getRope (b ));
3457
3406
}
3458
-
3459
- @ Specialization (guards = "isEmpty(b)" )
3460
- protected boolean secondEmpty (DynamicObject a , DynamicObject b ) {
3461
- return true ;
3462
- }
3463
-
3464
- @ Specialization (guards = { "is7Bit(a, codeRangeNode)" , "is7Bit(b, codeRangeNode)" })
3465
- protected boolean bothCR7bit (DynamicObject a , DynamicObject b ) {
3466
- return true ;
3467
- }
3468
-
3469
- @ Specialization (guards = { "is7Bit(a, codeRangeNode)" , "isAsciiCompatible(b)" })
3470
- protected boolean CR7bitASCII (DynamicObject a , DynamicObject b ) {
3471
- return true ;
3472
- }
3473
-
3474
- @ Specialization (guards = { "isAsciiCompatible(a)" , "is7Bit(b, codeRangeNode)" })
3475
- protected boolean ASCIICR7bit (DynamicObject a , DynamicObject b ) {
3476
- return true ;
3477
- }
3478
-
3479
- @ Fallback
3480
- protected boolean notCompatible (DynamicObject a , DynamicObject b ) {
3481
- return false ;
3482
- }
3483
-
3484
- protected static Encoding getEncoding (DynamicObject string ) {
3485
- return rope (string ).getEncoding ();
3486
- }
3487
-
3488
3407
}
3489
3408
3490
3409
@ ImportStatic ({ StringGuards .class , StringOperations .class })
@@ -4260,26 +4179,28 @@ public static ByteIndexFromCharIndexNode create() {
4260
4179
return ByteIndexFromCharIndexNodeGen .create ();
4261
4180
}
4262
4181
4182
+ @ Child protected SingleByteOptimizableNode singleByteOptimizableNode = SingleByteOptimizableNode .create ();
4183
+
4263
4184
public abstract int execute (Rope rope , int startByteOffset , int characterIndex );
4264
4185
4265
- @ Specialization (guards = "rope. isSingleByteOptimizable()" )
4186
+ @ Specialization (guards = "isSingleByteOptimizable(rope )" )
4266
4187
protected int singleByteOptimizable (Rope rope , int startByteOffset , int characterIndex ) {
4267
4188
return startByteOffset + characterIndex ;
4268
4189
}
4269
4190
4270
- @ Specialization (guards = { "!rope. isSingleByteOptimizable()" , "isFixedWidthEncoding(rope)" })
4191
+ @ Specialization (guards = { "!isSingleByteOptimizable(rope )" , "isFixedWidthEncoding(rope)" })
4271
4192
protected int fixedWidthEncoding (Rope rope , int startByteOffset , int characterIndex ) {
4272
4193
final Encoding encoding = rope .getEncoding ();
4273
4194
return startByteOffset + characterIndex * encoding .minLength ();
4274
4195
}
4275
4196
4276
4197
@ Specialization (
4277
- guards = { "!rope. isSingleByteOptimizable()" , "!isFixedWidthEncoding(rope)" , "characterIndex == 0" })
4198
+ guards = { "!isSingleByteOptimizable(rope )" , "!isFixedWidthEncoding(rope)" , "characterIndex == 0" })
4278
4199
protected int multiByteZeroIndex (Rope rope , int startByteOffset , int characterIndex ) {
4279
4200
return startByteOffset ;
4280
4201
}
4281
4202
4282
- @ Specialization (guards = { "!rope. isSingleByteOptimizable()" , "!isFixedWidthEncoding(rope)" })
4203
+ @ Specialization (guards = { "!isSingleByteOptimizable(rope )" , "!isFixedWidthEncoding(rope)" })
4283
4204
protected int multiBytes (Rope rope , int startByteOffset , int characterIndex ,
4284
4205
@ Cached ("createBinaryProfile()" ) ConditionProfile indexTooLargeProfile ,
4285
4206
@ Cached ("createBinaryProfile()" ) ConditionProfile invalidByteProfile ,
@@ -4316,6 +4237,10 @@ protected int multiBytes(Rope rope, int startByteOffset, int characterIndex,
4316
4237
}
4317
4238
}
4318
4239
4240
+ protected boolean isSingleByteOptimizable (Rope rope ) {
4241
+ return singleByteOptimizableNode .execute (rope );
4242
+ }
4243
+
4319
4244
}
4320
4245
4321
4246
// Named 'string_byte_index' in Rubinius.
0 commit comments