Author: Carl Friedrich Bolz-Tereick <[email protected]>
Branch: rdict-fast-hash
Changeset: r93367:a903e9b5358b
Date: 2017-12-11 17:38 +0100
http://bitbucket.org/pypy/pypy/changeset/a903e9b5358b/
Log: thread the fast_hash info through the various layers into the
rordereddict implementation
diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py
--- a/rpython/annotator/bookkeeper.py
+++ b/rpython/annotator/bookkeeper.py
@@ -194,13 +194,14 @@
listdef.generalize_range_step(flags['range_step'])
return SomeList(listdef)
- def getdictdef(self, is_r_dict=False, force_non_null=False):
+ def getdictdef(self, is_r_dict=False, force_non_null=False,
fast_hash=False):
"""Get the DictDef associated with the current position."""
try:
dictdef = self.dictdefs[self.position_key]
except KeyError:
dictdef = DictDef(self, is_r_dict=is_r_dict,
- force_non_null=force_non_null)
+ force_non_null=force_non_null,
+ fast_hash=fast_hash)
self.dictdefs[self.position_key] = dictdef
return dictdef
diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py
--- a/rpython/annotator/builtin.py
+++ b/rpython/annotator/builtin.py
@@ -238,6 +238,14 @@
@analyzer_for(rpython.rlib.objectmodel.r_dict)
def robjmodel_r_dict(s_eqfn, s_hashfn, s_force_non_null=None,
s_fast_hash=None):
+ return _r_dict_helper(SomeDict, s_eqfn, s_hashfn, s_force_non_null,
s_fast_hash)
+
+@analyzer_for(rpython.rlib.objectmodel.r_ordereddict)
+def robjmodel_r_ordereddict(s_eqfn, s_hashfn, s_force_non_null=None,
s_fast_hash=None):
+ return _r_dict_helper(SomeOrderedDict, s_eqfn, s_hashfn,
+ s_force_non_null, s_fast_hash)
+
+def _r_dict_helper(cls, s_eqfn, s_hashfn, s_force_non_null, s_fast_hash):
if s_force_non_null is None:
force_non_null = False
else:
@@ -249,15 +257,10 @@
assert s_fast_hash.is_constant()
fast_hash = s_fast_hash.const
dictdef = getbookkeeper().getdictdef(is_r_dict=True,
- force_non_null=force_non_null)
+ force_non_null=force_non_null,
+ fast_hash=fast_hash)
dictdef.dictkey.update_rdict_annotations(s_eqfn, s_hashfn)
- return SomeDict(dictdef)
-
-@analyzer_for(rpython.rlib.objectmodel.r_ordereddict)
-def robjmodel_r_ordereddict(s_eqfn, s_hashfn):
- dictdef = getbookkeeper().getdictdef(is_r_dict=True)
- dictdef.dictkey.update_rdict_annotations(s_eqfn, s_hashfn)
- return SomeOrderedDict(dictdef)
+ return cls(dictdef)
@analyzer_for(rpython.rlib.objectmodel.hlinvoke)
def robjmodel_hlinvoke(s_repr, s_llcallable, *args_s):
diff --git a/rpython/annotator/dictdef.py b/rpython/annotator/dictdef.py
--- a/rpython/annotator/dictdef.py
+++ b/rpython/annotator/dictdef.py
@@ -81,12 +81,14 @@
def __init__(self, bookkeeper, s_key = s_ImpossibleValue,
s_value = s_ImpossibleValue,
is_r_dict = False,
- force_non_null = False):
+ force_non_null = False,
+ fast_hash = False):
self.dictkey = DictKey(bookkeeper, s_key, is_r_dict)
self.dictkey.itemof[self] = True
self.dictvalue = DictValue(bookkeeper, s_value)
self.dictvalue.itemof[self] = True
self.force_non_null = force_non_null
+ self.fast_hash = fast_hash
def read_key(self, position_key):
self.dictkey.read_locations.add(position_key)
diff --git a/rpython/rtyper/lltypesystem/rdict.py
b/rpython/rtyper/lltypesystem/rdict.py
--- a/rpython/rtyper/lltypesystem/rdict.py
+++ b/rpython/rtyper/lltypesystem/rdict.py
@@ -42,7 +42,8 @@
class DictRepr(AbstractDictRepr):
def __init__(self, rtyper, key_repr, value_repr, dictkey, dictvalue,
- custom_eq_hash=None, force_non_null=False):
+ custom_eq_hash=None, force_non_null=False, fast_hash=False):
+ # fast_hash is ignored (only implemented in rordereddict.py)
self.rtyper = rtyper
self.DICT = lltype.GcForwardReference()
self.lowleveltype = lltype.Ptr(self.DICT)
diff --git a/rpython/rtyper/lltypesystem/rordereddict.py
b/rpython/rtyper/lltypesystem/rordereddict.py
--- a/rpython/rtyper/lltypesystem/rordereddict.py
+++ b/rpython/rtyper/lltypesystem/rordereddict.py
@@ -66,7 +66,7 @@
def get_ll_dict(DICTKEY, DICTVALUE, get_custom_eq_hash=None, DICT=None,
ll_fasthash_function=None, ll_hash_function=None,
- ll_eq_function=None, method_cache={},
+ ll_eq_function=None, method_cache={}, fast_hash=False,
dummykeyobj=None, dummyvalueobj=None, rtyper=None):
# get the actual DICT type. if DICT is None, it's created, otherwise
# forward reference is becoming DICT
@@ -114,7 +114,10 @@
# * the value
entryfields.append(("value", DICTVALUE))
- if ll_fasthash_function is None:
+ if fast_hash:
+ assert get_custom_eq_hash is not None
+ entrymeths['entry_hash'] = ll_hash_custom_fast
+ elif ll_fasthash_function is None:
entryfields.append(("f_hash", lltype.Signed))
entrymeths['entry_hash'] = ll_hash_from_cache
else:
@@ -140,7 +143,7 @@
'keyeq': ll_keyeq_custom,
'r_rdict_eqfn': r_rdict_eqfn,
'r_rdict_hashfn': r_rdict_hashfn,
- 'paranoia': True,
+ 'paranoia': not fast_hash,
}
else:
# figure out which functions must be used to hash and compare
@@ -167,13 +170,14 @@
class OrderedDictRepr(AbstractDictRepr):
def __init__(self, rtyper, key_repr, value_repr, dictkey, dictvalue,
- custom_eq_hash=None, force_non_null=False):
+ custom_eq_hash=None, force_non_null=False, fast_hash=False):
#assert not force_non_null
self.rtyper = rtyper
self.finalized = False
self.DICT = lltype.GcForwardReference()
self.lowleveltype = lltype.Ptr(self.DICT)
self.custom_eq_hash = custom_eq_hash is not None
+ self.fast_hash = fast_hash
if not isinstance(key_repr, rmodel.Repr): # not computed yet, done by
setup()
assert callable(key_repr)
self._key_repr_computer = key_repr
@@ -211,6 +215,7 @@
self.r_rdict_eqfn, self.r_rdict_hashfn = (
self._custom_eq_hash_repr())
kwd['get_custom_eq_hash'] = self._custom_eq_hash_repr
+ kwd['fast_hash'] = self.fast_hash
else:
kwd['ll_hash_function'] = self.key_repr.get_ll_hash_function()
kwd['ll_eq_function'] = self.key_repr.get_ll_eq_function()
@@ -609,6 +614,12 @@
ENTRIES = lltype.typeOf(entries).TO
return ENTRIES.fasthashfn(entries[i].key)
+@signature(types.any(), types.any(), types.int(), returns=types.any())
+def ll_hash_custom_fast(entries, d, i):
+ DICT = lltype.typeOf(d).TO
+ key = entries[i].key
+ return objectmodel.hlinvoke(DICT.r_rdict_hashfn, d.fnkeyhash, key)
+
def ll_keyhash_custom(d, key):
DICT = lltype.typeOf(d).TO
return objectmodel.hlinvoke(DICT.r_rdict_hashfn, d.fnkeyhash, key)
diff --git a/rpython/rtyper/rdict.py b/rpython/rtyper/rdict.py
--- a/rpython/rtyper/rdict.py
+++ b/rpython/rtyper/rdict.py
@@ -15,6 +15,7 @@
s_key = dictkey.s_value
s_value = dictvalue.s_value
force_non_null = self.dictdef.force_non_null
+ fast_hash = self.dictdef.fast_hash
if dictkey.custom_eq_hash:
custom_eq_hash = lambda: (rtyper.getrepr(dictkey.s_rdict_eqfn),
rtyper.getrepr(dictkey.s_rdict_hashfn))
@@ -22,7 +23,7 @@
custom_eq_hash = None
return self.get_dict_repr()(rtyper, lambda: rtyper.getrepr(s_key),
lambda: rtyper.getrepr(s_value), dictkey, dictvalue,
- custom_eq_hash, force_non_null)
+ custom_eq_hash, force_non_null, fast_hash)
def rtyper_makekey(self):
self.dictdef.dictkey .dont_change_any_more = True
diff --git a/rpython/rtyper/test/test_rordereddict.py
b/rpython/rtyper/test/test_rordereddict.py
--- a/rpython/rtyper/test/test_rordereddict.py
+++ b/rpython/rtyper/test/test_rordereddict.py
@@ -386,8 +386,8 @@
return OrderedDict()
@staticmethod
- def new_r_dict(myeq, myhash):
- return objectmodel.r_ordereddict(myeq, myhash)
+ def new_r_dict(myeq, myhash, force_non_null=False, fast_hash=False):
+ return objectmodel.r_ordereddict(myeq, myhash,
force_non_null=force_non_null, fast_hash=fast_hash)
def test_two_dicts_with_different_value_types(self):
def func(i):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit