blob: fb545c699d54c647fc9acfd0eab57c61f2dad19d [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.ir.conversion;
import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
import com.android.tools.r8.contexts.CompilationContext.ProcessorContext;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.conversion.callgraph.CallSiteInformation;
import com.android.tools.r8.threading.ThreadingModule;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.ThreadUtils.WorkLoad;
import com.android.tools.r8.utils.collections.ProgramMethodSet;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
/**
* A {@link MethodProcessor} that doesn't persist; rather just processes the given methods one-time,
* along with a default abstraction of concurrent processing.
*/
public class OneTimeMethodProcessor extends MethodProcessorWithWave {
private final MethodProcessorEventConsumer eventConsumer;
private final ProcessorContext processorContext;
private OneTimeMethodProcessor(
MethodProcessorEventConsumer eventConsumer,
ProcessorContext processorContext,
ProgramMethodSet wave) {
this.eventConsumer = eventConsumer;
this.processorContext = processorContext;
this.wave = wave;
}
public static Builder builder(MethodProcessorEventConsumer eventConsumer, AppView<?> appView) {
return builder(eventConsumer, appView.createProcessorContext());
}
public static Builder builder(
MethodProcessorEventConsumer eventConsumer, ProcessorContext processorContext) {
return new Builder(eventConsumer, processorContext);
}
public static OneTimeMethodProcessor create(
ProgramMethod methodToProcess,
MethodProcessorEventConsumer eventConsumer,
AppView<?> appView) {
return create(ProgramMethodSet.create(methodToProcess), eventConsumer, appView);
}
public static OneTimeMethodProcessor create(
ProgramMethod methodToProcess,
MethodProcessorEventConsumer eventConsumer,
ProcessorContext processorContext) {
return create(ProgramMethodSet.create(methodToProcess), eventConsumer, processorContext);
}
public static OneTimeMethodProcessor create(
ProgramMethodSet methodsToProcess,
MethodProcessorEventConsumer eventConsumer,
AppView<?> appView) {
return create(methodsToProcess, eventConsumer, appView.createProcessorContext());
}
public static OneTimeMethodProcessor create(
ProgramMethodSet methodsToProcess,
MethodProcessorEventConsumer eventConsumer,
ProcessorContext processorContext) {
return new OneTimeMethodProcessor(eventConsumer, processorContext, methodsToProcess);
}
private CallSiteInformation callSiteInformation;
@Override
public CallSiteInformation getCallSiteInformation() {
return callSiteInformation != null ? callSiteInformation : super.getCallSiteInformation();
}
public void setCallSiteInformation(CallSiteInformation callSiteInformation) {
this.callSiteInformation = callSiteInformation;
}
@Override
public MethodProcessorEventConsumer getEventConsumer() {
return eventConsumer;
}
@Override
public boolean shouldApplyCodeRewritings(ProgramMethod method) {
return true;
}
@FunctionalInterface
public interface MethodAction {
void accept(ProgramMethod method, MethodProcessingContext methodProcessingContext);
}
public void forEachWaveWithExtension(MethodAction consumer) {
while (!wave.isEmpty()) {
for (ProgramMethod method : wave) {
consumer.accept(method, processorContext.createMethodProcessingContext(method));
}
prepareForWaveExtensionProcessing();
}
}
public void forEachWaveWithExtension(
MethodAction consumer, ThreadingModule threadingModule, ExecutorService executorService)
throws ExecutionException {
while (!wave.isEmpty()) {
ThreadUtils.processItems(
wave,
(method, ignored) ->
consumer.accept(method, processorContext.createMethodProcessingContext(method)),
threadingModule,
executorService,
WorkLoad.HEAVY);
prepareForWaveExtensionProcessing();
}
}
public static class Builder {
private final ProgramMethodSet methodsToProcess = ProgramMethodSet.create();
private final MethodProcessorEventConsumer eventConsumer;
private final ProcessorContext processorContext;
Builder(MethodProcessorEventConsumer eventConsumer, ProcessorContext processorContext) {
this.eventConsumer = eventConsumer;
this.processorContext = processorContext;
}
public Builder add(ProgramMethod methodToProcess) {
methodsToProcess.add(methodToProcess);
return this;
}
public OneTimeMethodProcessor build() {
return create(methodsToProcess, eventConsumer, processorContext);
}
}
}