1
1
package scala .async .internal
2
2
3
+ import java .util
4
+
3
5
import scala .collection .immutable .IntMap
4
6
5
7
trait LiveVariables {
@@ -19,19 +21,22 @@ trait LiveVariables {
19
21
def fieldsToNullOut (asyncStates : List [AsyncState ], liftables : List [Tree ]): Map [Int , List [Tree ]] = {
20
22
// live variables analysis:
21
23
// the result map indicates in which states a given field should be nulled out
22
- val liveVarsMap : Map [Tree , Set [ Int ] ] = liveVars(asyncStates, liftables)
24
+ val liveVarsMap : Map [Tree , StateSet ] = liveVars(asyncStates, liftables)
23
25
24
26
var assignsOf = Map [Int , List [Tree ]]()
25
27
26
- for ((fld, where) <- liveVarsMap; state <- where)
27
- assignsOf get state match {
28
- case None =>
29
- assignsOf += (state -> List (fld))
30
- case Some (trees) if ! trees.exists(_.symbol == fld.symbol) =>
31
- assignsOf += (state -> (fld +: trees))
32
- case _ =>
33
- /* do nothing */
28
+ for ((fld, where) <- liveVarsMap) {
29
+ where.foreach { (state : Int ) =>
30
+ assignsOf get state match {
31
+ case None =>
32
+ assignsOf += (state -> List (fld))
33
+ case Some (trees) if ! trees.exists(_.symbol == fld.symbol) =>
34
+ assignsOf += (state -> (fld +: trees))
35
+ case _ =>
36
+ // do nothing
37
+ }
34
38
}
39
+ }
35
40
36
41
assignsOf
37
42
}
@@ -48,7 +53,7 @@ trait LiveVariables {
48
53
* @param liftables the lifted fields
49
54
* @return a map which indicates for a given field (the key) the states in which it should be nulled out
50
55
*/
51
- def liveVars (asyncStates : List [AsyncState ], liftables : List [Tree ]): Map [Tree , Set [ Int ] ] = {
56
+ def liveVars (asyncStates : List [AsyncState ], liftables : List [Tree ]): Map [Tree , StateSet ] = {
52
57
val liftedSyms : Set [Symbol ] = // include only vars
53
58
liftables.iterator.filter {
54
59
case ValDef (mods, _, _, _) => mods.hasFlag(MUTABLE )
@@ -230,53 +235,58 @@ trait LiveVariables {
230
235
}
231
236
}
232
237
233
- def lastUsagesOf (field : Tree , at : AsyncState ): Set [ Int ] = {
238
+ def lastUsagesOf (field : Tree , at : AsyncState ): StateSet = {
234
239
val avoid = scala.collection.mutable.HashSet [AsyncState ]()
235
240
236
- def lastUsagesOf0 (field : Tree , at : AsyncState ): Set [Int ] = {
237
- if (avoid(at)) Set ()
241
+ val result = new StateSet
242
+ def lastUsagesOf0 (field : Tree , at : AsyncState ): Unit = {
243
+ if (avoid(at)) ()
238
244
else if (captured(field.symbol)) {
239
- Set ()
245
+ ()
240
246
}
241
247
else LVentry get at.state match {
242
248
case Some (fields) if fields.contains(field.symbol) =>
243
- Set ( at.state)
249
+ result += at.state
244
250
case _ =>
245
251
avoid += at
246
- val preds = asyncStates.filter(state => contains(state.nextStates, at.state)).toSet
247
- preds.flatMap(p => lastUsagesOf0(field, p))
252
+ for (state <- asyncStates) {
253
+ if (contains(state.nextStates, at.state)) {
254
+ lastUsagesOf0(field, state)
255
+ }
256
+ }
248
257
}
249
258
}
250
259
251
260
lastUsagesOf0(field, at)
261
+ result
252
262
}
253
263
254
- val lastUsages : Map [Tree , Set [ Int ] ] =
255
- liftables.map(fld => fld -> lastUsagesOf(fld, finalState)).toMap
264
+ val lastUsages : Map [Tree , StateSet ] =
265
+ liftables.iterator. map(fld => fld -> lastUsagesOf(fld, finalState)).toMap
256
266
257
267
if (AsyncUtils .verbose) {
258
268
for ((fld, lastStates) <- lastUsages)
259
- AsyncUtils .vprintln(s " field ${fld.symbol.name} is last used in states ${lastStates.mkString(" , " )}" )
269
+ AsyncUtils .vprintln(s " field ${fld.symbol.name} is last used in states ${lastStates.iterator. mkString(" , " )}" )
260
270
}
261
271
262
- val nullOutAt : Map [Tree , Set [ Int ] ] =
272
+ val nullOutAt : Map [Tree , StateSet ] =
263
273
for ((fld, lastStates) <- lastUsages) yield {
264
- val killAt = lastStates.flatMap { s =>
265
- if ( s == finalState.state) Set ()
266
- else {
274
+ var result = new StateSet
275
+ lastStates.foreach { s =>
276
+ if (s != finalState.state) {
267
277
val lastAsyncState = asyncStates.find(_.state == s).get
268
278
val succNums = lastAsyncState.nextStates
269
279
// all successor states that are not indirect predecessors
270
280
// filter out successor states where the field is live at the entry
271
- succNums.iterator. filter(num => ! isPred(num, s)).filterNot (num => LVentry (num).contains(fld.symbol))
281
+ util. Arrays .stream(succNums). filter(num => ! isPred(num, s)).filter (num => ! LVentry (num).contains(fld.symbol)).forEach(result += _ )
272
282
}
273
283
}
274
- (fld, killAt )
284
+ (fld, result )
275
285
}
276
286
277
287
if (AsyncUtils .verbose) {
278
288
for ((fld, killAt) <- nullOutAt)
279
- AsyncUtils .vprintln(s " field ${fld.symbol.name} should be nulled out in states ${killAt.mkString(" , " )}" )
289
+ AsyncUtils .vprintln(s " field ${fld.symbol.name} should be nulled out in states ${killAt.iterator. mkString(" , " )}" )
280
290
}
281
291
282
292
nullOutAt
0 commit comments