mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 00:04:10 -08:00
Improve <clinit> elimination. Improve inlining in ADVANCED optimization mode
This commit is contained in:
parent
fecdd6613a
commit
d76eeb9be3
|
@ -174,6 +174,9 @@ public class ClassInitializerAnalysis implements ClassInitializerInfo {
|
|||
}
|
||||
|
||||
private boolean hasSideEffects(MethodReader method) {
|
||||
if (method.hasModifier(ElementModifier.ABSTRACT)) {
|
||||
return false;
|
||||
}
|
||||
if (method.getAnnotations().get(NoSideEffects.class.getName()) != null) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -71,11 +71,11 @@ public class ClassInitElimination implements MethodOptimization {
|
|||
return false;
|
||||
}
|
||||
|
||||
class Step {
|
||||
static class Step {
|
||||
int node;
|
||||
Set<String> initializedClasses = new HashSet<>();
|
||||
|
||||
public Step(int node) {
|
||||
Step(int node) {
|
||||
this.node = node;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,11 @@ public class DefaultInliningStrategy implements InliningStrategy {
|
|||
complexity--;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assign(VariableReader receiver, VariableReader assignee) {
|
||||
complexity--;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(VariableReader receiver, VariableReader instance, MethodReference method,
|
||||
List<? extends VariableReader> arguments, InvocationType type) {
|
||||
|
|
|
@ -15,14 +15,17 @@
|
|||
*/
|
||||
package org.teavm.jso.core;
|
||||
|
||||
import org.teavm.interop.NoSideEffects;
|
||||
import org.teavm.jso.JSIndexer;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.JSProperty;
|
||||
|
||||
public interface JSArrayReader<T extends JSObject> extends JSObject {
|
||||
@JSProperty
|
||||
@NoSideEffects
|
||||
int getLength();
|
||||
|
||||
@JSIndexer
|
||||
@NoSideEffects
|
||||
T get(int index);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.function.Function;
|
|||
import org.teavm.backend.javascript.spi.GeneratedBy;
|
||||
import org.teavm.backend.javascript.spi.InjectedBy;
|
||||
import org.teavm.dependency.PluggableDependency;
|
||||
import org.teavm.interop.NoSideEffects;
|
||||
import org.teavm.jso.JSBody;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.core.JSArray;
|
||||
|
@ -33,83 +34,107 @@ final class JS {
|
|||
}
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native JSObject arrayData(Object array);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@PluggableDependency(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native byte[] dataToByteArray(JSObject obj);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@PluggableDependency(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native char[] dataToCharArray(JSObject obj);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@PluggableDependency(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native short[] dataToShortArray(JSObject obj);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@PluggableDependency(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native int[] dataToIntArray(JSObject obj);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@PluggableDependency(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native float[] dataToFloatArray(JSObject obj);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@PluggableDependency(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native double[] dataToDoubleArray(JSObject obj);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@PluggableDependency(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native JSObject[] dataToArray(JSObject obj);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native JSObject wrap(byte value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native JSObject wrap(short value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native JSObject wrap(int value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native JSObject wrap(char value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native JSObject wrap(float value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native JSObject wrap(double value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native JSObject wrap(boolean value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native JSObject wrap(String value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native byte unwrapByte(JSObject value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native char unwrapCharacter(JSObject value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native short unwrapShort(JSObject value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native int unwrapInt(JSObject value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native float unwrapFloat(JSObject value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native double unwrapDouble(JSObject value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native boolean unwrapBoolean(JSObject value);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@PluggableDependency(JSNativeGenerator.class)
|
||||
@NoSideEffects
|
||||
public static native String unwrapString(JSObject value);
|
||||
|
||||
public static <T extends JSObject> JSArray<T> wrap(T[] array) {
|
||||
|
@ -486,10 +511,20 @@ final class JS {
|
|||
@JSBody(params = { "instance", "index" }, script = "return instance[index];")
|
||||
public static native JSObject get(JSObject instance, JSObject index);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@JSBody(params = { "instance", "index" }, script = "return instance[index];")
|
||||
@NoSideEffects
|
||||
public static native JSObject getPure(JSObject instance, JSObject index);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@JSBody(params = { "instance", "index", "obj" }, script = "instance[index] = obj;")
|
||||
public static native void set(JSObject instance, JSObject index, JSObject obj);
|
||||
|
||||
@InjectedBy(JSNativeGenerator.class)
|
||||
@JSBody(params = { "instance", "index", "obj" }, script = "instance[index] = obj;")
|
||||
@NoSideEffects
|
||||
public static native void setPure(JSObject instance, JSObject index, JSObject obj);
|
||||
|
||||
@GeneratedBy(JSNativeGenerator.class)
|
||||
@PluggableDependency(JSNativeGenerator.class)
|
||||
public static native JSObject function(JSObject instance, JSObject property);
|
||||
|
|
|
@ -69,6 +69,7 @@ import org.teavm.model.util.ModelUtils;
|
|||
import org.teavm.model.util.ProgramUtils;
|
||||
|
||||
class JSClassProcessor {
|
||||
private static final String NO_SIDE_EFFECTS = NoSideEffects.class.getName();
|
||||
private final ClassReaderSource classSource;
|
||||
private final JSBodyRepository repository;
|
||||
private final JavaInvocationProcessor javaInvocationProcessor;
|
||||
|
@ -359,6 +360,7 @@ class JSClassProcessor {
|
|||
}
|
||||
|
||||
private boolean processProperty(MethodReader method, CallLocation callLocation, InvokeInstruction invoke) {
|
||||
boolean pure = method.getAnnotations().get(NO_SIDE_EFFECTS) != null;
|
||||
if (isProperGetter(method)) {
|
||||
String propertyName = extractSuggestedPropertyName(method);
|
||||
if (propertyName == null) {
|
||||
|
@ -366,7 +368,7 @@ class JSClassProcessor {
|
|||
: cutPrefix(method.getName(), 3);
|
||||
}
|
||||
Variable result = invoke.getReceiver() != null ? program.createVariable() : null;
|
||||
addPropertyGet(propertyName, invoke.getInstance(), result, invoke.getLocation());
|
||||
addPropertyGet(propertyName, invoke.getInstance(), result, invoke.getLocation(), pure);
|
||||
if (result != null) {
|
||||
result = marshaller.unwrapReturnValue(callLocation, result, method.getResultType(), false);
|
||||
copyVar(result, invoke.getReceiver(), invoke.getLocation());
|
||||
|
@ -380,7 +382,7 @@ class JSClassProcessor {
|
|||
}
|
||||
Variable wrapped = marshaller.wrapArgument(callLocation, invoke.getArguments().get(0),
|
||||
method.parameterType(0), false);
|
||||
addPropertySet(propertyName, invoke.getInstance(), wrapped, invoke.getLocation());
|
||||
addPropertySet(propertyName, invoke.getInstance(), wrapped, invoke.getLocation(), pure);
|
||||
return true;
|
||||
}
|
||||
diagnostics.error(callLocation, "Method {{m0}} is not a proper native JavaScript property "
|
||||
|
@ -674,22 +676,23 @@ class JSClassProcessor {
|
|||
}
|
||||
|
||||
private void addPropertyGet(String propertyName, Variable instance, Variable receiver,
|
||||
TextLocation location) {
|
||||
TextLocation location, boolean pure) {
|
||||
Variable nameVar = marshaller.addStringWrap(marshaller.addString(propertyName, location), location);
|
||||
InvokeInstruction insn = new InvokeInstruction();
|
||||
insn.setType(InvocationType.SPECIAL);
|
||||
insn.setMethod(JSMethods.GET);
|
||||
insn.setMethod(pure ? JSMethods.GET_PURE : JSMethods.GET);
|
||||
insn.setReceiver(receiver);
|
||||
insn.setArguments(instance, nameVar);
|
||||
insn.setLocation(location);
|
||||
replacement.add(insn);
|
||||
}
|
||||
|
||||
private void addPropertySet(String propertyName, Variable instance, Variable value, TextLocation location) {
|
||||
private void addPropertySet(String propertyName, Variable instance, Variable value, TextLocation location,
|
||||
boolean pure) {
|
||||
Variable nameVar = marshaller.addStringWrap(marshaller.addString(propertyName, location), location);
|
||||
InvokeInstruction insn = new InvokeInstruction();
|
||||
insn.setType(InvocationType.SPECIAL);
|
||||
insn.setMethod(JSMethods.SET);
|
||||
insn.setMethod(pure ? JSMethods.SET_PURE : JSMethods.SET);
|
||||
insn.setArguments(instance, nameVar, value);
|
||||
insn.setLocation(location);
|
||||
replacement.add(insn);
|
||||
|
|
|
@ -26,8 +26,12 @@ import org.teavm.model.ValueType;
|
|||
final class JSMethods {
|
||||
public static final MethodReference GET = new MethodReference(JS.class, "get", JSObject.class,
|
||||
JSObject.class, JSObject.class);
|
||||
public static final MethodReference GET_PURE = new MethodReference(JS.class, "getPure", JSObject.class,
|
||||
JSObject.class, JSObject.class);
|
||||
public static final MethodReference SET = new MethodReference(JS.class, "set", JSObject.class, JSObject.class,
|
||||
JSObject.class, void.class);
|
||||
public static final MethodReference SET_PURE = new MethodReference(JS.class, "setPure", JSObject.class,
|
||||
JSObject.class, JSObject.class, void.class);
|
||||
public static final MethodReference FUNCTION = new MethodReference(JS.class, "function", JSObject.class,
|
||||
JSObject.class, JSObject.class);
|
||||
public static final MethodReference ARRAY_DATA = new MethodReference(JS.class, "arrayData",
|
||||
|
|
|
@ -98,10 +98,12 @@ public class JSNativeGenerator implements Injector, DependencyPlugin, Generator
|
|||
writer.append(".data");
|
||||
break;
|
||||
case "get":
|
||||
case "getPure":
|
||||
context.writeExpr(context.getArgument(0), Precedence.MEMBER_ACCESS);
|
||||
renderProperty(context.getArgument(1), context);
|
||||
break;
|
||||
case "set":
|
||||
case "setPure":
|
||||
context.writeExpr(context.getArgument(0), Precedence.ASSIGNMENT.next());
|
||||
renderProperty(context.getArgument(1), context);
|
||||
writer.ws().append('=').ws();
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package org.teavm.platform;
|
||||
|
||||
import org.teavm.interop.NoSideEffects;
|
||||
import org.teavm.interop.Unmanaged;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.JSProperty;
|
||||
|
@ -22,13 +23,16 @@ import org.teavm.jso.JSProperty;
|
|||
public interface PlatformClass extends JSObject {
|
||||
@JSProperty("$meta")
|
||||
@Unmanaged
|
||||
@NoSideEffects
|
||||
PlatformClassMetadata getMetadata();
|
||||
|
||||
@JSProperty("classObject")
|
||||
@Unmanaged
|
||||
@NoSideEffects
|
||||
void setJavaClass(PlatformObject obj);
|
||||
|
||||
@JSProperty("classObject")
|
||||
@Unmanaged
|
||||
@NoSideEffects
|
||||
PlatformObject getJavaClass();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package org.teavm.platform;
|
||||
|
||||
import org.teavm.interop.NoSideEffects;
|
||||
import org.teavm.interop.Unmanaged;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.JSProperty;
|
||||
|
@ -22,40 +23,51 @@ import org.teavm.jso.JSProperty;
|
|||
public interface PlatformClassMetadata extends JSObject {
|
||||
@JSProperty("item")
|
||||
@Unmanaged
|
||||
@NoSideEffects
|
||||
PlatformClass getArrayItem();
|
||||
|
||||
@JSProperty
|
||||
@NoSideEffects
|
||||
PlatformSequence<PlatformClass> getSupertypes();
|
||||
|
||||
@JSProperty
|
||||
@Unmanaged
|
||||
@NoSideEffects
|
||||
PlatformClass getSuperclass();
|
||||
|
||||
@JSProperty
|
||||
@Unmanaged
|
||||
@NoSideEffects
|
||||
String getName();
|
||||
|
||||
@JSProperty
|
||||
@NoSideEffects
|
||||
boolean isPrimitive();
|
||||
|
||||
@JSProperty
|
||||
@NoSideEffects
|
||||
boolean isEnum();
|
||||
|
||||
@JSProperty
|
||||
@NoSideEffects
|
||||
int getFlags();
|
||||
|
||||
@JSProperty
|
||||
@NoSideEffects
|
||||
int getAccessLevel();
|
||||
|
||||
@JSProperty
|
||||
@Unmanaged
|
||||
@NoSideEffects
|
||||
String getSimpleName();
|
||||
|
||||
@JSProperty
|
||||
@Unmanaged
|
||||
@NoSideEffects
|
||||
PlatformClass getEnclosingClass();
|
||||
|
||||
@JSProperty
|
||||
@Unmanaged
|
||||
@NoSideEffects
|
||||
PlatformClass getDeclaringClass();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package org.teavm.platform;
|
||||
|
||||
import org.teavm.interop.NoSideEffects;
|
||||
import org.teavm.interop.Unmanaged;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.JSProperty;
|
||||
|
@ -22,13 +23,16 @@ import org.teavm.jso.JSProperty;
|
|||
public interface PlatformObject extends JSObject {
|
||||
@JSProperty("constructor")
|
||||
@Unmanaged
|
||||
@NoSideEffects
|
||||
PlatformClass getPlatformClass();
|
||||
|
||||
@JSProperty("$id$")
|
||||
@Unmanaged
|
||||
@NoSideEffects
|
||||
int getId();
|
||||
|
||||
@JSProperty("$id$")
|
||||
@Unmanaged
|
||||
@NoSideEffects
|
||||
void setId(int id);
|
||||
}
|
||||
|
|
|
@ -17,12 +17,14 @@ package org.teavm.platform;
|
|||
|
||||
import org.teavm.backend.javascript.spi.InjectedBy;
|
||||
import org.teavm.dependency.PluggableDependency;
|
||||
import org.teavm.interop.NoSideEffects;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.JSProperty;
|
||||
import org.teavm.platform.plugin.PlatformQueueGenerator;
|
||||
|
||||
public abstract class PlatformQueue<T> implements JSObject {
|
||||
@JSProperty
|
||||
@NoSideEffects
|
||||
public abstract int getLength();
|
||||
|
||||
public final boolean isEmpty() {
|
||||
|
@ -47,5 +49,6 @@ public abstract class PlatformQueue<T> implements JSObject {
|
|||
|
||||
@InjectedBy(PlatformQueueGenerator.class)
|
||||
@PluggableDependency(PlatformQueueGenerator.class)
|
||||
@NoSideEffects
|
||||
private static native <S> S unwrap(PlatformObject obj);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user