summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala66
1 files changed, 2 insertions, 64 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala b/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala
index 120ee5c26e..a1923ead21 100644
--- a/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala
@@ -326,16 +326,7 @@ trait AccessorSynthesis extends Transform with ast.TreeDSL {
*
* This way the inliner should optimize the fast path because the method body is small enough.
*/
- def expandLazyClassMember(lazyVar: Symbol, lazyAccessor: Symbol, transformedRhs: Tree, nullables: Map[Symbol, List[Symbol]]): Tree = {
- // use cast so that specialization can turn null.asInstanceOf[T] into null.asInstanceOf[Long]
- def nullify(sym: Symbol) =
- Select(thisRef, sym.accessedOrSelf) === gen.mkAsInstanceOf(NULL, sym.info.resultType)
-
- val nulls = nullables.getOrElse(lazyAccessor, Nil) map nullify
-
- if (nulls.nonEmpty)
- log("nulling fields inside " + lazyAccessor + ": " + nulls)
-
+ def expandLazyClassMember(lazyVar: global.Symbol, lazyAccessor: global.Symbol, transformedRhs: global.Tree): Tree = {
val slowPathSym = slowPathFor(lazyAccessor)
val rhsAtSlowDef = transformedRhs.changeOwner(lazyAccessor -> slowPathSym)
@@ -346,7 +337,7 @@ trait AccessorSynthesis extends Transform with ast.TreeDSL {
def needsInit = mkTest(lazyAccessor)
val doInit = Block(List(storeRes), mkSetFlag(lazyAccessor))
// the slow part of double-checked locking (TODO: is this the most efficient pattern? https://github.come/scala/scala-dev/issues/204)
- val slowPathRhs = Block(gen.mkSynchronized(thisRef)(If(needsInit, doInit, EmptyTree)) :: nulls, selectVar)
+ val slowPathRhs = Block(gen.mkSynchronized(thisRef)(If(needsInit, doInit, EmptyTree)) :: Nil, selectVar)
// The lazy accessor delegates to the compute method if needed, otherwise just accesses the var (it was initialized previously)
// `if ((bitmap&n & MASK) == 0) this.l$compute() else l$`
@@ -358,59 +349,6 @@ trait AccessorSynthesis extends Transform with ast.TreeDSL {
}
}
- /** Map lazy values to the fields they should null after initialization. */
- // TODO: fix
- def lazyValNullables(clazz: Symbol, templStats: List[Tree]): Map[Symbol, List[Symbol]] = {
- // if there are no lazy fields, take the fast path and save a traversal of the whole AST
- if (!clazz.info.decls.exists(_.isLazy)) Map()
- else {
- // A map of single-use fields to the lazy value that uses them during initialization.
- // Each field has to be private and defined in the enclosing class, and there must
- // be exactly one lazy value using it.
- //
- // Such fields will be nulled after the initializer has memoized the lazy value.
- val singleUseFields: Map[Symbol, List[Symbol]] = {
- val usedIn = mutable.HashMap[Symbol, List[Symbol]]() withDefaultValue Nil
-
- object SingleUseTraverser extends Traverser {
- override def traverse(tree: Tree) {
- tree match {
- // assignment targets don't count as a dereference -- only check the rhs
- case Assign(_, rhs) => traverse(rhs)
- case tree: RefTree if tree.symbol != NoSymbol =>
- val sym = tree.symbol
- // println(s"$sym in ${sym.owner} from $currentOwner ($tree)")
- if ((sym.hasAccessorFlag || (sym.isTerm && !sym.isMethod)) && sym.isPrivate && !sym.isLazy // non-lazy private field or its accessor
- && !definitions.isPrimitiveValueClass(sym.tpe.resultType.typeSymbol) // primitives don't hang on to significant amounts of heap
- && sym.owner == currentOwner.enclClass && !(currentOwner.isGetter && currentOwner.accessed == sym)) {
-
- // println("added use in: " + currentOwner + " -- " + tree)
- usedIn(sym) ::= currentOwner
- }
- super.traverse(tree)
- case _ => super.traverse(tree)
- }
- }
- }
- templStats foreach SingleUseTraverser.apply
- // println("usedIn: " + usedIn)
-
- // only consider usages from non-transient lazy vals (SI-9365)
- val singlyUsedIn = usedIn filter { case (_, member :: Nil) => member.isLazy && !member.accessed.hasAnnotation(TransientAttr) case _ => false } toMap
-
- // println("singlyUsedIn: " + singlyUsedIn)
- singlyUsedIn
- }
-
- val map = mutable.Map[Symbol, Set[Symbol]]() withDefaultValue Set()
- // invert the map to see which fields can be nulled for each non-transient lazy val
- for ((field, users) <- singleUseFields; lazyFld <- users) map(lazyFld) += field
-
- map.mapValues(_.toList sortBy (_.id)).toMap
- }
- }
-
-
class SynthInitCheckedAccessorsIn(protected val clazz: Symbol) extends SynthCheckedAccessorsTreesInClass with CheckInitAccessorSymbolSynth {
private object addInitBitsTransformer extends Transformer {
private def checkedGetter(lhs: Tree)(pos: Position) = {