diff graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java @ 9258:07f8d136a05e

Truffle API changes for the Frame API. Introduction of Assumptions class.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 23 Apr 2013 15:34:06 +0200
parents f07cafa29db1
children cd1a1d92b3e3
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java	Tue Apr 23 15:08:11 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java	Tue Apr 23 15:34:06 2013 +0200
@@ -24,30 +24,33 @@
 
 import java.util.*;
 
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.impl.*;
+
 /**
  * Descriptor of the slots of frame objects. Multiple frame instances are associated with one such
  * descriptor.
  */
-public final class FrameDescriptor {
+public final class FrameDescriptor implements Cloneable {
 
-    protected final TypeConversion typeConversion;
+    private final FrameTypeConversion typeConversion;
     private final ArrayList<FrameSlotImpl> slots;
-    private FrameVersionImpl lastVersion;
     private final HashMap<Object, FrameSlotImpl> identifierToSlotMap;
+    private Assumption version;
 
     public FrameDescriptor() {
-        this(DefaultTypeConversion.getInstance());
+        this(DefaultFrameTypeConversion.getInstance());
     }
 
-    public FrameDescriptor(TypeConversion typeConversion) {
+    public FrameDescriptor(FrameTypeConversion typeConversion) {
         this.typeConversion = typeConversion;
         slots = new ArrayList<>();
         identifierToSlotMap = new HashMap<>();
-        lastVersion = new FrameVersionImpl();
+        version = createVersion();
     }
 
     public FrameSlot addFrameSlot(Object identifier) {
-        return addFrameSlot(identifier, typeConversion.getTopType());
+        return addFrameSlot(identifier, null);
     }
 
     public FrameSlot addFrameSlot(Object identifier, Class<?> type) {
@@ -55,6 +58,7 @@
         FrameSlotImpl slot = new FrameSlotImpl(this, identifier, slots.size(), type);
         slots.add(slot);
         identifierToSlotMap.put(identifier, slot);
+        updateVersion();
         return slot;
     }
 
@@ -70,8 +74,12 @@
         return addFrameSlot(identifier);
     }
 
-    public FrameVersion getCurrentVersion() {
-        return lastVersion;
+    public FrameSlot findOrAddFrameSlot(Object identifier, Class<?> type) {
+        FrameSlot result = findFrameSlot(identifier);
+        if (result != null) {
+            return result;
+        }
+        return addFrameSlot(identifier, type);
     }
 
     public int getSize() {
@@ -82,121 +90,42 @@
         return Collections.unmodifiableList(slots);
     }
 
-    protected void appendVersion(FrameVersionImpl newVersion) {
-        lastVersion.next = newVersion;
-        lastVersion = newVersion;
-    }
-}
-
-class FrameVersionImpl implements FrameVersion {
-
-    protected FrameVersionImpl next;
-
-    @Override
-    public final FrameVersion getNext() {
-        return next;
-    }
-}
-
-class TypeChangeFrameVersionImpl extends FrameVersionImpl implements FrameVersion.TypeChange {
-
-    private final FrameSlotImpl slot;
-    private final Class<?> oldType;
-    private final Class<?> newType;
-
-    protected TypeChangeFrameVersionImpl(FrameSlotImpl slot, Class<?> oldType, Class<?> newType) {
-        this.slot = slot;
-        this.oldType = oldType;
-        this.newType = newType;
-    }
-
-    @Override
-    public final void applyTransformation(Frame frame) {
-        Object value = slot.getValue(oldType, frame);
-        slot.setValue(newType, frame, value);
-    }
-}
-
-class FrameSlotImpl implements FrameSlot {
-
-    private final FrameDescriptor descriptor;
-    private final Object identifier;
-    private final int index;
-    private Class<?> type;
-    private ArrayList<FrameSlotTypeListener> listeners;
-
-    protected FrameSlotImpl(FrameDescriptor descriptor, Object identifier, int index, Class<?> type) {
-        this.descriptor = descriptor;
-        this.identifier = identifier;
-        this.index = index;
-        this.type = type;
-        assert type != null;
-    }
-
-    public Object getIdentifier() {
-        return identifier;
-    }
-
-    public int getIndex() {
-        return index;
+    /**
+     * (db) to retrieve the list of all the identifiers associated with this frame descriptor.
+     * 
+     * @return the list of all the identifiers in this frame descriptor
+     */
+    public Set<Object> getIdentifiers() {
+        return Collections.unmodifiableSet(identifierToSlotMap.keySet());
     }
 
-    public Class<?> getType() {
-        return type;
-    }
-
-    protected Object getValue(Class<?> accessType, Frame frame) {
-        if (accessType == Integer.class) {
-            return frame.getInt(this);
-        } else if (accessType == Long.class) {
-            return frame.getLong(this);
-        } else if (accessType == Float.class) {
-            return frame.getFloat(this);
-        } else if (accessType == Double.class) {
-            return frame.getDouble(this);
-        } else {
-            return frame.getObject(this);
+    /**
+     * (db): this method is used for creating a clone of the {@link FrameDescriptor} object ready
+     * for parallel execution.
+     */
+    public FrameDescriptor copy() {
+        FrameDescriptor clonedFrameDescriptor = new FrameDescriptor(this.typeConversion);
+        for (int i = 0; i < this.getSlots().size(); i++) {
+            Object identifier = this.getSlots().get(i).getIdentifier();
+            clonedFrameDescriptor.addFrameSlot(identifier);
         }
+        return clonedFrameDescriptor;
     }
 
-    protected void setValue(Class<?> accessType, Frame frame, Object value) {
-        Object newValue = descriptor.typeConversion.convertTo(accessType, value);
-        if (accessType == Integer.class) {
-            frame.setInt(this, (Integer) newValue);
-        } else if (accessType == Long.class) {
-            frame.setLong(this, (Long) newValue);
-        } else if (accessType == Float.class) {
-            frame.setFloat(this, (Float) newValue);
-        } else if (accessType == Double.class) {
-            frame.setDouble(this, (Double) newValue);
-        } else {
-            frame.setObject(this, newValue);
-        }
+    void updateVersion() {
+        version.invalidate();
+        version = createVersion();
+    }
+
+    public Assumption getVersion() {
+        return version;
     }
 
-    public void setType(final Class<?> type) {
-        final Class<?> oldType = this.type;
-        this.type = type;
-        ArrayList<FrameSlotTypeListener> oldListeners = this.listeners;
-        this.listeners = null;
-        if (oldListeners != null) {
-            for (FrameSlotTypeListener listener : oldListeners) {
-                listener.typeChanged(this, oldType);
-            }
-        }
-        descriptor.appendVersion(new TypeChangeFrameVersionImpl(this, oldType, type));
+    private static Assumption createVersion() {
+        return Truffle.getRuntime().createAssumption("frame version");
     }
 
-    @Override
-    public String toString() {
-        return "[" + index + "," + identifier + "]";
-    }
-
-    @Override
-    public void registerOneShotTypeListener(FrameSlotTypeListener listener) {
-        if (listeners == null) {
-            listeners = new ArrayList<>();
-        }
-        listeners.add(listener);
+    public FrameTypeConversion getTypeConversion() {
+        return typeConversion;
     }
 }