Skip to content

Add sbt-based bootstrap #1896

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 14 commits into from
Jan 28, 2017
Merged

Add sbt-based bootstrap #1896

merged 14 commits into from
Jan 28, 2017

Conversation

smarter
Copy link
Member

@smarter smarter commented Jan 11, 2017

This PR might be the hardest I've worked on just because of all the deep and subtle issues in dotty it forced me to figure out (especially #1770, #1856, #1895), but is now finally ready! (Well, almost, the backend needs to updated with lampepfl/scala#4 first and we need to get #1894 in, but other than that it should be complete).

This adds two new project to the sbt build: dotty-library-bootstrapped and dotty-compiler-bootstrapped. These projects use the same source files as dotty-library and dotty-compiler but are compiled using dotty itself. The main usecase for this is that we can now run the JUnit tests (which are not just a subset of the tests run by partest, for example the REPL tests are only run through JUnit) with a bootstrapped compiler:

$ sbt
> publishLocal # Non-bootstrapped dotty needs to be published first
> dotty-bootstrapped/test

But this also allows one to experiment with a bootstrapped dotty in a much nicer way. This also replaces the previous bootstrap mechanism used for partest: partest and partest-only will now go through dotty-compiler-bootstrapped. Since partest bootstrapping has been broken for several months now, I consider that a win (we could also keep the old mechanism around but only if someone volunteers to maintain it).

@smarter
Copy link
Member Author

smarter commented Jan 11, 2017

Review by @felixmulder for the sbt/tests related stuff and by @odersky for everything else :).

@smarter
Copy link
Member Author

smarter commented Jan 11, 2017

Every day is a new adventure, apparently compiling dotty (with scalac) is enough to fill up the code cache of the JVM now? http://dotty-ci.epfl.ch/lampepfl/dotty/530/2

CodeCache: size=131072Kb used=124845Kb max_used=125852Kb free=6226Kb
 bounds [0x00007f0cd0d0f000, 0x00007f0cd8d0f000, 0x00007f0cd8d0f000]
 total_blobs=27273 nmethods=26706 adapters=462
 compilation: disabled (not enough contiguous free space left)
OpenJDK 64-Bit Server VM warning: CodeCache is full. Compiler has been disabled.
OpenJDK 64-Bit Server VM warning: Try increasing the code cache size using -XX:ReservedCodeCacheSize=

@retronym
Copy link
Member

Every day is a new adventure, apparently compiling dotty (with scalac) is enough to fill up the code cache of the JVM now? http://dotty-ci.epfl.ch/lampepfl/dotty/530/2

We decided to handle bootstrapping outside of the SBT build in the Scala build for this reason. We use sbt .... publishLocal; sbt -Dstarr.version=.... instead.

@smarter
Copy link
Member Author

smarter commented Jan 11, 2017

I think I can handle it by restricting sbt task parallelism when I bootstrap (right now it's happily compiling/publishing everything at the same time)

@smarter
Copy link
Member Author

smarter commented Jan 11, 2017

Oh, I think what's going is that it's compiling dotty twice at the same time, I thought sbt whole job was to not do that sort of things:

[info] Compiling 296 Scala sources and 1 Java source to /drone/src/github.com/lampepfl/dotty/compiler/target/scala-2.11/classes...
...
[info] Compiling 296 Scala sources and 1 Java source to /drone/src/github.com/lampepfl/dotty/compiler/target/scala-2.11/classes...

@smarter smarter force-pushed the fix/bootstrap branch 5 times, most recently from 851a0b9 to ab209a1 Compare January 11, 2017 11:48
@DarkDimius
Copy link
Contributor

lampepfl/scala#4 was merged

Copy link
Contributor

@felixmulder felixmulder left a comment

Choose a reason for hiding this comment

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

Otherwise build changes look good to me.

TestFrameworks.JUnit, "-a", "-v",
"--run-listener=dotty.tools.ContextEscapeDetector"
TestFrameworks.JUnit, "-a", "-v"/*,
"--run-listener=dotty.tools.ContextEscapeDetector"*/
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this need to be disabled still?

Copy link
Member Author

Choose a reason for hiding this comment

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

Until we have a published new backend and #1894 is merged, yes. (I'll wait for these things to happen before merging this PR)

// val s = state.value
// val e = Project.extract(s)
// e.runAggregated(publishLocal in dotty, s)
// })
Copy link
Contributor

Choose a reason for hiding this comment

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

comment in empty settings?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah I should comment the whole thing

@smarter smarter requested a review from odersky January 11, 2017 14:35
If something needs to be fixed, fix it at the source. This prevented
dotty-compiler-bootstrapped from using the dotty-library-bootstrapped
clases instead of the dotty-library jar
This is necessary to run the tests with the bootstrapped projects and is
just much better than hardcoding them anyway.
This adds two new project to the sbt build: dotty-library-bootstrapped
and dotty-compiler bootstrapped. These projects use the same source
files as dotty-library and dotty-compiler but are compiled using dotty
itself. The main usecase for this is that we can now run the JUnit
tests (which are _not_ just a subset of the tests run by partest, for
example the REPL tests are only run through JUnit) with
a bootstrapped compiler:

$ sbt
> publishLocal # Non-bootstrapped dotty needs to be published first
> dotty-compiler-bootstrapped/test

But this also allows one to experiment with a bootstrapped dotty much
more easily in general.

This revealed many issues in the compiler that are fixed in subsequent
commits in this PR.
@smarter
Copy link
Member Author

smarter commented Jan 27, 2017

Rebased to master which contains #1912 which was the last blocker to get this in

`partest` and `partest-only` are now run through
`dotty-compiler-bootstrapped`. The old bootstrapping mechanism is
deleted since it has been unmaintained and broken for several months and
that I do not wish to maintain two bootstrapping mechanisms.
Copy link
Contributor

@odersky odersky left a comment

Choose a reason for hiding this comment

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

Otherwise LGTM. Nice job!

}
_DottyPredefModuleRef
}
private[this] var _DottyPredefModuleRef: TermRef = _
Copy link
Contributor

Choose a reason for hiding this comment

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

Aside: Following @Ichoran's example, I tend to use myDottyPredefModuleRef for private vars that have a getter DottyPredefModuleRef. But _... notation works as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

OK, let's standardize on my

@@ -398,8 +398,13 @@ class DPTestRunner(testFile: File, suiteRunner: DPSuiteRunner) extends nest.Runn
override def extraClasspath =
suiteRunner.fileManager.asInstanceOf[DottyFileManager].extraJarList ::: super.extraClasspath


// FIXME: Dotty deviation: error if return type is emitted:
Copy link
Contributor

Choose a reason for hiding this comment

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

emitted -> omitted

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Contributor

@odersky odersky left a comment

Choose a reason for hiding this comment

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

Otherwise LGTM. Nice job!

As reportd by dotty (same thing with showShop):
  cyclic reference involving implicit value showCar
  This happens when the right hand-side of value showCar's
  definition involves an implicit search.
  To avoid the error, give value showCar an explicit type.
Using changeOwnerAfter would be more appropriate but currently fails
with an assertion in LambdaLift
The bug was that we declared case classes like:
  case class CompFailed() extends NegTestState
but we used their companion objects like in:
  case _ => CompFailed

Interestingly, this bug was caught by compiling this code with dotty,
instead of `failureStates` getting inferred to be of type `AnyRef`, it
ended up being a union of object types, this allows dotty to realize our
subsequent pattern match on `failureStates` cannot possibly succeed:

-- Error: /home/smarter/opt/dotty/compiler/test/dotty/partest/DPConsoleRunner.scala
353 |          case CompFailedButWrongDiff() =>
    |          ^
    | missing parameter type for parameter x$1 of expanded function x$1 =>
    |   x$1 @unchecked match
    |     {
    |       case CompFailedButWrongDiff() =>
    |         nextTestActionFailing(s"output differs")
    |         true
    |       case _ =>
    |         false
    |     }, expected = ?
-- Error: /home/smarter/opt/dotty/compiler/test/dotty/partest/DPConsoleRunner.scala
353 |          case CompFailedButWrongDiff() =>
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
    |Pattern type CompFailedButWrongDiff is neither a subtype nor a supertype of selector type CompSucceeded | CompFailedButWrongNErr | CompFailed | CompFailedButWrongDiff'where:    CompFailedButWrongDiff  is a class in method runNegTest
    |          CompFailedButWrongDiff' is a object in method runNegTest
Type#member might return a denotation that doesn't "really exists" (as
defined by TypeAssigner#reallyExists), in some circumstance this
denotation can refer to a symbol in a class that is in the classpath but
that is not used by this file, so using addDependency on the result of
Type#member might add a false dependency. We avoid this by using
Type#select instead which will internally do the right thing.

This issue was discovered while compiling the bootstrapped projects
which would sometimes force a full recompilation for no reason.
sbt runs up to `Runtime.getRuntime.availableProcessors` tasks in
parallel, on our CI that means 40 tasks, compilation tasks are the one
with the biggest footprint and the introduction of
`dotty-library-bootstrapped` and `dotty-compiler-bootstrapped` in this
PR means that sbt can now run more compilation tasks in parallel. To
prevent the JVM from exploding, we increase:
- The max heap size, from 1G to 4G
- The max code cache size, from 240M to 512M
- The max metaspace size, from 256M to 1G
This way you can run both the dotty-library-bootstrapped and
dotty-compiler-bootstrapped tests with one command:
  sbt ;publishLocal;dotty-bootstrapped/test
@smarter smarter merged commit 6e8933c into scala:master Jan 28, 2017
@allanrenucci allanrenucci deleted the fix/bootstrap branch December 14, 2017 19:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants