57
57
import com .oracle .graal .python .nodes .function .ClassBodyRootNode ;
58
58
import com .oracle .graal .python .nodes .object .GetClassNode ;
59
59
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
60
+ import com .oracle .graal .python .util .PythonUtils ;
60
61
import com .oracle .truffle .api .CompilerDirectives ;
61
62
import com .oracle .truffle .api .dsl .Cached ;
62
63
import com .oracle .truffle .api .dsl .Cached .Shared ;
@@ -295,138 +296,30 @@ public abstract static class SyncFrameValuesNode extends Node {
295
296
static void doLocalsStorageCachedAST (PFrame pyFrame , Frame frameToSync , @ SuppressWarnings ("unused" ) Node location ,
296
297
@ Cached ("createClassProfile()" ) ValueProfile frameProfile ,
297
298
@ Cached ("frameToSync.getFrameDescriptor()" ) FrameDescriptor cachedFd ) {
298
- boolean invalidState = false ;
299
299
LocalsStorage localsStorage = getLocalsStorage (pyFrame );
300
300
MaterializedFrame target = frameProfile .profile (localsStorage .getFrame ());
301
301
assert cachedFd == target .getFrameDescriptor ();
302
302
303
303
for (int slot = 0 ; slot < cachedFd .getNumberOfSlots (); slot ++) {
304
304
if (FrameSlotIDs .isUserFrameSlot (cachedFd .getSlotName (slot ))) {
305
- if (frameToSync .isBoolean (slot )) {
306
- try {
307
- target .setBoolean (slot , frameToSync .getBoolean (slot ));
308
- } catch (FrameSlotTypeException e ) {
309
- CompilerDirectives .transferToInterpreter ();
310
- invalidState = true ;
311
- }
312
- } else if (frameToSync .isByte (slot )) {
313
- try {
314
- target .setByte (slot , frameToSync .getByte (slot ));
315
- } catch (FrameSlotTypeException e ) {
316
- CompilerDirectives .transferToInterpreter ();
317
- invalidState = true ;
318
- }
319
- } else if (frameToSync .isDouble (slot )) {
320
- try {
321
- target .setDouble (slot , frameToSync .getDouble (slot ));
322
- } catch (FrameSlotTypeException e ) {
323
- CompilerDirectives .transferToInterpreter ();
324
- invalidState = true ;
325
- }
326
- } else if (frameToSync .isFloat (slot )) {
327
- try {
328
- target .setFloat (slot , frameToSync .getFloat (slot ));
329
- } catch (FrameSlotTypeException e ) {
330
- CompilerDirectives .transferToInterpreter ();
331
- invalidState = true ;
332
- }
333
- } else if (frameToSync .isInt (slot )) {
334
- try {
335
- target .setInt (slot , frameToSync .getInt (slot ));
336
- } catch (FrameSlotTypeException e ) {
337
- CompilerDirectives .transferToInterpreter ();
338
- invalidState = true ;
339
- }
340
- } else if (frameToSync .isLong (slot )) {
341
- try {
342
- target .setLong (slot , frameToSync .getLong (slot ));
343
- } catch (FrameSlotTypeException e ) {
344
- CompilerDirectives .transferToInterpreter ();
345
- invalidState = true ;
346
- }
347
- } else if (frameToSync .isObject (slot )) {
348
- try {
349
- target .setObject (slot , frameToSync .getObject (slot ));
350
- } catch (FrameSlotTypeException e ) {
351
- CompilerDirectives .transferToInterpreter ();
352
- invalidState = true ;
353
- }
354
- }
305
+ PythonUtils .copyFrameSlot (frameToSync , target , slot );
355
306
}
356
307
}
357
- if (CompilerDirectives .inInterpreter () && invalidState ) {
358
- // we're always in the interpreter if invalidState was set
359
- throw new IllegalStateException ("the frame lied about the frame slot type" );
360
- }
361
308
}
362
309
363
310
@ Specialization (guards = {"!isBytecodeFrame(frameToSync)" , "hasLocalsStorage(pyFrame, frameToSync, frameProfile)" , "frameToSync.getFrameDescriptor() == cachedFd" }, limit = "1" )
364
311
static void doLocalsStorageLoopAST (PFrame pyFrame , Frame frameToSync , @ SuppressWarnings ("unused" ) Node location ,
365
312
@ Cached ("createClassProfile()" ) ValueProfile frameProfile ,
366
313
@ Cached ("frameToSync.getFrameDescriptor()" ) FrameDescriptor cachedFd ) {
367
- boolean invalidState = false ;
368
314
LocalsStorage localsStorage = getLocalsStorage (pyFrame );
369
315
MaterializedFrame target = frameProfile .profile (localsStorage .getFrame ());
370
316
assert cachedFd == target .getFrameDescriptor ();
371
317
372
318
for (int slot = 0 ; slot < cachedFd .getNumberOfSlots (); slot ++) {
373
319
if (FrameSlotIDs .isUserFrameSlot (cachedFd .getSlotName (slot ))) {
374
- if (frameToSync .isBoolean (slot )) {
375
- try {
376
- target .setBoolean (slot , frameToSync .getBoolean (slot ));
377
- } catch (FrameSlotTypeException e ) {
378
- CompilerDirectives .transferToInterpreter ();
379
- invalidState = true ;
380
- }
381
- } else if (frameToSync .isByte (slot )) {
382
- try {
383
- target .setByte (slot , frameToSync .getByte (slot ));
384
- } catch (FrameSlotTypeException e ) {
385
- CompilerDirectives .transferToInterpreter ();
386
- invalidState = true ;
387
- }
388
- } else if (frameToSync .isDouble (slot )) {
389
- try {
390
- target .setDouble (slot , frameToSync .getDouble (slot ));
391
- } catch (FrameSlotTypeException e ) {
392
- CompilerDirectives .transferToInterpreter ();
393
- invalidState = true ;
394
- }
395
- } else if (frameToSync .isFloat (slot )) {
396
- try {
397
- target .setFloat (slot , frameToSync .getFloat (slot ));
398
- } catch (FrameSlotTypeException e ) {
399
- CompilerDirectives .transferToInterpreter ();
400
- invalidState = true ;
401
- }
402
- } else if (frameToSync .isInt (slot )) {
403
- try {
404
- target .setInt (slot , frameToSync .getInt (slot ));
405
- } catch (FrameSlotTypeException e ) {
406
- CompilerDirectives .transferToInterpreter ();
407
- invalidState = true ;
408
- }
409
- } else if (frameToSync .isLong (slot )) {
410
- try {
411
- target .setLong (slot , frameToSync .getLong (slot ));
412
- } catch (FrameSlotTypeException e ) {
413
- CompilerDirectives .transferToInterpreter ();
414
- invalidState = true ;
415
- }
416
- } else if (frameToSync .isObject (slot )) {
417
- try {
418
- target .setObject (slot , frameToSync .getObject (slot ));
419
- } catch (FrameSlotTypeException e ) {
420
- CompilerDirectives .transferToInterpreter ();
421
- invalidState = true ;
422
- }
423
- }
320
+ PythonUtils .copyFrameSlot (frameToSync , target , slot );
424
321
}
425
322
}
426
- if (CompilerDirectives .inInterpreter () && invalidState ) {
427
- // we're always in the interpreter if invalidState was set
428
- throw new IllegalStateException ("the frame lied about the frame slot type" );
429
- }
430
323
}
431
324
432
325
@ Specialization (guards = {"!isBytecodeFrame(frameToSync)" , "hasLocalsStorage(pyFrame, frameToSync, frameProfile)" }, replaces = {"doLocalsStorageCachedAST" , "doLocalsStorageLoopAST" })
@@ -440,21 +333,7 @@ static void doLocalsStorageUncachedAST(PFrame pyFrame, Frame frameToSync, @Suppr
440
333
441
334
for (int slot = 0 ; slot < fd .getNumberOfSlots (); slot ++) {
442
335
if (FrameSlotIDs .isUserFrameSlot (fd .getSlotName (slot ))) {
443
- if (frameToSync .isBoolean (slot )) {
444
- target .setBoolean (slot , frameToSync .getBoolean (slot ));
445
- } else if (frameToSync .isByte (slot )) {
446
- target .setByte (slot , frameToSync .getByte (slot ));
447
- } else if (frameToSync .isDouble (slot )) {
448
- target .setDouble (slot , frameToSync .getDouble (slot ));
449
- } else if (frameToSync .isFloat (slot )) {
450
- target .setFloat (slot , frameToSync .getFloat (slot ));
451
- } else if (frameToSync .isInt (slot )) {
452
- target .setInt (slot , frameToSync .getInt (slot ));
453
- } else if (frameToSync .isLong (slot )) {
454
- target .setLong (slot , frameToSync .getLong (slot ));
455
- } else if (frameToSync .isObject (slot )) {
456
- target .setObject (slot , frameToSync .getObject (slot ));
457
- }
336
+ PythonUtils .copyFrameSlot (frameToSync , target , slot );
458
337
}
459
338
}
460
339
} catch (FrameSlotTypeException e ) {
@@ -560,7 +439,8 @@ static void doCustomLocalsObject(PFrame pyFrame, Frame frameToSync, @SuppressWar
560
439
// nothing to do; we already worked on the custom object
561
440
}
562
441
563
- @ Specialization (guards = {"isBytecodeFrame(frameToSync)" , "hasLocalsStorage(pyFrame, frameToSync, frameProfile)" , "frameToSync.getFrameDescriptor() == cachedFd" }, limit = "1" )
442
+ @ Specialization (guards = {"isBytecodeFrame(frameToSync)" , "hasLocalsStorage(pyFrame, frameToSync, frameProfile)" , "frameToSync.getFrameDescriptor() == cachedFd" ,
443
+ "variableSlotCount(cachedFd) < 32" }, limit = "1" )
564
444
@ ExplodeLoop
565
445
static void doLocalsStorageCachedExploded (PFrame pyFrame , Frame frameToSync , @ SuppressWarnings ("unused" ) Node location ,
566
446
@ Cached ("createClassProfile()" ) ValueProfile frameProfile ,
@@ -570,7 +450,7 @@ static void doLocalsStorageCachedExploded(PFrame pyFrame, Frame frameToSync, @Su
570
450
assert cachedFd == target .getFrameDescriptor ();
571
451
int slotCount = variableSlotCount (cachedFd );
572
452
for (int slot = 0 ; slot < slotCount ; slot ++) {
573
- copySlot (frameToSync , target , slot );
453
+ PythonUtils . copyFrameSlot (frameToSync , target , slot );
574
454
}
575
455
}
576
456
@@ -584,7 +464,7 @@ static void doLocalsStorageCachedLoop(PFrame pyFrame, Frame frameToSync, @Suppre
584
464
assert cachedFd == target .getFrameDescriptor ();
585
465
int slotCount = variableSlotCount (cachedFd );
586
466
for (int slot = 0 ; slot < slotCount ; slot ++) {
587
- copySlot (frameToSync , target , slot );
467
+ PythonUtils . copyFrameSlot (frameToSync , target , slot );
588
468
}
589
469
}
590
470
@@ -595,17 +475,18 @@ static void doLocalsStorageUncached(PFrame pyFrame, Frame frameToSync, @Suppress
595
475
MaterializedFrame target = frameProfile .profile (localsStorage .getFrame ());
596
476
int slotCount = variableSlotCount (frameToSync .getFrameDescriptor ());
597
477
for (int slot = 0 ; slot < slotCount ; slot ++) {
598
- copySlot (frameToSync , target , slot );
478
+ PythonUtils . copyFrameSlot (frameToSync , target , slot );
599
479
}
600
480
}
601
481
602
482
@ Specialization (guards = { //
603
483
"isBytecodeFrame(frameToSync)" ,
604
484
"isDictWithCustomStorage(pyFrame)" ,
605
485
"frameToSync.getFrameDescriptor() == cachedFd" ,
486
+ "variableSlotCount(cachedFd) < 32"
606
487
}, limit = "1" )
607
488
@ ExplodeLoop
608
- static void doGenericDictCached (VirtualFrame frame , PFrame pyFrame , Frame frameToSync , @ SuppressWarnings ("unused" ) Node location ,
489
+ static void doGenericDictCachedExploded (VirtualFrame frame , PFrame pyFrame , Frame frameToSync , @ SuppressWarnings ("unused" ) Node location ,
609
490
@ Cached ("frameToSync.getFrameDescriptor()" ) @ SuppressWarnings ("unused" ) FrameDescriptor cachedFd ,
610
491
@ Cached (value = "getProfiles(variableSlotCount(cachedFd))" , dimensions = 1 ) ConditionProfile [] profiles ,
611
492
@ Cached BranchProfile updatedStorage ,
@@ -625,7 +506,32 @@ static void doGenericDictCached(VirtualFrame frame, PFrame pyFrame, Frame frameT
625
506
}
626
507
}
627
508
628
- @ Specialization (guards = {"isBytecodeFrame(frameToSync)" , "isDictWithCustomStorage(pyFrame)" }, replaces = "doGenericDictCached" )
509
+ @ Specialization (guards = { //
510
+ "isBytecodeFrame(frameToSync)" ,
511
+ "isDictWithCustomStorage(pyFrame)" ,
512
+ "frameToSync.getFrameDescriptor() == cachedFd" ,
513
+ }, limit = "1" , replaces = "doGenericDictCachedExploded" )
514
+ static void doGenericDictCachedLoop (VirtualFrame frame , PFrame pyFrame , Frame frameToSync , @ SuppressWarnings ("unused" ) Node location ,
515
+ @ Cached ("frameToSync.getFrameDescriptor()" ) @ SuppressWarnings ("unused" ) FrameDescriptor cachedFd ,
516
+ @ Cached (value = "getProfiles(variableSlotCount(cachedFd))" , dimensions = 1 ) ConditionProfile [] profiles ,
517
+ @ Cached BranchProfile updatedStorage ,
518
+ @ Cached ConditionProfile hasFrame ,
519
+ @ CachedLibrary (limit = "1" ) HashingStorageLibrary lib ) {
520
+ // This can happen if someone received the locals dict using 'locals()' or similar and
521
+ // then assigned to the dictionary. Assigning will switch the storage. But we still must
522
+ // refresh the values.
523
+
524
+ // The cast is guaranteed by the guard.
525
+ PDict localsDict = (PDict ) pyFrame .getLocalsDict ();
526
+ FrameInfo info = (FrameInfo ) cachedFd .getInfo ();
527
+ int slotCount = info .getVariableCount ();
528
+ for (int slot = 0 ; slot < slotCount ; slot ++) {
529
+ ConditionProfile profile = profiles [slot ];
530
+ syncDict (frame , slot , info , frameToSync , localsDict , lib , hasFrame , updatedStorage , profile );
531
+ }
532
+ }
533
+
534
+ @ Specialization (guards = {"isBytecodeFrame(frameToSync)" , "isDictWithCustomStorage(pyFrame)" }, replaces = {"doGenericDictCachedExploded" , "doGenericDictCachedLoop" })
629
535
static void doGenericDict (VirtualFrame frame , PFrame pyFrame , Frame frameToSync , @ SuppressWarnings ("unused" ) Node location ,
630
536
@ Cached BranchProfile updatedStorage ,
631
537
@ Cached ConditionProfile hasFrame ,
@@ -728,23 +634,5 @@ private static Object resolveCellValue(ConditionProfile profile, Object value) {
728
634
public static SyncFrameValuesNode create () {
729
635
return SyncFrameValuesNodeGen .create ();
730
636
}
731
-
732
- public static void copySlot (Frame frameToSync , MaterializedFrame target , int slot ) {
733
- if (frameToSync .isBoolean (slot )) {
734
- target .setBoolean (slot , frameToSync .getBoolean (slot ));
735
- } else if (frameToSync .isByte (slot )) {
736
- target .setByte (slot , frameToSync .getByte (slot ));
737
- } else if (frameToSync .isDouble (slot )) {
738
- target .setDouble (slot , frameToSync .getDouble (slot ));
739
- } else if (frameToSync .isFloat (slot )) {
740
- target .setFloat (slot , frameToSync .getFloat (slot ));
741
- } else if (frameToSync .isInt (slot )) {
742
- target .setInt (slot , frameToSync .getInt (slot ));
743
- } else if (frameToSync .isLong (slot )) {
744
- target .setLong (slot , frameToSync .getLong (slot ));
745
- } else if (frameToSync .isObject (slot )) {
746
- target .setObject (slot , frameToSync .getObject (slot ));
747
- }
748
- }
749
637
}
750
638
}
0 commit comments