RFR 8160710: Enable Thread to grant VarHandle field access to ThreadLocalRandom/Striped64
Martin Buchholz
martinrb at google.com
Wed Jan 11 23:39:52 UTC 2017
Doug, please try to remember the details of the thread group code.
On Wed, Jan 11, 2017 at 3:13 PM, Paul Sandoz <paul.sandoz at oracle.com> wrote:
>
> > On 11 Jan 2017, at 14:00, Martin Buchholz <martinrb at google.com> wrote:
>
> > Our inline assignment style is non-standard, but we like it and it saves
> a byte of bytecode occasionally, making things a tiny bit easier for the
> JIT.
> >
>
> Are you referring to cases like:
>
> 964 int r = (int) SECONDARY.get(t);
> 965 if (r != 0) {
>
> ?
>
> I moved it out to make it clearer on the cast, but i can inline it as you
> prefer.
>
>
Yes. jsr166 style is to inline, even though we don't recommend it for
regular java code.
> ---
> >
> > The threadgroup creation code that uses cheating has always seemed fishy
> to me. The straightforward
> >
> > /**
> > * Returns a new group with the system ThreadGroup (the
> > * topmost, parent-less group) as parent.
> > */
> > static final ThreadGroup createThreadGroup(String name) {
> > if (name == null)
> > throw new NullPointerException();
> > ThreadGroup group = Thread.currentThread().getThreadGroup();
> > for (ThreadGroup p; (p = group.getParent()) != null; )
> > group = p;
> > return new ThreadGroup(group, name);
> > }
> >
> > passes all tests. That could be wrapped in a doPrivileged, or we could
> add something more principled to ThreadGroup itself. I don't know what the
> motivations are for the threadgroup code.
> >
>
> Good point, me neither, nor the association with TLR (perhaps because
> there are over methods used by InnocuousForkJoinWorkerThread, see below).
> The Unsafe usage rolled in with:
>
> https://bugs.openjdk.java.net/browse/JDK-8157523
> http://hg.openjdk.java.net/jdk9/dev/jdk/rev/fd4819ec5afd
>
>
> In ForkJoinWorkerThread:
>
> static final class InnocuousForkJoinWorkerThread extends
> ForkJoinWorkerThread {
> /** The ThreadGroup for all InnocuousForkJoinWorkerThreads */
> private static final ThreadGroup innocuousThreadGroup =
> ThreadLocalRandom.createThreadGroup("
> InnocuousForkJoinWorkerThreadGroup”);
>
>
> In ForkJoinPool:
>
> private ForkJoinPool(byte forCommonPoolOnly) {
> ...
> ForkJoinWorkerThreadFactory fac = null;
> ...
> if (fac == null) {
> if (System.getSecurityManager() == null)
> fac = defaultForkJoinWorkerThreadFactory;
> else // use security-managed default
> fac = new InnocuousForkJoinWorkerThreadFactory();
> }
> …
>
>
> private static final class InnocuousForkJoinWorkerThreadFactory
> implements ForkJoinWorkerThreadFactory {
> ...
> public final ForkJoinWorkerThread newThread(ForkJoinPool pool) {
> return AccessController.doPrivileged(new PrivilegedAction<>() {
> public ForkJoinWorkerThread run() {
> return new ForkJoinWorkerThread.
> InnocuousForkJoinWorkerThread(pool);
> }}, INNOCUOUS_ACC);
> }
> }
>
>
> So everything is wrapped in a doPrivileged block.
>
> My guess as at some point in development it was important to efficiently
> bypass the security check of ThreadGroup.getParent, and Thread.getGroup
> came along for the ride.
>
> AFAICT I don’t think we need it, and it would be nice to remove the
> VarHandle code and move createThreadGroup to be a static method of
> InnocuousForkJoinWorkerThread. How about:
>
>
> static final class InnocuousForkJoinWorkerThread extends
> ForkJoinWorkerThread {
> /** The ThreadGroup for all InnocuousForkJoinWorkerThreads */
> private static final ThreadGroup innocuousThreadGroup =
> createThreadGroup();
> …
> private static ThreadGroup createThreadGroup() {
> ThreadGroup currentGroup = Thread.currentThread().
> getThreadGroup();
> ThreadGroup topGroup = java.security.
> AccessController.doPrivileged(
> new java.security.PrivilegedAction<ThreadGroup>() {
> public ThreadGroup run() {
> ThreadGroup group = currentGroup;
> for (ThreadGroup p; (p = group.getParent()) !=
> null; )
> group = p;
> return group;
> }});
> return new ThreadGroup(topGroup, "InnocuousForkJoinWorkerThreadG
> roup");
> }
> }
>
> That also passes the tests we have for the Innocuous case.
>
>
That seems good to me.
>
> > ---
> >
> > 431 // Teleport the lookup to access fields in Thread
> >
> > Teleport?! Maybe "Obtain a private lookup object" but that should be
> obvious from the name “privateLookupIn”
> >
>
> Yes, i removed the comments.
>
> Thanks,
> Paul.
>
>
> >
> > On Wed, Jan 11, 2017 at 12:21 PM, Paul Sandoz <paul.sandoz at oracle.com>
> wrote:
> > Hi,
> >
> > Please review:
> >
> > http://cr.openjdk.java.net/~psandoz/jdk9/8160710-thread-to-tlr/webrev/
> >
> > This patch updates ThreadLocalRandom, Striped64 and LockSupport to use
> VarHandles instead of Unsafe to access fields in Thread, via the
> MethodsHandles.privateLookupIn method.
> >
> > Since there are three usages of MethodsHandles.privateLookupIn in
> ThreadLocalRandom i consolidated the doPrivileged block in a private static
> helper method, being paranoid i placed some checks to avoid this method
> being potentially abused to circumvent the security check, perhaps that is
> overkill?
> >
> > I ran this patch though our test infra a few times and have not observed
> any transient failures.
> >
> > Thanks,
> > Paul.
> >
>
>
More information about the core-libs-dev
mailing list