diff options
author | Paul Phillips <paulp@improving.org> | 2013-01-25 07:57:48 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2013-01-25 07:57:48 -0800 |
commit | 417304514b664e5f66bfc06fb2b0e86b99d23a63 (patch) | |
tree | e4b4b5516667615567ac65ed4bb6a498399b43d0 /src | |
parent | 4e27a23082cc0fefa1b73c9b1f180547794aa5ff (diff) | |
parent | 0d01cc1c300b718afd1fe69d5030d36d8000e0cd (diff) | |
download | scala-417304514b664e5f66bfc06fb2b0e86b99d23a63.tar.gz scala-417304514b664e5f66bfc06fb2b0e86b99d23a63.tar.bz2 scala-417304514b664e5f66bfc06fb2b0e86b99d23a63.zip |
Merge pull request #1902 from paulp/issue/6969
SI-6969, mishandling of SoftReferences in method cache.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/CleanUp.scala | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index a6ea45d8b4..44510ab0c2 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -207,12 +207,17 @@ abstract class CleanUp extends Transform with ast.TreeDSL { var reflPoly$Cache: SoftReference[scala.runtime.MethodCache] = new SoftReference(new EmptyMethodCache()) def reflMethod$Method(forReceiver: JClass[_]): JMethod = { - var method: JMethod = reflPoly$Cache.find(forReceiver) - if (method != null) + var methodCache: MethodCache = reflPoly$Cache.find(forReceiver) + if (methodCache eq null) { + methodCache = new EmptyMethodCache + reflPoly$Cache = new SoftReference(methodCache) + } + var method: JMethod = methodCache.find(forReceiver) + if (method ne null) return method else { method = ScalaRunTime.ensureAccessible(forReceiver.getMethod("xyz", reflParams$Cache)) - reflPoly$Cache = new SoftReference(reflPoly$Cache.get.add(forReceiver, method)) + reflPoly$Cache = new SoftReference(methodCache.add(forReceiver, method)) return method } } @@ -229,16 +234,22 @@ abstract class CleanUp extends Transform with ast.TreeDSL { def getPolyCache = gen.mkCast(fn(REF(reflPolyCacheSym), nme.get), MethodCacheClass.tpe) addStaticMethodToClass((reflMethodSym, forReceiverSym) => { + val methodCache = reflMethodSym.newVariable(mkTerm("methodCache"), ad.pos) setInfo MethodCacheClass.tpe val methodSym = reflMethodSym.newVariable(mkTerm("method"), ad.pos) setInfo MethodClass.tpe BLOCK( - IF (getPolyCache OBJ_EQ NULL) THEN (REF(reflPolyCacheSym) === mkNewPolyCache) ENDIF, - VAL(methodSym) === ((getPolyCache DOT methodCache_find)(REF(forReceiverSym))) , - IF (REF(methodSym) OBJ_!= NULL) . + VAR(methodCache) === getPolyCache, + IF (REF(methodCache) OBJ_EQ NULL) THEN BLOCK( + REF(methodCache) === NEW(TypeTree(EmptyMethodCacheClass.tpe)), + REF(reflPolyCacheSym) === gen.mkSoftRef(REF(methodCache)) + ) ENDIF, + + VAR(methodSym) === (REF(methodCache) DOT methodCache_find)(REF(forReceiverSym)), + IF (REF(methodSym) OBJ_NE NULL) . THEN (Return(REF(methodSym))) ELSE { def methodSymRHS = ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), REF(reflParamsCacheSym))) - def cacheRHS = ((getPolyCache DOT methodCache_add)(REF(forReceiverSym), REF(methodSym))) + def cacheRHS = ((REF(methodCache) DOT methodCache_add)(REF(forReceiverSym), REF(methodSym))) BLOCK( REF(methodSym) === (REF(ensureAccessibleMethod) APPLY (methodSymRHS)), REF(reflPolyCacheSym) === gen.mkSoftRef(cacheRHS), @@ -247,6 +258,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { } ) }) + } /* ### HANDLING METHODS NORMALLY COMPILED TO OPERATORS ### */ |