aboutsummaryrefslogtreecommitdiff
path: root/dexlib2
diff options
context:
space:
mode:
authorBen Gruver <bgruv@google.com>2020-02-03 00:09:21 -0800
committerBen Gruver <bgruv@google.com>2020-02-03 00:09:21 -0800
commitc1f2da0e0b85cf6a5eb0432f96fe4b316cfc34be (patch)
tree54946349b12d1df18bff79dfe3b077071abc76fe /dexlib2
parent409cf27ba9f38d1ee62092724246fd2664174539 (diff)
downloadgoogle-smali-c1f2da0e0b85cf6a5eb0432f96fe4b316cfc34be.tar.gz
Improve the performance of the TypeRewriter.rewrite method
Diffstat (limited to 'dexlib2')
-rw-r--r--dexlib2/src/main/java/org/jf/dexlib2/rewriter/TypeRewriter.java14
-rw-r--r--dexlib2/src/test/java/org/jf/dexlib2/rewriter/RewriteArrayTypeTest.java25
2 files changed, 36 insertions, 3 deletions
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/TypeRewriter.java b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/TypeRewriter.java
index 862111fc..252003c5 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/rewriter/TypeRewriter.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/rewriter/TypeRewriter.java
@@ -36,12 +36,20 @@ import javax.annotation.Nonnull;
public class TypeRewriter implements Rewriter<String> {
@Nonnull @Override public String rewrite(@Nonnull String value) {
if (value.length() > 0 && value.charAt(0) == '[') {
- int dimensions = value.lastIndexOf("[") + 1;
+ int dimensions = 0;
+ while (value.charAt(dimensions) == '[') {
+ dimensions++;
+ }
- String arraySpecifiers = value.substring(0, dimensions);
String unwrappedType = value.substring(dimensions);
String rewrittenType = rewriteUnwrappedType(unwrappedType);
- return arraySpecifiers + rewrittenType;
+
+ // instance equality, to avoid a value comparison in the common case of the type being unmodified
+ if (unwrappedType != rewrittenType) {
+ return new StringBuilder(dimensions + rewrittenType.length())
+ .append(value, 0, dimensions).append(rewrittenType).toString();
+ }
+ return value;
} else {
return rewriteUnwrappedType(value);
}
diff --git a/dexlib2/src/test/java/org/jf/dexlib2/rewriter/RewriteArrayTypeTest.java b/dexlib2/src/test/java/org/jf/dexlib2/rewriter/RewriteArrayTypeTest.java
index c8b8d7fb..ab5f7da9 100644
--- a/dexlib2/src/test/java/org/jf/dexlib2/rewriter/RewriteArrayTypeTest.java
+++ b/dexlib2/src/test/java/org/jf/dexlib2/rewriter/RewriteArrayTypeTest.java
@@ -80,4 +80,29 @@ public class RewriteArrayTypeTest {
Assert.assertEquals(rewrittenClassDef.getType(), "Lcls2;");
Assert.assertEquals(rewrittenMethodDef.getParameterTypes().get(0), "[[[Lcls2;");
}
+
+ @Test
+ public void testUnmodifiedArrayTypeTest() {
+ ClassDef class1 = new ImmutableClassDef("Lcls1;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null,
+ Lists.newArrayList(new ImmutableAnnotation(AnnotationVisibility.RUNTIME, "Lannotation;", null)),
+ Lists.<Field>newArrayList(
+ new ImmutableField("Lcls1;", "field1", "I", AccessFlags.PUBLIC.getValue(), null, null, null)
+ ),
+ Lists.<Method>newArrayList(
+ new ImmutableMethod("Lcls1", "method1",
+ Lists.<MethodParameter>newArrayList(new ImmutableMethodParameter("[[[Lcls1;", null, null)), "V",
+ AccessFlags.PUBLIC.getValue(), null, null, null)));
+
+ ImmutableDexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableSet.of(class1));
+
+ DexRewriter rewriter = new DexRewriter(new RewriterModule());
+
+ DexFile rewrittenDexFile = rewriter.getDexFileRewriter().rewrite(dexFile);
+
+ ClassDef rewrittenClassDef = Lists.newArrayList(rewrittenDexFile.getClasses()).get(0);
+ Method rewrittenMethodDef = Lists.newArrayList(rewrittenClassDef.getMethods()).get(0);
+
+ Assert.assertEquals(rewrittenClassDef.getType(), "Lcls1;");
+ Assert.assertEquals(rewrittenMethodDef.getParameterTypes().get(0), "[[[Lcls1;");
+ }
}