With this change, we can now prune variables that are assigned to, but never read from. Once this occurs, we go back and fix up any assignment sites by replacing the assignment expression with the right hand side of the assignment. This change also enables pruning of local variables. (+spelling fixes)
Review by: mmendez
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@479 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
index eabc993..83f68d9 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JavaToJavaScriptCompiler.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -237,7 +237,7 @@
}
String[] entryPts = Util.toStringArray(allEntryPoints);
- // Add intrinsics needed for code gen.
+ // Add intrinsics needed for code generation.
//
int k = entryPts.length;
String[] seedTypeNames = new String[k + 3];
@@ -312,7 +312,7 @@
throw new UnableToCompleteException();
}
- // Compute all supertype/subtype info
+ // Compute all super type/sub type info
jprogram.typeOracle.computeBeforeAST();
// (3) Create a normalized Java AST using our own notation.
@@ -352,7 +352,7 @@
didChange = Pruner.exec(jprogram, true) || didChange;
// finalize locals, params, fields, methods, classes
didChange = MethodAndClassFinalizer.exec(jprogram) || didChange;
- // rewrite non-poly calls as static calls; update all call sites
+ // rewrite non-polymorphic calls as static calls; update all call sites
didChange = MakeCallsStatic.exec(jprogram) || didChange;
// type flow tightening
@@ -360,7 +360,7 @@
// - params based on assignment and call sites
// - method bodies based on return statements
// - polymorphic methods based on return types of all implementors
- // - optimize casts and instanceof
+ // - optimize casts and instance of
didChange = TypeTightener.exec(jprogram) || didChange;
// tighten method call bindings
@@ -372,13 +372,18 @@
// inlining
didChange = MethodInliner.exec(jprogram) || didChange;
+ if (didChange) {
+ // recompute clinits; some may now be empty
+ jprogram.typeOracle.recomputeClinits();
+ }
+
// prove that any types that have been culled from the main tree are
// unreferenced due to type tightening?
} while (didChange);
// (5) "Normalize" the high-level Java tree into a lower-level tree more
- // suited for JavaScript code gen. Don't go reordering these willy-nilly
- // because there are some subtle interdependencies.
+ // suited for JavaScript code generation. Don't go reordering these
+ // willy-nilly because there are some subtle interdependencies.
if (isDebugEnabled) {
// AssertionNormalizer.exec(jprogram);
}
@@ -388,7 +393,7 @@
CastNormalizer.exec(jprogram);
ArrayNormalizer.exec(jprogram);
- // (6) Perform furthur post-normalization optimizations
+ // (6) Perform further post-normalization optimizations
// Prune everything
Pruner.exec(jprogram, false);
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java
index 06ad7bc..5c217ff 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JNewArray.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -18,7 +18,7 @@
import java.util.ArrayList;
/**
- * New array experssion.
+ * New array expression.
*/
public class JNewArray extends JExpression implements HasSettableType {
@@ -40,7 +40,22 @@
}
public boolean hasSideEffects() {
- return true;
+ if (initializers != null) {
+ for (int i = 0, c = initializers.size(); i < c; ++i) {
+ if (((JExpression) initializers.get(i)).hasSideEffects()) {
+ return true;
+ }
+ }
+ }
+ if (dims != null) {
+ for (int i = 0, c = dims.size(); i < c; ++i) {
+ if (((JExpression) dims.get(i)).hasSideEffects()) {
+ return true;
+ }
+ }
+ }
+ // The new operation on an array does not actually cause side effects.
+ return false;
}
public void setType(JType arrayType) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JNewInstance.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JNewInstance.java
index b12751d..c82e577 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JNewInstance.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JNewInstance.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -16,7 +16,9 @@
package com.google.gwt.dev.jjs.ast;
/**
- * Java new instance expression.
+ * A new instance expression. This differs from a standard Java new operation in
+ * that no constructor is implied. Rather, a new operation creates an
+ * uninitialized Object which is passed as an argument to a constructor method.
*/
public class JNewInstance extends JExpression {
@@ -36,7 +38,8 @@
}
public boolean hasSideEffects() {
- return true;
+ // The actual new operation itself has no side effects (see class comment).
+ return false;
}
public void traverse(JVisitor visitor, Context ctx) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
index 9b76274..855349c 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -33,8 +33,6 @@
private final Map/* <JClassType, Set<JInterfaceType>> */couldImplementMap = new IdentityHashMap();
- private JClassType javaLangObject = null;
-
private final Set/* <JReferenceType> */hasClinitSet = new HashSet();
private final Map/* <JClassType, Set<JInterfaceType>> */implementsMap = new IdentityHashMap();
@@ -43,6 +41,8 @@
private final Map/* <JInterfaceType, Set<JClassType>> */isImplementedMap = new IdentityHashMap();
+ private JClassType javaLangObject = null;
+
private final JProgram program;
private final Map/* <JClassType, Set<JClassType>> */subClassMap = new IdentityHashMap();
@@ -79,7 +79,7 @@
int dims = aType.getDims();
int qDims = qaType.getDims();
- // null[] or Object[] -> int[][] might work, other combos won't
+ // null[] or Object[] -> int[][] might work, other combinations won't
if (dims < qDims && leafType != program.getTypeJavaLangObject()
&& !(leafType instanceof JNullType)) {
return false;
@@ -167,11 +167,7 @@
}
public void computeAfterAST() {
- hasClinitSet.clear();
- for (int i = 0; i < program.getDeclaredTypes().size(); ++i) {
- JReferenceType type = (JReferenceType) program.getDeclaredTypes().get(i);
- computeHasClinit(type);
- }
+ recomputeClinits();
}
public void computeBeforeAST() {
@@ -249,6 +245,14 @@
return instantiatedTypes.contains(type);
}
+ public void recomputeClinits() {
+ hasClinitSet.clear();
+ for (int i = 0; i < program.getDeclaredTypes().size(); ++i) {
+ JReferenceType type = (JReferenceType) program.getDeclaredTypes().get(i);
+ computeHasClinit(type);
+ }
+ }
+
public void setInstantiatedTypes(Set/* <JReferenceType> */instantiatedTypes) {
this.instantiatedTypes.clear();
this.instantiatedTypes.addAll(instantiatedTypes);
@@ -411,7 +415,7 @@
}
/**
- * Record the all of my superclasses (and myself as a subclass of them).
+ * Record the all of my super classes (and myself as a subclass of them).
*/
private void recordSuperSubInfo(JClassType type) {
Set/* <JClassType> */superSet = getOrCreate(superClassMap, type);
@@ -422,7 +426,7 @@
}
/**
- * Record the all of my superinterfaces (and myself as a subinterface of
+ * Record the all of my super interfaces (and myself as a sub interface of
* them).
*/
private void recordSuperSubInfo(JInterfaceType type) {
@@ -431,7 +435,7 @@
}
/**
- * Recursively record all of my superinterfaces.
+ * Recursively record all of my super interfaces.
*/
private void recordSuperSubInfo(JInterfaceType base,
Set/* <JInterfaceType> */superSet, JInterfaceType cur) {
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
index 9f43513..d2bfbc5 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/BuildTypeMap.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -71,7 +71,7 @@
* create raw unfinished, unlinked AST nodes for types, methods, fields, and
* parameters, and to map the original JDT nodes to these AST nodes. That way
* when GenerateJavaDom runs, it just uses the TypeMap output from this Builder
- * to retrieve whatever referencable nodes it needs without worrying about
+ * to retrieve whatever referenceable nodes it needs without worrying about
* whether they need to be created. Building our AST from JDT starts here.
*/
public class BuildTypeMap {
@@ -79,16 +79,16 @@
/**
* Creates JNodes for every method, field, initializer, parameter, and local
* and memorizes the mapping from the JDT Binding to the corresponding JNode
- * for each thing created. Note that this pass also 1) sets up the
- * supertype(s) for any member or local types created in BuildTypeMapVisitor
- * (see the comments there about why it had to be deferred). 2) adds each
+ * for each thing created. Note that this pass also 1) sets up the super
+ * type(s) for any member or local types created in BuildTypeMapVisitor (see
+ * the comments there about why it had to be deferred). 2) adds each
* user-defined type to a flat list. 3) Creates JNodes for all methods and
* variables and memorizes the mapping from the JDT Binding to the
* corresponding JNode for each created method and variable. 4) Maps all
* synthetic arguments and fields for nested and local classes. 5) Slurps in
* JSNI code for native methods as an opaque string.
*
- * Note that fethods and fields are not added to their classes here, that
+ * Note that methods and fields are not added to their classes here, that
* isn't done until {@link GenerateJavaDom}.
*/
private static class BuildDeclMapVisitor extends ASTVisitor {
@@ -158,7 +158,7 @@
* Weird: we used to have JConstructor (and JConstructorCall) in our AST,
* but we got rid of them completely and instead model them as instance
* methods whose qualifier is a naked no-argument new operation. See
- * {@link GenerateJavaDom.GenerateJavaDomVisitor#processConstructor(ConstructorDeclaration)}
+ * {@link GenerateJavaAST.JavaASTGenerationVisitor#processConstructor(ConstructorDeclaration)}
* for details.
*/
public boolean visit(ConstructorDeclaration ctorDecl, ClassScope scope) {
@@ -175,7 +175,7 @@
int syntheticParamCount = 0;
ReferenceBinding declaringClass = b.declaringClass;
if (declaringClass.isNestedType() && !declaringClass.isStatic()) {
- // add synthentic args for outer this and locals
+ // add synthetic args for outer this and locals
NestedTypeBinding nestedBinding = (NestedTypeBinding) declaringClass;
Set alreadyNamedVariables = new HashSet();
if (nestedBinding.enclosingInstances != null) {
@@ -296,7 +296,7 @@
jsniCode = jsniCode.substring(startPos, endPos);
// Here we parse it as an anonymous function, but we will give it a
- // name later when we generate the JavaScript during codegen.
+ // name later when we generate the JavaScript during code generation.
//
String syntheticFnHeader = "function (";
boolean first = true;
@@ -466,14 +466,14 @@
}
/**
- * Add synthetic fields, setup supertypes. You'll notice that we DON'T have
+ * Add synthetic fields, setup super types. You'll notice that we DON'T have
* any concept of "inner" or "outer" types in our AST. Truth is, we found it
* easier to simply model everything as flat classes and emulate the nesting
* behavior (and final local access on local classes). It's much closer to
- * how we'll eventually be generating JavaScript code (codegen is more
- * straightforward), it makes for fewer kinds of things to worry about when
- * optimizing (more aggressive optimizations), and it's how Java actually
- * implements the stuff under the hood anyway.
+ * how we'll eventually be generating JavaScript code (code generation is
+ * more straightforward), it makes for fewer kinds of things to worry about
+ * when optimizing (more aggressive optimizations), and it's how Java
+ * actually implements the stuff under the hood anyway.
*/
private boolean process(TypeDeclaration typeDeclaration) {
CompilationResult compResult = typeDeclaration.compilationResult;
@@ -490,7 +490,7 @@
JReferenceType type = (JReferenceType) typeMap.get(binding);
try {
if (binding.isNestedType() && !binding.isStatic()) {
- // add synthentic fields for outer this and locals
+ // add synthetic fields for outer this and locals
assert (type instanceof JClassType);
NestedTypeBinding nestedBinding = (NestedTypeBinding) binding;
if (nestedBinding.enclosingInstances != null) {
@@ -551,7 +551,7 @@
/**
* Creates JNodes for every type and memorizes the mapping from the JDT
* Binding to the corresponding JNode for each created type. Note that since
- * there could be forward references, it is not possible to set up supertypes;
+ * there could be forward references, it is not possible to set up super types;
* it must be done is a subsequent pass.
*/
private static class BuildTypeMapVisitor extends ASTVisitor {
@@ -637,7 +637,7 @@
}
/**
- * We emulate static initializers and intance initializers as methods.
+ * We emulate static initializers and instance initializers as methods.
* As in other cases, this gives us: simpler AST, easier to optimize,
* more like output JavaScript. Clinit is always in slot 0, init (if it
* exists) is always in slot 1.
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java b/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
index 4291e55..47a6d17 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/Pruner.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2007 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -22,19 +22,27 @@
import com.google.gwt.dev.jjs.ast.JBinaryOperator;
import com.google.gwt.dev.jjs.ast.JClassLiteral;
import com.google.gwt.dev.jjs.ast.JClassType;
+import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JFieldRef;
import com.google.gwt.dev.jjs.ast.JInterfaceType;
+import com.google.gwt.dev.jjs.ast.JLocal;
+import com.google.gwt.dev.jjs.ast.JLocalRef;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodCall;
+import com.google.gwt.dev.jjs.ast.JModVisitor;
import com.google.gwt.dev.jjs.ast.JNewArray;
import com.google.gwt.dev.jjs.ast.JNewInstance;
import com.google.gwt.dev.jjs.ast.JParameter;
+import com.google.gwt.dev.jjs.ast.JParameterRef;
import com.google.gwt.dev.jjs.ast.JPrimitiveType;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReferenceType;
import com.google.gwt.dev.jjs.ast.JStringLiteral;
+import com.google.gwt.dev.jjs.ast.JThisRef;
import com.google.gwt.dev.jjs.ast.JType;
+import com.google.gwt.dev.jjs.ast.JVariable;
+import com.google.gwt.dev.jjs.ast.JVariableRef;
import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.dev.jjs.ast.js.JsniFieldRef;
import com.google.gwt.dev.jjs.ast.js.JsniMethod;
@@ -57,18 +65,39 @@
*
* Note: references to pruned types may still exist in the tree after this pass
* runs, however, it should only be in contexts that do not rely on any code
- * generation for the pruned type. For example, it's legal to have a varable of
+ * generation for the pruned type. For example, it's legal to have a variable of
* a pruned type, or to try to cast to a pruned type. These will cause natural
* failures at run time; or later optimizations might be able to hard-code
* failures at compile time.
- *
- * TODO(later): prune params and locals
- *
- * TODO(later): make RescueVisitor use less stack?
*/
public class Pruner {
/**
+ * Remove assignments to pruned fields and locals.
+ *
+ * TODO(later): prune params too
+ */
+ private class CleanupRefsVisitor extends JModVisitor {
+
+ public void endVisit(JBinaryOperation x, Context ctx) {
+ // The LHS of assignments may have been pruned.
+ if (x.getOp() == JBinaryOperator.ASG) {
+ JExpression lhs = x.getLhs();
+ if (lhs.hasSideEffects()) {
+ return;
+ }
+ if (lhs instanceof JFieldRef || lhs instanceof JLocalRef) {
+ JVariable var = ((JVariableRef) lhs).getTarget();
+ if (!referencedNonTypes.contains(var)) {
+ // Just replace with my RHS
+ ctx.replaceMe(x.getRhs());
+ }
+ }
+ }
+ }
+ }
+
+ /**
* Remove any unreferenced classes and interfaces from JProgram. Remove any
* unreferenced methods and fields from their containing classes.
*/
@@ -101,6 +130,8 @@
|| pruneViaNoninstantiability(isInstantiated, method)) {
it.remove();
didChange = true;
+ } else {
+ accept(method);
}
}
@@ -138,6 +169,17 @@
return false;
}
+ public boolean visit(JMethod method, Context ctx) {
+ for (Iterator it = method.locals.iterator(); it.hasNext();) {
+ JLocal local = (JLocal) it.next();
+ if (!referencedNonTypes.contains(local)) {
+ it.remove();
+ didChange = true;
+ }
+ }
+ return false;
+ }
+
// @Override
public boolean visit(JProgram program, Context ctx) {
for (int i = 0; i < program.getDeclaredTypes().size(); ++i) {
@@ -192,6 +234,8 @@
* Marks as "referenced" any types, methods, and fields that are reachable.
* Also marks as "instantiable" any the classes and interfaces that can
* possibly be instantiated.
+ *
+ * TODO(later): make RescueVisitor use less stack?
*/
private class RescueVisitor extends JVisitor {
@@ -202,16 +246,6 @@
}
// @Override
- public void endVisit(JBinaryOperation x, Context ctx) {
- // special string concat handling
- if (x.getOp() == JBinaryOperator.ADD
- && x.getType() == program.getTypeJavaLangString()) {
- rescueByConcat(x.getLhs().getType());
- rescueByConcat(x.getRhs().getType());
- }
- }
-
- // @Override
public boolean visit(JArrayType type, Context ctx) {
assert (referencedTypes.contains(type));
boolean isInstantiated = instantiatedTypes.contains(type);
@@ -237,6 +271,55 @@
return false;
}
+ public boolean visit(JBinaryOperation x, Context ctx) {
+ // special string concat handling
+ if (x.getOp() == JBinaryOperator.ADD
+ && x.getType() == program.getTypeJavaLangString()) {
+ rescueByConcat(x.getLhs().getType());
+ rescueByConcat(x.getRhs().getType());
+ } else if (x.getOp() == JBinaryOperator.ASG) {
+ // Don't rescue variables that are merely assigned to and never read
+ boolean doSkip = false;
+ JExpression lhs = x.getLhs();
+ if (lhs.hasSideEffects()) {
+ // cannot skip
+ } else if (lhs instanceof JLocalRef) {
+ // locals are ok to skip
+ doSkip = true;
+ } else if (lhs instanceof JFieldRef) {
+ JFieldRef fieldRef = (JFieldRef) lhs;
+ /*
+ * Whether we can skip depends on what the qualifier is; we have to be
+ * certain the qualifier cannot be a null pointer (in which case we'd
+ * fail to throw the appropriate exception.
+ *
+ * TODO: better non-null tracking!
+ */
+ JExpression instance = fieldRef.getInstance();
+ if (fieldRef.getField().isStatic()) {
+ // statics are always okay
+ doSkip = true;
+ } else if (instance instanceof JThisRef) {
+ // a this ref cannot be null
+ doSkip = true;
+ } else if (instance instanceof JParameterRef) {
+ JParameter param = ((JParameterRef) instance).getParameter();
+ JMethod enclosingMethod = param.getEnclosingMethod();
+ if (program.isStaticImpl(enclosingMethod)
+ && enclosingMethod.params.get(0) == param) {
+ doSkip = true;
+ }
+ }
+ }
+
+ if (doSkip) {
+ accept(x.getRhs());
+ return false;
+ }
+ }
+ return true;
+ }
+
// @Override
public boolean visit(JClassLiteral literal, Context ctx) {
// rescue and instantiate java.lang.Class
@@ -252,8 +335,8 @@
/*
* SPECIAL: Some classes contain methods used by code generation later.
- * Unless those transforms have already been performed, we must rescuse
- * all contained methods for later user.
+ * Unless those transforms have already been performed, we must rescue all
+ * contained methods for later user.
*/
if (noSpecialTypes && program.specialTypes.contains(type)) {
for (int i = 0; i < type.methods.size(); ++i) {
@@ -321,6 +404,13 @@
}
// @Override
+ public boolean visit(JLocalRef ref, Context ctx) {
+ JLocal target = ref.getLocal();
+ rescue(target);
+ return true;
+ }
+
+ // @Override
public boolean visit(JMethodCall call, Context ctx) {
JMethod target = call.getTarget();
// JLS 12.4.1: references to static methods rescue the enclosing class
@@ -419,14 +509,6 @@
}
}
- private void rescue(JField field) {
- if (field != null) {
- if (!referencedNonTypes.contains(field)) {
- referencedNonTypes.add(field);
- }
- }
- }
-
private boolean rescue(JMethod method) {
if (method != null) {
if (!referencedNonTypes.contains(method)) {
@@ -466,6 +548,14 @@
}
}
+ private void rescue(JVariable var) {
+ if (var != null) {
+ if (!referencedNonTypes.contains(var)) {
+ referencedNonTypes.add(var);
+ }
+ }
+ }
+
/**
* Handle special rescues needed implicitly to support concat.
*/
@@ -559,13 +649,9 @@
}
private final boolean noSpecialTypes;
-
private final JProgram program;
-
private final Set/* <JNode> */referencedNonTypes = new HashSet/* <JNode> */();
-
private final Set/* <JReferenceType> */referencedTypes = new HashSet/* <JReferenceType> */();
-
private JMethod stringValueOfChar = null;
private Pruner(JProgram program, boolean noSpecialTypes) {
@@ -598,6 +684,9 @@
break;
}
+ CleanupRefsVisitor cleaner = new CleanupRefsVisitor();
+ cleaner.accept(program);
+
referencedTypes.clear();
referencedNonTypes.clear();
madeChanges = true;
diff --git a/eclipse/settings/english.dictionary b/eclipse/settings/english.dictionary
index dc0bbdc..5b8bb0b 100644
--- a/eclipse/settings/english.dictionary
+++ b/eclipse/settings/english.dictionary
@@ -47180,12 +47180,10 @@
analyzed
i18n
dict
-ljava
lang
var
localized
locales
-mechasims
checkbox
programmatically
apache
@@ -47193,3 +47191,33 @@
puppycrawl
checkstyle
initializer
+uninitialized
+memorizes
+referenceable
+slurps
+args
+param
+optimizations
+java
+optimizing
+uninstantiable
+initializers
+optimize
+clinit
+init
+instantiable
+optimization
+reachability
+params
+inlined
+rebind
+rebinding
+normalized
+clinits
+info
+finalize
+polymorphic
+inlining
+normalization
+normalize
+rethrow