diff options
author | michelou <michelou@epfl.ch> | 2007-02-05 13:07:41 +0000 |
---|---|---|
committer | michelou <michelou@epfl.ch> | 2007-02-05 13:07:41 +0000 |
commit | 611f4541686a87ba6d871a95951d476a288816a4 (patch) | |
tree | 922347a5fc11ecd340370b40b480a7601980dcf4 /src | |
parent | 50ce776c18e2fb715b78be3c9d1d4dbbd07fba62 (diff) | |
download | scala-611f4541686a87ba6d871a95951d476a288816a4.tar.gz scala-611f4541686a87ba6d871a95951d476a288816a4.tar.bz2 scala-611f4541686a87ba6d871a95951d476a288816a4.zip |
fixed compilation error in CopyPropagation.scala
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/Properties.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala | 211 | ||||
-rw-r--r-- | src/library/scala/Iterable.scala | 24 | ||||
-rw-r--r-- | src/library/scala/IterableProxy.scala | 4 |
4 files changed, 129 insertions, 112 deletions
diff --git a/src/compiler/scala/tools/nsc/Properties.scala b/src/compiler/scala/tools/nsc/Properties.scala index ea13f14a81..9d7fb0fa33 100644 --- a/src/compiler/scala/tools/nsc/Properties.scala +++ b/src/compiler/scala/tools/nsc/Properties.scala @@ -3,7 +3,7 @@ * @author Stephane Micheloud */ -// $Id: $ +// $Id$ package scala.tools.nsc diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala index ec39086663..7d6bb09ba3 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala @@ -1,5 +1,5 @@ /* NSC -- new Scala compiler - * Copyright 2005-2006 LAMP/EPFL + * Copyright 2005-2007 LAMP/EPFL * @author Martin Odersky */ @@ -9,6 +9,7 @@ package scala.tools.nsc.backend.icode.analysis import scala.collection.mutable.{Map, HashMap} import scala.tools.nsc.symtab.Flags.DEFERRED + /** * A modified copy-propagation like analysis. It * is augmented with a record-like value which is used @@ -21,32 +22,32 @@ abstract class CopyPropagation { /** Locations can be local variables. */ abstract sealed class Location; - case class LocalVar(l: Local) extends Location; - case class Field(r: Record, sym: Symbol) extends Location; + case class LocalVar(l: Local) extends Location + case class Field(r: Record, sym: Symbol) extends Location /** Values that can be on the stack. */ abstract class Value { - def isRecord = false; + def isRecord = false } - case class This extends Value; + case class This extends Value case class Record(cls: Symbol, bindings: Map[Symbol, Value]) extends Value { - override def isRecord = true; + override def isRecord = true } case class Deref(l: Location) extends Value; - case object Unknown extends Value; - object AllRecords extends Record(NoSymbol, new HashMap[Symbol, Value]); + case object Unknown extends Value + object AllRecords extends Record(NoSymbol, new HashMap[Symbol, Value]) /** The lattice for this analysis. */ object copyLattice extends CompleteLattice { - type Bindings = Map[Location, Value]; + type Bindings = Map[Location, Value] - def emptyBinding = new HashMap[Location, Value](); + def emptyBinding = new HashMap[Location, Value]() class State(val bindings: Bindings, var stack: List[Value]) { override def equals(that: Any): Boolean = (this eq that.asInstanceOf[AnyRef]) || that.isInstanceOf[State] && { - val other = that.asInstanceOf[State]; + val other = that.asInstanceOf[State] /* comparison with bottom is reference equality! */ if ((other eq bottom) || (this eq bottom)) @@ -59,13 +60,13 @@ abstract class CopyPropagation { /* Return the binding for the given local (another local) */ def getAlias(l: Local): Local = { - var target = l; - var stop = false; + var target = l + var stop = false while (bindings.isDefinedAt(LocalVar(target)) && !stop) { bindings(LocalVar(target)) match { - case Deref(LocalVar(t)) => target = t; - case _ => stop = true; + case Deref(LocalVar(t)) => target = t + case _ => stop = true } } target @@ -73,16 +74,16 @@ abstract class CopyPropagation { /* Return the binding for the given local. */ def getBinding(l: Local): Value = { - var target = l; - var stop = false; - var value: Value = Deref(LocalVar(target)); + var target = l + var stop = false + var value: Value = Deref(LocalVar(target)) while (bindings.isDefinedAt(LocalVar(target)) && !stop) { -// Console.println("finding binding for " + target); - value = bindings(LocalVar(target)); +// Console.println("finding binding for " + target) + value = bindings(LocalVar(target)) value match { - case Deref(LocalVar(t)) => target = t; - case _ => stop = true; + case Deref(LocalVar(t)) => target = t + case _ => stop = true } } value @@ -107,7 +108,7 @@ abstract class CopyPropagation { assert(r.bindings.isDefinedAt(f), "Record " + r + " does not contain a field " + f); - var target: Value = r.bindings(f); + var target: Value = r.bindings(f) target match { case Deref(LocalVar(l)) => Some(Deref(LocalVar(getAlias(l)))) case This() => Some(target) @@ -115,21 +116,20 @@ abstract class CopyPropagation { } } - override def toString(): String = { + override def toString(): String = "\nBindings: " + bindings + "\nStack: " + stack; - } def dup: State = { - val b: Bindings = new HashMap(); - b ++= bindings; + val b: Bindings = new HashMap() + b ++= bindings new State(b, stack) } } - type Elem = State; + type Elem = State - val top = new State(emptyBinding, Nil); - val bottom = new State(emptyBinding, Nil); + val top = new State(emptyBinding, Nil) + val bottom = new State(emptyBinding, Nil) def lub2(a: Elem, b: Elem): Elem = { if (a eq bottom) b @@ -141,8 +141,8 @@ abstract class CopyPropagation { val resStack = List.map2(a.stack, b.stack) { (v1, v2) => if (v1 == v2) v1 else Unknown } - val commonPairs = a.bindings.toList intersect (b.bindings.toList); - val resBindings = new HashMap[Location, Value]; + val commonPairs = a.bindings.toList intersect (b.bindings.toList) + val resBindings = new HashMap[Location, Value] for (val Pair(k, v) <- commonPairs) resBindings += k -> v; new State(resBindings, resStack) @@ -151,20 +151,20 @@ abstract class CopyPropagation { } final class CopyAnalysis extends DataFlowAnalysis[copyLattice.type] { - type P = BasicBlock; - val lattice = copyLattice; + type P = BasicBlock + val lattice = copyLattice - var method: IMethod = _; + var method: IMethod = _ def init(m: IMethod): Unit = { - this.method = m; + this.method = m init { - worklist += m.code.startBlock; - worklist ++= (m.exh map (.startBlock)); + worklist += m.code.startBlock + worklist ++= (m.exh map (.startBlock)) m.code.blocks.foreach { b => - in(b) = lattice.bottom; - out(b) = lattice.bottom; + in(b) = lattice.bottom + out(b) = lattice.bottom } m.exh foreach { e => in(e.startBlock) = new copyLattice.State(copyLattice.emptyBinding, Unknown :: Nil); @@ -176,7 +176,7 @@ abstract class CopyPropagation { } override def run: Unit = { - forwardAnalysis(blockTransfer); + forwardAnalysis(blockTransfer) if (settings.debug.value) { linearizer.linearize(method).foreach(b => if (b != method.code.startBlock) assert(in(b) != lattice.bottom, @@ -184,35 +184,34 @@ abstract class CopyPropagation { } } - def blockTransfer(b: BasicBlock, in: lattice.Elem): lattice.Elem = { + def blockTransfer(b: BasicBlock, in: lattice.Elem): lattice.Elem = b.toList.foldLeft(in)(interpret) - } - import opcodes._; + import opcodes._ /** Abstract interpretation for one instruction. */ def interpret(in: copyLattice.Elem, i: Instruction): copyLattice.Elem = { - var out = in.dup; + var out = in.dup if (settings.debug.value) { - log("- " + i); - log("in: " + in); - log("\n"); + log("- " + i) + log("in: " + in) + log("\n") } i match { case THIS(_) => - out.stack = This :: out.stack; + out.stack = This :: out.stack case CONSTANT(k) => - if (k.tag != UnitTag) - out.stack = Unknown :: out.stack; + if (k.tag != UnitTag) + out.stack = Unknown :: out.stack; case LOAD_ARRAY_ITEM(_) => - out.stack = (Unknown :: out.stack.drop(2)); + out.stack = (Unknown :: out.stack.drop(2)) case LOAD_LOCAL(local) => - out.stack = Deref(LocalVar(local)) :: out.stack; + out.stack = Deref(LocalVar(local)) :: out.stack case LOAD_FIELD(field, isStatic) => if (isStatic) @@ -224,19 +223,19 @@ abstract class CopyPropagation { case _ => Unknown } - out.stack = v1 :: out.stack.drop(1); + out.stack = v1 :: out.stack.drop(1) } case LOAD_MODULE(module) => - out.stack = Unknown :: out.stack; + out.stack = Unknown :: out.stack case STORE_ARRAY_ITEM(kind) => - out.stack = out.stack.drop(3); + out.stack = out.stack.drop(3) case STORE_LOCAL(local) => - cleanReferencesTo(out, LocalVar(local)); + cleanReferencesTo(out, LocalVar(local)) in.stack match { - case Unknown :: xs => (); + case Unknown :: xs => () case v :: vs => v match { case Deref(LocalVar(other)) => @@ -263,15 +262,15 @@ abstract class CopyPropagation { } case CALL_PRIMITIVE(primitive) => - out.stack = Unknown :: out.stack.drop(i.consumed); + out.stack = Unknown :: out.stack.drop(i.consumed) case CALL_METHOD(method, style) => style match { case Dynamic => - out = simulateCall(in, method, false); + out = simulateCall(in, method, false) case Static(onInstance) => if (onInstance) { - val obj = out.stack.drop(method.info.paramTypes.length).head; + val obj = out.stack.drop(method.info.paramTypes.length).head if (method.isConstructor) { obj match { case Record(_, bindings) => @@ -282,14 +281,14 @@ abstract class CopyPropagation { case _ => () } // put the Record back on the stack and remove the 'returned' value - out.stack = out.stack.drop(1 + method.info.paramTypes.length); + out.stack = out.stack.drop(1 + method.info.paramTypes.length) } else - out = simulateCall(in, method, false); + out = simulateCall(in, method, false) } else - out = simulateCall(in, method, true); + out = simulateCall(in, method, true) case SuperCall(_) => - out = simulateCall(in, method, false); + out = simulateCall(in, method, false) } case BOX(tpe) => @@ -312,48 +311,48 @@ abstract class CopyPropagation { out.stack = v1 :: out.stack case CREATE_ARRAY(elem) => - out.stack = Unknown :: out.stack.drop(1); + out.stack = Unknown :: out.stack.drop(1) case IS_INSTANCE(tpe) => - out.stack = Unknown :: out.stack.drop(1); + out.stack = Unknown :: out.stack.drop(1) case CHECK_CAST(tpe) => - out.stack = Unknown :: out.stack.drop(1); + out.stack = Unknown :: out.stack.drop(1) case SWITCH(tags, labels) => - out.stack = out.stack.drop(1); + out.stack = out.stack.drop(1) case JUMP(where) => () case CJUMP(success, failure, cond, kind) => - out.stack = out.stack.drop(2); + out.stack = out.stack.drop(2) case CZJUMP(success, failure, cond, kind) => - out.stack = out.stack.drop(1); + out.stack = out.stack.drop(1) case RETURN(kind) => if (kind != UNIT) - out.stack = out.stack.drop(1); + out.stack = out.stack.drop(1) case THROW() => - out.stack = out.stack.drop(1); + out.stack = out.stack.drop(1) case DROP(kind) => - out.stack = out.stack.drop(1); + out.stack = out.stack.drop(1) case DUP(kind) => - out.stack = out.stack.head :: out.stack; + out.stack = out.stack.head :: out.stack case MONITOR_ENTER() => out.stack = out.stack.drop(1); case MONITOR_EXIT() => - out.stack = out.stack.drop(1); + out.stack = out.stack.drop(1) case _ => - dump; - abort("Unknown instruction: " + i); + dump + abort("Unknown instruction: " + i) } out } /* def interpret */ @@ -364,7 +363,7 @@ abstract class CopyPropagation { */ final def cleanReferencesTo(s: copyLattice.State, target: Location): Unit = { def cleanRecord(r: Record): Record = { - r.bindings retain { case Pair(loc, value) => + r.bindings retain { (loc, value) => value match { case Deref(loc1) if (loc1 == target) => false case _ => true @@ -379,7 +378,7 @@ abstract class CopyPropagation { case _ => v }} - s.bindings retain { case Pair(loc, value) => + s.bindings retain { (loc, value) => (value match { case Deref(loc1) if (loc1 == target) => false case Record(_, _) => @@ -394,11 +393,17 @@ abstract class CopyPropagation { } } - /** Update the state 's' after the call to 'method'. The stack elements are dropped and replaced - * by the result of the call. If the method is impure, all bindings to record fields are cleared. + /** Update the state <code>s</code> after the call to <code>method</code>. + * The stack elements are dropped and replaced by the result of the call. + * If the method is impure, all bindings to record fields are cleared. + * + * @param state ... + * @param method ... + * @param static ... + * @return ... */ - final def simulateCall(s: copyLattice.State, method: Symbol, static: Boolean): copyLattice.State = { - val out = new copyLattice.State(s.bindings, s.stack); + final def simulateCall(state: copyLattice.State, method: Symbol, static: Boolean): copyLattice.State = { + val out = new copyLattice.State(state.bindings, state.stack); out.stack = out.stack.drop(method.info.paramTypes.length + (if (static) 0 else 1)); if (method.info.resultType != definitions.UnitClass.tpe) out.stack = Unknown :: out.stack; @@ -407,15 +412,18 @@ abstract class CopyPropagation { out } - /** Drop everything known about record fields. */ - final def invalidateRecords(s: copyLattice.State): Unit = { - s.stack = s.stack map { v => v match { + /** Drop everything known about record fields. + * + * @param state ... + */ + final def invalidateRecords(state: copyLattice.State): Unit = { + state.stack = state.stack map { v => v match { case Record(cls, bindings) => - Record(cls, new HashMap[Symbol, Value]); + Record(cls, new HashMap[Symbol, Value]) case _ => v }} - s.bindings retain { case Pair(loc, value) => + state.bindings retain {(loc, value) => value match { case Deref(Field(_, _)) => false case _ => true @@ -423,10 +431,13 @@ abstract class CopyPropagation { } } - /** - * Return bindings from closure's fields to the values on the stack. This - * method has to find the correct mapping from fields to the order in which - * they are passed on the stack. + /** Return bindings from closure's fields to the values on the stack. This + * method has to find the correct mapping from fields to the order in which + * they are passed on the stack. + * + * @param in ... + * @param ctor ... + * @return ... */ private def getBindingsForClosure(in: copyLattice.State, ctor: Symbol): Map[Symbol, Value] = { val paramAccessors = ctor.owner.constrParamAccessors; @@ -443,7 +454,11 @@ abstract class CopyPropagation { bindings } - /** Is `cls' a closure class? */ + /** Is <code>cls</code> a closure class? + * + * @param cls ... + * @return ... + */ final def isClosureClass(cls: Symbol): Boolean = cls.isFinal && cls.tpe.parents.exists { t => @@ -451,7 +466,11 @@ abstract class CopyPropagation { definitions.FunctionClass exists sym.== } - /** Is `m' a pure method? */ + /** Is symbol <code>m</code> a pure method? + * + * @param m ... + * @return ... + */ final def isPureMethod(m: Symbol): Boolean = // MO: I added !m.hasFlag(DEFERRED) in a refactoring where // getters now can be abstract whereas before they could not. @@ -460,7 +479,7 @@ abstract class CopyPropagation { m.isGetter && !m.hasFlag(DEFERRED); final override def toString(): String = { - var res = ""; + var res = "" for (val b <- this.method.code.blocks.toList) res = (res + "\nIN(" + b.label + "):\t Bindings: " + in(b).bindings + "\nIN(" + b.label +"):\t Stack: " + in(b).stack) + "\n"; diff --git a/src/library/scala/Iterable.scala b/src/library/scala/Iterable.scala index 6ef8e2ec06..916b0ecdf4 100644 --- a/src/library/scala/Iterable.scala +++ b/src/library/scala/Iterable.scala @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** @@ -88,19 +88,15 @@ trait Iterable[+A] { */ def elements: Iterator[A] - /** Appends two iterable objects + /** Appends two iterable objects. * * @return the new iterable object * @deprecated use <code>++</code> instead */ - [deprecated] def concat [B >: A](that: Iterable[B]): Iterable[B] = { - val buf = new ArrayBuffer[B] - this copyToBuffer buf - that copyToBuffer buf - buf - } + [deprecated] def concat[B >: A](that: Iterable[B]): Iterable[B] = + this ++ that - /** Appends two iterable objects + /** Appends two iterable objects. * * @return the new iterable object */ @@ -111,11 +107,12 @@ trait Iterable[+A] { buf } - /** Returns the iterable resulting from applying the given function <code>f</code> to each - * element of this iterable. + /** Returns the iterable resulting from applying the given function + * <code>f</code> to each element of this iterable. * * @param f function to apply to each element. - * @return <code>f(a0), ..., f(an)</code> if this iterable is <code>a0, ..., an</code>. + * @return <code>f(a<sub>0</sub>), ..., f(a<sub>n</sub>)</code> + * if this iterable is <code>a<sub>0</sub>, ..., an</code>. */ def map[B](f: A => B): Iterable[B] = { val buf = new ArrayBuffer[B] @@ -182,7 +179,8 @@ trait Iterable[+A] { new ArrayBuffer[A] ++ elements.take(n) /** Returns this iterable without its <code>n</code> first elements - * If this iterable has less than <code>n</code> elements, the empty iterable is returned. + * If this iterable has less than <code>n</code> elements, the empty + * iterable is returned. * * @param n the number of elements to drop * @return the new iterable diff --git a/src/library/scala/IterableProxy.scala b/src/library/scala/IterableProxy.scala index 642b352694..a69fc91dd4 100644 --- a/src/library/scala/IterableProxy.scala +++ b/src/library/scala/IterableProxy.scala @@ -1,6 +1,6 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL ** +** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** @@ -11,7 +11,7 @@ package scala -import collection.mutable.Buffer +import scala.collection.mutable.Buffer import scala.compat.StringBuilder |