Skip to content

Fix #2924: make TreeChecker.typedBlock iterative #3080

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 11, 2017

Conversation

nicolasstucki
Copy link
Contributor

@nicolasstucki nicolasstucki commented Sep 6, 2017

This PR makes it posssible to compile arbitarley large blocks without growing the stack.

@nicolasstucki
Copy link
Contributor Author

test performance please

@dottybot
Copy link
Member

dottybot commented Sep 6, 2017

performance test scheduled: 1 job(s) in queue.

@dottybot
Copy link
Member

dottybot commented Sep 6, 2017

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/3080 to see the changes.

Benchmarks is based on merge(s) with master

@nicolasstucki
Copy link
Contributor Author

test performance please

@dottybot
Copy link
Member

dottybot commented Sep 7, 2017

performance test scheduled: 1 job(s) in queue.

@nicolasstucki
Copy link
Contributor Author

test performance please

@dottybot
Copy link
Member

dottybot commented Sep 7, 2017

performance test scheduled: 1 job(s) in queue.

@biboudis
Copy link
Contributor

biboudis commented Sep 7, 2017

Yeap. I think this is a blocker for #3065 and more as we saw over the last weeks. /cc @odersky

@dottybot
Copy link
Member

dottybot commented Sep 7, 2017

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/3080 to see the changes.

Benchmarks is based on merge(s) with master

@@ -92,26 +92,27 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer with Annota
private def reorderAndComplete(stats: List[Tree])(implicit ctx: Context): List[Tree] = {
val moduleClassDefs, singleClassDefs = mutable.Map[Name, Tree]()

def reorder(stats: List[Tree]): List[Tree] = stats match {
def reorder(stats: List[Tree], revPrefix: List[Tree] = Nil): List[Tree] = stats match {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a rather complex algorithm. Whenever I see reversed lists my head starts to hurt. Can we simplify it using ListBuffers? Also, if we keep it we need more docs to explain it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To clarify: I believe the original reorder algorithm was already close to the limit of tolerable complexity.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking more about it, I believe the revPrefix idea is the best option. So OK to leave the code as is. Just document what revPrefix stands for. I.e. at any point:

reordered statements = revPrefix.reverse ++ reorder(stats, Nil)

Also, I'd not make revPrefix have a default parameter. To easy to make errors that way.

@@ -149,34 +149,42 @@ class TreeChecker extends Phase with SymTransformer {

def withDefinedSym[T](tree: untpd.Tree)(op: => T)(implicit ctx: Context): T = tree match {
case tree: untpd.DefTree =>
val sym = tree.symbol
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the original logic was complicated - that foldRightBN is sneaky because it mixes laziness with side-effects ! The changes remove the foldRightBN complexity but make everything else more complex. Proposal: make withDefinedSyms take a repeated argument and remove withDefinedSym. I.e.

   def withDefinedSyms[T](trees: untpd.Tree*)(op: => T)(implicit ctx: Context)

withDefinedSyms can step iteratively through all the trees, record the symbols found as defined in a ListBuffer or List and then execute op.

@nicolasstucki
Copy link
Contributor Author

test performance please

@dottybot
Copy link
Member

dottybot commented Sep 8, 2017

performance test scheduled: 1 job(s) in queue.

@dottybot
Copy link
Member

dottybot commented Sep 8, 2017

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/3080 to see the changes.

Benchmarks is based on merge(s) with master

@nicolasstucki
Copy link
Contributor Author

test performance please

@dottybot
Copy link
Member

dottybot commented Sep 8, 2017

performance test scheduled: 1 job(s) in queue.

@dottybot
Copy link
Member

dottybot commented Sep 8, 2017

Performance test finished successfully:

Visit http://dotty-bench.epfl.ch/3080 to see the changes.

Benchmarks is based on merge(s) with master

case (stat: TypeDef) :: stats1 if stat.symbol.isClass =>
if (stat.symbol is Flags.Module) {
def pushOnTop(xs: List[Tree], ys: List[Tree]): List[Tree] = xs match {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is a natural fold

(ys /: xs)((ys, x) => x :: ys)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it's also OK to leave as it is

@nicolasstucki nicolasstucki merged commit c2a30ec into scala:master Sep 11, 2017
@allanrenucci allanrenucci deleted the improve-#2924 branch December 14, 2017 19:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants