5252import com .oracle .graal .python .builtins .objects .function .PArguments ;
5353import com .oracle .graal .python .builtins .objects .function .PKeyword ;
5454import com .oracle .graal .python .builtins .objects .str .PString ;
55+ import com .oracle .graal .python .builtins .objects .superobject .SuperBuiltinsFactory .GetObjectNodeGen ;
56+ import com .oracle .graal .python .builtins .objects .superobject .SuperBuiltinsFactory .GetObjectTypeNodeGen ;
57+ import com .oracle .graal .python .builtins .objects .superobject .SuperBuiltinsFactory .GetTypeNodeGen ;
5558import com .oracle .graal .python .builtins .objects .superobject .SuperBuiltinsFactory .SuperInitNodeFactory ;
5659import com .oracle .graal .python .builtins .objects .type .PythonClass ;
5760import com .oracle .graal .python .nodes .SpecialAttributeNames ;
8487import com .oracle .truffle .api .frame .FrameSlot ;
8588import com .oracle .truffle .api .frame .FrameSlotTypeException ;
8689import com .oracle .truffle .api .frame .VirtualFrame ;
90+ import com .oracle .truffle .api .nodes .Node ;
8791import com .oracle .truffle .api .profiles .ConditionProfile ;
8892
8993@ CoreFunctions (extendClasses = PythonBuiltinClassType .Super )
@@ -93,6 +97,54 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
9397 return SuperBuiltinsFactory .getFactories ();
9498 }
9599
100+ abstract static class GetTypeNode extends Node {
101+ abstract Object execute (SuperObject self );
102+
103+ @ Specialization (guards = "self == cachedSelf" , assumptions = "cachedSelf.getNeverReinitializedAssumption()" , limit = "1" )
104+ Object cached (@ SuppressWarnings ("unused" ) SuperObject self ,
105+ @ SuppressWarnings ("unused" ) @ Cached ("self" ) SuperObject cachedSelf ,
106+ @ Cached ("self.getType()" ) Object type ) {
107+ return type ;
108+ }
109+
110+ @ Specialization (replaces = "cached" )
111+ Object uncached (SuperObject self ) {
112+ return self .getType ();
113+ }
114+ }
115+
116+ abstract static class GetObjectTypeNode extends Node {
117+ abstract PythonClass execute (SuperObject self );
118+
119+ @ Specialization (guards = "self == cachedSelf" , assumptions = "cachedSelf.getNeverReinitializedAssumption()" , limit = "1" )
120+ PythonClass cached (@ SuppressWarnings ("unused" ) SuperObject self ,
121+ @ SuppressWarnings ("unused" ) @ Cached ("self" ) SuperObject cachedSelf ,
122+ @ Cached ("self.getObjectType()" ) PythonClass type ) {
123+ return type ;
124+ }
125+
126+ @ Specialization (replaces = "cached" )
127+ PythonClass uncached (SuperObject self ) {
128+ return self .getObjectType ();
129+ }
130+ }
131+
132+ abstract static class GetObjectNode extends Node {
133+ abstract Object execute (SuperObject self );
134+
135+ @ Specialization (guards = "self == cachedSelf" , assumptions = "cachedSelf.getNeverReinitializedAssumption()" , limit = "1" )
136+ Object cached (@ SuppressWarnings ("unused" ) SuperObject self ,
137+ @ SuppressWarnings ("unused" ) @ Cached ("self" ) SuperObject cachedSelf ,
138+ @ Cached ("self.getObject()" ) Object object ) {
139+ return object ;
140+ }
141+
142+ @ Specialization (replaces = "cached" )
143+ Object uncached (SuperObject self ) {
144+ return self .getObject ();
145+ }
146+ }
147+
96148 @ Builtin (name = SpecialMethodNames .__INIT__ , minNumOfPositionalArgs = 1 , takesVarArgs = true , takesVarKeywordArgs = true , alwaysNeedsCallerFrame = true )
97149 @ GenerateNodeFactory
98150 public abstract static class SuperInitNode extends PythonVarargsBuiltinNode {
@@ -307,20 +359,23 @@ private PythonClass supercheck(Object cls, Object object) {
307359 @ Builtin (name = SpecialMethodNames .__GET__ , fixedNumOfPositionalArgs = 2 , keywordArguments = {"type" })
308360 @ GenerateNodeFactory
309361 public abstract static class GetNode extends PythonTernaryBuiltinNode {
362+ @ Child GetObjectNode getObject = GetObjectNodeGen .create ();
363+ @ Child GetTypeNode getType ;
310364 @ Child SuperInitNode superInit ;
311365
312366 @ Specialization
313367 public Object get (SuperObject self , Object obj , @ SuppressWarnings ("unused" ) Object type ) {
314- if (obj == PNone .NONE || self . getObject ( ) != null ) {
368+ if (obj == PNone .NONE || getObject . execute ( self ) != null ) {
315369 // not binding to an object or already bound
316370 return this ;
317371 } else {
318372 if (superInit == null ) {
319373 CompilerDirectives .transferToInterpreterAndInvalidate ();
320374 superInit = insert (SuperInitNodeFactory .create ());
375+ getType = insert (GetTypeNodeGen .create ());
321376 }
322377 SuperObject newSuper = factory ().createSuperObject (self .getPythonClass ());
323- superInit .execute (null , newSuper , self . getType ( ), obj );
378+ superInit .execute (null , newSuper , getType . execute ( self ), obj );
324379 return newSuper ;
325380 }
326381 }
@@ -331,6 +386,9 @@ public Object get(SuperObject self, Object obj, @SuppressWarnings("unused") Obje
331386 public abstract static class GetattributeNode extends PythonBinaryBuiltinNode {
332387 @ Child ReadAttributeFromObjectNode readFromDict = ReadAttributeFromObjectNode .create ();
333388 @ Child LookupInheritedAttributeNode readGet = LookupInheritedAttributeNode .create (SpecialMethodNames .__GET__ );
389+ @ Child GetObjectTypeNode getObjectType = GetObjectTypeNodeGen .create ();
390+ @ Child GetTypeNode getType ;
391+ @ Child GetObjectNode getObject ;
334392 @ Child CallTernaryMethodNode callGet ;
335393 @ Child LookupAndCallBinaryNode getAttr ;
336394
@@ -342,17 +400,9 @@ private Object genericGetAttr(Object object, Object attr) {
342400 return getAttr .executeObject (object , attr );
343401 }
344402
345- private CallTernaryMethodNode getCallGet () {
346- if (callGet == null ) {
347- CompilerDirectives .transferToInterpreterAndInvalidate ();
348- callGet = insert (CallTernaryMethodNode .create ());
349- }
350- return callGet ;
351- }
352-
353403 @ Specialization
354404 public Object get (SuperObject self , Object attr ) {
355- PythonClass startType = self . getObjectType ( );
405+ PythonClass startType = getObjectType . execute ( self );
356406 if (startType == null ) {
357407 return genericGetAttr (self , attr );
358408 }
@@ -373,12 +423,18 @@ public Object get(SuperObject self, Object attr) {
373423 }
374424 }
375425
426+ // acts as a branch profile
427+ if (getType == null ) {
428+ CompilerDirectives .transferToInterpreterAndInvalidate ();
429+ getType = insert (GetTypeNodeGen .create ());
430+ }
431+
376432 PythonClass [] mro = startType .getMethodResolutionOrder ();
377433 /* No need to check the last one: it's gonna be skipped anyway. */
378434 int i = 0 ;
379435 int n = mro .length ;
380436 for (i = 0 ; i + 1 < n ; i ++) {
381- if (self . getType ( ) == mro [i ]) {
437+ if (getType . execute ( self ) == mro [i ]) {
382438 break ;
383439 }
384440 }
@@ -396,7 +452,13 @@ public Object get(SuperObject self, Object attr) {
396452 /*
397453 * Only pass 'obj' param if this is instance-mode super (See SF ID #743627)
398454 */
399- res = getCallGet ().execute (get , res , self .getObject () == startType ? PNone .NO_VALUE : self .getObject (), startType );
455+ // acts as a branch profile
456+ if (getObject == null ) {
457+ CompilerDirectives .transferToInterpreterAndInvalidate ();
458+ getObject = insert (GetObjectNodeGen .create ());
459+ callGet = insert (CallTernaryMethodNode .create ());
460+ }
461+ res = callGet .execute (get , res , getObject .execute (self ) == startType ? PNone .NO_VALUE : self .getObject (), startType );
400462 }
401463 return res ;
402464 }
@@ -409,9 +471,11 @@ public Object get(SuperObject self, Object attr) {
409471 @ Builtin (name = "__thisclass__" , fixedNumOfPositionalArgs = 1 , isGetter = true )
410472 @ GenerateNodeFactory
411473 public abstract static class ThisClassNode extends PythonUnaryBuiltinNode {
474+ @ Child GetTypeNode getType = GetTypeNodeGen .create ();
475+
412476 @ Specialization
413477 Object getClass (SuperObject self ) {
414- Object type = self . getType ( );
478+ Object type = getType . execute ( self );
415479 if (type == null ) {
416480 return PNone .NONE ;
417481 }
@@ -422,9 +486,11 @@ Object getClass(SuperObject self) {
422486 @ Builtin (name = "__self__" , fixedNumOfPositionalArgs = 1 , isGetter = true )
423487 @ GenerateNodeFactory
424488 public abstract static class SelfNode extends PythonUnaryBuiltinNode {
489+ @ Child GetObjectNode getObject = GetObjectNodeGen .create ();
490+
425491 @ Specialization
426492 Object getClass (SuperObject self ) {
427- Object object = self . getObject ( );
493+ Object object = getObject . execute ( self );
428494 if (object == null ) {
429495 return PNone .NONE ;
430496 }
@@ -435,9 +501,11 @@ Object getClass(SuperObject self) {
435501 @ Builtin (name = "__self_class__" , fixedNumOfPositionalArgs = 1 , isGetter = true )
436502 @ GenerateNodeFactory
437503 public abstract static class SelfClassNode extends PythonUnaryBuiltinNode {
504+ @ Child GetObjectTypeNode getObjectType = GetObjectTypeNodeGen .create ();
505+
438506 @ Specialization
439507 Object getClass (SuperObject self ) {
440- PythonClass objectType = self . getObjectType ( );
508+ PythonClass objectType = getObjectType . execute ( self );
441509 if (objectType == null ) {
442510 return PNone .NONE ;
443511 }
0 commit comments