5757import java .nio .charset .IllegalCharsetNameException ;
5858import java .nio .charset .StandardCharsets ;
5959import java .nio .charset .UnsupportedCharsetException ;
60+ import java .util .Arrays ;
6061import java .util .List ;
6162
6263import org .graalvm .nativeimage .ImageInfo ;
@@ -1438,18 +1439,32 @@ private Object encodeString(String self, String encoding, String errors) {
14381439 @ TypeSystemReference (PythonArithmeticTypes .class )
14391440 abstract static class MulNode extends PythonBinaryBuiltinNode {
14401441
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" })
14421460 String doStringInt (String left , int right ) {
1443- if (right <= 0 ) {
1444- return "" ;
1445- }
14461461 return repeatString (left , right );
14471462 }
14481463
14491464 @ Specialization (limit = "1" )
14501465 String doStringLong (String left , long right ,
14511466 @ Exclusive @ CachedLibrary ("right" ) PythonObjectLibrary lib ) {
1452- return doStringInt (left , lib .asSize (right ));
1467+ return doStringIntGeneric (left , lib .asSize (right ));
14531468 }
14541469
14551470 @ Specialization
@@ -1464,7 +1479,7 @@ String doStringObject(VirtualFrame frame, String left, Object right,
14641479 } else {
14651480 repeat = lib .asSize (right );
14661481 }
1467- return doStringInt (left , repeat );
1482+ return doStringIntGeneric (left , repeat );
14681483 } catch (PException e ) {
14691484 e .expect (PythonBuiltinClassType .OverflowError , typeErrorProfile );
14701485 throw raise (MemoryError );
@@ -1481,14 +1496,27 @@ Object doGeneric(VirtualFrame frame, Object self, Object times,
14811496 return doStringObject (frame , selfStr , times , hasFrame , lib , typeErrorProfile );
14821497 }
14831498
1499+ public String doStringIntGeneric (String left , int right ) {
1500+ if (right <= 0 ) {
1501+ return "" ;
1502+ }
1503+ return repeatString (left , right );
1504+ }
1505+
14841506 @ TruffleBoundary
14851507 private String repeatString (String left , int times ) {
14861508 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 ;
14901518 }
1491- return str . toString ( );
1519+ return new String ( result );
14921520 } catch (OutOfMemoryError | ArithmeticException e ) {
14931521 throw raise (MemoryError );
14941522 }
0 commit comments