[pypy-commit] pypy kqueue: Merge upstream.
oberstet
noreply at buildbot.pypy.org
Sun Mar 4 20:39:28 CET 2012
Author: Tobias Oberstein <tobias.oberstein at gmail.com>
Branch: kqueue
Changeset: r53194:b11d2bf7c116
Date: 2012-03-03 18:59 +0100
http://bitbucket.org/pypy/pypy/changeset/b11d2bf7c116/
Log: Merge upstream.
diff --git a/lib_pypy/cPickle.py b/lib_pypy/cPickle.py
--- a/lib_pypy/cPickle.py
+++ b/lib_pypy/cPickle.py
@@ -2,16 +2,95 @@
# One-liner implementation of cPickle
#
-from pickle import *
+from pickle import Pickler, dump, dumps, PickleError, PicklingError, UnpicklingError, _EmptyClass
from pickle import __doc__, __version__, format_version, compatible_formats
+from types import *
+from copy_reg import dispatch_table
+from copy_reg import _extension_registry, _inverted_registry, _extension_cache
+import marshal, struct, sys
try: from __pypy__ import builtinify
except ImportError: builtinify = lambda f: f
+# These are purely informational; no code uses these.
+format_version = "2.0" # File format version we write
+compatible_formats = ["1.0", # Original protocol 0
+ "1.1", # Protocol 0 with INST added
+ "1.2", # Original protocol 1
+ "1.3", # Protocol 1 with BINFLOAT added
+ "2.0", # Protocol 2
+ ] # Old format versions we can read
+
+# Keep in synch with cPickle. This is the highest protocol number we
+# know how to read.
+HIGHEST_PROTOCOL = 2
BadPickleGet = KeyError
UnpickleableError = PicklingError
+MARK = ord('(') # push special markobject on stack
+STOP = ord('.') # every pickle ends with STOP
+POP = ord('0') # discard topmost stack item
+POP_MARK = ord('1') # discard stack top through topmost markobject
+DUP = ord('2') # duplicate top stack item
+FLOAT = ord('F') # push float object; decimal string argument
+INT = ord('I') # push integer or bool; decimal string argument
+BININT = ord('J') # push four-byte signed int
+BININT1 = ord('K') # push 1-byte unsigned int
+LONG = ord('L') # push long; decimal string argument
+BININT2 = ord('M') # push 2-byte unsigned int
+NONE = ord('N') # push None
+PERSID = ord('P') # push persistent object; id is taken from string arg
+BINPERSID = ord('Q') # " " " ; " " " " stack
+REDUCE = ord('R') # apply callable to argtuple, both on stack
+STRING = ord('S') # push string; NL-terminated string argument
+BINSTRING = ord('T') # push string; counted binary string argument
+SHORT_BINSTRING = ord('U') # " " ; " " " " < 256 bytes
+UNICODE = ord('V') # push Unicode string; raw-unicode-escaped'd argument
+BINUNICODE = ord('X') # " " " ; counted UTF-8 string argument
+APPEND = ord('a') # append stack top to list below it
+BUILD = ord('b') # call __setstate__ or __dict__.update()
+GLOBAL = ord('c') # push self.find_class(modname, name); 2 string args
+DICT = ord('d') # build a dict from stack items
+EMPTY_DICT = ord('}') # push empty dict
+APPENDS = ord('e') # extend list on stack by topmost stack slice
+GET = ord('g') # push item from memo on stack; index is string arg
+BINGET = ord('h') # " " " " " " ; " " 1-byte arg
+INST = ord('i') # build & push class instance
+LONG_BINGET = ord('j') # push item from memo on stack; index is 4-byte arg
+LIST = ord('l') # build list from topmost stack items
+EMPTY_LIST = ord(']') # push empty list
+OBJ = ord('o') # build & push class instance
+PUT = ord('p') # store stack top in memo; index is string arg
+BINPUT = ord('q') # " " " " " ; " " 1-byte arg
+LONG_BINPUT = ord('r') # " " " " " ; " " 4-byte arg
+SETITEM = ord('s') # add key+value pair to dict
+TUPLE = ord('t') # build tuple from topmost stack items
+EMPTY_TUPLE = ord(')') # push empty tuple
+SETITEMS = ord('u') # modify dict by adding topmost key+value pairs
+BINFLOAT = ord('G') # push float; arg is 8-byte float encoding
+
+TRUE = 'I01\n' # not an opcode; see INT docs in pickletools.py
+FALSE = 'I00\n' # not an opcode; see INT docs in pickletools.py
+
+# Protocol 2
+
+PROTO = ord('\x80') # identify pickle protocol
+NEWOBJ = ord('\x81') # build object by applying cls.__new__ to argtuple
+EXT1 = ord('\x82') # push object from extension registry; 1-byte index
+EXT2 = ord('\x83') # ditto, but 2-byte index
+EXT4 = ord('\x84') # ditto, but 4-byte index
+TUPLE1 = ord('\x85') # build 1-tuple from stack top
+TUPLE2 = ord('\x86') # build 2-tuple from two topmost stack items
+TUPLE3 = ord('\x87') # build 3-tuple from three topmost stack items
+NEWTRUE = ord('\x88') # push True
+NEWFALSE = ord('\x89') # push False
+LONG1 = ord('\x8a') # push long from < 256 bytes
+LONG4 = ord('\x8b') # push really big long
+
+_tuplesize2code = [EMPTY_TUPLE, TUPLE1, TUPLE2, TUPLE3]
+
+
# ____________________________________________________________
# XXX some temporary dark magic to produce pickled dumps that are
# closer to the ones produced by cPickle in CPython
@@ -44,3 +123,474 @@
file = StringIO()
Pickler(file, protocol).dump(obj)
return file.getvalue()
+
+# Why use struct.pack() for pickling but marshal.loads() for
+# unpickling? struct.pack() is 40% faster than marshal.dumps(), but
+# marshal.loads() is twice as fast as struct.unpack()!
+mloads = marshal.loads
+
+# Unpickling machinery
+
+class Unpickler(object):
+
+ def __init__(self, file):
+ """This takes a file-like object for reading a pickle data stream.
+
+ The protocol version of the pickle is detected automatically, so no
+ proto argument is needed.
+
+ The file-like object must have two methods, a read() method that
+ takes an integer argument, and a readline() method that requires no
+ arguments. Both methods should return a string. Thus file-like
+ object can be a file object opened for reading, a StringIO object,
+ or any other custom object that meets this interface.
+ """
+ self.readline = file.readline
+ self.read = file.read
+ self.memo = {}
+
+ def load(self):
+ """Read a pickled object representation from the open file.
+
+ Return the reconstituted object hierarchy specified in the file.
+ """
+ self.mark = object() # any new unique object
+ self.stack = []
+ self.append = self.stack.append
+ try:
+ key = ord(self.read(1))
+ while key != STOP:
+ self.dispatch[key](self)
+ key = ord(self.read(1))
+ except TypeError:
+ if self.read(1) == '':
+ raise EOFError
+ raise
+ return self.stack.pop()
+
+ # Return largest index k such that self.stack[k] is self.mark.
+ # If the stack doesn't contain a mark, eventually raises IndexError.
+ # This could be sped by maintaining another stack, of indices at which
+ # the mark appears. For that matter, the latter stack would suffice,
+ # and we wouldn't need to push mark objects on self.stack at all.
+ # Doing so is probably a good thing, though, since if the pickle is
+ # corrupt (or hostile) we may get a clue from finding self.mark embedded
+ # in unpickled objects.
+ def marker(self):
+ k = len(self.stack)-1
+ while self.stack[k] is not self.mark: k -= 1
+ return k
+
+ dispatch = {}
+
+ def load_proto(self):
+ proto = ord(self.read(1))
+ if not 0 <= proto <= 2:
+ raise ValueError, "unsupported pickle protocol: %d" % proto
+ dispatch[PROTO] = load_proto
+
+ def load_persid(self):
+ pid = self.readline()[:-1]
+ self.append(self.persistent_load(pid))
+ dispatch[PERSID] = load_persid
+
+ def load_binpersid(self):
+ pid = self.stack.pop()
+ self.append(self.persistent_load(pid))
+ dispatch[BINPERSID] = load_binpersid
+
+ def load_none(self):
+ self.append(None)
+ dispatch[NONE] = load_none
+
+ def load_false(self):
+ self.append(False)
+ dispatch[NEWFALSE] = load_false
+
+ def load_true(self):
+ self.append(True)
+ dispatch[NEWTRUE] = load_true
+
+ def load_int(self):
+ data = self.readline()
+ if data == FALSE[1:]:
+ val = False
+ elif data == TRUE[1:]:
+ val = True
+ else:
+ try:
+ val = int(data)
+ except ValueError:
+ val = long(data)
+ self.append(val)
+ dispatch[INT] = load_int
+
+ def load_binint(self):
+ self.append(mloads('i' + self.read(4)))
+ dispatch[BININT] = load_binint
+
+ def load_binint1(self):
+ self.append(ord(self.read(1)))
+ dispatch[BININT1] = load_binint1
+
+ def load_binint2(self):
+ self.append(mloads('i' + self.read(2) + '\000\000'))
+ dispatch[BININT2] = load_binint2
+
+ def load_long(self):
+ self.append(long(self.readline()[:-1], 0))
+ dispatch[LONG] = load_long
+
+ def load_long1(self):
+ n = ord(self.read(1))
+ bytes = self.read(n)
+ self.append(decode_long(bytes))
+ dispatch[LONG1] = load_long1
+
+ def load_long4(self):
+ n = mloads('i' + self.read(4))
+ bytes = self.read(n)
+ self.append(decode_long(bytes))
+ dispatch[LONG4] = load_long4
+
+ def load_float(self):
+ self.append(float(self.readline()[:-1]))
+ dispatch[FLOAT] = load_float
+
+ def load_binfloat(self, unpack=struct.unpack):
+ self.append(unpack('>d', self.read(8))[0])
+ dispatch[BINFLOAT] = load_binfloat
+
+ def load_string(self):
+ rep = self.readline()
+ if len(rep) < 3:
+ raise ValueError, "insecure string pickle"
+ if rep[0] == "'" == rep[-2]:
+ rep = rep[1:-2]
+ elif rep[0] == '"' == rep[-2]:
+ rep = rep[1:-2]
+ else:
+ raise ValueError, "insecure string pickle"
+ self.append(rep.decode("string-escape"))
+ dispatch[STRING] = load_string
+
+ def load_binstring(self):
+ L = mloads('i' + self.read(4))
+ self.append(self.read(L))
+ dispatch[BINSTRING] = load_binstring
+
+ def load_unicode(self):
+ self.append(unicode(self.readline()[:-1],'raw-unicode-escape'))
+ dispatch[UNICODE] = load_unicode
+
+ def load_binunicode(self):
+ L = mloads('i' + self.read(4))
+ self.append(unicode(self.read(L),'utf-8'))
+ dispatch[BINUNICODE] = load_binunicode
+
+ def load_short_binstring(self):
+ L = ord(self.read(1))
+ self.append(self.read(L))
+ dispatch[SHORT_BINSTRING] = load_short_binstring
+
+ def load_tuple(self):
+ k = self.marker()
+ self.stack[k:] = [tuple(self.stack[k+1:])]
+ dispatch[TUPLE] = load_tuple
+
+ def load_empty_tuple(self):
+ self.stack.append(())
+ dispatch[EMPTY_TUPLE] = load_empty_tuple
+
+ def load_tuple1(self):
+ self.stack[-1] = (self.stack[-1],)
+ dispatch[TUPLE1] = load_tuple1
+
+ def load_tuple2(self):
+ self.stack[-2:] = [(self.stack[-2], self.stack[-1])]
+ dispatch[TUPLE2] = load_tuple2
+
+ def load_tuple3(self):
+ self.stack[-3:] = [(self.stack[-3], self.stack[-2], self.stack[-1])]
+ dispatch[TUPLE3] = load_tuple3
+
+ def load_empty_list(self):
+ self.stack.append([])
+ dispatch[EMPTY_LIST] = load_empty_list
+
+ def load_empty_dictionary(self):
+ self.stack.append({})
+ dispatch[EMPTY_DICT] = load_empty_dictionary
+
+ def load_list(self):
+ k = self.marker()
+ self.stack[k:] = [self.stack[k+1:]]
+ dispatch[LIST] = load_list
+
+ def load_dict(self):
+ k = self.marker()
+ d = {}
+ items = self.stack[k+1:]
+ for i in range(0, len(items), 2):
+ key = items[i]
+ value = items[i+1]
+ d[key] = value
+ self.stack[k:] = [d]
+ dispatch[DICT] = load_dict
+
+ # INST and OBJ differ only in how they get a class object. It's not
+ # only sensible to do the rest in a common routine, the two routines
+ # previously diverged and grew different bugs.
+ # klass is the class to instantiate, and k points to the topmost mark
+ # object, following which are the arguments for klass.__init__.
+ def _instantiate(self, klass, k):
+ args = tuple(self.stack[k+1:])
+ del self.stack[k:]
+ instantiated = 0
+ if (not args and
+ type(klass) is ClassType and
+ not hasattr(klass, "__getinitargs__")):
+ try:
+ value = _EmptyClass()
+ value.__class__ = klass
+ instantiated = 1
+ except RuntimeError:
+ # In restricted execution, assignment to inst.__class__ is
+ # prohibited
+ pass
+ if not instantiated:
+ try:
+ value = klass(*args)
+ except TypeError, err:
+ raise TypeError, "in constructor for %s: %s" % (
+ klass.__name__, str(err)), sys.exc_info()[2]
+ self.append(value)
+
+ def load_inst(self):
+ module = self.readline()[:-1]
+ name = self.readline()[:-1]
+ klass = self.find_class(module, name)
+ self._instantiate(klass, self.marker())
+ dispatch[INST] = load_inst
+
+ def load_obj(self):
+ # Stack is ... markobject classobject arg1 arg2 ...
+ k = self.marker()
+ klass = self.stack.pop(k+1)
+ self._instantiate(klass, k)
+ dispatch[OBJ] = load_obj
+
+ def load_newobj(self):
+ args = self.stack.pop()
+ cls = self.stack[-1]
+ obj = cls.__new__(cls, *args)
+ self.stack[-1] = obj
+ dispatch[NEWOBJ] = load_newobj
+
+ def load_global(self):
+ module = self.readline()[:-1]
+ name = self.readline()[:-1]
+ klass = self.find_class(module, name)
+ self.append(klass)
+ dispatch[GLOBAL] = load_global
+
+ def load_ext1(self):
+ code = ord(self.read(1))
+ self.get_extension(code)
+ dispatch[EXT1] = load_ext1
+
+ def load_ext2(self):
+ code = mloads('i' + self.read(2) + '\000\000')
+ self.get_extension(code)
+ dispatch[EXT2] = load_ext2
+
+ def load_ext4(self):
+ code = mloads('i' + self.read(4))
+ self.get_extension(code)
+ dispatch[EXT4] = load_ext4
+
+ def get_extension(self, code):
+ nil = []
+ obj = _extension_cache.get(code, nil)
+ if obj is not nil:
+ self.append(obj)
+ return
+ key = _inverted_registry.get(code)
+ if not key:
+ raise ValueError("unregistered extension code %d" % code)
+ obj = self.find_class(*key)
+ _extension_cache[code] = obj
+ self.append(obj)
+
+ def find_class(self, module, name):
+ # Subclasses may override this
+ __import__(module)
+ mod = sys.modules[module]
+ klass = getattr(mod, name)
+ return klass
+
+ def load_reduce(self):
+ args = self.stack.pop()
+ func = self.stack[-1]
+ value = self.stack[-1](*args)
+ self.stack[-1] = value
+ dispatch[REDUCE] = load_reduce
+
+ def load_pop(self):
+ del self.stack[-1]
+ dispatch[POP] = load_pop
+
+ def load_pop_mark(self):
+ k = self.marker()
+ del self.stack[k:]
+ dispatch[POP_MARK] = load_pop_mark
+
+ def load_dup(self):
+ self.append(self.stack[-1])
+ dispatch[DUP] = load_dup
+
+ def load_get(self):
+ self.append(self.memo[self.readline()[:-1]])
+ dispatch[GET] = load_get
+
+ def load_binget(self):
+ i = ord(self.read(1))
+ self.append(self.memo[repr(i)])
+ dispatch[BINGET] = load_binget
+
+ def load_long_binget(self):
+ i = mloads('i' + self.read(4))
+ self.append(self.memo[repr(i)])
+ dispatch[LONG_BINGET] = load_long_binget
+
+ def load_put(self):
+ self.memo[self.readline()[:-1]] = self.stack[-1]
+ dispatch[PUT] = load_put
+
+ def load_binput(self):
+ i = ord(self.read(1))
+ self.memo[repr(i)] = self.stack[-1]
+ dispatch[BINPUT] = load_binput
+
+ def load_long_binput(self):
+ i = mloads('i' + self.read(4))
+ self.memo[repr(i)] = self.stack[-1]
+ dispatch[LONG_BINPUT] = load_long_binput
+
+ def load_append(self):
+ value = self.stack.pop()
+ self.stack[-1].append(value)
+ dispatch[APPEND] = load_append
+
+ def load_appends(self):
+ stack = self.stack
+ mark = self.marker()
+ lst = stack[mark - 1]
+ lst.extend(stack[mark + 1:])
+ del stack[mark:]
+ dispatch[APPENDS] = load_appends
+
+ def load_setitem(self):
+ stack = self.stack
+ value = stack.pop()
+ key = stack.pop()
+ dict = stack[-1]
+ dict[key] = value
+ dispatch[SETITEM] = load_setitem
+
+ def load_setitems(self):
+ stack = self.stack
+ mark = self.marker()
+ dict = stack[mark - 1]
+ for i in range(mark + 1, len(stack), 2):
+ dict[stack[i]] = stack[i + 1]
+
+ del stack[mark:]
+ dispatch[SETITEMS] = load_setitems
+
+ def load_build(self):
+ stack = self.stack
+ state = stack.pop()
+ inst = stack[-1]
+ setstate = getattr(inst, "__setstate__", None)
+ if setstate:
+ setstate(state)
+ return
+ slotstate = None
+ if isinstance(state, tuple) and len(state) == 2:
+ state, slotstate = state
+ if state:
+ try:
+ d = inst.__dict__
+ try:
+ for k, v in state.iteritems():
+ d[intern(k)] = v
+ # keys in state don't have to be strings
+ # don't blow up, but don't go out of our way
+ except TypeError:
+ d.update(state)
+
+ except RuntimeError:
+ # XXX In restricted execution, the instance's __dict__
+ # is not accessible. Use the old way of unpickling
+ # the instance variables. This is a semantic
+ # difference when unpickling in restricted
+ # vs. unrestricted modes.
+ # Note, however, that cPickle has never tried to do the
+ # .update() business, and always uses
+ # PyObject_SetItem(inst.__dict__, key, value) in a
+ # loop over state.items().
+ for k, v in state.items():
+ setattr(inst, k, v)
+ if slotstate:
+ for k, v in slotstate.items():
+ setattr(inst, k, v)
+ dispatch[BUILD] = load_build
+
+ def load_mark(self):
+ self.append(self.mark)
+ dispatch[MARK] = load_mark
+
+#from pickle import decode_long
+
+def decode_long(data):
+ r"""Decode a long from a two's complement little-endian binary string.
+
+ >>> decode_long('')
+ 0L
+ >>> decode_long("\xff\x00")
+ 255L
+ >>> decode_long("\xff\x7f")
+ 32767L
+ >>> decode_long("\x00\xff")
+ -256L
+ >>> decode_long("\x00\x80")
+ -32768L
+ >>> decode_long("\x80")
+ -128L
+ >>> decode_long("\x7f")
+ 127L
+ """
+
+ nbytes = len(data)
+ if nbytes == 0:
+ return 0L
+ ind = nbytes - 1
+ while ind and ord(data[ind]) == 0:
+ ind -= 1
+ n = ord(data[ind])
+ while ind:
+ n <<= 8
+ ind -= 1
+ if ord(data[ind]):
+ n += ord(data[ind])
+ if ord(data[nbytes - 1]) >= 128:
+ n -= 1L << (nbytes << 3)
+ return n
+
+def load(f):
+ return Unpickler(f).load()
+
+def loads(str):
+ f = StringIO(str)
+ return Unpickler(f).load()
diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py
--- a/lib_pypy/datetime.py
+++ b/lib_pypy/datetime.py
@@ -1032,8 +1032,8 @@
def __setstate(self, string):
if len(string) != 4 or not (1 <= ord(string[2]) <= 12):
raise TypeError("not enough arguments")
- yhi, ylo, self._month, self._day = map(ord, string)
- self._year = yhi * 256 + ylo
+ self._month, self._day = ord(string[2]), ord(string[3])
+ self._year = ord(string[0]) * 256 + ord(string[1])
def __reduce__(self):
return (self.__class__, self._getstate())
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -208,6 +208,7 @@
This is the class supporting --gcrootfinder=asmgcc.
"""
is_shadow_stack = False
+ is_64_bit = (WORD == 8)
LOC_REG = 0
LOC_ESP_PLUS = 1
@@ -336,17 +337,17 @@
self._gcmap_deadentries += 1
item += asmgcroot.arrayitemsize
- def get_basic_shape(self, is_64_bit=False):
+ def get_basic_shape(self):
# XXX: Should this code even really know about stack frame layout of
# the JIT?
- if is_64_bit:
- return [chr(self.LOC_EBP_PLUS | 8),
- chr(self.LOC_EBP_MINUS | 8),
- chr(self.LOC_EBP_MINUS | 16),
- chr(self.LOC_EBP_MINUS | 24),
- chr(self.LOC_EBP_MINUS | 32),
- chr(self.LOC_EBP_MINUS | 40),
- chr(self.LOC_EBP_PLUS | 0),
+ if self.is_64_bit:
+ return [chr(self.LOC_EBP_PLUS | 4), # return addr: at 8(%rbp)
+ chr(self.LOC_EBP_MINUS | 4), # saved %rbx: at -8(%rbp)
+ chr(self.LOC_EBP_MINUS | 8), # saved %r12: at -16(%rbp)
+ chr(self.LOC_EBP_MINUS | 12), # saved %r13: at -24(%rbp)
+ chr(self.LOC_EBP_MINUS | 16), # saved %r14: at -32(%rbp)
+ chr(self.LOC_EBP_MINUS | 20), # saved %r15: at -40(%rbp)
+ chr(self.LOC_EBP_PLUS | 0), # saved %rbp: at (%rbp)
chr(0)]
else:
return [chr(self.LOC_EBP_PLUS | 4), # return addr: at 4(%ebp)
@@ -366,7 +367,11 @@
shape.append(chr(number | flag))
def add_frame_offset(self, shape, offset):
- assert (offset & 3) == 0
+ if self.is_64_bit:
+ assert (offset & 7) == 0
+ offset >>= 1
+ else:
+ assert (offset & 3) == 0
if offset >= 0:
num = self.LOC_EBP_PLUS | offset
else:
@@ -518,7 +523,7 @@
def initialize(self):
pass
- def get_basic_shape(self, is_64_bit=False):
+ def get_basic_shape(self):
return []
def add_frame_offset(self, shape, offset):
diff --git a/pypy/jit/backend/llsupport/test/test_gc.py b/pypy/jit/backend/llsupport/test/test_gc.py
--- a/pypy/jit/backend/llsupport/test/test_gc.py
+++ b/pypy/jit/backend/llsupport/test/test_gc.py
@@ -57,6 +57,7 @@
def frame_pos(n):
return -4*(4+n)
gcrootmap = GcRootMap_asmgcc()
+ gcrootmap.is_64_bit = False
num1 = frame_pos(-5)
num1a = num1|2
num2 = frame_pos(55)
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -1393,7 +1393,7 @@
self.force_spill_var(op.getarg(0))
def get_mark_gc_roots(self, gcrootmap, use_copy_area=False):
- shape = gcrootmap.get_basic_shape(IS_X86_64)
+ shape = gcrootmap.get_basic_shape()
for v, val in self.fm.bindings.items():
if (isinstance(v, BoxPtr) and self.rm.stays_alive(v)):
assert isinstance(val, StackLoc)
diff --git a/pypy/jit/metainterp/optimizeopt/__init__.py b/pypy/jit/metainterp/optimizeopt/__init__.py
--- a/pypy/jit/metainterp/optimizeopt/__init__.py
+++ b/pypy/jit/metainterp/optimizeopt/__init__.py
@@ -9,7 +9,7 @@
from pypy.jit.metainterp.optimizeopt.simplify import OptSimplify
from pypy.jit.metainterp.optimizeopt.pure import OptPure
from pypy.jit.metainterp.optimizeopt.earlyforce import OptEarlyForce
-from pypy.rlib.jit import PARAMETERS
+from pypy.rlib.jit import PARAMETERS, ENABLE_ALL_OPTS
from pypy.rlib.unroll import unrolling_iterable
from pypy.rlib.debug import debug_start, debug_stop, debug_print
@@ -30,6 +30,9 @@
ALL_OPTS_LIST = [name for name, _ in ALL_OPTS]
ALL_OPTS_NAMES = ':'.join([name for name, _ in ALL_OPTS])
+assert ENABLE_ALL_OPTS == ALL_OPTS_NAMES, (
+ 'please fix rlib/jit.py to say ENABLE_ALL_OPTS = %r' % (ALL_OPTS_NAMES,))
+
def build_opt_chain(metainterp_sd, enable_opts):
config = metainterp_sd.config
optimizations = []
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -9,7 +9,6 @@
from pypy.jit.metainterp.inliner import Inliner
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.jit.metainterp.resume import Snapshot
-from pypy.rlib.debug import debug_print
import sys, os
# FIXME: Introduce some VirtualOptimizer super class instead
@@ -121,9 +120,9 @@
limit = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.retrace_limit
if cell_token.retraced_count < limit:
cell_token.retraced_count += 1
- debug_print('Retracing (%d/%d)' % (cell_token.retraced_count, limit))
+ #debug_print('Retracing (%d/%d)' % (cell_token.retraced_count, limit))
else:
- debug_print("Retrace count reached, jumping to preamble")
+ #debug_print("Retrace count reached, jumping to preamble")
assert cell_token.target_tokens[0].virtual_state is None
jumpop.setdescr(cell_token.target_tokens[0])
self.optimizer.send_extra_operation(jumpop)
@@ -273,9 +272,9 @@
not newvalue.is_constant():
op = ResOperation(rop.SAME_AS, [op.result], newresult)
self.optimizer._newoperations.append(op)
- if self.optimizer.loop.logops:
- debug_print(' Falling back to add extra: ' +
- self.optimizer.loop.logops.repr_of_resop(op))
+ #if self.optimizer.loop.logops:
+ # debug_print(' Falling back to add extra: ' +
+ # self.optimizer.loop.logops.repr_of_resop(op))
self.optimizer.flush()
self.optimizer.emitting_dissabled = False
@@ -341,8 +340,8 @@
if i == len(newoperations):
while j < len(jumpargs):
a = jumpargs[j]
- if self.optimizer.loop.logops:
- debug_print('J: ' + self.optimizer.loop.logops.repr_of_arg(a))
+ #if self.optimizer.loop.logops:
+ # debug_print('J: ' + self.optimizer.loop.logops.repr_of_arg(a))
self.import_box(a, inputargs, short_jumpargs, jumpargs)
j += 1
else:
@@ -353,11 +352,11 @@
if op.is_guard():
args = args + op.getfailargs()
- if self.optimizer.loop.logops:
- debug_print('OP: ' + self.optimizer.loop.logops.repr_of_resop(op))
+ #if self.optimizer.loop.logops:
+ # debug_print('OP: ' + self.optimizer.loop.logops.repr_of_resop(op))
for a in args:
- if self.optimizer.loop.logops:
- debug_print('A: ' + self.optimizer.loop.logops.repr_of_arg(a))
+ #if self.optimizer.loop.logops:
+ # debug_print('A: ' + self.optimizer.loop.logops.repr_of_arg(a))
self.import_box(a, inputargs, short_jumpargs, jumpargs)
i += 1
newoperations = self.optimizer.get_newoperations()
@@ -370,18 +369,18 @@
# that is compatible with the virtual state at the start of the loop
modifier = VirtualStateAdder(self.optimizer)
final_virtual_state = modifier.get_virtual_state(original_jumpargs)
- debug_start('jit-log-virtualstate')
- virtual_state.debug_print('Closed loop with ')
+ #debug_start('jit-log-virtualstate')
+ #virtual_state.debug_print('Closed loop with ')
bad = {}
if not virtual_state.generalization_of(final_virtual_state, bad):
# We ended up with a virtual state that is not compatible
# and we are thus unable to jump to the start of the loop
- final_virtual_state.debug_print("Bad virtual state at end of loop, ",
- bad)
- debug_stop('jit-log-virtualstate')
+ #final_virtual_state.debug_print("Bad virtual state at end of loop, ",
+ # bad)
+ #debug_stop('jit-log-virtualstate')
raise InvalidLoop
- debug_stop('jit-log-virtualstate')
+ #debug_stop('jit-log-virtualstate')
maxguards = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.max_retrace_guards
if self.optimizer.emitted_guards > maxguards:
@@ -444,9 +443,9 @@
self.ensure_short_op_emitted(self.short_boxes.producer(a), optimizer,
seen)
- if self.optimizer.loop.logops:
- debug_print(' Emitting short op: ' +
- self.optimizer.loop.logops.repr_of_resop(op))
+ #if self.optimizer.loop.logops:
+ # debug_print(' Emitting short op: ' +
+ # self.optimizer.loop.logops.repr_of_resop(op))
optimizer.send_extra_operation(op)
seen[op.result] = True
@@ -527,8 +526,8 @@
args = jumpop.getarglist()
modifier = VirtualStateAdder(self.optimizer)
virtual_state = modifier.get_virtual_state(args)
- debug_start('jit-log-virtualstate')
- virtual_state.debug_print("Looking for ")
+ #debug_start('jit-log-virtualstate')
+ #virtual_state.debug_print("Looking for ")
for target in cell_token.target_tokens:
if not target.virtual_state:
@@ -537,10 +536,10 @@
extra_guards = []
bad = {}
- debugmsg = 'Did not match '
+ #debugmsg = 'Did not match '
if target.virtual_state.generalization_of(virtual_state, bad):
ok = True
- debugmsg = 'Matched '
+ #debugmsg = 'Matched '
else:
try:
cpu = self.optimizer.cpu
@@ -549,13 +548,13 @@
extra_guards)
ok = True
- debugmsg = 'Guarded to match '
+ #debugmsg = 'Guarded to match '
except InvalidLoop:
pass
- target.virtual_state.debug_print(debugmsg, bad)
+ #target.virtual_state.debug_print(debugmsg, bad)
if ok:
- debug_stop('jit-log-virtualstate')
+ #debug_stop('jit-log-virtualstate')
values = [self.getvalue(arg)
for arg in jumpop.getarglist()]
@@ -576,13 +575,13 @@
newop = inliner.inline_op(shop)
self.optimizer.send_extra_operation(newop)
except InvalidLoop:
- debug_print("Inlining failed unexpectedly",
- "jumping to preamble instead")
+ #debug_print("Inlining failed unexpectedly",
+ # "jumping to preamble instead")
assert cell_token.target_tokens[0].virtual_state is None
jumpop.setdescr(cell_token.target_tokens[0])
self.optimizer.send_extra_operation(jumpop)
return True
- debug_stop('jit-log-virtualstate')
+ #debug_stop('jit-log-virtualstate')
return False
class ValueImporter(object):
diff --git a/pypy/jit/metainterp/optimizeopt/virtualstate.py b/pypy/jit/metainterp/optimizeopt/virtualstate.py
--- a/pypy/jit/metainterp/optimizeopt/virtualstate.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualstate.py
@@ -681,13 +681,14 @@
self.synthetic[op] = True
def debug_print(self, logops):
- debug_start('jit-short-boxes')
- for box, op in self.short_boxes.items():
- if op:
- debug_print(logops.repr_of_arg(box) + ': ' + logops.repr_of_resop(op))
- else:
- debug_print(logops.repr_of_arg(box) + ': None')
- debug_stop('jit-short-boxes')
+ if 0:
+ debug_start('jit-short-boxes')
+ for box, op in self.short_boxes.items():
+ if op:
+ debug_print(logops.repr_of_arg(box) + ': ' + logops.repr_of_resop(op))
+ else:
+ debug_print(logops.repr_of_arg(box) + ': None')
+ debug_stop('jit-short-boxes')
def operations(self):
if not we_are_translated(): # For tests
diff --git a/pypy/jit/metainterp/test/test_compile.py b/pypy/jit/metainterp/test/test_compile.py
--- a/pypy/jit/metainterp/test/test_compile.py
+++ b/pypy/jit/metainterp/test/test_compile.py
@@ -14,7 +14,7 @@
ts = typesystem.llhelper
def __init__(self):
self.seen = []
- def compile_loop(self, inputargs, operations, token, name=''):
+ def compile_loop(self, inputargs, operations, token, log=True, name=''):
self.seen.append((inputargs, operations, token))
class FakeLogger(object):
diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py
--- a/pypy/module/array/interp_array.py
+++ b/pypy/module/array/interp_array.py
@@ -11,6 +11,7 @@
from pypy.objspace.std.register_all import register_all
from pypy.rlib.rarithmetic import ovfcheck
from pypy.rlib.unroll import unrolling_iterable
+from pypy.rlib.objectmodel import specialize
from pypy.rpython.lltypesystem import lltype, rffi
@@ -159,13 +160,15 @@
def make_array(mytype):
+ W_ArrayBase = globals()['W_ArrayBase']
+
class W_Array(W_ArrayBase):
itemsize = mytype.bytes
typecode = mytype.typecode
@staticmethod
def register(typeorder):
- typeorder[W_Array] = []
+ typeorder[W_Array] = [(W_ArrayBase, None)]
def __init__(self, space):
self.space = space
@@ -583,30 +586,28 @@
raise OperationError(space.w_ValueError, space.wrap(msg))
# Compare methods
+ @specialize.arg(3)
def _cmp_impl(space, self, other, space_fn):
- if isinstance(other, W_ArrayBase):
- w_lst1 = array_tolist__Array(space, self)
- w_lst2 = space.call_method(other, 'tolist')
- return space_fn(w_lst1, w_lst2)
- else:
- return space.w_NotImplemented
+ w_lst1 = array_tolist__Array(space, self)
+ w_lst2 = space.call_method(other, 'tolist')
+ return space_fn(w_lst1, w_lst2)
- def eq__Array_ANY(space, self, other):
+ def eq__Array_ArrayBase(space, self, other):
return _cmp_impl(space, self, other, space.eq)
- def ne__Array_ANY(space, self, other):
+ def ne__Array_ArrayBase(space, self, other):
return _cmp_impl(space, self, other, space.ne)
- def lt__Array_ANY(space, self, other):
+ def lt__Array_ArrayBase(space, self, other):
return _cmp_impl(space, self, other, space.lt)
- def le__Array_ANY(space, self, other):
+ def le__Array_ArrayBase(space, self, other):
return _cmp_impl(space, self, other, space.le)
- def gt__Array_ANY(space, self, other):
+ def gt__Array_ArrayBase(space, self, other):
return _cmp_impl(space, self, other, space.gt)
- def ge__Array_ANY(space, self, other):
+ def ge__Array_ArrayBase(space, self, other):
return _cmp_impl(space, self, other, space.ge)
# Misc methods
diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py
--- a/pypy/module/array/test/test_array.py
+++ b/pypy/module/array/test/test_array.py
@@ -845,8 +845,11 @@
cls.maxint = sys.maxint
class AppTestArray(BaseArrayTests):
+ OPTIONS = {}
+
def setup_class(cls):
- cls.space = gettestobjspace(usemodules=('array', 'struct', '_rawffi'))
+ cls.space = gettestobjspace(usemodules=('array', 'struct', '_rawffi'),
+ **cls.OPTIONS)
cls.w_array = cls.space.appexec([], """():
import array
return array.array
@@ -868,3 +871,7 @@
a = self.array('b', range(4))
a[::-1] = a
assert a == self.array('b', [3, 2, 1, 0])
+
+
+class AppTestArrayBuiltinShortcut(AppTestArray):
+ OPTIONS = {'objspace.std.builtinshortcut': True}
diff --git a/pypy/module/select/test/test_ztranslation.py b/pypy/module/select/test/test_ztranslation.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/select/test/test_ztranslation.py
@@ -0,0 +1,5 @@
+
+from pypy.objspace.fake.checkmodule import checkmodule
+
+def test_select_translates():
+ checkmodule('select')
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -392,6 +392,9 @@
class JitHintError(Exception):
"""Inconsistency in the JIT hints."""
+ENABLE_ALL_OPTS = (
+ 'intbounds:rewrite:virtualize:string:earlyforce:pure:heap:ffi:unroll')
+
PARAMETER_DOCS = {
'threshold': 'number of times a loop has to run for it to become hot',
'function_threshold': 'number of times a function must run for it to become traced from start',
@@ -402,7 +405,8 @@
'retrace_limit': 'how many times we can try retracing before giving up',
'max_retrace_guards': 'number of extra guards a retrace can cause',
'max_unroll_loops': 'number of extra unrollings a loop can cause',
- 'enable_opts': 'optimizations to enable or all, INTERNAL USE ONLY'
+ 'enable_opts': 'INTERNAL USE ONLY: optimizations to enable, or all = %s' %
+ ENABLE_ALL_OPTS,
}
PARAMETERS = {'threshold': 1039, # just above 1024, prime
diff --git a/pypy/rpython/memory/gctransform/asmgcroot.py b/pypy/rpython/memory/gctransform/asmgcroot.py
--- a/pypy/rpython/memory/gctransform/asmgcroot.py
+++ b/pypy/rpython/memory/gctransform/asmgcroot.py
@@ -442,6 +442,8 @@
ll_assert(location >= 0, "negative location")
kind = location & LOC_MASK
offset = location & ~ LOC_MASK
+ if IS_64_BITS:
+ offset <<= 1
if kind == LOC_REG: # register
if location == LOC_NOWHERE:
return llmemory.NULL
diff --git a/pypy/translator/c/gcc/instruction.py b/pypy/translator/c/gcc/instruction.py
--- a/pypy/translator/c/gcc/instruction.py
+++ b/pypy/translator/c/gcc/instruction.py
@@ -13,13 +13,17 @@
ARGUMENT_REGISTERS_64 = ('%rdi', '%rsi', '%rdx', '%rcx', '%r8', '%r9')
-def frameloc_esp(offset):
+def frameloc_esp(offset, wordsize):
assert offset >= 0
- assert offset % 4 == 0
+ assert offset % wordsize == 0
+ if wordsize == 8: # in this case, there are 3 null bits, but we
+ offset >>= 1 # only need 2 of them
return LOC_ESP_PLUS | offset
-def frameloc_ebp(offset):
- assert offset % 4 == 0
+def frameloc_ebp(offset, wordsize):
+ assert offset % wordsize == 0
+ if wordsize == 8: # in this case, there are 3 null bits, but we
+ offset >>= 1 # only need 2 of them
if offset >= 0:
return LOC_EBP_PLUS | offset
else:
@@ -57,12 +61,12 @@
# try to use esp-relative addressing
ofs_from_esp = framesize + self.ofs_from_frame_end
if ofs_from_esp % 2 == 0:
- return frameloc_esp(ofs_from_esp)
+ return frameloc_esp(ofs_from_esp, wordsize)
# we can get an odd value if the framesize is marked as bogus
# by visit_andl()
assert uses_frame_pointer
ofs_from_ebp = self.ofs_from_frame_end + wordsize
- return frameloc_ebp(ofs_from_ebp)
+ return frameloc_ebp(ofs_from_ebp, wordsize)
class Insn(object):
diff --git a/pypy/translator/c/gcc/trackgcroot.py b/pypy/translator/c/gcc/trackgcroot.py
--- a/pypy/translator/c/gcc/trackgcroot.py
+++ b/pypy/translator/c/gcc/trackgcroot.py
@@ -78,9 +78,9 @@
if self.is_stack_bottom:
retaddr = LOC_NOWHERE # end marker for asmgcroot.py
elif self.uses_frame_pointer:
- retaddr = frameloc_ebp(self.WORD)
+ retaddr = frameloc_ebp(self.WORD, self.WORD)
else:
- retaddr = frameloc_esp(insn.framesize)
+ retaddr = frameloc_esp(insn.framesize, self.WORD)
shape = [retaddr]
# the first gcroots are always the ones corresponding to
# the callee-saved registers
@@ -894,6 +894,8 @@
return '%' + cls.CALLEE_SAVE_REGISTERS[reg].replace("%", "")
else:
offset = loc & ~ LOC_MASK
+ if cls.WORD == 8:
+ offset <<= 1
if kind == LOC_EBP_PLUS:
result = '(%' + cls.EBP.replace("%", "") + ')'
elif kind == LOC_EBP_MINUS:
diff --git a/pypy/translator/goal/app_main.py b/pypy/translator/goal/app_main.py
--- a/pypy/translator/goal/app_main.py
+++ b/pypy/translator/goal/app_main.py
@@ -130,30 +130,46 @@
sys.executable,)
print __doc__.rstrip()
if 'pypyjit' in sys.builtin_module_names:
- _print_jit_help()
+ print " --jit OPTIONS advanced JIT options: try 'off' or 'help'"
print
raise SystemExit
def _print_jit_help():
- import pypyjit
+ try:
+ import pypyjit
+ except ImportError:
+ print >> sys.stderr, "No jit support in %s" % (sys.executable,)
+ return
items = pypyjit.defaults.items()
items.sort()
+ print 'Advanced JIT options: a comma-separated list of OPTION=VALUE:'
for key, value in items:
- prefix = ' --jit %s=N %s' % (key, ' '*(18-len(key)))
+ print
+ print ' %s=N' % (key,)
doc = '%s (default %s)' % (pypyjit.PARAMETER_DOCS[key], value)
- while len(doc) > 51:
- i = doc[:51].rfind(' ')
- print prefix + doc[:i]
+ while len(doc) > 72:
+ i = doc[:74].rfind(' ')
+ if i < 0:
+ i = doc.find(' ')
+ if i < 0:
+ i = len(doc)
+ print ' ' + doc[:i]
doc = doc[i+1:]
- prefix = ' '*len(prefix)
- print prefix + doc
- print ' --jit off turn off the JIT'
+ print ' ' + doc
+ print
+ print ' off'
+ print ' turn off the JIT'
+ print ' help'
+ print ' print this page'
def print_version(*args):
print >> sys.stderr, "Python", sys.version
raise SystemExit
def set_jit_option(options, jitparam, *args):
+ if jitparam == 'help':
+ _print_jit_help()
+ raise SystemExit
if 'pypyjit' not in sys.builtin_module_names:
print >> sys.stderr, ("Warning: No jit support in %s" %
(sys.executable,))
More information about the pypy-commit
mailing list