Author: Carl Friedrich Bolz <[email protected]>
Branch: guard-compatible
Changeset: r83143:befa6a197166
Date: 2016-03-18 18:02 +0100
http://bitbucket.org/pypy/pypy/changeset/befa6a197166/
Log: fix getattr (both in the objspace and in the callmethod version) to
not read (and thus promote) the type when we have a mapdict object
and we are jitted.
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
@@ -41,10 +41,19 @@
w_name = f.getname_w(nameindex)
w_value = None
- w_type = space.type(w_obj)
- if w_type.has_object_getattribute():
+ safe = False
+ if space.config.objspace.std.withmapdict and jit.we_are_jitted():
+ # compute safeness without reading the type
+ map = w_obj._get_mapdict_map_no_promote()
+ if map is not None and map._type_safe_to_do_getattr():
+ safe = True
+ else:
+ w_type = space.type(w_obj)
+ safe = w_type.has_object_getattribute()
+
+ if safe:
name = space.str_w(w_name)
- w_descr = w_type.lookup(name)
+ w_descr = space.lookup(w_obj, name)
if w_descr is None:
# this handles directly the common case
# module.function(args..)
@@ -62,6 +71,7 @@
if (space.config.objspace.std.withmapdict and
not jit.we_are_jitted()):
# let mapdict cache stuff
+ w_type = space.type(w_obj)
LOOKUP_METHOD_mapdict_fill_cache_method(
space, f.getcode(), name, nameindex, w_obj, w_type)
return
@@ -113,8 +123,17 @@
"""An optimized version of space.call_method()
based on the same principle as above.
"""
- w_type = space.type(w_obj)
- if w_type.has_object_getattribute():
+ safe = False
+ if space.config.objspace.std.withmapdict:
+ # compute safeness without reading the type
+ map = w_obj._get_mapdict_map_no_promote()
+ if map is not None and map._type_safe_to_do_getattr():
+ import pdb; pdb.set_trace()
+ safe = True
+ else:
+ w_type = space.type(w_obj)
+ safe = w_type.has_object_getattribute()
+ if safe:
w_descr = space.lookup(w_obj, methname)
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
@@ -333,7 +333,7 @@
assert version is not None
w_type = self.terminator.w_cls
w_res = w_type._pure_lookup_where_with_method_cache(
- name, w_cls.version_tag())
+ name, w_type.version_tag())[1]
return w_res
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -530,15 +530,23 @@
return self._DescrOperation_getattr(w_obj, w_name)
# an optional shortcut for performance
- w_type = self.type(w_obj)
- w_descr = w_type.getattribute_if_not_from_object()
- if w_descr is not None:
- return self._handle_getattribute(w_descr, w_obj, w_name)
+ safe = False
+ if self.config.objspace.std.withmapdict and jit.we_are_jitted():
+ # compute safeness without reading the type
+ map = w_obj._get_mapdict_map_no_promote()
+ if map is not None and map._type_safe_to_do_getattr():
+ safe = True
+
+ if not safe:
+ w_type = self.type(w_obj)
+ w_descr = w_type.getattribute_if_not_from_object()
+ if w_descr is not None:
+ return self._handle_getattribute(w_descr, w_obj, w_name)
# fast path: XXX this is duplicating most of the logic
# from the default __getattribute__ and the getattr() method...
name = self.str_w(w_name)
- w_descr = w_type.lookup(name)
+ w_descr = self.lookup(w_obj, name)
e = None
if w_descr is not None:
w_get = None
@@ -554,6 +562,7 @@
if w_get is not None:
# __get__ is allowed to raise an AttributeError to trigger
# use of __getattr__.
+ w_type = self.type(w_obj)
try:
return self.get_and_call_function(w_get, w_descr, w_obj,
w_type)
diff --git a/pypy/objspace/std/test/test_callmethod.py
b/pypy/objspace/std/test/test_callmethod.py
--- a/pypy/objspace/std/test/test_callmethod.py
+++ b/pypy/objspace/std/test/test_callmethod.py
@@ -111,6 +111,9 @@
class AppTestCallMethodWithGetattributeShortcut(AppTestCallMethod):
spaceconfig = {"objspace.std.getattributeshortcut": True}
+class AppTestCallMethodWithGetattributeShortcutAndMapdict(AppTestCallMethod):
+ spaceconfig = {"objspace.std.getattributeshortcut": True,
+ "objspace.std.withmapdict": True}
class TestCallMethod:
def test_space_call_method(self):
@@ -132,3 +135,7 @@
callmethod.LOOKUP_METHOD)
assert (self.space.FrameClass.CALL_METHOD.im_func ==
callmethod.CALL_METHOD)
+
+class TestCallMethodMapDict(TestCallMethod):
+ spaceconfig = {"objspace.std.getattributeshortcut": True,
+ "objspace.std.withmapdict": True}
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit