Author: Armin Rigo <ar...@tunes.org> Branch: mapdict-interp Changeset: r44255:0eedad4896ba Date: 2011-05-17 17:36 +0200 http://bitbucket.org/pypy/pypy/changeset/0eedad4896ba/
Log: Comments. diff --git a/pypy/objspace/std/callmethod.py b/pypy/objspace/std/callmethod.py --- a/pypy/objspace/std/callmethod.py +++ b/pypy/objspace/std/callmethod.py @@ -51,6 +51,7 @@ # this handles directly the common case # module.function(args..) w_value = w_obj.getdictvalue(space, name) + # xxx we could also use the mapdict cache in that case, probably else: typ = type(w_descr) if typ is function.Function or typ is function.FunctionWithFixedCode: 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 @@ -762,19 +762,27 @@ assert space.config.objspace.std.withmethodcache _, w_descr = w_type._pure_lookup_where_with_method_cache( name, version_tag) + # selector = ("", INVALID) if w_descr is None: - selector = (name, DICT) # common case: not shadowing anything + selector = (name, DICT) #common case: no such attr in the class elif isinstance(w_descr, TypeCell): - pass # shadowing a TypeCell: give up + pass # we have a TypeCell in the class: give up + elif space.is_data_descr(w_descr): + # we have a data descriptor, which means the dictionary value + # (if any) has no relevance. + from pypy.interpreter.typedef import Member + descr = space.interpclass_w(w_descr) + if isinstance(descr, Member): # it is a slot -- easy case + selector = ("slot", SLOTS_STARTING_FROM + descr.index) else: - if space.is_data_descr(w_descr): - from pypy.interpreter.typedef import Member - descr = space.interpclass_w(w_descr) - if isinstance(descr, Member): # a slot - selector = ("slot", SLOTS_STARTING_FROM + descr.index) - else: - selector = (name, DICT) # shadowing a non-data descr + # There is a non-data descriptor in the class. If there is + # also a dict attribute, use the latter, caching its position. + # If not, we loose. We could do better in this case too, + # but we don't care too much; the common case of a method + # invocation is handled by LOOKUP_METHOD_xxx below. + selector = (name, DICT) + # if selector[1] != INVALID: index = map.index(selector) if index >= 0: @@ -818,3 +826,7 @@ if w_method is None or isinstance(w_method, TypeCell): return _fill_cache(pycode, nameindex, map, version_tag, -1, w_method) + +# XXX fix me: if a function contains a loop with both LOAD_ATTR and +# XXX LOOKUP_METHOD on the same attribute name, it keeps trashing and +# XXX rebuilding the cache _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit