changeset 18510:cb4d5cc2b52b

Truffle: clone ConditionProfile and BranchProfile node fields
author Andreas Woess <andreas.woess@jku.at>
date Tue, 25 Nov 2014 13:21:50 +0100
parents 7bf2965140de
children 62aac33db669
files graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeCloneable.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BranchProfile.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ConditionProfile.java
diffstat 4 files changed, 64 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeCloneable.java	Tue Nov 25 13:21:50 2014 +0100
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.nodes;
+
+/**
+ * Declarative interface for node fields that are to be cloned together with the containing node.
+ */
+public interface NodeCloneable extends Cloneable {
+    public Object clone();
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Tue Nov 25 13:21:38 2014 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Tue Nov 25 13:21:50 2014 +0100
@@ -179,6 +179,7 @@
         private final long parentOffset;
         private final long[] childOffsets;
         private final long[] childrenOffsets;
+        private final long[] cloneableOffsets;
         private final Class<? extends Node> clazz;
 
         public static NodeClass get(Class<? extends Node> clazz) {
@@ -190,6 +191,7 @@
             long parentFieldOffset = -1;
             List<Long> childOffsetsList = new ArrayList<>();
             List<Long> childrenOffsetsList = new ArrayList<>();
+            List<Long> cloneableOffsetsList = new ArrayList<>();
 
             for (Field field : getAllFields(clazz)) {
                 if (Modifier.isStatic(field.getModifiers()) || field.isSynthetic()) {
@@ -209,6 +211,9 @@
                     checkChildrenField(field);
                     kind = NodeFieldKind.CHILDREN;
                     childrenOffsetsList.add(fieldOffsetProvider.objectFieldOffset(field));
+                } else if (NodeCloneable.class.isAssignableFrom(field.getType())) {
+                    kind = NodeFieldKind.DATA;
+                    cloneableOffsetsList.add(fieldOffsetProvider.objectFieldOffset(field));
                 } else {
                     kind = NodeFieldKind.DATA;
                 }
@@ -223,6 +228,7 @@
             this.parentOffset = parentFieldOffset;
             this.childOffsets = toLongArray(childOffsetsList);
             this.childrenOffsets = toLongArray(childrenOffsetsList);
+            this.cloneableOffsets = toLongArray(cloneableOffsetsList);
             this.clazz = clazz;
         }
 
@@ -471,6 +477,12 @@
                 unsafe.putObject(clone, fieldOffset, clonedChildren);
             }
         }
+        for (long fieldOffset : nodeClass.cloneableOffsets) {
+            Object cloneable = unsafe.getObject(clone, fieldOffset);
+            if (cloneable != null && cloneable == unsafe.getObject(orig, fieldOffset)) {
+                unsafe.putObject(clone, fieldOffset, ((NodeCloneable) cloneable).clone());
+            }
+        }
         return (T) clone;
     }
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BranchProfile.java	Tue Nov 25 13:21:38 2014 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BranchProfile.java	Tue Nov 25 13:21:50 2014 +0100
@@ -26,6 +26,7 @@
 
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.nodes.*;
 
 /**
  * Utility class to speculate on branches to be never visited. If the {@link #enter()} method is
@@ -36,7 +37,7 @@
  * All {@code BranchProfile} instances must be held in {@code final} fields for compiler
  * optimizations to take effect.
  */
-public final class BranchProfile {
+public final class BranchProfile implements NodeCloneable {
 
     @CompilationFinal private boolean visited;
 
@@ -63,4 +64,12 @@
         return String.format("%s(%s)@%x", getClass().getSimpleName(), visited ? "visited" : "not-visited", hashCode());
     }
 
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new AssertionError(e);
+        }
+    }
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ConditionProfile.java	Tue Nov 25 13:21:38 2014 +0100
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ConditionProfile.java	Tue Nov 25 13:21:50 2014 +0100
@@ -25,6 +25,7 @@
 package com.oracle.truffle.api.utilities;
 
 import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.nodes.*;
 
 /**
  * Abstract utility class to speculate on conditions. Condition profiles are intended to be used as
@@ -50,7 +51,7 @@
  * @see #createCountingProfile()
  * @see #createBinaryProfile()
  */
-public abstract class ConditionProfile {
+public abstract class ConditionProfile implements NodeCloneable {
 
     public abstract boolean profile(boolean value);
 
@@ -80,4 +81,12 @@
         return new BinaryConditionProfile();
     }
 
+    @Override
+    public final Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new AssertionError(e);
+        }
+    }
 }