Mercurial > hg > graal-compiler
comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.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 | 645f216a00c4 |
children | 8cf939b349dd |
comparison
equal
deleted
inserted
replaced
9257:542712a4732a | 9258:07f8d136a05e |
---|---|
27 import com.oracle.truffle.api.*; | 27 import com.oracle.truffle.api.*; |
28 import com.oracle.truffle.api.frame.*; | 28 import com.oracle.truffle.api.frame.*; |
29 | 29 |
30 public final class DefaultVirtualFrame implements VirtualFrame { | 30 public final class DefaultVirtualFrame implements VirtualFrame { |
31 | 31 |
32 private static final Object UNDEFINED_OBJECT = null; | |
33 private static final Boolean UNDEFINED_BOOLEAN = false; | |
34 private static final Integer UNDEFINED_INTEGER = 0; | |
35 private static final Float UNDEFINED_FLOAT = 0.0f; | |
36 private static final Long UNDEFINED_LONG = 0L; | |
37 private static final Double UNDEFINED_DOUBLE = 0.0d; | |
38 | |
39 private final FrameDescriptor descriptor; | 32 private final FrameDescriptor descriptor; |
40 private final PackedFrame caller; | 33 private final PackedFrame caller; |
41 private final Arguments arguments; | 34 private final Arguments arguments; |
42 private FrameVersion currentVersion; | 35 private Object[] locals; |
43 protected Object[] locals; | 36 private Class[] tags; |
44 protected Class[] tags; | |
45 | 37 |
46 public DefaultVirtualFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments arguments) { | 38 public DefaultVirtualFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments arguments) { |
47 this.descriptor = descriptor; | 39 this.descriptor = descriptor; |
48 this.caller = caller; | 40 this.caller = caller; |
49 this.arguments = arguments; | 41 this.arguments = arguments; |
50 this.currentVersion = descriptor.getCurrentVersion(); | |
51 this.locals = new Object[descriptor.getSize()]; | 42 this.locals = new Object[descriptor.getSize()]; |
52 // The tags are only needed for assertion checking, so initialize the field only when | 43 this.tags = new Class[descriptor.getSize()]; |
53 // assertions are enabled | |
54 assert (this.tags = new Class[descriptor.getSize()]) != null; | |
55 } | 44 } |
56 | 45 |
57 @Override | 46 @Override |
58 public Arguments getArguments() { | 47 public Arguments getArguments() { |
59 return arguments; | 48 return arguments; |
73 public MaterializedFrame materialize() { | 62 public MaterializedFrame materialize() { |
74 return new DefaultMaterializedFrame(this); | 63 return new DefaultMaterializedFrame(this); |
75 } | 64 } |
76 | 65 |
77 @Override | 66 @Override |
78 public Object getObject(FrameSlot slot) { | 67 public Object getObject(FrameSlot slot) throws FrameSlotTypeException { |
79 return get(slot, Object.class, UNDEFINED_OBJECT); | 68 verifyGet(slot, Object.class); |
80 } | 69 return locals[slot.getIndex()]; |
81 | 70 } |
82 @Override | 71 |
83 public void setObject(FrameSlot slot, Object value) { | 72 @Override |
84 set(slot, Object.class, value); | 73 public void setObject(FrameSlot slot, Object value) throws FrameSlotTypeException { |
85 } | 74 verifySet(slot, Object.class); |
86 | 75 locals[slot.getIndex()] = value; |
87 @Override | 76 } |
88 public boolean getBoolean(FrameSlot slot) { | 77 |
89 return (Boolean) get(slot, Boolean.class, UNDEFINED_BOOLEAN); | 78 @Override |
90 } | 79 public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException { |
91 | 80 verifyGet(slot, boolean.class); |
92 @Override | 81 return (boolean) locals[slot.getIndex()]; |
93 public void setBoolean(FrameSlot slot, boolean value) { | 82 } |
94 set(slot, Boolean.class, value); | 83 |
95 } | 84 @Override |
96 | 85 public void setBoolean(FrameSlot slot, boolean value) throws FrameSlotTypeException { |
97 @Override | 86 verifySet(slot, boolean.class); |
98 public int getInt(FrameSlot slot) { | 87 locals[slot.getIndex()] = value; |
99 return (Integer) get(slot, Integer.class, UNDEFINED_INTEGER); | 88 } |
100 } | 89 |
101 | 90 @Override |
102 @Override | 91 public int getInt(FrameSlot slot) throws FrameSlotTypeException { |
103 public void setInt(FrameSlot slot, int value) { | 92 verifyGet(slot, int.class); |
104 set(slot, Integer.class, value); | 93 return (int) locals[slot.getIndex()]; |
105 } | 94 } |
106 | 95 |
107 @Override | 96 @Override |
108 public long getLong(FrameSlot slot) { | 97 public void setInt(FrameSlot slot, int value) throws FrameSlotTypeException { |
109 return (Long) get(slot, Long.class, UNDEFINED_LONG); | 98 verifySet(slot, int.class); |
110 } | 99 locals[slot.getIndex()] = value; |
111 | 100 } |
112 @Override | 101 |
113 public void setLong(FrameSlot slot, long value) { | 102 @Override |
114 set(slot, Long.class, value); | 103 public long getLong(FrameSlot slot) throws FrameSlotTypeException { |
115 } | 104 verifyGet(slot, long.class); |
116 | 105 return (long) locals[slot.getIndex()]; |
117 @Override | 106 } |
118 public float getFloat(FrameSlot slot) { | 107 |
119 return (Float) get(slot, Float.class, UNDEFINED_FLOAT); | 108 @Override |
120 } | 109 public void setLong(FrameSlot slot, long value) throws FrameSlotTypeException { |
121 | 110 verifySet(slot, long.class); |
122 @Override | 111 locals[slot.getIndex()] = value; |
123 public void setFloat(FrameSlot slot, float value) { | 112 } |
124 set(slot, Float.class, value); | 113 |
125 } | 114 @Override |
126 | 115 public float getFloat(FrameSlot slot) throws FrameSlotTypeException { |
127 @Override | 116 verifyGet(slot, float.class); |
128 public double getDouble(FrameSlot slot) { | 117 return (float) locals[slot.getIndex()]; |
129 return (Double) get(slot, Double.class, UNDEFINED_DOUBLE); | 118 } |
130 } | 119 |
131 | 120 @Override |
132 @Override | 121 public void setFloat(FrameSlot slot, float value) throws FrameSlotTypeException { |
133 public void setDouble(FrameSlot slot, double value) { | 122 verifySet(slot, float.class); |
134 set(slot, Double.class, value); | 123 locals[slot.getIndex()] = value; |
135 } | 124 } |
136 | 125 |
137 private Object get(FrameSlot slot, Class<?> accessType, Object defaultValue) { | 126 @Override |
138 Object value = locals[slot.getIndex()]; | 127 public double getDouble(FrameSlot slot) throws FrameSlotTypeException { |
139 assert verifyGet(slot, accessType, value); | 128 verifyGet(slot, double.class); |
140 if (value == null) { | 129 return (double) locals[slot.getIndex()]; |
141 return defaultValue; | 130 } |
142 } else { | 131 |
143 return value; | 132 @Override |
144 } | 133 public void setDouble(FrameSlot slot, double value) throws FrameSlotTypeException { |
145 } | 134 verifySet(slot, double.class); |
146 | 135 locals[slot.getIndex()] = value; |
147 private boolean verifyGet(FrameSlot slot, Class<?> accessType, Object value) { | |
148 assert descriptor.getSlots().get(slot.getIndex()) == slot; | |
149 Class<?> tag = tags[slot.getIndex()]; | |
150 if (value == null) { | |
151 assert tag == null || tag == Object.class; | |
152 } else { | |
153 assert tag == accessType : "Local variable " + slot + " was written with set" + tag.getSimpleName() + ", but is read with get" + accessType.getSimpleName(); | |
154 } | |
155 return true; | |
156 } | |
157 | |
158 private void set(FrameSlot slot, Class<?> accessType, Object value) { | |
159 assert verifySet(slot, accessType, value); | |
160 locals[slot.getIndex()] = value; | |
161 } | |
162 | |
163 private boolean verifySet(FrameSlot slot, Class<?> accessType, Object value) { | |
164 assert descriptor.getSlots().get(slot.getIndex()) == slot; | |
165 tags[slot.getIndex()] = accessType; | |
166 assert accessType.isAssignableFrom(slot.getType()) : "Local variable " + slot + ": " + accessType + " is not assignable from " + slot.getType(); | |
167 if (value == null) { | |
168 assert accessType == Object.class; | |
169 } else { | |
170 assert slot.getType().isAssignableFrom(value.getClass()) : "Local variable " + slot + ": " + slot.getType() + " is not assignable from " + value.getClass(); | |
171 } | |
172 return true; | |
173 } | |
174 | |
175 @Override | |
176 public void updateToLatestVersion() { | |
177 if (currentVersion.getNext() != null) { | |
178 doUpdateToLatestVersion(); | |
179 } | |
180 } | |
181 | |
182 private void doUpdateToLatestVersion() { | |
183 FrameVersion version = currentVersion; | |
184 while (version.getNext() != null) { | |
185 version = version.getNext(); | |
186 if (version instanceof FrameVersion.TypeChange) { | |
187 ((FrameVersion.TypeChange) version).applyTransformation(this); | |
188 } else if (version instanceof FrameVersion.Resize) { | |
189 int newSize = ((FrameVersion.Resize) version).getNewSize(); | |
190 locals = Arrays.copyOf(locals, newSize); | |
191 } | |
192 } | |
193 currentVersion = version; | |
194 } | 136 } |
195 | 137 |
196 @Override | 138 @Override |
197 public FrameDescriptor getFrameDescriptor() { | 139 public FrameDescriptor getFrameDescriptor() { |
198 return this.descriptor; | 140 return this.descriptor; |
199 } | 141 } |
142 | |
143 @Override | |
144 public Object getValue(FrameSlot slot) { | |
145 int index = slot.getIndex(); | |
146 if (index >= tags.length) { | |
147 assert index >= 0 && index < descriptor.getSize(); | |
148 return descriptor.getTypeConversion().getDefaultValue(); | |
149 } | |
150 Class tag = tags[index]; | |
151 if (tag == null) { | |
152 return descriptor.getTypeConversion().getDefaultValue(); | |
153 } else { | |
154 return locals[index]; | |
155 } | |
156 } | |
157 | |
158 private void verifySet(FrameSlot slot, Class accessType) throws FrameSlotTypeException { | |
159 if (slot.getType() != accessType) { | |
160 throw new FrameSlotTypeException(); | |
161 } | |
162 int slotIndex = slot.getIndex(); | |
163 if (slotIndex >= tags.length) { | |
164 resize(); | |
165 } | |
166 tags[slotIndex] = accessType; | |
167 } | |
168 | |
169 private void verifyGet(FrameSlot slot, Class accessType) throws FrameSlotTypeException { | |
170 Class<?> slotType = slot.getType(); | |
171 int slotIndex = slot.getIndex(); | |
172 if (slotType != accessType) { | |
173 if (slotType == null) { | |
174 slot.setType(Object.class); | |
175 this.setObject(slot, descriptor.getTypeConversion().getDefaultValue()); | |
176 if (accessType != Object.class) { | |
177 throw new FrameSlotTypeException(); | |
178 } | |
179 } else { | |
180 throw new FrameSlotTypeException(); | |
181 } | |
182 } | |
183 if (slotIndex >= tags.length) { | |
184 resize(); | |
185 } | |
186 Class tag = tags[slotIndex]; | |
187 if (tag != slotType) { | |
188 descriptor.getTypeConversion().updateFrameSlot(this, slot, getValue(slot)); | |
189 if (tags[slotIndex] != slotType) { | |
190 throw new FrameSlotTypeException(); | |
191 } | |
192 } | |
193 } | |
194 | |
195 private void resize() { | |
196 int newSize = descriptor.getSize(); | |
197 if (newSize > tags.length) { | |
198 locals = Arrays.copyOf(locals, newSize); | |
199 tags = Arrays.copyOf(tags, newSize); | |
200 } | |
201 } | |
200 } | 202 } |