summaryrefslogtreecommitdiffstats
path: root/dx
diff options
context:
space:
mode:
authorJesse Wilson <jessewilson@google.com>2011-03-11 16:55:51 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-03-11 16:55:51 -0800
commit66fd70afb7f73bbe35ac83ddfaa6c6161d7ef84d (patch)
tree3fe9f725721120511fa1dbabf6281acd6158ec57 /dx
parent964ff5f44e12bce8562e20882a83d5470240a1d6 (diff)
parentd1e1668224cde06bbe5ad8953c7fb86d1d0d40e4 (diff)
downloadandroid_dalvik-66fd70afb7f73bbe35ac83ddfaa6c6161d7ef84d.tar.gz
android_dalvik-66fd70afb7f73bbe35ac83ddfaa6c6161d7ef84d.tar.bz2
android_dalvik-66fd70afb7f73bbe35ac83ddfaa6c6161d7ef84d.zip
Merge "Fix bugs in incremental dx." into dalvik-dev
Diffstat (limited to 'dx')
-rw-r--r--dx/src/com/android/dx/dex/TableOfContents.java10
-rw-r--r--dx/src/com/android/dx/io/DexBuffer.java8
-rw-r--r--dx/src/com/android/dx/merge/DexMerger.java29
-rw-r--r--dx/src/com/android/dx/merge/IndexMap.java33
4 files changed, 49 insertions, 31 deletions
diff --git a/dx/src/com/android/dx/dex/TableOfContents.java b/dx/src/com/android/dx/dex/TableOfContents.java
index e5d56b7cd..d85c826c9 100644
--- a/dx/src/com/android/dx/dex/TableOfContents.java
+++ b/dx/src/com/android/dx/dex/TableOfContents.java
@@ -122,7 +122,7 @@ public final class TableOfContents {
int size = in.readInt();
int offset = in.readInt();
- if ((section.size != -1 && section.size != size)
+ if ((section.size != 0 && section.size != size)
|| (section.off != -1 && section.off != offset)) {
throw new DexException("Unexpected map value for 0x" + Integer.toHexString(type));
}
@@ -192,14 +192,14 @@ public final class TableOfContents {
public void writeMap(DexBuffer.Section out) throws IOException {
int count = 0;
for (Section section : sections) {
- if (section.size > 0) {
+ if (section.exists()) {
count++;
}
}
out.writeInt(count);
for (Section section : sections) {
- if (section.size > 0) {
+ if (section.exists()) {
out.writeShort(section.type);
out.writeShort((short) 0);
out.writeInt(section.size);
@@ -210,7 +210,7 @@ public final class TableOfContents {
public static class Section implements Comparable<Section> {
public final short type;
- public int size = -1;
+ public int size = 0;
public int off = -1;
public int byteCount = 0;
@@ -219,7 +219,7 @@ public final class TableOfContents {
}
public boolean exists() {
- return size != -1;
+ return size > 0;
}
public int compareTo(Section section) {
diff --git a/dx/src/com/android/dx/io/DexBuffer.java b/dx/src/com/android/dx/io/DexBuffer.java
index cedb0aa84..cc511d6f9 100644
--- a/dx/src/com/android/dx/io/DexBuffer.java
+++ b/dx/src/com/android/dx/io/DexBuffer.java
@@ -32,6 +32,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.AbstractList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
@@ -41,9 +42,9 @@ import java.util.NoSuchElementException;
* are unsigned.
*/
public final class DexBuffer {
- private byte[] data;
+ private byte[] data = new byte[0];
+ private int length = 0;
private final TableOfContents tableOfContents = new TableOfContents();
- private int length;
private final List<String> strings = new AbstractList<String>() {
@Override public String get(int index) {
@@ -205,6 +206,9 @@ public final class DexBuffer {
public Iterable<ClassDef> classDefs() {
return new Iterable<ClassDef>() {
public Iterator<ClassDef> iterator() {
+ if (!tableOfContents.classDefs.exists()) {
+ return Collections.<ClassDef>emptySet().iterator();
+ }
return new Iterator<ClassDef>() {
private DexBuffer.Section in = open(tableOfContents.classDefs.off);
private int count = 0;
diff --git a/dx/src/com/android/dx/merge/DexMerger.java b/dx/src/com/android/dx/merge/DexMerger.java
index 1fe0ff558..d67c0737b 100644
--- a/dx/src/com/android/dx/merge/DexMerger.java
+++ b/dx/src/com/android/dx/merge/DexMerger.java
@@ -66,8 +66,6 @@ public final class DexMerger {
/** minimum number of wasted bytes before it's worthwhile to compact the result */
private int compactWasteThreshold = 1024 * 1024; // 1MiB
- /** minimum number of wasted bytes before it's worthwhile to emit a warning. */
- private final int warnWasteThreshold = 100 * 1024; // 100KiB
public DexMerger(DexBuffer dexA, DexBuffer dexB) throws IOException {
this(dexA, dexB, new WriterSizes(dexA, dexB));
@@ -96,45 +94,35 @@ public final class DexMerger {
mapListOut = dexOut.appendSection(writerSizes.mapList, "map list");
contentsOut.typeLists.off = dexOut.getLength();
- contentsOut.typeLists.size = 0;
typeListOut = dexOut.appendSection(writerSizes.typeList, "type list");
contentsOut.annotationSetRefLists.off = dexOut.getLength();
- contentsOut.annotationSetRefLists.size = 0;
annotationSetRefListOut = dexOut.appendSection(
writerSizes.annotationsSetRefList, "annotation set ref list");
contentsOut.annotationSets.off = dexOut.getLength();
- contentsOut.annotationSets.size = 0;
annotationSetOut = dexOut.appendSection(
writerSizes.annotationsSet, "annotation sets");
contentsOut.classDatas.off = dexOut.getLength();
- contentsOut.classDatas.size = 0;
classDataOut = dexOut.appendSection(writerSizes.classData, "class data");
contentsOut.codes.off = dexOut.getLength();
- contentsOut.codes.size = 0;
codeOut = dexOut.appendSection(writerSizes.code, "code");
contentsOut.stringDatas.off = dexOut.getLength();
- contentsOut.stringDatas.size = 0;
stringDataOut = dexOut.appendSection(writerSizes.stringData, "string data");
contentsOut.debugInfos.off = dexOut.getLength();
- contentsOut.debugInfos.size = 0;
debugInfoOut = dexOut.appendSection(writerSizes.debugInfo, "debug info");
contentsOut.annotations.off = dexOut.getLength();
- contentsOut.annotations.size = 0;
annotationOut = dexOut.appendSection(writerSizes.annotation, "annotation");
contentsOut.encodedArrays.off = dexOut.getLength();
- contentsOut.encodedArrays.size = 0;
encodedArrayOut = dexOut.appendSection(writerSizes.encodedArray, "encoded array");
contentsOut.annotationsDirectories.off = dexOut.getLength();
- contentsOut.annotationsDirectories.size = 0;
annotationsDirectoryOut = dexOut.appendSection(
writerSizes.annotationsDirectory, "annotations directory");
@@ -183,15 +171,12 @@ public final class DexMerger {
compactedSizes.minusWaste(this);
int wastedByteCount = writerSizes.size() - compactedSizes.size();
if (wastedByteCount > + compactWasteThreshold) {
- DexMerger compacter = new DexMerger(dexOut, dexOut, compactedSizes);
+ DexMerger compacter = new DexMerger(dexOut, new DexBuffer(), compactedSizes);
result = compacter.mergeDexBuffers();
System.out.printf("Result compacted from %.1fKiB to %.1fKiB to save %.1fKiB%n",
dexOut.getLength() / 1024f,
result.getLength() / 1024f,
wastedByteCount / 1024f);
- } else if (wastedByteCount >= warnWasteThreshold) {
- System.out.printf("Result includes %.1fKiB of wasted space",
- wastedByteCount / 1024f);
}
long elapsed = System.nanoTime() - start;
@@ -226,6 +211,8 @@ public final class DexMerger {
DexBuffer.Section inA = aSection.exists() ? dexA.open(aSection.off) : null;
DexBuffer.Section inB = bSection.exists() ? dexB.open(bSection.off) : null;
+ int aOffset = -1;
+ int bOffset = -1;
int aIndex = 0;
int bIndex = 0;
int outCount = 0;
@@ -233,12 +220,10 @@ public final class DexMerger {
T b = null;
while (true) {
- int aOffset = -1;
if (a == null && aIndex < aSection.size) {
aOffset = inA.getPosition();
a = read(inA, aIndexMap, aIndex);
}
- int bOffset = -1;
if (b == null && bIndex < bSection.size) {
bOffset = inB.getPosition();
b = read(inB, bIndexMap, bIndex);
@@ -261,11 +246,13 @@ public final class DexMerger {
toWrite = a;
updateIndex(aOffset, aIndexMap, aIndex++, outCount);
a = null;
+ aOffset = -1;
}
if (advanceB) {
toWrite = b;
updateIndex(bOffset, bIndexMap, bIndex++, outCount);
b = null;
+ bOffset = -1;
}
if (toWrite == null) {
break; // advanceA == false && advanceB == false
@@ -337,7 +324,7 @@ public final class DexMerger {
}
@Override void updateIndex(int offset, IndexMap indexMap, int oldIndex, int newIndex) {
- indexMap.typeListOffsets.put(offset, typeListOut.getPosition());
+ indexMap.putTypeListOffset(offset, typeListOut.getPosition());
}
@Override void write(TypeList value) {
@@ -547,7 +534,7 @@ public final class DexMerger {
DexBuffer in, DexBuffer.Section directoryIn, IndexMap indexMap) {
contentsOut.annotationsDirectories.size++;
annotationsDirectoryOut.assertFourByteAligned();
- indexMap.annotationDirectoryOffsets.put(
+ indexMap.putAnnotationDirectoryOffset(
directoryIn.getPosition(), annotationsDirectoryOut.getPosition());
int classAnnotationsOffset = indexMap.adjustAnnotationSet(directoryIn.readInt());
@@ -605,7 +592,7 @@ public final class DexMerger {
private void transformAnnotationSet(DexBuffer in, IndexMap indexMap, DexBuffer.Section setIn) {
contentsOut.annotationSets.size++;
annotationSetOut.assertFourByteAligned();
- indexMap.annotationSetOffsets.put(setIn.getPosition(), annotationSetOut.getPosition());
+ indexMap.putAnnotationSetOffset(setIn.getPosition(), annotationSetOut.getPosition());
int size = setIn.readInt();
annotationSetOut.writeInt(size);
diff --git a/dx/src/com/android/dx/merge/IndexMap.java b/dx/src/com/android/dx/merge/IndexMap.java
index 26e87ae78..a06bdafb7 100644
--- a/dx/src/com/android/dx/merge/IndexMap.java
+++ b/dx/src/com/android/dx/merge/IndexMap.java
@@ -36,9 +36,9 @@ public final class IndexMap {
public final short[] protoIds;
public final short[] fieldIds;
public final short[] methodIds;
- public final HashMap<Integer, Integer> typeListOffsets;
- public final HashMap<Integer, Integer> annotationSetOffsets;
- public final HashMap<Integer, Integer> annotationDirectoryOffsets;
+ private final HashMap<Integer, Integer> typeListOffsets;
+ private final HashMap<Integer, Integer> annotationSetOffsets;
+ private final HashMap<Integer, Integer> annotationDirectoryOffsets;
public IndexMap(DexBuffer target, TableOfContents tableOfContents) {
this.target = target;
@@ -60,6 +60,33 @@ public final class IndexMap {
this.annotationDirectoryOffsets.put(0, 0);
}
+ private int[] createIntMap(TableOfContents.Section section) {
+ return section.exists()
+ ? new int[section.size]
+ : new int[0];
+ }
+
+ public void putTypeListOffset(int oldOffset, int newOffset) {
+ if (oldOffset <= 0 || newOffset <= 0) {
+ throw new IllegalArgumentException();
+ }
+ typeListOffsets.put(oldOffset, newOffset);
+ }
+
+ public void putAnnotationSetOffset(int oldOffset, int newOffset) {
+ if (oldOffset <= 0 || newOffset <= 0) {
+ throw new IllegalArgumentException();
+ }
+ annotationSetOffsets.put(oldOffset, newOffset);
+ }
+
+ public void putAnnotationDirectoryOffset(int oldOffset, int newOffset) {
+ if (oldOffset <= 0 || newOffset <= 0) {
+ throw new IllegalArgumentException();
+ }
+ annotationDirectoryOffsets.put(oldOffset, newOffset);
+ }
+
public int adjustString(int stringIndex) {
return stringIndex == ClassDef.NO_INDEX ? ClassDef.NO_INDEX : stringIds[stringIndex];
}