|
53 | 53 | import com.oracle.truffle.api.dsl.Specialization;
|
54 | 54 | import com.oracle.truffle.api.frame.FrameDescriptor;
|
55 | 55 | import com.oracle.truffle.api.frame.FrameSlot;
|
| 56 | +import com.oracle.truffle.api.frame.FrameSlotKind; |
56 | 57 | import com.oracle.truffle.api.frame.FrameUtil;
|
57 | 58 | import com.oracle.truffle.api.frame.MaterializedFrame;
|
58 | 59 | import com.oracle.truffle.api.frame.VirtualFrame;
|
@@ -187,56 +188,37 @@ public abstract static class GetSpecialVariableStorage extends RubyContextNode {
|
187 | 188 | public abstract SpecialVariableStorage execute(VirtualFrame frame);
|
188 | 189 |
|
189 | 190 | @Specialization(
|
190 |
| - guards = { "frame.getFrameDescriptor() == descriptor", "slot != null" }, |
| 191 | + guards = { "frame.getFrameDescriptor() == descriptor", "declarationFrameSlot != null" }, |
191 | 192 | assumptions = "frameAssumption",
|
192 | 193 | limit = "1")
|
193 |
| - protected SpecialVariableStorage sameFrame(VirtualFrame frame, |
| 194 | + protected SpecialVariableStorage getFromKnownFrameDescriptor(VirtualFrame frame, |
194 | 195 | @Cached("frame.getFrameDescriptor()") FrameDescriptor descriptor,
|
195 |
| - @Cached("descriptor.findFrameSlot(SPECIAL_VARIABLES_STORAGE)") FrameSlot slot, |
196 |
| - @Cached("descriptor.getVersion()") Assumption frameAssumption) { |
197 |
| - Object storage = FrameUtil.getObjectSafe(frame, slot); |
198 |
| - if (storage == nil) { |
199 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
200 |
| - storage = new SpecialVariableStorage(); |
201 |
| - frame.setObject(slot, storage); |
202 |
| - } |
203 |
| - return (SpecialVariableStorage) storage; |
204 |
| - } |
205 |
| - |
206 |
| - @Specialization( |
207 |
| - guards = { "frame.getFrameDescriptor() == descriptor", "slot == null", "declarationFrameSlot != null" }, |
208 |
| - assumptions = "frameAssumption", |
209 |
| - limit = "1") |
210 |
| - protected SpecialVariableStorage declarationFrame(VirtualFrame frame, |
211 |
| - @Cached("frame.getFrameDescriptor()") FrameDescriptor descriptor, |
212 |
| - @Cached("descriptor.findFrameSlot(SPECIAL_VARIABLES_STORAGE)") FrameSlot slot, |
213 | 196 | @Cached("declarationDepth(frame)") int declarationFrameDepth,
|
214 |
| - @Cached("declarationSlot(frame)") FrameSlot declarationFrameSlot, |
215 |
| - @Cached("declarationDescriptor(frame).getVersion()") Assumption frameAssumption) { |
216 |
| - MaterializedFrame storageFrame = RubyArguments.getDeclarationFrame(frame, declarationFrameDepth); |
217 |
| - |
218 |
| - Object storage = FrameUtil.getObjectSafe(storageFrame, declarationFrameSlot); |
219 |
| - if (storage == nil) { |
220 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
221 |
| - storage = new SpecialVariableStorage(); |
222 |
| - storageFrame.setObject(declarationFrameSlot, storage); |
| 197 | + @Cached("declarationDescriptor(frame, declarationFrameDepth)") FrameDescriptor declarationFrameDescriptor, |
| 198 | + @Cached("declarationSlot(declarationFrameDescriptor)") FrameSlot declarationFrameSlot, |
| 199 | + @Cached("declarationFrameDescriptor.getVersion()") Assumption frameAssumption) { |
| 200 | + Object storage; |
| 201 | + if (declarationFrameDepth == 0) { |
| 202 | + storage = FrameUtil.getObjectSafe(frame, declarationFrameSlot); |
| 203 | + if (storage == nil) { |
| 204 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 205 | + storage = new SpecialVariableStorage(); |
| 206 | + frame.setObject(declarationFrameSlot, storage); |
| 207 | + } |
| 208 | + } else { |
| 209 | + MaterializedFrame storageFrame = RubyArguments.getDeclarationFrame(frame, declarationFrameDepth); |
| 210 | + |
| 211 | + storage = FrameUtil.getObjectSafe(storageFrame, declarationFrameSlot); |
| 212 | + if (storage == nil) { |
| 213 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 214 | + storage = new SpecialVariableStorage(); |
| 215 | + storageFrame.setObject(declarationFrameSlot, storage); |
| 216 | + } |
223 | 217 | }
|
224 | 218 | return (SpecialVariableStorage) storage;
|
225 | 219 | }
|
226 | 220 |
|
227 |
| - @Specialization( |
228 |
| - guards = { "frame.getFrameDescriptor() == descriptor", "slot == null", "declarationFrameSlot == null" }, |
229 |
| - assumptions = "frameAssumption", |
230 |
| - limit = "1") |
231 |
| - protected SpecialVariableStorage unset(VirtualFrame frame, |
232 |
| - @Cached("frame.getFrameDescriptor()") FrameDescriptor descriptor, |
233 |
| - @Cached("descriptor.findFrameSlot(SPECIAL_VARIABLES_STORAGE)") FrameSlot slot, |
234 |
| - @Cached("declarationSlot(frame)") FrameSlot declarationFrameSlot, |
235 |
| - @Cached("declarationDescriptor(frame).getVersion()") Assumption frameAssumption) { |
236 |
| - return getSlow(frame.materialize()); |
237 |
| - } |
238 |
| - |
239 |
| - @Specialization(replaces = { "sameFrame", "declarationFrame", "unset" }) |
| 221 | + @Specialization(replaces = "getFromKnownFrameDescriptor") |
240 | 222 | protected SpecialVariableStorage slowPath(VirtualFrame frame) {
|
241 | 223 | return getSlow(frame.materialize());
|
242 | 224 | }
|
@@ -290,40 +272,19 @@ protected int declarationDepth(VirtualFrame topFrame) {
|
290 | 272 | }
|
291 | 273 | }
|
292 | 274 |
|
293 |
| - protected FrameDescriptor declarationDescriptor(VirtualFrame topFrame) { |
294 |
| - MaterializedFrame frame = topFrame.materialize(); |
295 |
| - |
296 |
| - while (true) { |
297 |
| - final FrameSlot slot = getVariableSlot(frame); |
298 |
| - if (slot != null) { |
299 |
| - return frame.getFrameDescriptor(); |
300 |
| - } |
301 |
| - |
302 |
| - final MaterializedFrame nextFrame = RubyArguments.getDeclarationFrame(frame); |
303 |
| - if (nextFrame != null) { |
304 |
| - frame = nextFrame; |
305 |
| - } else { |
306 |
| - return frame.getFrameDescriptor(); |
307 |
| - } |
| 275 | + protected FrameDescriptor declarationDescriptor(VirtualFrame topFrame, int depth) { |
| 276 | + MaterializedFrame frame; |
| 277 | + if (depth == 0) { |
| 278 | + frame = topFrame.materialize(); |
| 279 | + } else { |
| 280 | + frame = RubyArguments.getDeclarationFrame(topFrame, depth); |
308 | 281 | }
|
| 282 | + return frame.getFrameDescriptor(); |
309 | 283 | }
|
310 | 284 |
|
311 |
| - protected FrameSlot declarationSlot(VirtualFrame topFrame) { |
312 |
| - MaterializedFrame frame = topFrame.materialize(); |
313 |
| - |
314 |
| - while (true) { |
315 |
| - final FrameSlot slot = getVariableSlot(frame); |
316 |
| - if (slot != null) { |
317 |
| - return slot; |
318 |
| - } |
319 |
| - |
320 |
| - final MaterializedFrame nextFrame = RubyArguments.getDeclarationFrame(frame); |
321 |
| - if (nextFrame != null) { |
322 |
| - frame = nextFrame; |
323 |
| - } else { |
324 |
| - return null; |
325 |
| - } |
326 |
| - } |
| 285 | + @TruffleBoundary |
| 286 | + protected FrameSlot declarationSlot(FrameDescriptor descriptor) { |
| 287 | + return descriptor.findOrAddFrameSlot(Layouts.SPECIAL_VARIABLES_STORAGE, FrameSlotKind.Object); |
327 | 288 | }
|
328 | 289 |
|
329 | 290 | private static FrameSlot getVariableSlot(MaterializedFrame frame) {
|
|
0 commit comments