comparison 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
comparison
equal deleted inserted replaced
9257:542712a4732a 9258:07f8d136a05e
22 */ 22 */
23 package com.oracle.truffle.api.frame; 23 package com.oracle.truffle.api.frame;
24 24
25 import java.util.*; 25 import java.util.*;
26 26
27 import com.oracle.truffle.api.*;
28 import com.oracle.truffle.api.impl.*;
29
27 /** 30 /**
28 * Descriptor of the slots of frame objects. Multiple frame instances are associated with one such 31 * Descriptor of the slots of frame objects. Multiple frame instances are associated with one such
29 * descriptor. 32 * descriptor.
30 */ 33 */
31 public final class FrameDescriptor { 34 public final class FrameDescriptor implements Cloneable {
32 35
33 protected final TypeConversion typeConversion; 36 private final FrameTypeConversion typeConversion;
34 private final ArrayList<FrameSlotImpl> slots; 37 private final ArrayList<FrameSlotImpl> slots;
35 private FrameVersionImpl lastVersion;
36 private final HashMap<Object, FrameSlotImpl> identifierToSlotMap; 38 private final HashMap<Object, FrameSlotImpl> identifierToSlotMap;
39 private Assumption version;
37 40
38 public FrameDescriptor() { 41 public FrameDescriptor() {
39 this(DefaultTypeConversion.getInstance()); 42 this(DefaultFrameTypeConversion.getInstance());
40 } 43 }
41 44
42 public FrameDescriptor(TypeConversion typeConversion) { 45 public FrameDescriptor(FrameTypeConversion typeConversion) {
43 this.typeConversion = typeConversion; 46 this.typeConversion = typeConversion;
44 slots = new ArrayList<>(); 47 slots = new ArrayList<>();
45 identifierToSlotMap = new HashMap<>(); 48 identifierToSlotMap = new HashMap<>();
46 lastVersion = new FrameVersionImpl(); 49 version = createVersion();
47 } 50 }
48 51
49 public FrameSlot addFrameSlot(Object identifier) { 52 public FrameSlot addFrameSlot(Object identifier) {
50 return addFrameSlot(identifier, typeConversion.getTopType()); 53 return addFrameSlot(identifier, null);
51 } 54 }
52 55
53 public FrameSlot addFrameSlot(Object identifier, Class<?> type) { 56 public FrameSlot addFrameSlot(Object identifier, Class<?> type) {
54 assert !identifierToSlotMap.containsKey(identifier); 57 assert !identifierToSlotMap.containsKey(identifier);
55 FrameSlotImpl slot = new FrameSlotImpl(this, identifier, slots.size(), type); 58 FrameSlotImpl slot = new FrameSlotImpl(this, identifier, slots.size(), type);
56 slots.add(slot); 59 slots.add(slot);
57 identifierToSlotMap.put(identifier, slot); 60 identifierToSlotMap.put(identifier, slot);
61 updateVersion();
58 return slot; 62 return slot;
59 } 63 }
60 64
61 public FrameSlot findFrameSlot(Object identifier) { 65 public FrameSlot findFrameSlot(Object identifier) {
62 return identifierToSlotMap.get(identifier); 66 return identifierToSlotMap.get(identifier);
68 return result; 72 return result;
69 } 73 }
70 return addFrameSlot(identifier); 74 return addFrameSlot(identifier);
71 } 75 }
72 76
73 public FrameVersion getCurrentVersion() { 77 public FrameSlot findOrAddFrameSlot(Object identifier, Class<?> type) {
74 return lastVersion; 78 FrameSlot result = findFrameSlot(identifier);
79 if (result != null) {
80 return result;
81 }
82 return addFrameSlot(identifier, type);
75 } 83 }
76 84
77 public int getSize() { 85 public int getSize() {
78 return slots.size(); 86 return slots.size();
79 } 87 }
80 88
81 public List<? extends FrameSlot> getSlots() { 89 public List<? extends FrameSlot> getSlots() {
82 return Collections.unmodifiableList(slots); 90 return Collections.unmodifiableList(slots);
83 } 91 }
84 92
85 protected void appendVersion(FrameVersionImpl newVersion) { 93 /**
86 lastVersion.next = newVersion; 94 * (db) to retrieve the list of all the identifiers associated with this frame descriptor.
87 lastVersion = newVersion; 95 *
96 * @return the list of all the identifiers in this frame descriptor
97 */
98 public Set<Object> getIdentifiers() {
99 return Collections.unmodifiableSet(identifierToSlotMap.keySet());
100 }
101
102 /**
103 * (db): this method is used for creating a clone of the {@link FrameDescriptor} object ready
104 * for parallel execution.
105 */
106 public FrameDescriptor copy() {
107 FrameDescriptor clonedFrameDescriptor = new FrameDescriptor(this.typeConversion);
108 for (int i = 0; i < this.getSlots().size(); i++) {
109 Object identifier = this.getSlots().get(i).getIdentifier();
110 clonedFrameDescriptor.addFrameSlot(identifier);
111 }
112 return clonedFrameDescriptor;
113 }
114
115 void updateVersion() {
116 version.invalidate();
117 version = createVersion();
118 }
119
120 public Assumption getVersion() {
121 return version;
122 }
123
124 private static Assumption createVersion() {
125 return Truffle.getRuntime().createAssumption("frame version");
126 }
127
128 public FrameTypeConversion getTypeConversion() {
129 return typeConversion;
88 } 130 }
89 } 131 }
90
91 class FrameVersionImpl implements FrameVersion {
92
93 protected FrameVersionImpl next;
94
95 @Override
96 public final FrameVersion getNext() {
97 return next;
98 }
99 }
100
101 class TypeChangeFrameVersionImpl extends FrameVersionImpl implements FrameVersion.TypeChange {
102
103 private final FrameSlotImpl slot;
104 private final Class<?> oldType;
105 private final Class<?> newType;
106
107 protected TypeChangeFrameVersionImpl(FrameSlotImpl slot, Class<?> oldType, Class<?> newType) {
108 this.slot = slot;
109 this.oldType = oldType;
110 this.newType = newType;
111 }
112
113 @Override
114 public final void applyTransformation(Frame frame) {
115 Object value = slot.getValue(oldType, frame);
116 slot.setValue(newType, frame, value);
117 }
118 }
119
120 class FrameSlotImpl implements FrameSlot {
121
122 private final FrameDescriptor descriptor;
123 private final Object identifier;
124 private final int index;
125 private Class<?> type;
126 private ArrayList<FrameSlotTypeListener> listeners;
127
128 protected FrameSlotImpl(FrameDescriptor descriptor, Object identifier, int index, Class<?> type) {
129 this.descriptor = descriptor;
130 this.identifier = identifier;
131 this.index = index;
132 this.type = type;
133 assert type != null;
134 }
135
136 public Object getIdentifier() {
137 return identifier;
138 }
139
140 public int getIndex() {
141 return index;
142 }
143
144 public Class<?> getType() {
145 return type;
146 }
147
148 protected Object getValue(Class<?> accessType, Frame frame) {
149 if (accessType == Integer.class) {
150 return frame.getInt(this);
151 } else if (accessType == Long.class) {
152 return frame.getLong(this);
153 } else if (accessType == Float.class) {
154 return frame.getFloat(this);
155 } else if (accessType == Double.class) {
156 return frame.getDouble(this);
157 } else {
158 return frame.getObject(this);
159 }
160 }
161
162 protected void setValue(Class<?> accessType, Frame frame, Object value) {
163 Object newValue = descriptor.typeConversion.convertTo(accessType, value);
164 if (accessType == Integer.class) {
165 frame.setInt(this, (Integer) newValue);
166 } else if (accessType == Long.class) {
167 frame.setLong(this, (Long) newValue);
168 } else if (accessType == Float.class) {
169 frame.setFloat(this, (Float) newValue);
170 } else if (accessType == Double.class) {
171 frame.setDouble(this, (Double) newValue);
172 } else {
173 frame.setObject(this, newValue);
174 }
175 }
176
177 public void setType(final Class<?> type) {
178 final Class<?> oldType = this.type;
179 this.type = type;
180 ArrayList<FrameSlotTypeListener> oldListeners = this.listeners;
181 this.listeners = null;
182 if (oldListeners != null) {
183 for (FrameSlotTypeListener listener : oldListeners) {
184 listener.typeChanged(this, oldType);
185 }
186 }
187 descriptor.appendVersion(new TypeChangeFrameVersionImpl(this, oldType, type));
188 }
189
190 @Override
191 public String toString() {
192 return "[" + index + "," + identifier + "]";
193 }
194
195 @Override
196 public void registerOneShotTypeListener(FrameSlotTypeListener listener) {
197 if (listeners == null) {
198 listeners = new ArrayList<>();
199 }
200 listeners.add(listener);
201 }
202 }