Repair incremental builder

This commit is contained in:
Alexey Andreev 2015-10-21 20:51:43 +03:00
parent edf2a47f27
commit 8702f7ee33
3 changed files with 24 additions and 4 deletions

View File

@ -1,9 +1,11 @@
package org.teavm.classlib.impl.lambda; package org.teavm.classlib.impl.lambda;
import java.util.Arrays; import java.util.Arrays;
import org.teavm.cache.NoCache;
import org.teavm.dependency.BootstrapMethodSubstitutor; import org.teavm.dependency.BootstrapMethodSubstitutor;
import org.teavm.dependency.DynamicCallSite; import org.teavm.dependency.DynamicCallSite;
import org.teavm.model.AccessLevel; import org.teavm.model.AccessLevel;
import org.teavm.model.AnnotationHolder;
import org.teavm.model.ClassHolder; import org.teavm.model.ClassHolder;
import org.teavm.model.ClassReader; import org.teavm.model.ClassReader;
import org.teavm.model.ClassReaderSource; import org.teavm.model.ClassReaderSource;
@ -46,10 +48,12 @@ public class LambdaMetafactorySubstitutor implements BootstrapMethodSubstitutor
int capturedVarCount = callSite.getCalledMethod().parameterCount(); int capturedVarCount = callSite.getCalledMethod().parameterCount();
MethodHolder ctor = createConstructor(classSource, implementor, MethodHolder ctor = createConstructor(classSource, implementor,
Arrays.copyOfRange(invokedType, 0, capturedVarCount)); Arrays.copyOfRange(invokedType, 0, capturedVarCount));
ctor.getAnnotations().add(new AnnotationHolder(NoCache.class.getName()));
createBridge(classSource, implementor, callSite.getCalledMethod().getName(), instantiatedMethodType, createBridge(classSource, implementor, callSite.getCalledMethod().getName(), instantiatedMethodType,
samMethodType); samMethodType);
MethodHolder worker = new MethodHolder(callSite.getCalledMethod().getName(), instantiatedMethodType); MethodHolder worker = new MethodHolder(callSite.getCalledMethod().getName(), instantiatedMethodType);
worker.getAnnotations().add(new AnnotationHolder(NoCache.class.getName()));
worker.setLevel(AccessLevel.PUBLIC); worker.setLevel(AccessLevel.PUBLIC);
ProgramEmitter pe = ProgramEmitter.create(worker, callSite.getAgent().getClassSource()); ProgramEmitter pe = ProgramEmitter.create(worker, callSite.getAgent().getClassSource());
ValueEmitter thisVar = pe.var(0, implementor); ValueEmitter thisVar = pe.var(0, implementor);
@ -244,6 +248,7 @@ public class LambdaMetafactorySubstitutor implements BootstrapMethodSubstitutor
} }
MethodHolder bridge = new MethodHolder(name, bridgeTypes); MethodHolder bridge = new MethodHolder(name, bridgeTypes);
bridge.getAnnotations().add(new AnnotationHolder(NoCache.class.getName()));
bridge.setLevel(AccessLevel.PUBLIC); bridge.setLevel(AccessLevel.PUBLIC);
bridge.getModifiers().add(ElementModifier.BRIDGE); bridge.getModifiers().add(ElementModifier.BRIDGE);
ProgramEmitter pe = ProgramEmitter.create(bridge, classSource); ProgramEmitter pe = ProgramEmitter.create(bridge, classSource);

View File

@ -20,7 +20,9 @@ import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.teavm.cache.NoCache;
import org.teavm.callgraph.DefaultCallGraphNode; import org.teavm.callgraph.DefaultCallGraphNode;
import org.teavm.model.AnnotationHolder;
import org.teavm.model.BasicBlock; import org.teavm.model.BasicBlock;
import org.teavm.model.BasicBlockReader; import org.teavm.model.BasicBlockReader;
import org.teavm.model.CallLocation; import org.teavm.model.CallLocation;
@ -190,6 +192,7 @@ class DependencyGraphBuilder {
return; return;
} }
ProgramEmitter pe = ProgramEmitter.create(program, dependencyChecker.getClassSource()); ProgramEmitter pe = ProgramEmitter.create(program, dependencyChecker.getClassSource());
boolean hasIndy = false;
for (int i = 0; i < program.basicBlockCount(); ++i) { for (int i = 0; i < program.basicBlockCount(); ++i) {
BasicBlock block = program.basicBlockAt(i); BasicBlock block = program.basicBlockAt(i);
for (int j = 0; j < block.getInstructions().size(); ++j) { for (int j = 0; j < block.getInstructions().size(); ++j) {
@ -213,6 +216,7 @@ class DependencyGraphBuilder {
continue; continue;
} }
hasIndy = true;
BasicBlock splitBlock = program.createBasicBlock(); BasicBlock splitBlock = program.createBasicBlock();
List<Instruction> splitInstructions = block.getInstructions().subList(j + 1, List<Instruction> splitInstructions = block.getInstructions().subList(j + 1,
block.getInstructions().size()); block.getInstructions().size());
@ -254,6 +258,10 @@ class DependencyGraphBuilder {
pe.jump(splitBlock); pe.jump(splitBlock);
} }
} }
if (hasIndy && methodDep.method.getAnnotations().get(NoCache.class.getName()) == null) {
methodDep.method.getAnnotations().add(new AnnotationHolder(NoCache.class.getName()));
}
} }
private ExceptionConsumer createExceptionConsumer(MethodDependency methodDep, BasicBlockReader block) { private ExceptionConsumer createExceptionConsumer(MethodDependency methodDep, BasicBlockReader block) {

View File

@ -30,6 +30,7 @@ import org.mozilla.javascript.Context;
import org.mozilla.javascript.ast.AstNode; import org.mozilla.javascript.ast.AstNode;
import org.mozilla.javascript.ast.AstRoot; import org.mozilla.javascript.ast.AstRoot;
import org.mozilla.javascript.ast.FunctionNode; import org.mozilla.javascript.ast.FunctionNode;
import org.teavm.cache.NoCache;
import org.teavm.diagnostics.Diagnostics; import org.teavm.diagnostics.Diagnostics;
import org.teavm.javascript.spi.GeneratedBy; import org.teavm.javascript.spi.GeneratedBy;
import org.teavm.javascript.spi.InjectedBy; import org.teavm.javascript.spi.InjectedBy;
@ -304,7 +305,7 @@ class JSClassProcessor {
} }
CallLocation callLocation = new CallLocation(methodToProcess.getReference(), insn.getLocation()); CallLocation callLocation = new CallLocation(methodToProcess.getReference(), insn.getLocation());
replacement.clear(); replacement.clear();
if (processInvocation(method, callLocation, invoke)) { if (processInvocation(method, callLocation, invoke, methodToProcess)) {
block.getInstructions().set(j, replacement.get(0)); block.getInstructions().set(j, replacement.get(0));
block.getInstructions().addAll(j + 1, replacement.subList(1, replacement.size())); block.getInstructions().addAll(j + 1, replacement.subList(1, replacement.size()));
j += replacement.size() - 1; j += replacement.size() - 1;
@ -313,9 +314,10 @@ class JSClassProcessor {
} }
} }
private boolean processInvocation(MethodReader method, CallLocation callLocation, InvokeInstruction invoke) { private boolean processInvocation(MethodReader method, CallLocation callLocation, InvokeInstruction invoke,
MethodHolder methodToProcess) {
if (method.getAnnotations().get(JSBody.class.getName()) != null) { if (method.getAnnotations().get(JSBody.class.getName()) != null) {
return processJSBodyInvocation(method, callLocation, invoke); return processJSBodyInvocation(method, callLocation, invoke, methodToProcess);
} }
if (!typeHelper.isJavaScriptClass(invoke.getMethod().getClassName())) { if (!typeHelper.isJavaScriptClass(invoke.getMethod().getClassName())) {
@ -352,7 +354,8 @@ class JSClassProcessor {
} }
} }
private boolean processJSBodyInvocation(MethodReader method, CallLocation callLocation, InvokeInstruction invoke) { private boolean processJSBodyInvocation(MethodReader method, CallLocation callLocation, InvokeInstruction invoke,
MethodHolder methodToProcess) {
requireJSBody(diagnostics, method); requireJSBody(diagnostics, method);
MethodReference delegate = repository.methodMap.get(method.getReference()); MethodReference delegate = repository.methodMap.get(method.getReference());
if (delegate == null) { if (delegate == null) {
@ -382,6 +385,10 @@ class JSClassProcessor {
copyVar(result, invoke.getReceiver(), invoke.getLocation()); copyVar(result, invoke.getReceiver(), invoke.getLocation());
} }
if (methodToProcess.getAnnotations().get(NoCache.class.getName()) == null) {
methodToProcess.getAnnotations().add(new AnnotationHolder(NoCache.class.getName()));
}
return true; return true;
} }