diff options
author | mikaelpeltier <mikaelpeltier@google.com> | 2015-02-19 11:32:01 +0100 |
---|---|---|
committer | mikaelpeltier <mikaelpeltier@google.com> | 2015-04-07 17:03:37 +0200 |
commit | bdbdeb2b2c143c8ff201058024bf77a78a425a80 (patch) | |
tree | dcedac10d79caad3a3413d9f81e582094e301a66 | |
parent | a26140be0f0575cc9c046ffe03908e1fc0435fe7 (diff) | |
download | toolchain_jack-bdbdeb2b2c143c8ff201058024bf77a78a425a80.zip toolchain_jack-bdbdeb2b2c143c8ff201058024bf77a78a425a80.tar.gz toolchain_jack-bdbdeb2b2c143c8ff201058024bf77a78a425a80.tar.bz2 |
Speed-up Jack merger
- Try to reuse same objects (CstString, CstType and so on) each time
that it is possible.
- Replace maps by arrays when it is possible.
Change-Id: I227326bd9eb707b94a4edd8761ac06766078362f
5 files changed, 173 insertions, 225 deletions
diff --git a/dx/src/com/android/jack/dx/rop/cst/CstIndexMap.java b/dx/src/com/android/jack/dx/rop/cst/CstIndexMap.java index 9a5d55e..c4ec624 100644 --- a/dx/src/com/android/jack/dx/rop/cst/CstIndexMap.java +++ b/dx/src/com/android/jack/dx/rop/cst/CstIndexMap.java @@ -17,10 +17,10 @@ package com.android.jack.dx.rop.cst; import com.android.jack.dx.dex.file.DexFile; import com.android.jack.dx.dex.file.IndexedItem; +import com.android.jack.dx.io.DexBuffer; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; /** * Maps {@link TypedConstant} index offsets from a dex file to those into another. @@ -28,30 +28,33 @@ import java.util.Map; public class CstIndexMap { /** Mapping between index and {@link CstString} value of a dex file.*/ - private final Map<Integer, CstString> stringsIndexMap = new HashMap<Integer, CstString>(); + private final CstString[] strings; /** Mapping between index and {@link CstType} value of a dex file.*/ - private final Map<Integer, CstType> typesIndexMap = new HashMap<Integer, CstType>(); + private final CstType[] types; - /** Mapping between index and {@link CstBaseMethodRef} value of a dex file.*/ - private final Map<Integer, CstBaseMethodRef> methodsIndexMap = - new HashMap<Integer, CstBaseMethodRef>(); + /** Mapping between index and {@link CstMethodRef} value of a dex file.*/ + private final CstMethodRef[] methods; /** Mapping between index and {@link CstFieldRef} value of a dex file.*/ - private final Map<Integer, CstFieldRef> fieldsIndexMap = new HashMap<Integer, CstFieldRef>(); + private final CstFieldRef[] fields; + public CstIndexMap(DexBuffer dexBuffer) { + strings = new CstString[dexBuffer.strings().size()]; + types = new CstType[dexBuffer.typeNames().size()]; + methods = new CstMethodRef[dexBuffer.methodIds().size()]; + fields = new CstFieldRef[dexBuffer.fieldIds().size()]; + } /** * Keeps string mapping of a dex file. * @param index String index. * @param cstString The string. */ - public void addStringMapping(int index, CstString cstString) { - Integer key = new Integer(index); - assert index >= 0; - assert stringsIndexMap.get(key) == null || stringsIndexMap.get(key).compareTo(cstString) == 0; + public void addStringMapping(@Nonnegative int index, CstString cstString) { + assert strings[index] == null || strings[index].compareTo(cstString) == 0; - if (!stringsIndexMap.containsKey(key)) { - stringsIndexMap.put(key, cstString); + if (strings[index] == null) { + strings[index] = cstString; } } @@ -60,13 +63,11 @@ public class CstIndexMap { * @param index Type index. * @param cstType The type. */ - public void addTypeMapping(int index, CstType cstType) { - Integer key = new Integer(index); - assert index >= 0; - assert typesIndexMap.get(key) == null || typesIndexMap.get(key).compareTo(cstType) == 0; + public void addTypeMapping(@Nonnegative int index, CstType cstType) { + assert types[index] == null || types[index].compareTo(cstType) == 0; - if (!typesIndexMap.containsKey(key)) { - typesIndexMap.put(key, cstType); + if (types[index] == null) { + types[index] = cstType; } } @@ -75,13 +76,11 @@ public class CstIndexMap { * @param index Method index. * @param methodRef The method. */ - public void addMethodMapping(int index, CstBaseMethodRef methodRef) { - Integer key = new Integer(index); - assert index >= 0; - assert methodsIndexMap.get(key) == null || methodsIndexMap.get(key).compareTo(methodRef) == 0; + public void addMethodMapping(@Nonnegative int index, CstMethodRef methodRef) { + assert methods[index] == null || methods[index].compareTo(methodRef) == 0; - if (!methodsIndexMap.containsKey(key)) { - methodsIndexMap.put(key, methodRef); + if (methods[index] == null) { + methods[index] = methodRef; } } @@ -90,13 +89,11 @@ public class CstIndexMap { * @param index Field index. * @param fieldRef The Field. */ - public void addFieldMapping(int index, CstFieldRef fieldRef) { - Integer key = new Integer(index); - assert index >= 0; - assert fieldsIndexMap.get(key) == null || fieldsIndexMap.get(key).compareTo(fieldRef) == 0; + public void addFieldMapping(@Nonnegative int index, CstFieldRef fieldRef) { + assert fields[index] == null || fields[index].compareTo(fieldRef) == 0; - if (!fieldsIndexMap.containsKey(key)) { - fieldsIndexMap.put(key, fieldRef); + if (fields[index] == null) { + fields[index] = fieldRef; } } @@ -105,19 +102,19 @@ public class CstIndexMap { * @param dex The dex file where values are merged. */ public void mergeConstantsIntoDexFile(DexFile dex) { - for (CstString cst : stringsIndexMap.values()) { + for (CstString cst : strings) { dex.getStringIds().intern(cst); } - for (CstBaseMethodRef cst : methodsIndexMap.values()) { + for (CstBaseMethodRef cst : methods) { dex.getMethodIds().intern(cst); } - for (CstFieldRef cst : fieldsIndexMap.values()) { + for (CstFieldRef cst : fields) { dex.getFieldIds().intern(cst); } - for (CstType cst : typesIndexMap.values()) { + for (CstType cst : types) { dex.getTypeIds().intern(cst); } } @@ -129,11 +126,8 @@ public class CstIndexMap { * @param index The old index to remap into {@code file}. * @return The new index remapped into {@code file}. */ - public int getRemappedCstStringIndex(DexFile file, int index) { - Integer key = new Integer(index); - assert index >= 0; - assert stringsIndexMap.containsKey(key); - IndexedItem indexedItem = file.findItemOrNull(stringsIndexMap.get(key)); + public int getRemappedCstStringIndex(DexFile file, @Nonnegative int index) { + IndexedItem indexedItem = file.findItemOrNull(strings[index]); assert indexedItem != null; return indexedItem.getIndex(); } @@ -144,11 +138,8 @@ public class CstIndexMap { * @param index The old index to remap into {@code file}. * @return The new index remapped into {@code file}. */ - public int getRemappedCstTypeIndex(DexFile file, int index) { - Integer key = new Integer(index); - assert index >= 0; - assert typesIndexMap.containsKey(key); - IndexedItem indexedItem = file.findItemOrNull(typesIndexMap.get(key)); + public int getRemappedCstTypeIndex(DexFile file, @Nonnegative int index) { + IndexedItem indexedItem = file.findItemOrNull(types[index]); assert indexedItem != null; return indexedItem.getIndex(); } @@ -159,11 +150,8 @@ public class CstIndexMap { * @param index The old index to remap into {@code file}. * @return The new index remapped into {@code file}. */ - public int getRemappedCstBaseMethodRefIndex(DexFile file, int index) { - Integer key = new Integer(index); - assert index >= 0; - assert methodsIndexMap.containsKey(key); - IndexedItem indexedItem = file.findItemOrNull(methodsIndexMap.get(key)); + public int getRemappedCstBaseMethodRefIndex(DexFile file, @Nonnegative int index) { + IndexedItem indexedItem = file.findItemOrNull(methods[index]); assert indexedItem != null; return indexedItem.getIndex(); } @@ -174,20 +162,37 @@ public class CstIndexMap { * @param index The old index to remap into {@code file}. * @return The new index remapped into {@code file}. */ - public int getRemappedCstFieldRefIndex(DexFile file, int index) { - Integer key = new Integer(index); - assert index >= 0; - assert fieldsIndexMap.containsKey(key); - IndexedItem indexedItem = file.findItemOrNull(fieldsIndexMap.get(key)); + public int getRemappedCstFieldRefIndex(DexFile file, @Nonnegative int index) { + IndexedItem indexedItem = file.findItemOrNull(fields[index]); assert indexedItem != null; return indexedItem.getIndex(); } - /** - * Returns all strings that must be remapped. - * @return All string to remap. - */ - public Collection<CstString> getStrings() { - return (stringsIndexMap.values()); + @Nonnull + public CstMethodRef getCstMethodRef(@Nonnegative int index) { + CstMethodRef cstMethodRef = methods[index]; + assert cstMethodRef != null; + return cstMethodRef; + } + + @Nonnull + public CstFieldRef getCstFieldRef(@Nonnegative int index) { + CstFieldRef cstFieldRef = fields[index]; + assert cstFieldRef != null; + return cstFieldRef; + } + + @Nonnull + public CstString getCstString(@Nonnegative int index) { + CstString cstString = strings[index]; + assert cstString != null; + return cstString; + } + + @Nonnull + public CstType getCstType(@Nonnegative int index) { + CstType cstType = types[index]; + assert cstType != null; + return cstType; } } diff --git a/jack/src/com/android/jack/tools/merger/AnnotationMerger.java b/jack/src/com/android/jack/tools/merger/AnnotationMerger.java index 58c28fd..c3123b7 100644 --- a/jack/src/com/android/jack/tools/merger/AnnotationMerger.java +++ b/jack/src/com/android/jack/tools/merger/AnnotationMerger.java @@ -23,6 +23,7 @@ import com.android.jack.dx.io.DexBuffer; import com.android.jack.dx.io.DexBuffer.Section; import com.android.jack.dx.io.EncodedValueCodec; import com.android.jack.dx.io.EncodedValueReader; +import com.android.jack.dx.io.FieldId; import com.android.jack.dx.rop.annotation.AnnotationVisibility; import com.android.jack.dx.rop.annotation.Annotations; import com.android.jack.dx.rop.annotation.AnnotationsList; @@ -34,16 +35,18 @@ import com.android.jack.dx.rop.cst.CstBoolean; import com.android.jack.dx.rop.cst.CstByte; import com.android.jack.dx.rop.cst.CstChar; import com.android.jack.dx.rop.cst.CstDouble; +import com.android.jack.dx.rop.cst.CstEnumRef; import com.android.jack.dx.rop.cst.CstFieldRef; import com.android.jack.dx.rop.cst.CstFloat; +import com.android.jack.dx.rop.cst.CstIndexMap; import com.android.jack.dx.rop.cst.CstInteger; import com.android.jack.dx.rop.cst.CstKnownNull; import com.android.jack.dx.rop.cst.CstLong; import com.android.jack.dx.rop.cst.CstMethodRef; +import com.android.jack.dx.rop.cst.CstNat; import com.android.jack.dx.rop.cst.CstShort; import com.android.jack.dx.rop.cst.CstString; import com.android.jack.dx.rop.cst.CstType; -import com.android.jack.dx.rop.type.Type; import com.android.jack.dx.util.ByteInput; import com.android.jack.dx.util.Leb128Utils; @@ -56,8 +59,13 @@ import javax.annotation.Nonnull; */ public class AnnotationMerger extends MergerTools { + @CheckForNull + private CstIndexMap cstIndexMap; + public void mergeAnnotationDirectory(@Nonnull DexBuffer dex, - @Nonnegative int annotationDirectoryOffset, @Nonnull ClassDefItem newClassDef) { + @Nonnegative int annotationDirectoryOffset, @Nonnull ClassDefItem newClassDef, + @Nonnull CstIndexMap cstIndexMap) { + this.cstIndexMap = cstIndexMap; Section directoryIn = dex.open(annotationDirectoryOffset); int classAnnotationSetOffset = directoryIn.readInt(); @@ -72,17 +80,17 @@ public class AnnotationMerger extends MergerTools { int parameterListSize = directoryIn.readInt(); for (int i = 0; i < fieldsSize; i++) { - CstFieldRef cstFieldRef = getCstFieldRef(dex, dex.fieldIds().get(directoryIn.readInt())); + CstFieldRef cstFieldRef = cstIndexMap.getCstFieldRef(directoryIn.readInt()); newClassDef.addFieldAnnotations(cstFieldRef, readAnnotationSet(dex, directoryIn.readInt())); } for (int i = 0; i < methodsSize; i++) { - CstMethodRef cstMethodRef = getCstMethodRef(dex, dex.methodIds().get(directoryIn.readInt())); + CstMethodRef cstMethodRef = cstIndexMap.getCstMethodRef(directoryIn.readInt()); newClassDef.addMethodAnnotations(cstMethodRef, readAnnotationSet(dex, directoryIn.readInt())); } for (int i = 0; i < parameterListSize; i++) { - CstMethodRef cstMethodRef = getCstMethodRef(dex, dex.methodIds().get(directoryIn.readInt())); + CstMethodRef cstMethodRef = cstIndexMap.getCstMethodRef(directoryIn.readInt()); newClassDef.addParameterAnnotations(cstMethodRef, readAnnotationSetRefList(dex, directoryIn.readInt())); } @@ -123,7 +131,8 @@ public class AnnotationMerger extends MergerTools { @Nonnegative int annotationItemOffset) { Section annotationItemIn = dex.open(annotationItemOffset); Annotation ioAnnotation = annotationItemIn.readAnnotation(); - CstType annotationType = getCstTypeFromTypeIndex(dex, ioAnnotation.getTypeIndex()); + assert cstIndexMap != null; + CstType annotationType = cstIndexMap.getCstType(ioAnnotation.getTypeIndex()); com.android.jack.dx.rop.annotation.Annotation a = new com.android.jack.dx.rop.annotation.Annotation(annotationType, AnnotationItem.getAnnotationVisibility(ioAnnotation.getVisibility())); @@ -132,7 +141,8 @@ public class AnnotationMerger extends MergerTools { AnnotationValueReader avr = new AnnotationValueReader(dex, ioAnnotation.getValues()[i].asByteInput()); avr.readValue(); - a.add(new NameValuePair(getCstStringFromIndex(dex, ioAnnotation.getNames()[i]), + assert cstIndexMap != null; + a.add(new NameValuePair(cstIndexMap.getCstString(ioAnnotation.getNames()[i]), avr.getCstValue())); } @@ -172,7 +182,8 @@ public class AnnotationMerger extends MergerTools { @Override protected void visitString(int type, int index) { - constantValue = new CstString(dex.strings().get(index)); + assert cstIndexMap != null; + constantValue = cstIndexMap.getCstString(index); } @Override @@ -184,14 +195,15 @@ public class AnnotationMerger extends MergerTools { public final void readAnnotation() { int typeIndex = Leb128Utils.readUnsignedLeb128(in); int size = Leb128Utils.readUnsignedLeb128(in); - + assert cstIndexMap != null; com.android.jack.dx.rop.annotation.Annotation embeddedAnnotation = new com.android.jack.dx.rop.annotation.Annotation( - getCstTypeFromTypeIndex(dex, typeIndex), AnnotationVisibility.EMBEDDED); + cstIndexMap.getCstType(typeIndex), AnnotationVisibility.EMBEDDED); for (int i = 0; i < size; i++) { - CstString pairName = getCstStringFromIndex(dex, (Leb128Utils.readUnsignedLeb128(in))); + assert cstIndexMap != null; + CstString pairName = cstIndexMap.getCstString((Leb128Utils.readUnsignedLeb128(in))); readValue(); embeddedAnnotation.add(new NameValuePair(pairName, constantValue)); constantValue = null; @@ -236,27 +248,29 @@ public class AnnotationMerger extends MergerTools { @Override protected void visitField(int type, int index) { + assert cstIndexMap != null; if (type == ENCODED_FIELD) { - constantValue = getCstFieldRef(dex, index); + constantValue = cstIndexMap.getCstFieldRef(index); } else { assert type == ENCODED_ENUM; - constantValue = getCstEnumRef(dex, index); + FieldId fieldId = dex.fieldIds().get(index); + CstNat fieldNat = new CstNat(cstIndexMap.getCstString(fieldId.getNameIndex()), + new CstString(dex.typeNames().get(fieldId.getTypeIndex()))); + constantValue = new CstEnumRef(fieldNat); } } @Override protected void visitMethod(int type, int index) { - constantValue = getCstMethodRef(dex, index); + assert cstIndexMap != null; + constantValue = cstIndexMap.getCstMethodRef(index); } @Override protected void visitType(int type, int index) { - if (dex.typeNames().get(index).equals(Type.VOID.getDescriptor())) { - constantValue = CstType.intern(Type.VOID); - } else { - constantValue = getCstTypeFromTypeIndex(dex, index); - } + assert cstIndexMap != null; + constantValue = cstIndexMap.getCstType(index); } @Override diff --git a/jack/src/com/android/jack/tools/merger/ConstantManager.java b/jack/src/com/android/jack/tools/merger/ConstantManager.java index 19f7b70..e56be8c 100644 --- a/jack/src/com/android/jack/tools/merger/ConstantManager.java +++ b/jack/src/com/android/jack/tools/merger/ConstantManager.java @@ -20,9 +20,11 @@ import com.android.jack.dx.dex.file.DexFile; import com.android.jack.dx.io.DexBuffer; import com.android.jack.dx.io.FieldId; import com.android.jack.dx.io.MethodId; +import com.android.jack.dx.io.ProtoId; import com.android.jack.dx.rop.cst.CstFieldRef; import com.android.jack.dx.rop.cst.CstIndexMap; import com.android.jack.dx.rop.cst.CstMethodRef; +import com.android.jack.dx.rop.cst.CstNat; import com.android.jack.dx.rop.cst.CstString; import com.android.jack.dx.rop.cst.CstType; import com.android.jack.dx.rop.type.Type; @@ -53,11 +55,14 @@ public class ConstantManager extends MergerTools { private final HashSet<CstType> cstTypes = new HashSet<CstType>(); @Nonnull + private final Map<String, CstString> protoStr2CstString = new HashMap<String, CstString>(); + + @Nonnull private final List<CstIndexMap> cstIndexMaps = new ArrayList<CstIndexMap>(); @Nonnull public CstIndexMap addDexFile(@Nonnull DexBuffer dexBuffer) throws MergingOverflowException { - CstIndexMap cstIndexMap = new CstIndexMap(); + CstIndexMap cstIndexMap = new CstIndexMap(dexBuffer); List<String> cstStringsNewlyAdded = new ArrayList<String>(); List<CstFieldRef> cstFieldRefsNewlyAdded = new ArrayList<CstFieldRef>(); @@ -65,7 +70,6 @@ public class ConstantManager extends MergerTools { List<CstType> cstTypesNewlyAdded = new ArrayList<CstType>(); int idx = 0; - for (String string : dexBuffer.strings()) { CstString cstString = string2CstStrings.get(string); if (cstString == null) { @@ -77,25 +81,8 @@ public class ConstantManager extends MergerTools { } idx = 0; - for (FieldId fieldId : dexBuffer.fieldIds()) { - CstFieldRef cstFieldRef = getCstFieldRef(dexBuffer, fieldId); - if (cstFieldRefs.add(cstFieldRef)) { - cstFieldRefsNewlyAdded.add(cstFieldRef); - } - cstIndexMap.addFieldMapping(idx++, cstFieldRef); - } - - idx = 0; - for (MethodId methodId : dexBuffer.methodIds()) { - CstMethodRef cstMethodRef = getCstMethodRef(dexBuffer, methodId); - if (cstMethodRefs.add(cstMethodRef)) { - cstMethodRefsNewlyAdded.add(cstMethodRef); - } - cstIndexMap.addMethodMapping(idx++, cstMethodRef); - } - - idx = 0; - for (String typeNameDesc : dexBuffer.typeNames()) { + List<String> typeNames = dexBuffer.typeNames(); + for (String typeNameDesc : typeNames) { /* * Note: VOID isn't put in the intern table of type, since it's special and shouldn't be found * by a normal call to intern() from Type. @@ -104,7 +91,7 @@ public class ConstantManager extends MergerTools { if (typeNameDesc.equals(Type.VOID.getDescriptor())) { cstType = CstType.intern(Type.VOID); } else { - cstType = getCstTypeFromTypeName(typeNameDesc); + cstType = CstType.intern(Type.intern(typeNameDesc)); } if (cstTypes.add(cstType)) { @@ -114,6 +101,51 @@ public class ConstantManager extends MergerTools { cstIndexMap.addTypeMapping(idx++, cstType); } + + idx = 0; + for (FieldId fieldId : dexBuffer.fieldIds()) { + CstNat fieldNat = new CstNat(cstIndexMap.getCstString(fieldId.getNameIndex()), + cstIndexMap.getCstType(fieldId.getTypeIndex()).getDescriptor()); + CstFieldRef cstFieldRef = + new CstFieldRef(cstIndexMap.getCstType(fieldId.getDeclaringClassIndex()), fieldNat); + if (cstFieldRefs.add(cstFieldRef)) { + cstFieldRefsNewlyAdded.add(cstFieldRef); + } + cstIndexMap.addFieldMapping(idx++, cstFieldRef); + } + + idx = 0; + List<ProtoId> protoIds = dexBuffer.protoIds(); + String[] protoIdx2String = new String[protoIds.size()]; + + for (MethodId methodId : dexBuffer.methodIds()) { + int protoIdx = methodId.getProtoIndex(); + String protoStr = protoIdx2String[protoIdx]; + ProtoId protoId = protoIds.get(protoIdx); + + if (protoStr == null) { + protoStr = dexBuffer.readTypeList(protoId.getParametersOffset()).toString(); + protoIdx2String[protoIdx] = protoStr; + } + + protoStr += typeNames.get(protoId.getReturnTypeIndex()); + + CstString protoCstString = protoStr2CstString.get(protoStr); + if (protoCstString == null) { + protoCstString = new CstString(protoStr); + protoStr2CstString.put(protoStr, protoCstString); + } + + CstNat methNat = + new CstNat(cstIndexMap.getCstString(methodId.getNameIndex()), protoCstString); + CstMethodRef cstMethodRef = + new CstMethodRef(cstIndexMap.getCstType(methodId.getDeclaringClassIndex()), methNat); + if (cstMethodRefs.add(cstMethodRef)) { + cstMethodRefsNewlyAdded.add(cstMethodRef); + } + cstIndexMap.addMethodMapping(idx++, cstMethodRef); + } + if ((cstFieldRefs.size()) > DexFormat.MAX_MEMBER_IDX + 1) { removeItems(cstStringsNewlyAdded, cstFieldRefsNewlyAdded, cstMethodRefsNewlyAdded, cstTypesNewlyAdded); diff --git a/jack/src/com/android/jack/tools/merger/JackMerger.java b/jack/src/com/android/jack/tools/merger/JackMerger.java index bce76f5..01108b3 100644 --- a/jack/src/com/android/jack/tools/merger/JackMerger.java +++ b/jack/src/com/android/jack/tools/merger/JackMerger.java @@ -33,12 +33,10 @@ import com.android.jack.dx.rop.cst.CstMethodRef; import com.android.jack.dx.rop.cst.CstString; import com.android.jack.dx.rop.cst.CstType; import com.android.jack.dx.rop.type.StdTypeList; -import com.android.jack.dx.rop.type.Type; import com.android.jack.dx.rop.type.TypeList; import java.io.IOException; import java.io.OutputStream; -import java.util.List; import javax.annotation.Nonnull; @@ -71,33 +69,31 @@ public class JackMerger extends MergerTools { CstIndexMap cstIndexMap = cstManager.addDexFile(dexToMerge); for (ClassDef classDefToMerge : dexToMerge.classDefs()) { - List<String> typeNames = dexToMerge.typeNames(); - String typeNameDesc = classDefToMerge.getTypeName(); CstType superType = null; int supertypeIndex = classDefToMerge.getSupertypeIndex(); if (supertypeIndex != ClassDef.NO_INDEX) { - superType = CstType.intern(Type.intern(typeNames.get(supertypeIndex))); + superType = cstIndexMap.getCstType(supertypeIndex); } CstString sourceFilename = null; int sourceFileIndex = classDefToMerge.getSourceFileIndex(); if (sourceFileIndex != ClassDef.NO_INDEX) { - sourceFilename = new CstString(dexToMerge.strings().get(sourceFileIndex)); + sourceFilename = cstIndexMap.getCstString(sourceFileIndex); } - ClassDefItem newClassDef = - new ClassDefItem(CstType.intern(Type.intern(typeNameDesc)), - classDefToMerge.getAccessFlags(), superType, getInterfacesList(dexToMerge, - classDefToMerge), sourceFilename); + ClassDefItem newClassDef = new ClassDefItem( + cstIndexMap.getCstType(classDefToMerge.getTypeIndex()), classDefToMerge.getAccessFlags(), + superType, getInterfacesList(classDefToMerge, cstIndexMap), sourceFilename); dexResult.add(newClassDef); - mergeAnnotations(dexToMerge, classDefToMerge, newClassDef); + mergeAnnotations(dexToMerge, classDefToMerge, newClassDef, cstIndexMap); if (classDefToMerge.getClassDataOffset() != 0) { ClassData classDataToMerge = dexToMerge.readClassData(classDefToMerge); for (Field fieldToMerge : classDataToMerge.getInstanceFields()) { - newClassDef.addInstanceField(new EncodedField(getCstFieldRef(dexToMerge, fieldToMerge), + newClassDef.addInstanceField(new EncodedField( + cstIndexMap.getCstFieldRef(fieldToMerge.getFieldIndex()), fieldToMerge.getAccessFlags())); } @@ -110,9 +106,9 @@ public class JackMerger extends MergerTools { int cstIdx = 0; for (Field fieldToMerge : classDataToMerge.getStaticFields()) { - EncodedField encodedField = - new EncodedField(getCstFieldRef(dexToMerge, fieldToMerge), - fieldToMerge.getAccessFlags()); + EncodedField encodedField = new EncodedField( + cstIndexMap.getCstFieldRef(fieldToMerge.getFieldIndex()), + fieldToMerge.getAccessFlags()); newClassDef .addStaticField(encodedField, (cvab != null && cstIdx < cvab.getCstSize()) ? cvab.getCstValueAtIdx(cstIdx++) @@ -120,7 +116,7 @@ public class JackMerger extends MergerTools { } for (Method method : classDataToMerge.allMethods()) { - CstMethodRef cstMethodRef = getCstMethodRef(dexToMerge, method); + CstMethodRef cstMethodRef = cstIndexMap.getCstMethodRef(method.getMethodIndex()); ImportedCodeItem importCode = null; if (method.getCodeOffset() != 0) { @@ -157,15 +153,16 @@ public class JackMerger extends MergerTools { } private void mergeAnnotations(@Nonnull DexBuffer dexToMerge, @Nonnull ClassDef classDefToMerge, - @Nonnull ClassDefItem newClassDef) { + @Nonnull ClassDefItem newClassDef, @Nonnull CstIndexMap cstIndexMap) { if (classDefToMerge.getAnnotationsOffset() != 0) { - am.mergeAnnotationDirectory(dexToMerge, classDefToMerge.getAnnotationsOffset(), newClassDef); + am.mergeAnnotationDirectory(dexToMerge, classDefToMerge.getAnnotationsOffset(), newClassDef, + cstIndexMap); } } @Nonnull - private TypeList getInterfacesList(@Nonnull DexBuffer dexToMerge, - @Nonnull ClassDef classDefToMerge) { + private TypeList getInterfacesList(@Nonnull ClassDef classDefToMerge, + @Nonnull CstIndexMap cstIndexMap) { int interfaceCount = classDefToMerge.getInterfaces().length; if (interfaceCount == 0) { return StdTypeList.EMPTY; @@ -174,7 +171,7 @@ public class JackMerger extends MergerTools { StdTypeList interfaceList = new StdTypeList(interfaceCount); int idx = 0; for (int interfaceIdx : classDefToMerge.getInterfaces()) { - interfaceList.set(idx++, getTypeFromTypeIndex(dexToMerge, interfaceIdx)); + interfaceList.set(idx++, cstIndexMap.getCstType(interfaceIdx).getClassType()); } return (interfaceList); diff --git a/jack/src/com/android/jack/tools/merger/MergerTools.java b/jack/src/com/android/jack/tools/merger/MergerTools.java index a12be92..bd5b5ff 100644 --- a/jack/src/com/android/jack/tools/merger/MergerTools.java +++ b/jack/src/com/android/jack/tools/merger/MergerTools.java @@ -15,31 +15,20 @@ */ package com.android.jack.tools.merger; -import com.android.jack.dx.io.ClassData.Field; -import com.android.jack.dx.io.ClassData.Method; import com.android.jack.dx.io.DexBuffer; import com.android.jack.dx.io.EncodedValueCodec; import com.android.jack.dx.io.EncodedValueReader; -import com.android.jack.dx.io.FieldId; -import com.android.jack.dx.io.MethodId; -import com.android.jack.dx.io.ProtoId; import com.android.jack.dx.rop.cst.Constant; import com.android.jack.dx.rop.cst.CstBoolean; import com.android.jack.dx.rop.cst.CstByte; import com.android.jack.dx.rop.cst.CstChar; import com.android.jack.dx.rop.cst.CstDouble; -import com.android.jack.dx.rop.cst.CstEnumRef; -import com.android.jack.dx.rop.cst.CstFieldRef; import com.android.jack.dx.rop.cst.CstFloat; import com.android.jack.dx.rop.cst.CstInteger; import com.android.jack.dx.rop.cst.CstKnownNull; import com.android.jack.dx.rop.cst.CstLong; -import com.android.jack.dx.rop.cst.CstMethodRef; -import com.android.jack.dx.rop.cst.CstNat; import com.android.jack.dx.rop.cst.CstShort; import com.android.jack.dx.rop.cst.CstString; -import com.android.jack.dx.rop.cst.CstType; -import com.android.jack.dx.rop.type.Type; import com.android.jack.dx.util.ByteInput; import javax.annotation.CheckForNull; @@ -51,95 +40,6 @@ import javax.annotation.Nonnull; */ public class MergerTools { - @Nonnull - protected CstMethodRef getCstMethodRef(@Nonnull DexBuffer dex, @Nonnegative int methodIdx) { - MethodId methodId = dex.methodIds().get(methodIdx); - return getCstMethodRef(dex, methodId); - } - - @Nonnull - protected CstMethodRef getCstMethodRef(@Nonnull DexBuffer dex, @Nonnull Method method) { - MethodId methodId = dex.methodIds().get(method.getMethodIndex()); - return getCstMethodRef(dex, methodId); - } - - @Nonnull - protected CstMethodRef getCstMethodRef(@Nonnull DexBuffer dex, @Nonnull MethodId methodId) { - return new CstMethodRef(getCstTypeFromTypeIndex(dex, methodId.getDeclaringClassIndex()), - getCstNatFromMethodId(dex, methodId)); - } - - protected CstEnumRef getCstEnumRef(DexBuffer dex, int fieldIdx) { - return new CstEnumRef(getCstNatFromFieldId(dex, dex.fieldIds().get(fieldIdx))); - } - - @Nonnull - protected CstFieldRef getCstFieldRef(@Nonnull DexBuffer dex, @Nonnegative int fieldIdx) { - FieldId fieldId = dex.fieldIds().get(fieldIdx); - return getCstFieldRef(dex, fieldId); - } - - @Nonnull - protected CstFieldRef getCstFieldRef(@Nonnull DexBuffer dex, @Nonnull Field field) { - FieldId fieldId = dex.fieldIds().get(field.getFieldIndex()); - return getCstFieldRef(dex, fieldId); - } - - @Nonnull - protected CstFieldRef getCstFieldRef(@Nonnull DexBuffer dex, @Nonnull FieldId fieldId) { - return new CstFieldRef(getCstTypeFromTypeIndex(dex, fieldId.getDeclaringClassIndex()), - getCstNatFromFieldId(dex, fieldId)); - } - - @Nonnull - protected CstNat getCstNatFromMethodId(@Nonnull DexBuffer dex, @Nonnull MethodId methodId) { - ProtoId protoId = dex.protoIds().get(methodId.getProtoIndex()); - return new CstNat(getCstStringFromIndex(dex, methodId.getNameIndex()), - new CstString(getProtoString(protoId, dex))); - } - - @Nonnull - protected String getProtoString(@Nonnull ProtoId protoId, @Nonnull DexBuffer dex) { - return dex.readTypeList(protoId.getParametersOffset()) + dex.typeNames().get( - protoId.getReturnTypeIndex()); - } - - @Nonnull - protected CstNat getCstNatFromFieldId(@Nonnull DexBuffer dex, @Nonnull FieldId fieldId) { - return new CstNat(getCstStringFromIndex(dex, fieldId.getNameIndex()), - getCstStringFromTypeIndex(dex, fieldId.getTypeIndex())); - } - - @Nonnull - protected CstString getCstStringFromIndex(@Nonnull DexBuffer dex, @Nonnegative int stringIdx) { - String str = dex.strings().get(stringIdx); - return new CstString(str); - } - - @Nonnull - protected CstString getCstStringFromTypeIndex(@Nonnull DexBuffer dex, @Nonnegative int typeIdx) { - String typeNameDesc = dex.typeNames().get(typeIdx); - return new CstString(typeNameDesc); - } - - @Nonnull - protected Type getTypeFromTypeIndex(@Nonnull DexBuffer dex, @Nonnegative int typeIdx) { - String typeNameDesc = dex.typeNames().get(typeIdx); - return Type.intern(typeNameDesc); - } - - @Nonnull - protected CstType getCstTypeFromTypeIndex(@Nonnull DexBuffer dex, @Nonnegative int typeIdx) { - String typeNameDesc = dex.typeNames().get(typeIdx); - return CstType.intern(Type.intern(typeNameDesc)); - } - - @Nonnull - protected CstType getCstTypeFromTypeName(@Nonnull String typeNameDesc) { - return CstType.intern(Type.intern(typeNameDesc)); - } - - /** * A tool to build {@link Constant} arrays. */ |