@@ -314,6 +314,7 @@ enum Kind {
314
314
GET_DOUBLE_VOLATILE ("getDoubleVolatile" ),
315
315
PUT_DOUBLE_VOLATILE ("putDoubleVolatile" ),
316
316
TRY_FINALLY ("tryFinally" ),
317
+ TABLE_SWITCH ("tableSwitch" ),
317
318
COLLECT ("collect" ),
318
319
COLLECTOR ("collector" ),
319
320
CONVERT ("convert" ),
@@ -707,6 +708,32 @@ boolean isTryFinally(int pos) {
707
708
return isMatchingIdiom (pos , "tryFinally" , 2 );
708
709
}
709
710
711
+ /**
712
+ * Check if i-th name is a start of the tableSwitch idiom.
713
+ */
714
+ boolean isTableSwitch (int pos ) {
715
+ // tableSwitch idiom:
716
+ // t_{n}:L=MethodHandle.invokeBasic(...) // args
717
+ // t_{n+1}:L=MethodHandleImpl.tableSwitch(*, *, *, t_{n})
718
+ // t_{n+2}:?=MethodHandle.invokeBasic(*, t_{n+1})
719
+ if (pos + 2 >= names .length ) return false ;
720
+
721
+ final int POS_COLLECT_ARGS = pos ;
722
+ final int POS_TABLE_SWITCH = pos + 1 ;
723
+ final int POS_UNBOX_RESULT = pos + 2 ;
724
+
725
+ Name collectArgs = names [POS_COLLECT_ARGS ];
726
+ Name tableSwitch = names [POS_TABLE_SWITCH ];
727
+ Name unboxResult = names [POS_UNBOX_RESULT ];
728
+ return tableSwitch .refersTo (MethodHandleImpl .class , "tableSwitch" ) &&
729
+ collectArgs .isInvokeBasic () &&
730
+ unboxResult .isInvokeBasic () &&
731
+ tableSwitch .lastUseIndex (collectArgs ) == 3 && // t_{n+1}:L=MethodHandleImpl.<invoker>(*, *, *, t_{n});
732
+ lastUseIndex (collectArgs ) == POS_TABLE_SWITCH && // t_{n} is local: used only in t_{n+1}
733
+ unboxResult .lastUseIndex (tableSwitch ) == 1 && // t_{n+2}:?=MethodHandle.invokeBasic(*, t_{n+1})
734
+ lastUseIndex (tableSwitch ) == POS_UNBOX_RESULT ; // t_{n+1} is local: used only in t_{n+2}
735
+ }
736
+
710
737
/**
711
738
* Check if i-th name is a start of the loop idiom.
712
739
*/
@@ -1067,24 +1094,13 @@ static class NamedFunction {
1067
1094
final MemberName member ;
1068
1095
private @ Stable MethodHandle resolvedHandle ;
1069
1096
@ Stable MethodHandle invoker ;
1070
- private final MethodHandleImpl .Intrinsic intrinsicName ;
1071
1097
1072
1098
NamedFunction (MethodHandle resolvedHandle ) {
1073
- this (resolvedHandle .internalMemberName (), resolvedHandle , MethodHandleImpl .Intrinsic .NONE );
1074
- }
1075
- NamedFunction (MethodHandle resolvedHandle , MethodHandleImpl .Intrinsic intrinsic ) {
1076
- this (resolvedHandle .internalMemberName (), resolvedHandle , intrinsic );
1099
+ this (resolvedHandle .internalMemberName (), resolvedHandle );
1077
1100
}
1078
1101
NamedFunction (MemberName member , MethodHandle resolvedHandle ) {
1079
- this (member , resolvedHandle , MethodHandleImpl .Intrinsic .NONE );
1080
- }
1081
- NamedFunction (MemberName member , MethodHandle resolvedHandle , MethodHandleImpl .Intrinsic intrinsic ) {
1082
1102
this .member = member ;
1083
1103
this .resolvedHandle = resolvedHandle ;
1084
- this .intrinsicName = intrinsic ;
1085
- assert (resolvedHandle == null ||
1086
- resolvedHandle .intrinsicName () == MethodHandleImpl .Intrinsic .NONE ||
1087
- resolvedHandle .intrinsicName () == intrinsic ) : resolvedHandle .intrinsicName () + " != " + intrinsic ;
1088
1104
// The following assert is almost always correct, but will fail for corner cases, such as PrivateInvokeTest.
1089
1105
//assert(!isInvokeBasic(member));
1090
1106
}
@@ -1097,7 +1113,6 @@ static class NamedFunction {
1097
1113
// necessary to pass BigArityTest
1098
1114
this .member = Invokers .invokeBasicMethod (basicInvokerType );
1099
1115
}
1100
- this .intrinsicName = MethodHandleImpl .Intrinsic .NONE ;
1101
1116
assert (isInvokeBasic (member ));
1102
1117
}
1103
1118
@@ -1250,7 +1265,15 @@ public boolean isConstantZero() {
1250
1265
}
1251
1266
1252
1267
public MethodHandleImpl .Intrinsic intrinsicName () {
1253
- return intrinsicName ;
1268
+ return resolvedHandle != null
1269
+ ? resolvedHandle .intrinsicName ()
1270
+ : MethodHandleImpl .Intrinsic .NONE ;
1271
+ }
1272
+
1273
+ public Object intrinsicData () {
1274
+ return resolvedHandle != null
1275
+ ? resolvedHandle .intrinsicData ()
1276
+ : null ;
1254
1277
}
1255
1278
}
1256
1279
@@ -1732,15 +1755,15 @@ private static void createFormsFor(BasicType type) {
1732
1755
Name [] idNames = new Name [] { argument (0 , L_TYPE ), argument (1 , type ) };
1733
1756
idForm = new LambdaForm (2 , idNames , 1 , Kind .IDENTITY );
1734
1757
idForm .compileToBytecode ();
1735
- idFun = new NamedFunction (idMem , SimpleMethodHandle .make (idMem .getInvocationType (), idForm ),
1736
- MethodHandleImpl .Intrinsic .IDENTITY );
1758
+ idFun = new NamedFunction (idMem , MethodHandleImpl . makeIntrinsic ( SimpleMethodHandle .make (idMem .getInvocationType (), idForm ),
1759
+ MethodHandleImpl .Intrinsic .IDENTITY )) ;
1737
1760
1738
1761
Object zeValue = Wrapper .forBasicType (btChar ).zero ();
1739
1762
Name [] zeNames = new Name [] { argument (0 , L_TYPE ), new Name (idFun , zeValue ) };
1740
1763
zeForm = new LambdaForm (1 , zeNames , 1 , Kind .ZERO );
1741
1764
zeForm .compileToBytecode ();
1742
- zeFun = new NamedFunction (zeMem , SimpleMethodHandle .make (zeMem .getInvocationType (), zeForm ),
1743
- MethodHandleImpl .Intrinsic .ZERO );
1765
+ zeFun = new NamedFunction (zeMem , MethodHandleImpl . makeIntrinsic ( SimpleMethodHandle .make (zeMem .getInvocationType (), zeForm ),
1766
+ MethodHandleImpl .Intrinsic .ZERO )) ;
1744
1767
}
1745
1768
1746
1769
LF_zero [ord ] = zeForm ;
0 commit comments