-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
…private fields.
- 9.4.12.0
- 9.4.11.0
- 9.4.10.0
- 9.4.9.0
- 9.4.8.0
- 9.4.7.0
- 9.4.6.0
- 9.4.5.0
- 9.4.4.0
- 9.4.3.0
- 9.4.2.0
- 9.4.1.0
- 9.4.0.0
- 9.3.15.0
- 9.3.14.0
- 9.3.13.0
- 9.3.12.0
- 9.3.11.0
- 9.3.10.0
- 9.3.9.0
- 9.3.8.0
- 9.3.7.0
- 9.3.6.0
- 9.3.5.0
- 9.3.4.0
- 9.3.3.0
- 9.3.2.0
- 9.3.1.0
- 9.3.0.0
- 9.2.21.0
- 9.2.20.1
- 9.2.20.0
- 9.2.19.0
- 9.2.18.0
- 9.2.17.0
- 9.2.16.0
- 9.2.15.0
- 9.2.14.0
- 9.2.13.0
- 9.2.12.0
- 9.2.11.1
- 9.2.11.0
- 9.2.10.0
- 9.2.9.0
- 9.2.8.0
- 9.2.7.0
- 9.2.6.0
- 9.2.5.0
- 9.2.4.1
- 9.2.4.0
- 9.2.3.0
- 9.2.2.0
- 9.2.1.0
- 9.2.0.0
- 9.1.17.0
- 9.1.16.0
- 9.1.15.0
- 9.1.14.0
- 9.1.13.0
- 9.1.12.0
- 9.1.11.0
- 9.1.10.0
- 9.1.9.0
- 9.1.8.0
- 9.1.7.0
- 9.1.6.0
- 9.1.5.0
- 9.1.4.0
- 9.1.3.0
- 9.1.2.0
- 9.1.1.0
- 9.1.0.0
- 9.0.5.0
- 9.0.4.0
- 9.0.3.0
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,15 +17,17 @@ | |
import com.oracle.truffle.api.dsl.Specialization; | ||
import com.oracle.truffle.api.object.DynamicObject; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
|
||
import org.jruby.runtime.Visibility; | ||
import org.jruby.truffle.nodes.RubyNode; | ||
import org.jruby.truffle.nodes.cast.BooleanCastWithDefaultNodeGen; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.control.RaiseException; | ||
import org.jruby.truffle.runtime.layouts.Layouts; | ||
import org.jruby.truffle.runtime.subsystems.ThreadManager.BlockingAction; | ||
import org.jruby.util.unsafe.UnsafeHolder; | ||
import org.jruby.truffle.runtime.util.MethodHandleUtils; | ||
|
||
import java.lang.invoke.MethodHandle; | ||
import java.util.concurrent.BlockingQueue; | ||
import java.util.concurrent.LinkedBlockingQueue; | ||
import java.util.concurrent.TimeUnit; | ||
|
@@ -230,21 +232,27 @@ public Object marshal_dump(DynamicObject self) { | |
@CoreMethod(names = "num_waiting") | ||
public abstract static class NumWaitingNode extends CoreMethodArrayArgumentsNode { | ||
|
||
private static final long LOCK_FIELD_OFFSET = UnsafeHolder.fieldOffset(LinkedBlockingQueue.class, "takeLock"); | ||
private static final long NOT_EMPTY_CONDITION_FIELD_OFFSET = UnsafeHolder.fieldOffset(LinkedBlockingQueue.class, "notEmpty"); | ||
private static final MethodHandle TAKE_LOCK_FIELD_GETTER = MethodHandleUtils.getPrivateGetter(LinkedBlockingQueue.class, "takeLock"); | ||
private static final MethodHandle NOT_EMPTY_CONDITION_FIELD_GETTER = MethodHandleUtils.getPrivateGetter(LinkedBlockingQueue.class, "notEmpty"); | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
eregon
Author
Member
|
||
|
||
public NumWaitingNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
} | ||
|
||
@SuppressWarnings("restriction") | ||
@Specialization | ||
public int num_waiting(DynamicObject self) { | ||
final BlockingQueue<Object> queue = Layouts.QUEUE.getQueue(self); | ||
|
||
final LinkedBlockingQueue<Object> linkedBlockingQueue = (LinkedBlockingQueue<Object>) queue; | ||
final ReentrantLock lock = (ReentrantLock) UnsafeHolder.U.getObject(linkedBlockingQueue, LOCK_FIELD_OFFSET); | ||
final Condition notEmptyCondition = (Condition) UnsafeHolder.U.getObject(linkedBlockingQueue, NOT_EMPTY_CONDITION_FIELD_OFFSET); | ||
|
||
final ReentrantLock lock; | ||
final Condition notEmptyCondition; | ||
try { | ||
lock = (ReentrantLock) TAKE_LOCK_FIELD_GETTER.invokeExact(linkedBlockingQueue); | ||
notEmptyCondition = (Condition) NOT_EMPTY_CONDITION_FIELD_GETTER.invokeExact(linkedBlockingQueue); | ||
} catch (Throwable e) { | ||
throw new RuntimeException(e); | ||
} | ||
|
||
getContext().getThreadManager().runUntilResult(this, new BlockingAction<Boolean>() { | ||
@Override | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This | ||
* code is released under a tri EPL/GPL/LGPL license. You can use it, | ||
* redistribute it and/or modify it under the terms of the: | ||
* | ||
* Eclipse Public License version 1.0 | ||
* GNU General Public License version 2 | ||
* GNU Lesser General Public License version 2.1 | ||
*/ | ||
package org.jruby.truffle.runtime.util; | ||
|
||
import java.lang.invoke.MethodHandle; | ||
import java.lang.invoke.MethodHandles; | ||
import java.lang.reflect.Field; | ||
import java.security.AccessController; | ||
import java.security.PrivilegedAction; | ||
|
||
public abstract class MethodHandleUtils { | ||
|
||
public static MethodHandle getPrivateGetter(Class<?> klass, String fieldName) { | ||
final Field field = getPrivateField(klass, fieldName); | ||
try { | ||
return MethodHandles.lookup().unreflectGetter(field); | ||
} catch (IllegalAccessException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
public static MethodHandle getPrivateSetter(final Class<?> klass, final String fieldName) { | ||
final Field field = getPrivateField(klass, fieldName); | ||
try { | ||
return MethodHandles.lookup().unreflectSetter(field); | ||
} catch (IllegalAccessException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
private static Field getPrivateField(final Class<?> klass, final String fieldName) { | ||
return AccessController.doPrivileged(new PrivilegedAction<Field>() { | ||
This comment has been minimized.
Sorry, something went wrong.
nirvdrum
Contributor
|
||
@Override | ||
public Field run() { | ||
final Field field; | ||
try { | ||
field = klass.getDeclaredField(fieldName); | ||
field.setAccessible(true); | ||
return field; | ||
} catch (NoSuchFieldException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
} |
Is there no better way to do this? I'm trying to limit use of things like unsafe and reflection where possible for a cleaner implementation.