|
310 | 310 | import com.oracle.truffle.api.nodes.Node; |
311 | 311 | import com.oracle.truffle.api.nodes.RootNode; |
312 | 312 | import com.oracle.truffle.api.object.DynamicObject; |
313 | | -import com.oracle.truffle.api.object.Property; |
314 | 313 | import com.oracle.truffle.api.object.PropertyGetter; |
315 | 314 | import com.oracle.truffle.api.object.Shape; |
316 | 315 | import com.oracle.truffle.api.profiles.InlinedBranchProfile; |
@@ -1928,19 +1927,8 @@ public static Object doIt(VirtualFrame frame, |
1928 | 1927 |
|
1929 | 1928 | @Operation(storeBytecodeIndex = true) |
1930 | 1929 | @ConstantOperand(type = TruffleString.class) |
1931 | | - @ImportStatic({PGuards.class, TpSlots.class}) |
| 1930 | + @ImportStatic({PGuards.class, TpSlots.class, PythonUtils.class}) |
1932 | 1931 | public static final class GetAttribute { |
1933 | | - static PropertyGetter getPropertyGetterWithFinalAssumption(Shape shape, Object key) { |
1934 | | - PropertyGetter getter = shape.makePropertyGetter(key); |
1935 | | - if (getter != null) { |
1936 | | - Property property = shape.getProperty(key); |
1937 | | - if (property != null) { |
1938 | | - property.getLocation().getFinalAssumption(); |
1939 | | - } |
1940 | | - } |
1941 | | - return getter; |
1942 | | - } |
1943 | | - |
1944 | 1932 | // Builtin module object fast-path: we know there aren't any descriptors for other than |
1945 | 1933 | // dunder (__xxx__) names |
1946 | 1934 | public static Object loadModuleValue(PythonModule object, Shape cachedShape, PropertyGetter cachedPropertyGetter) { |
@@ -2013,7 +2001,7 @@ static Object doType(VirtualFrame frame, TruffleString key, PythonManagedClass r |
2013 | 2001 | return value; |
2014 | 2002 | } |
2015 | 2003 |
|
2016 | | - // Object instance field fast-path: for cases where there is no descriptor and it's just |
| 2004 | + // Object instance field fast-path: for cases where there is no descriptor, and it's just |
2017 | 2005 | // simple DOM property read |
2018 | 2006 | public static Object loadInstanceValue(Node inliningTarget, PythonObject object, LookupAttributeInMRONode getDesc, Shape cachedShape, PropertyGetter cachedPropertyGetter, |
2019 | 2007 | InlineWeakValueProfile slotsValueProfile) { |
@@ -2081,13 +2069,46 @@ public static Object doItUncached(VirtualFrame frame, TruffleString key, Object |
2081 | 2069 | @Operation(storeBytecodeIndex = true) |
2082 | 2070 | @ConstantOperand(type = TruffleString.class) |
2083 | 2071 | public static final class SetAttribute { |
2084 | | - @Specialization |
| 2072 | + public static boolean canStoreInstanceValue(Node inliningTarget, PythonObject object, Shape cachedShape, LookupAttributeInMRONode getDesc, |
| 2073 | + GetObjectSlotsNode getDescSlotsNode, InlineWeakValueProfile slotsValueProfile) { |
| 2074 | + TpSlots slots; |
| 2075 | + Object type = cachedShape.getDynamicType(); |
| 2076 | + if (type instanceof PythonBuiltinClassType pbct) { |
| 2077 | + slots = pbct.getSlots(); |
| 2078 | + } else if (type instanceof PythonManagedClass klass) { |
| 2079 | + slots = slotsValueProfile.execute(inliningTarget, klass.getTpSlots()); |
| 2080 | + } else { |
| 2081 | + return false; |
| 2082 | + } |
| 2083 | + if (slots.tp_setattro() == ObjectBuiltins.SLOTS.tp_setattro()) { |
| 2084 | + Object descr = getDesc.execute(type); |
| 2085 | + if (descr == PNone.NO_VALUE || getDescSlotsNode.execute(inliningTarget, descr).tp_descr_set() == null) { |
| 2086 | + assert object.checkDictFlags(); |
| 2087 | + return (cachedShape.getFlags() & (PythonObject.HAS_MATERIALIZED_DICT | PythonObject.HAS_SLOTS_BUT_NO_DICT_FLAG)) == 0; |
| 2088 | + } |
| 2089 | + } |
| 2090 | + return false; |
| 2091 | + } |
| 2092 | + |
| 2093 | + @ForceQuickening |
| 2094 | + @Specialization(guards = {"cachedShape.check(receiver)", "canStoreInstanceValue(inliningTarget, receiver, cachedShape, getDesc, getDescSlotsNode, slotsValueProfile)"}, limit = "3") |
| 2095 | + static void doInstanceValue(TruffleString key, Object value, PythonObject receiver, |
| 2096 | + @Bind Node inliningTarget, |
| 2097 | + @Cached("receiver.getShape()") Shape cachedShape, |
| 2098 | + @Cached("create(key)") LookupAttributeInMRONode getDesc, |
| 2099 | + @Cached GetObjectSlotsNode getDescSlotsNode, |
| 2100 | + @Cached InlineWeakValueProfile slotsValueProfile, |
| 2101 | + @Cached DynamicObject.PutNode putNode) { |
| 2102 | + putNode.execute(receiver, key, value); |
| 2103 | + } |
| 2104 | + |
| 2105 | + @Specialization(replaces = "doInstanceValue") |
2085 | 2106 | public static void doIt(VirtualFrame frame, |
2086 | 2107 | TruffleString key, |
2087 | 2108 | Object value, |
2088 | 2109 | Object object, |
2089 | 2110 | @Bind Node inliningTarget, |
2090 | | - @Cached PyObjectSetAttr setAttrNode) { |
| 2111 | + @Exclusive @Cached PyObjectSetAttr setAttrNode) { |
2091 | 2112 | setAttrNode.execute(frame, inliningTarget, object, key, value); |
2092 | 2113 | } |
2093 | 2114 | } |
|
0 commit comments