diff --git a/classlib/src/main/java/org/teavm/classlib/impl/lambda/LambdaMetafactorySubstitutor.java b/classlib/src/main/java/org/teavm/classlib/impl/lambda/LambdaMetafactorySubstitutor.java index 986931f3e..44574d0af 100644 --- a/classlib/src/main/java/org/teavm/classlib/impl/lambda/LambdaMetafactorySubstitutor.java +++ b/classlib/src/main/java/org/teavm/classlib/impl/lambda/LambdaMetafactorySubstitutor.java @@ -1,9 +1,11 @@ package org.teavm.classlib.impl.lambda; import java.util.Arrays; +import org.teavm.cache.NoCache; import org.teavm.dependency.BootstrapMethodSubstitutor; import org.teavm.dependency.DynamicCallSite; import org.teavm.model.AccessLevel; +import org.teavm.model.AnnotationHolder; import org.teavm.model.ClassHolder; import org.teavm.model.ClassReader; import org.teavm.model.ClassReaderSource; @@ -46,10 +48,12 @@ public class LambdaMetafactorySubstitutor implements BootstrapMethodSubstitutor int capturedVarCount = callSite.getCalledMethod().parameterCount(); MethodHolder ctor = createConstructor(classSource, implementor, Arrays.copyOfRange(invokedType, 0, capturedVarCount)); + ctor.getAnnotations().add(new AnnotationHolder(NoCache.class.getName())); createBridge(classSource, implementor, callSite.getCalledMethod().getName(), instantiatedMethodType, samMethodType); MethodHolder worker = new MethodHolder(callSite.getCalledMethod().getName(), instantiatedMethodType); + worker.getAnnotations().add(new AnnotationHolder(NoCache.class.getName())); worker.setLevel(AccessLevel.PUBLIC); ProgramEmitter pe = ProgramEmitter.create(worker, callSite.getAgent().getClassSource()); ValueEmitter thisVar = pe.var(0, implementor); @@ -244,6 +248,7 @@ public class LambdaMetafactorySubstitutor implements BootstrapMethodSubstitutor } MethodHolder bridge = new MethodHolder(name, bridgeTypes); + bridge.getAnnotations().add(new AnnotationHolder(NoCache.class.getName())); bridge.setLevel(AccessLevel.PUBLIC); bridge.getModifiers().add(ElementModifier.BRIDGE); ProgramEmitter pe = ProgramEmitter.create(bridge, classSource); diff --git a/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java b/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java index d08be0772..5831e35b5 100644 --- a/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java +++ b/core/src/main/java/org/teavm/dependency/DependencyGraphBuilder.java @@ -20,7 +20,9 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; +import org.teavm.cache.NoCache; import org.teavm.callgraph.DefaultCallGraphNode; +import org.teavm.model.AnnotationHolder; import org.teavm.model.BasicBlock; import org.teavm.model.BasicBlockReader; import org.teavm.model.CallLocation; @@ -190,6 +192,7 @@ class DependencyGraphBuilder { return; } ProgramEmitter pe = ProgramEmitter.create(program, dependencyChecker.getClassSource()); + boolean hasIndy = false; for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlock block = program.basicBlockAt(i); for (int j = 0; j < block.getInstructions().size(); ++j) { @@ -213,6 +216,7 @@ class DependencyGraphBuilder { continue; } + hasIndy = true; BasicBlock splitBlock = program.createBasicBlock(); List splitInstructions = block.getInstructions().subList(j + 1, block.getInstructions().size()); @@ -254,6 +258,10 @@ class DependencyGraphBuilder { 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) { diff --git a/jso/impl/src/main/java/org/teavm/jso/impl/JSClassProcessor.java b/jso/impl/src/main/java/org/teavm/jso/impl/JSClassProcessor.java index 432ae6dfa..61af97332 100644 --- a/jso/impl/src/main/java/org/teavm/jso/impl/JSClassProcessor.java +++ b/jso/impl/src/main/java/org/teavm/jso/impl/JSClassProcessor.java @@ -30,6 +30,7 @@ import org.mozilla.javascript.Context; import org.mozilla.javascript.ast.AstNode; import org.mozilla.javascript.ast.AstRoot; import org.mozilla.javascript.ast.FunctionNode; +import org.teavm.cache.NoCache; import org.teavm.diagnostics.Diagnostics; import org.teavm.javascript.spi.GeneratedBy; import org.teavm.javascript.spi.InjectedBy; @@ -304,7 +305,7 @@ class JSClassProcessor { } CallLocation callLocation = new CallLocation(methodToProcess.getReference(), insn.getLocation()); replacement.clear(); - if (processInvocation(method, callLocation, invoke)) { + if (processInvocation(method, callLocation, invoke, methodToProcess)) { block.getInstructions().set(j, replacement.get(0)); block.getInstructions().addAll(j + 1, replacement.subList(1, replacement.size())); 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) { - return processJSBodyInvocation(method, callLocation, invoke); + return processJSBodyInvocation(method, callLocation, invoke, methodToProcess); } 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); MethodReference delegate = repository.methodMap.get(method.getReference()); if (delegate == null) { @@ -382,6 +385,10 @@ class JSClassProcessor { copyVar(result, invoke.getReceiver(), invoke.getLocation()); } + if (methodToProcess.getAnnotations().get(NoCache.class.getName()) == null) { + methodToProcess.getAnnotations().add(new AnnotationHolder(NoCache.class.getName())); + } + return true; }