26
26
import com .oracle .truffle .api .TruffleSafepoint ;
27
27
import com .oracle .truffle .api .dsl .Bind ;
28
28
import com .oracle .truffle .api .dsl .Fallback ;
29
+ import com .oracle .truffle .api .dsl .GenerateCached ;
30
+ import com .oracle .truffle .api .dsl .GenerateInline ;
29
31
import com .oracle .truffle .api .dsl .ImportStatic ;
32
+ import com .oracle .truffle .api .dsl .NeverDefault ;
30
33
import com .oracle .truffle .api .interop .InteropException ;
31
34
import com .oracle .truffle .api .interop .InteropLibrary ;
32
35
import com .oracle .truffle .api .library .CachedLibrary ;
65
68
import org .truffleruby .core .string .StringNodes .StringAppendPrimitiveNode ;
66
69
import org .truffleruby .core .string .StringOperations ;
67
70
import org .truffleruby .core .string .StringUtils ;
71
+ import org .truffleruby .interop .LazyTranslateInteropExceptionNode ;
68
72
import org .truffleruby .interop .TranslateInteropExceptionNode ;
69
- import org .truffleruby .interop .TranslateInteropExceptionNodeGen ;
70
73
import org .truffleruby .language .LazyWarnNode ;
71
74
import org .truffleruby .language .RubyBaseNode ;
72
75
import org .truffleruby .language .RubyGuards ;
83
86
import com .oracle .truffle .api .nodes .ExplodeLoop ;
84
87
import com .oracle .truffle .api .nodes .Node ;
85
88
import com .oracle .truffle .api .profiles .ConditionProfile ;
89
+ import org .truffleruby .language .dispatch .LazyDispatchNode ;
86
90
import org .truffleruby .language .library .RubyStringLibrary ;
87
91
import org .truffleruby .language .objects .AllocationTracing ;
88
92
import org .truffleruby .parser .RubyDeferredWarnings ;
@@ -752,6 +756,7 @@ private <K, V> void buildAndSetDistributionHash(HashStoreLibrary hashStoreLibrar
752
756
@ Primitive (name = "regexp_match_in_region" , lowerFixnum = { 2 , 3 , 5 })
753
757
public abstract static class MatchInRegionNode extends PrimitiveArrayArgumentsNode {
754
758
759
+ @ NeverDefault
755
760
public static MatchInRegionNode create () {
756
761
return TruffleRegexpNodesFactory .MatchInRegionNodeFactory .create (null );
757
762
}
@@ -826,16 +831,43 @@ protected static Object matchInRegion(
826
831
}
827
832
}
828
833
829
- @ Primitive (name = "regexp_match_in_region_tregex" , lowerFixnum = { 2 , 3 , 5 })
830
- public abstract static class MatchInRegionTRegexNode extends PrimitiveArrayArgumentsNode {
834
+ @ GenerateCached (false )
835
+ @ GenerateInline (inlineByDefault = true )
836
+ public abstract static class LazyMatchInRegionNode extends RubyBaseNode {
831
837
832
- @ Child MatchInRegionNode fallbackMatchInRegionNode ;
833
- @ Child DispatchNode warnOnFallbackNode ;
838
+ public final MatchInRegionNode get (Node node ) {
839
+ return execute (node );
840
+ }
841
+
842
+ protected abstract MatchInRegionNode execute (Node node );
843
+
844
+ @ Specialization
845
+ protected static MatchInRegionNode doLazy (
846
+ @ Cached (inline = false ) MatchInRegionNode matchInRegionNode ) {
847
+ return matchInRegionNode ;
848
+ }
849
+ }
850
+
851
+ @ GenerateCached (false )
852
+ @ GenerateInline (inlineByDefault = true )
853
+ public abstract static class LazyTruffleStringSubstringByteIndexNode extends RubyBaseNode {
854
+
855
+ public final TruffleString .SubstringByteIndexNode get (Node node ) {
856
+ return execute (node );
857
+ }
858
+
859
+ protected abstract TruffleString .SubstringByteIndexNode execute (Node node );
860
+
861
+ @ Specialization
862
+ protected static TruffleString .SubstringByteIndexNode doLazy (
863
+ @ Cached (inline = false ) TruffleString .SubstringByteIndexNode substringByteIndexNode ) {
864
+ return substringByteIndexNode ;
865
+ }
866
+ }
834
867
835
- @ Child DispatchNode stringDupNode ;
836
- @ Child TranslateInteropExceptionNode translateInteropExceptionNode ;
868
+ @ Primitive ( name = "regexp_match_in_region_tregex" , lowerFixnum = { 2 , 3 , 5 })
869
+ public abstract static class MatchInRegionTRegexNode extends PrimitiveArrayArgumentsNode {
837
870
838
- @ Child TruffleString .SubstringByteIndexNode substringByteIndexNode ;
839
871
840
872
@ Specialization (guards = "libString.isRubyString(string)" , limit = "1" )
841
873
protected Object matchInRegionTRegex (
@@ -858,7 +890,12 @@ protected Object matchInRegionTRegex(
858
890
@ Cached PrepareRegexpEncodingNode prepareRegexpEncodingNode ,
859
891
@ Cached TRegexCompileNode tRegexCompileNode ,
860
892
@ Cached RubyStringLibrary libString ,
861
- @ Cached (inline = false ) IntValueProfile groupCountProfile ) {
893
+ @ Cached (inline = false ) IntValueProfile groupCountProfile ,
894
+ @ Cached LazyDispatchNode warnOnFallbackNode ,
895
+ @ Cached LazyDispatchNode stringDupNode ,
896
+ @ Cached LazyTranslateInteropExceptionNode lazyTranslateInteropExceptionNode ,
897
+ @ Cached LazyMatchInRegionNode fallbackMatchInRegionNode ,
898
+ @ Cached LazyTruffleStringSubstringByteIndexNode substringByteIndexNode ) {
862
899
final Object tRegex ;
863
900
final RubyEncoding negotiatedEncoding = prepareRegexpEncodingNode .executePrepare (regexp , string );
864
901
var tstring = switchEncodingNode .execute (libString .getTString (string ), negotiatedEncoding .tencoding );
@@ -878,7 +915,9 @@ protected Object matchInRegionTRegex(
878
915
toPos ,
879
916
atStart ,
880
917
startPos ,
881
- createMatchData );
918
+ createMatchData ,
919
+ warnOnFallbackNode .get (this ),
920
+ fallbackMatchInRegionNode .get (this ));
882
921
}
883
922
884
923
if (getContext ().getOptions ().REGEXP_INSTRUMENT_MATCH ) {
@@ -900,11 +939,7 @@ protected Object matchInRegionTRegex(
900
939
assert fromPos == startPos ;
901
940
fromIndex = 0 ;
902
941
903
- if (substringByteIndexNode == null ) {
904
- CompilerDirectives .transferToInterpreterAndInvalidate ();
905
- substringByteIndexNode = insert (TruffleString .SubstringByteIndexNode .create ());
906
- }
907
- tstringToMatch = substringByteIndexNode .execute (tstring , startPos , toPos - startPos ,
942
+ tstringToMatch = substringByteIndexNode .get (this ).execute (tstring , startPos , toPos - startPos ,
908
943
negotiatedEncoding .tencoding , true );
909
944
} else {
910
945
tstringToMatch = tstring ;
@@ -917,15 +952,17 @@ protected Object matchInRegionTRegex(
917
952
tstringToMatch = tstring ;
918
953
execMethod = "execBoolean" ;
919
954
}
920
-
921
- final Object result = invoke ( regexInterop , tRegex , execMethod , tstringToMatch , fromIndex );
955
+ final Object result = invoke ( regexInterop , tRegex , execMethod , lazyTranslateInteropExceptionNode . get ( this ),
956
+ tstringToMatch , fromIndex );
922
957
923
958
if (createMatchDataProfile .profile (createMatchData )) {
924
- final boolean isMatch = (boolean ) readMember (resultInterop , result , "isMatch" );
959
+ final boolean isMatch = (boolean ) readMember (resultInterop , result , "isMatch" ,
960
+ lazyTranslateInteropExceptionNode .get (this ));
925
961
926
962
if (matchFoundProfile .profile (isMatch )) {
927
963
final int groupCount = groupCountProfile
928
- .profile ((int ) readMember (regexInterop , tRegex , "groupCount" ));
964
+ .profile ((int ) readMember (regexInterop , tRegex , "groupCount" ,
965
+ lazyTranslateInteropExceptionNode .get (this )));
929
966
final Region region = new Region (groupCount );
930
967
931
968
try {
@@ -938,7 +975,7 @@ protected Object matchInRegionTRegex(
938
975
profileAndReportLoopCount (loopProfile , groupCount );
939
976
}
940
977
941
- return createMatchData (regexp , dupString (string ), region , result );
978
+ return createMatchData (regexp , dupString (string , stringDupNode . get ( this ) ), region , result );
942
979
} else {
943
980
return nil ;
944
981
}
@@ -948,12 +985,9 @@ protected Object matchInRegionTRegex(
948
985
}
949
986
950
987
private Object fallbackToJoni (RubyRegexp regexp , Object string , RubyEncoding encoding , int fromPos , int toPos ,
951
- boolean atStart , int startPos , boolean createMatchData ) {
988
+ boolean atStart , int startPos , boolean createMatchData , DispatchNode warnOnFallbackNode ,
989
+ MatchInRegionNode fallbackMatchInRegionNode ) {
952
990
if (getContext ().getOptions ().WARN_TRUFFLE_REGEX_MATCH_FALLBACK ) {
953
- if (warnOnFallbackNode == null ) {
954
- CompilerDirectives .transferToInterpreterAndInvalidate ();
955
- warnOnFallbackNode = insert (DispatchNode .create ());
956
- }
957
991
958
992
warnOnFallbackNode .call (
959
993
getContext ().getCoreLibrary ().truffleRegexpOperationsModule ,
@@ -968,11 +1002,6 @@ private Object fallbackToJoni(RubyRegexp regexp, Object string, RubyEncoding enc
968
1002
startPos });
969
1003
}
970
1004
971
- if (fallbackMatchInRegionNode == null ) {
972
- CompilerDirectives .transferToInterpreterAndInvalidate ();
973
- fallbackMatchInRegionNode = insert (MatchInRegionNode .create ());
974
- }
975
-
976
1005
return fallbackMatchInRegionNode
977
1006
.executeMatchInRegion (regexp , string , fromPos , toPos , atStart , startPos , createMatchData );
978
1007
}
@@ -989,36 +1018,25 @@ private Object createMatchData(RubyRegexp regexp, Object string, Region region,
989
1018
return matchData ;
990
1019
}
991
1020
992
- private Object readMember (InteropLibrary interop , Object receiver , String name ) {
1021
+ private Object readMember (InteropLibrary interop , Object receiver , String name ,
1022
+ TranslateInteropExceptionNode translateInteropExceptionNode ) {
993
1023
try {
994
1024
return interop .readMember (receiver , name );
995
1025
} catch (InteropException e ) {
996
- if (translateInteropExceptionNode == null ) {
997
- CompilerDirectives .transferToInterpreterAndInvalidate ();
998
- translateInteropExceptionNode = insert (TranslateInteropExceptionNodeGen .create ());
999
- }
1000
1026
throw translateInteropExceptionNode .execute (e );
1001
1027
}
1002
1028
}
1003
1029
1004
- private Object invoke (InteropLibrary interop , Object receiver , String member , Object ... args ) {
1030
+ private Object invoke (InteropLibrary interop , Object receiver , String member ,
1031
+ TranslateInteropExceptionNode translateInteropExceptionNode , Object ... args ) {
1005
1032
try {
1006
1033
return interop .invokeMember (receiver , member , args );
1007
1034
} catch (InteropException e ) {
1008
- if (translateInteropExceptionNode == null ) {
1009
- CompilerDirectives .transferToInterpreterAndInvalidate ();
1010
- translateInteropExceptionNode = insert (TranslateInteropExceptionNodeGen .create ());
1011
- }
1012
1035
throw translateInteropExceptionNode .executeInInvokeMember (e , receiver , args );
1013
1036
}
1014
1037
}
1015
1038
1016
- private Object dupString (Object string ) {
1017
- if (stringDupNode == null ) {
1018
- CompilerDirectives .transferToInterpreterAndInvalidate ();
1019
- stringDupNode = insert (DispatchNode .create ());
1020
- }
1021
-
1039
+ private Object dupString (Object string , DispatchNode stringDupNode ) {
1022
1040
return stringDupNode .call (string , "dup" );
1023
1041
}
1024
1042
}
0 commit comments