-
Notifications
You must be signed in to change notification settings - Fork 281
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
document cases where ijar + scalac is suboptimal #125
Comments
This could be useful as an example of parsing the scala annotation on each class: https://github.com/avityuk/scala-pickled-visualizer It is not clear to me if the scala annotation is already minimal or if we could remove data about private methods and prevent changes. Might be interesting to make some test cases, run ijar and the above tool and see if things change when |
Hi @johnynek just learning about ijars which I think will be essential for avoiding invalidating scalac dependency chains. Running some experiements with scala_libary rules. I can see ijars getting created but it didn't look like they were actually used when I was testing adding/removing private methods to down stream dependencies which shouldn't have an affect on needing to recompile upstream users. Then I found this thread. I tried adding the Here's of my experiement scala_library(
name = "foo",
srcs = glob(
[
"foo/src/main/scala/**/*.scala",
"foo/src/main/java/**/*.java"
]
),
scalacopts = ["-Yskip-inline-info-attribute"]
)
scala_library(
name = "bar",
srcs = glob(
[
"bar/src/main/scala/**/*.scala",
"bar/src/main/java/**/*.java"
]
),
deps = [":foo"],
scalacopts = ["-Yskip-inline-info-attribute"]
) I'm testing adding and removing private methods in package Do you have an examples you can point to help demonstrate how to make this work? |
I also tried the |
I don't know that it will work for that case right now (sadly).
Try changing logic inside of a method and see if it recompiles.
I think the issue is that the scala signature, a serialized attribute on
the class, has information about it still.
The other issue might be only private[this] can work.
Like I said, we don't know enough yet. :/
…On Sat, Feb 11, 2017 at 11:23 doug tangren ***@***.***> wrote:
Hi @johnynek <https://github.com/johnynek> just learning about ijars
which I think will be essential for avoiding invalidating scalac dependency
chains. Running some experiements with scala_libary rules. I can see ijars
getting created but it didn't look like they were actually used when I was
testing adding/removing private methods to down stream dependencies which
shouldn't have an affect on needing to recompile upstream users. Then I
found this thread. I tried adding the -Yskip-inline-info-attribute
suggestion and it didn't seem to help.
Here's of my experiement
scala_library(
name = "foo",
srcs = glob(
[
"foo/src/main/scala/**/*.scala",
"foo/src/main/java/**/*.java"
]
),
scalacopts = ["-Yskip-inline-info-attribute"]
)
scala_library(
name = "bar",
srcs = glob(
[
"bar/src/main/scala/**/*.scala",
"bar/src/main/java/**/*.java"
]
),
deps = [":foo"],
scalacopts = ["-Yskip-inline-info-attribute"]
)
I'm testing adding and removing private methods in package foo then bazel
building bar. I expected that with the ijar machinery in place bar wouldn't
require a rebuild since it doesn't/cant reference foo's private parts.
Do you have an examples you can point to help demonstrate how to make this
work?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#125 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAEJdqBgv4VOjafH9F74t_xGgNh5Ox6fks5rbia5gaJpZM4Lnafl>
.
|
We may need to parse and rewrite the scalasignature to only include non
private information. I've looked at that a bit, but I have not found such a
clear explanation of how it is serialized, nor what might be safe to remove.
On Sat, Feb 11, 2017 at 11:25 P. Oscar Boykin <[email protected]>
wrote:
… I don't know that it will work for that case right now (sadly).
Try changing logic inside of a method and see if it recompiles.
I think the issue is that the scala signature, a serialized attribute on
the class, has information about it still.
The other issue might be only private[this] can work.
Like I said, we don't know enough yet. :/
On Sat, Feb 11, 2017 at 11:23 doug tangren ***@***.***>
wrote:
Hi @johnynek <https://github.com/johnynek> just learning about ijars
which I think will be essential for avoiding invalidating scalac dependency
chains. Running some experiements with scala_libary rules. I can see ijars
getting created but it didn't look like they were actually used when I was
testing adding/removing private methods to down stream dependencies which
shouldn't have an affect on needing to recompile upstream users. Then I
found this thread. I tried adding the -Yskip-inline-info-attribute
suggestion and it didn't seem to help.
Here's of my experiement
scala_library(
name = "foo",
srcs = glob(
[
"foo/src/main/scala/**/*.scala",
"foo/src/main/java/**/*.java"
]
),
scalacopts = ["-Yskip-inline-info-attribute"]
)
scala_library(
name = "bar",
srcs = glob(
[
"bar/src/main/scala/**/*.scala",
"bar/src/main/java/**/*.java"
]
),
deps = [":foo"],
scalacopts = ["-Yskip-inline-info-attribute"]
)
I'm testing adding and removing private methods in package foo then bazel
building bar. I expected that with the ijar machinery in place bar wouldn't
require a rebuild since it doesn't/cant reference foo's private parts.
Do you have an examples you can point to help demonstrate how to make this
work?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#125 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAEJdqBgv4VOjafH9F74t_xGgNh5Ox6fks5rbia5gaJpZM4Lnafl>
.
|
ok cool I'll watch this issue and post back if I find updates. Just a final note because Im still newish to bazel and what happens when I run bazel build ... I confirmed that I got different md5 checksums on my |
It might be interesting for us to actually look at the contents and see the
difference. Then we could validate if it is a scalasignature issue or not.
…On Sat, Feb 11, 2017 at 11:33 doug tangren ***@***.***> wrote:
ok cool I'll watch this issue and post back if I find updates. Just a
final note because Im still newish to bazel and what happens when I run
bazel build ...
I confirmed that I got different md5 checksums on my
bazel-out/local-fastbuild/bin/foo_ijar.jar did change when I
added/removed new private members and so forth. So I don't think its an
issue with scala_rules in general, it does the right thing when ijars
change. Maybe just a recipe for dealing with scalasignatures we need to
find.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#125 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAEJdpCwDv6bBypCMigsevyq3y5lVS25ks5rbikdgaJpZM4Lnafl>
.
|
checksum of the ijar stays consistent when I modify the contents of the private methods but that still triggers some action which looks like a recompile (not positive) because it takes about 6 seconds . Still new to bazel so I'm not sure what that could be. |
Cc @ianoc
It could be something sloppy in the rules somewhere. You can set and option
to show the compile time for scalac (Ian can remind us) so we can be sure
if it is the compiler, or something else (maybe the jar process is somehow
running no matter what?)
…On Sat, Feb 11, 2017 at 11:41 doug tangren ***@***.***> wrote:
checksum of the ijar stays consistent when I modify the contents of the
private methods but that still triggers some action which looks like a
recompile (not positive) because it takes about 6 seconds . Still new to
bazel so I'm not sure what that could be.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#125 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAEJdo4jFBLnhDdO_Clt6pS6NYHBiznvks5rbir1gaJpZM4Lnafl>
.
|
Six seconds seems like a long time, if it's not private code is it
possible for you to put a public code/ repo up somewhere as a test case ?
Generally so far changing the signature of methods be there private or
public I think triggers recompiles. However changing the content of methods
if we stripped the in-line information out generally seems to avoid the
recompile. If we have a test case where that doesn't happen I would be very
interested to look at it, since we probably hit this and just don't know it
On Sat, Feb 11, 2017 at 1:44 PM P. Oscar Boykin <[email protected]>
wrote:
Cc @ianoc
It could be something sloppy in the rules somewhere. You can set and option
to show the compile time for scalac (Ian can remind us) so we can be sure
if it is the compiler, or something else (maybe the jar process is somehow
running no matter what?)
On Sat, Feb 11, 2017 at 11:41 doug tangren ***@***.***>
wrote:
> checksum of the ijar stays consistent when I modify the contents of the
> private methods but that still triggers some action which looks like a
> recompile (not positive) because it takes about 6 seconds . Still new to
> bazel so I'm not sure what that could be.
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <
#125 (comment)
>,
> or mute the thread
> <
https://github.com/notifications/unsubscribe-auth/AAEJdo4jFBLnhDdO_Clt6pS6NYHBiznvks5rbir1gaJpZM4Lnafl
>
> .
>
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#125 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAbQvDo3tVCuXgTygezW3g-kAWrtNBYmks5rbiujgaJpZM4Lnafl>
.
--
Sent from Gmail Mobile
|
Testing with an private company best-practices repo to show our team some examples of how to build their mixed scala/java projects with bazel. I'll try to put up a simple public example sometime this weekend. |
Okay, I did some digging. In the ijar, the private methods don't appear (neither
So, scala embeds information about private methods into the scala signature. That means to improve on matters, we need a scala-specific ijar (or probably better, extension to the bazel ijar that parses the scalasignature, removes any info about private methods, and puts it back). Here is a page that shows some demos of parsing it: @gkossakowski do you have any input you can share with us here? Should this be hard or easy? It seems like is should be straightforward enough. |
cc @adriaanm any suggestions on how to produce an interface jar for scala (a jar of bytecode that only has the non-private interfaces, and none of the code). Using bazel's ijar produces an interface, but the scalasig is left untouched, so the hash changes, so adding a private method causes a recompilation. |
@softprops are you using the
|
I wonder if it could be as easy just removing any item with the private flag set: |
For public it includes method length I think ? May want to do something
about that also if we are doing some custom stuff. Chunking method sizes
into blocks maybe ? (Though I'm not sure what the compiler can do inlining
wise if it just has the ijar )
On Sat, Feb 11, 2017 at 4:01 PM P. Oscar Boykin ***@***.***> wrote:
I wonder if it could be as easy just removing any item with the private
flag set:
https://github.com/avityuk/scala-pickled-visualizer/blob/master/src/PickledVisualizer.scala#L377
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#125 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAbQvCo98Zk0xmUksw7MKTOnSNU_8dBYks5rbkvMgaJpZM4Lnafl>
.
--
Sent from Gmail Mobile
|
I imagine, the compiler can't inline across package boundaries if we take this approach (so you have to rely on the JIT in such cases). That may be a tradeoff worth making if the JIT usually does well enough and maybe a lot of inlining is from the std-lib or from within the package. |
Today, it can't work either can it? Right now we compile against the ijar
across targets right?
On Sat, Feb 11, 2017 at 4:05 PM P. Oscar Boykin ***@***.***> wrote:
I imagine, the compiler can't inline across package boundaries if we take
this approach (so you have to rely on the JIT in such cases). That may be a
tradeoff worth making if the JIT usually does well enough and maybe a lot
of inlining is from the std-lib or from within the package.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#125 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAbQvNLuVji0tX_IsMMImWfwiTF7dDdOks5rbky8gaJpZM4Lnafl>
.
--
Sent from Gmail Mobile
|
We don't ijar the standard library or compiler (or anything with macros), and of course, within a target, you are not using an ijar. But other than that, yeah, we are probably killing the ability for scalac to inline. |
So from today's experience do we think there is any losses by just
stripping all of this info ? We didn't do it always before since we had the
notion the inline might matter, but I can't see why now. Might as well
aggressively drop.
On Sat, Feb 11, 2017 at 4:18 PM Ian O'Connell ***@***.***> wrote:
Yeah, so I guess I mean the Delta by stripping most of this information
is probably nothing in losses I think ? Since the compiler can't use it to
inline anyway.
On Sat, Feb 11, 2017 at 4:17 PM P. Oscar Boykin ***@***.***>
wrote:
We don't ijar the standard library or compiler (or anything with macros),
but other than that, yeah, we are probably killing the ability for scalac
to inline.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#125 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAbQvC_0M87qIM2jHG1gxBLaqG37QXzCks5rbk97gaJpZM4Lnafl>
.
--
Sent from Gmail Mobile
|
I think you can't compile scala without it. For instance, the |
Yeah we need the extra type information but hopefully that's relatively
static.
On Sat, Feb 11, 2017 at 4:23 PM P. Oscar Boykin ***@***.***> wrote:
I think you can't compile scala without it. For instance, the implicit
labels are probably the biggest things, but other aspects of the
type-system are in there. Dropping everything, I think, would be pretty bad
news.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#125 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAbQvFoyAI9AyrAZlWz0L230fBg3vouqks5rblEYgaJpZM4Lnafl>
.
--
Sent from Gmail Mobile
|
Wasn't using any nondefault flags. I wonder if there's and knowledge that can be minded from sbts analyzing compiler. It seems a bit more knowledgeable about how to detect scala public api changes |
I wonder if sbt really does this. My understanding is that it takes another
approach: automatically build a fine training dependency graph. Bazel takes
the approach of humans fixing targets and then trying to minimize
rebuilding whole targets.
Of course it would be great if we can learn from sbt/zinc.
…On Sat, Feb 11, 2017 at 15:24 doug tangren ***@***.***> wrote:
https://github.com/sbt/zinc/tree/1.0/internal/zinc-classfile/src/main/scala/sbt/internal/inc/classfile
maybe
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#125 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAEJdix_N2eMIlmJru1ww4LoltZuu4uvks5rbl9pgaJpZM4Lnafl>
.
|
So I guess to maybe capture for myself having thought about this a bit, and
see if we are on the same page, i think there are 3 major bits around this
ijar stuff:
1) Does our current usage of iJar have any performance degradation. None we
have noticed, but i don't think the code base we use bazel for at stripe is
maybe a super performance sensitive one(we also don't that I know of have
any benchmarks). We could probably do with some benchmarks that
with/without JIT'd code does:
object A {
@inline
def foo(a: X): Bar
}
perform differently if its within the same bazel target or in a different
one? Right now if we are compiling against the ijar i believe we cannot
make use of that inline. Though I don't know if that matters.
2) If (1) matters, we probably need to do some surgery to actually unwind
part of the ijar semantics such that inline methods are included in ijars
rather than all method bodies being stripped? (looking at privacy here will
matter too). I don't think the scala compiler inlines otherwise unless one
uses `-optimise`. So if this stuff matters do we make it an option to allow
scala inlining, explicit or implicit across packages or do we say the rules
only support JVM inlining?
3) If (1) doesn't matter, then i think we can aim to basically minify the
scala signature for correctness, that is strip anything not really required
for building. I think we've been slow to touch it before because of fears
of something like (1) , but if its not an issue then sufficiently large
code bases compiling with the rules along with whatever test cases we can
make is a pretty good validation we haven't messed it up. (Given our
liberal usage of types/implicits/macros i'm not too worried about us
missing some gremlins here).
Thoughts?
On Sat, Feb 11, 2017 at 5:28 PM, P. Oscar Boykin <[email protected]>
wrote:
… I wonder if sbt really does this. My understanding is that it takes another
approach: automatically build a fine training dependency graph. Bazel takes
the approach of humans fixing targets and then trying to minimize
rebuilding whole targets.
Of course it would be great if we can learn from sbt/zinc.
On Sat, Feb 11, 2017 at 15:24 doug tangren ***@***.***>
wrote:
>
> https://github.com/sbt/zinc/tree/1.0/internal/zinc-
classfile/src/main/scala/sbt/internal/inc/classfile
> maybe
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/bazelbuild/rules_scala/issues/
125#issuecomment-279189073>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AAEJdix_
N2eMIlmJru1ww4LoltZuu4uvks5rbl9pgaJpZM4Lnafl>
> .
>
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#125 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAbQvPEJM3YcQmhCx-orThk4wcBCl2Xwks5rbmBSgaJpZM4Lnafl>
.
|
Yeah, Ian, I think that is a good summary.
In any case, we need to improve ijar or implement a scala specific ijar to
improve the current situation (which, as you note seems fairly tolerable at
Stripe at the moment).
One thing that occurs to me is that maybe this work could be done directly
on the scala compiler: it could emit interface classes as it compiles. That
could be useful for everyone and it would keep the code colacated with the
actual signature parsing and writing code.
We could probably get this merged in mainline scala or typelevel if it was
done well.
If there was a scala linker, we could defer the question about inlining
until linking.
…On Sat, Feb 11, 2017 at 16:24 ianoc ***@***.***> wrote:
So I guess to maybe capture for myself having thought about this a bit, and
see if we are on the same page, i think there are 3 major bits around this
ijar stuff:
1) Does our current usage of iJar have any performance degradation. None we
have noticed, but i don't think the code base we use bazel for at stripe is
maybe a super performance sensitive one(we also don't that I know of have
any benchmarks). We could probably do with some benchmarks that
with/without JIT'd code does:
object A {
@inline
def foo(a: X): Bar
}
perform differently if its within the same bazel target or in a different
one? Right now if we are compiling against the ijar i believe we cannot
make use of that inline. Though I don't know if that matters.
2) If (1) matters, we probably need to do some surgery to actually unwind
part of the ijar semantics such that inline methods are included in ijars
rather than all method bodies being stripped? (looking at privacy here will
matter too). I don't think the scala compiler inlines otherwise unless one
uses `-optimise`. So if this stuff matters do we make it an option to allow
scala inlining, explicit or implicit across packages or do we say the rules
only support JVM inlining?
3) If (1) doesn't matter, then i think we can aim to basically minify the
scala signature for correctness, that is strip anything not really required
for building. I think we've been slow to touch it before because of fears
of something like (1) , but if its not an issue then sufficiently large
code bases compiling with the rules along with whatever test cases we can
make is a pretty good validation we haven't messed it up. (Given our
liberal usage of types/implicits/macros i'm not too worried about us
missing some gremlins here).
Thoughts?
On Sat, Feb 11, 2017 at 5:28 PM, P. Oscar Boykin ***@***.***
>
wrote:
> I wonder if sbt really does this. My understanding is that it takes
another
> approach: automatically build a fine training dependency graph. Bazel
takes
> the approach of humans fixing targets and then trying to minimize
> rebuilding whole targets.
>
> Of course it would be great if we can learn from sbt/zinc.
> On Sat, Feb 11, 2017 at 15:24 doug tangren ***@***.***>
> wrote:
>
> >
> > https://github.com/sbt/zinc/tree/1.0/internal/zinc-
> classfile/src/main/scala/sbt/internal/inc/classfile
> > maybe
> >
> > —
> > You are receiving this because you were mentioned.
> > Reply to this email directly, view it on GitHub
> > <https://github.com/bazelbuild/rules_scala/issues/
> 125#issuecomment-279189073>,
> > or mute the thread
> > <https://github.com/notifications/unsubscribe-auth/AAEJdix_
> N2eMIlmJru1ww4LoltZuu4uvks5rbl9pgaJpZM4Lnafl>
> > .
>
> >
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <
#125 (comment)
>,
> or mute the thread
> <
https://github.com/notifications/unsubscribe-auth/AAbQvPEJM3YcQmhCx-orThk4wcBCl2Xwks5rbmBSgaJpZM4Lnafl
>
> .
>
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#125 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAEJdlT26R5Fjdbc6SVaSOyv0j-h52pBks5rbm1fgaJpZM4Lnafl>
.
|
Do you think that would be probable those changes would be landable in the 2.11.x line of scala? I'm targeting bazel as a viable alternative to sbt for a monorepo for the potential improved performance and correctness without changing existing scala 2.11 runtime dependencies. My goal is the prove this out by dark building in ci and drawing comparisons to our existing sbt build. |
Doug, by the way, we find bazel very usable as is. He worker mode is
critical, and i do think what we are talking about here is a second order
effect. Most changes, I think, are to method bodies, or public APIs.
With bazel you never need to clean, something sbt does not really offer
(for instance I bet your CI does a clean build, not a cached build, but
bazel can totally run a CI without cleans and you get some big performance
wins from that often).
We are just discussing a small set of changes we won't need to recompile:
adding/removing private methods.
I do think landing an option to 2.11 mainline is possible to have it emit
interface classes, but this is purely guessing based on the kinds of
changes I have seen accepted (@adriaanm may have other opinions).
Alternatively, you could imagine an option where it does not emit any
scalasig info for private methods. I'm not sure why you need that, but
maybe someone else can think of a reason. It seems like only the current
compilation unit needs to know about private.
…On Sat, Feb 11, 2017 at 16:56 doug tangren ***@***.***> wrote:
Do you think that would be probable those changes would be landable in the
2.11.x line of scala? I'm targeting bazel as a viable alternative to sbt
for a monorepo for the potential improved performance and correctness
without changing existing scala 2.11 runtime dependencies. My goal is the
prove this out by dark building in ci and drawing comparisons to our
existing sbt build.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#125 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAEJdtUWTZDQmK15YJ7R733nFGxLW790ks5rbnT4gaJpZM4Lnafl>
.
|
Ok I talked to my team and there wasn't really anything private in here so I just flipped the GH private repo flag. Here's the repo I'm testing with https://github.com/meetup/blt-best-bazel. There are two packages I'm fiddling with those here here's how the dance currently goes ( on osx ) $ bazel build //bar
WARNING: Sandboxed execution is not supported on your system and thus hermeticity of actions cannot be guaranteed. See http://bazel.build/docs/bazel-user-manual.html#sandboxing for more information. You can turn off this warning via --ignore_unsupported_sandboxing.
INFO: Found 1 target...
Target //bar:bar up-to-date:
bazel-bin/bar/bar.jar
INFO: Elapsed time: 3.436s, Critical Path: 3.34s
# no change (its fast of course!)
$ bazel build //bar
WARNING: Sandboxed execution is not supported on your system and thus hermeticity of actions cannot be guaranteed. See http://bazel.build/docs/bazel-user-manual.html#sandboxing for more information. You can turn off this warning via --ignore_unsupported_sandboxing.
INFO: Found 1 target...
Target //bar:bar up-to-date:
bazel-bin/bar/bar.jar
INFO: Elapsed time: 0.079s, Critical Path: 0.00s
# fiddle with private members of foo package
$ bazel build //bar
WARNING: Sandboxed execution is not supported on your system and thus hermeticity of actions cannot be guaranteed. See http://bazel.build/docs/bazel-user-manual.html#sandboxing for more information. You can turn off this warning via --ignore_unsupported_sandboxing.
INFO: Found 1 target...
Target //bar:bar up-to-date:
bazel-bin/bar/bar.jar
INFO: Elapsed time: 6.038s, Critical Path: 5.96s I reread some of the comments above last night and an getting a better sense of the scala-specifc problem. The public interfaces indeed doesn't change so ijar is doing what it advertises. By scala encodes enriched type interface ( including private interfaces ) metadata as bytearray in a @ScalaSig annotation attached to the public interfaces which invalidates the cache. Some options on the table are to some how edit that bytearray, maybe with PickBuffers write methods and deserialize those definitions and store that in the ijar. This would be very cool. ScalaSig tampering. If there were a lib for that I'd call it forgery! The other option is to get scalac to do all the work up front and not use ijar and use a scalaspecific form that uses public interfaces scalac may emit for us. Let me know if my understanding is on the right path. This is a very interesting problem but one I think more scala shops will appreciate a good solution for when adopting bazel |
Yes. This seems like a good summary. One pattern we use is to define a repo-local set of the scala rules (that call the standard one) where we can change some default options (like compiler plugins and compiler flags):
etc.... This way, we can put skip inline attribute in one place. Also, I can't stress enough what a big performance difference the worker strategy makes. |
Oh nice! |
I wonder if this is as easy as right here: adding a check that the |
BTW -- I checked out that repo...
./bazel build bar/...
:
uncomment ` // private val privateField: Int = 1`
in foo/src/main/scala/com/meetup/blt/foo/BestScala.scala
```
INFO: Reading 'startup' options from
/var/folders/pd/2j4md8hj5_x01529sxvr8_gr0000gn/T//bazel_bazel_rc_1486931405:
--watchfs
INFO: Found 1 target...
Target //bar:bar up-to-date:
bazel-bin/bar/bar.jar
INFO: Elapsed time: 0.915s, Critical Path: 0.84s
```
I basically can't get a recompile time above 1 second
This is using the worker strategy, and watchfs on my osx laptop.
With bazel clean/expunge and such building the whole repo looks like:
INFO: Reading 'startup' options from
/var/folders/pd/2j4md8hj5_x01529sxvr8_gr0000gn/T//bazel_bazel_rc_1486931601:
--watchfs
.
INFO: Found 3 targets...
INFO: From Building
external/io_bazel_rules_scala/src/java/io/bazel/rulesscala/scalac/scalac.jar
(2 source files) [for host]:
Note:
external/io_bazel_rules_scala/src/java/io/bazel/rulesscala/scalac/CompileOptions.java
uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
INFO: Elapsed time: 16.320s, Critical Path: 9.21s
…On Sun, Feb 12, 2017 at 12:25 PM, P. Oscar Boykin ***@***.***> wrote:
I wonder if this is as easy as right here:
https://github.com/scala/scala/blob/2.11.x/src/compiler/scala/tools/nsc/
symtab/classfile/Pickler.scala#L45
adding a check that the tree.symbol.hasFlag(PRIVATE) and if it does, skip
it. I might try that tomorrow and see if that can solve the issue.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#125 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAbQvLnakx2cLYPeIoxoKsG0qMXYrTOzks5rb2qfgaJpZM4Lnafl>
.
|
Awesome. You folks are seriously the best. |
Last note for the weekend.
|
Hi guys, Scalac produces a number of synthetic members (e.g. accessors for nested classes, holders for default arguments) that are public but should not be included in the interface. The issues you're wresting are the same sbt/zinc needed to solve. I encourage for you to borrow ideas and code from: Zinc solves two problems for incremental compilation:
Bazel has a different approach to 1. but 2. is shared between bazel and zinc as problem to tackle. Trying to solve 2. from scratch by surgery to ScalaSig is doomed to be an epic amount of work. Lastly, there have discussion about integrating ExtractAPI back to scalac because that code is very tied to internals of scalac and we had a feeling that other tools than just zinc could make use of the info produced by |
As a bonus, I'm throwing a fun issue that you would have to solve yourself if you go down of manually tweaking |
Thanks for replying in detail @gkk-stripe. I saw this comment: Is that still your understanding? I wonder if the conservative approach might be to just not write private defs into the scalasig in the first place. That seems like it will cover most of the cases that matter. |
Scalasig is used for recreating faithfully the state of a symbol across compiler runs (so it supports separate compilation). Consider an example like this: // A.scala
class A
// B.scala
class B extends A Scalasig pickles all information about
or
Skipping even private defs would break that property. Scalasig serves many clients that would break in subtle ways:
In all these cases you would get different results from either a clean build or an incremental build. This would break the main selling point of bazel that you don't need ever to clean manually. |
So, @gkk-stripe and I spoke offline. The TL;DR is:
We are thinking of a SIP proposal for item 2 above. We will update this issue with links to any discussions. |
Sounds grrrreat |
see also http://docs.scala-lang.org/sips/pending/binary-compatibility.html. this was just discussed at the SIP meeting today and seems likely to move forward in some form. cc @DarkDimius @jvican |
ijar https://github.com/bazelbuild/bazel/blob/master/third_party/ijar/README.txt is what bazel uses to create "interface jars" from compiled jars. By hashing those interfaces we see if we need to recompile.
The challenge with scala is that scalac adds a
ScalaSignature
annotation to the class that includes extra information from the scala type system. Any change to that, will change the hash. It may be that not all of them are actually essential to compile potentially for private method, for instance, where other callers can't call the method, we may be able to strip the ScalaSignature.The
-Yskip-inline-info-attribute
scalac option greatly improves things since without that almost every change will cause a recomputation. It seems that is a tradeoff that is worth it, but we have not benchmarked to see if that costs performance./cc @ianoc
The text was updated successfully, but these errors were encountered: