163
163
import com .oracle .graal .python .builtins .objects .type .SpecialMethodSlot ;
164
164
import com .oracle .graal .python .builtins .objects .type .TpSlots ;
165
165
import com .oracle .graal .python .builtins .objects .type .TpSlots .GetObjectSlotsNode ;
166
- import com .oracle .graal .python .builtins .objects .type .TypeBuiltins ;
167
- import com .oracle .graal .python .builtins .objects .type .TypeNodes .IsSameTypeNode ;
166
+ import com .oracle .graal .python .builtins .objects .type .TypeNodes ;
168
167
import com .oracle .graal .python .builtins .objects .type .TypeNodes .IsTypeNode ;
169
168
import com .oracle .graal .python .builtins .objects .type .slots .TpSlotIterNext .CallSlotTpIterNextNode ;
170
169
import com .oracle .graal .python .builtins .objects .type .slots .TpSlotUnaryFunc .CallSlotUnaryNode ;
237
236
import com .oracle .graal .python .nodes .function .builtins .PythonUnaryClinicBuiltinNode ;
238
237
import com .oracle .graal .python .nodes .function .builtins .PythonVarargsBuiltinNode ;
239
238
import com .oracle .graal .python .nodes .function .builtins .clinic .ArgumentClinicProvider ;
239
+ import com .oracle .graal .python .nodes .object .BuiltinClassProfiles .IsBuiltinClassExactProfile ;
240
240
import com .oracle .graal .python .nodes .object .BuiltinClassProfiles .IsBuiltinObjectProfile ;
241
241
import com .oracle .graal .python .nodes .object .GetClassNode ;
242
242
import com .oracle .graal .python .nodes .object .GetOrCreateDictNode ;
308
308
import com .oracle .truffle .api .strings .TruffleString ;
309
309
import com .oracle .truffle .api .strings .TruffleString .Encoding ;
310
310
import com .oracle .truffle .api .strings .TruffleStringBuilder ;
311
- import com .oracle .truffle .api .utilities .TriState ;
312
311
313
312
@ CoreFunctions (defineModule = J_BUILTINS , isEager = true )
314
313
public final class BuiltinFunctions extends PythonBuiltins {
@@ -1381,40 +1380,33 @@ public IsInstanceNode createRecursive(byte newDepth) {
1381
1380
return BuiltinFunctionsFactory .IsInstanceNodeFactory .create (newDepth );
1382
1381
}
1383
1382
1384
- private static TriState isInstanceCheckInternal (VirtualFrame frame , Object instance , Object cls , LookupAndCallBinaryNode instanceCheckNode ,
1385
- PyObjectIsTrueNode castToBooleanNode ) {
1383
+ @ Specialization (guards = "!isPTuple(cls)" )
1384
+ static boolean isInstance (VirtualFrame frame , Object instance , Object cls ,
1385
+ @ Bind Node inliningTarget ,
1386
+ @ Cached GetClassNode getClsClassNode ,
1387
+ @ Cached IsBuiltinClassExactProfile classProfile ,
1388
+ @ Cached GetClassNode getInstanceClassNode ,
1389
+ @ Cached TypeNodes .IsSameTypeNode isSameTypeNode ,
1390
+ @ Cached ("create(InstanceCheck)" ) LookupAndCallBinaryNode instanceCheckNode ,
1391
+ @ Cached PyObjectIsTrueNode isTrueNode ,
1392
+ @ Cached TypeNodes .GenericInstanceCheckNode genericInstanceCheckNode ,
1393
+ @ Cached InlinedBranchProfile noInstanceCheckProfile ) {
1394
+ if (isSameTypeNode .execute (inliningTarget , getInstanceClassNode .execute (inliningTarget , instance ), cls )) {
1395
+ // Exact match, don't call __instancecheck__
1396
+ return true ;
1397
+ }
1398
+ if (classProfile .profileClass (inliningTarget , getClsClassNode .execute (inliningTarget , cls ), PythonBuiltinClassType .PythonClass )) {
1399
+ // Avoid the lookup and call overhead when we know we're calling
1400
+ // type.__instancecheck__
1401
+ return genericInstanceCheckNode .execute (frame , inliningTarget , instance , cls );
1402
+ }
1386
1403
try {
1387
- Object instanceCheckResult = instanceCheckNode .executeObject (frame , cls , instance );
1388
- return TriState . valueOf ( castToBooleanNode . execute (frame , instanceCheckResult ) );
1404
+ Object result = instanceCheckNode .executeObject (frame , cls , instance );
1405
+ return isTrueNode . execute (frame , result );
1389
1406
} catch (SpecialMethodNotFound ignore ) {
1390
- return TriState .UNDEFINED ;
1391
- }
1392
- }
1393
-
1394
- @ Specialization (guards = "isPythonClass(cls)" )
1395
- static boolean isInstance (VirtualFrame frame , Object instance , Object cls ,
1396
- @ Bind ("this" ) Node inliningTarget ,
1397
- @ Shared ("instanceCheck" ) @ Cached ("create(InstanceCheck)" ) LookupAndCallBinaryNode instanceCheckNode ,
1398
- @ Exclusive @ Cached PyObjectIsTrueNode castToBooleanNode ,
1399
- @ Cached GetClassNode getClassNode ,
1400
- @ Cached IsSameTypeNode isSameTypeNode ,
1401
- @ Cached IsSubtypeNode isSubtypeNode ) {
1402
- Object instanceClass = getClassNode .execute (inliningTarget , instance );
1403
- return isSameTypeNode .execute (inliningTarget , instanceClass , cls ) || isSubtypeNode .execute (frame , instanceClass , cls )//
1404
- || isInstanceCheckInternal (frame , instance , cls , instanceCheckNode , castToBooleanNode ) == TriState .TRUE ;
1405
- }
1406
-
1407
- @ Specialization (guards = {"!isPTuple(cls)" , "!isPythonClass(cls)" })
1408
- static boolean isInstance (VirtualFrame frame , Object instance , Object cls ,
1409
- @ Bind ("this" ) Node inliningTarget ,
1410
- @ Shared ("instanceCheck" ) @ Cached ("create(InstanceCheck)" ) LookupAndCallBinaryNode instanceCheckNode ,
1411
- @ Exclusive @ Cached PyObjectIsTrueNode castToBooleanNode ,
1412
- @ Cached TypeBuiltins .InstanceCheckNode typeInstanceCheckNode ) {
1413
- TriState check = isInstanceCheckInternal (frame , instance , cls , instanceCheckNode , castToBooleanNode );
1414
- if (check == TriState .UNDEFINED ) {
1415
- return typeInstanceCheckNode .executeWith (frame , cls , instance );
1407
+ noInstanceCheckProfile .enter (inliningTarget );
1408
+ return genericInstanceCheckNode .execute (frame , inliningTarget , instance , cls );
1416
1409
}
1417
- return check == TriState .TRUE ;
1418
1410
}
1419
1411
}
1420
1412
@@ -1439,14 +1431,24 @@ public IsSubClassNode createRecursive(byte newDepth) {
1439
1431
1440
1432
@ Specialization (guards = "!isPTuple(cls)" )
1441
1433
static boolean isSubclass (VirtualFrame frame , Object derived , Object cls ,
1434
+ @ Bind Node inliningTarget ,
1435
+ @ Cached GetClassNode getClsClassNode ,
1436
+ @ Cached IsBuiltinClassExactProfile classProfile ,
1442
1437
@ Cached ("create(Subclasscheck)" ) LookupAndCallBinaryNode subclassCheckNode ,
1443
- @ Cached PyObjectIsTrueNode castToBooleanNode ,
1444
- @ Cached IsSubtypeNode isSubtypeNode ) {
1438
+ @ Cached PyObjectIsTrueNode isTrueNode ,
1439
+ @ Cached TypeNodes .GenericSubclassCheckNode genericSubclassCheckNode ,
1440
+ @ Cached InlinedBranchProfile noInstanceCheckProfile ) {
1441
+ if (classProfile .profileClass (inliningTarget , getClsClassNode .execute (inliningTarget , cls ), PythonBuiltinClassType .PythonClass )) {
1442
+ // Avoid the lookup and call overhead when we know we're calling
1443
+ // type.__subclasscheck__
1444
+ return genericSubclassCheckNode .execute (frame , inliningTarget , derived , cls );
1445
+ }
1445
1446
try {
1446
- Object instanceCheckResult = subclassCheckNode .executeObject (frame , cls , derived );
1447
- return castToBooleanNode .execute (frame , instanceCheckResult );
1447
+ Object result = subclassCheckNode .executeObject (frame , cls , derived );
1448
+ return isTrueNode .execute (frame , result );
1448
1449
} catch (SpecialMethodNotFound ignore ) {
1449
- return isSubtypeNode .execute (frame , derived , cls );
1450
+ noInstanceCheckProfile .enter (inliningTarget );
1451
+ return genericSubclassCheckNode .execute (frame , inliningTarget , derived , cls );
1450
1452
}
1451
1453
}
1452
1454
@@ -1508,9 +1510,7 @@ static Object minmaxSequenceWithKey(VirtualFrame frame, Node inliningTarget, Obj
1508
1510
@ Exclusive @ Cached PyObjectRichCompareBool compareNode ,
1509
1511
@ Exclusive @ Cached PyObjectGetIter getIter ,
1510
1512
@ Exclusive @ Cached PyIterNextNode nextNode ,
1511
- @ Exclusive @ Cached PyObjectIsTrueNode castToBooleanNode ,
1512
1513
@ Exclusive @ Cached CallNode .Lazy keyCall ,
1513
- @ Exclusive @ Cached InlinedBranchProfile seenNonBoolean ,
1514
1514
@ Exclusive @ Cached InlinedConditionProfile keywordArgIsNone ,
1515
1515
@ Exclusive @ Cached InlinedConditionProfile hasDefaultProfile ,
1516
1516
@ Exclusive @ Cached PRaiseNode raiseNode ) {
@@ -1555,8 +1555,6 @@ static Object minmaxBinaryWithKey(VirtualFrame frame, Node inliningTarget, Objec
1555
1555
RichCmpOp op ,
1556
1556
@ Exclusive @ Cached PyObjectRichCompareBool compareNode ,
1557
1557
@ Exclusive @ Cached CallNode .Lazy keyCall ,
1558
- @ Exclusive @ Cached PyObjectIsTrueNode castToBooleanNode ,
1559
- @ Exclusive @ Cached InlinedBranchProfile seenNonBoolean ,
1560
1558
@ Exclusive @ Cached InlinedConditionProfile keywordArgIsNone ,
1561
1559
@ Exclusive @ Cached InlinedConditionProfile moreThanTwo ,
1562
1560
@ Exclusive @ Cached InlinedLoopConditionProfile loopProfile ,
0 commit comments