Generate shorter <clinit> caller names in minified mode

This commit is contained in:
Alexey Andreev 2018-10-03 12:48:14 +03:00
parent 6b063bc567
commit be21e474c5
12 changed files with 85 additions and 41 deletions

View File

@ -291,7 +291,7 @@ public class ClassGenerator implements Generator, Injector, DependencyPlugin {
private void initClass(SourceWriter writer, MemberReader member) throws IOException { private void initClass(SourceWriter writer, MemberReader member) throws IOException {
if (member.hasModifier(ElementModifier.STATIC)) { if (member.hasModifier(ElementModifier.STATIC)) {
writer.appendClass(member.getOwnerName()).append("_$callClinit();").softNewLine(); writer.append(writer.getNaming().getNameForClassInit(member.getOwnerName())).append("();").softNewLine();
} }
} }

View File

@ -84,7 +84,7 @@ public class SystemNativeGenerator implements Generator, DependencyPlugin {
} }
private void generateCurrentTimeMillis(SourceWriter writer) throws IOException { private void generateCurrentTimeMillis(SourceWriter writer) throws IOException {
writer.append(writer.getNaming().getNameFor("java.lang.System")).append("_$callClinit();").softNewLine(); writer.append(writer.getNaming().getNameForClassInit("java.lang.System")).append("();").softNewLine();
writer.append("return Long_fromNumber(new Date().getTime());").softNewLine(); writer.append("return Long_fromNumber(new Date().getTime());").softNewLine();
} }

View File

@ -31,4 +31,6 @@ public interface AliasProvider {
String getClassAlias(String className); String getClassAlias(String className);
String getFunctionAlias(String name); String getFunctionAlias(String name);
String getClassInitAlias(String className);
} }

View File

@ -30,7 +30,10 @@ public class DefaultAliasProvider implements AliasProvider {
@Override @Override
public String getClassAlias(String cls) { public String getClassAlias(String cls) {
return classAliases.computeIfAbsent(cls, key -> { return classAliases.computeIfAbsent(cls, key -> makeUnique(knownAliases, suggestAliasForClass(key)));
}
private static String suggestAliasForClass(String cls) {
StringBuilder alias = new StringBuilder(); StringBuilder alias = new StringBuilder();
int lastIndex = 0; int lastIndex = 0;
while (true) { while (true) {
@ -60,8 +63,7 @@ public class DefaultAliasProvider implements AliasProvider {
alias.setCharAt(0, '_'); alias.setCharAt(0, '_');
} }
return makeUnique(knownAliases, alias.toString()); return alias.toString();
});
} }
@Override @Override
@ -111,6 +113,11 @@ public class DefaultAliasProvider implements AliasProvider {
return name; return name;
} }
@Override
public String getClassInitAlias(String className) {
return makeUnique(knownAliases, suggestAliasForClass(className) + "_$callClinit");
}
private String makeUnique(Set<String> knowAliases, String alias) { private String makeUnique(Set<String> knowAliases, String alias) {
String uniqueAlias = alias; String uniqueAlias = alias;
int index = 1; int index = 1;

View File

@ -28,6 +28,7 @@ public class DefaultNamingStrategy implements NamingStrategy {
private final Map<String, String> fieldAliases = new HashMap<>(); private final Map<String, String> fieldAliases = new HashMap<>();
private final Map<String, String> staticFieldAliases = new HashMap<>(); private final Map<String, String> staticFieldAliases = new HashMap<>();
private final Map<String, String> functionAliases = new HashMap<>(); private final Map<String, String> functionAliases = new HashMap<>();
private final Map<String, String> classInitAliases = new HashMap<>();
public DefaultNamingStrategy(AliasProvider aliasProvider, ClassReaderSource classSource) { public DefaultNamingStrategy(AliasProvider aliasProvider, ClassReaderSource classSource) {
this.aliasProvider = aliasProvider; this.aliasProvider = aliasProvider;
@ -99,7 +100,12 @@ public class DefaultNamingStrategy implements NamingStrategy {
@Override @Override
public String getNameForFunction(String name) throws NamingException { public String getNameForFunction(String name) throws NamingException {
return functionAliases.computeIfAbsent(name, key -> aliasProvider.getFunctionAlias(name)); return functionAliases.computeIfAbsent(name, key -> aliasProvider.getFunctionAlias(key));
}
@Override
public String getNameForClassInit(String className) throws NamingException {
return classInitAliases.computeIfAbsent(className, key -> aliasProvider.getClassInitAlias(key));
} }
private MethodReference getRealMethod(MethodReference methodRef) { private MethodReference getRealMethod(MethodReference methodRef) {

View File

@ -67,11 +67,24 @@ public class MinifyingAliasProvider implements AliasProvider {
@Override @Override
public String getClassAlias(String className) { public String getClassAlias(String className) {
return RenderingUtil.indexToId(lastSuffix++, startLetters); String result;
do {
result = RenderingUtil.indexToId(lastSuffix++, startLetters);
} while (!usedAliases.add(result) || RenderingUtil.KEYWORDS.contains(result));
return result;
} }
@Override @Override
public String getFunctionAlias(String className) { public String getFunctionAlias(String className) {
return RenderingUtil.indexToId(lastSuffix++, startLetters); return RenderingUtil.indexToId(lastSuffix++, startLetters);
} }
@Override
public String getClassInitAlias(String className) {
String result;
do {
result = RenderingUtil.indexToId(lastSuffix++, startLetters);
} while (!usedAliases.add(result) || RenderingUtil.KEYWORDS.contains(result));
return result;
}
} }

View File

@ -28,6 +28,8 @@ public interface NameFrequencyConsumer {
void consume(String className); void consume(String className);
void consumeClassInit(String className);
void consume(FieldReference field); void consume(FieldReference field);
void consumeFunction(String name); void consumeFunction(String name);

View File

@ -24,7 +24,7 @@ public class NamingOrderer implements NameFrequencyConsumer {
private Map<String, Entry> entries = new HashMap<>(); private Map<String, Entry> entries = new HashMap<>();
@Override @Override
public void consume(final MethodReference method) { public void consume(MethodReference method) {
String key = "R:" + method; String key = "R:" + method;
Entry entry = entries.get(key); Entry entry = entries.get(key);
if (entry == null) { if (entry == null) {
@ -37,7 +37,7 @@ public class NamingOrderer implements NameFrequencyConsumer {
@Override @Override
public void consumeInit(final MethodReference method) { public void consumeInit(MethodReference method) {
String key = "I:" + method; String key = "I:" + method;
Entry entry = entries.get(key); Entry entry = entries.get(key);
if (entry == null) { if (entry == null) {
@ -49,7 +49,7 @@ public class NamingOrderer implements NameFrequencyConsumer {
} }
@Override @Override
public void consume(final MethodDescriptor method) { public void consume(MethodDescriptor method) {
String key = "r:" + method; String key = "r:" + method;
Entry entry = entries.get(key); Entry entry = entries.get(key);
if (entry == null) { if (entry == null) {
@ -61,7 +61,7 @@ public class NamingOrderer implements NameFrequencyConsumer {
} }
@Override @Override
public void consume(final String className) { public void consume(String className) {
String key = "c:" + className; String key = "c:" + className;
Entry entry = entries.get(key); Entry entry = entries.get(key);
if (entry == null) { if (entry == null) {
@ -73,7 +73,19 @@ public class NamingOrderer implements NameFrequencyConsumer {
} }
@Override @Override
public void consume(final FieldReference field) { public void consumeClassInit(String className) {
String key = "C:" + className;
Entry entry = entries.get(key);
if (entry == null) {
entry = new Entry();
entry.operation = naming -> naming.getNameForClassInit(className);
entries.put(key, entry);
}
entry.frequency++;
}
@Override
public void consume(FieldReference field) {
String key = "f:" + field; String key = "f:" + field;
Entry entry = entries.get(key); Entry entry = entries.get(key);
if (entry == null) { if (entry == null) {
@ -85,7 +97,7 @@ public class NamingOrderer implements NameFrequencyConsumer {
} }
@Override @Override
public void consumeFunction(final String name) { public void consumeFunction(String name) {
String key = "n:" + name; String key = "n:" + name;
Entry entry = entries.get(key); Entry entry = entries.get(key);
if (entry == null) { if (entry == null) {

View File

@ -33,4 +33,6 @@ public interface NamingStrategy {
String getFullNameFor(FieldReference method) throws NamingException; String getFullNameFor(FieldReference method) throws NamingException;
String getNameForFunction(String name) throws NamingException; String getNameForFunction(String name) throws NamingException;
String getNameForClassInit(String className) throws NamingException;
} }

View File

@ -147,7 +147,7 @@ class NameFrequencyEstimator extends RecursiveVisitor implements MethodNodeVisit
@Override @Override
public void visit(InitClassStatement statement) { public void visit(InitClassStatement statement) {
consumer.consume(statement.getClassName()); consumer.consumeClassInit(statement.getClassName());
} }
@Override @Override

View File

@ -430,7 +430,7 @@ public class Renderer implements RenderingManager {
.append("false;").softNewLine(); .append("false;").softNewLine();
} }
writer.append("function ").appendClass(cls.getName()).append("_$callClinit()").ws() writer.append("function ").append(naming.getNameForClassInit(cls.getName())).append("()").ws()
.append("{").softNewLine().indent(); .append("{").softNewLine().indent();
if (isAsync) { if (isAsync) {
@ -479,7 +479,7 @@ public class Renderer implements RenderingManager {
} }
private void renderEraseClinit(ClassNode cls) throws IOException { private void renderEraseClinit(ClassNode cls) throws IOException {
writer.appendClass(cls.getName()).append("_$callClinit").ws().append("=").ws() writer.append(naming.getNameForClassInit(cls.getName())).ws().append("=").ws()
.appendClass(cls.getName()).append(".$clinit").ws().append("=").ws() .appendClass(cls.getName()).append(".$clinit").ws().append("=").ws()
.append("function(){};").newLine(); .append("function(){};").newLine();
} }
@ -518,7 +518,7 @@ public class Renderer implements RenderingManager {
MethodReader clinit = classSource.get(cls.getName()).getMethod( MethodReader clinit = classSource.get(cls.getName()).getMethod(
new MethodDescriptor("<clinit>", ValueType.VOID)); new MethodDescriptor("<clinit>", ValueType.VOID));
if (clinit != null) { if (clinit != null) {
writer.appendClass(cls.getName()).append("_$callClinit"); writer.append(naming.getNameForClassInit(cls.getName()));
} else { } else {
writer.append('0'); writer.append('0');
} }

View File

@ -437,7 +437,7 @@ public class StatementRenderer implements ExprVisitor, StatementVisitor {
if (statement.getLocation() != null) { if (statement.getLocation() != null) {
pushLocation(statement.getLocation()); pushLocation(statement.getLocation());
} }
writer.appendClass(statement.getClassName()).append("_$callClinit();").softNewLine(); writer.append(naming.getNameForClassInit(statement.getClassName())).append("();").softNewLine();
if (statement.isAsync()) { if (statement.isAsync()) {
emitSuspendChecker(); emitSuspendChecker();
} }