66
66
import com .oracle .truffle .api .dsl .Cached ;
67
67
import com .oracle .truffle .api .dsl .ImportStatic ;
68
68
import com .oracle .truffle .api .dsl .ReportPolymorphism ;
69
+ import com .oracle .truffle .api .dsl .ReportPolymorphism .Megamorphic ;
69
70
import com .oracle .truffle .api .dsl .Specialization ;
70
71
import com .oracle .truffle .api .frame .VirtualFrame ;
71
72
import com .oracle .truffle .api .nodes .Node ;
@@ -386,10 +387,24 @@ boolean callBoolean(VirtualFrame frame, double left, double right,
386
387
387
388
// Object, Object
388
389
389
- @ Specialization (guards = {"!isReversible()" })
390
- Object callObject (VirtualFrame frame , Object left , Object right ,
390
+ @ Specialization (guards = {"!isReversible()" , "left.getClass() == cachedLeftClass" , "right.getClass() == cachedRightClass" }, limit = "5" )
391
+ Object callObjectGeneric (VirtualFrame frame , Object left , Object right ,
392
+ @ SuppressWarnings ("unused" ) @ Cached ("left.getClass()" ) Class <?> cachedLeftClass ,
393
+ @ SuppressWarnings ("unused" ) @ Cached ("right.getClass()" ) Class <?> cachedRightClass ,
391
394
@ Cached GetClassNode getClassNode ,
392
395
@ Cached ("create(name, ignoreDescriptorException)" ) LookupSpecialMethodSlotNode getattr ) {
396
+ return doCallObject (frame , left , right , getClassNode , getattr );
397
+ }
398
+
399
+ @ Specialization (guards = "!isReversible()" , replaces = "callObjectGeneric" )
400
+ @ Megamorphic
401
+ Object callObjectMegamorphic (VirtualFrame frame , Object left , Object right ,
402
+ @ Cached GetClassNode getClassNode ,
403
+ @ Cached ("create(name, ignoreDescriptorException)" ) LookupSpecialMethodSlotNode getattr ) {
404
+ return doCallObject (frame , left , right , getClassNode , getattr );
405
+ }
406
+
407
+ private Object doCallObject (VirtualFrame frame , Object left , Object right , GetClassNode getClassNode , LookupSpecialMethodSlotNode getattr ) {
393
408
Object leftClass = getClassNode .execute (left );
394
409
Object leftCallable = getattr .execute (frame , leftClass , left );
395
410
if (leftCallable == PNone .NO_VALUE ) {
@@ -402,8 +417,10 @@ Object callObject(VirtualFrame frame, Object left, Object right,
402
417
return ensureDispatch ().executeObject (frame , leftCallable , left , right );
403
418
}
404
419
405
- @ Specialization (guards = {"isReversible()" })
406
- Object callObjectR (VirtualFrame frame , Object left , Object right ,
420
+ @ Specialization (guards = {"isReversible()" , "left.getClass() == cachedLeftClass" , "right.getClass() == cachedRightClass" }, limit = "5" )
421
+ Object callObjectGenericR (VirtualFrame frame , Object left , Object right ,
422
+ @ SuppressWarnings ("unused" ) @ Cached ("left.getClass()" ) Class <?> cachedLeftClass ,
423
+ @ SuppressWarnings ("unused" ) @ Cached ("right.getClass()" ) Class <?> cachedRightClass ,
407
424
@ Cached ("create(name, ignoreDescriptorException)" ) LookupSpecialMethodNode getattr ,
408
425
@ Cached ("create(rname, ignoreDescriptorException)" ) LookupSpecialMethodNode getattrR ,
409
426
@ Cached GetClassNode getLeftClassNode ,
@@ -417,6 +434,34 @@ Object callObjectR(VirtualFrame frame, Object left, Object right,
417
434
@ Cached BranchProfile noLeftBuiltinClassType ,
418
435
@ Cached BranchProfile noRightBuiltinClassType ,
419
436
@ Cached BranchProfile gotResultBranch ) {
437
+ return doCallObjectR (frame , left , right , getattr , getattrR , getLeftClassNode , getRightClassNode , isSameTypeNode , isSubtype , hasLeftCallable , hasRightCallable , notImplementedProfile ,
438
+ hasEnclosingBuiltin , noLeftBuiltinClassType , noRightBuiltinClassType , gotResultBranch );
439
+ }
440
+
441
+ @ Specialization (guards = "isReversible()" , replaces = "callObjectGenericR" )
442
+ @ Megamorphic
443
+ Object callObjectRMegamorphic (VirtualFrame frame , Object left , Object right ,
444
+ @ Cached ("create(name, ignoreDescriptorException)" ) LookupSpecialMethodNode getattr ,
445
+ @ Cached ("create(rname, ignoreDescriptorException)" ) LookupSpecialMethodNode getattrR ,
446
+ @ Cached GetClassNode getLeftClassNode ,
447
+ @ Cached GetClassNode getRightClassNode ,
448
+ @ Cached TypeNodes .IsSameTypeNode isSameTypeNode ,
449
+ @ Cached IsSubtypeNode isSubtype ,
450
+ @ Cached ConditionProfile hasLeftCallable ,
451
+ @ Cached ConditionProfile hasRightCallable ,
452
+ @ Cached ConditionProfile notImplementedProfile ,
453
+ @ Cached ConditionProfile hasEnclosingBuiltin ,
454
+ @ Cached BranchProfile noLeftBuiltinClassType ,
455
+ @ Cached BranchProfile noRightBuiltinClassType ,
456
+ @ Cached BranchProfile gotResultBranch ) {
457
+ return doCallObjectR (frame , left , right , getattr , getattrR , getLeftClassNode , getRightClassNode , isSameTypeNode , isSubtype , hasLeftCallable , hasRightCallable , notImplementedProfile ,
458
+ hasEnclosingBuiltin , noLeftBuiltinClassType , noRightBuiltinClassType , gotResultBranch );
459
+ }
460
+
461
+ private Object doCallObjectR (VirtualFrame frame , Object left , Object right , LookupSpecialMethodNode getattr , LookupSpecialMethodNode getattrR , GetClassNode getLeftClassNode ,
462
+ GetClassNode getRightClassNode , TypeNodes .IsSameTypeNode isSameTypeNode , IsSubtypeNode isSubtype , ConditionProfile hasLeftCallable , ConditionProfile hasRightCallable ,
463
+ ConditionProfile notImplementedProfile , ConditionProfile hasEnclosingBuiltin , BranchProfile noLeftBuiltinClassType , BranchProfile noRightBuiltinClassType ,
464
+ BranchProfile gotResultBranch ) {
420
465
// This specialization implements the logic from cpython://Objects/abstract.c#binary_op1
421
466
// (the structure is modelled closely on it), as well as the additional logic in
422
467
// cpython://Objects/typeobject.c#SLOT1BINFULL. The latter has the addition that it swaps
0 commit comments