Skip to content

Commit e9c88c7

Browse files
committed
[GR-76035] Quicken attribute stores.
PullRequest: graalpython/4579
2 parents c717d71 + c2d61a0 commit e9c88c7

2 files changed

Lines changed: 51 additions & 16 deletions

File tree

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,6 @@
310310
import com.oracle.truffle.api.nodes.Node;
311311
import com.oracle.truffle.api.nodes.RootNode;
312312
import com.oracle.truffle.api.object.DynamicObject;
313-
import com.oracle.truffle.api.object.Property;
314313
import com.oracle.truffle.api.object.PropertyGetter;
315314
import com.oracle.truffle.api.object.Shape;
316315
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
@@ -1933,19 +1932,8 @@ public static Object doIt(VirtualFrame frame,
19331932

19341933
@Operation(storeBytecodeIndex = true)
19351934
@ConstantOperand(type = TruffleString.class)
1936-
@ImportStatic({PGuards.class, TpSlots.class})
1935+
@ImportStatic({PGuards.class, TpSlots.class, PythonUtils.class})
19371936
public static final class GetAttribute {
1938-
static PropertyGetter getPropertyGetterWithFinalAssumption(Shape shape, Object key) {
1939-
PropertyGetter getter = shape.makePropertyGetter(key);
1940-
if (getter != null) {
1941-
Property property = shape.getProperty(key);
1942-
if (property != null) {
1943-
property.getLocation().getFinalAssumption();
1944-
}
1945-
}
1946-
return getter;
1947-
}
1948-
19491937
// Builtin module object fast-path: we know there aren't any descriptors for other than
19501938
// dunder (__xxx__) names
19511939
public static Object loadModuleValue(PythonModule object, Shape cachedShape, PropertyGetter cachedPropertyGetter) {
@@ -2018,7 +2006,7 @@ static Object doType(VirtualFrame frame, TruffleString key, PythonManagedClass r
20182006
return value;
20192007
}
20202008

2021-
// Object instance field fast-path: for cases where there is no descriptor and it's just
2009+
// Object instance field fast-path: for cases where there is no descriptor, and it's just
20222010
// simple DOM property read
20232011
public static Object loadInstanceValue(Node inliningTarget, PythonObject object, LookupAttributeInMRONode getDesc, Shape cachedShape, PropertyGetter cachedPropertyGetter,
20242012
InlineWeakValueProfile slotsValueProfile) {
@@ -2086,13 +2074,46 @@ public static Object doItUncached(VirtualFrame frame, TruffleString key, Object
20862074
@Operation(storeBytecodeIndex = true)
20872075
@ConstantOperand(type = TruffleString.class)
20882076
public static final class SetAttribute {
2089-
@Specialization
2077+
public static boolean canStoreInstanceValue(Node inliningTarget, PythonObject object, Shape cachedShape, LookupAttributeInMRONode getDesc,
2078+
GetObjectSlotsNode getDescSlotsNode, InlineWeakValueProfile slotsValueProfile) {
2079+
TpSlots slots;
2080+
Object type = cachedShape.getDynamicType();
2081+
if (type instanceof PythonBuiltinClassType pbct) {
2082+
slots = pbct.getSlots();
2083+
} else if (type instanceof PythonManagedClass klass) {
2084+
slots = slotsValueProfile.execute(inliningTarget, klass.getTpSlots());
2085+
} else {
2086+
return false;
2087+
}
2088+
if (slots.tp_setattro() == ObjectBuiltins.SLOTS.tp_setattro()) {
2089+
Object descr = getDesc.execute(type);
2090+
if (descr == PNone.NO_VALUE || getDescSlotsNode.execute(inliningTarget, descr).tp_descr_set() == null) {
2091+
assert object.checkDictFlags();
2092+
return (cachedShape.getFlags() & (PythonObject.HAS_MATERIALIZED_DICT | PythonObject.HAS_SLOTS_BUT_NO_DICT_FLAG)) == 0;
2093+
}
2094+
}
2095+
return false;
2096+
}
2097+
2098+
@ForceQuickening
2099+
@Specialization(guards = {"cachedShape.check(receiver)", "canStoreInstanceValue(inliningTarget, receiver, cachedShape, getDesc, getDescSlotsNode, slotsValueProfile)"}, limit = "3")
2100+
static void doInstanceValue(TruffleString key, Object value, PythonObject receiver,
2101+
@Bind Node inliningTarget,
2102+
@Cached("receiver.getShape()") Shape cachedShape,
2103+
@Cached("create(key)") LookupAttributeInMRONode getDesc,
2104+
@Cached GetObjectSlotsNode getDescSlotsNode,
2105+
@Cached InlineWeakValueProfile slotsValueProfile,
2106+
@Cached DynamicObject.PutNode putNode) {
2107+
putNode.execute(receiver, key, value);
2108+
}
2109+
2110+
@Specialization(replaces = "doInstanceValue")
20902111
public static void doIt(VirtualFrame frame,
20912112
TruffleString key,
20922113
Object value,
20932114
Object object,
20942115
@Bind Node inliningTarget,
2095-
@Cached PyObjectSetAttr setAttrNode) {
2116+
@Exclusive @Cached PyObjectSetAttr setAttrNode) {
20962117
setAttrNode.execute(frame, inliningTarget, object, key, value);
20972118
}
20982119
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/PythonUtils.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@
100100
import com.oracle.truffle.api.nodes.NodeUtil;
101101
import com.oracle.truffle.api.nodes.NodeVisitor;
102102
import com.oracle.truffle.api.nodes.RootNode;
103+
import com.oracle.truffle.api.object.Property;
104+
import com.oracle.truffle.api.object.PropertyGetter;
105+
import com.oracle.truffle.api.object.Shape;
103106
import com.oracle.truffle.api.profiles.ConditionProfile;
104107
import com.oracle.truffle.api.source.Source;
105108
import com.oracle.truffle.api.strings.TruffleString;
@@ -1097,4 +1100,15 @@ public List<Class<? extends Node>> getExecutionSignature() {
10971100
throw new IllegalAccessError();
10981101
}
10991102
}
1103+
1104+
public static PropertyGetter getPropertyGetterWithFinalAssumption(Shape shape, Object key) {
1105+
PropertyGetter getter = shape.makePropertyGetter(key);
1106+
if (getter != null) {
1107+
Property property = shape.getProperty(key);
1108+
if (property != null) {
1109+
property.getLocation().getFinalAssumption();
1110+
}
1111+
}
1112+
return getter;
1113+
}
11001114
}

0 commit comments

Comments
 (0)