From c1f2da0e0b85cf6a5eb0432f96fe4b316cfc34be Mon Sep 17 00:00:00 2001 From: Ben Gruver Date: Mon, 3 Feb 2020 00:09:21 -0800 Subject: Improve the performance of the TypeRewriter.rewrite method --- .../java/org/jf/dexlib2/rewriter/TypeRewriter.java | 14 +++++++++--- .../jf/dexlib2/rewriter/RewriteArrayTypeTest.java | 25 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) (limited to 'dexlib2') 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 { @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.newArrayList( + new ImmutableField("Lcls1;", "field1", "I", AccessFlags.PUBLIC.getValue(), null, null, null) + ), + Lists.newArrayList( + new ImmutableMethod("Lcls1", "method1", + Lists.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;"); + } } -- cgit v1.2.3