[pypy-commit] pypy stmgc-c7: Do a single lookup in all methods of hashtable, stmset and stmdict.
arigo
noreply at buildbot.pypy.org
Sun Feb 1 10:19:46 CET 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c7
Changeset: r75617:982b5fc67ac4
Date: 2015-02-01 10:19 +0100
http://bitbucket.org/pypy/pypy/changeset/982b5fc67ac4/
Log: Do a single lookup in all methods of hashtable, stmset and stmdict.
diff --git a/pypy/module/pypystm/hashtable.py b/pypy/module/pypystm/hashtable.py
--- a/pypy/module/pypystm/hashtable.py
+++ b/pypy/module/pypystm/hashtable.py
@@ -25,15 +25,15 @@
@unwrap_spec(key=int)
def setitem_w(self, key, w_value):
- gcref = cast_instance_to_gcref(w_value)
- self.h.set(key, gcref)
+ entry = self.h.lookup(key)
+ entry.object = cast_instance_to_gcref(w_value)
@unwrap_spec(key=int)
def delitem_w(self, space, key):
- gcref = self.h.get(key)
- if not gcref:
+ entry = self.h.lookup(key)
+ if not entry.object:
space.raise_key_error(space.wrap(key))
- self.h.set(key, rstm.NULL_GCREF)
+ entry.object = rstm.NULL_GCREF
@unwrap_spec(key=int)
def contains_w(self, space, key):
@@ -49,10 +49,10 @@
@unwrap_spec(key=int, w_default=WrappedDefault(None))
def setdefault_w(self, space, key, w_default):
- gcref = self.h.get(key)
+ entry = self.h.lookup(key)
+ gcref = entry.object
if not gcref:
- gcref = cast_instance_to_gcref(w_default)
- self.h.set(key, gcref)
+ entry.object = cast_instance_to_gcref(w_default)
return w_default
return cast_gcref_to_instance(W_Root, gcref)
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
@@ -61,8 +61,8 @@
def setitem_w(self, space, w_key, w_value):
hkey = space.hash_w(w_key)
- gcref = self.h.get(hkey)
- array = lltype.cast_opaque_ptr(PARRAY, gcref)
+ entry = self.h.lookup(hkey)
+ array = lltype.cast_opaque_ptr(PARRAY, entry.object)
if array:
i = find_equal_item(space, array, w_key)
if i >= 0:
@@ -77,13 +77,12 @@
L = 0
narray[L] = cast_instance_to_gcref(w_key)
narray[L + 1] = cast_instance_to_gcref(w_value)
- gcref = lltype.cast_opaque_ptr(llmemory.GCREF, narray)
- self.h.set(hkey, gcref)
+ entry.object = lltype.cast_opaque_ptr(llmemory.GCREF, narray)
def delitem_w(self, space, w_key):
hkey = space.hash_w(w_key)
- gcref = self.h.get(hkey)
- array = lltype.cast_opaque_ptr(PARRAY, gcref)
+ entry = self.h.lookup(hkey)
+ array = lltype.cast_opaque_ptr(PARRAY, entry.object)
if array:
i = find_equal_item(space, array, w_key)
if i >= 0:
@@ -95,8 +94,7 @@
narray = lltype.malloc(ARRAY, L)
ll_arraycopy(array, narray, 0, 0, i)
ll_arraycopy(array, narray, i + 2, i, L - i)
- gcref = lltype.cast_opaque_ptr(llmemory.GCREF, narray)
- self.h.set(hkey, gcref)
+ entry.object = lltype.cast_opaque_ptr(llmemory.GCREF, narray)
return
space.raise_key_error(w_key)
@@ -122,8 +120,8 @@
@unwrap_spec(w_default=WrappedDefault(None))
def setdefault_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)
+ entry = self.h.lookup(hkey)
+ array = lltype.cast_opaque_ptr(PARRAY, entry.object)
if array:
i = find_equal_item(space, array, w_key)
if i >= 0:
@@ -137,8 +135,7 @@
L = 0
narray[L] = cast_instance_to_gcref(w_key)
narray[L + 1] = cast_instance_to_gcref(w_default)
- gcref = lltype.cast_opaque_ptr(llmemory.GCREF, narray)
- self.h.set(hkey, gcref)
+ entry.object = lltype.cast_opaque_ptr(llmemory.GCREF, narray)
return w_default
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
@@ -53,8 +53,8 @@
def add_w(self, space, w_key):
hkey = space.hash_w(w_key)
- gcref = self.h.get(hkey)
- array = lltype.cast_opaque_ptr(PARRAY, gcref)
+ 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
@@ -65,13 +65,12 @@
narray = lltype.malloc(ARRAY, 1)
L = 0
narray[L] = cast_instance_to_gcref(w_key)
- gcref = lltype.cast_opaque_ptr(llmemory.GCREF, narray)
- self.h.set(hkey, gcref)
+ entry.object = lltype.cast_opaque_ptr(llmemory.GCREF, narray)
def try_remove(self, space, w_key):
hkey = space.hash_w(w_key)
- gcref = self.h.get(hkey)
- array = lltype.cast_opaque_ptr(PARRAY, gcref)
+ entry = self.h.lookup(hkey)
+ array = lltype.cast_opaque_ptr(PARRAY, entry.object)
if not array:
return False
i = find_equal_item(space, array, w_key)
@@ -85,8 +84,7 @@
narray = lltype.malloc(ARRAY, L)
ll_arraycopy(array, narray, 0, 0, i)
ll_arraycopy(array, narray, i + 1, i, L - i)
- gcref = lltype.cast_opaque_ptr(llmemory.GCREF, narray)
- self.h.set(hkey, gcref)
+ entry.object = lltype.cast_opaque_ptr(llmemory.GCREF, narray)
return True
def remove_w(self, space, w_key):
diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py
--- a/rpython/rlib/rstm.py
+++ b/rpython/rlib/rstm.py
@@ -181,6 +181,7 @@
_STM_HASHTABLE_ENTRY = lltype.GcStruct('HASHTABLE_ENTRY',
('index', lltype.Unsigned),
('object', llmemory.GCREF))
+_STM_HASHTABLE_ENTRY_P = lltype.Ptr(_STM_HASHTABLE_ENTRY)
@dont_look_inside
def _ll_hashtable_get(h, key):
@@ -191,11 +192,17 @@
def _ll_hashtable_set(h, key, value):
llop.stm_hashtable_write(lltype.Void, h, h.ll_raw_hashtable, key, value)
+ at dont_look_inside
+def _ll_hashtable_lookup(h, key):
+ return llop.stm_hashtable_lookup(_STM_HASHTABLE_ENTRY_P,
+ h, h.ll_raw_hashtable, key)
+
_HASHTABLE_OBJ = lltype.GcStruct('HASHTABLE_OBJ',
('ll_raw_hashtable', _STM_HASHTABLE_P),
rtti=True,
adtmeths={'get': _ll_hashtable_get,
- 'set': _ll_hashtable_set})
+ 'set': _ll_hashtable_set,
+ 'lookup': _ll_hashtable_lookup})
NULL_HASHTABLE = lltype.nullptr(_HASHTABLE_OBJ)
def _ll_hashtable_trace(gc, obj, callback, arg):
@@ -254,3 +261,19 @@
del self._content[key]
except KeyError:
pass
+
+ def lookup(self, key):
+ assert type(key) is int
+ return EntryObjectForTest(self, key)
+
+class EntryObjectForTest(object):
+ def __init__(self, hashtable, key):
+ self.hashtable = hashtable
+ self.key = key
+
+ def _getobj(self):
+ return self.hashtable.get(self.key)
+ def _setobj(self, nvalue):
+ self.hashtable.set(self.key, nvalue)
+
+ object = property(_getobj, _setobj)
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -464,6 +464,7 @@
'stm_hashtable_free': LLOp(),
'stm_hashtable_read': LLOp(),
'stm_hashtable_write': LLOp(),
+ 'stm_hashtable_lookup': LLOp(),
'stm_hashtable_tracefn': LLOp(),
# __________ address operations __________
diff --git a/rpython/translator/stm/funcgen.py b/rpython/translator/stm/funcgen.py
--- a/rpython/translator/stm/funcgen.py
+++ b/rpython/translator/stm/funcgen.py
@@ -312,6 +312,14 @@
return ('stm_hashtable_write((object_t *)%s, %s, %s, (object_t *)%s, '
'&stm_thread_local);' % (arg0, arg1, arg2, arg3))
+def stm_hashtable_lookup(funcgen, op):
+ arg0 = funcgen.expr(op.args[0])
+ arg1 = funcgen.expr(op.args[1])
+ arg2 = funcgen.expr(op.args[2])
+ result = funcgen.expr(op.result)
+ return '%s = stm_hashtable_lookup((object_t *)%s, %s, %s);' % (
+ result, arg0, arg1, arg2)
+
def stm_hashtable_tracefn(funcgen, op):
arg0 = funcgen.expr(op.args[0])
arg1 = funcgen.expr(op.args[1])
More information about the pypy-commit
mailing list