diff options
author | Paul Phillips <paulp@improving.org> | 2012-01-10 07:10:05 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-01-11 16:21:38 -0800 |
commit | 5f5029d2ac6348ecb07fc11f6656621c662ced92 (patch) | |
tree | 59f3946d2c5e2612cd2c36ca008c016b0c69b0d5 /src/compiler/scala/tools/nsc/transform | |
parent | b00002f9049c034510438881b4a4449d73fe2f54 (diff) | |
download | scala-5f5029d2ac6348ecb07fc11f6656621c662ced92.tar.gz scala-5f5029d2ac6348ecb07fc11f6656621c662ced92.tar.bz2 scala-5f5029d2ac6348ecb07fc11f6656621c662ced92.zip |
Optimizing TypeRef, starting with Symbols.
There are too many potential optimizations unavailable to us due to the
lack of bright lines among different kinds of symbols. For instance the
difference between a TypeSymbol which represents a type alias and one
which represents an abstract type is only whether the DEFERRED flag
is set. This creates issues.
1) There are many (many) places where tests are performed on every symbol
which could be done more efficiently and (especially) more verifiably
correctly with polymorphism.
2) TypeRefs based on those symbols are also checking that flag
constantly, in perpetuity. A symbol created as an alias is never (to the
best of my knowledge) going to intentionally morph into one representing
an abstract type, nor vice versa.
3) One has no guarantees, because anyone can set or reset the DEFERRED
flag at any time.
So tackling more than one problem at once herein:
1) I created canonical symbol creation points which take the flags as
an argument, so that there can be a difference between initializing a
symbol's flags and setting/resetting them at arbitrary times.
2) I structured all the symbol creators to take arguments in the
same order, which is:
def newXXX(name: Name, ..., pos: Position = NoPosition, flags: Long = 0L)
(Where "..." is for those symbols which require something
beyond the name to create, such as a TypeSkolem's origin.)
The name is first because it's the only always required argument.
I left but deprecated the variations which take (pos, name).
3) I created subclasses of TypeRef based on the information which
should be stable from creation time onward:
- args or no args?
- abstract type, type alias, or class?
2x3 == 6 and that's how many subclasses of TypeRef there are now. So
now, for example, every TypeRef doesn't have to carry null symInfoCache
and thisInfoCache fields for the benefit of the minority which use them.
I still intend to realize the gain possible once we can evade the fields
for pre and args without losing pattern matcher efficiency.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform')
7 files changed, 26 insertions, 26 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 034628e95f..0bc137f3e8 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -143,13 +143,13 @@ abstract class CleanUp extends Transform with ast.TreeDSL { /* ### CREATING THE METHOD CACHE ### */ def addStaticVariableToClass(forName: TermName, forType: Type, forInit: Tree, isFinal: Boolean): Symbol = { - val varSym = ( - currentClass.newVariable(ad.pos, mkTerm("" + forName)) - setFlag PRIVATE | STATIC | SYNTHETIC - setInfo forType + val flags = PRIVATE | STATIC | SYNTHETIC | ( + if (isFinal) FINAL else 0 ) - if (isFinal) varSym setFlag FINAL - else varSym.addAnnotation(VolatileAttr) + + val varSym = currentClass.newVariable(mkTerm("" + forName), ad.pos, flags) setInfo forType + if (!isFinal) + varSym.addAnnotation(VolatileAttr) currentClass.info.decls enter varSym val varDef = typedPos( VAL(varSym) === forInit ) @@ -280,7 +280,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { addStaticMethodToClass(nme.reflMethodName, List(ClassClass.tpe), MethodClass.tpe) { case Pair(reflMethodSym, List(forReceiverSym)) => - val methodSym = reflMethodSym.newVariable(ad.pos, mkTerm("method")) setInfo MethodClass.tpe + val methodSym = reflMethodSym.newVariable(mkTerm("method"), ad.pos) setInfo MethodClass.tpe BLOCK( IF (getPolyCache OBJ_EQ NULL) THEN (safeREF(reflPolyCacheSym) === mkNewPolyCache) ENDIF, @@ -565,7 +565,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { case theTry @ Try(block, catches, finalizer) if theTry.tpe.typeSymbol != definitions.UnitClass && theTry.tpe.typeSymbol != definitions.NothingClass => val tpe = theTry.tpe.widen - val tempVar = currentOwner.newVariable(theTry.pos, mkTerm(nme.EXCEPTION_RESULT_PREFIX)).setInfo(tpe) + val tempVar = currentOwner.newVariable(mkTerm(nme.EXCEPTION_RESULT_PREFIX), theTry.pos).setInfo(tpe) def assignBlock(rhs: Tree) = super.transform(BLOCK(Ident(tempVar) === transform(rhs))) val newBlock = assignBlock(block) @@ -637,8 +637,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { // create a symbol for the static field val stfieldSym = ( - currentClass.newVariable(pos, mkTerm("symbol$")) - setFlag PRIVATE | STATIC | SYNTHETIC | FINAL + currentClass.newVariable(mkTerm("symbol$"), pos, PRIVATE | STATIC | SYNTHETIC | FINAL) setInfo SymbolClass.tpe ) currentClass.info.decls enter stfieldSym diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index cf7d6c94fe..701fda1035 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -136,7 +136,7 @@ abstract class ExplicitOuter extends InfoTransform } if (sym.owner.isTrait) sym setNotFlag PROTECTED // 6 if (sym.isClassConstructor && isInner(sym.owner)) { // 1 - val p = sym.newValueParameter(sym.pos, innerClassConstructorParamName) + val p = sym.newValueParameter(innerClassConstructorParamName, sym.pos) .setInfo(sym.owner.outerClass.thisType) MethodType(p :: params, restpe) } else if (restpe ne restpe1) @@ -475,7 +475,7 @@ abstract class ExplicitOuter extends InfoTransform val vparamss1 = if (isInner(clazz)) { // (4) val outerParam = - sym.newValueParameter(sym.pos, nme.OUTER) setInfo outerField(clazz).info + sym.newValueParameter(nme.OUTER, sym.pos) setInfo outerField(clazz).info ((ValDef(outerParam) setType NoType) :: vparamss.head) :: vparamss.tail } else vparamss super.transform(treeCopy.DefDef(tree, mods, name, tparams, vparamss1, tpt, rhs)) diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala index 5452087aa3..f8c5f5bfc6 100644 --- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala +++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala @@ -246,7 +246,7 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD if (bmps.length > n) bmps(n) else { - val sym = meth.newVariable(meth.pos, nme.newBitmapName(nme.BITMAP_NORMAL, n)).setInfo(IntClass.tpe) + val sym = meth.newVariable(nme.newBitmapName(nme.BITMAP_NORMAL, n), meth.pos).setInfo(IntClass.tpe) atPhase(currentRun.typerPhase) { sym addAnnotation VolatileAttr } diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index c7d3b331a6..d011c15494 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -396,9 +396,12 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { if (sourceModule != NoSymbol) { sourceModule setPos sym.pos sourceModule.flags = MODULE | FINAL - } else { - sourceModule = clazz.owner.newModule( - sym.pos, sym.name.toTermName, sym.asInstanceOf[ClassSymbol]) + } + else { + sourceModule = ( + clazz.owner.newModuleSymbol(sym.name.toTermName, sym.pos, MODULE | FINAL) + setModuleClass sym.asInstanceOf[ClassSymbol] + ) clazz.owner.info.decls enter sourceModule } sourceModule setInfo sym.tpe @@ -742,7 +745,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { assert(!sym.isOverloaded, sym) def createBitmap: Symbol = { - val sym = clazz0.newVariable(clazz0.pos, bitmapName) setInfo IntClass.tpe + val sym = clazz0.newVariable(bitmapName, clazz0.pos) setInfo IntClass.tpe atPhase(currentRun.typerPhase)(sym addAnnotation VolatileAttr) category match { diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 99b0a82690..5d13f80897 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -407,7 +407,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { */ private def typeParamSubAnyRef(sym: Symbol, cls: Symbol) = ( anyrefSpecCache.getOrElseUpdate(sym, - cls.newTypeParameter(sym.pos, sym.name append nme.SPECIALIZED_SUFFIX_NAME toTypeName) + cls.newTypeParameter(sym.name append nme.SPECIALIZED_SUFFIX_NAME toTypeName, sym.pos) setInfo TypeBounds(sym.info.bounds.lo, AnyRefClass.tpe) ).tpe ) diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala index e2cd0a8402..da767b6bce 100644 --- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala +++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala @@ -128,7 +128,7 @@ abstract class TailCalls extends Transform { * the label field. */ this.label = { - val label = method.newLabel(method.pos, newTermName("_" + method.name)) + val label = method.newLabel(newTermName("_" + method.name), method.pos) val thisParam = method.newSyntheticValueParam(currentClass.typeOfThis) label setInfo MethodType(thisParam :: method.tpe.params, method.tpe.finalResultType) } diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index adb408f7e4..4ae4042cc7 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -133,11 +133,9 @@ abstract class UnCurry extends InfoTransform /** Return non-local return key for given method */ private def nonLocalReturnKey(meth: Symbol) = - nonLocalReturnKeys.getOrElseUpdate(meth, { - meth.newValue(meth.pos, unit.freshTermName("nonLocalReturnKey")) - .setFlag (SYNTHETIC) - .setInfo (ObjectClass.tpe) - }) + nonLocalReturnKeys.getOrElseUpdate(meth, + meth.newValue(unit.freshTermName("nonLocalReturnKey"), meth.pos, SYNTHETIC) setInfo ObjectClass.tpe + ) /** Generate a non-local return throw with given return expression from given method. * I.e. for the method's non-local return key, generate: @@ -255,7 +253,7 @@ abstract class UnCurry extends InfoTransform if (fun1 ne fun) fun1 else { val (formals, restpe) = (targs.init, targs.last) - val anonClass = owner newAnonymousFunctionClass fun.pos setFlag (FINAL | SYNTHETIC | inConstructorFlag) + val anonClass = owner.newAnonymousFunctionClass(fun.pos, inConstructorFlag) def parents = if (isFunctionType(fun.tpe)) List(abstractFunctionForFunctionType(fun.tpe), SerializableClass.tpe) else if (isPartial) List(appliedType(AbstractPartialFunctionClass.typeConstructor, targs), SerializableClass.tpe) @@ -772,7 +770,7 @@ abstract class UnCurry extends InfoTransform } val forwresult = dd.symbol.tpe.finalResultType val forwformsyms = map2(forwformals, flatparams)((tp, oldparam) => - currentClass.newValueParameter(oldparam.symbol.pos, oldparam.name).setInfo(tp) + currentClass.newValueParameter(oldparam.name, oldparam.symbol.pos).setInfo(tp) ) def mono = MethodType(forwformsyms, forwresult) val forwtype = dd.symbol.tpe match { |