Author: Armin Rigo <[email protected]>
Branch: stmgc-c8-dictstrategy
Changeset: r80644:0a32e67e5682
Date: 2015-11-12 09:23 +0100
http://bitbucket.org/pypy/pypy/changeset/0a32e67e5682/
Log: started, not working at all---we need prebuilt stmdicts...
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -273,6 +273,11 @@
default=False,
# weakrefs needed, because of get_subclasses()
requires=[("translation.rweakref", True)]),
+
+ BoolOption("withstmdict",
+ "for stm: make all dicts be conflict-aware",
+ default=False,
+ requires=[("translation.stm", True)]),
]),
])
@@ -326,7 +331,7 @@
# it creates many conflicts
# if config.objspace.std.withmapdict:
# config.objspace.std.withmethodcache = True #False
- pass
+ config.objspace.std.suggest(withstmdict=True)
def enable_allworkingmodules(config):
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
@@ -101,38 +101,50 @@
return w_value
+def create():
+ return rstm.create_hashtable()
+
+def getitem(space, h, w_key):
+ entry, array, i = really_find_equal_item(space, 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(space, h, w_key, w_value):
+ entry, array, i = really_find_equal_item(space, h, w_key)
+ if array:
+ if i >= 0:
+ # already there, update the value
+ array[i + 1] = cast_instance_to_gcref(w_value)
+ return
+ L = len(array)
+ narray = lltype.malloc(ARRAY, L + 2)
+ ll_arraycopy(array, narray, 0, 0, L)
+ else:
+ narray = lltype.malloc(ARRAY, 2)
+ L = 0
+ narray[L] = cast_instance_to_gcref(w_key)
+ narray[L + 1] = cast_instance_to_gcref(w_value)
+ h.writeobj(entry, lltype.cast_opaque_ptr(llmemory.GCREF, narray))
+
+def delitem(space, h, w_key):
+ if pop_from_entry(h, space, w_key) is None:
+ space.raise_key_error(w_key)
+
class W_STMDict(W_Root):
def __init__(self):
- self.h = rstm.create_hashtable()
+ self.h = create()
def getitem_w(self, space, 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)
+ return getitem(space, self.h, w_key)
def setitem_w(self, space, w_key, w_value):
- entry, array, i = really_find_equal_item(space, self.h, w_key)
- if array:
- if i >= 0:
- # already there, update the value
- array[i + 1] = cast_instance_to_gcref(w_value)
- return
- L = len(array)
- narray = lltype.malloc(ARRAY, L + 2)
- ll_arraycopy(array, narray, 0, 0, L)
- else:
- narray = lltype.malloc(ARRAY, 2)
- L = 0
- narray[L] = cast_instance_to_gcref(w_key)
- narray[L + 1] = cast_instance_to_gcref(w_value)
- self.h.writeobj(entry, lltype.cast_opaque_ptr(llmemory.GCREF, narray))
+ setitem(space, self.h, w_key, w_value)
def delitem_w(self, space, w_key):
- if pop_from_entry(self.h, space, w_key) is None:
- space.raise_key_error(w_key)
+ delitem(space, self.h, w_key)
def contains_w(self, space, w_key):
entry, array, i = really_find_equal_item(space, self.h, w_key)
diff --git a/pypy/objspace/std/celldict.py b/pypy/objspace/std/celldict.py
--- a/pypy/objspace/std/celldict.py
+++ b/pypy/objspace/std/celldict.py
@@ -149,12 +149,9 @@
def switch_to_object_strategy(self, w_dict):
space = self.space
d = self.unerase(w_dict.dstorage)
- strategy = space.fromcache(ObjectDictStrategy)
- d_new = strategy.unerase(strategy.get_empty_storage())
+ strategy = DictStrategy.make_empty_with_object_strategy(space, w_dict)
for key, cell in d.iteritems():
- d_new[_wrapkey(space, key)] = unwrap_cell(self.space, cell)
- w_dict.strategy = strategy
- w_dict.dstorage = strategy.erase(d_new)
+ strategy.setitem_str(w_dict, key, unwrap_cell(space, cell))
def getiterkeys(self, w_dict):
return self.unerase(w_dict.dstorage).iterkeys()
diff --git a/pypy/objspace/std/dictmultiobject.py
b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -55,13 +55,16 @@
elif space.config.objspace.std.withmapdict and instance:
from pypy.objspace.std.mapdict import MapDictStrategy
strategy = space.fromcache(MapDictStrategy)
- elif instance or strdict or module:
- assert w_type is None
- strategy = space.fromcache(BytesDictStrategy)
elif kwargs:
assert w_type is None
from pypy.objspace.std.kwargsdict import EmptyKwargsDictStrategy
strategy = space.fromcache(EmptyKwargsDictStrategy)
+ elif space.config.objspace.std.withstmdict:
+ from pypy.objspace.std.stmdict import StmDictStrategy
+ strategy = space.fromcache(StmDictStrategy)
+ elif instance or strdict or module:
+ assert w_type is None
+ strategy = space.fromcache(BytesDictStrategy)
else:
strategy = space.fromcache(EmptyDictStrategy)
if w_type is None:
@@ -528,12 +531,30 @@
def prepare_update(self, w_dict, num_extra):
pass
+ @staticmethod
+ def make_empty_with_object_strategy(space, w_dict):
+ if space.config.objspace.std.withstmdict:
+ from pypy.objspace.std.stmdict import StmDictStrategy
+ Cls = StmDictStrategy
+ else:
+ Cls = ObjectDictStrategy
+ strategy = space.fromcache(Cls)
+ storage = strategy.get_empty_storage()
+ w_dict.strategy = strategy
+ w_dict.dstorage = storage
+ return strategy
+
class EmptyDictStrategy(DictStrategy):
erase, unerase = rerased.new_erasing_pair("empty")
erase = staticmethod(erase)
unerase = staticmethod(unerase)
+ def __init__(self, space):
+ DictStrategy.__init__(self, space)
+ assert not space.config.objspace.std.withstmdict, (
+ "withstmdict: should not use EmptyDictStrategy at all")
+
def get_empty_storage(self):
return self.erase(None)
@@ -579,10 +600,7 @@
w_dict.dstorage = storage
def switch_to_object_strategy(self, w_dict):
- strategy = self.space.fromcache(ObjectDictStrategy)
- storage = strategy.get_empty_storage()
- w_dict.strategy = strategy
- w_dict.dstorage = storage
+ DictStrategy.make_empty_with_object_strategy(self.space, w_dict)
def getitem(self, w_dict, w_key):
#return w_value or None
@@ -840,6 +858,11 @@
class AbstractTypedStrategy(object):
_mixin_ = True
+ def __init__(self, space):
+ DictStrategy.__init__(self, space)
+ assert not space.config.objspace.std.withstmdict, (
+ "withstmdict: should not use %s at all" % self.__class__.__name__)
+
@staticmethod
def erase(storage):
raise NotImplementedError("abstract base class")
diff --git a/pypy/objspace/std/stmdict.py b/pypy/objspace/std/stmdict.py
new file mode 100644
--- /dev/null
+++ b/pypy/objspace/std/stmdict.py
@@ -0,0 +1,17 @@
+from rpython.rlib import rerased
+from pypy.objspace.std.dictmultiobject import (DictStrategy,
+ create_iterator_classes)
+from pypy.module.pypystm import stmdict
+
+
+class StmDictStrategy(DictStrategy):
+ erase, unerase = rerased.new_erasing_pair("stm")
+ erase = staticmethod(erase)
+ unerase = staticmethod(unerase)
+
+ def get_empty_storage(self):
+ return self.erase(stmdict.create())
+
+ def setitem(self, w_dict, w_key, w_value):
+ h = self.unerase(w_dict.dstorage)
+ stmdict.setitem(self.space, h, w_key, w_value)
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py
b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -1118,6 +1118,7 @@
withmethodcache = False
withidentitydict = False
withmapdict = False
+ withstmdict = False
FakeSpace.config = Config()
diff --git a/pypy/objspace/std/test/test_stmdict.py
b/pypy/objspace/std/test/test_stmdict.py
new file mode 100644
--- /dev/null
+++ b/pypy/objspace/std/test/test_stmdict.py
@@ -0,0 +1,8 @@
+import py
+from pypy.objspace.std.stmdict import StmDictStrategy
+from pypy.objspace.std.test.test_dictmultiobject import (
+ BaseTestRDictImplementation)
+
+
+class TestStmDictImplementation(BaseTestRDictImplementation):
+ StrategyClass = StmDictStrategy
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit