Skip to content

Commit eda145b

Browse files
moenn12elkorchi
authored andcommitted
[GR-65325] Backport to 24.2: We have null keys in our hashingstorage.
PullRequest: graalpython/3813
2 parents 70e5cc0 + f7316db commit eda145b

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

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

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -61,6 +61,7 @@
6161
import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile;
6262
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
6363
import com.oracle.graal.python.runtime.exception.PException;
64+
import com.oracle.truffle.api.CompilerDirectives;
6465
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
6566
import com.oracle.truffle.api.dsl.Bind;
6667
import com.oracle.truffle.api.dsl.Cached;
@@ -121,8 +122,8 @@ abstract static class SetValueHashingStorageNode extends PNodeWithContext {
121122

122123
@Specialization
123124
static HashingStorage doEconomicStorage(VirtualFrame frame, Node inliningTarget, EconomicMapStorage map, Object value,
124-
@Cached ObjectHashMap.PutNode putNode,
125-
@Cached InlinedLoopConditionProfile loopProfile) {
125+
@Shared("putNode") @Cached ObjectHashMap.PutNode putNode,
126+
@Shared("loopProfile") @Cached InlinedLoopConditionProfile loopProfile) {
126127
// We want to avoid calling __hash__() during map.put
127128
map.setValueForAllKeys(frame, inliningTarget, value, putNode, loopProfile);
128129
return map;
@@ -134,14 +135,25 @@ static HashingStorage doGeneric(VirtualFrame frame, Node inliningTarget, Hashing
134135
@Cached HashingStorageSetItem setItem,
135136
@Cached HashingStorageGetIterator getIterator,
136137
@Cached HashingStorageIteratorNext itNext,
137-
@Cached HashingStorageIteratorKey itKey) {
138+
@Cached HashingStorageIteratorKey itKey,
139+
@Shared("putNode") @Cached ObjectHashMap.PutNode putNode,
140+
@Shared("loopProfile") @Cached InlinedLoopConditionProfile loopProfile) {
138141
HashingStorageIterator it = getIterator.execute(inliningTarget, map);
139-
HashingStorage storage = map;
140142
while (itNext.execute(inliningTarget, map, it)) {
141-
Object key = itKey.execute(inliningTarget, storage, it);
142-
storage = setItem.execute(frame, inliningTarget, storage, key, value);
143+
Object key = itKey.execute(inliningTarget, map, it);
144+
HashingStorage newStorage = setItem.execute(frame, inliningTarget, map, key, value);
145+
if (newStorage != map) {
146+
// when the storage changes, the iterator state is not a reliable cursor
147+
// anymore and we need to restart.
148+
if (newStorage instanceof EconomicMapStorage mapStorage) {
149+
mapStorage.setValueForAllKeys(frame, inliningTarget, value, putNode, loopProfile);
150+
return mapStorage;
151+
} else {
152+
throw CompilerDirectives.shouldNotReachHere("We only generalize to EconomicMapStorage");
153+
}
154+
}
143155
}
144-
return storage;
156+
return map;
145157
}
146158

147159
protected static boolean isEconomicMapStorage(Object o) {

0 commit comments

Comments
 (0)