[pypy-commit] pypy stmgc-c8-gcc: same changes for stmdict and some cleanup (that may be suboptimal for performance)
Raemi
noreply at buildbot.pypy.org
Tue Sep 8 18:28:01 CEST 2015
Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: stmgc-c8-gcc
Changeset: r79549:196fe36e9067
Date: 2015-09-08 18:31 +0200
http://bitbucket.org/pypy/pypy/changeset/196fe36e9067/
Log: same changes for stmdict and some cleanup (that may be suboptimal
for performance)
diff --git a/pypy/module/pypystm/stmdict.py b/pypy/module/pypystm/stmdict.py
--- a/pypy/module/pypystm/stmdict.py
+++ b/pypy/module/pypystm/stmdict.py
@@ -17,7 +17,27 @@
-def find_equal_item(space, array, w_key):
+def really_find_equal_item(space, h, w_key):
+ hkey = space.hash_w(w_key)
+ entry = h.lookup(hkey)
+ array = lltype.cast_opaque_ptr(PARRAY, entry.object)
+ while True:
+ if not array:
+ return (entry, array, -1)
+
+ i = _find_equal_item(space, array, w_key)
+ if not space.type(w_key).compares_by_identity():
+ entry2 = h.lookup(hkey)
+ array2 = lltype.cast_opaque_ptr(PARRAY, entry2.object)
+ if array2 != array:
+ entry = entry2
+ array = array2
+ continue
+
+ return (entry, array, i)
+
+
+def _find_equal_item(space, array, w_key):
# result by this function is based on 'array'. If the entry
# changes, the result is stale.
w_item = cast_gcref_to_instance(W_Root, array[0])
@@ -27,15 +47,17 @@
return _run_next_iterations(space, array, w_key)
return -1
+
@jit.dont_look_inside
def _run_next_iterations(space, array, w_key):
i = 2
+ limit = len(array) # fixed size
while True:
w_item = cast_gcref_to_instance(W_Root, array[i])
- if space.eq_w(w_key, w_item): # array may change here
+ if space.eq_w(w_key, w_item):
return i
i += 2
- if i >= len(array):
+ if i >= limit:
return -1
def ll_arraycopy(source, dest, source_start, dest_start, length):
@@ -46,35 +68,20 @@
dest[dest_start + i] = source[source_start + i]
def pop_from_entry(h, space, w_key):
- hkey = space.hash_w(w_key)
- entry = h.lookup(hkey)
- array = lltype.cast_opaque_ptr(PARRAY, entry.object)
- while True:
- if not array:
- return None
-
- i = find_equal_item(space, array, w_key)
- if not space.type(w_key).compares_by_identity():
- entry2 = h.lookup(hkey)
- array2 = lltype.cast_opaque_ptr(PARRAY, entry2.object)
- if array2 != array:
- entry = entry2
- array = array2
- continue # not utopia yet
-
- if i < 0:
- return None
- # found
- w_value = cast_gcref_to_instance(W_Root, array[i + 1])
- L = len(array) - 2
- if L == 0:
- narray = lltype.nullptr(ARRAY)
- else:
- narray = lltype.malloc(ARRAY, L)
- ll_arraycopy(array, narray, 0, 0, i)
- ll_arraycopy(array, narray, i + 2, i, L - i)
- h.writeobj(entry, lltype.cast_opaque_ptr(llmemory.GCREF, narray))
- return w_value
+ entry, array, i = really_find_equal_item(space, h, w_key)
+ if i < 0:
+ return None
+ # found
+ w_value = cast_gcref_to_instance(W_Root, array[i + 1])
+ L = len(array) - 2
+ if L == 0:
+ narray = lltype.nullptr(ARRAY)
+ else:
+ narray = lltype.malloc(ARRAY, L)
+ ll_arraycopy(array, narray, 0, 0, i)
+ ll_arraycopy(array, narray, i + 2, i, L - i)
+ h.writeobj(entry, lltype.cast_opaque_ptr(llmemory.GCREF, narray))
+ return w_value
@@ -84,28 +91,10 @@
self.h = rstm.create_hashtable()
def getitem_w(self, space, w_key):
- hkey = space.hash_w(w_key)
- entry = self.h.lookup(hkey)
- array = lltype.cast_opaque_ptr(PARRAY, entry.object)
- while True:
- if array:
- i = find_equal_item(space, array, w_key)
-
- if not space.type(w_key).compares_by_identity():
- # the world may have changed:
- # if entry has changed, we are lost
- # if array has changed, the result we got from find_equal_item
- # is not trustworthy; should also imply entry!=entry2
- entry2 = self.h.lookup(hkey)
- array2 = lltype.cast_opaque_ptr(PARRAY, entry2.object)
- if array2 != array:
- entry = entry2
- array = array2
- continue # not utopia yet
-
- if i >= 0:
- return cast_gcref_to_instance(W_Root, array[i + 1])
- space.raise_key_error(w_key)
+ entry, array, i = really_find_equal_item(space, self.h, w_key)
+ if array and i >= 0:
+ return cast_gcref_to_instance(W_Root, array[i + 1])
+ space.raise_key_error(w_key)
def setitem_w(self, space, w_key, w_value):
hkey = space.hash_w(w_key)
@@ -113,15 +102,9 @@
array = lltype.cast_opaque_ptr(PARRAY, entry.object)
while True:
if array:
- i = find_equal_item(space, array, w_key)
- if not space.type(w_key).compares_by_identity():
- entry2 = self.h.lookup(hkey)
- array2 = lltype.cast_opaque_ptr(PARRAY, entry2.object)
- if array2 != array:
- entry = entry2
- array = array2
- continue
-
+ entry, array, i = really_find_equal_item(space, self.h, w_key)
+ if not array:
+ continue
if i >= 0:
# already there, update the value
array[i + 1] = cast_instance_to_gcref(w_value)
@@ -142,35 +125,17 @@
space.raise_key_error(w_key)
def contains_w(self, space, w_key):
- hkey = space.hash_w(w_key)
- gcref = self.h.get(hkey)
- array = lltype.cast_opaque_ptr(PARRAY, gcref)
- while True:
- if array and find_equal_item(space, array, w_key) >= 0:
- if not space.type(w_key).compares_by_identity():
- array2 = lltype.cast_opaque_ptr(PARRAY, self.h.get(hkey))
- if array2 != array:
- array = array2
- continue
- return space.w_True
- return space.w_False
+ entry, array, i = really_find_equal_item(space, self.h, w_key)
+ if array and i >= 0:
+ return space.w_True
+ return space.w_False
@unwrap_spec(w_default=WrappedDefault(None))
def get_w(self, space, w_key, w_default):
- hkey = space.hash_w(w_key)
- gcref = self.h.get(hkey)
- array = lltype.cast_opaque_ptr(PARRAY, gcref)
- while True:
- if array:
- i = find_equal_item(space, array, w_key)
- if not space.type(w_key).compares_by_identity():
- array2 = lltype.cast_opaque_ptr(PARRAY, self.h.get(hkey))
- if array2 != array:
- array = array2
- continue
- if i >= 0:
- return cast_gcref_to_instance(W_Root, array[i + 1])
- return w_default
+ entry, array, i = really_find_equal_item(space, self.h, w_key)
+ if array and i >= 0:
+ return cast_gcref_to_instance(W_Root, array[i + 1])
+ return w_default
def pop_w(self, space, w_key, w_default=None):
w_value = pop_from_entry(self.h, space, w_key)
@@ -188,14 +153,9 @@
array = lltype.cast_opaque_ptr(PARRAY, entry.object)
while True:
if array:
- i = find_equal_item(space, array, w_key)
- if not space.type(w_key).compares_by_identity():
- entry2 = self.h.lookup(hkey)
- array2 = lltype.cast_opaque_ptr(PARRAY, entry2.object)
- if array2 != array:
- entry = entry2
- array = array2
- continue
+ entry, array, i = really_find_equal_item(space, self.h, w_key)
+ if not array:
+ continue
if i >= 0:
# already there, return the existing value
return cast_gcref_to_instance(W_Root, array[i + 1])
diff --git a/pypy/module/pypystm/stmset.py b/pypy/module/pypystm/stmset.py
--- a/pypy/module/pypystm/stmset.py
+++ b/pypy/module/pypystm/stmset.py
@@ -17,7 +17,27 @@
PARRAY = lltype.Ptr(ARRAY)
-def find_equal_item(space, array, w_key):
+
+def really_find_equal_item(space, h, w_key):
+ hkey = space.hash_w(w_key)
+ entry = h.lookup(hkey)
+ array = lltype.cast_opaque_ptr(PARRAY, entry.object)
+ while True:
+ if not array:
+ return (entry, array, -1)
+
+ i = _find_equal_item(space, array, w_key)
+ if not space.type(w_key).compares_by_identity():
+ entry2 = h.lookup(hkey)
+ array2 = lltype.cast_opaque_ptr(PARRAY, entry2.object)
+ if array2 != array:
+ entry = entry2
+ array = array2
+ continue
+
+ return (entry, array, i)
+
+def _find_equal_item(space, array, w_key):
w_item = cast_gcref_to_instance(W_Root, array[0])
if space.eq_w(w_key, w_item):
return 0
@@ -44,10 +64,8 @@
self.h = rstm.create_hashtable()
def contains_w(self, space, w_key):
- hkey = space.hash_w(w_key)
- gcref = self.h.get(hkey)
- array = lltype.cast_opaque_ptr(PARRAY, gcref)
- if array and find_equal_item(space, array, w_key) >= 0:
+ entry, array, i = really_find_equal_item(space, self.h, w_key)
+ if array and i >= 0:
return space.w_True
return space.w_False
@@ -55,17 +73,22 @@
hkey = space.hash_w(w_key)
entry = self.h.lookup(hkey)
array = lltype.cast_opaque_ptr(PARRAY, entry.object)
- if array:
- if find_equal_item(space, array, w_key) >= 0:
- return # already there
- L = len(array)
- narray = lltype.malloc(ARRAY, L + 1)
- ll_arraycopy(array, narray, 0, 0, L)
- else:
- narray = lltype.malloc(ARRAY, 1)
- L = 0
- narray[L] = cast_instance_to_gcref(w_key)
- self.h.writeobj(entry, lltype.cast_opaque_ptr(llmemory.GCREF, narray))
+ while True:
+ if array:
+ entry, array, i = really_find_equal_item(space, self.h, w_key)
+ if not array:
+ continue
+ if i >= 0:
+ return # already there
+ L = len(array)
+ narray = lltype.malloc(ARRAY, L + 1)
+ ll_arraycopy(array, narray, 0, 0, L)
+ else:
+ narray = lltype.malloc(ARRAY, 1)
+ L = 0
+ narray[L] = cast_instance_to_gcref(w_key)
+ self.h.writeobj(entry, lltype.cast_opaque_ptr(llmemory.GCREF, narray))
+ return
def try_remove(self, space, w_key):
hkey = space.hash_w(w_key)
@@ -73,8 +96,8 @@
array = lltype.cast_opaque_ptr(PARRAY, entry.object)
if not array:
return False
- i = find_equal_item(space, array, w_key)
- if i < 0:
+ entry, array, i = really_find_equal_item(space, self.h, w_key)
+ if not array or i < 0:
return False
# found
L = len(array) - 1
diff --git a/pypy/module/pypystm/test/test_stmdict.py b/pypy/module/pypystm/test/test_stmdict.py
--- a/pypy/module/pypystm/test/test_stmdict.py
+++ b/pypy/module/pypystm/test/test_stmdict.py
@@ -119,8 +119,6 @@
def test_custom_evil_eq(self):
- import pypystm
-
class A(object):
depth = []
def __hash__(self):
@@ -131,6 +129,7 @@
del d[a]
print "del a"
return self is other
+ import pypystm
d = pypystm.stmdict()
a = A()
b = A()
@@ -140,8 +139,6 @@
assert b in d
def test_custom_evil_eq2(self):
- import pypystm
-
class A(object):
depth = []
def __hash__(self):
@@ -152,6 +149,7 @@
del d[a]
print "del a"
return self is other
+ import pypystm
d = pypystm.stmdict()
a = A()
b = A()
More information about the pypy-commit
mailing list