blob: 595ff58aecf318372352cffeb5136644c2a8bc18 [file] [log] [blame]
// Copyright (c) 2020, 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.classmerging;
import com.android.tools.r8.utils.Timing;
import java.util.Collection;
import java.util.LinkedList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
/**
* This is a simple policy executor that ensures regular sequential execution of policies. It should
* primarily be readable and correct. The SimplePolicyExecutor should be a reference implementation,
* against which more efficient policy executors can be compared.
*/
public abstract class PolicyExecutor<MG extends MergeGroup> {
/**
* Given an initial collection of class groups which can potentially be merged, run all of the
* policies registered to this policy executor on the class groups yielding a new collection of
* class groups.
*/
// TODO(b/270398965): Replace LinkedList.
@SuppressWarnings("JdkObsolete")
public Collection<MG> run(
Collection<MG> inputGroups,
Collection<? extends Policy> policies,
ExecutorService executorService,
Timing timing)
throws ExecutionException {
LinkedList<MG> linkedGroups;
if (inputGroups instanceof LinkedList) {
linkedGroups = (LinkedList<MG>) inputGroups;
} else {
linkedGroups = new LinkedList<>(inputGroups);
}
for (Policy policy : policies) {
if (policy.shouldSkipPolicy()) {
continue;
}
timing.begin(policy.getName());
linkedGroups = apply(policy, linkedGroups, executorService);
timing.end();
policy.clear();
if (linkedGroups.isEmpty()) {
break;
}
// Any policy should not return any trivial groups.
assert linkedGroups.stream().allMatch(group -> group.size() >= 2);
}
return linkedGroups;
}
protected abstract LinkedList<MG> apply(
Policy policy, LinkedList<MG> linkedGroups, ExecutorService executorService)
throws ExecutionException;
}