Author: Carl Friedrich Bolz <cfb...@gmx.de> Branch: value-profiling Changeset: r78897:5a064b6c607a Date: 2015-08-11 16:08 +0200 http://bitbucket.org/pypy/pypy/changeset/5a064b6c607a/
Log: (arigo, cfbolz): also support value profiling of instance attributes diff --git a/pypy/interpreter/valueprof.py b/pypy/interpreter/valueprof.py --- a/pypy/interpreter/valueprof.py +++ b/pypy/interpreter/valueprof.py @@ -47,8 +47,12 @@ if status != SEEN_TOO_MUCH: self._vprof_status = SEEN_TOO_MUCH elif status == SEEN_NOTHING: - self._vprof_value_wref = ref(value) - self._vprof_status = SEEN_OBJ + try: + self._vprof_value_wref = ref(value) + self._vprof_status = SEEN_OBJ + except TypeError: + # for tests, which really use unwrapped ints in a few places + self._vprof_status = SEEN_TOO_MUCH elif status == SEEN_INT: self._vprof_status = SEEN_TOO_MUCH elif status == SEEN_OBJ: diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py --- a/pypy/objspace/std/mapdict.py +++ b/pypy/objspace/std/mapdict.py @@ -4,6 +4,7 @@ from rpython.rlib.rarithmetic import intmask, r_uint from pypy.interpreter.baseobjspace import W_Root +from pypy.interpreter import valueprof from pypy.objspace.std.dictmultiobject import ( W_DictMultiObject, DictStrategy, ObjectDictStrategy, BaseKeyIterator, BaseValueIterator, BaseItemIterator, _never_equal_to_string @@ -30,9 +31,17 @@ self.terminator = terminator def read(self, obj, selector): + from pypy.objspace.std.intobject import W_IntObject attr = self.find_map_attr(selector) if attr is None: return self.terminator._read_terminator(obj, selector) + # XXX move to PlainAttribute? + if attr.can_fold_read_int(): + return W_IntObject(attr.read_constant_int()) + elif attr.can_fold_read_obj(): + w_res = attr.try_read_constant_obj() + if w_res is not None: + return w_res if ( jit.isconstant(attr.storageindex) and jit.isconstant(obj) and @@ -50,6 +59,7 @@ attr = self.find_map_attr(selector) if attr is None: return self.terminator._write_terminator(obj, selector, w_value) + attr.see_write(w_value) if not attr.ever_mutated: attr.ever_mutated = True obj._mapdict_write_storage(attr.storageindex, w_value) @@ -170,6 +180,7 @@ # for the benefit of the special subclasses obj._set_mapdict_map(attr) obj._mapdict_write_storage(attr.storageindex, w_value) + attr.see_write(w_value) def materialize_r_dict(self, space, obj, dict_w): raise NotImplementedError("abstract base class") @@ -274,8 +285,10 @@ terminator = terminator.devolved_dict_terminator return Terminator.set_terminator(self, obj, terminator) + class PlainAttribute(AbstractAttribute): _immutable_fields_ = ['selector', 'storageindex', 'back', 'ever_mutated?'] + objectmodel.import_from_mixin(valueprof.ValueProf) def __init__(self, selector, back): AbstractAttribute.__init__(self, back.space, back.terminator) @@ -284,6 +297,19 @@ self.back = back self._size_estimate = self.length() * NUM_DIGITS_POW2 self.ever_mutated = False + self.init_valueprof() + + # ____________________________________________________________ + # methods for ValueProf mixin + def is_int(self, w_obj): + from pypy.objspace.std.intobject import W_IntObject + return type(w_obj) is W_IntObject + + def get_int_val(self, w_obj): + from pypy.objspace.std.intobject import W_IntObject + assert isinstance(w_obj, W_IntObject) + return w_obj.intval + # ____________________________________________________________ def _copy_attr(self, obj, new_obj): w_value = self.read(obj, self.selector) diff --git a/pypy/objspace/std/test/test_mapdict.py b/pypy/objspace/std/test/test_mapdict.py --- a/pypy/objspace/std/test/test_mapdict.py +++ b/pypy/objspace/std/test/test_mapdict.py @@ -348,6 +348,31 @@ obj.setdictvalue(space, a, 50) assert c.terminator.size_estimate() in [(i + 10) // 2, (i + 11) // 2] +def test_value_profiling(monkeypatch): + class Value: + pass + a = Value() + cls = Class() + obj = cls.instantiate() + obj.setdictvalue(space, "a", a) + obj = cls.instantiate() + obj.setdictvalue(space, "a", a) + obj.setdictvalue(space, "a", a) + + def _mapdict_read_storage(storageindex): + assert 0 # not reached + + obj._mapdict_read_storage = _mapdict_read_storage + + assert obj.getdictvalue(space, "a") == a + assert obj.getdictvalue(space, "a") == a + + obj = cls.instantiate() + obj.setdictvalue(space, "a", a) + obj.setdictvalue(space, "a", Value()) + assert not obj.map.can_fold_read_obj() + + # ___________________________________________________________ # dict tests _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit