99 */
1010package org .jruby .truffle .nodes .core ;
1111
12+ import com .oracle .truffle .api .CompilerDirectives ;
1213import com .oracle .truffle .api .CompilerDirectives .SlowPath ;
1314import com .oracle .truffle .api .SourceSection ;
14- import com .oracle .truffle .api .dsl .Generic ;
1515import com .oracle .truffle .api .dsl .Specialization ;
1616import com .oracle .truffle .api .frame .VirtualFrame ;
17- import com .oracle .truffle .api .nodes .ExplodeLoop ;
1817import com .oracle .truffle .api .nodes .UnexpectedResultException ;
1918import com .oracle .truffle .api .utilities .BranchProfile ;
19+ import org .jruby .truffle .nodes .RubyRootNode ;
2020import org .jruby .truffle .nodes .call .DispatchHeadNode ;
2121import org .jruby .truffle .runtime .NilPlaceholder ;
2222import org .jruby .truffle .runtime .RubyContext ;
@@ -543,21 +543,34 @@ public EachNode(EachNode prev) {
543543
544544 @ Specialization
545545 public Object each (VirtualFrame frame , RubyArray array , RubyProc block ) {
546- outer : for (int n = 0 ; n < array .size (); n ++) {
547- while (true ) {
548- try {
549- yield(frame , block , array .get (n ));
550- continue outer ;
551- } catch (BreakException e ) {
552- breakProfile .enter ();
553- return e .getResult ();
554- } catch (NextException e ) {
555- nextProfile .enter ();
556- continue outer ;
557- } catch (RedoException e ) {
558- redoProfile .enter ();
546+ int count = 0 ;
547+
548+ try {
549+ outer :
550+ for (int n = 0 ; n < array .size (); n ++) {
551+ while (true ) {
552+ if (CompilerDirectives .inInterpreter ()) {
553+ count ++;
554+ }
555+
556+ try {
557+ yield(frame , block , array .get (n ));
558+ continue outer ;
559+ } catch (BreakException e ) {
560+ breakProfile .enter ();
561+ return e .getResult ();
562+ } catch (NextException e ) {
563+ nextProfile .enter ();
564+ continue outer ;
565+ } catch (RedoException e ) {
566+ redoProfile .enter ();
567+ }
559568 }
560569 }
570+ } finally {
571+ if (CompilerDirectives .inInterpreter ()) {
572+ ((RubyRootNode ) getRootNode ()).reportLoopCountThroughBlocks (count );
573+ }
561574 }
562575
563576 return NilPlaceholder .INSTANCE ;
@@ -578,11 +591,23 @@ public EachWithIndexNode(EachWithIndexNode prev) {
578591
579592 @ Specialization
580593 public NilPlaceholder eachWithIndex (VirtualFrame frame , RubyArray array , RubyProc block ) {
581- for (int n = 0 ; n < array .size (); n ++) {
582- try {
583- yield (frame , block , array .get (n ), n );
584- } catch (BreakException e ) {
585- break ;
594+ int count = 0 ;
595+
596+ try {
597+ for (int n = 0 ; n < array .size (); n ++) {
598+ if (CompilerDirectives .inInterpreter ()) {
599+ count ++;
600+ }
601+
602+ try {
603+ yield (frame , block , array .get (n ), n );
604+ } catch (BreakException e ) {
605+ break ;
606+ }
607+ }
608+ } finally {
609+ if (CompilerDirectives .inInterpreter ()) {
610+ ((RubyRootNode ) getRootNode ()).reportLoopCountThroughBlocks (count );
586611 }
587612 }
588613
@@ -740,8 +765,20 @@ public InjectNode(InjectNode prev) {
740765 public Object inject (VirtualFrame frame , RubyArray array , @ SuppressWarnings ("unused" ) UndefinedPlaceholder initial , RubyProc block ) {
741766 Object accumulator = array .get (0 );
742767
743- for (int n = 1 ; n < array .size (); n ++) {
744- accumulator = yield (frame , block , accumulator , array .get (n ));
768+ int count = 0 ;
769+
770+ try {
771+ for (int n = 1 ; n < array .size (); n ++) {
772+ if (CompilerDirectives .inInterpreter ()) {
773+ count ++;
774+ }
775+
776+ accumulator = yield (frame , block , accumulator , array .get (n ));
777+ }
778+ } finally {
779+ if (CompilerDirectives .inInterpreter ()) {
780+ ((RubyRootNode ) getRootNode ()).reportLoopCountThroughBlocks (count );
781+ }
745782 }
746783
747784 return accumulator ;
@@ -755,8 +792,20 @@ public Object inject(VirtualFrame frame, RubyArray array, Object initial, RubyPr
755792
756793 Object accumulator = initial ;
757794
758- for (int n = 0 ; n < array .size (); n ++) {
759- accumulator = yield (frame , block , accumulator , array .get (n ));
795+ int count = 0 ;
796+
797+ try {
798+ for (int n = 0 ; n < array .size (); n ++) {
799+ if (CompilerDirectives .inInterpreter ()) {
800+ count ++;
801+ }
802+
803+ accumulator = yield (frame , block , accumulator , array .get (n ));
804+ }
805+ } finally {
806+ if (CompilerDirectives .inInterpreter ()) {
807+ ((RubyRootNode ) getRootNode ()).reportLoopCountThroughBlocks (count );
808+ }
760809 }
761810
762811 return accumulator ;
@@ -866,10 +915,22 @@ public MapNode(MapNode prev) {
866915
867916 @ Specialization
868917 public RubyArray map (VirtualFrame frame , RubyArray array , RubyProc block ) {
918+ int count = 0 ;
919+
869920 final RubyArray result = new RubyArray (array .getRubyClass ().getContext ().getCoreLibrary ().getArrayClass ());
870921
871- for (int n = 0 ; n < array .size (); n ++) {
872- result .push (yield (frame , block , array .get (n )));
922+ try {
923+ for (int n = 0 ; n < array .size (); n ++) {
924+ if (CompilerDirectives .inInterpreter ()) {
925+ count ++;
926+ }
927+
928+ result .push (yield (frame , block , array .get (n )));
929+ }
930+ } finally {
931+ if (CompilerDirectives .inInterpreter ()) {
932+ ((RubyRootNode ) getRootNode ()).reportLoopCountThroughBlocks (count );
933+ }
873934 }
874935
875936 return result ;
@@ -889,8 +950,20 @@ public MapInPlaceNode(MapInPlaceNode prev) {
889950
890951 @ Specialization
891952 public RubyArray mapInPlace (VirtualFrame frame , RubyArray array , RubyProc block ) {
892- for (int n = 0 ; n < array .size (); n ++) {
893- array .set (n , yield (frame , block , array .get (n )));
953+ int count = 0 ;
954+
955+ try {
956+ for (int n = 0 ; n < array .size (); n ++) {
957+ if (CompilerDirectives .inInterpreter ()) {
958+ count ++;
959+ }
960+
961+ array .set (n , yield (frame , block , array .get (n )));
962+ }
963+ } finally {
964+ if (CompilerDirectives .inInterpreter ()) {
965+ ((RubyRootNode ) getRootNode ()).reportLoopCountThroughBlocks (count );
966+ }
894967 }
895968
896969 return array ;
@@ -1137,11 +1210,23 @@ public SelectNode(SelectNode prev) {
11371210 public Object select (VirtualFrame frame , RubyArray array , RubyProc block ) {
11381211 final RubyArray result = new RubyArray (getContext ().getCoreLibrary ().getArrayClass ());
11391212
1140- for (int n = 0 ; n < array .size (); n ++) {
1141- final Object value = array .get (n );
1213+ int count = 0 ;
11421214
1143- if (yieldBoolean (frame , block , value )) {
1144- result .push (value );
1215+ try {
1216+ for (int n = 0 ; n < array .size (); n ++) {
1217+ if (CompilerDirectives .inInterpreter ()) {
1218+ count ++;
1219+ }
1220+
1221+ final Object value = array .get (n );
1222+
1223+ if (yieldBoolean (frame , block , value )) {
1224+ result .push (value );
1225+ }
1226+ }
1227+ } finally {
1228+ if (CompilerDirectives .inInterpreter ()) {
1229+ ((RubyRootNode ) getRootNode ()).reportLoopCountThroughBlocks (count );
11451230 }
11461231 }
11471232
0 commit comments