blob: fb3868abb0993eb648f267fe445b5613d7c45c7e [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.shaking;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.analysis.EnqueuerCheckCastAnalysis;
import com.android.tools.r8.graph.analysis.EnqueuerExceptionGuardAnalysis;
import com.android.tools.r8.graph.analysis.EnqueuerInstanceOfAnalysis;
import com.android.tools.r8.utils.SetUtils;
import com.google.common.collect.Sets;
import java.util.Set;
public class RuntimeTypeCheckInfo {
private final Set<DexType> instanceOfTypes;
private final Set<DexType> checkCastTypes;
private final Set<DexType> exceptionGuardTypes;
public RuntimeTypeCheckInfo(
Set<DexType> instanceOfTypes, Set<DexType> checkCastTypes, Set<DexType> exceptionGuardTypes) {
this.instanceOfTypes = instanceOfTypes;
this.checkCastTypes = checkCastTypes;
this.exceptionGuardTypes = exceptionGuardTypes;
}
public static class Builder
implements EnqueuerInstanceOfAnalysis,
EnqueuerCheckCastAnalysis,
EnqueuerExceptionGuardAnalysis {
private final DexItemFactory factory;
private final Set<DexType> instanceOfTypes = Sets.newIdentityHashSet();
private final Set<DexType> checkCastTypes = Sets.newIdentityHashSet();
private final Set<DexType> exceptionGuardTypes = Sets.newIdentityHashSet();
public Builder(DexItemFactory factory) {
this.factory = factory;
}
public RuntimeTypeCheckInfo build() {
return new RuntimeTypeCheckInfo(instanceOfTypes, checkCastTypes, exceptionGuardTypes);
}
@Override
public void traceCheckCast(DexType type, ProgramMethod context) {
add(type, checkCastTypes);
}
@Override
public void traceInstanceOf(DexType type, ProgramMethod context) {
add(type, instanceOfTypes);
}
@Override
public void traceExceptionGuard(DexType guard, ProgramMethod context) {
add(guard, exceptionGuardTypes);
}
private void add(DexType type, Set<DexType> set) {
DexType baseType = type.toBaseType(factory);
if (baseType.isClassType()) {
set.add(baseType);
}
}
public void attach(Enqueuer enqueuer) {
enqueuer
.registerInstanceOfAnalysis(this)
.registerCheckCastAnalysis(this)
.registerExceptionGuardAnalysis(this);
}
}
public boolean isCheckCastType(DexProgramClass clazz) {
return checkCastTypes.contains(clazz.type);
}
public boolean isInstanceOfType(DexProgramClass clazz) {
return instanceOfTypes.contains(clazz.type);
}
public boolean isExceptionGuardType(DexProgramClass clazz) {
return exceptionGuardTypes.contains(clazz.type);
}
public boolean isRuntimeCheckType(DexProgramClass clazz) {
return isInstanceOfType(clazz) || isCheckCastType(clazz) || isExceptionGuardType(clazz);
}
public RuntimeTypeCheckInfo rewriteWithLens(GraphLens.NonIdentityGraphLens graphLens) {
return new RuntimeTypeCheckInfo(
SetUtils.mapIdentityHashSet(instanceOfTypes, graphLens::lookupType),
SetUtils.mapIdentityHashSet(checkCastTypes, graphLens::lookupType),
SetUtils.mapIdentityHashSet(exceptionGuardTypes, graphLens::lookupType));
}
}