changeset 17252:1680a4ddc2a7

Truffle-DSL: added thread-safety for DSL rewrites.
author Christian Humer <christian.humer@gmail.com>
date Mon, 29 Sep 2014 18:39:05 +0200
parents 6ee7afea175a
children b8611b23c4f8
files graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/DSLShare.java
diffstat 1 files changed, 53 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/DSLShare.java	Mon Sep 29 18:37:24 2014 +0200
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/internal/DSLShare.java	Mon Sep 29 18:39:05 2014 +0200
@@ -25,6 +25,7 @@
 package com.oracle.truffle.api.dsl.internal;
 
 import java.util.*;
+import java.util.concurrent.*;
 
 import com.oracle.truffle.api.nodes.*;
 
@@ -50,19 +51,23 @@
         return containsClass(newNode.getMetadata0().getIncludes(), oldNode);
     }
 
-    public static <T extends Node & DSLNode> T rewrite(Node thisNode, T newNode, String message) {
-        assert newNode != null;
-        if (getNext(thisNode) != null || getPrevious(thisNode) != null) {
-            // already polymorphic -> append
-            return appendPolymorphic(findUninitialized(thisNode), newNode);
-        } else if (includes(thisNode, newNode)) {
-            // included -> remains monomorphic
-            newNode.adoptChildren0(thisNode, null);
-            return thisNode.replace(newNode, message);
-        } else {
-            // goto polymorphic
-            return null;
-        }
+    public static <T extends Node & DSLNode> T rewrite(final Node thisNode, final T newNode, final String message) {
+        return thisNode.atomic(new Callable<T>() {
+            public T call() {
+                assert newNode != null;
+                if (getNext(thisNode) != null || getPrevious(thisNode) != null) {
+                    // already polymorphic -> append
+                    return appendPolymorphic(findUninitialized(thisNode), newNode);
+                } else if (includes(thisNode, newNode)) {
+                    // included -> remains monomorphic
+                    newNode.adoptChildren0(thisNode, null);
+                    return thisNode.replace(newNode, message);
+                } else {
+                    // goto polymorphic
+                    return null;
+                }
+            }
+        });
     }
 
     @SuppressWarnings("unchecked")
@@ -86,37 +91,47 @@
         return cur;
     }
 
-    public static <T extends Node & DSLNode> T rewriteUninitialized(Node uninitialized, T newNode) {
-        Node prev = getPrevious(uninitialized);
-        if (prev == null) {
-            newNode.adoptChildren0(uninitialized, null);
-            return uninitialized.replace(newNode, "Uninitialized monomorphic");
-        } else {
-            return appendPolymorphic(uninitialized, newNode);
-        }
+    public static <T extends Node & DSLNode> T rewriteUninitialized(final Node uninitialized, final T newNode) {
+        return uninitialized.atomic(new Callable<T>() {
+            public T call() {
+                Node prev = getPrevious(uninitialized);
+                if (prev == null) {
+                    newNode.adoptChildren0(uninitialized, null);
+                    return uninitialized.replace(newNode, "Uninitialized monomorphic");
+                } else {
+                    return appendPolymorphic(uninitialized, newNode);
+                }
+            }
+        });
+
     }
 
-    public static <T extends Node & DSLNode> T rewriteToPolymorphic(Node oldNode, DSLNode uninitializedDSL, T polymorphic, DSLNode currentCopy, DSLNode newNodeDSL, String message) {
-        assert getNext(oldNode) == null;
-        assert getPrevious(oldNode) == null;
-        assert newNodeDSL != null;
+    public static <T extends Node & DSLNode> T rewriteToPolymorphic(final Node oldNode, final DSLNode uninitializedDSL, final T polymorphic, final DSLNode currentCopy, final DSLNode newNodeDSL,
+                    final String message) {
+        return oldNode.atomic(new Callable<T>() {
+            public T call() {
+                assert getNext(oldNode) == null;
+                assert getPrevious(oldNode) == null;
+                assert newNodeDSL != null;
 
-        Node uninitialized = (Node) uninitializedDSL;
-        Node newNode = (Node) newNodeDSL;
-        polymorphic.adoptChildren0(oldNode, (Node) currentCopy);
+                Node uninitialized = (Node) uninitializedDSL;
+                Node newNode = (Node) newNodeDSL;
+                polymorphic.adoptChildren0(oldNode, (Node) currentCopy);
 
-        updateSourceSection(oldNode, uninitialized);
-        // new specialization
-        updateSourceSection(oldNode, newNode);
-        newNodeDSL.adoptChildren0(null, uninitialized);
-        currentCopy.adoptChildren0(null, newNode);
+                updateSourceSection(oldNode, uninitialized);
+                // new specialization
+                updateSourceSection(oldNode, newNode);
+                newNodeDSL.adoptChildren0(null, uninitialized);
+                currentCopy.adoptChildren0(null, newNode);
 
-        oldNode.replace(polymorphic, message);
+                oldNode.replace(polymorphic, message);
 
-        assert polymorphic.getNext0() == currentCopy;
-        assert newNode != null ? currentCopy.getNext0() == newNode : currentCopy.getNext0() == uninitialized;
-        assert uninitializedDSL.getNext0() == null;
-        return polymorphic;
+                assert polymorphic.getNext0() == currentCopy;
+                assert newNode != null ? currentCopy.getNext0() == newNode : currentCopy.getNext0() == uninitialized;
+                assert uninitializedDSL.getNext0() == null;
+                return polymorphic;
+            }
+        });
     }
 
     private static void updateSourceSection(Node oldNode, Node newNode) {