Reduce minumus JS runtime a little

This commit is contained in:
Alexey Andreev 2018-12-07 00:52:05 +03:00
parent 2bb146af47
commit 1b83519280
4 changed files with 52 additions and 12 deletions

View File

@ -100,6 +100,7 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
private TeaVMTargetController controller; private TeaVMTargetController controller;
private boolean minifying = true; private boolean minifying = true;
private boolean stackTraceIncluded = false;
private final Map<MethodReference, Generator> methodGenerators = new HashMap<>(); private final Map<MethodReference, Generator> methodGenerators = new HashMap<>();
private final Map<MethodReference, Injector> methodInjectors = new HashMap<>(); private final Map<MethodReference, Injector> methodInjectors = new HashMap<>();
private final List<Function<ProviderContext, Generator>> generatorProviders = new ArrayList<>(); private final List<Function<ProviderContext, Generator>> generatorProviders = new ArrayList<>();
@ -194,6 +195,10 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
return true; return true;
} }
public void setStackTraceIncluded(boolean stackTraceIncluded) {
this.stackTraceIncluded = stackTraceIncluded;
}
@Override @Override
public List<TeaVMHostExtension> getHostExtensions() { public List<TeaVMHostExtension> getHostExtensions() {
return Collections.singletonList(this); return Collections.singletonList(this);
@ -219,7 +224,7 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
dependencyAnalyzer.linkField(new FieldReference(String.class.getName(), "characters"), null); dependencyAnalyzer.linkField(new FieldReference(String.class.getName(), "characters"), null);
dependencyAnalyzer.linkMethod(new MethodReference(Object.class, "clone", Object.class), null).use(); dependencyAnalyzer.linkMethod(new MethodReference(Object.class, "clone", Object.class), null);
MethodDependency exceptionCons = dependencyAnalyzer.linkMethod(new MethodReference( MethodDependency exceptionCons = dependencyAnalyzer.linkMethod(new MethodReference(
NoClassDefFoundError.class, "<init>", String.class, void.class), null); NoClassDefFoundError.class, "<init>", String.class, void.class), null);
@ -246,6 +251,16 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
exceptionCons.getVariable(1).propagate(stringType); exceptionCons.getVariable(1).propagate(stringType);
exceptionCons.use(); exceptionCons.use();
if (stackTraceIncluded) {
includeStackTraceMethods(dependencyAnalyzer);
}
}
public static void includeStackTraceMethods(DependencyAnalyzer dependencyAnalyzer) {
MethodDependency dep;
DependencyType stringType = dependencyAnalyzer.getType("java.lang.String");
dep = dependencyAnalyzer.linkMethod(new MethodReference( dep = dependencyAnalyzer.linkMethod(new MethodReference(
StackTraceElement.class, "<init>", String.class, String.class, String.class, StackTraceElement.class, "<init>", String.class, String.class, String.class,
int.class, void.class), null); int.class, void.class), null);

View File

@ -44,6 +44,10 @@ public class RuntimeRenderer {
String.class, String.class); String.class, String.class);
private static final MethodDescriptor CURRENT_THREAD_METHOD = new MethodDescriptor("currentThread", private static final MethodDescriptor CURRENT_THREAD_METHOD = new MethodDescriptor("currentThread",
Thread.class); Thread.class);
private static final MethodReference STACK_TRACE_ELEM_INIT = new MethodReference(StackTraceElement.class,
"<init>", String.class, String.class, String.class, int.class, void.class);
private static final MethodReference SET_STACK_TRACE_METHOD = new MethodReference(Throwable.class,
"setStackTrace", StackTraceElement[].class, void.class);
private final ClassReaderSource classSource; private final ClassReaderSource classSource;
private final NamingStrategy naming; private final NamingStrategy naming;
@ -197,26 +201,37 @@ public class RuntimeRenderer {
} }
private void renderCreateStackTraceElement() throws IOException { private void renderCreateStackTraceElement() throws IOException {
ClassReader cls = classSource.get(STACK_TRACE_ELEM_INIT.getClassName());
boolean supported = cls != null && cls.getMethod(STACK_TRACE_ELEM_INIT.getDescriptor()) != null;
writer.append("function $rt_createStackElement(") writer.append("function $rt_createStackElement(")
.append("className,").ws() .append("className,").ws()
.append("methodName,").ws() .append("methodName,").ws()
.append("fileName,").ws() .append("fileName,").ws()
.append("lineNumber)").ws().append("{").indent().softNewLine(); .append("lineNumber)").ws().append("{").indent().softNewLine();
writer.append("return "); writer.append("return ");
writer.append(writer.getNaming().getNameForInit(new MethodReference(StackTraceElement.class, if (supported) {
"<init>", String.class, String.class, String.class, int.class, void.class))); writer.append(writer.getNaming().getNameForInit(STACK_TRACE_ELEM_INIT));
writer.append("(className,").ws() writer.append("(className,").ws()
.append("methodName,").ws() .append("methodName,").ws()
.append("fileName,").ws() .append("fileName,").ws()
.append("lineNumber);").softNewLine(); .append("lineNumber)");
} else {
writer.append("null");
}
writer.append(";").softNewLine();
writer.outdent().append("}").newLine(); writer.outdent().append("}").newLine();
} }
private void renderSetStackTrace() throws IOException { private void renderSetStackTrace() throws IOException {
ClassReader cls = classSource.get(SET_STACK_TRACE_METHOD.getClassName());
boolean supported = cls != null && cls.getMethod(SET_STACK_TRACE_METHOD.getDescriptor()) != null;
writer.append("function $rt_setStack(e,").ws().append("stack)").ws().append("{").indent().softNewLine(); writer.append("function $rt_setStack(e,").ws().append("stack)").ws().append("{").indent().softNewLine();
writer.appendMethodBody(new MethodReference(Throwable.class, "setStackTrace", StackTraceElement[].class, if (supported) {
void.class)); writer.appendMethodBody(SET_STACK_TRACE_METHOD);
writer.append("(e,").ws().append("stack);").softNewLine(); writer.append("(e,").ws().append("stack);").softNewLine();
}
writer.outdent().append("}").newLine(); writer.outdent().append("}").newLine();
} }
} }

View File

@ -231,14 +231,23 @@ function $rt_exception(ex) {
if (typeof $rt_decodeStack === "function" && err.stack) { if (typeof $rt_decodeStack === "function" && err.stack) {
var stack = $rt_decodeStack(err.stack); var stack = $rt_decodeStack(err.stack);
var javaStack = $rt_createArray($rt_objcls(), stack.length); var javaStack = $rt_createArray($rt_objcls(), stack.length);
var elem;
var noStack = false;
for (var i = 0; i < stack.length; ++i) { for (var i = 0; i < stack.length; ++i) {
var element = stack[i]; var element = stack[i];
javaStack.data[i] = $rt_createStackElement($rt_str(element.className), elem = $rt_createStackElement($rt_str(element.className),
$rt_str(element.methodName), $rt_str(element.fileName), element.lineNumber); $rt_str(element.methodName), $rt_str(element.fileName), element.lineNumber);
if (elem == null) {
noStack = true;
break;
} }
javaStack.data[i] = elem;
}
if (!noStack) {
$rt_setStack(ex, javaStack); $rt_setStack(ex, javaStack);
} }
} }
}
return err; return err;
} }
function $rt_createMultiArray(cls, dimensions) { function $rt_createMultiArray(cls, dimensions) {

View File

@ -559,6 +559,7 @@ public class TeaVMTestRunner extends Runner implements Filterable {
JavaScriptTarget target = new JavaScriptTarget(); JavaScriptTarget target = new JavaScriptTarget();
if (decodeStack) { if (decodeStack) {
target.setDebugEmitter(debugEmitter); target.setDebugEmitter(debugEmitter);
target.setStackTraceIncluded(true);
} }
return target; return target;
}; };