blob: 07471e78c5c3263729090bb1f6b4b0fb8bc91cf7 [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.ir.optimize.enums;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.optimize.enums.EnumInstanceFieldData.EnumInstanceFieldKnownData;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
public class EnumDataMap {
private final ImmutableMap<DexType, EnumData> map;
public static EnumDataMap empty() {
return new EnumDataMap(ImmutableMap.of());
}
public EnumDataMap(ImmutableMap<DexType, EnumData> map) {
this.map = map;
}
public boolean isUnboxedEnum(DexType type) {
return map.containsKey(type);
}
public boolean isEmpty() {
return map.isEmpty();
}
public Set<DexType> getUnboxedEnums() {
return map.keySet();
}
public EnumInstanceFieldKnownData getInstanceFieldData(
DexType enumType, DexField enumInstanceField) {
assert map.containsKey(enumType);
return map.get(enumType).getInstanceFieldData(enumInstanceField);
}
public boolean hasUnboxedValueFor(DexField enumStaticField) {
return isUnboxedEnum(enumStaticField.holder)
&& map.get(enumStaticField.holder).hasUnboxedValueFor(enumStaticField);
}
public int getUnboxedValue(DexField enumStaticField) {
assert map.containsKey(enumStaticField.holder);
return map.get(enumStaticField.holder).getUnboxedValue(enumStaticField);
}
public int getValuesSize(DexType enumType) {
assert map.containsKey(enumType);
return map.get(enumType).getValuesSize();
}
public boolean matchesValuesField(DexField staticField) {
assert map.containsKey(staticField.holder);
return map.get(staticField.holder).matchesValuesField(staticField);
}
public static class EnumData {
static final int INVALID_VALUES_SIZE = -1;
// Map each enum instance field to the list of field known data.
final ImmutableMap<DexField, EnumInstanceFieldKnownData> instanceFieldMap;
// Map each enum instance (static field) to the unboxed integer value.
final ImmutableMap<DexField, Integer> unboxedValues;
// Fields matching the $VALUES content and type, usually one.
final ImmutableSet<DexField> valuesFields;
// Size of the $VALUES field, if the valuesFields set is empty, set to INVALID_VALUES_SIZE.
final int valuesSize;
public EnumData(
ImmutableMap<DexField, EnumInstanceFieldKnownData> instanceFieldMap,
ImmutableMap<DexField, Integer> unboxedValues,
ImmutableSet<DexField> valuesFields,
int valuesSize) {
this.instanceFieldMap = instanceFieldMap;
this.unboxedValues = unboxedValues;
this.valuesFields = valuesFields;
this.valuesSize = valuesSize;
}
public EnumInstanceFieldKnownData getInstanceFieldData(DexField enumInstanceField) {
assert instanceFieldMap.containsKey(enumInstanceField);
return instanceFieldMap.get(enumInstanceField);
}
public int getUnboxedValue(DexField field) {
assert unboxedValues.containsKey(field);
return unboxedValues.get(field);
}
public boolean hasUnboxedValueFor(DexField field) {
return unboxedValues.get(field) != null;
}
public boolean matchesValuesField(DexField field) {
return valuesFields.contains(field);
}
public int getValuesSize() {
assert valuesSize != INVALID_VALUES_SIZE;
return valuesSize;
}
}
}