diff --git a/src/vm/jvm/runtime/org/raku/nqp/runtime/Intrinsics.java b/src/vm/jvm/runtime/org/raku/nqp/runtime/Intrinsics.java deleted file mode 100644 index 875255deb..000000000 --- a/src/vm/jvm/runtime/org/raku/nqp/runtime/Intrinsics.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.raku.nqp.runtime; - -import java.lang.reflect.Field; -import java.util.function.Consumer; -import java.util.function.Function; -import org.raku.nqp.runtime.ExceptionHandling; -import org.raku.nqp.runtime.ThreadContext; -import sun.misc.Unsafe; - -public class Intrinsics { - private static Unsafe unsafe; - - protected static synchronized Unsafe getUnsafe(ThreadContext tc) { - if (unsafe == null) - try { - Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); - theUnsafe.setAccessible(true); - unsafe = (Unsafe) theUnsafe.get(null); - theUnsafe.setAccessible(false); // Clean up after ourselves. - } - catch (Exception e) { - throw ExceptionHandling.dieInternal(tc, e); - } - finally { - return unsafe; - } - else - return unsafe; - } - - /** - * Map given the unsafe singleton. - */ - public static T butUnsafe(ThreadContext tc, Function f) { - return (T) f.apply(getUnsafe(tc)); - } - - /** - * Foreach given the unsafe singleton. - */ - public static void itsUnsafe(ThreadContext tc, Consumer f) { - f.accept(getUnsafe(tc)); - } -} - diff --git a/src/vm/jvm/runtime/org/raku/nqp/runtime/Ops.java b/src/vm/jvm/runtime/org/raku/nqp/runtime/Ops.java index e366f86cb..912496d5b 100644 --- a/src/vm/jvm/runtime/org/raku/nqp/runtime/Ops.java +++ b/src/vm/jvm/runtime/org/raku/nqp/runtime/Ops.java @@ -14,6 +14,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; +import java.lang.invoke.VarHandle; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; @@ -6039,7 +6040,7 @@ public static SixModelObject atomicbindattr(SixModelObject obj, SixModelObject c return value; } public static SixModelObject barrierfull(ThreadContext tc) { - Intrinsics.itsUnsafe(tc, (unsafe) -> { unsafe.fullFence(); }); + VarHandle.fullFence(); return createNull(tc); } diff --git a/src/vm/jvm/runtime/org/raku/nqp/sixmodel/SixModelObject.java b/src/vm/jvm/runtime/org/raku/nqp/sixmodel/SixModelObject.java index ba399ccc5..b12abd361 100644 --- a/src/vm/jvm/runtime/org/raku/nqp/sixmodel/SixModelObject.java +++ b/src/vm/jvm/runtime/org/raku/nqp/sixmodel/SixModelObject.java @@ -33,25 +33,28 @@ public SixModelObject get_attribute_boxed(ThreadContext tc, SixModelObject class public void get_attribute_native(ThreadContext tc, SixModelObject class_handle, String name, long hint) { throw ExceptionHandling.dieInternal(tc, this.st.REPR.name + " representation does not support natively typed attributes"); } - public void bind_attribute_boxed(ThreadContext tc,SixModelObject class_handle, + public void bind_attribute_boxed(ThreadContext tc, SixModelObject class_handle, String name, long hint, SixModelObject value) { throw ExceptionHandling.dieInternal(tc, this.st.REPR.name + " representation does not support attributes"); } - public void bind_attribute_native(ThreadContext tc,SixModelObject class_handle, String name, long hint) { + public void bind_attribute_native(ThreadContext tc, SixModelObject class_handle, String name, long hint) { throw ExceptionHandling.dieInternal(tc, this.st.REPR.name + " representation does not support natively typed attributes"); } public long is_attribute_initialized(ThreadContext tc, SixModelObject class_handle, String name, long hint) { throw ExceptionHandling.dieInternal(tc, this.st.REPR.name + " representation does not support attributes"); } - public SixModelObject cas_attribute_boxed(ThreadContext tc,SixModelObject class_handle, + public SixModelObject cas_attribute_boxed(ThreadContext tc, SixModelObject class_handle, String name, SixModelObject expected, SixModelObject value) { throw ExceptionHandling.dieInternal(tc, this.st.REPR.name + " representation does not support cas of attributes"); } - public void atomic_bind_attribute_boxed(ThreadContext tc,SixModelObject class_handle, + public void atomic_bind_attribute_boxed(ThreadContext tc, SixModelObject class_handle, String name, SixModelObject value) { throw ExceptionHandling.dieInternal(tc, this.st.REPR.name + " representation does not support atomic binding to attributes"); } + public SixModelObject atomic_load_attribute_boxed(ThreadContext tc, SixModelObject class_handle, String name) { + throw ExceptionHandling.dieInternal(tc, this.st.REPR.name + " representation does not support atomic loading of attributes"); + } /** * Boxing related functions. diff --git a/src/vm/jvm/runtime/org/raku/nqp/sixmodel/reprs/P6OpaqueBaseInstance.java b/src/vm/jvm/runtime/org/raku/nqp/sixmodel/reprs/P6OpaqueBaseInstance.java index b34f465a4..ffc5581c0 100644 --- a/src/vm/jvm/runtime/org/raku/nqp/sixmodel/reprs/P6OpaqueBaseInstance.java +++ b/src/vm/jvm/runtime/org/raku/nqp/sixmodel/reprs/P6OpaqueBaseInstance.java @@ -1,6 +1,8 @@ package org.raku.nqp.sixmodel.reprs; + +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; import org.raku.nqp.runtime.ExceptionHandling; -import org.raku.nqp.runtime.Intrinsics; import org.raku.nqp.runtime.Ops; import org.raku.nqp.runtime.ThreadContext; import org.raku.nqp.sixmodel.STable; @@ -115,41 +117,53 @@ public long is_attribute_initialized(ThreadContext tc, SixModelObject class_hand return super.is_attribute_initialized(tc, class_handle, name, hint); } - private long scalarValueOffset; - @Override public SixModelObject cas_attribute_boxed(ThreadContext tc, SixModelObject class_handle, String name, SixModelObject expected, SixModelObject value) { - return Intrinsics.butUnsafe(tc, (unsafe) -> { - try { - long offset = unsafe.objectFieldOffset(this.getClass().getDeclaredField( - "field_" + resolveAttribute(class_handle, name))); - return unsafe.compareAndSwapObject(this, offset, expected, value) - ? expected - : (SixModelObject)unsafe.getObjectVolatile(this, offset); - } - catch (Exception e) { - throw ExceptionHandling.dieInternal(tc, e); - } - finally { - return Ops.createNull(tc); - } - }); + SixModelObject result = null; + try { + String attribute = "field_" + resolveAttribute(class_handle, name); + VarHandle variable = MethodHandles.lookup().in(this.getClass()) + .findVarHandle(this.getClass(), attribute, SixModelObject.class); + result = (SixModelObject)variable.compareAndExchange(this, expected, value); + } + catch (Exception e) { + throw ExceptionHandling.dieInternal(tc, e); + } + finally { + return result == null ? Ops.createNull(tc) : result; + } } @Override public void atomic_bind_attribute_boxed(ThreadContext tc, SixModelObject class_handle, String name, SixModelObject value) { - Intrinsics.itsUnsafe(tc, (unsafe) -> { - try { - long offset = unsafe.objectFieldOffset(this.getClass().getDeclaredField( - "field_" + resolveAttribute(class_handle, name))); - unsafe.putObjectVolatile(this, offset, value); - } - catch (Exception e) { - throw ExceptionHandling.dieInternal(tc, e); - } - }); + try { + String attribute = "field_" + resolveAttribute(class_handle, name); + VarHandle variable = MethodHandles.lookup().in(this.getClass()) + .findVarHandle(this.getClass(), attribute, SixModelObject.class); + variable.setRelease(this, value); + } + catch (Exception e) { + throw ExceptionHandling.dieInternal(tc, e); + } + } + + @Override + public SixModelObject atomic_load_attribute_boxed(ThreadContext tc, SixModelObject class_handle, String name) { + SixModelObject result = null; + try { + String attribute = "field_" + resolveAttribute(class_handle, name); + VarHandle variable = MethodHandles.lookup().in(this.getClass()) + .findVarHandle(this.getClass(), attribute, SixModelObject.class); + result = (SixModelObject)variable.getAcquire(this); + } + catch (Exception e) { + throw ExceptionHandling.dieInternal(tc, e); + } + finally { + return result == null ? Ops.createNull(tc) : result; + } } public SixModelObject posDelegate() {