summaryrefslogtreecommitdiffstats
path: root/dx
diff options
context:
space:
mode:
authorJesse Wilson <jessewilson@google.com>2012-03-26 14:53:18 -0400
committerJesse Wilson <jessewilson@google.com>2012-03-26 14:53:18 -0400
commitfa3b293a068fd521a6ba6019a051ad502dfaca55 (patch)
treeb01abbf075f067e87ca66915c68f421840ebed70 /dx
parent231611a78e46c2144f9c88577772b9ae265922da (diff)
downloadandroid_dalvik-fa3b293a068fd521a6ba6019a051ad502dfaca55.tar.gz
android_dalvik-fa3b293a068fd521a6ba6019a051ad502dfaca55.tar.bz2
android_dalvik-fa3b293a068fd521a6ba6019a051ad502dfaca55.zip
Transform static values eagerly rather than on use.
Apparently there is some situations where a single static value may be referenced by multiple sites. Not transforming them eagerly lead to oversized dex files (and could crash the merge). Change-Id: I4ac5b9cd621b0fff1e5ba247c9590aa0d562cd65
Diffstat (limited to 'dx')
-rw-r--r--dx/src/com/android/dx/io/DexBuffer.java2
-rw-r--r--dx/src/com/android/dx/merge/DexMerger.java26
-rw-r--r--dx/src/com/android/dx/merge/IndexMap.java18
3 files changed, 36 insertions, 10 deletions
diff --git a/dx/src/com/android/dx/io/DexBuffer.java b/dx/src/com/android/dx/io/DexBuffer.java
index d10b08c55..217de725b 100644
--- a/dx/src/com/android/dx/io/DexBuffer.java
+++ b/dx/src/com/android/dx/io/DexBuffer.java
@@ -217,7 +217,7 @@ public final class DexBuffer {
return length;
}
- private static int fourByteAlign(int position) {
+ public static int fourByteAlign(int position) {
return (position + 3) & ~3;
}
diff --git a/dx/src/com/android/dx/merge/DexMerger.java b/dx/src/com/android/dx/merge/DexMerger.java
index b8071176a..1ba876aef 100644
--- a/dx/src/com/android/dx/merge/DexMerger.java
+++ b/dx/src/com/android/dx/merge/DexMerger.java
@@ -33,7 +33,9 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
/**
* Combine two dex files into one.
@@ -595,6 +597,8 @@ public final class DexMerger {
transformAnnotationSets(dexB, bIndexMap);
transformAnnotationDirectories(dexA, aIndexMap);
transformAnnotationDirectories(dexB, bIndexMap);
+ transformStaticValues(dexA, aIndexMap);
+ transformStaticValues(dexB, bIndexMap);
}
private void transformAnnotationSets(DexBuffer in, IndexMap indexMap) {
@@ -617,6 +621,16 @@ public final class DexMerger {
}
}
+ private void transformStaticValues(DexBuffer in, IndexMap indexMap) {
+ TableOfContents.Section section = in.getTableOfContents().encodedArrays;
+ if (section.exists()) {
+ DexBuffer.Section staticValuesIn = in.open(section.off);
+ for (int i = 0; i < section.size; i++) {
+ transformStaticValues(staticValuesIn, indexMap);
+ }
+ }
+ }
+
/**
* Reads a class_def_item beginning at {@code in} and writes the index and
* data.
@@ -644,13 +658,7 @@ public final class DexMerger {
}
int staticValuesOff = classDef.getStaticValuesOffset();
- if (staticValuesOff == 0) {
- idsDefsOut.writeInt(0);
- } else {
- DexBuffer.Section staticValuesIn = in.open(staticValuesOff);
- idsDefsOut.writeInt(encodedArrayOut.getPosition());
- transformStaticValues(staticValuesIn, indexMap);
- }
+ idsDefsOut.writeInt(indexMap.adjustStaticValues(staticValuesOff));
}
/**
@@ -839,6 +847,7 @@ public final class DexMerger {
private void transformStaticValues(DexBuffer.Section in, IndexMap indexMap) {
contentsOut.encodedArrays.size++;
+ indexMap.putStaticValuesOffset(in.getPosition(), encodedArrayOut.getPosition());
indexMap.adjustEncodedArray(in.readEncodedArray()).writeTo(encodedArrayOut);
}
@@ -914,6 +923,9 @@ public final class DexMerger {
// at most 1/3 of the bytes in an encoding arrays section are uleb/sleb
annotation += (int) Math.ceil(contents.annotations.byteCount * 1.34);
}
+
+ typeList = DexBuffer.fourByteAlign(typeList);
+ code = DexBuffer.fourByteAlign(code);
}
public void minusWaste(DexMerger dexMerger) {
diff --git a/dx/src/com/android/dx/merge/IndexMap.java b/dx/src/com/android/dx/merge/IndexMap.java
index a7b20bede..a5c9584dc 100644
--- a/dx/src/com/android/dx/merge/IndexMap.java
+++ b/dx/src/com/android/dx/merge/IndexMap.java
@@ -48,6 +48,7 @@ public final class IndexMap {
private final HashMap<Integer, Integer> annotationOffsets;
private final HashMap<Integer, Integer> annotationSetOffsets;
private final HashMap<Integer, Integer> annotationDirectoryOffsets;
+ private final HashMap<Integer, Integer> staticValuesOffsets;
public IndexMap(DexBuffer target, TableOfContents tableOfContents) {
this.target = target;
@@ -60,14 +61,16 @@ public final class IndexMap {
this.annotationOffsets = new HashMap<Integer, Integer>();
this.annotationSetOffsets = new HashMap<Integer, Integer>();
this.annotationDirectoryOffsets = new HashMap<Integer, Integer>();
+ this.staticValuesOffsets = new HashMap<Integer, Integer>();
/*
- * A type list, annotation set, or annotation directory at offset 0 is
- * always empty. Always map offset 0 to 0.
+ * A type list, annotation set, annotation directory, or static value at
+ * offset 0 is always empty. Always map offset 0 to 0.
*/
this.typeListOffsets.put(0, 0);
this.annotationSetOffsets.put(0, 0);
this.annotationDirectoryOffsets.put(0, 0);
+ this.staticValuesOffsets.put(0, 0);
}
public void putTypeListOffset(int oldOffset, int newOffset) {
@@ -98,6 +101,13 @@ public final class IndexMap {
annotationDirectoryOffsets.put(oldOffset, newOffset);
}
+ public void putStaticValuesOffset(int oldOffset, int newOffset) {
+ if (oldOffset <= 0 || newOffset <= 0) {
+ throw new IllegalArgumentException();
+ }
+ staticValuesOffsets.put(oldOffset, newOffset);
+ }
+
public int adjustString(int stringIndex) {
return stringIndex == ClassDef.NO_INDEX ? ClassDef.NO_INDEX : stringIds[stringIndex];
}
@@ -145,6 +155,10 @@ public final class IndexMap {
return annotationDirectoryOffsets.get(annotationDirectoryOffset);
}
+ public int adjustStaticValues(int staticValuesOffset) {
+ return staticValuesOffsets.get(staticValuesOffset);
+ }
+
public MethodId adjust(MethodId methodId) {
return new MethodId(target,
adjustType(methodId.getDeclaringClassIndex()),