diff graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java @ 11898:f753092f608d

Adjustments to unsafe access and unsafe cast compiler directives in Truffle API.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sun, 06 Oct 2013 15:36:12 +0200
parents 992508ee13b6
children 139b84d713bc
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Sat Oct 05 15:01:01 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Sun Oct 06 15:36:12 2013 +0200
@@ -25,13 +25,16 @@
 package com.oracle.truffle.api;
 
 import java.lang.annotation.*;
+import java.lang.reflect.*;
 import java.util.concurrent.*;
 
+import sun.misc.*;
+
 /**
  * Directives that influence the optimizations of the Truffle compiler. All of the operations have
  * no effect when executed in the Truffle interpreter.
  */
-public class CompilerDirectives {
+public final class CompilerDirectives {
 
     public static final double LIKELY_PROBABILITY = 0.75;
     public static final double UNLIKELY_PROBABILITY = 1.0 - LIKELY_PROBABILITY;
@@ -39,6 +42,22 @@
     public static final double SLOWPATH_PROBABILITY = 0.0001;
     public static final double FASTPATH_PROBABILITY = 1.0 - SLOWPATH_PROBABILITY;
 
+    private static final Unsafe UNSAFE = getUnsafe();
+
+    private static Unsafe getUnsafe() {
+        try {
+            return Unsafe.getUnsafe();
+        } catch (SecurityException e) {
+        }
+        try {
+            Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
+            theUnsafeInstance.setAccessible(true);
+            return (Unsafe) theUnsafeInstance.get(Unsafe.class);
+        } catch (Exception e) {
+            throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e);
+        }
+    }
+
     /**
      * Directive for the compiler to discontinue compilation at this code position and instead
      * insert a transfer to the interpreter.
@@ -130,72 +149,275 @@
     }
 
     /**
-     * Marks methods that are considered unsafe. Wrong usage of those methods can lead to unexpected
-     * behavior including a crash of the runtime. Therefore, special care should be taken.
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target({ElementType.METHOD})
-    public @interface Unsafe {
-    }
-
-    /**
-     * Treats the given value as a value of the given class. The class must evaluate to a constant.
+     * Casts the given value to the value of the given type without any checks. The class must
+     * evaluate to a constant. The condition parameter gives a hint to the compiler under which
+     * circumstances this cast can be moved to an earlier location in the program.
      * 
      * @param value the value that is known to have the specified type
-     * @param clazz the specified type of the value
-     * @return the value
-     */
-    @Unsafe
-    public static <T> T unsafeCast(Object value, Class<T> clazz) {
-        return unsafeCast(value, clazz, null, null);
-    }
-
-    /**
-     * Associates the given type token with the given value for the case that condition is true.
-     * 
-     * @param condition the custom type check
-     * @param value the value that is of the given custom type after the check
-     * @param customType the custom type that should be associated with the value
-     * @return the type check condition
-     */
-    public static boolean customTypeCheck(boolean condition, Object value, Object customType) {
-        return condition;
-    }
-
-    /**
-     * Treats the given value as a value of the given class. The class must evaluate to a constant.
-     * If the compiler can prove that the given value is of the given custom type, the cast is safe.
-     * 
-     * @param value the value that is known to have the specified type
-     * @param clazz the specified type of the value
-     * @param receiver the receiver on which the custom type is tested
-     * @param customType the custom type that if present on a value makes this unsafe cast safe
-     * @return the value
+     * @param type the specified new type of the value
+     * @param condition the condition that makes this cast safe also at an earlier location of the
+     *            program
+     * @return the value to be casted to the new type
      */
     @SuppressWarnings("unchecked")
-    @Unsafe
-    public static <T> T unsafeCast(Object value, Class<T> clazz, Object receiver, Object customType) {
+    public static <T> T unsafeCast(Object value, Class<T> type, boolean condition) {
         return (T) value;
     }
 
     /**
-     * Proxies an object instance into an instance that adds a custom location identity on its
-     * accesses via sun.misc.Unsafe. This means that the accesses on these kind of location
-     * identities can only alias among themselves. It also allows to specify a custom type for the
-     * receiver values of follow-up unsafe accesses. Both the custom type and the location identity
-     * must evaluate to a constant. Furthermore, you should use the proxied receiver object
-     * immediately for one read or write access via a sun.misc.Unsafe method and not store it
-     * anywhere.
+     * Unsafe access to a boolean value within an object. The condition parameter gives a hint to
+     * the compiler under which circumstances this access can be moved to an earlier location in the
+     * program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static boolean unsafeGetBoolean(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getBoolean(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a byte value within an object. The condition parameter gives a hint to the
+     * compiler under which circumstances this access can be moved to an earlier location in the
+     * program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static byte unsafeGetByte(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getByte(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a short value within an object. The condition parameter gives a hint to the
+     * compiler under which circumstances this access can be moved to an earlier location in the
+     * program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static short unsafeGetShort(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getShort(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a int value within an object. The condition parameter gives a hint to the
+     * compiler under which circumstances this access can be moved to an earlier location in the
+     * program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
      * 
-     * @param receiver the object that is accessed via sun.misc.Unsafe
-     * @param condition the condition that ifTrue allows this unsafe access to be floating
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getInt(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a long value within an object. The condition parameter gives a hint to the
+     * compiler under which circumstances this access can be moved to an earlier location in the
+     * program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static long unsafeGetLong(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getLong(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a float value within an object. The condition parameter gives a hint to the
+     * compiler under which circumstances this access can be moved to an earlier location in the
+     * program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getFloat(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a double value within an object. The condition parameter gives a hint to the
+     * compiler under which circumstances this access can be moved to an earlier location in the
+     * program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
      * @param locationIdentity the location identity token that can be used for improved global
      *            value numbering or null
      * @return the accessed value
      */
-    @Unsafe
-    public static Object unsafeCustomization(Object receiver, boolean condition, Object locationIdentity) {
-        return receiver;
+    public static double unsafeGetDouble(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getDouble(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a Object value within an object. The condition parameter gives a hint to the
+     * compiler under which circumstances this access can be moved to an earlier location in the
+     * program. The location identity gives a hint to the compiler for improved global value
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static Object unsafeGetObject(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getObject(receiver, offset);
+    }
+
+    /**
+     * Write a boolean value within an object. The location identity gives a hint to the compiler
+     * for improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutBoolean(Object receiver, long offset, boolean value, Object locationIdentity) {
+        UNSAFE.putBoolean(receiver, offset, value);
+    }
+
+    /**
+     * Write a byte value within an object. The location identity gives a hint to the compiler for
+     * improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutByte(Object receiver, long offset, byte value, Object locationIdentity) {
+        UNSAFE.putByte(receiver, offset, value);
+    }
+
+    /**
+     * Write a short value within an object. The location identity gives a hint to the compiler for
+     * improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutShort(Object receiver, long offset, short value, Object locationIdentity) {
+        UNSAFE.putShort(receiver, offset, value);
+    }
+
+    /**
+     * Write a int value within an object. The location identity gives a hint to the compiler for
+     * improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutInt(Object receiver, long offset, int value, Object locationIdentity) {
+        UNSAFE.putInt(receiver, offset, value);
+    }
+
+    /**
+     * Write a long value within an object. The location identity gives a hint to the compiler for
+     * improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutLong(Object receiver, long offset, long value, Object locationIdentity) {
+        UNSAFE.putLong(receiver, offset, value);
+    }
+
+    /**
+     * Write a float value within an object. The location identity gives a hint to the compiler for
+     * improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutFloat(Object receiver, long offset, float value, Object locationIdentity) {
+        UNSAFE.putFloat(receiver, offset, value);
+    }
+
+    /**
+     * Write a double value within an object. The location identity gives a hint to the compiler for
+     * improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutDouble(Object receiver, long offset, double value, Object locationIdentity) {
+        UNSAFE.putDouble(receiver, offset, value);
+    }
+
+    /**
+     * Write a Object value within an object. The location identity gives a hint to the compiler for
+     * improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity) {
+        UNSAFE.putObject(receiver, offset, value);
     }
 
     /**