summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-10-23 10:41:59 +1000
committerJason Zaugg <jzaugg@gmail.com>2014-11-07 18:19:10 +1000
commit33393c759cc6081cffc3089baf806c08d64dbffc (patch)
tree2656ccd7702d10178efe13379104babe13419cc9 /src/compiler
parentced9e167d9d2c9016e76b6db94ceea7335d37bf2 (diff)
downloadscala-33393c759cc6081cffc3089baf806c08d64dbffc.tar.gz
scala-33393c759cc6081cffc3089baf806c08d64dbffc.tar.bz2
scala-33393c759cc6081cffc3089baf806c08d64dbffc.zip
SI-8933 Disable static Symbol literal cache in traits
In Scala 2.8.2, an optimization was added to create a static cache for Symbol literals (ie, the results of `Symbol.apply("foo"))`. This saves the map lookup on the second pass through code. This actually was broken somewhere during the Scala 2.10 series, after the addition of an overloaded `apply` method to `Symbol`. The cache synthesis code was made aware of the overload and brought back to working condition recently, in #3149. However, this has uncovered a latent bug when the Symbol literals are defined with traits. One of the enclosed tests failed with: jvm > t8933b-run.log java.lang.IllegalAccessError: tried to access field MotherClass.symbol$1 from class MixinWithSymbol$class at MixinWithSymbol$class.symbolFromTrait(A.scala:3) at MotherClass.symbolFromTrait(Test.scala:1) This commit simply disables the optimization if we are in a trait. Alternative fixes might be: a) make the static Symbol cache field public / b) "mixin" the static symbol cache. Neither of these seem worth the effort and risk for an already fairly situational optimization. Here's how the optimization looks in a class: % cat sandbox/test.scala; qscalac sandbox/test.scala && echo ":javap C" | qscala; class C { 'a; 'b } Welcome to Scala version 2.11.5-20141106-145558-aa558dce6d (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_20). Type in expressions to have them evaluated. Type :help for more information. scala> :javap C Size 722 bytes MD5 checksum 6bb00189166917254e8d40499ee7c887 Compiled from "test.scala" public class C { public static {}; descriptor: ()V flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=0, args_size=0 0: getstatic #16 // Field scala/Symbol$.MODULE$:Lscala/Symbol$; 3: ldc #18 // String a 5: invokevirtual #22 // Method scala/Symbol$.apply:(Ljava/lang/String;)Lscala/Symbol; 8: putstatic #26 // Field symbol$1:Lscala/Symbol; 11: getstatic #16 // Field scala/Symbol$.MODULE$:Lscala/Symbol$; 14: ldc #28 // String b 16: invokevirtual #22 // Method scala/Symbol$.apply:(Ljava/lang/String;)Lscala/Symbol; 19: putstatic #31 // Field symbol$2:Lscala/Symbol; 22: return public C(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #34 // Method java/lang/Object."<init>":()V 4: getstatic #26 // Field symbol$1:Lscala/Symbol; 7: pop 8: getstatic #31 // Field symbol$2:Lscala/Symbol; 11: pop 12: return } fixup
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index 1664fe0e0d..e5a19205ae 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -520,7 +520,7 @@ abstract class CleanUp extends Statics with Transform with ast.TreeDSL {
* And, finally, be advised - Scala's Symbol literal (scala.Symbol) and the Symbol class of the compiler
* have little in common.
*/
- case Apply(fn, (arg @ Literal(Constant(symname: String))) :: Nil) if fn.symbol == Symbol_apply =>
+ case Apply(fn, (arg @ Literal(Constant(symname: String))) :: Nil) if fn.symbol == Symbol_apply && !currentClass.isTrait =>
def transformApply = {
// add the symbol name to a map if it's not there already
val rhs = gen.mkMethodCall(Symbol_apply, arg :: Nil)