From 52743262319bceadb3d1335db1470b52005d3198 Mon Sep 17 00:00:00 2001 From: Lukas Stadler <lukas.stadler@oracle.com> Date: Mon, 12 Dec 2016 12:03:55 +0100 Subject: [PATCH] thread safety in PromiseNode --- .../truffle/r/nodes/function/PromiseNode.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java index c46789e565..e9a2275663 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java @@ -409,8 +409,17 @@ public abstract class PromiseNode extends RNode { private final ConditionProfile argsValueAndNamesProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile containsVarargProfile = ConditionProfile.createBinaryProfile(); - @CompilationFinal ArgumentsSignature cachedVarArgSignature; - @CompilationFinal ArgumentsSignature cachedResultSignature; + private static final class Cache { + private final ArgumentsSignature signature; + private final ArgumentsSignature result; + + protected Cache(ArgumentsSignature signature, ArgumentsSignature result) { + this.signature = signature; + this.result = result; + } + } + + @CompilationFinal private Cache varArgsCache; InlineVarArgsNode(RNode[] nodes, ArgumentsSignature signature) { this.varargs = nodes; @@ -455,13 +464,20 @@ public abstract class PromiseNode extends RNode { if (evaluatedArgs.length == 1) { finalSignature = ((RArgsValuesAndNames) evaluatedArgs[0]).getSignature(); } else { - if (cachedVarArgSignature == ArgumentsSignature.INVALID_SIGNATURE) { + Cache cache = varArgsCache; + if (cache == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + finalSignature = createSignature(evaluatedArgs, flattenedArgs.length); + varArgsCache = new Cache(varArgSignature, finalSignature); + } else if (cache.signature == ArgumentsSignature.INVALID_SIGNATURE) { finalSignature = createSignature(evaluatedArgs, flattenedArgs.length); - } else if (varArgSignature == cachedVarArgSignature) { - finalSignature = cachedResultSignature; + } else if (varArgSignature == cache.signature) { + finalSignature = cache.result; } else { + CompilerDirectives.transferToInterpreterAndInvalidate(); + // fallback to the generic case finalSignature = createSignature(evaluatedArgs, flattenedArgs.length); - cachedVarArgSignature = cachedVarArgSignature == null ? finalSignature : ArgumentsSignature.INVALID_SIGNATURE; + varArgsCache = new Cache(ArgumentsSignature.INVALID_SIGNATURE, null); } } return new RArgsValuesAndNames(flattenedArgs, finalSignature); -- GitLab