-
Notifications
You must be signed in to change notification settings - Fork 3.1k
SI-8362: Support for Future without sun.misc.Unsafe. #4313
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
Conversation
Instead of raising ExceptionInInitializerError, set the field offset to an invalid value, then check for that value when updating the state, falling back to the official but slower AtomicReferenceFieldUpdater. Hotspot is smart enough to inline only the compareAndSwapObject intrinsic in the caller, and ignore the fallback code.
/rebuild -- having issues with jenkins spuriously disconnecting from workers |
I think I prefer the 2.12.x solution: https://github.com/scala/scala/blob/2.12.x/src/library/scala/concurrent/impl/Promise.scala#L181 |
I had a lot of trouble getting the Scala build tests to run, and getting Hotspot to tell me if it wasn't getting any slower, and eventually I gave up. For the 2.12.x solution, that's extending Until 2.12.x is released and Google App Engine supports Java 8, at least this change here would make Scala work on GAE without changing the superclass of |
in fact AtomicReferenceFieldUpdater save bytes. |
Not the way Scala 2.12.x does it. 2.11's I'm quite impressed by how Scala 2.12.x does it. For this pull request, as far as I could tell the Hotspot compiler would always notice that |
@carey Thanks for the kind words regarding the 2.12.x implementation. What about the following proposal: Remove the Unsafe-usage from |
if there is large instance of Promise,using the AtomicReferenceFieldUpdater will reduce the memory footprint.but one drawback is you have to write java code. |
@hepin1989 Yes, compared to composing an AtomicX, but not extending one. |
The project manager in me isn't happy with a change like that in a minor release; on the other hand, I've just tested a simple version of it on App Engine and it works fine:
|
So, what exactly would the 2.12 solution entail? Adding a new package-protected class to an impl package? (I tried to figure it out based on the commits/linked diff, but not sure.) |
@adriaanm Like: #4313 (comment) |
I was suspicious changing implementation to match 2.12.x will break binary compatibility, and effectively it does:
I have used following implementation package scala.concurrent.impl;
import java.util.concurrent.atomic.AtomicReference;
abstract class AbstractPromise extends AtomicReference<Object> {
protected final boolean updateState(Object oldState, Object newState) {
return compareAndSet(oldState, newState);
}
protected final Object getState() {
return get();
}
} |
DefaultPromise is in (https://github.com/scala/scala/blob/2.11.x/src/library/scala/concurrent/impl/Promise.scala#L153) which is |
The jenkins failing build log of |
@mchv Yep, so it needs a mima exception added. |
@viktorklang It looks to me that ignoring private classes is currently unsupported by mima, do you know if there is a way to specify explicitely a qualified classname to ignore? |
@viktorklang @dotta nevermind I just found documentation about it and associated filters file in codebase. I will update the pull request |
Instead of using AtomicReferenceFieldUpdater extends directly AtomicReference as AtomicReferenceFieldUpdater.compareAndSet() isn't necessarily even inlined by Hotspot, while AtomicReference.compareAndSet() should be compiled down to the machine's CAS instruction. The implementation is similar to the 2.12.x branch’s one. Add an exclusion rule for mima to not check backward and forward compatibility as the class is package protected and in an imp package.
@dotta may you review my changes related to mima? |
@mchv The filter rules seems correct (and the build bot is happy). Maybe one day someone will work on lightbend-labs/mima#34. |
In general, I can't think of any real issue with adding a superclass (which contributes only final methods) to a class in an implementation package (as long as those methods were not introduced in any illicit subclasses of said class). I think this
8000
actual plays in favor of @viktorklang's solution in 2.12. If we're going to change superclasses, why not do it closest to the source? This is both clearer and more focussed, leaving those subclasses of EDIT: forgot that java classes are package protected by default (in casu, Since binary compatibility mistakes can tank whole releases, I'd like a second opinion from the others in @scala/team-core-scala |
Since the 2.11.6 deadline is extremely nigh, I've tentatively postponed this PR (along with other recent ones) to 2.11.7. I'll make a pass through reviewed 2.11.7 PRs on Friday and move them back to 2.11.6 where feasible. In the mean time, feel free to let me know if you'd like some help getting this reviewed by then. |
@adriaanm @scala/team-core-scala Any update on planning to merge this for |
FYI: I'll give binary compatibility thought today. |
A burnt child dreads the fire. Still, to me it looks good in terms of binary compatibility. |
I also we are fine here when it comes to binary compatibility. |
I'll adopt this PR. Going to have a look at some jars in the wild to see if there are any dependencies we may have missed. |
It doesn't take much code to generate a problem: package scala.concurrent.impl
class AbPro extends AbstractPromise { def u = AbstractPromise.updater } But I guess people normally don't do that (or we don't support them doing that; that's not what we mean by "binary compatibility"), so otherwise it should be good. The optimizer doesn't seem to slurp anything untoward into the bytecode for concurrent.Promise. |
Indeed -- i was going to just grep for any mention of scala.concurrent.impl.AbstractPromise. If you still have those jars expanded, maybe that would be convenient for you to pick up? |
@adriaanm - I'm not sure where they went, actually. I think I might have copied them from a USB drive to /tmp, then lost the USB drive. I can do it anyway, though, if you'd like. (Might need to tell me the best incantation to grab the right jars from Maven.) |
Ok, no prob -- I'll look into it then. |
Closing in favor of the rebased & slightly reworked #4443. |
Since the work on
Future
performances,AbstractPromise
is usingUnsafe
breaking the ability forFuture
to be executed on GAE.At that time, @viktorklang suggested to implement a fallback in case
Unsafe
is not available.@carey proposed an implementation, but as far as I know he never created a pull request for it, so there it is.
Please comment if some improvement or changes are needed, so I could try to improve.
See SI-8362 for more details.