1
1
/*
2
- * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* The Universal Permissive License (UPL), Version 1.0
76
76
import com .oracle .truffle .api .dsl .Specialization ;
77
77
import com .oracle .truffle .api .frame .VirtualFrame ;
78
78
import com .oracle .truffle .api .nodes .ExplodeLoop ;
79
+ import com .oracle .truffle .api .nodes .LoopNode ;
80
+ import com .oracle .truffle .api .profiles .ConditionProfile ;
81
+ import com .oracle .truffle .api .profiles .LoopConditionProfile ;
79
82
import com .oracle .truffle .api .profiles .ValueProfile ;
80
83
81
84
public abstract class SortNodes {
@@ -214,9 +217,8 @@ void sort(DoubleSequenceStorage storage, @SuppressWarnings("unused") PNone keyfu
214
217
}
215
218
}
216
219
217
- @ Specialization (guards = "isStringOnly(storage)" )
218
220
@ TruffleBoundary
219
- void sort (ObjectSequenceStorage storage , @ SuppressWarnings ( "unused" ) PNone keyfunc , boolean reverse ) {
221
+ private static void sortStrings (ObjectSequenceStorage storage , boolean reverse ) {
220
222
Object [] array = storage .getInternalArray ();
221
223
int len = storage .length ();
222
224
Comparator <Object > comparator ;
@@ -228,23 +230,34 @@ void sort(ObjectSequenceStorage storage, @SuppressWarnings("unused") PNone keyfu
228
230
Arrays .sort (array , 0 , len , comparator );
229
231
}
230
232
231
- @ TruffleBoundary
232
- protected static boolean isStringOnly (ObjectSequenceStorage storage ) {
233
+ protected boolean isStringOnly (ObjectSequenceStorage storage , LoopConditionProfile isStringOnlyLoopProfile , ConditionProfile isStringOnlyBreakProfile ) {
233
234
int length = storage .length ();
234
235
Object [] array = storage .getInternalArray ();
235
- for (int i = 0 ; i < length ; i ++) {
236
+ for (int i = 0 ; isStringOnlyLoopProfile . profile ( i < length ) ; i ++) {
236
237
Object value = array [i ];
237
- if (!(value instanceof String )) {
238
+ if (isStringOnlyBreakProfile .profile (!(value instanceof String ))) {
239
+ LoopNode .reportLoopCount (this , i );
238
240
return false ;
239
241
}
240
242
}
243
+ LoopNode .reportLoopCount (this , length );
241
244
return true ;
242
245
}
243
246
244
247
@ Specialization
245
- void sort (VirtualFrame frame , ObjectSequenceStorage storage , @ SuppressWarnings ("unused" ) PNone keyfunc , boolean reverse ,
248
+ void sortObjSeqStorage (VirtualFrame frame , ObjectSequenceStorage storage , @ SuppressWarnings ("unused" ) PNone keyfunc , boolean reverse ,
249
+ @ Cached ConditionProfile isStringOnlyProfile ,
250
+ @ Cached LoopConditionProfile isStringOnlyLoopProfile ,
251
+ @ Cached ("createCountingProfile()" ) ConditionProfile isStringOnlyBreakProfile ,
246
252
@ Cached CallContext callContext ) {
247
- sortWithoutKey (frame , storage .getInternalArray (), storage .length (), reverse , callContext );
253
+ if (isStringOnlyProfile .profile (isStringOnly (storage , isStringOnlyLoopProfile , isStringOnlyBreakProfile ))) {
254
+ // Sorting of strings seems to be so much faster (especially on SVM) that it is
255
+ // worth always checking for string only sequences and not replacing the strings
256
+ // specialized code with generic object storage code
257
+ sortStrings (storage , reverse );
258
+ } else {
259
+ sortWithoutKey (frame , storage .getInternalArray (), storage .length (), reverse , callContext );
260
+ }
248
261
}
249
262
250
263
@ Specialization (guards = "!isPNone(keyfunc)" )
0 commit comments