blob: f17bab96b5fd6f71887cf2c50e8464bfeb68ab51 [file] [log] [blame]
// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
import static com.android.tools.r8.utils.ExceptionUtils.unwrapExecutionException;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.Marker.Tool;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.ir.desugar.PrefixRewritingMapper;
import com.android.tools.r8.jar.CfApplicationWriter;
import com.android.tools.r8.naming.PrefixRewritingNamingLens;
import com.android.tools.r8.shaking.AnnotationRemover;
import com.android.tools.r8.shaking.L8TreePruner;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.StringDiagnostic;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
/**
* The L8 compiler.
*/
@Keep
public class L8 {
/**
* Main API entry for the L8 compiler.
*
* @param command L8 command.
*/
public static void run(L8Command command) throws CompilationFailedException {
runForTesting(
command.getInputApp(),
command.getInternalOptions(),
command.isShrinking(),
command.getD8Command(),
command.getR8Command());
}
/**
* Main API entry for the L8 compiler.
*
* @param command L8 command.
* @param executor executor service from which to get threads for multi-threaded processing.
*/
public static void run(L8Command command, ExecutorService executor)
throws CompilationFailedException {
run(
command.getInputApp(),
command.getInternalOptions(),
command.isShrinking(),
command.getD8Command(),
command.getR8Command(),
executor);
}
static void runForTesting(
AndroidApp app,
InternalOptions options,
boolean shrink,
D8Command d8Command,
R8Command r8Command)
throws CompilationFailedException {
ExecutorService executorService = ThreadUtils.getExecutorService(options);
run(app, options, shrink, d8Command, r8Command, executorService);
}
private static void run(
AndroidApp app,
InternalOptions options,
boolean shrink,
D8Command d8Command,
R8Command r8Command,
ExecutorService executorService)
throws CompilationFailedException {
try {
ExceptionUtils.withD8CompilationHandler(
options.reporter,
() -> {
desugar(app, options, executorService);
});
if (shrink) {
options.reporter.warning(
new StringDiagnostic("Shrinking of desugared library is work in progress."));
R8.run(r8Command, executorService);
} else {
D8.run(d8Command, executorService);
}
} finally {
executorService.shutdown();
}
}
private static void desugar(
AndroidApp inputApp, InternalOptions options, ExecutorService executor) throws IOException {
Timing timing = new Timing("L8 desugaring");
try {
// Disable global optimizations.
options.disableGlobalOptimizations();
DexApplication app = new ApplicationReader(inputApp, options, timing).read(executor);
PrefixRewritingMapper rewritePrefix =
options.desugaredLibraryConfiguration.createPrefixRewritingMapper(options.itemFactory);
app = new L8TreePruner(options).prune(app, rewritePrefix);
if (app.classes().size() == 0) {
// TODO(b/134732760): report error instead of fatalError.
throw options.reporter.fatalError("Empty desugared library.");
}
AppInfo appInfo = new AppInfo(app);
AppView<?> appView = AppView.createForL8(appInfo, options, rewritePrefix);
IRConverter converter = new IRConverter(appView, timing);
if (!options.testing.disableL8AnnotationRemoval) {
AnnotationRemover.clearAnnotations(appView);
}
app = converter.convert(app, executor);
assert appView.appInfo() == appInfo;
new CfApplicationWriter(
app,
appView,
options,
options.getMarker(Tool.L8),
GraphLense.getIdentityLense(),
PrefixRewritingNamingLens.createPrefixRewritingNamingLens(options, rewritePrefix),
null)
.write(options.getClassFileConsumer(), executor);
options.printWarnings();
} catch (ExecutionException e) {
throw unwrapExecutionException(e);
} finally {
options.signalFinishedToConsumers();
// Dump timings.
if (options.printTimes) {
timing.report();
}
}
}
}