Improve the performance of the TypeRewriter.rewrite method

This commit is contained in:
Ben Gruver 2020-02-03 00:09:21 -08:00
parent 409cf27ba9
commit c1f2da0e0b
2 changed files with 36 additions and 3 deletions

View File

@ -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);
}

View File

@ -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;");
}
}