@@ -36,12 +36,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
36
36
37
37
protected def nextId () = { ids += 1 ; ids }
38
38
39
- /** Used for deciding in the IDE whether we can interrupt the compiler */
40
- // protected var activeLocks = 0
41
-
42
- /** Used for debugging only */
43
- // protected var lockedSyms = scala.collection.immutable.Set[Symbol]()
44
-
45
39
/** Used to keep track of the recursion depth on locked symbols */
46
40
private [this ] var _recursionTable = immutable.Map .empty[Symbol , Int ]
47
41
def recursionTable = _recursionTable
@@ -589,16 +583,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
589
583
} else {
590
584
_rawflags |= LOCKED
591
585
true
592
- // activeLocks += 1
593
- // lockedSyms += this
594
586
}
595
587
}
596
588
597
589
// Unlock a symbol
598
590
private [scala] def unlock () = {
599
591
if ((_rawflags & LOCKED ) != 0L ) {
600
- // activeLocks -= 1
601
- // lockedSyms -= this
602
592
_rawflags &= ~ LOCKED
603
593
if (settings.Yrecursion .value != 0 )
604
594
recursionTable -= this
@@ -1521,41 +1511,42 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
1521
1511
/** Get type info associated with symbol at current phase, after
1522
1512
* ensuring that symbol is initialized (i.e. type is completed).
1523
1513
*/
1524
- def info : Type = try {
1514
+ def info : Type = {
1525
1515
var cnt = 0
1526
- while (validTo == NoPeriod ) {
1527
- assert(infos ne null , this .name)
1528
- assert(infos.prev eq null , this .name)
1529
- val tp = infos.info
1530
-
1531
- if ((_rawflags & LOCKED ) != 0L ) { // rolled out once for performance
1532
- lock {
1533
- setInfo(ErrorType )
1534
- throw CyclicReference (this , tp)
1535
- }
1536
- } else {
1537
- _rawflags |= LOCKED
1538
- // TODO another commented out lines - this should be solved in one way or another
1539
- // activeLocks += 1
1540
- // lockedSyms += this
1541
- }
1542
- val current = phase
1543
- try {
1544
- assertCorrectThread()
1545
- phase = phaseOf(infos.validFrom)
1546
- tp.complete(this )
1547
- } finally {
1548
- unlock()
1549
- phase = current
1550
- }
1516
+ while (_validTo == NoPeriod ) {
1517
+ completeInfo()
1551
1518
cnt += 1
1552
1519
// allow for two completions:
1553
1520
// one: sourceCompleter to LazyType, two: LazyType to completed type
1554
- if (cnt == 3 ) abort(s " no progress in completing $this: $tp" )
1521
+ def abortNoProgress () = abort(s " no progress in completing $this: ${infos.info}" )
1522
+ if (cnt == 3 ) abortNoProgress()
1555
1523
}
1556
1524
rawInfo
1557
1525
}
1558
- catch {
1526
+
1527
+ private def completeInfo (): Unit = try {
1528
+ assert(infos ne null , this .name)
1529
+ assert(infos.prev eq null , this .name)
1530
+ val tp = infos.info
1531
+
1532
+ if ((_rawflags & LOCKED ) != 0L ) { // rolled out once for performance
1533
+ lock {
1534
+ setInfo(ErrorType )
1535
+ throw CyclicReference (this , tp)
1536
+ }
1537
+ } else {
1538
+ _rawflags |= LOCKED
1539
+ }
1540
+ val current = phase
1541
+ try {
1542
+ assertCorrectThread()
1543
+ phase = phaseOf(infos.validFrom)
1544
+ tp.complete(this )
1545
+ } finally {
1546
+ unlock()
1547
+ phase = current
1548
+ }
1549
+ } catch {
1559
1550
case ex : CyclicReference =>
1560
1551
devWarning(" ... hit cycle trying to complete " + this .fullLocationString)
1561
1552
throw ex
@@ -1611,81 +1602,87 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
1611
1602
1612
1603
/** Return info without checking for initialization or completing */
1613
1604
def rawInfo : Type = {
1605
+ // OPT: hoisting the outer reference reduces the bytecode size of this method a little which makes it more
1606
+ // likely to inline into hot callers of .info
1607
+ val outer = Symbols .this
1608
+
1614
1609
var infos = this .infos
1615
- assert(infos != null )
1616
- val curPeriod = currentPeriod
1617
- val curPid = phaseId(curPeriod)
1610
+ outer.assert(infos != null )
1611
+
1612
+ if (_validTo != NoPeriod ) {
1613
+ val curPeriod = outer.currentPeriod
1614
+ val curPid = outer.phaseId(curPeriod)
1618
1615
1619
- if (validTo != NoPeriod ) {
1620
1616
// skip any infos that concern later phases
1621
- while (curPid < phaseId(infos.validFrom) && infos.prev != null )
1617
+ while (curPid < outer. phaseId(infos.validFrom) && infos.prev != null )
1622
1618
infos = infos.prev
1623
1619
1624
- if (validTo < curPeriod) {
1625
- assertCorrectThread()
1620
+ if (_validTo < curPeriod) {
1626
1621
// adapt any infos that come from previous runs
1627
- val current = phase
1622
+ val curPhase = outer. phase
1628
1623
try {
1629
- infos = adaptInfos(infos)
1624
+ if (infos != null && outer.runId(infos.validFrom) != outer.currentRunId) {
1625
+ // scala/bug#8871 Discard all but the first element of type history. Specialization only works in the resident
1626
+ // compiler / REPL if re-run its info transformer in this run to correctly populate its
1627
+ // per-run caches, e.g. typeEnv
1628
+ infos = adaptInfo(infos.oldest)
1629
+ }
1630
1630
1631
1631
// assert(runId(validTo) == currentRunId, name)
1632
1632
// assert(runId(infos.validFrom) == currentRunId, name)
1633
1633
1634
- if (validTo < curPeriod) {
1635
- var itr = nextFrom(phaseId(validTo))
1636
- infoTransformers = itr; // caching optimization
1637
- while (itr.pid != NoPhase .id && itr.pid < current.id) {
1638
- phase = phaseWithId(itr.pid)
1639
- val info1 = itr.transform(this , infos.info)
1640
- if (info1 ne infos.info) {
1641
- infos = TypeHistory (currentPeriod + 1 , info1, infos)
1642
- this .infos = infos
1643
- }
1644
- _validTo = currentPeriod + 1 // to enable reads from same symbol during info-transform
1645
- itr = itr.next
1646
- }
1647
- _validTo = if (itr.pid == NoPhase .id) curPeriod
1648
- else period(currentRunId, itr.pid)
1634
+ if (_validTo < curPeriod) {
1635
+ infos = transformInfos(infos, curPhase, curPeriod)
1649
1636
}
1650
1637
} finally {
1651
- phase = current
1638
+ outer. phase = curPhase
1652
1639
}
1653
1640
}
1654
1641
}
1655
1642
infos.info
1656
1643
}
1657
1644
1645
+ private def transformInfos (infos0 : TypeHistory , curPhase : Phase , curPeriod : Period ): TypeHistory = {
1646
+ assertCorrectThread()
1647
+ var infos = infos0
1648
+ var itr = nextFrom(phaseId(_validTo))
1649
+ infoTransformers = itr; // caching optimization
1650
+ while (itr.pid != NoPhase .id && itr.pid < curPhase.id) {
1651
+ phase = phaseWithId(itr.pid)
1652
+ val info1 = itr.transform(this , infos.info)
1653
+ if (info1 ne infos.info) {
1654
+ infos = TypeHistory (currentPeriod + 1 , info1, infos)
1655
+ this .infos = infos
1656
+ }
1657
+ _validTo = currentPeriod + 1 // to enable reads from same symbol during info-transform
1658
+ itr = itr.next
1659
+ }
1660
+ _validTo = if (itr.pid == NoPhase .id) curPeriod
1661
+ else period(currentRunId, itr.pid)
1662
+ infos
1663
+ }
1664
+
1658
1665
// adapt to new run in fsc.
1659
- private def adaptInfos ( infos : TypeHistory ): TypeHistory = {
1666
+ private def adaptInfo ( oldest : TypeHistory ): TypeHistory = {
1660
1667
assert(isCompilerUniverse)
1661
- if (infos == null || runId(infos.validFrom) == currentRunId) {
1662
- infos
1663
- } else if (infos ne infos.oldest) {
1664
- // scala/bug#8871 Discard all but the first element of type history. Specialization only works in the resident
1665
- // compiler / REPL if re-run its info transformer in this run to correctly populate its
1666
- // per-run caches, e.g. typeEnv
1667
- adaptInfos(infos.oldest)
1668
+ assert(oldest.prev == null )
1669
+ val pid = phaseId(oldest.validFrom)
1670
+
1671
+ _validTo = period(currentRunId, pid)
1672
+ phase = phaseWithId(pid)
1673
+
1674
+ val info1 = adaptToNewRunMap(oldest.info)
1675
+ if (info1 eq oldest.info) {
1676
+ oldest.validFrom = validTo
1677
+ this .infos = oldest
1678
+ oldest
1668
1679
} else {
1669
- val prev1 = adaptInfos(infos.prev)
1670
- if (prev1 ne infos.prev) prev1
1671
- else {
1672
- val pid = phaseId(infos.validFrom)
1673
-
1674
- _validTo = period(currentRunId, pid)
1675
- phase = phaseWithId(pid)
1676
-
1677
- val info1 = adaptToNewRunMap(infos.info)
1678
- if (info1 eq infos.info) {
1679
- infos.validFrom = validTo
1680
- infos
1681
- } else {
1682
- this .infos = TypeHistory (validTo, info1, prev1)
1683
- this .infos
1684
- }
1685
- }
1680
+ this .infos = TypeHistory (validTo, info1, null )
1681
+ this .infos
1686
1682
}
1687
1683
}
1688
1684
1685
+
1689
1686
/** Raises a `MissingRequirementError` if this symbol is a `StubSymbol` */
1690
1687
def failIfStub (): Unit = {}
1691
1688
0 commit comments