Repository: soot-oss/soot

Issue #1609: CG phase performance degrades for Lombok generated build method
Created: 2021-05-11T19:22:48Z
For some Lombok-generated build methods, the CG phase goes into an endless loop. See attached a small example to reprod. The build() method just calls the constructor of the object using a lot of if-then-else expressions to set default values.
        @javax.annotation.Generated("lombok")
            public CossiInput build() {
            return new CossiInput(facilityId,
                                //   planId, 
                                //   startTime, 
                                //   endTime, 
                                   stackingFilters$set ? stackingFilters : CossiInput.$default$stackingFilters(),
                                   constantAllocationSFs$set ? constantAllocationSFs : CossiInput.$default$constantAllocationSFs(),
                                   volumeProjectionsForShipSorterSfs$set ? volumeProjectionsForShipSorterSfs : CossiInput.$default$volumeProjectionsForShipSorterSfs(),
                                   palletizationChutes$set ? palletizationChutes : CossiInput.$default$palletizationChutes(),
                                  chutesConnectingToExtensionSorters$set ? chutesConnectingToExtensionSorters : CossiInput.$default$chutesConnectingToExtensionSorters(), 
...
If I modify the code and comment out some of these arguments, the CG phase terminates. It doesn't seem to matter which of those I comment out. As long as I comment out at least 3 of them.
Time for Soot after removing 2 arguments: 3:15.38 (i.e. 3 minutes ...)
Time for Soot after removing 3 arguments: 35.954s
Time for Soot after removing 4 arguments: 5.623 s
Time for Soot after removing 5 arguments: 2.489 s
So, something in this code seems to trigger something very exponential in the call-graph construction.
Reprod using the run.sh in the attached zip.
reprod.zip

Duplicate issue #1931: Jimple generation performance issue
Created: 2022-11-24T11:37:05Z
It's not a bug, but a huge performance issue.
Description
If we try to generate JimpleBody for a invoke statement with "hanging" arguments (see code snippet), it will take an exponential time.
Input file

  Java snippet
public class SootIssue {
    void example(
            boolean b1,
            boolean b2,
            boolean b3,
            boolean b4,
            boolean b5,
            boolean b6,
            boolean b7,
            boolean b8,
            boolean b9,
            boolean b10,
            boolean b11,
            boolean b12,
            boolean b13,
            boolean b14,
            boolean b15,
            boolean b16,
            boolean b17,
            boolean b18,
            boolean b19,
            boolean b20,
            boolean b21,
            boolean b22,
            boolean b23,
            boolean b24,
            boolean b25,
            boolean b26,
            boolean b27,
            boolean b28,
            boolean b29,
            boolean b30,
            boolean b31,
            boolean b32
    ) {
        bar(
                (b1) ? 0 : 1,
                (b2) ? 2 : 3,
                (b3) ? 4 : 5,
                (b4) ? 6 : 5,
                (b5) ? 8 : 9,
                (b6) ? 10 : 11,
                (b7) ? 12 : 13,
                (b8) ? 14 : 15,
                (b9) ? 16 : 17,
                (b10) ? 18 : 19,
                (b11) ? 20 : 21,
                (b12) ? 22 : 23,
                (b13) ? 24 : 25,
                (b14) ? 26 : 27,
                (b15) ? 28 : 29,
                (b16) ? 30 : 31,
                (b17) ? 32 : 33,
                (b18) ? 34 : 35,
                (b19) ? 36 : 37,
                (b20) ? 38 : 39,
                (b21) ? 40 : 41,
                (b22) ? 42 : 43,
                (b23) ? 44 : 45,
                (b24) ? 46 : 45,
                (b25) ? 48 : 49,
                (b26) ? 50 : 51,
                (b27) ? 52 : 53,
                (b28) ? 54 : 55,
                (b29) ? 56 : 57,
                (b30) ? 58 : 59,
                (b31) ? 60 : 61,
                (b32) ? 62 : 63
        );
    }

    void bar(
            int a1,
            int a2,
            int a3,
            int a4,
            int a5,
            int a6,
            int a7,
            int a8,
            int a9,
            int a10,
            int a11,
            int a12,
            int a13,
            int a14,
            int a15,
            int a16,
            int a17,
            int a18,
            int a19,
            int a20,
            int a21,
            int a22,
            int a23,
            int a24,
            int a25,
            int a26,
            int a27,
            int a28,
            int a29,
            int a30,
            int a31,
            int a32
    ) {
    }
}
Each variable increases the time of conversion in two times. For this example, it doesn't finish locally on my computer for any reasonable time.

To reproduce
Soot initialization script in Kotlin:
fun initSoot(classpath: String?) {
    G.reset()
    val options = Options.v()

    options.apply {
        set_prepend_classpath(true)
        setPhaseOption("jb", "use-original-names:false")
        set_soot_classpath("")
        set_src_prec(Options.src_prec_only_class)
        set_process_dir(listOf(classpath))
        set_keep_line_number(true)
        set_ignore_classpath_errors(true)
        set_output_format(Options.output_format_jimple)
        set_allow_phantom_refs(true)
        set_full_resolver(true)
    }

    Scene.v().loadNecessaryClasses()
    PackManager.v().runPacks()
}
Expected behavior
There is no fundamental performance issues related to bytecode to 3-address code conversion, so I expect at least a polynomial time in a size of a source file.
Additional context
If we create a local variable for each argument and then call the method, there won't be any performance problems.
Some thoughts:
Looks like there is a problem in soot.asm.AsmMethodSource#addEdges method, because we traverse each possible path in a program instead of traversing each edge once, so it works in O(2^n * poly(n)) time.
Maybe the problem is that we explore every possible stack state instead of merging them earlier.

Closing comment (2022-11-25T04:45:19Z): UPD:
Looks like it's a duplicate of #1609 .