5959import java .util .HashSet ;
6060import java .util .List ;
6161import java .util .Map ;
62+ import java .util .Objects ;
6263import java .util .Optional ;
6364import java .util .Queue ;
6465import java .util .Set ;
@@ -444,22 +445,30 @@ private void step2ComputeTopologicalOrder() {
444445 currentPath .add (frames [0 ]);
445446 final Set <Frame > marked = new HashSet <>();
446447 marked .add (frames [0 ]);
447- while (!currentPath .isEmpty ()) {
448- final Frame currentNode = currentPath .peek ();
449- final List <Frame > forwardNodes = new ArrayList <>();
450-
451- // This could be improved if we have to successor list directly...
452- final Frame [] frames = getFrames ();
453- for (final Frame frame : frames ) {
454- // Maybe null due to unreachable statements in bytecode
455- if (frame != null ) {
456- for (final FrameCFGEdge edge : frame .predecessors ) {
457- if (edge .fromIndex () == currentNode .elementIndex && edge .flowType () == FlowType .FORWARD ) {
458- forwardNodes .add (frame );
448+
449+ final Map <Frame , List <Frame >> successors = new HashMap <>();
450+ for (final Frame frame : frames ) {
451+ if (frame != null ) {
452+
453+ for (final FrameCFGEdge edge : frame .predecessors ) {
454+ if (edge .flowType () == FlowType .FORWARD ) {
455+ final Frame fromFrame = frames [edge .fromIndex ()];
456+ if (fromFrame == null ) {
457+ illegalState ("fromFrame == null !, for " + edge );
459458 }
459+ final List <Frame > successorsList = successors .computeIfAbsent (fromFrame , k -> new ArrayList <>());
460+ successorsList .add (frame );
460461 }
461462 }
462463 }
464+ }
465+
466+ while (!currentPath .isEmpty ()) {
467+ final Frame currentNode = currentPath .peek ();
468+
469+ final List <Frame > forwardNodes ;
470+
471+ forwardNodes = Objects .requireNonNullElseGet (successors .get (currentNode ), ArrayList ::new );
463472
464473 // We sort by index in the code model to make this reproducible...
465474 forwardNodes .sort (Comparator .comparingInt (o -> o .elementIndex ));
@@ -701,7 +710,7 @@ private void step4FollowCFGAndInterpret(final CodeModel code) {
701710
702711 for (final Frame frame : topologicalOrder ) {
703712 boolean isExceptionHandler = false ;
704- final CodeElement frameElement = cm . elementList (). get ( frame .elementIndex ) ;
713+ final CodeElement frameElement = frame .codeElement ;
705714 if (frameElement instanceof final LabelTarget labelTarget ) {
706715 // Check is this is an exception handler
707716 isExceptionHandler = exceptionHandlers .contains (labelTarget .label ());
@@ -1225,7 +1234,7 @@ protected void parse_INVOKEDYNAMIC(final InvokeDynamicInstruction node, final Fr
12251234 }
12261235 final List <Value > bootstrapArguments = new ArrayList <>();
12271236
1228- final Value invokerType = ir .defineRuntimeclassReference (owner );
1237+ final Value invokerType = outgoing . control .defineRuntimeclassReference (owner );
12291238 final ClassDesc lookupOwner = ClassDesc .of (MethodHandles .Lookup .class .getName ());
12301239
12311240 // Default bootstrap arguments
@@ -1256,7 +1265,7 @@ protected void parse_INVOKEDYNAMIC(final InvokeDynamicInstruction node, final Fr
12561265 break ;
12571266 }
12581267 }
1259- final Value bootstrapInvocation = new InvokeStatic (bootstrapMethod .owner (), ir .defineRuntimeclassReference (bootstrapMethod .owner ()), bootstrapMethod .methodName (), bootstrapMethodType , bootstrapArguments );
1268+ final Value bootstrapInvocation = new InvokeStatic (bootstrapMethod .owner (), outgoing . control .defineRuntimeclassReference (bootstrapMethod .owner ()), bootstrapMethod .methodName (), bootstrapMethodType , bootstrapArguments );
12601269
12611270 final List <Value > dynamicArguments = new ArrayList <>();
12621271 for (int i = 0 ; i < expectedarguments ; i ++) {
@@ -1635,7 +1644,7 @@ private void parse_INVOKESTATIC(final ClassDesc owner, final String methodName,
16351644 final Status outgoing = frame .copyIncomingToOutgoing ();
16361645 assertMinimumStackSize (outgoing , args .length );
16371646
1638- final RuntimeclassReference runtimeClass = ir .defineRuntimeclassReference (owner );
1647+ final RuntimeclassReference runtimeClass = outgoing . control .defineRuntimeclassReference (owner );
16391648 final ClassInitialization init = new ClassInitialization (runtimeClass );
16401649
16411650 final List <Value > arguments = new ArrayList <>();
@@ -1718,7 +1727,6 @@ protected void parse_IF_ICMP_OP(final BranchInstruction node, final Frame frame,
17181727 final If next = new If (numericCondition );
17191728
17201729 outgoing .control = outgoing .control .controlFlowsTo (next , FlowType .FORWARD );
1721- outgoing .memory = outgoing .memory .memoryFlowsTo (next );
17221730 frame .entryPoint = next ;
17231731
17241732 final int codeElementIndex = labelToIndex .get (node .target ());
@@ -1742,7 +1750,6 @@ protected void parse_IF_NUMERIC_X(final BranchInstruction node, final Frame fram
17421750 final If next = new If (numericCondition );
17431751
17441752 outgoing .control = outgoing .control .controlFlowsTo (next , FlowType .FORWARD );
1745- outgoing .memory = outgoing .memory .memoryFlowsTo (next );
17461753 frame .entryPoint = next ;
17471754
17481755 final int codeElementIndex = labelToIndex .get (node .target ());
@@ -1766,7 +1773,6 @@ protected void parse_IF_REFERENCETEST_X(final BranchInstruction node, final Fram
17661773 final If next = new If (referenceCondition );
17671774
17681775 outgoing .control = outgoing .control .controlFlowsTo (next , FlowType .FORWARD );
1769- outgoing .memory = outgoing .memory .memoryFlowsTo (next );
17701776 frame .entryPoint = next ;
17711777
17721778 final int codeElementIndex = labelToIndex .get (node .target ());
@@ -1791,7 +1797,6 @@ protected void parse_IF_ACMP_OP(final BranchInstruction node, final Frame frame,
17911797 final If next = new If (condition );
17921798
17931799 outgoing .control = outgoing .control .controlFlowsTo (next , FlowType .FORWARD );
1794- outgoing .memory = outgoing .memory .memoryFlowsTo (next );
17951800 frame .entryPoint = next ;
17961801
17971802 final int codeElementIndex = labelToIndex .get (node .target ());
@@ -1856,7 +1861,7 @@ private Value constantToValue(final Node control, final ConstantDesc constantDes
18561861 case final Long l -> control .definePrimitiveLong (l );
18571862 case final Float f -> control .definePrimitiveFloat (f );
18581863 case final Double d -> control .definePrimitiveDouble (d );
1859- case final ClassDesc classDesc -> ir .defineRuntimeclassReference (classDesc );
1864+ case final ClassDesc classDesc -> control .defineRuntimeclassReference (classDesc );
18601865 case final MethodTypeDesc mtd -> ir .defineMethodType (mtd );
18611866 case final MethodHandleDesc mh -> ir .defineMethodHandle (mh );
18621867 case null , default -> {
@@ -1935,7 +1940,7 @@ private void parse_PUTFIELD(final ClassDesc owner, final ClassDesc fieldType, fi
19351940 private void parse_GETSTATIC (final ClassDesc owner , final ClassDesc fieldType , final String fieldName , final Frame frame ) {
19361941 final Status outgoing = frame .copyIncomingToOutgoing ();
19371942
1938- final RuntimeclassReference ri = ir .defineRuntimeclassReference (owner );
1943+ final RuntimeclassReference ri = outgoing . control .defineRuntimeclassReference (owner );
19391944 final ClassInitialization init = new ClassInitialization (ri );
19401945
19411946 outgoing .memory = outgoing .memory .memoryFlowsTo (init );
@@ -1948,12 +1953,12 @@ private void parse_GETSTATIC(final ClassDesc owner, final ClassDesc fieldType, f
19481953 }
19491954
19501955 private void parse_PUTSTATIC (final ClassDesc owner , final ClassDesc fieldType , final String fieldName , final Frame frame ) {
1951- final RuntimeclassReference ri = ir .defineRuntimeclassReference (owner );
1952- final ClassInitialization init = new ClassInitialization (ri );
1953-
19541956 final Status outgoing = frame .copyIncomingToOutgoing ();
19551957 assertMinimumStackSize (outgoing , 1 );
19561958
1959+ final RuntimeclassReference ri = outgoing .control .defineRuntimeclassReference (owner );
1960+ final ClassInitialization init = new ClassInitialization (ri );
1961+
19571962 outgoing .memory = outgoing .memory .memoryFlowsTo (init );
19581963
19591964 final Value v = outgoing .pop ();
@@ -1965,11 +1970,11 @@ private void parse_PUTSTATIC(final ClassDesc owner, final ClassDesc fieldType, f
19651970 }
19661971
19671972 private void parse_NEW (final ClassDesc type , final Frame frame ) {
1968- final RuntimeclassReference ri = ir .defineRuntimeclassReference (type );
1969- final ClassInitialization init = new ClassInitialization (ri );
1970-
19711973 final Status outgoing = frame .copyIncomingToOutgoing ();
19721974
1975+ final RuntimeclassReference ri = outgoing .control .defineRuntimeclassReference (type );
1976+ final ClassInitialization init = new ClassInitialization (ri );
1977+
19731978 final New n = new New (init );
19741979
19751980 outgoing .control = outgoing .control .controlFlowsTo (init , FlowType .FORWARD );
@@ -2025,7 +2030,7 @@ private void parse_CHECKCAST(final ClassDesc typeToCheck, final Frame frame) {
20252030 final Status outgoing = frame .copyIncomingToOutgoing ();
20262031
20272032 final Value objectToCheck = outgoing .peek ();
2028- final RuntimeclassReference expectedType = ir .defineRuntimeclassReference (typeToCheck );
2033+ final RuntimeclassReference expectedType = outgoing . control .defineRuntimeclassReference (typeToCheck );
20292034
20302035 final ClassInitialization classInit = new ClassInitialization (expectedType );
20312036 outgoing .control = outgoing .control .controlFlowsTo (classInit , FlowType .FORWARD );
@@ -2039,7 +2044,7 @@ private void parse_INSTANCEOF(final ClassDesc typeToCheck, final Frame frame) {
20392044 assertMinimumStackSize (outgoing , 1 );
20402045
20412046 final Value objectToCheck = outgoing .pop ();
2042- final RuntimeclassReference expectedType = ir .defineRuntimeclassReference (typeToCheck );
2047+ final RuntimeclassReference expectedType = outgoing . control .defineRuntimeclassReference (typeToCheck );
20432048
20442049 final ClassInitialization classInit = new ClassInitialization (expectedType );
20452050 outgoing .control = outgoing .control .controlFlowsTo (classInit , FlowType .FORWARD );
0 commit comments