1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
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
}
}
|