summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/Properties.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala211
-rw-r--r--src/library/scala/Iterable.scala24
-rw-r--r--src/library/scala/IterableProxy.scala4
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