diff graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java @ 14629:ba52fbec5b6c

Truffle: atomic node rewriting make Node#replace thread-safe add Node#atomic helper method for atomic tree operations add basic test for thread-safety
author Andreas Woess <andreas.woess@jku.at>
date Thu, 20 Mar 2014 01:29:19 +0100
parents a08b8694f556
children 64dcb92ee75a
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Wed Mar 19 23:11:46 2014 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Thu Mar 20 01:29:19 2014 +0100
@@ -27,6 +27,7 @@
 import java.io.*;
 import java.lang.annotation.*;
 import java.util.*;
+import java.util.concurrent.*;
 
 import com.oracle.truffle.api.*;
 
@@ -251,7 +252,11 @@
      */
     public final <T extends Node> T replace(final T newNode, final CharSequence reason) {
         CompilerDirectives.transferToInterpreterAndInvalidate();
-        replaceHelper(newNode, reason);
+        atomic(new Runnable() {
+            public void run() {
+                replaceHelper(newNode, reason);
+            }
+        });
         return newNode;
     }
 
@@ -478,4 +483,32 @@
         sb.append("@").append(Integer.toHexString(hashCode()));
         return sb.toString();
     }
+
+    public final void atomic(Runnable closure) {
+        RootNode rootNode = getRootNode();
+        if (rootNode != null) {
+            synchronized (rootNode) {
+                closure.run();
+            }
+        } else {
+            closure.run();
+        }
+    }
+
+    public final <T> T atomic(Callable<T> closure) {
+        try {
+            RootNode rootNode = getRootNode();
+            if (rootNode != null) {
+                synchronized (rootNode) {
+                    return closure.call();
+                }
+            } else {
+                return closure.call();
+            }
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
 }