Skip to content

Commit 8f2487d

Browse files
committed
Simplify attribute writes
1 parent bff1874 commit 8f2487d

File tree

5 files changed

+35
-97
lines changed

5 files changed

+35
-97
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingStorageNodes.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,10 @@ static HashingStorage foreign(Node inliningTarget, ForeignHashingStorage self, O
444444
return self;
445445
}
446446

447+
public static HashingStorageSetItem getUncached() {
448+
return HashingStorageSetItemNodeGen.getUncached();
449+
}
450+
447451
@GenerateUncached
448452
@GenerateInline
449453
@GenerateCached(false)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonClass.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,12 +282,6 @@ public boolean hasMroShapeSubTypes() {
282282
return mroShapeSubTypes != null;
283283
}
284284

285-
@Override
286-
public boolean canSkipOnAttributeUpdate(TruffleString key, @SuppressWarnings("unused") Object newValue, TruffleString.CodePointLengthNode codePointLengthNode,
287-
TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
288-
return super.canSkipOnAttributeUpdate(key, newValue, codePointLengthNode, codePointAtIndexNode) && mroShapeSubTypes == null;
289-
}
290-
291285
@TruffleBoundary
292286
@Override
293287
public void onAttributeUpdate(TruffleString key, Object newValue) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonManagedClass.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -207,16 +207,6 @@ public void setAttribute(TruffleString key, Object value) {
207207
onAttributeUpdate(key, value);
208208
}
209209

210-
/**
211-
* Fast-path check designed for PE code.
212-
*/
213-
public boolean canSkipOnAttributeUpdate(TruffleString key, @SuppressWarnings("unused") Object value, TruffleString.CodePointLengthNode codePointLengthNode,
214-
TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
215-
// TODO subclasses
216-
return !methodResolutionOrder.hasAttributeInMROFinalAssumptions() &&
217-
!TpSlots.canBeSpecialMethod(key, codePointLengthNode, codePointAtIndexNode);
218-
}
219-
220210
@TruffleBoundary
221211
public void onAttributeUpdate(TruffleString key, Object value) {
222212
for (PythonAbstractClass subclass : GetSubclassesAsArrayNode.executeUncached(this)) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/WriteAttributeToObjectNode.java

Lines changed: 31 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@
6060
import com.oracle.graal.python.builtins.objects.type.TpSlots;
6161
import com.oracle.graal.python.builtins.objects.type.TypeFlags;
6262
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
63-
import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode;
6463
import com.oracle.graal.python.nodes.ErrorMessages;
6564
import com.oracle.graal.python.nodes.PNodeWithContext;
6665
import com.oracle.graal.python.nodes.PRaiseNode;
6766
import com.oracle.graal.python.nodes.object.GetDictIfExistsNode;
6867
import com.oracle.graal.python.runtime.PythonContext;
6968
import com.oracle.truffle.api.CompilerAsserts;
69+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
7070
import com.oracle.truffle.api.dsl.Bind;
7171
import com.oracle.truffle.api.dsl.Cached;
7272
import com.oracle.truffle.api.dsl.Cached.Exclusive;
@@ -95,7 +95,7 @@ static boolean isAttrWritable(PythonObject self) {
9595
return (self.getShape().getFlags() & PythonObject.HAS_SLOTS_BUT_NO_DICT_FLAG) == 0;
9696
}
9797

98-
static boolean writeToDynamicStorageNoTypeGuard(Object obj, GetDictIfExistsNode getDict) {
98+
static boolean writeToDynamicStorageNoTypeGuard(PythonObject obj, GetDictIfExistsNode getDict) {
9999
return getDict.execute(obj) == null && !PythonManagedClass.isInstance(obj);
100100
}
101101

@@ -112,49 +112,48 @@ static boolean writeToDynamicStorageNoType(PythonObject object, TruffleString ke
112112
return true;
113113
}
114114

115-
// Specializations for no dict & PythonManagedClass -> requires calling onAttributeUpdate
116-
@Specialization(guards = {"isAttrWritable(klass)", "getDict.execute(klass) == null"})
117-
boolean writeToDynamicStorageBuiltinType(PythonBuiltinClass klass, TruffleString key, Object value,
118-
@Bind Node inliningTarget,
119-
@SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict,
120-
@Shared("callAttrUpdate") @Cached InlinedBranchProfile callAttrUpdate,
121-
@Shared("dylib") @CachedLibrary(limit = "getAttributeAccessInlineCacheMaxDepth()") DynamicObjectLibrary dylib,
122-
@Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode,
123-
@Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
124-
if (PythonContext.get(this).isInitialized()) {
115+
@Specialization(guards = "isPythonBuiltinClass(klassOrType) || isPythonBuiltinClassType(klassOrType)")
116+
@TruffleBoundary
117+
boolean writeToDynamicStorageBuiltinType(Object klassOrType, TruffleString key, Object value) {
118+
PythonContext context = PythonContext.get(this);
119+
PythonBuiltinClass klass;
120+
if (klassOrType instanceof PythonBuiltinClass pbc) {
121+
klass = pbc;
122+
} else {
123+
klass = context.lookupType((PythonBuiltinClassType) klassOrType);
124+
}
125+
if (context.isInitialized() || value == PNone.NO_VALUE) {
125126
throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, key, klass);
126127
} else {
127-
return writeToDynamicStorageManagedClass(klass, key, value, inliningTarget, callAttrUpdate, dylib, codePointLengthNode, codePointAtIndexNode);
128+
PDict dict = GetDictIfExistsNode.getUncached().execute(klass);
129+
if (dict == null) {
130+
return writeToDynamicStorageManagedClass(klass, key, value, DynamicObjectLibrary.getUncached());
131+
} else {
132+
return writeToDictManagedClass(klass, dict, key, value, null, InlinedBranchProfile.getUncached(), HashingStorageSetItem.getUncached());
133+
}
128134
}
129135
}
130136

131137
@Specialization(guards = {"isAttrWritable(klass)", "getDict.execute(klass) == null"})
132138
static boolean writeToDynamicStoragePythonClass(PythonClass klass, TruffleString key, Object value,
133139
@Bind Node inliningTarget,
134140
@SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict,
135-
@Exclusive @Cached InlinedBranchProfile callAttrUpdate,
136141
@Exclusive @Cached InlinedBranchProfile updateFlags,
137-
@Shared("dylib") @CachedLibrary(limit = "getAttributeAccessInlineCacheMaxDepth()") DynamicObjectLibrary dylib,
138-
@Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode,
139-
@Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
142+
@CachedLibrary(limit = "getAttributeAccessInlineCacheMaxDepth()") DynamicObjectLibrary dylib) {
140143
if (value == PNone.NO_VALUE) {
141144
updateFlags.enter(inliningTarget);
142145
dylib.setShapeFlags(klass, dylib.getShapeFlags(klass) | HAS_NO_VALUE_PROPERTIES);
143146
}
144-
return writeToDynamicStorageManagedClass(klass, key, value, inliningTarget, callAttrUpdate, dylib, codePointLengthNode, codePointAtIndexNode);
147+
return writeToDynamicStorageManagedClass(klass, key, value, dylib);
145148
}
146149

147-
private static boolean writeToDynamicStorageManagedClass(PythonManagedClass klass, TruffleString key, Object value, Node inliningTarget,
148-
InlinedBranchProfile callAttrUpdate, DynamicObjectLibrary dylib, TruffleString.CodePointLengthNode codePointLengthNode, TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
150+
private static boolean writeToDynamicStorageManagedClass(PythonManagedClass klass, TruffleString key, Object value, DynamicObjectLibrary dylib) {
149151
CompilerAsserts.partialEvaluationConstant(klass.getClass());
150152
try {
151153
dylib.put(klass, key, value);
152154
return true;
153155
} finally {
154-
if (!klass.canSkipOnAttributeUpdate(key, value, codePointLengthNode, codePointAtIndexNode)) {
155-
callAttrUpdate.enter(inliningTarget);
156-
klass.onAttributeUpdate(key, value);
157-
}
156+
klass.onAttributeUpdate(key, value);
158157
}
159158
}
160159

@@ -169,35 +168,14 @@ static boolean writeToDictNoType(@SuppressWarnings("unused") PythonObject object
169168
return writeToDict(dict, key, value, inliningTarget, updateStorage, setHashingStorageItem);
170169
}
171170

172-
// write to the dict & PythonManagedClass -> requires calling onAttributeUpdate
173-
@Specialization(guards = {"dict != null", "!isNoValue(value)"})
174-
boolean writeToDictBuiltinType(PythonBuiltinClass klass, TruffleString key, Object value,
175-
@Bind Node inliningTarget,
176-
@SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict,
177-
@Bind("getDict.execute(klass)") PDict dict,
178-
@Shared("callAttrUpdate") @Cached InlinedBranchProfile callAttrUpdate,
179-
@Shared("updateStorage") @Cached InlinedBranchProfile updateStorage,
180-
@Shared("setHashingStorageItem") @Cached HashingStorageSetItem setHashingStorageItem,
181-
@Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode,
182-
@Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
183-
if (PythonContext.get(this).isInitialized()) {
184-
throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, PyObjectReprAsTruffleStringNode.executeUncached(key), klass);
185-
} else {
186-
return writeToDictManagedClass(klass, dict, key, value, inliningTarget, callAttrUpdate, updateStorage, setHashingStorageItem, codePointLengthNode, codePointAtIndexNode);
187-
}
188-
}
189-
190171
@Specialization(guards = {"dict != null", "!isNoValue(value)"})
191172
static boolean writeToDictClass(PythonClass klass, TruffleString key, Object value,
192173
@Bind Node inliningTarget,
193174
@SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict,
194175
@Bind("getDict.execute(klass)") PDict dict,
195-
@Shared("callAttrUpdate") @Cached InlinedBranchProfile callAttrUpdate,
196176
@Shared("updateStorage") @Cached InlinedBranchProfile updateStorage,
197-
@Shared("setHashingStorageItem") @Cached HashingStorageSetItem setHashingStorageItem,
198-
@Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode,
199-
@Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
200-
return writeToDictManagedClass(klass, dict, key, value, inliningTarget, callAttrUpdate, updateStorage, setHashingStorageItem, codePointLengthNode, codePointAtIndexNode);
177+
@Shared("setHashingStorageItem") @Cached HashingStorageSetItem setHashingStorageItem) {
178+
return writeToDictManagedClass(klass, dict, key, value, inliningTarget, updateStorage, setHashingStorageItem);
201179
}
202180

203181
// @Exclusive for truffle-interpreted-performance
@@ -206,42 +184,24 @@ static boolean deleteFromPythonObject(PythonObject obj, TruffleString key, Objec
206184
@Bind Node inliningTarget,
207185
@SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict,
208186
@Bind("getDict.execute(obj)") PDict dict,
209-
@Exclusive @Cached InlinedBranchProfile callAttrUpdate,
210-
@Cached HashingStorageNodes.HashingStorageDelItem hashingStorageDelItem,
211-
@Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode,
212-
@Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
187+
@Cached HashingStorageNodes.HashingStorageDelItem hashingStorageDelItem) {
213188
try {
214189
HashingStorage dictStorage = dict.getDictStorage();
215190
return hashingStorageDelItem.execute(inliningTarget, dictStorage, key, dict);
216191
} finally {
217192
if (obj instanceof PythonManagedClass klass) {
218-
if (!klass.canSkipOnAttributeUpdate(key, value, codePointLengthNode, codePointAtIndexNode)) {
219-
callAttrUpdate.enter(inliningTarget);
220-
klass.onAttributeUpdate(key, value);
221-
}
193+
klass.onAttributeUpdate(key, value);
222194
}
223195
}
224196
}
225197

226-
@Specialization(guards = {"dict != null", "isNoValue(value)"})
227-
static boolean deleteFromPythonBuiltinClass(PythonBuiltinClass klass, TruffleString key, Object value,
228-
@Bind Node inliningTarget,
229-
@SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict,
230-
@Bind("getDict.execute(klass)") PDict dict) {
231-
throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, key, klass);
232-
}
233-
234198
private static boolean writeToDictManagedClass(PythonManagedClass klass, PDict dict, TruffleString key, Object value, Node inliningTarget,
235-
InlinedBranchProfile callAttrUpdate, InlinedBranchProfile updateStorage, HashingStorageSetItem setHashingStorageItem, TruffleString.CodePointLengthNode codePointLengthNode,
236-
TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
199+
InlinedBranchProfile updateStorage, HashingStorageSetItem setHashingStorageItem) {
237200
CompilerAsserts.partialEvaluationConstant(klass.getClass());
238201
try {
239202
return writeToDict(dict, key, value, inliningTarget, updateStorage, setHashingStorageItem);
240203
} finally {
241-
if (!klass.canSkipOnAttributeUpdate(key, value, codePointLengthNode, codePointAtIndexNode)) {
242-
callAttrUpdate.enter(inliningTarget);
243-
klass.onAttributeUpdate(key, value);
244-
}
204+
klass.onAttributeUpdate(key, value);
245205
}
246206
}
247207

@@ -261,12 +221,6 @@ static boolean writeToDict(PDict dict, TruffleString key, Object value,
261221
return true;
262222
}
263223

264-
@Specialization
265-
static boolean doPBCT(PythonBuiltinClassType object, TruffleString key, Object value,
266-
@Cached WriteAttributeToObjectNode recursive) {
267-
return recursive.execute(PythonContext.get(recursive).lookupType(object), key, value);
268-
}
269-
270224
private static void checkNativeImmutable(Node inliningTarget, PythonAbstractNativeObject object, TruffleString key,
271225
CStructAccess.ReadI64Node getNativeFlags,
272226
PRaiseNode raiseNode) {
@@ -288,8 +242,8 @@ static boolean writeNativeObjectOrClass(PythonAbstractNativeObject object, Truff
288242
@Exclusive @Cached InlinedBranchProfile canBeSpecialSlot,
289243
@Cached IsTypeNode isTypeNode,
290244
@Exclusive @Cached PRaiseNode raiseNode,
291-
@Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode,
292-
@Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
245+
@Cached TruffleString.CodePointLengthNode codePointLengthNode,
246+
@Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) {
293247
boolean isType = isTypeProfile.profile(inliningTarget, isTypeNode.execute(inliningTarget, object));
294248
try {
295249
Object dict;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/MroSequenceStorage.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,10 +213,6 @@ public void lookupChanged() {
213213
lookupStableAssumption.invalidate();
214214
}
215215

216-
public boolean hasAttributeInMROFinalAssumptions() {
217-
return attributesInMROFinalAssumptions != null;
218-
}
219-
220216
public NativeSequenceStorage getNativeMirror() {
221217
return nativeMirror;
222218
}

0 commit comments

Comments
 (0)