Mercurial > hg > graal-compiler
comparison graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.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 | 5e3d1a68664e |
children | cd1a1d92b3e3 |
comparison
equal
deleted
inserted
replaced
9257:542712a4732a | 9258:07f8d136a05e |
---|---|
32 * <h3>Specializing Frame Slot Types</h3> | 32 * <h3>Specializing Frame Slot Types</h3> |
33 * | 33 * |
34 * <p> | 34 * <p> |
35 * Dynamically typed languages can speculate on the type of a frame slot and only fall back at run | 35 * Dynamically typed languages can speculate on the type of a frame slot and only fall back at run |
36 * time to a more generic type if necessary. The new type of a frame slot can be set using the | 36 * time to a more generic type if necessary. The new type of a frame slot can be set using the |
37 * {@link FrameSlot#setType(Class)} method. It is the responsibility of the language implementor to | 37 * {@link FrameSlot#setType(Class)} method. |
38 * update the content of currently active frames (using {@link Frame#updateToLatestVersion()}). | |
39 * Also, nodes that depend a specific type of a frame slot must be replaced. Such node can register | |
40 * a listener that implements {@link FrameSlotTypeListener} using | |
41 * {@link FrameSlot#registerOneShotTypeListener(FrameSlotTypeListener)}. The event of a type change | |
42 * on the frame slot will fire only once for the next upcoming change. | |
43 * </p> | 38 * </p> |
44 * | 39 * |
45 * <p> | 40 * <p> |
46 * The next part of the Truffle API introduction is at | 41 * The next part of the Truffle API introduction is at |
47 * {@link com.oracle.truffle.api.test.ReturnTypeSpecializationTest}. | 42 * {@link com.oracle.truffle.api.test.ReturnTypeSpecializationTest}. |
51 | 46 |
52 @Test | 47 @Test |
53 public void test() { | 48 public void test() { |
54 TruffleRuntime runtime = Truffle.getRuntime(); | 49 TruffleRuntime runtime = Truffle.getRuntime(); |
55 FrameDescriptor frameDescriptor = new FrameDescriptor(); | 50 FrameDescriptor frameDescriptor = new FrameDescriptor(); |
56 FrameSlot slot = frameDescriptor.addFrameSlot("localVar", Integer.class); | 51 FrameSlot slot = frameDescriptor.addFrameSlot("localVar", int.class); |
57 TestRootNode rootNode = new TestRootNode(new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); | 52 TestRootNode rootNode = new TestRootNode(new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); |
58 CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor); | 53 CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor); |
59 Assert.assertEquals(Integer.class, slot.getType()); | 54 Assert.assertEquals(int.class, slot.getType()); |
60 Object result = target.call(); | 55 Object result = target.call(); |
61 Assert.assertEquals("42", result); | 56 Assert.assertEquals("42", result); |
62 Assert.assertEquals(Object.class, slot.getType()); | 57 Assert.assertEquals(Object.class, slot.getType()); |
63 } | 58 } |
64 | 59 |
100 return "42"; | 95 return "42"; |
101 } | 96 } |
102 | 97 |
103 } | 98 } |
104 | 99 |
105 class IntAssignLocal extends FrameSlotNode implements FrameSlotTypeListener { | 100 class IntAssignLocal extends FrameSlotNode { |
106 | 101 |
107 @Child private TestChildNode value; | 102 @Child private TestChildNode value; |
108 | 103 |
109 IntAssignLocal(FrameSlot slot, TestChildNode value) { | 104 IntAssignLocal(FrameSlot slot, TestChildNode value) { |
110 super(slot); | 105 super(slot); |
111 this.value = adoptChild(value); | 106 this.value = adoptChild(value); |
112 slot.registerOneShotTypeListener(this); | |
113 } | 107 } |
114 | 108 |
115 @Override | 109 @Override |
116 Object execute(VirtualFrame frame) { | 110 Object execute(VirtualFrame frame) { |
117 Object o = value.execute(frame); | 111 Object o = value.execute(frame); |
118 if (o instanceof Integer) { | 112 if (o instanceof Integer) { |
119 frame.setInt(slot, (Integer) o); | 113 try { |
120 } else { | 114 frame.setInt(slot, (Integer) o); |
121 slot.setType(Object.class); | 115 } catch (FrameSlotTypeException e) { |
122 frame.updateToLatestVersion(); | 116 // fall through |
123 frame.setObject(slot, o); | 117 } |
124 } | 118 } |
119 FrameUtil.setObjectSafe(frame, slot, o); | |
120 this.replace(new ObjectAssignLocal(slot, value)); | |
125 return null; | 121 return null; |
126 } | |
127 | |
128 @Override | |
129 public void typeChanged(FrameSlot changedSlot, Class<?> oldType) { | |
130 if (changedSlot.getType() == Object.class) { | |
131 this.replace(new ObjectAssignLocal(changedSlot, value)); | |
132 } | |
133 } | 122 } |
134 } | 123 } |
135 | 124 |
136 class ObjectAssignLocal extends FrameSlotNode { | 125 class ObjectAssignLocal extends FrameSlotNode { |
137 | 126 |
143 } | 132 } |
144 | 133 |
145 @Override | 134 @Override |
146 Object execute(VirtualFrame frame) { | 135 Object execute(VirtualFrame frame) { |
147 Object o = value.execute(frame); | 136 Object o = value.execute(frame); |
148 frame.setObject(slot, o); | 137 try { |
138 frame.setObject(slot, o); | |
139 } catch (FrameSlotTypeException e) { | |
140 FrameUtil.setObjectSafe(frame, slot, o); | |
141 } | |
149 return null; | 142 return null; |
150 } | 143 } |
151 } | 144 } |
152 | 145 |
153 class IntReadLocal extends FrameSlotNode implements FrameSlotTypeListener { | 146 class IntReadLocal extends FrameSlotNode { |
154 | 147 |
155 IntReadLocal(FrameSlot slot) { | 148 IntReadLocal(FrameSlot slot) { |
156 super(slot); | 149 super(slot); |
157 slot.registerOneShotTypeListener(this); | |
158 } | 150 } |
159 | 151 |
160 @Override | 152 @Override |
161 Object execute(VirtualFrame frame) { | 153 Object execute(VirtualFrame frame) { |
162 return frame.getInt(slot); | 154 try { |
163 } | 155 return frame.getInt(slot); |
164 | 156 } catch (FrameSlotTypeException e) { |
165 @Override | 157 return this.replace(new ObjectReadLocal(slot)).execute(frame); |
166 public void typeChanged(FrameSlot changedSlot, Class<?> oldType) { | |
167 if (changedSlot.getType() == Object.class) { | |
168 this.replace(new ObjectReadLocal(changedSlot)); | |
169 } | 158 } |
170 } | 159 } |
171 } | 160 } |
172 | 161 |
173 class ObjectReadLocal extends FrameSlotNode { | 162 class ObjectReadLocal extends FrameSlotNode { |
176 super(slot); | 165 super(slot); |
177 } | 166 } |
178 | 167 |
179 @Override | 168 @Override |
180 Object execute(VirtualFrame frame) { | 169 Object execute(VirtualFrame frame) { |
181 return frame.getObject(slot); | 170 try { |
171 return frame.getObject(slot); | |
172 } catch (FrameSlotTypeException e) { | |
173 throw new IllegalStateException(e); | |
174 } | |
182 } | 175 } |
183 } | 176 } |
184 } | 177 } |