From fe48ac9bd8b37501192c675adedaf1193b9c74cb Mon Sep 17 00:00:00 2001 From: jwilson Date: Fri, 5 Apr 2013 03:46:53 -0400 Subject: Don't duplicate annotation set ref lists when merging. See exception reported on this thread: https://groups.google.com/d/msg/android-contrib/h0sDMo5DVBI/MAMiBv5XR44J Change-Id: I867a8d2328b32625e5baa0b029f55e373fe11271 --- dx/src/com/android/dx/merge/DexMerger.java | 46 +++++++++++++++++++++--------- dx/src/com/android/dx/merge/IndexMap.java | 13 +++++++++ 2 files changed, 45 insertions(+), 14 deletions(-) (limited to 'dx') diff --git a/dx/src/com/android/dx/merge/DexMerger.java b/dx/src/com/android/dx/merge/DexMerger.java index b7677cf88..319153f39 100644 --- a/dx/src/com/android/dx/merge/DexMerger.java +++ b/dx/src/com/android/dx/merge/DexMerger.java @@ -604,6 +604,8 @@ public final class DexMerger { private void unionAnnotationSetsAndDirectories() { transformAnnotationSets(dexA, aIndexMap); transformAnnotationSets(dexB, bIndexMap); + transformAnnotationSetRefLists(dexA, aIndexMap); + transformAnnotationSetRefLists(dexB, bIndexMap); transformAnnotationDirectories(dexA, aIndexMap); transformAnnotationDirectories(dexB, bIndexMap); transformStaticValues(dexA, aIndexMap); @@ -620,12 +622,22 @@ public final class DexMerger { } } + private void transformAnnotationSetRefLists(DexBuffer in, IndexMap indexMap) { + TableOfContents.Section section = in.getTableOfContents().annotationSetRefLists; + if (section.exists()) { + DexBuffer.Section setIn = in.open(section.off); + for (int i = 0; i < section.size; i++) { + transformAnnotationSetRefList(indexMap, setIn); + } + } + } + private void transformAnnotationDirectories(DexBuffer in, IndexMap indexMap) { TableOfContents.Section section = in.getTableOfContents().annotationsDirectories; if (section.exists()) { DexBuffer.Section directoryIn = in.open(section.off); for (int i = 0; i < section.size; i++) { - transformAnnotationDirectory(in, directoryIn, indexMap); + transformAnnotationDirectory(directoryIn, indexMap); } } } @@ -674,7 +686,7 @@ public final class DexMerger { * Transform all annotations on a class. */ private void transformAnnotationDirectory( - DexBuffer in, DexBuffer.Section directoryIn, IndexMap indexMap) { + DexBuffer.Section directoryIn, IndexMap indexMap) { contentsOut.annotationsDirectories.size++; annotationsDirectoryOut.assertFourByteAligned(); indexMap.putAnnotationDirectoryOffset( @@ -710,22 +722,12 @@ public final class DexMerger { } for (int i = 0; i < parameterListSize; i++) { - contentsOut.annotationSetRefLists.size++; - annotationSetRefListOut.assertFourByteAligned(); - // method index annotationsDirectoryOut.writeInt(indexMap.adjustMethod(directoryIn.readInt())); // annotations offset - annotationsDirectoryOut.writeInt(annotationSetRefListOut.getPosition()); - DexBuffer.Section refListIn = in.open(directoryIn.readInt()); - - // parameters - int parameterCount = refListIn.readInt(); - annotationSetRefListOut.writeInt(parameterCount); - for (int p = 0; p < parameterCount; p++) { - annotationSetRefListOut.writeInt(indexMap.adjustAnnotationSet(refListIn.readInt())); - } + annotationsDirectoryOut.writeInt( + indexMap.adjustAnnotationSetRefList(directoryIn.readInt())); } } @@ -745,6 +747,22 @@ public final class DexMerger { } } + /** + * Transform all annotation set ref lists. + */ + private void transformAnnotationSetRefList(IndexMap indexMap, DexBuffer.Section refListIn) { + contentsOut.annotationSetRefLists.size++; + annotationSetRefListOut.assertFourByteAligned(); + indexMap.putAnnotationSetRefListOffset( + refListIn.getPosition(), annotationSetRefListOut.getPosition()); + + int parameterCount = refListIn.readInt(); + annotationSetRefListOut.writeInt(parameterCount); + for (int p = 0; p < parameterCount; p++) { + annotationSetRefListOut.writeInt(indexMap.adjustAnnotationSet(refListIn.readInt())); + } + } + private void transformClassData(DexBuffer in, ClassData classData, IndexMap indexMap) { contentsOut.classDatas.size++; diff --git a/dx/src/com/android/dx/merge/IndexMap.java b/dx/src/com/android/dx/merge/IndexMap.java index a5c9584dc..89d2dd671 100644 --- a/dx/src/com/android/dx/merge/IndexMap.java +++ b/dx/src/com/android/dx/merge/IndexMap.java @@ -47,6 +47,7 @@ public final class IndexMap { private final HashMap typeListOffsets; private final HashMap annotationOffsets; private final HashMap annotationSetOffsets; + private final HashMap annotationSetRefListOffsets; private final HashMap annotationDirectoryOffsets; private final HashMap staticValuesOffsets; @@ -60,6 +61,7 @@ public final class IndexMap { this.typeListOffsets = new HashMap(); this.annotationOffsets = new HashMap(); this.annotationSetOffsets = new HashMap(); + this.annotationSetRefListOffsets = new HashMap(); this.annotationDirectoryOffsets = new HashMap(); this.staticValuesOffsets = new HashMap(); @@ -94,6 +96,13 @@ public final class IndexMap { annotationSetOffsets.put(oldOffset, newOffset); } + public void putAnnotationSetRefListOffset(int oldOffset, int newOffset) { + if (oldOffset <= 0 || newOffset <= 0) { + throw new IllegalArgumentException(); + } + annotationSetRefListOffsets.put(oldOffset, newOffset); + } + public void putAnnotationDirectoryOffset(int oldOffset, int newOffset) { if (oldOffset <= 0 || newOffset <= 0) { throw new IllegalArgumentException(); @@ -151,6 +160,10 @@ public final class IndexMap { return annotationSetOffsets.get(annotationSetOffset); } + public int adjustAnnotationSetRefList(int annotationSetRefListOffset) { + return annotationSetRefListOffsets.get(annotationSetRefListOffset); + } + public int adjustAnnotationDirectory(int annotationDirectoryOffset) { return annotationDirectoryOffsets.get(annotationDirectoryOffset); } -- cgit v1.2.3