[pypy-commit] pypy stdlib-2.7.4: merge default
bdkearns
noreply at buildbot.pypy.org
Sun Apr 14 20:48:42 CEST 2013
Author: Brian Kearns <bdkearns at gmail.com>
Branch: stdlib-2.7.4
Changeset: r63337:39e2b357b2cb
Date: 2013-04-14 14:48 -0400
http://bitbucket.org/pypy/pypy/changeset/39e2b357b2cb/
Log: merge default
diff too long, truncating to 2000 out of 3015 lines
diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py
--- a/pypy/module/_cffi_backend/ccallback.py
+++ b/pypy/module/_cffi_backend/ccallback.py
@@ -134,7 +134,7 @@
# W_CTypePrimitiveSigned.convert_from_object() in order
# to write a whole 'ffi_arg'.
value = misc.as_long(space, w_res)
- misc.write_raw_signed_data(ll_res, value, SIZE_OF_FFI_ARG)
+ misc.write_raw_integer_data(ll_res, value, SIZE_OF_FFI_ARG)
return
else:
# zero extension: fill the '*result' with zeros, and (on big-
diff --git a/pypy/module/_cffi_backend/cdataobj.py b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -280,13 +280,8 @@
return self.ctype.iter(self)
@specialize.argtype(1)
- def write_raw_signed_data(self, source):
- misc.write_raw_signed_data(self._cdata, source, self.ctype.size)
- keepalive_until_here(self)
-
- @specialize.argtype(1)
- def write_raw_unsigned_data(self, source):
- misc.write_raw_unsigned_data(self._cdata, source, self.ctype.size)
+ def write_raw_integer_data(self, source):
+ misc.write_raw_integer_data(self._cdata, source, self.ctype.size)
keepalive_until_here(self)
def write_raw_float_data(self, source):
diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py
--- a/pypy/module/_cffi_backend/ctypeprim.py
+++ b/pypy/module/_cffi_backend/ctypeprim.py
@@ -63,7 +63,7 @@
else:
value = self._cast_generic(w_ob)
w_cdata = cdataobj.W_CDataMem(space, self.size, self)
- self.write_raw_integer_data(w_cdata, value)
+ w_cdata.write_raw_integer_data(value)
return w_cdata
def _cast_result(self, intvalue):
@@ -94,9 +94,6 @@
from pypy.module._cffi_backend import newtype
return newtype.new_primitive_type(self.space, "int")
- def write_raw_integer_data(self, w_cdata, value):
- w_cdata.write_raw_unsigned_data(value)
-
class W_CTypePrimitiveChar(W_CTypePrimitiveCharOrUniChar):
_attrs_ = []
@@ -188,10 +185,10 @@
if self.size < rffi.sizeof(lltype.Signed):
if r_uint(value) - self.vmin > self.vrangemax:
self._overflow(w_ob)
- misc.write_raw_signed_data(cdata, value, self.size)
+ misc.write_raw_integer_data(cdata, value, self.size)
else:
value = misc.as_long_long(self.space, w_ob)
- misc.write_raw_signed_data(cdata, value, self.size)
+ misc.write_raw_integer_data(cdata, value, self.size)
def get_vararg_type(self):
if self.size < rffi.sizeof(rffi.INT):
@@ -199,9 +196,6 @@
return newtype.new_primitive_type(self.space, "int")
return self
- def write_raw_integer_data(self, w_cdata, value):
- w_cdata.write_raw_signed_data(value)
-
class W_CTypePrimitiveUnsigned(W_CTypePrimitive):
_attrs_ = ['value_fits_long', 'value_fits_ulong', 'vrangemax']
@@ -228,10 +222,10 @@
if self.value_fits_long:
if value > self.vrangemax:
self._overflow(w_ob)
- misc.write_raw_unsigned_data(cdata, value, self.size)
+ misc.write_raw_integer_data(cdata, value, self.size)
else:
value = misc.as_unsigned_long_long(self.space, w_ob, strict=True)
- misc.write_raw_unsigned_data(cdata, value, self.size)
+ misc.write_raw_integer_data(cdata, value, self.size)
def convert_to_object(self, cdata):
if self.value_fits_ulong:
@@ -250,9 +244,6 @@
return newtype.new_primitive_type(self.space, "int")
return self
- def write_raw_integer_data(self, w_cdata, value):
- w_cdata.write_raw_unsigned_data(value)
-
class W_CTypePrimitiveBool(W_CTypePrimitiveUnsigned):
_attrs_ = []
diff --git a/pypy/module/_cffi_backend/ctypestruct.py b/pypy/module/_cffi_backend/ctypestruct.py
--- a/pypy/module/_cffi_backend/ctypestruct.py
+++ b/pypy/module/_cffi_backend/ctypestruct.py
@@ -242,13 +242,11 @@
#
value = misc.as_long_long(space, w_ob)
if isinstance(ctype, ctypeprim.W_CTypePrimitiveSigned):
- is_signed = True
fmin = -(r_longlong(1) << (self.bitsize - 1))
fmax = (r_longlong(1) << (self.bitsize - 1)) - 1
if fmax == 0:
fmax = 1 # special case to let "int x:1" receive "1"
else:
- is_signed = False
fmin = r_longlong(0)
fmax = r_longlong((r_ulonglong(1) << self.bitsize) - 1)
if value < fmin or value > fmax:
@@ -260,10 +258,7 @@
rawvalue = r_ulonglong(value) << self.bitshift
rawfielddata = misc.read_raw_unsigned_data(cdata, ctype.size)
rawfielddata = (rawfielddata & ~rawmask) | (rawvalue & rawmask)
- if is_signed:
- misc.write_raw_signed_data(cdata, rawfielddata, ctype.size)
- else:
- misc.write_raw_unsigned_data(cdata, rawfielddata, ctype.size)
+ misc.write_raw_integer_data(cdata, rawfielddata, ctype.size)
W_CField.typedef = TypeDef(
diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -9,7 +9,6 @@
from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
from rpython.translator.tool.cbuild import ExternalCompilationInfo
-
# ____________________________________________________________
_prim_signed_types = unrolling_iterable([
@@ -66,22 +65,19 @@
return rffi.cast(rffi.LONGDOUBLEP, target)[0]
@specialize.argtype(1)
-def write_raw_unsigned_data(target, source, size):
- for TP, TPP in _prim_unsigned_types:
- if size == rffi.sizeof(TP):
- rffi.cast(TPP, target)[0] = rffi.cast(TP, source)
- return
+def write_raw_integer_data(target, source, size):
+ if is_signed_integer_type(lltype.typeOf(source)):
+ for TP, TPP in _prim_signed_types:
+ if size == rffi.sizeof(TP):
+ rffi.cast(TPP, target)[0] = rffi.cast(TP, source)
+ return
+ else:
+ for TP, TPP in _prim_unsigned_types:
+ if size == rffi.sizeof(TP):
+ rffi.cast(TPP, target)[0] = rffi.cast(TP, source)
+ return
raise NotImplementedError("bad integer size")
- at specialize.argtype(1)
-def write_raw_signed_data(target, source, size):
- for TP, TPP in _prim_signed_types:
- if size == rffi.sizeof(TP):
- rffi.cast(TPP, target)[0] = rffi.cast(TP, source)
- return
- raise NotImplementedError("bad integer size")
-
-
def write_raw_float_data(target, source, size):
for TP, TPP in _prim_float_types:
if size == rffi.sizeof(TP):
diff --git a/pypy/module/pypyjit/test_pypy_c/test__ffi.py b/pypy/module/pypyjit/test_pypy_c/test__ffi.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/pypyjit/test_pypy_c/test__ffi.py
@@ -0,0 +1,272 @@
+import sys, py
+from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC
+
+class Test__ffi(BaseTestPyPyC):
+
+ def test__ffi_call(self):
+ from rpython.rlib.test.test_clibffi import get_libm_name
+ def main(libm_name):
+ try:
+ from _ffi import CDLL, types
+ except ImportError:
+ sys.stderr.write('SKIP: cannot import _ffi\n')
+ return 0
+
+ libm = CDLL(libm_name)
+ pow = libm.getfunc('pow', [types.double, types.double],
+ types.double)
+ i = 0
+ res = 0
+ while i < 300:
+ tmp = pow(2, 3) # ID: fficall
+ res += tmp
+ i += 1
+ return pow.getaddr(), res
+ #
+ libm_name = get_libm_name(sys.platform)
+ log = self.run(main, [libm_name])
+ pow_addr, res = log.result
+ assert res == 8.0 * 300
+ py.test.xfail() # XXX re-optimize _ffi for the JIT?
+ loop, = log.loops_by_filename(self.filepath)
+ if 'ConstClass(pow)' in repr(loop): # e.g. OS/X
+ pow_addr = 'ConstClass(pow)'
+ assert loop.match_by_id('fficall', """
+ guard_not_invalidated(descr=...)
+ i17 = force_token()
+ setfield_gc(p0, i17, descr=<.* .*PyFrame.vable_token .*>)
+ f21 = call_release_gil(%s, 2.000000, 3.000000, descr=<Callf 8 ff EF=6>)
+ guard_not_forced(descr=...)
+ guard_no_exception(descr=...)
+ """ % pow_addr)
+
+
+ def test__ffi_call_frame_does_not_escape(self):
+ from rpython.rlib.test.test_clibffi import get_libm_name
+ def main(libm_name):
+ try:
+ from _ffi import CDLL, types
+ except ImportError:
+ sys.stderr.write('SKIP: cannot import _ffi\n')
+ return 0
+
+ libm = CDLL(libm_name)
+ pow = libm.getfunc('pow', [types.double, types.double],
+ types.double)
+
+ def mypow(a, b):
+ return pow(a, b)
+
+ i = 0
+ res = 0
+ while i < 300:
+ tmp = mypow(2, 3)
+ res += tmp
+ i += 1
+ return pow.getaddr(), res
+ #
+ libm_name = get_libm_name(sys.platform)
+ log = self.run(main, [libm_name])
+ pow_addr, res = log.result
+ assert res == 8.0 * 300
+ loop, = log.loops_by_filename(self.filepath)
+ opnames = log.opnames(loop.allops())
+ # we only force the virtualref, not its content
+ assert opnames.count('new_with_vtable') == 1
+
+ def test__ffi_call_releases_gil(self):
+ from rpython.rlib.clibffi import get_libc_name
+ def main(libc_name, n):
+ import time
+ import os
+ from threading import Thread
+ #
+ if os.name == 'nt':
+ from _ffi import WinDLL, types
+ libc = WinDLL('Kernel32.dll')
+ sleep = libc.getfunc('Sleep', [types.uint], types.uint)
+ delays = [0]*n + [1000]
+ else:
+ from _ffi import CDLL, types
+ libc = CDLL(libc_name)
+ sleep = libc.getfunc('sleep', [types.uint], types.uint)
+ delays = [0]*n + [1]
+ #
+ def loop_of_sleeps(i, delays):
+ for delay in delays:
+ sleep(delay) # ID: sleep
+ #
+ threads = [Thread(target=loop_of_sleeps, args=[i, delays]) for i in range(5)]
+ start = time.time()
+ for i, thread in enumerate(threads):
+ thread.start()
+ for thread in threads:
+ thread.join()
+ end = time.time()
+ return end - start
+ log = self.run(main, [get_libc_name(), 200], threshold=150,
+ import_site=True)
+ assert 1 <= log.result <= 1.5 # at most 0.5 seconds of overhead
+ loops = log.loops_by_id('sleep')
+ assert len(loops) == 1 # make sure that we actually JITted the loop
+
+ def test_ctypes_call(self):
+ from rpython.rlib.test.test_clibffi import get_libm_name
+ def main(libm_name):
+ import ctypes
+ libm = ctypes.CDLL(libm_name)
+ fabs = libm.fabs
+ fabs.argtypes = [ctypes.c_double]
+ fabs.restype = ctypes.c_double
+ x = -4
+ i = 0
+ while i < 300:
+ x = fabs(x)
+ x = x - 100
+ i += 1
+ return fabs._ptr.getaddr(), x
+
+ libm_name = get_libm_name(sys.platform)
+ log = self.run(main, [libm_name], import_site=True)
+ fabs_addr, res = log.result
+ assert res == -4.0
+ loop, = log.loops_by_filename(self.filepath)
+ ops = loop.allops()
+ opnames = log.opnames(ops)
+ assert opnames.count('new_with_vtable') == 1 # only the virtualref
+ py.test.xfail() # XXX re-optimize _ffi for the JIT?
+ assert opnames.count('call_release_gil') == 1
+ idx = opnames.index('call_release_gil')
+ call = ops[idx]
+ assert (call.args[0] == 'ConstClass(fabs)' or # e.g. OS/X
+ int(call.args[0]) == fabs_addr)
+
+
+ def test__ffi_struct(self):
+ def main():
+ from _ffi import _StructDescr, Field, types
+ fields = [
+ Field('x', types.slong),
+ ]
+ descr = _StructDescr('foo', fields)
+ struct = descr.allocate()
+ i = 0
+ while i < 300:
+ x = struct.getfield('x') # ID: getfield
+ x = x+1
+ struct.setfield('x', x) # ID: setfield
+ i += 1
+ return struct.getfield('x')
+ #
+ log = self.run(main, [])
+ py.test.xfail() # XXX re-optimize _ffi for the JIT?
+ loop, = log.loops_by_filename(self.filepath)
+ assert loop.match_by_id('getfield', """
+ guard_not_invalidated(descr=...)
+ i57 = getfield_raw(i46, descr=<FieldS dynamic 0>)
+ """)
+ assert loop.match_by_id('setfield', """
+ setfield_raw(i44, i57, descr=<FieldS dynamic 0>)
+ """)
+
+
+ def test__cffi_call(self):
+ from rpython.rlib.test.test_clibffi import get_libm_name
+ def main(libm_name):
+ try:
+ import _cffi_backend
+ except ImportError:
+ sys.stderr.write('SKIP: cannot import _cffi_backend\n')
+ return 0
+
+ libm = _cffi_backend.load_library(libm_name)
+ BDouble = _cffi_backend.new_primitive_type("double")
+ BPow = _cffi_backend.new_function_type([BDouble, BDouble], BDouble)
+ pow = libm.load_function(BPow, 'pow')
+ i = 0
+ res = 0
+ while i < 300:
+ tmp = pow(2, 3) # ID: cfficall
+ res += tmp
+ i += 1
+ BLong = _cffi_backend.new_primitive_type("long")
+ pow_addr = int(_cffi_backend.cast(BLong, pow))
+ return pow_addr, res
+ #
+ libm_name = get_libm_name(sys.platform)
+ log = self.run(main, [libm_name])
+ pow_addr, res = log.result
+ assert res == 8.0 * 300
+ loop, = log.loops_by_filename(self.filepath)
+ if 'ConstClass(pow)' in repr(loop): # e.g. OS/X
+ pow_addr = 'ConstClass(pow)'
+ assert loop.match_by_id('cfficall', """
+ ...
+ f1 = call_release_gil(..., descr=<Callf 8 ff EF=6 OS=62>)
+ ...
+ """)
+ # so far just check that call_release_gil() is produced.
+ # later, also check that the arguments to call_release_gil()
+ # are constants, and that the numerous raw_mallocs are removed
+
+ def test_cffi_call_guard_not_forced_fails(self):
+ # this is the test_pypy_c equivalent of
+ # rpython/jit/metainterp/test/test_fficall::test_guard_not_forced_fails
+ #
+ # it requires cffi to be installed for pypy in order to run
+ def main():
+ import sys
+ try:
+ import cffi
+ except ImportError:
+ sys.stderr.write('SKIP: cannot import cffi\n')
+ return 0
+
+ ffi = cffi.FFI()
+
+ ffi.cdef("""
+ typedef void (*functype)(int);
+ int foo(int n, functype func);
+ """)
+
+ lib = ffi.verify("""
+ #include <signal.h>
+ typedef void (*functype)(int);
+
+ int foo(int n, functype func) {
+ if (n >= 2000) {
+ func(n);
+ }
+ return n*2;
+ }
+ """)
+
+ @ffi.callback("functype")
+ def mycallback(n):
+ if n < 5000:
+ return
+ # make sure that guard_not_forced fails
+ d = {}
+ f = sys._getframe()
+ while f:
+ d.update(f.f_locals)
+ f = f.f_back
+
+ n = 0
+ while n < 10000:
+ res = lib.foo(n, mycallback) # ID: cfficall
+ # this is the real point of the test: before the
+ # refactor-call_release_gil branch, the assert failed when
+ # res == 5000
+ assert res == n*2
+ n += 1
+ return n
+
+ log = self.run(main, [], import_site=True)
+ assert log.result == 10000
+ loop, = log.loops_by_id('cfficall')
+ assert loop.match_by_id('cfficall', """
+ ...
+ f1 = call_release_gil(..., descr=<Calli 4 ii EF=6 OS=62>)
+ ...
+ """)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_ffi.py b/pypy/module/pypyjit/test_pypy_c/test_ffi.py
deleted file mode 100644
--- a/pypy/module/pypyjit/test_pypy_c/test_ffi.py
+++ /dev/null
@@ -1,279 +0,0 @@
-import sys, py
-from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC
-
-class Test__ffi(BaseTestPyPyC):
-
- def test__ffi_call(self):
- from rpython.rlib.test.test_clibffi import get_libm_name
- def main(libm_name):
- try:
- from _ffi import CDLL, types
- except ImportError:
- sys.stderr.write('SKIP: cannot import _ffi\n')
- return 0
-
- libm = CDLL(libm_name)
- pow = libm.getfunc('pow', [types.double, types.double],
- types.double)
- i = 0
- res = 0
- while i < 300:
- tmp = pow(2, 3) # ID: fficall
- res += tmp
- i += 1
- return pow.getaddr(), res
- #
- libm_name = get_libm_name(sys.platform)
- log = self.run(main, [libm_name])
- pow_addr, res = log.result
- assert res == 8.0 * 300
- py.test.xfail() # XXX re-optimize _ffi for the JIT?
- loop, = log.loops_by_filename(self.filepath)
- if 'ConstClass(pow)' in repr(loop): # e.g. OS/X
- pow_addr = 'ConstClass(pow)'
- assert loop.match_by_id('fficall', """
- guard_not_invalidated(descr=...)
- i17 = force_token()
- setfield_gc(p0, i17, descr=<.* .*PyFrame.vable_token .*>)
- f21 = call_release_gil(%s, 2.000000, 3.000000, descr=<Callf 8 ff EF=6>)
- guard_not_forced(descr=...)
- guard_no_exception(descr=...)
- """ % pow_addr)
-
-
- def test__ffi_call_frame_does_not_escape(self):
- from rpython.rlib.test.test_clibffi import get_libm_name
- def main(libm_name):
- try:
- from _ffi import CDLL, types
- except ImportError:
- sys.stderr.write('SKIP: cannot import _ffi\n')
- return 0
-
- libm = CDLL(libm_name)
- pow = libm.getfunc('pow', [types.double, types.double],
- types.double)
-
- def mypow(a, b):
- return pow(a, b)
-
- i = 0
- res = 0
- while i < 300:
- tmp = mypow(2, 3)
- res += tmp
- i += 1
- return pow.getaddr(), res
- #
- libm_name = get_libm_name(sys.platform)
- log = self.run(main, [libm_name])
- pow_addr, res = log.result
- assert res == 8.0 * 300
- loop, = log.loops_by_filename(self.filepath)
- opnames = log.opnames(loop.allops())
- # we only force the virtualref, not its content
- assert opnames.count('new_with_vtable') == 1
-
- def test__ffi_call_releases_gil(self):
- from rpython.rlib.clibffi import get_libc_name
- def main(libc_name, n):
- import time
- import os
- from threading import Thread
- #
- if os.name == 'nt':
- from _ffi import WinDLL, types
- libc = WinDLL('Kernel32.dll')
- sleep = libc.getfunc('Sleep', [types.uint], types.uint)
- delays = [0]*n + [1000]
- else:
- from _ffi import CDLL, types
- libc = CDLL(libc_name)
- sleep = libc.getfunc('sleep', [types.uint], types.uint)
- delays = [0]*n + [1]
- #
- def loop_of_sleeps(i, delays):
- for delay in delays:
- sleep(delay) # ID: sleep
- #
- threads = [Thread(target=loop_of_sleeps, args=[i, delays]) for i in range(5)]
- start = time.time()
- for i, thread in enumerate(threads):
- thread.start()
- for thread in threads:
- thread.join()
- end = time.time()
- return end - start
- log = self.run(main, [get_libc_name(), 200], threshold=150,
- import_site=True)
- assert 1 <= log.result <= 1.5 # at most 0.5 seconds of overhead
- loops = log.loops_by_id('sleep')
- assert len(loops) == 1 # make sure that we actually JITted the loop
-
- def test_ctypes_call(self):
- from rpython.rlib.test.test_clibffi import get_libm_name
- def main(libm_name):
- import ctypes
- libm = ctypes.CDLL(libm_name)
- fabs = libm.fabs
- fabs.argtypes = [ctypes.c_double]
- fabs.restype = ctypes.c_double
- x = -4
- i = 0
- while i < 300:
- x = fabs(x)
- x = x - 100
- i += 1
- return fabs._ptr.getaddr(), x
-
- libm_name = get_libm_name(sys.platform)
- log = self.run(main, [libm_name], import_site=True)
- fabs_addr, res = log.result
- assert res == -4.0
- loop, = log.loops_by_filename(self.filepath)
- ops = loop.allops()
- opnames = log.opnames(ops)
- assert opnames.count('new_with_vtable') == 1 # only the virtualref
- py.test.xfail() # XXX re-optimize _ffi for the JIT?
- assert opnames.count('call_release_gil') == 1
- idx = opnames.index('call_release_gil')
- call = ops[idx]
- assert (call.args[0] == 'ConstClass(fabs)' or # e.g. OS/X
- int(call.args[0]) == fabs_addr)
-
-
- def test__ffi_struct(self):
- def main():
- from _ffi import _StructDescr, Field, types
- fields = [
- Field('x', types.slong),
- ]
- descr = _StructDescr('foo', fields)
- struct = descr.allocate()
- i = 0
- while i < 300:
- x = struct.getfield('x') # ID: getfield
- x = x+1
- struct.setfield('x', x) # ID: setfield
- i += 1
- return struct.getfield('x')
- #
- log = self.run(main, [])
- py.test.xfail() # XXX re-optimize _ffi for the JIT?
- loop, = log.loops_by_filename(self.filepath)
- assert loop.match_by_id('getfield', """
- guard_not_invalidated(descr=...)
- i57 = getfield_raw(i46, descr=<FieldS dynamic 0>)
- """)
- assert loop.match_by_id('setfield', """
- setfield_raw(i44, i57, descr=<FieldS dynamic 0>)
- """)
-
-
- def test__cffi_call(self):
- from rpython.rlib.test.test_clibffi import get_libm_name
- def main(libm_name):
- try:
- import _cffi_backend
- except ImportError:
- sys.stderr.write('SKIP: cannot import _cffi_backend\n')
- return 0
-
- libm = _cffi_backend.load_library(libm_name)
- BDouble = _cffi_backend.new_primitive_type("double")
- BInt = _cffi_backend.new_primitive_type("int")
- BPow = _cffi_backend.new_function_type([BDouble, BInt], BDouble)
- ldexp = libm.load_function(BPow, 'ldexp')
- i = 0
- res = 0
- while i < 300:
- tmp = ldexp(1, 3) # ID: cfficall
- res += tmp
- i += 1
- BLong = _cffi_backend.new_primitive_type("long")
- ldexp_addr = int(_cffi_backend.cast(BLong, ldexp))
- return ldexp_addr, res
- #
- libm_name = get_libm_name(sys.platform)
- log = self.run(main, [libm_name])
- ldexp_addr, res = log.result
- assert res == 8.0 * 300
- loop, = log.loops_by_filename(self.filepath)
- if 'ConstClass(ldexp)' in repr(loop): # e.g. OS/X
- ldexp_addr = 'ConstClass(ldexp)'
- assert loop.match_by_id('cfficall', """
- ...
- f1 = call_release_gil(..., descr=<Callf 8 fi EF=6 OS=62>)
- ...
- """)
- ops = loop.ops_by_id('cfficall')
- assert 'raw_malloc' not in str(ops)
- assert 'raw_free' not in str(ops)
- assert 'getarrayitem_raw' not in log.opnames(ops)
- assert 'setarrayitem_raw' not in log.opnames(ops)
- # so far just check that call_release_gil() is produced.
- # later, also check that the arguments to call_release_gil()
- # are constants
- # are constants, and that the numerous raw_mallocs are removed
-
- def test_cffi_call_guard_not_forced_fails(self):
- # this is the test_pypy_c equivalent of
- # rpython/jit/metainterp/test/test_fficall::test_guard_not_forced_fails
- #
- # it requires cffi to be installed for pypy in order to run
- def main():
- import sys
- try:
- import cffi
- except ImportError:
- sys.stderr.write('SKIP: cannot import cffi\n')
- return 0
-
- ffi = cffi.FFI()
-
- ffi.cdef("""
- typedef void (*functype)(int);
- int foo(int n, functype func);
- """)
-
- lib = ffi.verify("""
- #include <signal.h>
- typedef void (*functype)(int);
-
- int foo(int n, functype func) {
- if (n >= 2000) {
- func(n);
- }
- return n*2;
- }
- """)
-
- @ffi.callback("functype")
- def mycallback(n):
- if n < 5000:
- return
- # make sure that guard_not_forced fails
- d = {}
- f = sys._getframe()
- while f:
- d.update(f.f_locals)
- f = f.f_back
-
- n = 0
- while n < 10000:
- res = lib.foo(n, mycallback) # ID: cfficall
- # this is the real point of the test: before the
- # refactor-call_release_gil branch, the assert failed when
- # res == 5000
- assert res == n*2
- n += 1
- return n
-
- log = self.run(main, [], import_site=True)
- assert log.result == 10000
- loop, = log.loops_by_id('cfficall')
- assert loop.match_by_id('cfficall', """
- ...
- f1 = call_release_gil(..., descr=<Calli 4 ii EF=6 OS=62>)
- ...
- """)
diff --git a/pypy/module/thread/os_thread.py b/pypy/module/thread/os_thread.py
--- a/pypy/module/thread/os_thread.py
+++ b/pypy/module/thread/os_thread.py
@@ -132,7 +132,7 @@
if not e.match(space, space.w_SystemExit):
ident = rthread.get_ident()
where = 'thread %d started by ' % ident
- e.write_unraisable(space, where, w_callable)
+ e.write_unraisable(space, where, w_callable, with_traceback=True)
e.clear(space)
# clean up space.threadlocals to remove the ExecutionContext
# entry corresponding to the current thread
diff --git a/pypy/module/thread/test/test_thread.py b/pypy/module/thread/test/test_thread.py
--- a/pypy/module/thread/test/test_thread.py
+++ b/pypy/module/thread/test/test_thread.py
@@ -129,10 +129,10 @@
sys.stderr = StringIO.StringIO()
thread.start_new_thread(fn3, ())
self.waitfor(lambda: "ValueError" in sys.stderr.getvalue())
- result = sys.stderr.getvalue()
- assert "ValueError" in result
- assert "hello world" in result
- assert len(result.splitlines()) == 1
+ result = sys.stderr.getvalue().splitlines()
+ #assert result[0].startswith("Unhandled exception in thread ")
+ assert result[1].startswith("Traceback ")
+ assert result[-1] == "ValueError: hello world"
finally:
sys.stderr = prev
diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -74,29 +74,6 @@
def setup_failure_recovery(self):
self.failure_recovery_code = [0, 0, 0, 0]
- @staticmethod
- def _release_gil_shadowstack():
- before = rffi.aroundstate.before
- if before:
- before()
-
- @staticmethod
- def _reacquire_gil_shadowstack():
- after = rffi.aroundstate.after
- if after:
- after()
-
- _NOARG_FUNC = lltype.Ptr(lltype.FuncType([], lltype.Void))
-
- def _build_release_gil(self, gcrootmap):
- assert gcrootmap.is_shadow_stack
- releasegil_func = llhelper(self._NOARG_FUNC,
- self._release_gil_shadowstack)
- reacqgil_func = llhelper(self._NOARG_FUNC,
- self._reacquire_gil_shadowstack)
- self.releasegil_addr = rffi.cast(lltype.Signed, releasegil_func)
- self.reacqgil_addr = rffi.cast(lltype.Signed, reacqgil_func)
-
def _build_propagate_exception_path(self):
if not self.cpu.propagate_exception_descr:
return # not supported (for tests, or non-translated)
@@ -537,7 +514,7 @@
clt.allgcrefs = []
clt.frame_info.clear() # for now
- if False and log:
+ if log:
operations = self._inject_debugging_code(looptoken, operations,
'e', looptoken.number)
diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -630,7 +630,9 @@
# argument the address of the structure we are writing into
# (the first argument to COND_CALL_GC_WB).
helper_num = card_marking
- if self._regalloc is not None and self._regalloc.vfprm.reg_bindings:
+ if is_frame:
+ helper_num = 4
+ elif self._regalloc is not None and self._regalloc.vfprm.reg_bindings:
helper_num += 2
if self.wb_slowpath[helper_num] == 0: # tests only
assert not we_are_translated()
@@ -1264,7 +1266,7 @@
resloc = arglocs[0]
if gcrootmap:
- self.call_release_gil(gcrootmap, arglocs, fcond)
+ self.call_release_gil(gcrootmap, arglocs, regalloc, fcond)
# do the call
self._store_force_index(guard_op)
#
@@ -1276,37 +1278,32 @@
resloc, (size, signed))
# then reopen the stack
if gcrootmap:
- self.call_reacquire_gil(gcrootmap, resloc, fcond)
+ self.call_reacquire_gil(gcrootmap, resloc, regalloc, fcond)
self._emit_guard_may_force(guard_op, arglocs[numargs+1:], numargs)
return fcond
- def call_release_gil(self, gcrootmap, save_registers, fcond):
- # First, we need to save away the registers listed in
- # 'save_registers' that are not callee-save.
+ def call_release_gil(self, gcrootmap, save_registers, regalloc, fcond):
+ # Save caller saved registers and do the call
# NOTE: We assume that the floating point registers won't be modified.
- regs_to_save = []
- for reg in self._regalloc.rm.save_around_call_regs:
- if reg in save_registers:
- regs_to_save.append(reg)
assert gcrootmap.is_shadow_stack
- with saved_registers(self.mc, regs_to_save):
+ with saved_registers(self.mc, regalloc.rm.save_around_call_regs):
self._emit_call(imm(self.releasegil_addr), [], fcond)
- def call_reacquire_gil(self, gcrootmap, save_loc, fcond):
- # save the previous result into the stack temporarily.
+ def call_reacquire_gil(self, gcrootmap, save_loc, regalloc, fcond):
+ # save the previous result into the stack temporarily, in case it is in
+ # a caller saved register.
# NOTE: like with call_release_gil(), we assume that we don't need to
# save vfp regs in this case. Besides the result location
regs_to_save = []
vfp_regs_to_save = []
- if save_loc.is_reg():
+ if save_loc and save_loc in regalloc.rm.save_around_call_regs:
regs_to_save.append(save_loc)
- if save_loc.is_vfp_reg():
+ regs_to_save.append(r.ip) # for alingment
+ elif save_loc and save_loc in regalloc.vfprm.save_around_call_regs:
vfp_regs_to_save.append(save_loc)
+ assert gcrootmap.is_shadow_stack
# call the reopenstack() function (also reacquiring the GIL)
- if len(regs_to_save) % 2 != 1:
- regs_to_save.append(r.ip) # for alingment
- assert gcrootmap.is_shadow_stack
with saved_registers(self.mc, regs_to_save, vfp_regs_to_save):
self._emit_call(imm(self.reacqgil_addr), [], fcond)
diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -554,10 +554,9 @@
return self._prepare_call(op)
def _prepare_call(self, op, force_store=[], save_all_regs=False):
- args = []
- args.append(None)
+ args = [None] * (op.numargs() + 1)
for i in range(op.numargs()):
- args.append(self.loc(op.getarg(i)))
+ args[i + 1] = self.loc(op.getarg(i))
# spill variables that need to be saved around calls
self.vfprm.before_call(save_all_regs=save_all_regs)
if not save_all_regs:
diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -484,15 +484,6 @@
else:
return self.bh_raw_load_i(struct, offset, descr)
- def unpack_arraydescr_size(self, arraydescr):
- from rpython.jit.backend.llsupport.symbolic import get_array_token
- from rpython.jit.backend.llsupport.descr import get_type_flag, FLAG_SIGNED
- assert isinstance(arraydescr, ArrayDescr)
- basesize, itemsize, _ = get_array_token(arraydescr.A, False)
- flag = get_type_flag(arraydescr.A.OF)
- is_signed = (flag == FLAG_SIGNED)
- return basesize, itemsize, is_signed
-
def bh_raw_store_i(self, struct, offset, newvalue, descr):
ll_p = rffi.cast(rffi.CCHARP, struct)
ll_p = rffi.cast(lltype.Ptr(descr.A), rffi.ptradd(ll_p, offset))
@@ -575,14 +566,10 @@
def bh_read_timestamp(self):
return read_timestamp()
- def bh_new_raw_buffer(self, size):
- return lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
-
def store_fail_descr(self, deadframe, descr):
pass # I *think*
-
class LLDeadFrame(object):
_TYPE = llmemory.GCREF
diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -9,7 +9,7 @@
debug_print)
from rpython.rlib.rarithmetic import r_uint
from rpython.rlib.objectmodel import specialize, compute_unique_id
-from rpython.rtyper.annlowlevel import cast_instance_to_gcref
+from rpython.rtyper.annlowlevel import cast_instance_to_gcref, llhelper
from rpython.rtyper.lltypesystem import rffi, lltype
@@ -282,6 +282,69 @@
debug_print(prefix + ':' + str(struct.i))
debug_stop('jit-backend-counts')
+ @staticmethod
+ @rgc.no_collect
+ def _release_gil_asmgcc(css):
+ # similar to trackgcroot.py:pypy_asm_stackwalk, first part
+ from rpython.memory.gctransform import asmgcroot
+ new = rffi.cast(asmgcroot.ASM_FRAMEDATA_HEAD_PTR, css)
+ next = asmgcroot.gcrootanchor.next
+ new.next = next
+ new.prev = asmgcroot.gcrootanchor
+ asmgcroot.gcrootanchor.next = new
+ next.prev = new
+ # and now release the GIL
+ before = rffi.aroundstate.before
+ if before:
+ before()
+
+ @staticmethod
+ @rgc.no_collect
+ def _reacquire_gil_asmgcc(css):
+ # first reacquire the GIL
+ after = rffi.aroundstate.after
+ if after:
+ after()
+ # similar to trackgcroot.py:pypy_asm_stackwalk, second part
+ from rpython.memory.gctransform import asmgcroot
+ old = rffi.cast(asmgcroot.ASM_FRAMEDATA_HEAD_PTR, css)
+ prev = old.prev
+ next = old.next
+ prev.next = next
+ next.prev = prev
+
+ @staticmethod
+ @rgc.no_collect
+ def _release_gil_shadowstack():
+ before = rffi.aroundstate.before
+ if before:
+ before()
+
+ @staticmethod
+ @rgc.no_collect
+ def _reacquire_gil_shadowstack():
+ after = rffi.aroundstate.after
+ if after:
+ after()
+
+ _NOARG_FUNC = lltype.Ptr(lltype.FuncType([], lltype.Void))
+ _CLOSESTACK_FUNC = lltype.Ptr(lltype.FuncType([rffi.LONGP],
+ lltype.Void))
+
+ def _build_release_gil(self, gcrootmap):
+ if gcrootmap.is_shadow_stack:
+ releasegil_func = llhelper(self._NOARG_FUNC,
+ self._release_gil_shadowstack)
+ reacqgil_func = llhelper(self._NOARG_FUNC,
+ self._reacquire_gil_shadowstack)
+ else:
+ releasegil_func = llhelper(self._CLOSESTACK_FUNC,
+ self._release_gil_asmgcc)
+ reacqgil_func = llhelper(self._CLOSESTACK_FUNC,
+ self._reacquire_gil_asmgcc)
+ self.releasegil_addr = self.cpu.cast_ptr_to_int(releasegil_func)
+ self.reacqgil_addr = self.cpu.cast_ptr_to_int(reacqgil_func)
+
def debug_bridge(descr_number, rawstart, codeendpos):
diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py
--- a/rpython/jit/backend/llsupport/llmodel.py
+++ b/rpython/jit/backend/llsupport/llmodel.py
@@ -742,9 +742,6 @@
as_array[self.vtable_offset/WORD] = vtable
return res
- def bh_new_raw_buffer(self, size):
- return lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
-
def bh_classof(self, struct):
struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct)
result_adr = llmemory.cast_ptr_to_adr(struct.typeptr)
diff --git a/rpython/jit/backend/llsupport/test/zrpy_gc_boehm_test.py b/rpython/jit/backend/llsupport/test/zrpy_gc_boehm_test.py
--- a/rpython/jit/backend/llsupport/test/zrpy_gc_boehm_test.py
+++ b/rpython/jit/backend/llsupport/test/zrpy_gc_boehm_test.py
@@ -2,7 +2,6 @@
import weakref
from rpython.rlib.jit import JitDriver, dont_look_inside
from rpython.jit.backend.llsupport.test.zrpy_gc_test import run, get_entry, compile
-from rpython.jit.backend.llsupport.test.ztranslation_test import fix_annotator_for_vrawbuffer
class X(object):
def __init__(self, x=0):
@@ -32,8 +31,7 @@
g._dont_inline_ = True
return g
-def compile_boehm_test(monkeypatch):
- fix_annotator_for_vrawbuffer(monkeypatch)
+def compile_boehm_test():
myjitdriver = JitDriver(greens = [], reds = ['n', 'x'])
@dont_look_inside
def see(lst, n):
diff --git a/rpython/jit/backend/llsupport/test/ztranslation_test.py b/rpython/jit/backend/llsupport/test/ztranslation_test.py
--- a/rpython/jit/backend/llsupport/test/ztranslation_test.py
+++ b/rpython/jit/backend/llsupport/test/ztranslation_test.py
@@ -9,23 +9,10 @@
from rpython.jit.codewriter.policy import StopAtXPolicy
-def fix_annotator_for_vrawbuffer(monkeypatch):
- from rpython.rlib.nonconst import NonConstant
- from rpython.jit.metainterp.optimizeopt.virtualize import VRawBufferValue
- from rpython.jit.metainterp import warmspot
-
- def my_hook_for_tests(cpu):
- # this is needed so that the annotator can see it
- if NonConstant(False):
- v = VRawBufferValue(cpu, None, -1, None, None)
- monkeypatch.setattr(warmspot, 'hook_for_tests', my_hook_for_tests)
-
-
class TranslationTest(CCompiledMixin):
CPUClass = getcpuclass()
- def test_stuff_translates(self, monkeypatch):
- fix_annotator_for_vrawbuffer(monkeypatch)
+ def test_stuff_translates(self):
# this is a basic test that tries to hit a number of features and their
# translation:
# - jitting of loops and bridges
@@ -102,10 +89,9 @@
class TranslationTestCallAssembler(CCompiledMixin):
CPUClass = getcpuclass()
- def test_direct_assembler_call_translates(self, monkeypatch):
+ def test_direct_assembler_call_translates(self):
"""Test CALL_ASSEMBLER and the recursion limit"""
from rpython.rlib.rstackovf import StackOverflow
- fix_annotator_for_vrawbuffer(monkeypatch)
class Thing(object):
def __init__(self, val):
@@ -183,8 +169,7 @@
class TranslationTestJITStats(CCompiledMixin):
CPUClass = getcpuclass()
- def test_jit_get_stats(self, monkeypatch):
- fix_annotator_for_vrawbuffer(monkeypatch)
+ def test_jit_get_stats(self):
driver = JitDriver(greens = [], reds = ['i'])
def f():
@@ -207,8 +192,7 @@
class TranslationRemoveTypePtrTest(CCompiledMixin):
CPUClass = getcpuclass()
- def test_external_exception_handling_translates(self, monkeypatch):
- fix_annotator_for_vrawbuffer(monkeypatch)
+ def test_external_exception_handling_translates(self):
jitdriver = JitDriver(greens = [], reds = ['n', 'total'])
class ImDone(Exception):
diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py
--- a/rpython/jit/backend/model.py
+++ b/rpython/jit/backend/model.py
@@ -194,18 +194,11 @@
def typedescrof(self, TYPE):
raise NotImplementedError
- def unpack_arraydescr_size(self, arraydescr):
- """
- Return basesize, itemsize, is_signed
- """
- raise NotImplementedError
-
@staticmethod
def cast_int_to_ptr(x, TYPE):
x = llmemory.cast_int_to_adr(x)
return llmemory.cast_adr_to_ptr(x, TYPE)
-
# ---------- the backend-dependent operations ----------
# lltype specific operations
@@ -242,8 +235,6 @@
raise NotImplementedError
def bh_newunicode(self, length):
raise NotImplementedError
- def bh_new_raw_buffer(self, size):
- raise NotImplementedError
def bh_arraylen_gc(self, array, arraydescr):
raise NotImplementedError
diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -367,69 +367,6 @@
else:
self.wb_slowpath[withcards + 2 * withfloats] = rawstart
- @staticmethod
- @rgc.no_collect
- def _release_gil_asmgcc(css):
- # similar to trackgcroot.py:pypy_asm_stackwalk, first part
- from rpython.memory.gctransform import asmgcroot
- new = rffi.cast(asmgcroot.ASM_FRAMEDATA_HEAD_PTR, css)
- next = asmgcroot.gcrootanchor.next
- new.next = next
- new.prev = asmgcroot.gcrootanchor
- asmgcroot.gcrootanchor.next = new
- next.prev = new
- # and now release the GIL
- before = rffi.aroundstate.before
- if before:
- before()
-
- @staticmethod
- @rgc.no_collect
- def _reacquire_gil_asmgcc(css):
- # first reacquire the GIL
- after = rffi.aroundstate.after
- if after:
- after()
- # similar to trackgcroot.py:pypy_asm_stackwalk, second part
- from rpython.memory.gctransform import asmgcroot
- old = rffi.cast(asmgcroot.ASM_FRAMEDATA_HEAD_PTR, css)
- prev = old.prev
- next = old.next
- prev.next = next
- next.prev = prev
-
- @staticmethod
- @rgc.no_collect
- def _release_gil_shadowstack():
- before = rffi.aroundstate.before
- if before:
- before()
-
- @staticmethod
- @rgc.no_collect
- def _reacquire_gil_shadowstack():
- after = rffi.aroundstate.after
- if after:
- after()
-
- _NOARG_FUNC = lltype.Ptr(lltype.FuncType([], lltype.Void))
- _CLOSESTACK_FUNC = lltype.Ptr(lltype.FuncType([rffi.LONGP],
- lltype.Void))
-
- def _build_release_gil(self, gcrootmap):
- if gcrootmap.is_shadow_stack:
- releasegil_func = llhelper(self._NOARG_FUNC,
- self._release_gil_shadowstack)
- reacqgil_func = llhelper(self._NOARG_FUNC,
- self._reacquire_gil_shadowstack)
- else:
- releasegil_func = llhelper(self._CLOSESTACK_FUNC,
- self._release_gil_asmgcc)
- reacqgil_func = llhelper(self._CLOSESTACK_FUNC,
- self._reacquire_gil_asmgcc)
- self.releasegil_addr = self.cpu.cast_ptr_to_int(releasegil_func)
- self.reacqgil_addr = self.cpu.cast_ptr_to_int(reacqgil_func)
-
def assemble_loop(self, loopname, inputargs, operations, looptoken, log):
'''adds the following attributes to looptoken:
_ll_function_addr (address of the generated func, as an int)
diff --git a/rpython/jit/codewriter/effectinfo.py b/rpython/jit/codewriter/effectinfo.py
--- a/rpython/jit/codewriter/effectinfo.py
+++ b/rpython/jit/codewriter/effectinfo.py
@@ -76,14 +76,14 @@
#
OS_MATH_SQRT = 100
#
- OS_RAW_MALLOC_VARSIZE_CHAR = 110
+ OS_RAW_MALLOC_VARSIZE = 110
OS_RAW_FREE = 111
OS_JIT_FORCE_VIRTUAL = 120
# for debugging:
_OS_CANRAISE = set([OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL,
- OS_RAW_MALLOC_VARSIZE_CHAR, OS_JIT_FORCE_VIRTUAL])
+ OS_RAW_MALLOC_VARSIZE, OS_JIT_FORCE_VIRTUAL])
def __new__(cls, readonly_descrs_fields, readonly_descrs_arrays,
write_descrs_fields, write_descrs_arrays,
diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -539,11 +539,9 @@
name += '_no_track_allocation'
op1 = self.prepare_builtin_call(op, name, args, (TYPE,), TYPE)
if name == 'raw_malloc_varsize':
- ITEMTYPE = op.args[0].value.OF
- if ITEMTYPE == lltype.Char:
- return self._handle_oopspec_call(op1, args,
- EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR,
- EffectInfo.EF_CAN_RAISE)
+ return self._handle_oopspec_call(op1, args,
+ EffectInfo.OS_RAW_MALLOC_VARSIZE,
+ EffectInfo.EF_CAN_RAISE)
return self.rewrite_op_direct_call(op1)
def rewrite_op_malloc_varsize(self, op):
diff --git a/rpython/jit/codewriter/test/test_jtransform.py b/rpython/jit/codewriter/test/test_jtransform.py
--- a/rpython/jit/codewriter/test/test_jtransform.py
+++ b/rpython/jit/codewriter/test/test_jtransform.py
@@ -126,7 +126,7 @@
INT = lltype.Signed
UNICHAR = lltype.UniChar
FLOAT = lltype.Float
- ARRAYPTR = rffi.CArrayPtr(lltype.Char)
+ ARRAYPTR = rffi.CArrayPtr(lltype.Signed)
argtypes = {
EI.OS_MATH_SQRT: ([FLOAT], FLOAT),
EI.OS_STR2UNICODE:([PSTR], PUNICODE),
@@ -143,7 +143,7 @@
EI.OS_UNIEQ_NONNULL_CHAR: ([PUNICODE, UNICHAR], INT),
EI.OS_UNIEQ_CHECKNULL_CHAR: ([PUNICODE, UNICHAR], INT),
EI.OS_UNIEQ_LENGTHOK: ([PUNICODE, PUNICODE], INT),
- EI.OS_RAW_MALLOC_VARSIZE_CHAR: ([INT], ARRAYPTR),
+ EI.OS_RAW_MALLOC_VARSIZE: ([INT], ARRAYPTR),
EI.OS_RAW_FREE: ([ARRAYPTR], lltype.Void),
}
argtypes = argtypes[oopspecindex]
@@ -151,7 +151,7 @@
assert argtypes[1] == op.result.concretetype
if oopspecindex == EI.OS_STR2UNICODE:
assert extraeffect == EI.EF_ELIDABLE_CAN_RAISE
- elif oopspecindex == EI.OS_RAW_MALLOC_VARSIZE_CHAR:
+ elif oopspecindex == EI.OS_RAW_MALLOC_VARSIZE:
assert extraeffect == EI.EF_CAN_RAISE
elif oopspecindex == EI.OS_RAW_FREE:
assert extraeffect == EI.EF_CANNOT_RAISE
@@ -161,7 +161,7 @@
def calldescr_canraise(self, calldescr):
EI = effectinfo.EffectInfo
- if calldescr == 'calldescr-%d' % EI.OS_RAW_MALLOC_VARSIZE_CHAR:
+ if calldescr == 'calldescr-%d' % EI.OS_RAW_MALLOC_VARSIZE:
return True
return False
@@ -555,7 +555,7 @@
assert op1.args == []
def test_raw_malloc():
- S = rffi.CArray(lltype.Char)
+ S = rffi.CArray(lltype.Signed)
v1 = varoftype(lltype.Signed)
v = varoftype(lltype.Ptr(S))
flags = Constant({'flavor': 'raw'}, lltype.Void)
@@ -566,7 +566,7 @@
assert op0.opname == 'residual_call_ir_i'
assert op0.args[0].value == 'raw_malloc_varsize' # pseudo-function as a str
assert (op0.args[-1] == 'calldescr-%d' %
- effectinfo.EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR)
+ effectinfo.EffectInfo.OS_RAW_MALLOC_VARSIZE)
assert op1.opname == '-live-'
assert op1.args == []
@@ -608,7 +608,7 @@
assert op1.args == []
def test_raw_free():
- S = rffi.CArray(lltype.Char)
+ S = rffi.CArray(lltype.Signed)
flags = Constant({'flavor': 'raw', 'track_allocation': True},
lltype.Void)
op = SpaceOperation('free', [varoftype(lltype.Ptr(S)), flags],
diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -15,7 +15,7 @@
from rpython.jit.metainterp import history, resume
from rpython.jit.metainterp.optimize import InvalidLoop
from rpython.jit.metainterp.inliner import Inliner
-from rpython.jit.metainterp.resume import NUMBERING, PENDINGFIELDSP, ResumeDataDirectReader
+from rpython.jit.metainterp.resume import NUMBERING, PENDINGFIELDSP
from rpython.jit.codewriter import heaptracker, longlong
def giveup():
@@ -656,9 +656,9 @@
class AllVirtuals:
llopaque = True
- cache = None
- def __init__(self, cache):
- self.cache = cache
+ list = [resume.ResumeDataDirectReader.virtual_default] # annotation hack
+ def __init__(self, list):
+ self.list = list
def hide(self, cpu):
ptr = cpu.ts.cast_instance_to_base_ref(self)
return cpu.ts.cast_to_ref(ptr)
@@ -682,9 +682,9 @@
from rpython.jit.metainterp.blackhole import resume_in_blackhole
hidden_all_virtuals = metainterp_sd.cpu.get_savedata_ref(deadframe)
obj = AllVirtuals.show(metainterp_sd.cpu, hidden_all_virtuals)
- all_virtuals = obj.cache
+ all_virtuals = obj.list
if all_virtuals is None:
- all_virtuals = ResumeDataDirectReader.VirtualCache([], [])
+ all_virtuals = []
assert jitdriver_sd is self.jitdriver_sd
resume_in_blackhole(metainterp_sd, jitdriver_sd, self, deadframe,
all_virtuals)
diff --git a/rpython/jit/metainterp/history.py b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -191,6 +191,7 @@
def get_jitcode_for_class(self, oocls):
return self.jitcodes[oocls]
+
class Const(AbstractValue):
__slots__ = ()
diff --git a/rpython/jit/metainterp/optimizeopt/earlyforce.py b/rpython/jit/metainterp/optimizeopt/earlyforce.py
--- a/rpython/jit/metainterp/optimizeopt/earlyforce.py
+++ b/rpython/jit/metainterp/optimizeopt/earlyforce.py
@@ -1,26 +1,15 @@
-from rpython.jit.codewriter.effectinfo import EffectInfo
from rpython.jit.metainterp.optimizeopt.optimizer import Optimization
from rpython.jit.metainterp.optimizeopt.vstring import VAbstractStringValue
from rpython.jit.metainterp.resoperation import rop, ResOperation
-def is_raw_free(op, opnum):
- if opnum != rop.CALL:
- return False
- einfo = op.getdescr().get_extra_info()
- return einfo.oopspecindex == EffectInfo.OS_RAW_FREE
-
-
class OptEarlyForce(Optimization):
def propagate_forward(self, op):
opnum = op.getopnum()
-
if (opnum != rop.SETFIELD_GC and
opnum != rop.SETARRAYITEM_GC and
- opnum != rop.SETARRAYITEM_RAW and
opnum != rop.QUASIIMMUT_FIELD and
opnum != rop.SAME_AS and
- opnum != rop.MARK_OPAQUE_PTR and
- not is_raw_free(op, opnum)):
+ opnum != rop.MARK_OPAQUE_PTR):
for arg in op.getarglist():
if arg in self.optimizer.values:
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -231,12 +231,6 @@
def setitem(self, index, value):
raise NotImplementedError
- def getitem_raw(self, offset, length, descr):
- raise NotImplementedError
-
- def setitem_raw(self, offset, length, descr, value):
- raise NotImplementedError
-
def getinteriorfield(self, index, ofs, default):
raise NotImplementedError
diff --git a/rpython/jit/metainterp/optimizeopt/rawbuffer.py b/rpython/jit/metainterp/optimizeopt/rawbuffer.py
deleted file mode 100644
--- a/rpython/jit/metainterp/optimizeopt/rawbuffer.py
+++ /dev/null
@@ -1,134 +0,0 @@
-from rpython.rlib.debug import debug_start, debug_stop, debug_print
-from rpython.rlib.objectmodel import compute_unique_id, we_are_translated
-
-class InvalidRawOperation(Exception):
- pass
-
-class InvalidRawWrite(InvalidRawOperation):
- pass
-
-class InvalidRawRead(InvalidRawOperation):
- pass
-
-class RawBuffer(object):
- def __init__(self, cpu, logops=None):
- # the following lists represents the writes in the buffer: values[i]
- # is the value of length lengths[i] stored at offset[i].
- #
- # the invariant is that they are ordered by offset, and that
- # offset[i]+length[i] <= offset[i+1], i.e. that the writes never
- # overlaps
- self.cpu = cpu
- self.logops = logops
- self.offsets = []
- self.lengths = []
- self.descrs = []
- self.values = []
-
- def _get_memory(self):
- """
- NOT_RPYTHON
- for testing only
- """
- return zip(self.offsets, self.lengths, self.descrs, self.values)
-
- def _repr_of_descr(self, descr):
- if self.logops:
- s = self.logops.repr_of_descr(descr)
- else:
- s = str(descr)
- s += " at %d" % compute_unique_id(descr)
- return s
-
- def _repr_of_value(self, value):
- if not we_are_translated() and isinstance(value, str):
- return value # for tests
- if self.logops:
- s = self.logops.repr_of_arg(value.box)
- else:
- s = str(value.box)
- s += " at %d" % compute_unique_id(value.box)
- return s
-
- def _dump_to_log(self):
- debug_print("RawBuffer state")
- debug_print("offset, length, descr, box")
- debug_print("(box == None means that the value is still virtual)")
- for i in range(len(self.offsets)):
- descr = self._repr_of_descr(self.descrs[i])
- box = self._repr_of_value(self.values[i])
- debug_print("%d, %d, %s, %s" % (self.offsets[i], self.lengths[i], descr, box))
-
- def _invalid_write(self, message, offset, length, descr, value):
- debug_start('jit-log-rawbuffer')
- debug_print('Invalid write: %s' % message)
- debug_print(" offset: %d" % offset)
- debug_print(" length: %d" % length)
- debug_print(" descr: %s" % self._repr_of_descr(descr))
- debug_print(" value: %s" % self._repr_of_value(value))
- self._dump_to_log()
- debug_stop('jit-log-rawbuffer')
- raise InvalidRawWrite
-
- def _invalid_read(self, message, offset, length, descr):
- debug_start('jit-log-rawbuffer')
- debug_print('Invalid read: %s' % message)
- debug_print(" offset: %d" % offset)
- debug_print(" length: %d" % length)
- debug_print(" descr: %s" % self._repr_of_descr(descr))
- self._dump_to_log()
- debug_stop('jit-log-rawbuffer')
- raise InvalidRawRead
-
- def _descrs_are_compatible(self, d1, d2):
- # two arraydescrs are compatible if they have the same basesize,
- # itemsize and sign, even if they are not identical
- unpack = self.cpu.unpack_arraydescr_size
- return unpack(d1) == unpack(d2)
-
- def write_value(self, offset, length, descr, value):
- i = 0
- N = len(self.offsets)
- while i < N:
- if self.offsets[i] == offset:
- if (length != self.lengths[i] or not
- self._descrs_are_compatible(descr, self.descrs[i])):
- # in theory we could add support for the cases in which
- # the length or descr is different, but I don't think we
- # need it in practice
- self._invalid_write('length or descr not compatible',
- offset, length, descr, value)
- # update the value at this offset
- self.values[i] = value
- return
- elif self.offsets[i] > offset:
- break
- i += 1
- #
- if i < len(self.offsets) and offset+length > self.offsets[i]:
- self._invalid_write("overlap with next bytes",
- offset, length, descr, value)
- if i > 0 and self.offsets[i-1]+self.lengths[i-1] > offset:
- self._invalid_write("overlap with previous bytes",
- offset, length, descr, value)
- # insert a new value at offset
- self.offsets.insert(i, offset)
- self.lengths.insert(i, length)
- self.descrs.insert(i, descr)
- self.values.insert(i, value)
-
- def read_value(self, offset, length, descr):
- i = 0
- N = len(self.offsets)
- while i < N:
- if self.offsets[i] == offset:
- if (length != self.lengths[i] or
- not self._descrs_are_compatible(descr, self.descrs[i])):
- self._invalid_read('length or descr not compatible',
- offset, length, descr)
- return self.values[i]
- i += 1
- # memory location not found: this means we are reading from
- # uninitialized memory, give up the optimization
- self._invalid_read('uninitialized memory',
- offset, length, descr)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -770,6 +770,8 @@
"""
self.optimize_loop(ops, expected)
+
+
def test_p123_simple(self):
ops = """
[i1, p2, p3]
@@ -1728,175 +1730,6 @@
# We cannot track virtuals that survive for more than two iterations.
self.optimize_loop(ops, expected, preamble)
- def test_virtual_raw_malloc(self):
- ops = """
- [i1]
- i2 = call('malloc', 10, descr=raw_malloc_descr)
- setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
- i3 = getarrayitem_raw(i2, 0, descr=rawarraydescr)
- call('free', i2, descr=raw_free_descr)
- jump(i3)
- """
- expected = """
- [i1]
- jump(i1)
- """
- self.optimize_loop(ops, expected)
-
- def test_virtual_raw_malloc_force(self):
- ops = """
- [i1]
- i2 = call('malloc', 10, descr=raw_malloc_descr)
- setarrayitem_raw(i2, 0, i1, descr=rawarraydescr_char)
- setarrayitem_raw(i2, 2, 456, descr=rawarraydescr_char)
- setarrayitem_raw(i2, 1, 123, descr=rawarraydescr_char)
- label('foo') # we expect the buffer to be forced *after* the label
- escape(i2)
- call('free', i2, descr=raw_free_descr)
- jump(i1)
- """
- expected = """
- [i1]
- label('foo')
- i2 = call('malloc', 10, descr=raw_malloc_descr)
- setarrayitem_raw(i2, 0, i1, descr=rawarraydescr_char)
- i3 = int_add(i2, 1)
- setarrayitem_raw(i3, 0, 123, descr=rawarraydescr_char)
- i4 = int_add(i2, 2)
- setarrayitem_raw(i4, 0, 456, descr=rawarraydescr_char)
- escape(i2)
- call('free', i2, descr=raw_free_descr)
- jump(i1)
- """
- self.optimize_loop(ops, expected)
-
- def test_virtual_raw_malloc_invalid_write_force(self):
- ops = """
- [i1]
- i2 = call('malloc', 10, descr=raw_malloc_descr)
- setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
- label('foo') # we expect the buffer to be forced *after* the label
- setarrayitem_raw(i2, 2, 456, descr=rawarraydescr_char) # overlap!
- call('free', i2, descr=raw_free_descr)
- jump(i1)
- """
- expected = """
- [i1]
- label('foo')
- i2 = call('malloc', 10, descr=raw_malloc_descr)
- setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
- setarrayitem_raw(i2, 2, 456, descr=rawarraydescr_char)
- call('free', i2, descr=raw_free_descr)
- jump(i1)
- """
- self.optimize_loop(ops, expected)
-
- def test_virtual_raw_malloc_invalid_read_force(self):
- ops = """
- [i1]
- i2 = call('malloc', 10, descr=raw_malloc_descr)
- setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
- label('foo') # we expect the buffer to be forced *after* the label
- i3 = getarrayitem_raw(i2, 0, descr=rawarraydescr_char)
- call('free', i2, descr=raw_free_descr)
- jump(i1)
- """
- expected = """
- [i1]
- label('foo')
- i2 = call('malloc', 10, descr=raw_malloc_descr)
- setarrayitem_raw(i2, 0, i1, descr=rawarraydescr)
- i3 = getarrayitem_raw(i2, 0, descr=rawarraydescr_char)
- call('free', i2, descr=raw_free_descr)
- jump(i1)
- """
- self.optimize_loop(ops, expected)
-
- def test_virtual_raw_slice(self):
- ops = """
- [i0, i1]
- i2 = call('malloc', 10, descr=raw_malloc_descr)
- setarrayitem_raw(i2, 0, 42, descr=rawarraydescr_char)
- i3 = int_add(i2, 1) # get a slice of the original buffer
- setarrayitem_raw(i3, 0, 4242, descr=rawarraydescr) # write to the slice
- i4 = getarrayitem_raw(i2, 0, descr=rawarraydescr_char)
- i5 = int_add(i2, 1)
- i6 = getarrayitem_raw(i5, 0, descr=rawarraydescr)
- call('free', i2, descr=raw_free_descr)
- jump(i0, i1)
- """
- expected = """
- [i0, i1]
- jump(i0, i1)
- """
- self.optimize_loop(ops, expected)
-
- def test_virtual_raw_slice_of_a_raw_slice(self):
- ops = """
- [i0, i1]
- i2 = call('malloc', 10, descr=raw_malloc_descr)
- i3 = int_add(i2, 1) # get a slice of the original buffer
- i4 = int_add(i3, 1) # get a slice of a slice
- setarrayitem_raw(i4, 0, i1, descr=rawarraydescr_char) # write to the slice
- i5 = getarrayitem_raw(i2, 2, descr=rawarraydescr_char)
- call('free', i2, descr=raw_free_descr)
- jump(i0, i5)
- """
- expected = """
- [i0, i1]
- jump(i0, i1)
- """
- self.optimize_loop(ops, expected)
-
- def test_virtual_raw_slice_force(self):
- ops = """
- [i0, i1]
- i2 = call('malloc', 10, descr=raw_malloc_descr)
- setarrayitem_raw(i2, 0, 42, descr=rawarraydescr_char)
- i3 = int_add(i2, 1) # get a slice of the original buffer
- setarrayitem_raw(i3, 4, 4242, descr=rawarraydescr_char) # write to the slice
- label('foo')
- escape(i3)
- jump(i0, i1)
- """
- expected = """
- [i0, i1]
- label('foo')
- # these ops are generated by VirtualRawBufferValue._really_force
- i2 = call('malloc', 10, descr=raw_malloc_descr)
- setarrayitem_raw(i2, 0, 42, descr=rawarraydescr_char)
- i3 = int_add(i2, 5) # 1+4*sizeof(char)
- setarrayitem_raw(i3, 0, 4242, descr=rawarraydescr_char)
- # this is generated by VirtualRawSliceValue._really_force
- i4 = int_add(i2, 1)
- escape(i4)
- jump(i0, i1)
- """
- self.optimize_loop(ops, expected)
-
- def test_virtual_raw_malloc_virtualstate(self):
- ops = """
- [i0]
- i1 = getarrayitem_raw(i0, 0, descr=rawarraydescr)
- i2 = int_add(i1, 1)
- call('free', i0, descr=raw_free_descr)
- i3 = call('malloc', 10, descr=raw_malloc_descr)
- setarrayitem_raw(i3, 0, i2, descr=rawarraydescr)
- label('foo')
- jump(i3)
- """
- expected = """
- [i0]
- i1 = getarrayitem_raw(i0, 0, descr=rawarraydescr)
- i2 = int_add(i1, 1)
- call('free', i0, descr=raw_free_descr)
- label('foo')
- i3 = call('malloc', 10, descr=raw_malloc_descr)
- setarrayitem_raw(i3, 0, i2, descr=rawarraydescr)
- jump(i3)
- """
- self.optimize_loop(ops, expected)
-
def test_duplicate_getfield_1(self):
ops = """
[p1, p2]
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_rawbuffer.py b/rpython/jit/metainterp/optimizeopt/test/test_rawbuffer.py
deleted file mode 100644
--- a/rpython/jit/metainterp/optimizeopt/test/test_rawbuffer.py
+++ /dev/null
@@ -1,90 +0,0 @@
-import py
-from rpython.jit.metainterp.optimizeopt.rawbuffer import (InvalidRawWrite,
- InvalidRawRead, RawBuffer)
-
-class FakeCPU(object):
- def unpack_arraydescr_size(self, descr):
- return descr, 'foo', 'bar'
-
-def test_write_value():
- buf = RawBuffer(FakeCPU())
- buf.write_value(8, 4, 'descr3', 'three')
- buf.write_value(0, 4, 'descr1', 'one')
- buf.write_value(4, 2, 'descr2', 'two')
- buf.write_value(12, 2, 'descr4', 'four')
- assert buf._get_memory() == [
- ( 0, 4, 'descr1', 'one'),
- ( 4, 2, 'descr2', 'two'),
- ( 8, 4, 'descr3', 'three'),
- (12, 2, 'descr4', 'four'),
- ]
- #
-
-def test_write_value_update():
- buf = RawBuffer(FakeCPU())
- buf.write_value(0, 4, 'descr', 'one')
- buf.write_value(4, 2, 'descr', 'two')
- buf.write_value(0, 4, 'descr', 'ONE')
- assert buf._get_memory() == [
- ( 0, 4, 'descr', 'ONE'),
- ( 4, 2, 'descr', 'two'),
- ]
-
-def test_write_value_invalid_length():
- buf = RawBuffer(FakeCPU())
- buf.write_value(0, 4, 'descr1', 'one')
- with py.test.raises(InvalidRawWrite):
- buf.write_value(0, 5, 'descr1', 'two')
- with py.test.raises(InvalidRawWrite):
- buf.write_value(0, 4, 'descr2', 'two')
-
-
-def test_write_value_overlapping_next():
- buf = RawBuffer(FakeCPU())
- buf.write_value(0, 4, 'descr', 'one')
- buf.write_value(6, 4, 'descr', 'two')
- with py.test.raises(InvalidRawWrite):
- buf.write_value(4, 4, 'descr', 'three')
-
-def test_write_value_overlapping_prev():
- buf = RawBuffer(FakeCPU())
- buf.write_value(0, 4, 'descr', 'one')
- with py.test.raises(InvalidRawWrite):
- buf.write_value(2, 1, 'descr', 'two')
-
-def test_read_value():
- buf = RawBuffer(FakeCPU())
- buf.write_value(0, 4, 'descr', 'one')
- buf.write_value(4, 4, 'descr', 'two')
- assert buf.read_value(0, 4, 'descr') == 'one'
- assert buf.read_value(4, 4, 'descr') == 'two'
- with py.test.raises(InvalidRawRead):
- buf.read_value(0, 2, 'descr')
- with py.test.raises(InvalidRawRead):
- buf.read_value(8, 2, 'descr')
- with py.test.raises(InvalidRawRead):
- buf.read_value(0, 4, 'another descr')
-
-def test_unpack_descrs():
- ArrayS_8_1 = object()
- ArrayS_8_2 = object()
- ArrayU_8 = object()
-
- class FakeCPU(object):
- def unpack_arraydescr_size(self, descr):
- if descr in (ArrayS_8_1, ArrayS_8_2):
- return 0, 8, True
- return 0, 8, False
-
- buf = RawBuffer(FakeCPU())
- buf.write_value(0, 4, ArrayS_8_1, 'one')
- assert buf.read_value(0, 4, ArrayS_8_1) == 'one'
- assert buf.read_value(0, 4, ArrayS_8_2) == 'one' # with a non-identical descr
- #
- buf.write_value(0, 4, ArrayS_8_2, 'two') # with a non-identical descr
- assert buf.read_value(0, 4, ArrayS_8_1) == 'two'
- #
- with py.test.raises(InvalidRawRead):
- buf.read_value(0, 4, ArrayU_8)
- with py.test.raises(InvalidRawWrite):
- buf.write_value(0, 4, ArrayU_8, 'three')
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -196,15 +196,6 @@
EffectInfo.EF_CANNOT_RAISE,
oopspecindex=EffectInfo.OS_ARRAYCOPY))
- raw_malloc_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([], [], [], [],
- EffectInfo.EF_CAN_RAISE,
- oopspecindex=EffectInfo.OS_RAW_MALLOC_VARSIZE_CHAR))
- raw_free_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
- EffectInfo([], [], [], [],
- EffectInfo.EF_CANNOT_RAISE,
- oopspecindex=EffectInfo.OS_RAW_FREE))
-
# array of structs (complex data)
complexarray = lltype.GcArray(
@@ -217,12 +208,6 @@
complexrealdescr = cpu.interiorfielddescrof(complexarray, "real")
compleximagdescr = cpu.interiorfielddescrof(complexarray, "imag")
- rawarraydescr = cpu.arraydescrof(lltype.Array(lltype.Signed,
- hints={'nolength': True}))
- rawarraydescr_char = cpu.arraydescrof(lltype.Array(lltype.Char,
- hints={'nolength': True}))
-
-
for _name, _os in [
('strconcatdescr', 'OS_STR_CONCAT'),
('strslicedescr', 'OS_STR_SLICE'),
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -6,9 +6,7 @@
from rpython.jit.metainterp.optimizeopt import optimizer
from rpython.jit.metainterp.optimizeopt.optimizer import OptValue, REMOVED
from rpython.jit.metainterp.optimizeopt.util import (make_dispatcher_method,
- descrlist_dict, sort_descrs)
-
-from rpython.jit.metainterp.optimizeopt.rawbuffer import RawBuffer, InvalidRawOperation
+ descrlist_dict, sort_descrs)
from rpython.jit.metainterp.resoperation import rop, ResOperation
from rpython.rlib.objectmodel import we_are_translated
@@ -238,36 +236,8 @@
def _get_descr(self):
return self.structdescr
-class AbstractVArrayValue(AbstractVirtualValue):
- """
- Base class for VArrayValue (for normal GC arrays) and VRawBufferValue (for
- malloc()ed memory)
- """
- def getlength(self):
- return len(self._items)
-
- def get_item_value(self, i):
- raise NotImplementedError
-
- def set_item_value(self, i, newval):
- raise NotImplementedError
-
- def get_args_for_fail(self, modifier):
- if self.box is None and not modifier.already_seen_virtual(self.keybox):
- # checks for recursion: it is False unless
- # we have already seen the very same keybox
- itemboxes = []
- for i in range(self.getlength()):
- itemvalue = self.get_item_value(i)
- itemboxes.append(itemvalue.get_key_box())
- modifier.register_virtual_fields(self.keybox, itemboxes)
- for i in range(self.getlength()):
- itemvalue = self.get_item_value(i)
- itemvalue.get_args_for_fail(modifier)
-
-
-class VArrayValue(AbstractVArrayValue):
+class VArrayValue(AbstractVirtualValue):
def __init__(self, arraydescr, constvalue, size, keybox, source_op=None):
AbstractVirtualValue.__init__(self, keybox, source_op)
@@ -278,12 +248,6 @@
def getlength(self):
return len(self._items)
- def get_item_value(self, i):
- return self._items[i]
-
- def set_item_value(self, i, newval):
- self._items[i] = newval
-
def getitem(self, index):
res = self._items[index]
return res
@@ -293,16 +257,11 @@
self._items[index] = itemvalue
def force_at_end_of_preamble(self, already_forced, optforce):
- # note that this method is on VArrayValue instead of
- # AbstractVArrayValue because we do not want to support virtualstate
- # for rawbuffers for now
if self in already_forced:
return self
already_forced[self] = self
- for index in range(self.getlength()):
- itemval = self.get_item_value(index)
- itemval = itemval.force_at_end_of_preamble(already_forced, optforce)
- self.set_item_value(index, itemval)
+ for index in range(len(self._items)):
+ self._items[index] = self._items[index].force_at_end_of_preamble(already_forced, optforce)
return self
def _really_force(self, optforce):
@@ -322,16 +281,29 @@
descr=self.arraydescr)
optforce.emit_operation(op)
+ def get_args_for_fail(self, modifier):
+ if self.box is None and not modifier.already_seen_virtual(self.keybox):
+ # checks for recursion: it is False unless
+ # we have already seen the very same keybox
+ itemboxes = []
+ for itemvalue in self._items:
+ itemboxes.append(itemvalue.get_key_box())
+ modifier.register_virtual_fields(self.keybox, itemboxes)
+ for itemvalue in self._items:
+ itemvalue.get_args_for_fail(modifier)
+
def _make_virtual(self, modifier):
return modifier.make_varray(self.arraydescr)
-
class VArrayStructValue(AbstractVirtualValue):
def __init__(self, arraydescr, size, keybox, source_op=None):
AbstractVirtualValue.__init__(self, keybox, source_op)
self.arraydescr = arraydescr
self._items = [{} for _ in xrange(size)]
+ def getlength(self):
+ return len(self._items)
+
def getinteriorfield(self, index, ofs, default):
return self._items[index].get(ofs, default)
@@ -391,90 +363,6 @@
return modifier.make_varraystruct(self.arraydescr, self._get_list_of_descrs())
-class VRawBufferValue(AbstractVArrayValue):
-
- def __init__(self, cpu, logops, size, keybox, source_op):
- AbstractVirtualValue.__init__(self, keybox, source_op)
- # note that size is unused, because we assume that the buffer is big
- # enough to write/read everything we need. If it's not, it's undefined
- # behavior anyway, although in theory we could probably detect such
- # cases here
- self.size = size
- self.buffer = RawBuffer(cpu, logops)
-
- def getlength(self):
- return len(self.buffer.values)
-
- def get_item_value(self, i):
- return self.buffer.values[i]
-
- def set_item_value(self, i, newval):
- self.buffer.values[i] = newval
-
More information about the pypy-commit
mailing list