Revert "Remove handling of shared synthetics in output"
This reverts commit 5cf6624c2b6263c6554f7f64823f930a8c804891.
Reason for revert: Still used in tests
Change-Id: Id25b4eea24b5e1edee7d6d47d899872603597e3c
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index 90af811..fa7e21d 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -641,11 +641,12 @@
}
// At least one method needs a jumbo string in which case we construct a thread local mapping
// for all code objects and write the processed results into that map.
- // TODO(b/181636450): Reconsider the code mapping setup now that synthetics are never duplicated
- // in outputs.
Map<DexEncodedMethod, DexCode> codeMapping = new IdentityHashMap<>();
for (DexProgramClass clazz : classes) {
- assert !appView.getSyntheticItems().isSharedSynthetic(clazz);
+ // TODO(b/181636450): Reconsider the code mapping setup now that synthetics are never
+ // duplicated in outputs.
+ boolean isSharedSynthetic =
+ appView.getSyntheticItems().getSynthesizingContexts(clazz.getType()).size() > 1;
clazz.forEachMethod(
method -> {
DexCode code =
@@ -654,10 +655,12 @@
application.dexItemFactory,
options.testing.forceJumboStringProcessing);
codeMapping.put(method, code);
- // The mapping now has ownership of the methods code object. This ensures freeing of
- // code resources once the map entry is cleared and also ensures that we don't end up
- // using the incorrect code pointer again later!
- method.removeCode();
+ if (!isSharedSynthetic) {
+ // If the class is not a shared class the mapping now has ownership of the methods
+ // code object. This ensures freeing of code resources once the map entry is cleared
+ // and also ensures that we don't end up using the incorrect code pointer again later!
+ method.removeCode();
+ }
});
}
return MethodToCodeObjectMapping.fromMapBacking(codeMapping);
diff --git a/src/main/java/com/android/tools/r8/dex/FileWriter.java b/src/main/java/com/android/tools/r8/dex/FileWriter.java
index 56a6e0c..889fc27 100644
--- a/src/main/java/com/android/tools/r8/dex/FileWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/FileWriter.java
@@ -653,7 +653,8 @@
}
}
- private void writeEncodedMethods(Iterable<DexEncodedMethod> unsortedMethods) {
+ private void writeEncodedMethods(
+ Iterable<DexEncodedMethod> unsortedMethods, boolean isSharedSynthetic) {
List<DexEncodedMethod> methods = IterableUtils.toNewArrayList(unsortedMethods);
methods.sort(
(a, b) ->
@@ -674,7 +675,7 @@
dest.putUleb128(mixedSectionOffsets.getOffsetFor(code));
// Writing the methods starts to take up memory so we are going to flush the
// code objects since they are no longer necessary after this.
- codeMapping.clearCode(method);
+ codeMapping.clearCode(method, isSharedSynthetic);
}
}
}
@@ -688,9 +689,10 @@
dest.putUleb128(clazz.getMethodCollection().numberOfVirtualMethods());
writeEncodedFields(clazz.staticFields());
writeEncodedFields(clazz.instanceFields());
- assert !appInfo.getSyntheticItems().isSharedSynthetic(clazz);
- writeEncodedMethods(clazz.directMethods());
- writeEncodedMethods(clazz.virtualMethods());
+ boolean isSharedSynthetic =
+ appInfo.getSyntheticItems().getSynthesizingContexts(clazz.getType()).size() > 1;
+ writeEncodedMethods(clazz.directMethods(), isSharedSynthetic);
+ writeEncodedMethods(clazz.virtualMethods(), isSharedSynthetic);
}
private void addStaticFieldValues(DexProgramClass clazz) {
diff --git a/src/main/java/com/android/tools/r8/dex/MethodToCodeObjectMapping.java b/src/main/java/com/android/tools/r8/dex/MethodToCodeObjectMapping.java
index 5541398..feeb64b 100644
--- a/src/main/java/com/android/tools/r8/dex/MethodToCodeObjectMapping.java
+++ b/src/main/java/com/android/tools/r8/dex/MethodToCodeObjectMapping.java
@@ -13,7 +13,7 @@
public abstract DexCode getCode(DexEncodedMethod method);
- public abstract void clearCode(DexEncodedMethod method);
+ public abstract void clearCode(DexEncodedMethod method, boolean isSharedSynthetic);
public abstract boolean verifyCodeObjects(Collection<DexCode> codes);
@@ -37,8 +37,11 @@
}
@Override
- public void clearCode(DexEncodedMethod method) {
- method.removeCode();
+ public void clearCode(DexEncodedMethod method, boolean isSharedSynthetic) {
+ // When using methods directly any shared class needs to maintain its methods as read-only.
+ if (!isSharedSynthetic) {
+ method.removeCode();
+ }
}
@Override
@@ -61,7 +64,7 @@
}
@Override
- public void clearCode(DexEncodedMethod method) {
+ public void clearCode(DexEncodedMethod method, boolean isSharedSynthetic) {
// We can safely clear the thread local pointer to even shared methods.
codes.put(method, null);
}
diff --git a/src/main/java/com/android/tools/r8/dex/VirtualFile.java b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
index a11e0ab..e44973a 100644
--- a/src/main/java/com/android/tools/r8/dex/VirtualFile.java
+++ b/src/main/java/com/android/tools/r8/dex/VirtualFile.java
@@ -329,10 +329,11 @@
Collection<DexProgramClass> synthetics = new ArrayList<>();
// Assign dedicated virtual files for all program classes.
for (DexProgramClass clazz : appView.appInfo().classes()) {
+ Collection<DexType> contexts =
+ appView.getSyntheticItems().getSynthesizingContexts(clazz.getType());
// TODO(b/181636450): Simplify this making use of the assumption that synthetics are never
// duplicated.
- if (!combineSyntheticClassesWithPrimaryClass
- || !appView.getSyntheticItems().isSyntheticClass(clazz)) {
+ if (!combineSyntheticClassesWithPrimaryClass || contexts.isEmpty()) {
VirtualFile file =
new VirtualFile(
virtualFiles.size(),
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
index 28401a5..d6c93aa 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -267,10 +267,6 @@
return Collections.emptyList();
}
- public boolean isSharedSynthetic(DexProgramClass clazz) {
- return getSynthesizingContexts(clazz.getType()).size() >= 2;
- }
-
// TODO(b/180091213): Implement this and remove client provided the oracle.
public Set<DexReference> getSynthesizingContexts(
DexProgramClass clazz, SynthesizingContextOracle oracle) {