41
41
package com .oracle .graal .python .nodes .frame ;
42
42
43
43
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
44
+ import com .oracle .graal .python .builtins .objects .cell .PCell ;
44
45
import com .oracle .graal .python .builtins .objects .common .HashingCollectionNodes .SetItemNode ;
45
46
import com .oracle .graal .python .builtins .objects .common .HashingStorage ;
46
47
import com .oracle .graal .python .builtins .objects .common .LocalsStorage ;
62
63
import com .oracle .truffle .api .frame .VirtualFrame ;
63
64
import com .oracle .truffle .api .nodes .ExplodeLoop ;
64
65
import com .oracle .truffle .api .nodes .Node ;
66
+ import com .oracle .truffle .api .profiles .ConditionProfile ;
65
67
66
68
/**
67
69
* This node makes sure that the current frame has a filled-in PFrame object with a backref
@@ -311,6 +313,7 @@ static void doLocalsStorageUncached(PFrame pyFrame, Frame frameToSync) {
311
313
static void doGenericDictCached (VirtualFrame frame , PFrame pyFrame , Frame frameToSync ,
312
314
@ Cached ("frameToSync.getFrameDescriptor()" ) @ SuppressWarnings ("unused" ) FrameDescriptor cachedFd ,
313
315
@ Cached (value = "getSlots(cachedFd)" , dimensions = 1 ) FrameSlot [] cachedSlots ,
316
+ @ Cached (value = "getProfiles(cachedSlots.length)" , dimensions = 1 ) ConditionProfile [] profiles ,
314
317
@ Cached SetItemNode setItemNode ) {
315
318
// This can happen if someone received the locals dict using 'locals()' or similar and
316
319
// then assigned to the dictionary. Assigning will switch the storage. But we still must
@@ -324,7 +327,11 @@ static void doGenericDictCached(VirtualFrame frame, PFrame pyFrame, Frame frameT
324
327
if (FrameSlotIDs .isUserFrameSlot (slot .getIdentifier ())) {
325
328
Object value = frameToSync .getValue (slot );
326
329
if (value != null ) {
327
- setItemNode .execute (frame , localsDict , slot .getIdentifier (), value );
330
+ if (profiles [i ].profile (value instanceof PCell )) {
331
+ setItemNode .execute (frame , localsDict , slot .getIdentifier (), ((PCell ) value ).getRef ());
332
+ } else {
333
+ setItemNode .execute (frame , localsDict , slot .getIdentifier (), value );
334
+ }
328
335
}
329
336
}
330
337
}
@@ -346,7 +353,9 @@ static void doGenericDict(VirtualFrame frame, PFrame pyFrame, Frame frameToSync,
346
353
FrameSlot slot = slots [i ];
347
354
if (FrameSlotIDs .isUserFrameSlot (slot .getIdentifier ())) {
348
355
Object value = frameToSync .getValue (slot );
349
- if (value != null ) {
356
+ if (value instanceof PCell ) {
357
+ setItemNode .execute (frame , localsDict , slot .getIdentifier (), ((PCell ) value ).getRef ());
358
+ } else {
350
359
setItemNode .execute (frame , localsDict , slot .getIdentifier (), value );
351
360
}
352
361
}
@@ -363,6 +372,14 @@ protected static FrameSlot[] getSlots(FrameDescriptor fd) {
363
372
return fd .getSlots ().toArray (new FrameSlot [0 ]);
364
373
}
365
374
375
+ protected static ConditionProfile [] getProfiles (int n ) {
376
+ ConditionProfile [] profiles = new ConditionProfile [n ];
377
+ for (int i = 0 ; i < profiles .length ; i ++) {
378
+ profiles [i ] = ConditionProfile .createBinaryProfile ();
379
+ }
380
+ return profiles ;
381
+ }
382
+
366
383
/**
367
384
* Guard that tests if the locals object is a dict having a {@link LocalsStorage} using the
368
385
* same frame descriptor as the frame to synchronize. That means, the dict represents
0 commit comments