Mercurial > hg > graal-jvmci-8
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 } |