Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1afe81f authored by Makoto Onuki's avatar Makoto Onuki Committed by Android (Google) Code Review
Browse files

Merge "[Ravenwood] Faster framework-minus-apex processing" into main

parents 185f2ecc 028ad699
Loading
Loading
Loading
Loading
+15 −17
Original line number Diff line number Diff line
@@ -43,29 +43,14 @@ genrule_defaults {
    ],
    out: [
        "ravenwood.jar",

        // Following files are created just as FYI.
        "hoststubgen_framework-minus-apex_keep_all.txt",
        "hoststubgen_framework-minus-apex_dump.txt",

        "hoststubgen_framework-minus-apex.log",
        "hoststubgen_framework-minus-apex_stats.csv",
        "hoststubgen_framework-minus-apex_apis.csv",
    ],
}

framework_minus_apex_cmd = "$(location hoststubgen) " +
    "@$(location :ravenwood-standard-options) " +

    "--debug-log $(location hoststubgen_framework-minus-apex.log) " +
    "--stats-file $(location hoststubgen_framework-minus-apex_stats.csv) " +
    "--supported-api-list-file $(location hoststubgen_framework-minus-apex_apis.csv) " +

    "--out-impl-jar $(location ravenwood.jar) " +

    "--gen-keep-all-file $(location hoststubgen_framework-minus-apex_keep_all.txt) " +
    "--gen-input-dump-file $(location hoststubgen_framework-minus-apex_dump.txt) " +

    "--in-jar $(location :framework-minus-apex-for-hoststubgen) " +
    "--policy-override-file $(location :ravenwood-framework-policies) " +
    "--annotation-allowed-classes-file $(location :ravenwood-annotation-allowed-classes) "
@@ -133,13 +118,26 @@ java_genrule {
// Build framework-minus-apex.ravenwood-base without sharding.
// We extract the various dump files from this one, rather than the sharded ones, because
// some dumps use the output from other classes (e.g. base classes) which may not be in the
// same shard.
// same shard. Also some of the dump files ("apis") may be slow even when sharded, because
// the output contains the information from all the input classes, rather than the output classes.
// Not using sharding is fine for this module because it's only used for collecting the
// dump / stats files, which don't have to happen regularly.
java_genrule {
    name: "framework-minus-apex.ravenwood-base_all",
    defaults: ["framework-minus-apex.ravenwood-base_defaults"],
    cmd: framework_minus_apex_cmd,
    cmd: framework_minus_apex_cmd +
        "--stats-file $(location hoststubgen_framework-minus-apex_stats.csv) " +
        "--supported-api-list-file $(location hoststubgen_framework-minus-apex_apis.csv) " +

        "--gen-keep-all-file $(location hoststubgen_framework-minus-apex_keep_all.txt) " +
        "--gen-input-dump-file $(location hoststubgen_framework-minus-apex_dump.txt) ",

    out: [
        "hoststubgen_framework-minus-apex_keep_all.txt",
        "hoststubgen_framework-minus-apex_dump.txt",
        "hoststubgen_framework-minus-apex_stats.csv",
        "hoststubgen_framework-minus-apex_apis.csv",
    ],
}

// Marge all the sharded jars
+51 −46
Original line number Diff line number Diff line
@@ -58,17 +58,19 @@ class HostStubGen(val options: HostStubGenOptions) {

        // Dump the classes, if specified.
        options.inputJarDumpFile.ifSet {
            log.iTime("Dump file created at $it") {
                PrintWriter(it).use { pw -> allClasses.dump(pw) }
            log.i("Dump file created at $it")
            }
        }

        options.inputJarAsKeepAllFile.ifSet {
            PrintWriter(it).use {
                pw -> allClasses.forEach {
                    classNode -> printAsTextPolicy(pw, classNode)
            log.iTime("Dump file created at $it") {
                PrintWriter(it).use { pw ->
                    allClasses.forEach { classNode ->
                        printAsTextPolicy(pw, classNode)
                    }
                }
            }
            log.i("Dump file created at $it")
        }

        // Build the filters.
@@ -91,16 +93,18 @@ class HostStubGen(val options: HostStubGenOptions) {

        // Dump statistics, if specified.
        options.statsFile.ifSet {
            log.iTime("Dump file created at $it") {
                PrintWriter(it).use { pw -> stats.dumpOverview(pw) }
            log.i("Dump file created at $it")
            }
        }
        options.apiListFile.ifSet {
            log.iTime("API list file created at $it") {
                PrintWriter(it).use { pw ->
                    // TODO, when dumping a jar that's not framework-minus-apex.jar, we need to feed
                    // framework-minus-apex.jar so that we can dump inherited methods from it.
                    ApiDumper(pw, allClasses, null, filter).dump()
                }
            log.i("API list file created at $it")
            }
        }
    }

@@ -221,8 +225,7 @@ class HostStubGen(val options: HostStubGenOptions) {
        log.i("Converting %s into [stub: %s, impl: %s] ...", inJar, outStubJar, outImplJar)
        log.i("ASM CheckClassAdapter is %s", if (enableChecker) "enabled" else "disabled")

        val start = System.currentTimeMillis()

        log.iTime("Transforming jar") {
            val packageRedirector = PackageRedirectRemapper(options.packageRedirects)

            var itemIndex = 0
@@ -242,14 +245,17 @@ class HostStubGen(val options: HostStubGenOptions) {
                            val inEntries = inZip.entries()
                            while (inEntries.hasMoreElements()) {
                                val entry = inEntries.nextElement()
                            val inShard = (shardStart <= itemIndex) && (itemIndex < shardNextStart)
                                val inShard = (shardStart <= itemIndex)
                                        && (itemIndex < shardNextStart)
                                itemIndex++
                                if (!inShard) {
                                    continue
                                }
                            convertSingleEntry(inZip, entry, stubOutStream, implOutStream,
                                convertSingleEntry(
                                    inZip, entry, stubOutStream, implOutStream,
                                    filter, packageRedirector, remapper,
                                    enableChecker, classes, errors, stats)
                                    enableChecker, classes, errors, stats
                                )
                                numItemsProcessed++
                            }
                            log.i("Converted all entries.")
@@ -259,9 +265,8 @@ class HostStubGen(val options: HostStubGenOptions) {
                    outImplJar?.let { log.i("Created impl: $it") }
                }
            }
        val end = System.currentTimeMillis()
        log.i("Done transforming the jar in %.1f second(s). %d / %d item(s) processed.",
            (end - start) / 1000.0, numItemsProcessed, numItems)
            log.i("%d / %d item(s) processed.", numItemsProcessed, numItems)
        }
    }

    private fun <T> maybeWithZipOutputStream(filename: String?, block: (ZipOutputStream?) -> T): T {
+10 −0
Original line number Diff line number Diff line
@@ -185,6 +185,16 @@ class HostStubGenLogger {
        println(LogLevel.Debug, format, *args)
    }

    inline fun <T> iTime(message: String, block: () -> T): T {
        val start = System.currentTimeMillis()
        val ret = block()
        val end = System.currentTimeMillis()

        log.i("%s: took %.1f second(s).", message, (end - start) / 1000.0)

        return ret
    }

    inline fun forVerbose(block: () -> Unit) {
        if (isEnabled(LogLevel.Verbose)) {
            block()
+38 −37
Original line number Diff line number Diff line
@@ -184,9 +184,7 @@ class ClassNodes {
         * Load all the classes, without code.
         */
        fun loadClassStructures(inJar: String): ClassNodes {
            log.i("Reading class structure from $inJar ...")
            val start = System.currentTimeMillis()

            log.iTime("Reading class structure from $inJar") {
                val allClasses = ClassNodes()

                log.withIndent {
@@ -200,8 +198,11 @@ class ClassNodes {
                                if (entry.name.endsWith(".class")) {
                                    val cr = ClassReader(bis)
                                    val cn = ClassNode()
                                cr.accept(cn, ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG
                                        or ClassReader.SKIP_FRAMES)
                                    cr.accept(
                                        cn, ClassReader.SKIP_CODE
                                                or ClassReader.SKIP_DEBUG
                                                or ClassReader.SKIP_FRAMES
                                    )
                                    if (!allClasses.addClass(cn)) {
                                        log.w("Duplicate class found: ${cn.name}")
                                    }
@@ -209,7 +210,9 @@ class ClassNodes {
                                    // Seems like it's an ART jar file. We can't process it.
                                    // It's a fatal error.
                                    throw InvalidJarFileException(
                                    "$inJar is not a desktop jar file. It contains a *.dex file.")
                                        "$inJar is not a desktop jar file."
                                        + " It contains a *.dex file."
                                    )
                                } else {
                                    // Unknown file type. Skip.
                                    while (bis.available() > 0) {
@@ -223,10 +226,8 @@ class ClassNodes {
                if (allClasses.size == 0) {
                    log.w("$inJar contains no *.class files.")
                }

            val end = System.currentTimeMillis()
            log.i("Done reading class structure in %.1f second(s).", (end - start) / 1000.0)
                return allClasses
            }
        }
    }
}
 No newline at end of file