241
241
import com .oracle .truffle .api .library .CachedLibrary ;
242
242
import com .oracle .truffle .api .nodes .ExplodeLoop ;
243
243
import com .oracle .truffle .api .nodes .ExplodeLoop .LoopExplosionKind ;
244
+ import com .oracle .truffle .api .nodes .LoopNode ;
244
245
import com .oracle .truffle .api .nodes .Node ;
245
246
import com .oracle .truffle .api .nodes .RootNode ;
246
247
import com .oracle .truffle .api .nodes .UnexpectedResultException ;
247
248
import com .oracle .truffle .api .profiles .BranchProfile ;
248
249
import com .oracle .truffle .api .profiles .ConditionProfile ;
250
+ import com .oracle .truffle .api .profiles .LoopConditionProfile ;
249
251
import com .oracle .truffle .api .source .Source ;
250
252
import com .oracle .truffle .api .utilities .TriState ;
251
253
@@ -306,20 +308,24 @@ enum NodeType {
306
308
307
309
@ Child private PyObjectIsTrueNode isTrueNode = PyObjectIsTrueNode .create ();
308
310
311
+ final private LoopConditionProfile loopConditionProfile = LoopConditionProfile .create ();
312
+
309
313
abstract boolean execute (Frame frame , Object storageObj , NodeType nodeType );
310
314
311
315
@ Specialization
312
316
boolean doBoolSequence (VirtualFrame frame ,
313
317
BoolSequenceStorage sequenceStorage ,
314
318
NodeType nodeType ) {
315
319
boolean [] internalArray = sequenceStorage .getInternalBoolArray ();
320
+ int i = 0 ;
316
321
317
- for ( int i = 0 ; i < sequenceStorage .length (); i ++ ) {
322
+ while ( loopConditionProfile . profile ( i < sequenceStorage .length ()) ) {
318
323
if (nodeType == NodeType .ALL && !isTrueNode .execute (frame , internalArray [i ])) {
319
324
return false ;
320
325
} else if (nodeType == NodeType .ANY && isTrueNode .execute (frame , internalArray [i ])) {
321
326
return true ;
322
327
}
328
+ i ++;
323
329
}
324
330
325
331
return nodeType == NodeType .ALL ;
@@ -330,8 +336,9 @@ boolean doIntSequence(VirtualFrame frame,
330
336
IntSequenceStorage sequenceStorage ,
331
337
NodeType nodeType ) {
332
338
int [] internalArray = sequenceStorage .getInternalIntArray ();
339
+ int i = 0 ;
333
340
334
- for ( int i = 0 ; i < sequenceStorage .length (); i ++ ) {
341
+ while ( loopConditionProfile . profile ( i < sequenceStorage .length ()) ) {
335
342
if (nodeType == NodeType .ALL && !isTrueNode .execute (frame , internalArray [i ])) {
336
343
return false ;
337
344
} else if (nodeType == NodeType .ANY && isTrueNode .execute (frame , internalArray [i ])) {
@@ -348,7 +355,10 @@ boolean doGenericSequence(VirtualFrame frame,
348
355
NodeType nodeType ,
349
356
@ Cached SequenceStorageNodes .LenNode lenNode ) {
350
357
Object [] internalArray = sequenceStorage .getInternalArray ();
351
- for (int i = 0 ; i < lenNode .execute (sequenceStorage ); i ++) {
358
+ int i = 0 ;
359
+ int seqLength = lenNode .execute (sequenceStorage );
360
+
361
+ while (loopConditionProfile .profile (i < seqLength )) {
352
362
if (nodeType == NodeType .ALL && !isTrueNode .execute (frame , internalArray [i ])) {
353
363
return false ;
354
364
} else if (nodeType == NodeType .ANY && isTrueNode .execute (frame , internalArray [i ])) {
@@ -365,6 +375,7 @@ protected boolean doHashStorage(VirtualFrame frame,
365
375
NodeType nodeType ,
366
376
@ CachedLibrary ("hashingStorage" ) HashingStorageLibrary hlib ) {
367
377
for (Object key : hlib .keys (hashingStorage )) {
378
+ LoopNode .reportLoopCount (this , 1 );
368
379
if (nodeType == NodeType .ALL ) {
369
380
if (!isTrueNode .execute (frame , key )) {
370
381
return false ;
@@ -407,7 +418,7 @@ static boolean doHashColl(VirtualFrame frame,
407
418
}
408
419
409
420
@ Specialization
410
- static boolean doObject (VirtualFrame frame ,
421
+ boolean doObject (VirtualFrame frame ,
411
422
Object object ,
412
423
@ Cached PyObjectGetIter getIter ,
413
424
@ Cached GetNextNode nextNode ,
@@ -416,6 +427,7 @@ static boolean doObject(VirtualFrame frame,
416
427
Object iterator = getIter .execute (frame , object );
417
428
while (true ) {
418
429
try {
430
+ LoopNode .reportLoopCount (this , 1 );
419
431
Object next = nextNode .execute (frame , iterator );
420
432
if (!isTrueNode .execute (frame , next )) {
421
433
return false ;
@@ -452,14 +464,14 @@ static boolean doTuple(VirtualFrame frame,
452
464
453
465
@ Specialization (guards = "cannotBeOverridden(object, getClassNode)" , limit = "1" )
454
466
static boolean doHashColl (VirtualFrame frame ,
455
- PHashingCollection object ,
467
+ PHashingCollection object ,
456
468
@ SuppressWarnings ("unused" ) @ Shared ("getClassNode" ) @ Cached GetClassNode getClassNode ,
457
469
@ Shared ("allOrAnyNode" ) @ Cached AllOrAnyNode allOrAnyNode ) {
458
470
return allOrAnyNode .execute (frame , object .getDictStorage (), AllOrAnyNode .NodeType .ANY );
459
471
}
460
472
461
473
@ Specialization
462
- static boolean doObject (VirtualFrame frame ,
474
+ boolean doObject (VirtualFrame frame ,
463
475
Object object ,
464
476
@ Cached PyObjectGetIter getIter ,
465
477
@ Cached GetNextNode nextNode ,
@@ -468,6 +480,7 @@ static boolean doObject(VirtualFrame frame,
468
480
Object iterator = getIter .execute (frame , object );
469
481
while (true ) {
470
482
try {
483
+ LoopNode .reportLoopCount (this , 1 );
471
484
Object next = nextNode .execute (frame , iterator );
472
485
if (isTrueNode .execute (frame , next )) {
473
486
return true ;
0 commit comments