@@ -93,6 +93,11 @@ public void visitEnd() {
93
93
getTypes ();
94
94
getBaselineSize ();
95
95
96
+ if (DEBUG_CONTROL ) {
97
+ for (int i = 1 ; i <= insnList .length ; i ++)
98
+ System .out .printf ("from=%d to=%d frag=%d\n " , 0 ,i ,calcFragmentSize (0 , i ));
99
+ }
100
+
96
101
System .exit (1 );
97
102
}
98
103
@@ -872,4 +877,183 @@ private void getBaselineSize() {
872
877
873
878
if (DEBUG_CONTROL ) System .out .println (Arrays .toString (baselineSize ));
874
879
}
880
+
881
+ private int calcFragmentSize (int from , int to ) {
882
+ // we have to include the instructions
883
+ int size = baselineSize [to ] - baselineSize [from ];
884
+
885
+ // need to include entry trampolines and exit trampolines
886
+ int [] entryPts = new int [to -from ];
887
+ int entryCt = 0 ;
888
+ boolean [] entryDedup = new boolean [to -from ];
889
+ int [] exitPts = new int [insnList .length ];
890
+ int exitCt = 0 ;
891
+ boolean [] exitDedup = new boolean [insnList .length ];
892
+
893
+ for (ControlEdge ce : controlEdges ) {
894
+ boolean from_this = (ce .from >= from && ce .from < to );
895
+ boolean to_this = (ce .to >= from && ce .to < to );
896
+ if (!from_this && to_this && !entryDedup [ce .to -from ]) {
897
+ entryDedup [ce .to -from ] = true ;
898
+ entryPts [entryCt ++] = ce .to ;
899
+ }
900
+ if (from_this && !to_this && !exitDedup [ce .to ]) {
901
+ exitDedup [ce .to ] = true ;
902
+ exitPts [exitCt ++] = ce .to ;
903
+ }
904
+ }
905
+
906
+ if (from == 0 && !entryDedup [0 ]) {
907
+ entryPts [entryCt ++] = 0 ;
908
+ }
909
+
910
+ if (DEBUG_CONTROL ) {
911
+ System .out .printf ("NONLOCAL ENTRY: %s\n " , Arrays .toString (Arrays .copyOfRange (entryPts ,0 ,entryCt )));
912
+ System .out .printf ("NONLOCAL EXIT: %s\n " , Arrays .toString (Arrays .copyOfRange (exitPts ,0 ,exitCt )));
913
+ }
914
+
915
+ // factor out commonalities from the trampolines
916
+ String [] commonEntry = commonTrampoline (entryPts , entryCt );
917
+ String [] commonExit = commonTrampoline (exitPts , exitCt );
918
+
919
+ // common entry code
920
+ // aload; {dup; ipush; aaload; UNBOX; xstore; }; iload; tableswitch
921
+
922
+ size ++;
923
+ for (int i = 0 ; i < commonEntry .length ; i ++) {
924
+ size += localEntrySize (i , commonEntry [i ]);
925
+ }
926
+ size += 13 ; // iload+tswitch
927
+
928
+ // uncommon entry code
929
+
930
+ for (int i = 0 ; i < entryCt ; i ++) {
931
+ size += 4 ; // dispatch vector
932
+ Frame f = types [entryPts [i ]];
933
+ for (int j = 0 ; j < f .sp ; j ++) {
934
+ if (j < commonEntry .length && commonEntry [j ].equals (f .stack [j ])) {
935
+ /* no action */
936
+ } else if (j < nlocal ) {
937
+ size += localEntrySize (j , f .stack [j ]);
938
+ } else {
939
+ size += stackEntrySize (j , f .stack [j ]);
940
+ }
941
+ }
942
+ size += 4 ; // astore
943
+ size += 5 ; // final jump
944
+ }
945
+
946
+ // jump insertion
947
+ size += 3 ;
948
+
949
+ // uncommon exit code
950
+ for (int i = 0 ; i < exitCt ; i ++) {
951
+ Frame f = types [exitPts [i ]];
952
+ for (int j = 0 ; j < f .sp ; j ++) {
953
+ if (j < commonExit .length && commonExit [j ].equals (f .stack [j ])) {
954
+ /* no action */
955
+ } else if (j < nlocal ) {
956
+ size += localExitSize (j , f .stack [j ]);
957
+ } else {
958
+ size += stackExitSize (j , f .stack [j ]);
959
+ }
960
+ }
961
+ size += 3 ; // ipush
962
+ size += 5 ; // jump to combiner
963
+ }
964
+
965
+ // common exit code
966
+ size += 4 ; // aload
967
+ for (int i = 0 ; i < commonExit .length ; i ++) {
968
+ size += localExitSize (i , commonExit [i ]);
969
+ }
970
+ size += 2 ; // pop; ireturn
971
+
972
+ return size ;
973
+ }
974
+
975
+ private int localEntrySize (int loc , String desc ) {
976
+ char c0 = desc .charAt (0 );
977
+ if (c0 == 'T' ) return 0 ; // not loaded
978
+ int sz ;
979
+ switch (c0 ) {
980
+ case '0' :
981
+ case 'U' :
982
+ // just load as a null
983
+ sz = 1 ;
984
+ break ;
985
+ case 'L' :
986
+ case '[' :
987
+ // dup, ipush, aaload, checkcast
988
+ sz = (loc < 128 ) ? 7 : 8 ;
989
+ break ;
990
+ default :
991
+ // dup, ipush, aaload, checkcast, fooValue
992
+ sz = (loc < 128 ) ? 10 : 11 ;
993
+ break ;
994
+ }
995
+ return sz + ((loc < 256 ) ? 2 : 4 );
996
+ }
997
+
998
+ private int localExitSize (int loc , String desc ) {
999
+ char c0 = desc .charAt (0 );
1000
+ if (c0 == 'T' || c0 == '0' || c0 == 'U' ) return 0 ; // not saved
1001
+ int sz = (loc < 256 ) ? 2 : 4 ;
1002
+ switch (c0 ) {
1003
+ case 'L' :
1004
+ case '[' :
1005
+ // dup, ipush, xload, aastore
1006
+ return sz + ((loc < 128 ) ? 4 : 5 );
1007
+ default :
1008
+ // dup, ipush, new, dup, xload, invokespecial, aastore
1009
+ return sz + ((loc < 128 ) ? 11 : 12 );
1010
+ }
1011
+ }
1012
+
1013
+ private int stackEntrySize (int loc , String desc ) {
1014
+ char c0 = desc .charAt (0 );
1015
+ switch (c0 ) {
1016
+ case '0' :
1017
+ case 'U' :
1018
+ // just load as a null
1019
+ return 1 ;
1020
+ case 'L' :
1021
+ case '[' :
1022
+ // aload, ipush, aaload, checkcast
1023
+ return (loc < 128 ) ? 10 : 11 ;
1024
+ default :
1025
+ // aload, ipush, aaload, checkcast, fooValue
1026
+ return (loc < 128 ) ? 13 : 14 ;
1027
+ }
1028
+ }
1029
+
1030
+ private int stackExitSize (int loc , String desc ) {
1031
+ char c0 = desc .charAt (0 );
1032
+ if (c0 == 'T' || c0 == '0' || c0 == 'U' ) return 1 ; // not saved
1033
+ switch (c0 ) {
1034
+ case 'L' :
1035
+ case '[' :
1036
+ // xstore, aload, ipush, xload, aastore
1037
+ return (loc < 128 ) ? 15 : 16 ;
1038
+ default :
1039
+ // xstore, aload, ipush, new, dup, xload, invokespecial, aastore
1040
+ return (loc < 128 ) ? 22 : 23 ;
1041
+ }
1042
+ }
1043
+
1044
+ private String [] commonTrampoline (int [] points , int ct ) {
1045
+ String [] common = null ;
1046
+ for (int i = 0 ; i < ct ; i ++) {
1047
+ Frame f = types [points [i ]];
1048
+ if (common == null ) {
1049
+ common = Arrays .copyOf (f .stack , nlocal );
1050
+ } else {
1051
+ for (int j = 0 ; j < common .length ; j ++) {
1052
+ if (j >= f .sp || !f .stack [j ].equals (common [j ]))
1053
+ common [j ] = "T" ;
1054
+ }
1055
+ }
1056
+ }
1057
+ return common == null ? new String [] { } : common ;
1058
+ }
875
1059
}
0 commit comments