summaryrefslogtreecommitdiff
path: root/examples/scala-js/tools/shared/src/main/scala/scala/scalajs/tools/optimizer/IncOptimizer.scala
diff options
context:
space:
mode:
Diffstat (limited to 'examples/scala-js/tools/shared/src/main/scala/scala/scalajs/tools/optimizer/IncOptimizer.scala')
-rw-r--r--examples/scala-js/tools/shared/src/main/scala/scala/scalajs/tools/optimizer/IncOptimizer.scala158
1 files changed, 158 insertions, 0 deletions
diff --git a/examples/scala-js/tools/shared/src/main/scala/scala/scalajs/tools/optimizer/IncOptimizer.scala b/examples/scala-js/tools/shared/src/main/scala/scala/scalajs/tools/optimizer/IncOptimizer.scala
new file mode 100644
index 0000000..d115618
--- /dev/null
+++ b/examples/scala-js/tools/shared/src/main/scala/scala/scalajs/tools/optimizer/IncOptimizer.scala
@@ -0,0 +1,158 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js tools **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013-2014, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.tools.optimizer
+
+import scala.collection.{GenTraversableOnce, GenIterable}
+import scala.collection.mutable
+
+import scala.scalajs.tools.sem.Semantics
+
+class IncOptimizer(semantics: Semantics) extends GenIncOptimizer(semantics) {
+
+ protected object CollOps extends GenIncOptimizer.AbsCollOps {
+ type Map[K, V] = mutable.Map[K, V]
+ type ParMap[K, V] = mutable.Map[K, V]
+ type AccMap[K, V] = mutable.Map[K, mutable.ListBuffer[V]]
+ type ParIterable[V] = mutable.ListBuffer[V]
+ type Addable[V] = mutable.ListBuffer[V]
+
+ def emptyAccMap[K, V]: AccMap[K, V] = mutable.Map.empty
+ def emptyMap[K, V]: Map[K, V] = mutable.Map.empty
+ def emptyParMap[K, V]: ParMap[K, V] = mutable.Map.empty
+ def emptyParIterable[V]: ParIterable[V] = mutable.ListBuffer.empty
+
+ // Operations on ParMap
+ def put[K, V](map: ParMap[K, V], k: K, v: V): Unit = map.put(k, v)
+ def remove[K, V](map: ParMap[K, V], k: K): Option[V] = map.remove(k)
+
+ def retain[K, V](map: ParMap[K, V])(p: (K, V) => Boolean): Unit =
+ map.retain(p)
+
+ // Operations on AccMap
+ def acc[K, V](map: AccMap[K, V], k: K, v: V): Unit =
+ map.getOrElseUpdate(k, mutable.ListBuffer.empty) += v
+
+ def getAcc[K, V](map: AccMap[K, V], k: K): GenIterable[V] =
+ map.getOrElse(k, Nil)
+
+ def parFlatMapKeys[A, B](map: AccMap[A, _])(
+ f: A => GenTraversableOnce[B]): GenIterable[B] =
+ map.keys.flatMap(f).toList
+
+ // Operations on ParIterable
+ def prepAdd[V](it: ParIterable[V]): Addable[V] = it
+ def add[V](addable: Addable[V], v: V): Unit = addable += v
+ def finishAdd[V](addable: Addable[V]): ParIterable[V] = addable
+ }
+
+ private val _interfaces = mutable.Map.empty[String, InterfaceType]
+ protected def getInterface(encodedName: String): InterfaceType =
+ _interfaces.getOrElseUpdate(encodedName, new SeqInterfaceType(encodedName))
+
+ private val methodsToProcess = mutable.ListBuffer.empty[MethodImpl]
+ protected def scheduleMethod(method: MethodImpl): Unit =
+ methodsToProcess += method
+
+ protected def newMethodImpl(owner: MethodContainer,
+ encodedName: String): MethodImpl = new SeqMethodImpl(owner, encodedName)
+
+ protected def processAllTaggedMethods(): Unit = {
+ logProcessingMethods(methodsToProcess.count(!_.deleted))
+ for (method <- methodsToProcess)
+ method.process()
+ methodsToProcess.clear()
+ }
+
+ private class SeqInterfaceType(encName: String) extends InterfaceType(encName) {
+ private val ancestorsAskers = mutable.Set.empty[MethodImpl]
+ private val dynamicCallers = mutable.Map.empty[String, mutable.Set[MethodImpl]]
+ private val staticCallers = mutable.Map.empty[String, mutable.Set[MethodImpl]]
+
+ private var _ancestors: List[String] = encodedName :: Nil
+
+ private var _instantiatedSubclasses: Set[Class] = Set.empty
+
+ def instantiatedSubclasses: Iterable[Class] = _instantiatedSubclasses
+
+ def addInstantiatedSubclass(x: Class): Unit =
+ _instantiatedSubclasses += x
+
+ def removeInstantiatedSubclass(x: Class): Unit =
+ _instantiatedSubclasses -= x
+
+ def ancestors: List[String] = _ancestors
+
+ def ancestors_=(v: List[String]): Unit = {
+ if (v != _ancestors) {
+ _ancestors = v
+ ancestorsAskers.foreach(_.tag())
+ ancestorsAskers.clear()
+ }
+ }
+
+ def registerAskAncestors(asker: MethodImpl): Unit =
+ ancestorsAskers += asker
+
+ def registerDynamicCaller(methodName: String, caller: MethodImpl): Unit =
+ dynamicCallers.getOrElseUpdate(methodName, mutable.Set.empty) += caller
+
+ def registerStaticCaller(methodName: String, caller: MethodImpl): Unit =
+ staticCallers.getOrElseUpdate(methodName, mutable.Set.empty) += caller
+
+ def unregisterDependee(dependee: MethodImpl): Unit = {
+ ancestorsAskers -= dependee
+ dynamicCallers.values.foreach(_ -= dependee)
+ staticCallers.values.foreach(_ -= dependee)
+ }
+
+ def tagDynamicCallersOf(methodName: String): Unit =
+ dynamicCallers.remove(methodName).foreach(_.foreach(_.tag()))
+
+ def tagStaticCallersOf(methodName: String): Unit =
+ staticCallers.remove(methodName).foreach(_.foreach(_.tag()))
+ }
+
+ private class SeqMethodImpl(owner: MethodContainer,
+ encodedName: String) extends MethodImpl(owner, encodedName) {
+
+ private val bodyAskers = mutable.Set.empty[MethodImpl]
+
+ def registerBodyAsker(asker: MethodImpl): Unit =
+ bodyAskers += asker
+
+ def unregisterDependee(dependee: MethodImpl): Unit =
+ bodyAskers -= dependee
+
+ def tagBodyAskers(): Unit = {
+ bodyAskers.foreach(_.tag())
+ bodyAskers.clear()
+ }
+
+ private var _registeredTo: List[Unregisterable] = Nil
+ private var tagged = false
+
+ protected def registeredTo(intf: Unregisterable): Unit =
+ _registeredTo ::= intf
+
+ protected def unregisterFromEverywhere(): Unit = {
+ _registeredTo.foreach(_.unregisterDependee(this))
+ _registeredTo = Nil
+ }
+
+ protected def protectTag(): Boolean = {
+ val res = !tagged
+ tagged = true
+ res
+ }
+ protected def resetTag(): Unit = tagged = false
+
+ }
+
+}