| // Copyright (c) 2021, 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.desugar; |
| |
| import com.android.tools.r8.graph.DexEncodedMethod; |
| import com.android.tools.r8.graph.DexMember; |
| import com.android.tools.r8.graph.DexProgramClass; |
| import com.android.tools.r8.graph.DexReference; |
| import com.android.tools.r8.graph.ProgramMethod; |
| import com.android.tools.r8.utils.ThreadUtils; |
| import com.google.common.collect.Sets; |
| import java.util.ArrayList; |
| import java.util.Comparator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.concurrent.ConcurrentHashMap; |
| import java.util.concurrent.ExecutionException; |
| import java.util.concurrent.ExecutorService; |
| import java.util.function.BiConsumer; |
| import java.util.function.Supplier; |
| |
| public class ProgramAdditions implements BiConsumer<DexMember<?, ?>, Supplier<ProgramMethod>> { |
| private final Set<DexReference> added = Sets.newConcurrentHashSet(); |
| private final Map<DexProgramClass, List<DexEncodedMethod>> additions = new ConcurrentHashMap<>(); |
| |
| @Override |
| public synchronized void accept( |
| DexMember<?, ?> reference, Supplier<ProgramMethod> programMethodSupplier) { |
| if (added.add(reference)) { |
| ProgramMethod method = programMethodSupplier.get(); |
| List<DexEncodedMethod> methods = |
| additions.computeIfAbsent(method.getHolder(), k -> new ArrayList<>()); |
| synchronized (methods) { |
| assert !methods.contains(method.getDefinition()); |
| assert method.getHolder().lookupProgramMethod(method.getReference()) == null; |
| methods.add(method.getDefinition()); |
| } |
| } |
| } |
| |
| public void apply(ExecutorService executorService) throws ExecutionException { |
| ThreadUtils.processMap( |
| additions, |
| (clazz, methods) -> { |
| methods.sort(Comparator.comparing(DexEncodedMethod::getReference)); |
| clazz.getMethodCollection().addDirectMethods(methods); |
| }, |
| executorService); |
| } |
| } |