blob: 245f2b4e0cfd1fecdd9d3c147ff995ae665e7bb0 [file] [log] [blame]
// Copyright (c) 2017, 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.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexEncodedMethod.ClassInlinerEligibility;
import com.android.tools.r8.graph.DexEncodedMethod.TrivialInitializer;
import com.android.tools.r8.graph.ParameterUsagesInfo;
import com.android.tools.r8.graph.UpdatableOptimizationInfo;
import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
import com.android.tools.r8.utils.IteratorUtils;
import java.util.BitSet;
import java.util.IdentityHashMap;
import java.util.Map;
public class OptimizationFeedbackDelayed implements OptimizationFeedback {
// Caching of updated optimization info and processed status.
private final Map<DexEncodedMethod, UpdatableOptimizationInfo> optimizationInfos =
new IdentityHashMap<>();
private final Map<DexEncodedMethod, ConstraintWithTarget> processed = new IdentityHashMap<>();
private synchronized UpdatableOptimizationInfo getOptimizationInfoForUpdating(
DexEncodedMethod method) {
UpdatableOptimizationInfo info = optimizationInfos.get(method);
if (info != null) {
return info;
}
info = method.getOptimizationInfo().mutableCopy();
optimizationInfos.put(method, info);
return info;
}
@Override
public synchronized void methodReturnsArgument(DexEncodedMethod method, int argument) {
getOptimizationInfoForUpdating(method).markReturnsArgument(argument);
}
@Override
public synchronized void methodReturnsConstant(DexEncodedMethod method, long value) {
getOptimizationInfoForUpdating(method).markReturnsConstant(value);
}
@Override
public synchronized void methodNeverReturnsNull(DexEncodedMethod method) {
getOptimizationInfoForUpdating(method).markNeverReturnsNull();
}
@Override
public synchronized void methodNeverReturnsNormally(DexEncodedMethod method) {
getOptimizationInfoForUpdating(method).markNeverReturnsNormally();
}
@Override
public synchronized void markProcessed(DexEncodedMethod method, ConstraintWithTarget state) {
processed.put(method, state);
}
@Override
public synchronized void markUseIdentifierNameString(DexEncodedMethod method) {
getOptimizationInfoForUpdating(method).markUseIdentifierNameString();
}
@Override
public synchronized void markCheckNullReceiverBeforeAnySideEffect(
DexEncodedMethod method, boolean mark) {
getOptimizationInfoForUpdating(method).markCheckNullReceiverBeforeAnySideEffect(mark);
}
@Override
public synchronized void markTriggerClassInitBeforeAnySideEffect(
DexEncodedMethod method, boolean mark) {
getOptimizationInfoForUpdating(method).markTriggerClassInitBeforeAnySideEffect(mark);
}
@Override
public synchronized void setClassInlinerEligibility(
DexEncodedMethod method, ClassInlinerEligibility eligibility) {
getOptimizationInfoForUpdating(method).setClassInlinerEligibility(eligibility);
}
@Override
public synchronized void setTrivialInitializer(DexEncodedMethod method, TrivialInitializer info) {
getOptimizationInfoForUpdating(method).setTrivialInitializer(info);
}
@Override
public synchronized void setInitializerEnablingJavaAssertions(DexEncodedMethod method) {
getOptimizationInfoForUpdating(method).setInitializerEnablingJavaAssertions();
}
@Override
public synchronized void setParameterUsages(
DexEncodedMethod method, ParameterUsagesInfo parameterUsagesInfo) {
getOptimizationInfoForUpdating(method).setParameterUsages(parameterUsagesInfo);
}
@Override
public synchronized void setNonNullParamOrThrow(DexEncodedMethod method, BitSet facts) {
getOptimizationInfoForUpdating(method).setNonNullParamOrThrow(facts);
}
@Override
public synchronized void setNonNullParamOnNormalExits(DexEncodedMethod method, BitSet facts) {
getOptimizationInfoForUpdating(method).setNonNullParamOnNormalExits(facts);
}
public void updateVisibleOptimizationInfo() {
// Remove methods that have become obsolete. A method may become obsolete, for example, as a
// result of the class staticizer, which aims to transform virtual methods on companion classes
// into static methods on the enclosing class of the companion class.
IteratorUtils.removeIf(
optimizationInfos.entrySet().iterator(), entry -> entry.getKey().isObsolete());
IteratorUtils.removeIf(processed.entrySet().iterator(), entry -> entry.getKey().isObsolete());
optimizationInfos.forEach(DexEncodedMethod::setOptimizationInfo);
processed.forEach(DexEncodedMethod::markProcessed);
optimizationInfos.clear();
processed.clear();
}
}