Author: Carl Friedrich Bolz <[email protected]>
Branch: dict-strategies
Changeset: r44495:49ef09de8987
Date: 2011-05-26 13:36 +0200
http://bitbucket.org/pypy/pypy/changeset/49ef09de8987/
Log: kill CALL_LIKELY_BUILTIN, it was not really worth the hassle any
more.
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -124,9 +124,6 @@
cmdline='--objspace -o'),
OptionDescription("opcodes", "opcodes to enable in the interpreter", [
- BoolOption("CALL_LIKELY_BUILTIN", "emit a special bytecode for likely
calls to builtin functions",
- default=False,
- requires=[("translation.stackless", False)]),
BoolOption("CALL_METHOD", "emit a special bytecode for expr.name()",
default=False),
]),
@@ -261,8 +258,7 @@
BoolOption("withcelldict",
"use dictionaries that are optimized for being used as
module dicts",
default=False,
- requires=[("objspace.opcodes.CALL_LIKELY_BUILTIN", False),
- ("objspace.honor__builtins__", False)]),
+ requires=[("objspace.honor__builtins__", False)]),
BoolOption("withmapdict",
"make instances really small but slow without the JIT",
@@ -345,8 +341,6 @@
backend = config.translation.backend
# all the good optimizations for PyPy should be listed here
- if level in ['2', '3']:
- config.objspace.opcodes.suggest(CALL_LIKELY_BUILTIN=True)
if level in ['2', '3', 'jit']:
config.objspace.opcodes.suggest(CALL_METHOD=True)
config.objspace.std.suggest(withrangelist=True)
diff --git a/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt
b/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt
deleted file mode 100644
--- a/pypy/doc/config/objspace.opcodes.CALL_LIKELY_BUILTIN.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Introduce a new opcode called ``CALL_LIKELY_BUILTIN``. It is used when
something
-is called, that looks like a builtin function (but could in reality be shadowed
-by a name in the module globals). For all module globals dictionaries it is
-then tracked which builtin name is shadowed in this module. If the
-``CALL_LIKELY_BUILTIN`` opcode is executed, it is checked whether the builtin
is
-shadowed. If not, the corresponding builtin is called. Otherwise the object
that
-is shadowing it is called instead. If no shadowing is happening, this saves two
-dictionary lookups on calls to builtins.
-
-For more information, see the section in `Standard Interpreter Optimizations`_.
-
-.. _`Standard Interpreter Optimizations`:
../interpreter-optimizations.html#call-likely-builtin
diff --git a/pypy/interpreter/astcompiler/assemble.py
b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -655,9 +655,6 @@
def _compute_CALL_FUNCTION_VAR_KW(arg):
return -_num_args(arg) - 2
-def _compute_CALL_LIKELY_BUILTIN(arg):
- return -(arg & 0xFF) + 1
-
def _compute_CALL_METHOD(arg):
return -_num_args(arg) - 1
diff --git a/pypy/interpreter/astcompiler/codegen.py
b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -12,7 +12,6 @@
from pypy.interpreter.pyparser.error import SyntaxError
from pypy.tool import stdlib_opcode as ops
from pypy.interpreter.error import OperationError
-from pypy.module.__builtin__.__init__ import BUILTIN_TO_INDEX
def compile_ast(space, module, info):
@@ -942,8 +941,7 @@
def visit_Call(self, call):
self.update_position(call.lineno)
- if self._optimize_builtin_call(call) or \
- self._optimize_method_call(call):
+ if self._optimize_method_call(call):
return
call.func.walkabout(self)
arg = 0
@@ -977,28 +975,6 @@
def _call_has_simple_args(self, call):
return self._call_has_no_star_args(call) and not call.keywords
- def _optimize_builtin_call(self, call):
- if not self.space.config.objspace.opcodes.CALL_LIKELY_BUILTIN or \
- not self._call_has_simple_args(call) or \
- not isinstance(call.func, ast.Name):
- return False
- func_name = call.func
- assert isinstance(func_name, ast.Name)
- name_scope = self.scope.lookup(func_name.id)
- if name_scope == symtable.SCOPE_GLOBAL_IMPLICIT or \
- name_scope == symtable.SCOPE_UNKNOWN:
- builtin_index = BUILTIN_TO_INDEX.get(func_name.id, -1)
- if builtin_index != -1:
- if call.args:
- args_count = len(call.args)
- self.visit_sequence(call.args)
- else:
- args_count = 0
- arg = builtin_index << 8 | args_count
- self.emit_op_arg(ops.CALL_LIKELY_BUILTIN, arg)
- return True
- return False
-
def _optimize_method_call(self, call):
if not self.space.config.objspace.opcodes.CALL_METHOD or \
not self._call_has_no_star_args(call) or \
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -1070,18 +1070,6 @@
def SET_LINENO(self, lineno, next_instr):
pass
- def CALL_LIKELY_BUILTIN(self, oparg, next_instr):
- # overridden by faster version in the standard object space.
- from pypy.module.__builtin__ import OPTIMIZED_BUILTINS
- varname = OPTIMIZED_BUILTINS[oparg >> 8]
- w_function = self._load_global(varname)
- nargs = oparg&0xFF
- try:
- w_result = self.space.call_valuestack(w_function, nargs, self)
- finally:
- self.dropvalues(nargs)
- self.pushvalue(w_result)
-
# overridden by faster version in the standard object space.
LOOKUP_METHOD = LOAD_ATTR
CALL_METHOD = CALL_FUNCTION
diff --git a/pypy/interpreter/test/test_executioncontext.py
b/pypy/interpreter/test/test_executioncontext.py
--- a/pypy/interpreter/test/test_executioncontext.py
+++ b/pypy/interpreter/test/test_executioncontext.py
@@ -232,31 +232,6 @@
assert [i[0] for i in events] == ['c_call', 'c_return', 'return',
'c_call']
assert events[0][1] == events[1][1]
- def test_tracing_range_builtinshortcut(self):
- opts = {"objspace.opcodes.CALL_LIKELY_BUILTIN": True}
- space = gettestobjspace(**opts)
- source = """def f(profile):
- import sys
- sys.setprofile(profile)
- range(10)
- sys.setprofile(None)
- """
- w_events = space.appexec([space.wrap(source)], """(source):
- import sys
- l = []
- def profile(frame, event, arg):
- l.append((event, arg))
- d = {}
- exec source in d
- f = d['f']
- f(profile)
- import dis
- print dis.dis(f)
- return l
- """)
- events = space.unwrap(w_events)
- assert [i[0] for i in events] == ['c_call', 'c_return', 'c_call']
-
def test_profile_and_exception(self):
space = self.space
w_res = space.appexec([], """():
@@ -280,9 +255,6 @@
""")
-class TestExecutionContextWithCallLikelyBuiltin(TestExecutionContext):
- keywords = {'objspace.opcodes.CALL_LIKELY_BUILTIN': True}
-
class TestExecutionContextWithCallMethod(TestExecutionContext):
keywords = {'objspace.opcodes.CALL_METHOD': True}
diff --git a/pypy/module/__builtin__/__init__.py
b/pypy/module/__builtin__/__init__.py
--- a/pypy/module/__builtin__/__init__.py
+++ b/pypy/module/__builtin__/__init__.py
@@ -5,20 +5,6 @@
# put builtins here that should be optimized somehow
-OPTIMIZED_BUILTINS = ["len", "range", "xrange", "min", "max", "enumerate",
- "isinstance", "type", "zip", "file", "format", "open", "abs", "chr",
- "unichr", "ord", "pow", "repr", "hash", "oct", "hex", "round", "cmp",
- "getattr", "setattr", "delattr", "callable", "int", "str", "float"]
-
-assert len(OPTIMIZED_BUILTINS) <= 256
-
-BUILTIN_TO_INDEX = {}
-
-for i, name in enumerate(OPTIMIZED_BUILTINS):
- BUILTIN_TO_INDEX[name] = i
-
-assert len(OPTIMIZED_BUILTINS) == len(BUILTIN_TO_INDEX)
-
class Module(MixedModule):
"""Built-in functions, exceptions, and other objects."""
expose__file__attribute = False
@@ -141,9 +127,6 @@
def setup_after_space_initialization(self):
"""NOT_RPYTHON"""
space = self.space
- self.builtins_by_index = [None] * len(OPTIMIZED_BUILTINS)
- for i, name in enumerate(OPTIMIZED_BUILTINS):
- self.builtins_by_index[i] = space.getattr(self, space.wrap(name))
# install the more general version of isinstance() & co. in the space
from pypy.module.__builtin__ import abstractinst as ab
space.abstract_isinstance_w = ab.abstract_isinstance_w.__get__(space)
diff --git a/pypy/module/__builtin__/test/test_builtin.py
b/pypy/module/__builtin__/test/test_builtin.py
--- a/pypy/module/__builtin__/test/test_builtin.py
+++ b/pypy/module/__builtin__/test/test_builtin.py
@@ -619,62 +619,6 @@
raises(TypeError, pr, end=3)
raises(TypeError, pr, sep=42)
-class AppTestBuiltinOptimized(object):
- def setup_class(cls):
- from pypy.conftest import gettestobjspace
- cls.space = gettestobjspace(**{"objspace.opcodes.CALL_LIKELY_BUILTIN":
True})
-
- # hum, we need to invoke the compiler explicitely
- def test_xrange_len(self):
- s = """def test():
- x = xrange(33)
- assert len(x) == 33
- x = xrange(33.2)
- assert len(x) == 33
- x = xrange(33,0,-1)
- assert len(x) == 33
- x = xrange(33,0)
- assert len(x) == 0
- x = xrange(33,0.2)
- assert len(x) == 0
- x = xrange(0,33)
- assert len(x) == 33
- x = xrange(0,33,-1)
- assert len(x) == 0
- x = xrange(0,33,2)
- assert len(x) == 17
- x = xrange(0,32,2)
- assert len(x) == 16
- """
- ns = {}
- exec s in ns
- ns["test"]()
-
- def test_delete_from_builtins(self):
- s = """ """
- # XXX write this test!
-
- def test_shadow_case_bound_method(self):
- s = """def test(l):
- n = len(l)
- old_len = len
- class A(object):
- x = 5
- def length(self, o):
- return self.x*old_len(o)
- import __builtin__
- __builtin__.len = A().length
- try:
- m = len(l)
- finally:
- __builtin__.len = old_len
- return n+m
- """
- ns = {}
- exec s in ns
- res = ns["test"]([2,3,4])
- assert res == 18
-
def test_round(self):
assert round(11.234) == 11.0
assert round(11.234, -1) == 10.0
diff --git a/pypy/module/__builtin__/test/test_classobj.py
b/pypy/module/__builtin__/test/test_classobj.py
--- a/pypy/module/__builtin__/test/test_classobj.py
+++ b/pypy/module/__builtin__/test/test_classobj.py
@@ -987,9 +987,9 @@
if option.runappdirect:
py.test.skip("can only be run on py.py")
def is_strdict(space, w_class):
- from pypy.objspace.std.dictmultiobject import StrDictImplementation
+ from pypy.objspace.std.dictmultiobject import StringDictStrategy
w_d = w_class.getdict(space)
- return space.wrap(isinstance(w_d, StrDictImplementation) and
w_d.r_dict_content is None)
+ return space.wrap(isinstance(w_d.strategy, StringDictStrategy))
cls.w_is_strdict = cls.space.wrap(gateway.interp2app(is_strdict))
diff --git a/pypy/module/_lsprof/test/test_cprofile.py
b/pypy/module/_lsprof/test/test_cprofile.py
--- a/pypy/module/_lsprof/test/test_cprofile.py
+++ b/pypy/module/_lsprof/test/test_cprofile.py
@@ -181,8 +181,7 @@
class AppTestWithDifferentBytecodes(AppTestCProfile):
- keywords = {'objspace.opcodes.CALL_LIKELY_BUILTIN': True,
- 'objspace.opcodes.CALL_METHOD': True}
+ keywords = {'objspace.opcodes.CALL_METHOD': True}
expected_output = {}
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -793,14 +793,13 @@
"""
-# XXX picking a magic number is a mess. So far it works because we
-# have only two extra opcodes, which bump the magic number by +1 and
-# +2 respectively, and CPython leaves a gap of 10 when it increases
+# picking a magic number is a mess. So far it works because we
+# have only one extra opcode, which bumps the magic number by +2, and CPython
+# leaves a gap of 10 when it increases
# its own magic number. To avoid assigning exactly the same numbers
# as CPython we always add a +2. We'll have to think again when we
-# get at the fourth new opcode :-(
+# get three more new opcodes
#
-# * CALL_LIKELY_BUILTIN +1
# * CALL_METHOD +2
#
# In other words:
@@ -823,8 +822,6 @@
return struct.unpack('<i', magic)[0]
result = default_magic
- if space.config.objspace.opcodes.CALL_LIKELY_BUILTIN:
- result += 1
if space.config.objspace.opcodes.CALL_METHOD:
result += 2
return result
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
@@ -4,7 +4,6 @@
from pypy.interpreter import gateway
from pypy.interpreter.argument import Signature
from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.module.__builtin__.__init__ import BUILTIN_TO_INDEX,
OPTIMIZED_BUILTINS
from pypy.rlib.objectmodel import r_dict, we_are_translated
from pypy.objspace.std.settype import set_typedef as settypedef
@@ -40,11 +39,6 @@
assert w_type is None
strategy = space.fromcache(ModuleDictStrategy)
- elif space.config.objspace.opcodes.CALL_LIKELY_BUILTIN and module:
- assert w_type is None
- # create new Strategy everytime, because each must have its own
shadow-attribute
- strategy = WaryDictStrategy(space)
-
elif instance or strdict or module:
assert w_type is None
strategy = space.fromcache(StringDictStrategy)
@@ -94,7 +88,7 @@
getitem_str delitem length \
clear keys values \
items iter setdefault \
- popitem get_builtin_indexed".split()
+ popitem".split()
def make_method(method):
def f(self, *args):
@@ -145,13 +139,6 @@
else:
return result
- # the following method only makes sense when the option to use the
- # CALL_LIKELY_BUILTIN opcode is set. Otherwise it won't even be seen
- # by the annotator
- def get_builtin_indexed(self, w_dict, i):
- key = OPTIMIZED_BUILTINS[i]
- return self.getitem_str(w_dict, key)
-
def clear(self, w_dict):
strategy = self.space.fromcache(EmptyDictStrategy)
storage = strategy.get_empty_storage()
@@ -465,36 +452,6 @@
return None, None
-class WaryDictStrategy(StringDictStrategy):
- def __init__(self, space):
- StringDictStrategy.__init__(self, space)
- self.shadowed = [None] * len(BUILTIN_TO_INDEX)
-
- def setitem_str(self, w_dict, key, w_value):
- i = BUILTIN_TO_INDEX.get(key, -1)
- if i != -1:
- self.shadowed[i] = w_value
- self.unerase(w_dict.dstorage)[key] = w_value
-
- def delitem(self, w_dict, w_key):
- space = self.space
- w_key_type = space.type(w_key)
- if space.is_w(w_key_type, space.w_str):
- key = space.str_w(w_key)
- del self.unerase(w_dict.dstorage)[key]
- i = BUILTIN_TO_INDEX.get(key, -1)
- if i != -1:
- self.shadowed[i] = None
- elif _is_sane_hash(space, w_key_type):
- raise KeyError
- else:
- self.switch_to_object_strategy(w_dict)
- return w_dict.delitem(w_key)
-
- def get_builtin_indexed(self, w_dict, i):
- return self.shadowed[i]
-
-
class RDictIteratorImplementation(IteratorImplementation):
def __init__(self, space, dictimplementation):
IteratorImplementation.__init__(self, space, dictimplementation)
diff --git a/pypy/objspace/std/frame.py b/pypy/objspace/std/frame.py
--- a/pypy/objspace/std/frame.py
+++ b/pypy/objspace/std/frame.py
@@ -6,7 +6,7 @@
from pypy.interpreter import pyopcode, function
from pypy.interpreter.pyframe import PyFrame
from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.module.__builtin__ import OPTIMIZED_BUILTINS, Module
+from pypy.module.__builtin__ import Module
from pypy.objspace.std import intobject, smallintobject
from pypy.objspace.std.multimethod import FailedToImplement
from pypy.objspace.std.dictmultiobject import W_DictMultiObject
@@ -66,41 +66,6 @@
w_result = f.space.getitem(w_1, w_2)
f.pushvalue(w_result)
-def CALL_LIKELY_BUILTIN(f, oparg, next_instr):
- w_globals = f.w_globals
- num = oparg >> 8
- assert isinstance(w_globals, W_DictMultiObject)
- w_value = w_globals.get_builtin_indexed(num)
- if w_value is None:
- builtins = f.get_builtin()
- assert isinstance(builtins, Module)
- w_builtin_dict = builtins.getdict(f.space)
- assert isinstance(w_builtin_dict, W_DictMultiObject)
- w_value = w_builtin_dict.get_builtin_indexed(num)
- if w_value is None:
- varname = OPTIMIZED_BUILTINS[num]
- message = "global name '%s' is not defined"
- raise operationerrfmt(f.space.w_NameError,
- message, varname)
- nargs = oparg & 0xff
- w_function = w_value
- try:
- w_result = call_likely_builtin(f, w_function, nargs)
- finally:
- f.dropvalues(nargs)
- f.pushvalue(w_result)
-
-def call_likely_builtin(f, w_function, nargs):
- if isinstance(w_function, function.Function):
- executioncontext = f.space.getexecutioncontext()
- executioncontext.c_call_trace(f, w_function)
- res = w_function.funccall_valuestack(nargs, f)
- executioncontext.c_return_trace(f, w_function)
- return res
- args = f.make_arguments(nargs)
- return f.space.call_args(w_function, args)
-
-
compare_table = [
"lt", # "<"
"le", # "<="
@@ -145,8 +110,6 @@
StdObjSpaceFrame.BINARY_ADD = int_BINARY_ADD
if space.config.objspace.std.optimized_list_getitem:
StdObjSpaceFrame.BINARY_SUBSCR = list_BINARY_SUBSCR
- if space.config.objspace.opcodes.CALL_LIKELY_BUILTIN:
- StdObjSpaceFrame.CALL_LIKELY_BUILTIN = CALL_LIKELY_BUILTIN
if space.config.objspace.opcodes.CALL_METHOD:
from pypy.objspace.std.callmethod import LOOKUP_METHOD, CALL_METHOD
StdObjSpaceFrame.LOOKUP_METHOD = LOOKUP_METHOD
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
@@ -833,8 +833,6 @@
withsmalldicts = False
withcelldict = False
withmethodcache = False
- class opcodes:
- CALL_LIKELY_BUILTIN = False
FakeSpace.config = Config()
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit