Skip to content

Commit f2fa4a4

Browse files
qunaibitsteve-s
authored andcommitted
Lookup Keys attribute using PyObjectLookupAttr
1 parent 364d900 commit f2fa4a4

File tree

2 files changed

+54
-46
lines changed

2 files changed

+54
-46
lines changed

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

Lines changed: 48 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.common;
4242

43+
import static com.oracle.graal.python.builtins.objects.function.PKeyword.EMPTY_KEYWORDS;
4344
import static com.oracle.graal.python.nodes.SpecialMethodNames.T_KEYS;
4445
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
4546
import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
47+
import static com.oracle.graal.python.util.PythonUtils.EMPTY_OBJECT_ARRAY;
4648

4749
import com.oracle.graal.python.PythonLanguage;
4850
import com.oracle.graal.python.builtins.objects.PNone;
@@ -58,13 +60,14 @@
5860
import com.oracle.graal.python.lib.GetNextNode;
5961
import com.oracle.graal.python.lib.PyObjectGetItem;
6062
import com.oracle.graal.python.lib.PyObjectGetIter;
63+
import com.oracle.graal.python.lib.PyObjectLookupAttr;
6164
import com.oracle.graal.python.nodes.ErrorMessages;
6265
import com.oracle.graal.python.nodes.IndirectCallNode;
6366
import com.oracle.graal.python.nodes.PNodeWithContext;
6467
import com.oracle.graal.python.nodes.PRaiseNode;
6568
import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode;
66-
import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode;
6769
import com.oracle.graal.python.nodes.builtins.ListNodes.FastConstructListNode;
70+
import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode;
6871
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
6972
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
7073
import com.oracle.graal.python.nodes.object.GetClassNode;
@@ -74,7 +77,6 @@
7477
import com.oracle.graal.python.runtime.sequence.PSequence;
7578
import com.oracle.graal.python.util.ArrayBuilder;
7679
import com.oracle.truffle.api.Assumption;
77-
import com.oracle.truffle.api.CompilerDirectives;
7880
import com.oracle.truffle.api.Truffle;
7981
import com.oracle.truffle.api.dsl.Bind;
8082
import com.oracle.truffle.api.dsl.Cached;
@@ -83,6 +85,7 @@
8385
import com.oracle.truffle.api.dsl.Specialization;
8486
import com.oracle.truffle.api.frame.VirtualFrame;
8587
import com.oracle.truffle.api.nodes.Node;
88+
import com.oracle.truffle.api.profiles.ConditionProfile;
8689
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
8790

8891
public abstract class HashingStorage {
@@ -103,8 +106,6 @@ public Assumption needNotPassExceptionAssumption() {
103106

104107
public abstract HashingStorage execute(VirtualFrame frame, Object mapping, PKeyword[] kwargs);
105108

106-
@Child private LookupInheritedAttributeNode lookupKeysAttributeNode;
107-
108109
protected boolean isEmpty(PKeyword[] kwargs) {
109110
return kwargs.length == 0;
110111
}
@@ -123,14 +124,6 @@ protected static boolean isPDict(Object o) {
123124
return o instanceof PHashingCollection;
124125
}
125126

126-
protected boolean hasKeysAttribute(Object o) {
127-
if (lookupKeysAttributeNode == null) {
128-
CompilerDirectives.transferToInterpreterAndInvalidate();
129-
lookupKeysAttributeNode = insert(LookupInheritedAttributeNode.create(T_KEYS));
130-
}
131-
return lookupKeysAttributeNode.execute(o) != PNone.NO_VALUE;
132-
}
133-
134127
@Specialization(guards = {"isEmpty(kwargs)", "!hasIterAttrButNotBuiltin(inliningTarget, dictLike, getClassNode, lookupIter)"}, limit = "1")
135128
static HashingStorage doPDict(PHashingCollection dictLike, @SuppressWarnings("unused") PKeyword[] kwargs,
136129
@SuppressWarnings("unused") @Bind("this") Node inliningTarget,
@@ -173,31 +166,20 @@ static HashingStorage doNoBuiltinKeysAttr(VirtualFrame frame, PHashingCollection
173166
@Exclusive @Cached GetNextNode nextNode,
174167
@Exclusive @Cached IsBuiltinObjectProfile errorProfile) {
175168
HashingStorage curStorage = PDict.createNewStorage(0);
176-
return copyToStorage(frame, inliningTarget, col, kwargs, curStorage, callKeysNode, getItemNode, getIter, nextNode, errorProfile, setHashingStorageItem, addAllToOther);
169+
Object keysIterable = callKeysNode.executeObject(frame, col);
170+
return copyToStorage(frame, col, kwargs, curStorage, inliningTarget, keysIterable, getItemNode, getIter, nextNode, errorProfile, setHashingStorageItem, addAllToOther);
177171
}
178172

179173
protected static boolean hasIterAttrButNotBuiltin(Node inliningTarget, PHashingCollection col, GetClassNode getClassNode, LookupCallableSlotInMRONode lookupIter) {
180174
Object attr = lookupIter.execute(getClassNode.execute(inliningTarget, col));
181175
return attr != PNone.NO_VALUE && !(attr instanceof PBuiltinMethod || attr instanceof PBuiltinFunction);
182176
}
183177

184-
@Specialization(guards = {"!isPDict(mapping)", "hasKeysAttribute(mapping)"})
185-
static HashingStorage doMapping(VirtualFrame frame, Object mapping, PKeyword[] kwargs,
186-
@Bind("this") Node inliningTarget,
187-
@Exclusive @Cached HashingStorageSetItem setHasihngStorageItem,
188-
@Exclusive @Cached HashingStorageAddAllToOther addAllToOther,
189-
@Exclusive @Cached PyObjectGetIter getIter,
190-
@Exclusive @Cached("create(T_KEYS)") LookupAndCallUnaryNode callKeysNode,
191-
@Exclusive @Cached PyObjectGetItem getItemNode,
192-
@Exclusive @Cached GetNextNode nextNode,
193-
@Exclusive @Cached IsBuiltinObjectProfile errorProfile) {
194-
HashingStorage curStorage = PDict.createNewStorage(0);
195-
return copyToStorage(frame, inliningTarget, mapping, kwargs, curStorage, callKeysNode, getItemNode, getIter, nextNode, errorProfile, setHasihngStorageItem, addAllToOther);
196-
}
197-
198-
@Specialization(guards = {"!isNoValue(iterable)", "!isPDict(iterable)", "!hasKeysAttribute(iterable)"})
199-
static HashingStorage doSequence(VirtualFrame frame, Object iterable, PKeyword[] kwargs,
178+
@Specialization(guards = {"!isNoValue(arg)", "!isPDict(arg)"})
179+
static HashingStorage updateArg(VirtualFrame frame, Object arg, PKeyword[] kwargs,
200180
@Bind("this") Node inliningTarget,
181+
@Cached PyObjectLookupAttr lookupKeysAttributeNode,
182+
@Cached CallVarargsMethodNode callKeysMethod,
201183
@Exclusive @Cached HashingStorageSetItem setHasihngStorageItem,
202184
@Exclusive @Cached HashingStorageAddAllToOther addAllToOther,
203185
@Exclusive @Cached PyObjectGetIter getIter,
@@ -207,12 +189,23 @@ static HashingStorage doSequence(VirtualFrame frame, Object iterable, PKeyword[]
207189
@Exclusive @Cached PyObjectGetItem getItemNode,
208190
@Cached SequenceNodes.LenNode seqLenNode,
209191
@Cached InlinedConditionProfile lengthTwoProfile,
192+
@Cached ConditionProfile hasKeyProfile,
210193
@Exclusive @Cached IsBuiltinObjectProfile errorProfile,
211194
@Exclusive @Cached IsBuiltinObjectProfile isTypeErrorProfile) {
212-
213-
return addSequenceToStorage(frame, inliningTarget, iterable, kwargs, PDict::createNewStorage, getIter, nextNode, createListNode,
214-
seqLenNode, lengthTwoProfile, raise, getItemNode, isTypeErrorProfile,
215-
errorProfile, setHasihngStorageItem, addAllToOther);
195+
Object keyAttr = lookupKeysAttributeNode.execute(frame, inliningTarget, arg, T_KEYS);
196+
if (hasKeyProfile.profile(keyAttr != PNone.NO_VALUE)) {
197+
HashingStorage curStorage = PDict.createNewStorage(0);
198+
// We don't need to pass self as the attribute object has it already.
199+
Object keysIterable = callKeysMethod.execute(frame, keyAttr, EMPTY_OBJECT_ARRAY, EMPTY_KEYWORDS);
200+
return copyToStorage(frame, arg, kwargs, curStorage,
201+
inliningTarget, keysIterable, getItemNode, getIter, nextNode,
202+
errorProfile, setHasihngStorageItem, addAllToOther);
203+
} else {
204+
return addSequenceToStorage(frame, arg, kwargs,
205+
inliningTarget, PDict::createNewStorage, getIter, nextNode, createListNode,
206+
seqLenNode, lengthTwoProfile, raise, getItemNode, isTypeErrorProfile,
207+
errorProfile, setHasihngStorageItem, addAllToOther);
208+
}
216209
}
217210

218211
@NeverDefault
@@ -239,10 +232,15 @@ public final HashingStorage unionCached(HashingStorage other, HashingStorageCopy
239232
* Adds all items from the given mapping object to storage. It is the caller responsibility to
240233
* ensure, that mapping has the 'keys' attribute.
241234
*/
242-
public static HashingStorage copyToStorage(VirtualFrame frame, Node inliningTarget, Object mapping, PKeyword[] kwargs, HashingStorage storage,
243-
LookupAndCallUnaryNode callKeysNode, PyObjectGetItem callGetItemNode, PyObjectGetIter getIter, GetNextNode nextNode,
244-
IsBuiltinObjectProfile errorProfile, HashingStorageSetItem setHashingStorageItem, HashingStorageAddAllToOther addAllToOtherNode) {
245-
Object keysIterable = callKeysNode.executeObject(frame, mapping);
235+
public static HashingStorage copyToStorage(VirtualFrame frame, Object mapping, PKeyword[] kwargs, HashingStorage storage,
236+
Node inliningTarget,
237+
Object keysIterable,
238+
PyObjectGetItem callGetItemNode,
239+
PyObjectGetIter getIter,
240+
GetNextNode nextNode,
241+
IsBuiltinObjectProfile errorProfile,
242+
HashingStorageSetItem setHashingStorageItem,
243+
HashingStorageAddAllToOther addAllToOtherNode) {
246244
Object keysIt = getIter.execute(frame, inliningTarget, keysIterable);
247245
HashingStorage curStorage = storage;
248246
while (true) {
@@ -267,10 +265,19 @@ public interface StorageSupplier {
267265
HashingStorage get(int length);
268266
}
269267

270-
public static HashingStorage addSequenceToStorage(VirtualFrame frame, Node inliningTarget, Object iterable, PKeyword[] kwargs, StorageSupplier storageSupplier,
271-
PyObjectGetIter getIter, GetNextNode nextNode, FastConstructListNode createListNode, LenNode seqLenNode,
272-
InlinedConditionProfile lengthTwoProfile, PRaiseNode.Lazy raise, PyObjectGetItem getItemNode, IsBuiltinObjectProfile isTypeErrorProfile,
273-
IsBuiltinObjectProfile errorProfile, HashingStorageSetItem setHashingStorageItem, HashingStorageAddAllToOther addAllToOther) throws PException {
268+
public static HashingStorage addSequenceToStorage(VirtualFrame frame, Object iterable, PKeyword[] kwargs, Node inliningTarget,
269+
StorageSupplier storageSupplier,
270+
PyObjectGetIter getIter,
271+
GetNextNode nextNode,
272+
FastConstructListNode createListNode,
273+
LenNode seqLenNode,
274+
InlinedConditionProfile lengthTwoProfile,
275+
PRaiseNode.Lazy raise,
276+
PyObjectGetItem getItemNode,
277+
IsBuiltinObjectProfile isTypeErrorProfile,
278+
IsBuiltinObjectProfile errorProfile,
279+
HashingStorageSetItem setHashingStorageItem,
280+
HashingStorageAddAllToOther addAllToOther) throws PException {
274281
Object it = getIter.execute(frame, inliningTarget, iterable);
275282
ArrayBuilder<PSequence> elements = new ArrayBuilder<>();
276283
try {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictNodes.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,9 @@ static void updateMapping(VirtualFrame frame, PDict self, Object other,
131131
@Exclusive @Cached PyObjectGetItem getItem,
132132
@Shared @Cached GetNextNode nextNode,
133133
@Exclusive @Cached IsBuiltinObjectProfile errorProfile) {
134-
HashingStorage storage = HashingStorage.copyToStorage(frame, inliningTarget, other, PKeyword.EMPTY_KEYWORDS, self.getDictStorage(),
135-
callKeysNode, getItem, getIter, nextNode, errorProfile, setHashingStorageItem, addAllToOther);
134+
Object keysIterable = callKeysNode.executeObject(frame, other);
135+
HashingStorage storage = HashingStorage.copyToStorage(frame, other, PKeyword.EMPTY_KEYWORDS, self.getDictStorage(),
136+
inliningTarget, keysIterable, getItem, getIter, nextNode, errorProfile, setHashingStorageItem, addAllToOther);
136137
self.setDictStorage(storage);
137138
}
138139

@@ -152,9 +153,9 @@ static void updateSequence(VirtualFrame frame, PDict self, Object other,
152153
@Exclusive @Cached IsBuiltinObjectProfile errorProfile,
153154
@Exclusive @Cached IsBuiltinObjectProfile isTypeErrorProfile) {
154155
HashingStorage.StorageSupplier storageSupplier = (int length) -> self.getDictStorage();
155-
HashingStorage storage = HashingStorage.addSequenceToStorage(frame, inliningTarget, other, PKeyword.EMPTY_KEYWORDS, storageSupplier,
156-
getIter, nextNode, createListNode, seqLenNode, lengthTwoProfile, raiseNode, getItem, isTypeErrorProfile,
157-
errorProfile, setHasihngStorageItem, addAllToOther);
156+
HashingStorage storage = HashingStorage.addSequenceToStorage(frame, other, PKeyword.EMPTY_KEYWORDS, inliningTarget,
157+
storageSupplier, getIter, nextNode, createListNode, seqLenNode, lengthTwoProfile, raiseNode, getItem,
158+
isTypeErrorProfile, errorProfile, setHasihngStorageItem, addAllToOther);
158159
self.setDictStorage(storage);
159160
}
160161

0 commit comments

Comments
 (0)