mirror of
https://github.com/konsoletyper/teavm.git
synced 2024-11-21 01:00:54 +08:00
JS: fix strict mode null pointer check with inlining
This commit is contained in:
parent
be259f1667
commit
98490e92f6
@ -339,11 +339,17 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeInlining(Program program, MethodReader method) {
|
||||
if (strict) {
|
||||
nullCheckInsertion.transformProgram(program, method.getReference());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeOptimizations(Program program, MethodReader method) {
|
||||
if (strict) {
|
||||
boundCheckInsertion.transformProgram(program, method.getReference());
|
||||
nullCheckInsertion.transformProgram(program, method.getReference());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ public class DefaultInliningStrategy implements InliningStrategy {
|
||||
private final int depthThreshold;
|
||||
private final int totalComplexityThreshold;
|
||||
private final boolean onceUsedOnly;
|
||||
private int getComplexityDepth;
|
||||
|
||||
public DefaultInliningStrategy(int complexityThreshold, int depthThreshold, int totalComplexityThreshold,
|
||||
boolean onceUsedOnly) {
|
||||
@ -52,7 +53,7 @@ public class DefaultInliningStrategy implements InliningStrategy {
|
||||
return new InliningStepImpl(complexityHolder);
|
||||
}
|
||||
|
||||
private static Complexity getComplexity(ProgramReader program, InliningContext context) {
|
||||
private Complexity getComplexity(ProgramReader program, InliningContext context) {
|
||||
int complexity = 0;
|
||||
ComplexityCounter counter = new ComplexityCounter(context);
|
||||
for (int i = 0; i < program.basicBlockCount(); ++i) {
|
||||
@ -101,7 +102,7 @@ public class DefaultInliningStrategy implements InliningStrategy {
|
||||
int complexity;
|
||||
}
|
||||
|
||||
static class ComplexityCounter extends AbstractInstructionReader {
|
||||
class ComplexityCounter extends AbstractInstructionReader {
|
||||
InliningContext context;
|
||||
int complexity;
|
||||
boolean callsToUsedOnceMethods;
|
||||
@ -132,10 +133,12 @@ public class DefaultInliningStrategy implements InliningStrategy {
|
||||
}
|
||||
|
||||
private boolean isTrivialCall(ProgramReader program) {
|
||||
if (program == null) {
|
||||
if (program == null || getComplexityDepth > 10) {
|
||||
return false;
|
||||
}
|
||||
getComplexityDepth++;
|
||||
Complexity complexity = getComplexity(program, context);
|
||||
getComplexityDepth--;
|
||||
return complexity.score <= 1 && !complexity.callsToUsedOnceMethods;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@ import org.teavm.model.instructions.AbstractInstructionVisitor;
|
||||
import org.teavm.model.instructions.ArrayLengthInstruction;
|
||||
import org.teavm.model.instructions.AssignInstruction;
|
||||
import org.teavm.model.instructions.BinaryInstruction;
|
||||
import org.teavm.model.instructions.BoundCheckInstruction;
|
||||
import org.teavm.model.instructions.CastInstruction;
|
||||
import org.teavm.model.instructions.CastIntegerInstruction;
|
||||
import org.teavm.model.instructions.CastNumberInstruction;
|
||||
@ -45,7 +44,6 @@ import org.teavm.model.instructions.InvokeInstruction;
|
||||
import org.teavm.model.instructions.IsInstanceInstruction;
|
||||
import org.teavm.model.instructions.LongConstantInstruction;
|
||||
import org.teavm.model.instructions.NegateInstruction;
|
||||
import org.teavm.model.instructions.NullCheckInstruction;
|
||||
import org.teavm.model.instructions.NullConstantInstruction;
|
||||
import org.teavm.model.instructions.StringConstantInstruction;
|
||||
import org.teavm.model.instructions.UnwrapArrayInstruction;
|
||||
@ -256,15 +254,5 @@ public class UnusedVariableElimination implements MethodOptimization {
|
||||
public void visit(IsInstanceInstruction insn) {
|
||||
requestUsage(insn.getReceiver());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(NullCheckInstruction insn) {
|
||||
requestUsage(insn.getReceiver());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(BoundCheckInstruction insn) {
|
||||
requestUsage(insn.getReceiver());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,6 +119,19 @@ public final class VariableEscapeAnalyzer {
|
||||
if (insn.getArray() != null) {
|
||||
escaping[insn.getArray().getIndex()] = true;
|
||||
}
|
||||
if (insn.getReceiver() != null) {
|
||||
escaping[insn.getReceiver().getIndex()] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(NullCheckInstruction insn) {
|
||||
if (insn.getValue() != null) {
|
||||
escaping[insn.getValue().getIndex()] = true;
|
||||
}
|
||||
if (insn.getReceiver() != null) {
|
||||
escaping[insn.getReceiver().getIndex()] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -467,6 +467,14 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||
|
||||
target.setController(targetController);
|
||||
|
||||
for (String className : classSet.getClassNames()) {
|
||||
ClassHolder cls = classSet.get(className);
|
||||
for (MethodHolder method : cls.getMethods()) {
|
||||
if (method.getProgram() != null) {
|
||||
target.beforeInlining(method.getProgram(), method);
|
||||
}
|
||||
}
|
||||
}
|
||||
inline(classSet);
|
||||
if (wasCancelled()) {
|
||||
return null;
|
||||
@ -979,6 +987,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||
missingItemsProcessor.processMethod(method.getReference(), program);
|
||||
linker.link(method, program);
|
||||
clinitInsertion.apply(method, program);
|
||||
target.beforeInlining(program, method);
|
||||
program = optimizeMethodCacheMiss(method, program);
|
||||
Program finalProgram = program;
|
||||
programCache.store(method.getReference(), finalProgram,
|
||||
|
@ -40,6 +40,9 @@ public interface TeaVMTarget {
|
||||
|
||||
void contributeDependencies(DependencyAnalyzer dependencyAnalyzer);
|
||||
|
||||
default void beforeInlining(Program program, MethodReader method) {
|
||||
}
|
||||
|
||||
default void analyzeBeforeOptimizations(ListableClassReaderSource classSource) {
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user