[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