6060import static com .oracle .graal .python .nodes .StringLiterals .T_NONE ;
6161import static com .oracle .graal .python .runtime .exception .PythonErrorType .AttributeError ;
6262import static com .oracle .graal .python .runtime .exception .PythonErrorType .TypeError ;
63+ import static com .oracle .graal .python .util .PythonUtils .TS_ENCODING ;
6364
6465import java .util .List ;
6566
130131import com .oracle .graal .python .nodes .util .CannotCastException ;
131132import com .oracle .graal .python .nodes .util .CastToTruffleStringNode ;
132133import com .oracle .graal .python .nodes .util .SplitArgsNode ;
134+ import com .oracle .truffle .api .CompilerAsserts ;
133135import com .oracle .truffle .api .CompilerDirectives ;
134136import com .oracle .truffle .api .CompilerDirectives .CompilationFinal ;
135137import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
139141import com .oracle .truffle .api .dsl .ImportStatic ;
140142import com .oracle .truffle .api .dsl .NodeFactory ;
141143import com .oracle .truffle .api .dsl .Specialization ;
144+ import com .oracle .truffle .api .dsl .Cached .Shared ;
142145import com .oracle .truffle .api .frame .VirtualFrame ;
143146import com .oracle .truffle .api .interop .InteropLibrary ;
144147import com .oracle .truffle .api .library .CachedLibrary ;
@@ -395,10 +398,26 @@ public abstract static class GetAttributeNode extends PythonBinaryBuiltinNode {
395398 @ Child private ReadAttributeFromObjectNode attrRead ;
396399 @ Child private GetClassNode getDescClassNode ;
397400
401+ protected static int tsLen (TruffleString ts ) {
402+ CompilerAsserts .neverPartOfCompilation ();
403+ return TruffleString .CodePointLengthNode .getUncached ().execute (ts , TS_ENCODING );
404+ }
405+
406+ // Shortcut, only useful for interpreter performance, but doesn't hurt peak
407+ @ Specialization (guards = {"keyObj == cachedKey" , "tsLen(cachedKey) < 32" }, limit = "1" )
408+ protected Object doItTruffleString (VirtualFrame frame , Object object , @ SuppressWarnings ("unused" ) TruffleString keyObj ,
409+ @ SuppressWarnings ("unused" ) @ Cached ("keyObj" ) TruffleString cachedKey ,
410+ @ Shared ("getClassNode" ) @ Cached GetClassNode getClassNode ,
411+ @ Cached ("create(cachedKey)" ) LookupAttributeInMRONode lookup ) {
412+ Object type = getClassNode .execute (object );
413+ Object descr = lookup .execute (type );
414+ return fullLookup (frame , object , cachedKey , type , descr );
415+ }
416+
398417 @ Specialization
399418 protected Object doIt (VirtualFrame frame , Object object , Object keyObj ,
400419 @ Cached LookupAttributeInMRONode .Dynamic lookup ,
401- @ Cached GetClassNode getClassNode ,
420+ @ Shared ( "getClassNode" ) @ Cached GetClassNode getClassNode ,
402421 @ Cached CastToTruffleStringNode castKeyToStringNode ) {
403422 TruffleString key ;
404423 try {
@@ -409,6 +428,10 @@ protected Object doIt(VirtualFrame frame, Object object, Object keyObj,
409428
410429 Object type = getClassNode .execute (object );
411430 Object descr = lookup .execute (type , key );
431+ return fullLookup (frame , object , key , type , descr );
432+ }
433+
434+ private Object fullLookup (VirtualFrame frame , Object object , TruffleString key , Object type , Object descr ) {
412435 Object dataDescClass = null ;
413436 boolean hasDescr = descr != PNone .NO_VALUE ;
414437 if (hasDescr && (profileFlags & HAS_DESCR ) == 0 ) {
0 commit comments