Permalink
Browse files

Part I of the Lazy Vals Saga: Bitmaps are no longer inherited.

  • Loading branch information...
hubertp committed May 2, 2012
1 parent e6d5d22 commit bdd9abedd87aea0806ce9bad6dcaba60e1eef69e
@@ -807,7 +807,6 @@ trait StdNames {
val BITMAP_NORMAL: NameType = BITMAP_PREFIX + "" // initialization bitmap for public/protected lazy vals
val BITMAP_TRANSIENT: NameType = BITMAP_PREFIX + "trans$" // initialization bitmap for transient lazy vals
- val BITMAP_PRIVATE: NameType = BITMAP_PREFIX + "priv$" // initialization bitmap for private lazy vals
val BITMAP_CHECKINIT: NameType = BITMAP_PREFIX + "init$" // initialization bitmap for checkinit values
val BITMAP_CHECKINIT_TRANSIENT: NameType = BITMAP_PREFIX + "inittrans$" // initialization bitmap for transient checkinit values
@@ -29,9 +29,6 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
/** Map a lazy, mixedin field accessor to it's trait member accessor */
private val initializer = perRunCaches.newMap[Symbol, Symbol]
- /** Deferred bitmaps that will be added during the transformation of a class */
- private val deferredBitmaps = perRunCaches.newMap[Symbol, List[Tree]]() withDefaultValue Nil
-
// --------- helper functions -----------------------------------------------
/** A member of a trait is implemented statically if its implementation after the
@@ -614,10 +611,6 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
if (isNormal) BITMAP_TRANSIENT
else BITMAP_CHECKINIT_TRANSIENT
}
- else if (field hasFlag PRIVATE | notPRIVATE) {
- if (isNormal) BITMAP_PRIVATE
- else BITMAP_CHECKINIT
- }
else {
if (isNormal) BITMAP_NORMAL
else BITMAP_CHECKINIT
@@ -686,11 +679,6 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
else newDefs ::: (stats filter isNotDuplicate)
}
- def addDeferredBitmap(clazz: Symbol, tree: Tree) {
- // Append the set of deferred defs
- deferredBitmaps(clazz) ::= typedPos(clazz.pos)(tree)
- }
-
/** If `stat` is a superaccessor, complete it by adding a right-hand side.
* Note: superaccessors are always abstract until this point.
* The method to call in a superaccessor is stored in the accessor symbol's alias field.
@@ -710,28 +698,17 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
import lazyVals._
- /**
- * Private or transient lazy vals use bitmaps that are private for the class context,
- * unlike public or protected vals, which can use inherited bitmaps.
- * Similarly fields in the checkinit mode use private bitmaps.
- */
- def isLocalBitmapField(field: Symbol) = (
- field.accessed.hasAnnotation(TransientAttr)
- || field.hasFlag(PRIVATE | notPRIVATE)
- || isCheckInitField(field)
- )
-
/**
* Return the bitmap field for 'offset'. Depending on the hierarchy it is possible to reuse
* the bitmap of its parents. If that does not exist yet we create one.
*/
- def bitmapFor(clazz0: Symbol, offset: Int, field: Symbol, searchParents: Boolean = true): Symbol = {
+ def bitmapFor(clazz0: Symbol, offset: Int, field: Symbol): Symbol = {
val category = bitmapCategory(field)
val bitmapName = nme.newBitmapName(category, offset / FLAGS_PER_WORD)
- val sym = clazz0.info.member(bitmapName)
+ val sym = clazz0.info.decl(bitmapName)
assert(!sym.isOverloaded, sym)
-
+
def createBitmap: Symbol = {
val sym = clazz0.newVariable(bitmapName, clazz0.pos) setInfo IntClass.tpe
beforeTyper(sym addAnnotation VolatileAttr)
@@ -740,55 +717,18 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
case nme.BITMAP_TRANSIENT | nme.BITMAP_CHECKINIT_TRANSIENT => sym addAnnotation TransientAttr
case _ =>
}
- category match {
- case nme.BITMAP_NORMAL if field.isLazy => sym setFlag PROTECTED
- case _ => sym setFlag PrivateLocal
- }
-
+ sym setFlag PrivateLocal
clazz0.info.decls.enter(sym)
- if (clazz0 == clazz)
- addDef(clazz.pos, VAL(sym) === ZERO)
- else {
- //FIXME: the assertion below will not work because of the way bitmaps are added.
- // They should be added during infoTransform, so that in separate compilation, bitmap
- // is a member of clazz and doesn't fail the condition couple lines below.
- // This works, as long as we assume that the previous classes were compiled correctly.
- //assert(clazz0.sourceFile != null)
- addDeferredBitmap(clazz0, VAL(sym) === ZERO)
- }
+ addDef(clazz0.pos, VAL(sym) === ZERO)
sym
}
if (sym ne NoSymbol)
sym
- else if (searchParents && !isLocalBitmapField(field))
- bitmapForParents(clazz0, offset, field) getOrElse createBitmap
else
createBitmap
}
- def bitmapForParents(clazz0: Symbol, offset: Int, valSym: Symbol): Option[Symbol] = {
- def requiredBitmaps(fs: Int): Int = if (fs == 0) -1 else (fs - 1) / FLAGS_PER_WORD
- val bitmapNum = offset / FLAGS_PER_WORD
-
- // filter private and transient
- // since we do not inherit normal values (in checkinit mode) also filter them out
- // !!! Not sure how that comment relates to this code...
- superClassesToCheck(clazz0) foreach { cl =>
- val fields0 = usedBits(cl)
-
- if (requiredBitmaps(fields0) < bitmapNum) {
- val fields1 = (cl.info.decls filter isNonLocalFieldWithBitmap).size
- return {
- if (requiredBitmaps(fields0 + fields1) >= bitmapNum)
- Some(bitmapFor(cl, offset, valSym, false))
- else None // Don't waste time, since we won't find bitmap anyway
- }
- }
- }
- None
- }
-
/** Return an (untyped) tree of the form 'Clazz.this.bmp = Clazz.this.bmp | mask'. */
def mkSetFlag(clazz: Symbol, offset: Int, valSym: Symbol): Tree = {
val bmp = bitmapFor(clazz, offset, valSym)
@@ -964,23 +904,12 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
def addInitBits(clazz: Symbol, rhs: Tree): Tree =
new AddInitBitsTransformer(clazz) transform rhs
- def isNonLocalFieldWithBitmap(field: Symbol) =
- isFieldWithBitmap(field) && !isLocalBitmapField(field)
-
def isCheckInitField(field: Symbol) =
needsInitFlag(field) && !field.isDeferred
def superClassesToCheck(clazz: Symbol) =
clazz.ancestors filterNot (_ hasFlag TRAIT | JAVA)
- /**
- * Return the number of bits used by superclass fields.
- */
- def usedBits(clazz0: Symbol): Int =
- superClassesToCheck(clazz0) flatMap (_.info.decls) count { f =>
- f.owner != clazz0 && isNonLocalFieldWithBitmap(f)
- }
-
// begin addNewDefs
/** Fill the map from fields to offset numbers.
@@ -991,22 +920,18 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
def fold(zero: Int, fields: List[Symbol]) = {
var idx = zero
fields foreach { f =>
- idx += 1
fieldOffset(f) = idx
+ idx += 1
}
}
clazz.info.decls.toList groupBy bitmapCategory foreach {
case (nme.NO_NAME, _) => ()
- case (nme.BITMAP_NORMAL, fields) => fold(usedBits(clazz), fields)
case (_, fields) => fold(0, fields)
}
}
buildBitmapOffsets()
var stats1 = addCheckedGetters(clazz, stats)
- // add deferred bitmaps
- deferredBitmaps remove clazz foreach { d => stats1 = add(stats1, d) }
-
def accessedReference(sym: Symbol) = sym.tpe match {
case MethodType(Nil, ConstantType(c)) => Literal(c)
case _ =>
@@ -306,7 +306,6 @@ class DummyMirror(cl: ClassLoader) extends api.Mirror {
val THIS: TermName = DummyName
val BITMAP_NORMAL: TermName = DummyName
val BITMAP_TRANSIENT: TermName = DummyName
- val BITMAP_PRIVATE: TermName = DummyName
val BITMAP_CHECKINIT: TermName = DummyName
val BITMAP_CHECKINIT_TRANSIENT: TermName = DummyName
val INTERPRETER_IMPORT_WRAPPER: String = ""
@@ -73,7 +73,6 @@ trait StandardNames {
val BITMAP_NORMAL: TermName
val BITMAP_TRANSIENT: TermName
- val BITMAP_PRIVATE: TermName
val BITMAP_CHECKINIT: TermName
val BITMAP_CHECKINIT_TRANSIENT: TermName
@@ -9,8 +9,7 @@ private int Test$X.var1
private int Test$X.var2
private int Test$X.var3
private int Test$X.x
-private volatile int Test$X.bitmap$priv$0
-public volatile int Test$X.bitmap$0
+private volatile int Test$X.bitmap$0
private final int Test$Y.z1
private final int Test$Y.z2
private int Test$Y.x

0 comments on commit bdd9abe

Please sign in to comment.