57
57
import java .nio .charset .IllegalCharsetNameException ;
58
58
import java .nio .charset .StandardCharsets ;
59
59
import java .nio .charset .UnsupportedCharsetException ;
60
+ import java .util .Arrays ;
60
61
import java .util .List ;
61
62
62
63
import org .graalvm .nativeimage .ImageInfo ;
@@ -1438,18 +1439,32 @@ private Object encodeString(String self, String encoding, String errors) {
1438
1439
@ TypeSystemReference (PythonArithmeticTypes .class )
1439
1440
abstract static class MulNode extends PythonBinaryBuiltinNode {
1440
1441
1441
- @ Specialization
1442
+ @ Specialization (guards = "right <= 0" )
1443
+ String doEmptyStringInt (@ SuppressWarnings ("unused" ) Object left , @ SuppressWarnings ("unused" ) int right ) {
1444
+ return "" ;
1445
+ }
1446
+
1447
+ @ Specialization (guards = {"left.length() == 0" , "right > 0" })
1448
+ String doEmptyStringInt (String left , @ SuppressWarnings ("unused" ) int right ) {
1449
+ return left ;
1450
+ }
1451
+
1452
+ @ Specialization (guards = {"left.length() == 1" , "right > 0" })
1453
+ String doCharInt (String left , int right ) {
1454
+ char [] result = new char [right ];
1455
+ Arrays .fill (result , left .charAt (0 ));
1456
+ return new String (result );
1457
+ }
1458
+
1459
+ @ Specialization (guards = {"left.length() > 1" , "right > 0" })
1442
1460
String doStringInt (String left , int right ) {
1443
- if (right <= 0 ) {
1444
- return "" ;
1445
- }
1446
1461
return repeatString (left , right );
1447
1462
}
1448
1463
1449
1464
@ Specialization (limit = "1" )
1450
1465
String doStringLong (String left , long right ,
1451
1466
@ Exclusive @ CachedLibrary ("right" ) PythonObjectLibrary lib ) {
1452
- return doStringInt (left , lib .asSize (right ));
1467
+ return doStringIntGeneric (left , lib .asSize (right ));
1453
1468
}
1454
1469
1455
1470
@ Specialization
@@ -1464,7 +1479,7 @@ String doStringObject(VirtualFrame frame, String left, Object right,
1464
1479
} else {
1465
1480
repeat = lib .asSize (right );
1466
1481
}
1467
- return doStringInt (left , repeat );
1482
+ return doStringIntGeneric (left , repeat );
1468
1483
} catch (PException e ) {
1469
1484
e .expect (PythonBuiltinClassType .OverflowError , typeErrorProfile );
1470
1485
throw raise (MemoryError );
@@ -1481,14 +1496,27 @@ Object doGeneric(VirtualFrame frame, Object self, Object times,
1481
1496
return doStringObject (frame , selfStr , times , hasFrame , lib , typeErrorProfile );
1482
1497
}
1483
1498
1499
+ public String doStringIntGeneric (String left , int right ) {
1500
+ if (right <= 0 ) {
1501
+ return "" ;
1502
+ }
1503
+ return repeatString (left , right );
1504
+ }
1505
+
1484
1506
@ TruffleBoundary
1485
1507
private String repeatString (String left , int times ) {
1486
1508
try {
1487
- StringBuilder str = new StringBuilder (Math .multiplyExact (left .length (), times ));
1488
- for (int i = 0 ; i < times ; i ++) {
1489
- str .append (left );
1509
+ int total = Math .multiplyExact (left .length (), times );
1510
+ char [] result = new char [total ];
1511
+ left .getChars (0 , left .length (), result , 0 );
1512
+ int done = left .length ();
1513
+ while (done < total ) {
1514
+ int todo = total - done ;
1515
+ int len = Math .min (done , todo );
1516
+ System .arraycopy (result , 0 , result , done , len );
1517
+ done += len ;
1490
1518
}
1491
- return str . toString ( );
1519
+ return new String ( result );
1492
1520
} catch (OutOfMemoryError | ArithmeticException e ) {
1493
1521
throw raise (MemoryError );
1494
1522
}
0 commit comments