From pypy.commits at gmail.com Mon Jul 1 05:56:20 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 01 Jul 2019 02:56:20 -0700 (PDT) Subject: [pypy-commit] pypy default: Bah, the printed message was bogus because "name" is redefined in the outer loop Message-ID: <5d19d8c4.1c69fb81.b343d.521b@mx.google.com> Author: Armin Rigo Branch: Changeset: r96887:886d3fec1ad3 Date: 2019-07-01 11:53 +0200 http://bitbucket.org/pypy/pypy/changeset/886d3fec1ad3/ Log: Bah, the printed message was bogus because "name" is redefined in the outer loop diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py --- a/pypy/module/cpyext/slotdefs.py +++ b/pypy/module/cpyext/slotdefs.py @@ -861,8 +861,7 @@ return 0 return buff_w -missing_wrappers = ['wrap_indexargfunc', 'wrap_delslice', 'wrap_coercefunc'] -for name in missing_wrappers: +def _make_missing_wrapper(name): assert name not in globals() class missing_wrapper(W_PyCWrapperObject): def call(self, space, w_self, __args__): @@ -871,6 +870,10 @@ missing_wrapper.__name__ = name globals()[name] = missing_wrapper +missing_wrappers = ['wrap_indexargfunc', 'wrap_delslice', 'wrap_coercefunc'] +for name in missing_wrappers: + _make_missing_wrapper(name) + def make_missing_slot(space, typedef, name, attr): return None From pypy.commits at gmail.com Mon Jul 1 06:47:04 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 01 Jul 2019 03:47:04 -0700 (PDT) Subject: [pypy-commit] pypy.org extradoc: Comment that this string-concatenation example does not apply on bytearrays. Message-ID: <5d19e4a8.1c69fb81.3d1f9.e712@mx.google.com> Author: Armin Rigo Branch: extradoc Changeset: r951:9fc40ec9dd54 Date: 2019-07-01 12:46 +0200 http://bitbucket.org/pypy/pypy.org/changeset/9fc40ec9dd54/ Log: Comment that this string-concatenation example does not apply on bytearrays. diff --git a/source/performance.txt b/source/performance.txt --- a/source/performance.txt +++ b/source/performance.txt @@ -226,7 +226,9 @@ the JIT cannot optimize out intermediate copies. This code is actually quadratic in the total size of the mylist strings due to -repeated string copies of ever-larger prefix segments. +repeated string copies of ever-larger prefix segments. (Such code +is always fine for bytearrays, because in this case ``+=`` is an +in-place operation.) This:: From pypy.commits at gmail.com Mon Jul 1 07:53:53 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 01 Jul 2019 04:53:53 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: hg merge e53c20a6841a (step-by-step merging with default) Message-ID: <5d19f451.1c69fb81.eec67.2c3d@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96888:822484ada2e3 Date: 2019-07-01 13:19 +0200 http://bitbucket.org/pypy/pypy/changeset/822484ada2e3/ Log: hg merge e53c20a6841a (step-by-step merging with default) From pypy.commits at gmail.com Mon Jul 1 07:53:55 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 01 Jul 2019 04:53:55 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: hg merge bc7aeb4d5987 (step-by-step merging with default) Message-ID: <5d19f453.1c69fb81.56433.8abd@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96889:ebf82d863e50 Date: 2019-07-01 13:21 +0200 http://bitbucket.org/pypy/pypy/changeset/ebf82d863e50/ Log: hg merge bc7aeb4d5987 (step-by-step merging with default) diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py b/extra_tests/cffi_tests/cffi1/test_recompiler.py --- a/extra_tests/cffi_tests/cffi1/test_recompiler.py +++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py @@ -2360,3 +2360,56 @@ assert q[0].a == p.a assert q[0].b == p.b assert q == p + +def test_unnamed_bitfield_1(): + ffi = FFI() + ffi.cdef("""struct A { char : 1; };""") + lib = verify(ffi, "test_unnamed_bitfield_1", """ + struct A { char : 1; }; + """) + p = ffi.new("struct A *") + assert ffi.sizeof(p[0]) == 1 + # Note: on gcc, the type name is ignored for anonymous bitfields + # and that's why the result is 1. On MSVC, the result is + # sizeof("char") which is also 1. + +def test_unnamed_bitfield_2(): + ffi = FFI() + ffi.cdef("""struct A { + short c : 1; short : 1; short d : 1; short : 1; };""") + lib = verify(ffi, "test_unnamed_bitfield_2", """ + struct A { + short c : 1; short : 1; short d : 1; short : 1; + }; + """) + p = ffi.new("struct A *") + assert ffi.sizeof(p[0]) == ffi.sizeof("short") + +def test_unnamed_bitfield_3(): + ffi = FFI() + ffi.cdef("""struct A { struct { char : 1; char : 1; } b; };""") + lib = verify(ffi, "test_unnamed_bitfield_3", """ + struct A { struct { char : 1; char : 1; } b; }; + """) + p = ffi.new("struct A *") + assert ffi.sizeof(p[0]) == 1 + # Note: on gcc, the type name is ignored for anonymous bitfields + # and that's why the result is 1. On MSVC, the result is + # sizeof("char") which is also 1. + +def test_unnamed_bitfield_4(): + ffi = FFI() + ffi.cdef("""struct A { struct { + unsigned c : 1; unsigned : 1; unsigned d : 1; unsigned : 1; } a; + }; + struct B { struct A a; };""") + lib = verify(ffi, "test_unnamed_bitfield_4", """ + struct A { struct { + unsigned c : 1; unsigned : 1; unsigned d : 1; unsigned : 1; } a; + }; + struct B { struct A a; }; + """) + b = ffi.new("struct B *") + a = ffi.new("struct A *") + assert ffi.sizeof(a[0]) == ffi.sizeof("unsigned") + assert ffi.sizeof(b[0]) == ffi.sizeof(a[0]) diff --git a/lib_pypy/cffi/recompiler.py b/lib_pypy/cffi/recompiler.py --- a/lib_pypy/cffi/recompiler.py +++ b/lib_pypy/cffi/recompiler.py @@ -855,8 +855,9 @@ try: if ftype.is_integer_type() or fbitsize >= 0: # accept all integers, but complain on float or double - prnt(" (void)((p->%s) | 0); /* check that '%s.%s' is " - "an integer */" % (fname, cname, fname)) + if fname != '': + prnt(" (void)((p->%s) | 0); /* check that '%s.%s' is " + "an integer */" % (fname, cname, fname)) continue # only accept exactly the type declared, except that '[]' # is interpreted as a '*' and so will match any array length. diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py --- a/pypy/module/_cffi_backend/newtype.py +++ b/pypy/module/_cffi_backend/newtype.py @@ -549,10 +549,11 @@ if sflags & SF_GCC_BIG_ENDIAN: bitshift = 8 * ftype.size - fbitsize- bitshift - fld = ctypestruct.W_CField(ftype, field_offset_bytes, - bitshift, fbitsize, fflags) - fields_list.append(fld) - fields_dict[fname] = fld + if fname != '': + fld = ctypestruct.W_CField(ftype, field_offset_bytes, + bitshift, fbitsize, fflags) + fields_list.append(fld) + fields_dict[fname] = fld if boffset > boffsetmax: boffsetmax = boffset diff --git a/rpython/rlib/_rsocket_rffi.py b/rpython/rlib/_rsocket_rffi.py --- a/rpython/rlib/_rsocket_rffi.py +++ b/rpython/rlib/_rsocket_rffi.py @@ -1426,10 +1426,10 @@ return rwin32.FormatError(errno) def socket_strerror_unicode(errno): - return rwin32.FormatErrorW(errno)[0] + return rwin32.FormatErrorW(errno)[0].decode('utf-8') def gai_strerror_unicode(errno): - return rwin32.FormatErrorW(errno)[0] + return rwin32.FormatErrorW(errno)[0].decode('utf-8') def socket_strerror_utf8(errno): return rwin32.FormatErrorW(errno) diff --git a/rpython/rlib/rvmprof/src/shared/vmp_stack.c b/rpython/rlib/rvmprof/src/shared/vmp_stack.c --- a/rpython/rlib/rvmprof/src/shared/vmp_stack.c +++ b/rpython/rlib/rvmprof/src/shared/vmp_stack.c @@ -82,12 +82,6 @@ static PY_STACK_FRAME_T * _write_python_stack_entry(PY_STACK_FRAME_T * frame, void ** result, int * depth, int max_depth) { - int len; - int addr; - int j; - uint64_t line; - char *lnotab; - #ifndef RPYTHON_VMPROF // pypy does not support line profiling if (vmp_profiles_python_lines()) { // In the line profiling mode we save a line number for every frame. @@ -99,27 +93,8 @@ // NOTE: the profiling overhead can be reduced by storing co_lnotab in the dump and // moving this computation to the reader instead of doing it here. - lnotab = PyStr_AS_STRING(frame->f_code->co_lnotab); - - if (lnotab != NULL) { - line = (uint64_t)frame->f_lineno; - addr = 0; - - len = (int)PyStr_GET_SIZE(frame->f_code->co_lnotab); - - for (j = 0; j < len; j += 2) { - addr += lnotab[j]; - if (addr > frame->f_lasti) { - break; - } - line += lnotab[j+1]; - } - result[*depth] = (void*) line; - *depth = *depth + 1; - } else { - result[*depth] = (void*) 0; - *depth = *depth + 1; - } + result[*depth] = (void*) (int64_t) PyFrame_GetLineNumber(frame); + *depth = *depth + 1; } result[*depth] = (void*)CODE_ADDR_TO_UID(FRAME_CODE(frame)); *depth = *depth + 1; diff --git a/rpython/rlib/rvmprof/test/test_file.py b/rpython/rlib/rvmprof/test/test_file.py --- a/rpython/rlib/rvmprof/test/test_file.py +++ b/rpython/rlib/rvmprof/test/test_file.py @@ -37,7 +37,7 @@ # if no_matches: print - print 'The following file dit NOT match' + print 'The following file did NOT match' for f in no_matches: print ' ', f.relto(RVMPROF) raise AssertionError("some files were updated on github, " From pypy.commits at gmail.com Mon Jul 1 07:53:56 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 01 Jul 2019 04:53:56 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: hg merge 53fb62020937 (step-by-step merging with default) Message-ID: <5d19f454.1c69fb81.70399.47de@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96890:f98216915c7a Date: 2019-07-01 13:23 +0200 http://bitbucket.org/pypy/pypy/changeset/f98216915c7a/ Log: hg merge 53fb62020937 (step-by-step merging with default) diff --git a/pypy/module/thread/test/test_local.py b/pypy/module/thread/test/test_local.py --- a/pypy/module/thread/test/test_local.py +++ b/pypy/module/thread/test/test_local.py @@ -5,6 +5,7 @@ def test_local_1(self): import _thread + import gc from _thread import _local as tlsobject freed = [] class X: @@ -34,8 +35,9 @@ _thread.start_new_thread(f, (i,)) self.waitfor(lambda: len(ok) == 20, delay=3) assert ok == 20*[True] # see stdout/stderr for failures in the threads + gc.collect(); gc.collect(); gc.collect() - self.waitfor(lambda: len(freed) >= 40) + self.waitfor(lambda: len(freed) >= 40, delay=20) assert len(freed) == 40 # in theory, all X objects should have been freed by now. Note that # Python's own thread._local objects suffer from the very same "bug" that From pypy.commits at gmail.com Mon Jul 1 07:53:58 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 01 Jul 2019 04:53:58 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: hg merge cde3d214c398 (step-by-step merging with default) Message-ID: <5d19f456.1c69fb81.2fb38.ec2d@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96891:79401e424fd4 Date: 2019-07-01 13:29 +0200 http://bitbucket.org/pypy/pypy/changeset/79401e424fd4/ Log: hg merge cde3d214c398 (step-by-step merging with default) I guess that unicodeobject.py's changes to unicode_to_decimal_w() can be ignored for the merge. 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 @@ -835,8 +835,9 @@ assert 0 def emit_op_load_effective_address(self, op, arglocs, regalloc, fcond): - self._gen_address(arglocs[4], arglocs[0], arglocs[1], arglocs[3].value, - arglocs[2].value) + static_ofs = op.getarg(2).getint() + scale = op.getarg(3).getint() + self._gen_address(arglocs[2], arglocs[0], arglocs[1], scale, static_ofs) return fcond # result = base_loc + (scaled_loc << scale) + static_offset 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 @@ -902,7 +902,7 @@ arg0 = self.make_sure_var_in_reg(args[0], args) arg1 = self.make_sure_var_in_reg(args[1], args) res = self.force_allocate_reg(op) - return [arg0, arg1, args[2], args[3], res] + return [arg0, arg1, res] def prepare_op_call_malloc_nursery(self, op, fcond): size_box = op.getarg(0) From pypy.commits at gmail.com Mon Jul 1 07:54:00 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 01 Jul 2019 04:54:00 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: hg merge 6d85d83cc17b (step-by-step merging with default) Message-ID: <5d19f458.1c69fb81.91e3d.1e44@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96892:09a00ce0b2e9 Date: 2019-07-01 13:30 +0200 http://bitbucket.org/pypy/pypy/changeset/09a00ce0b2e9/ Log: hg merge 6d85d83cc17b (step-by-step merging with default) diff --git a/lib-python/3/ctypes/test/test_loading.py b/lib-python/3/ctypes/test/test_loading.py --- a/lib-python/3/ctypes/test/test_loading.py +++ b/lib-python/3/ctypes/test/test_loading.py @@ -4,7 +4,6 @@ import unittest import test.support from ctypes.util import find_library -from ctypes.test import xfail libc_name = None @@ -82,7 +81,6 @@ self.assertRaises(AttributeError, dll.__getitem__, 1234) @unittest.skipUnless(os.name == "nt", 'Windows-specific test') - @xfail def test_1703286_A(self): from _ctypes import LoadLibrary, FreeLibrary # On winXP 64-bit, advapi32 loads at an address that does @@ -94,7 +92,6 @@ FreeLibrary(handle) @unittest.skipUnless(os.name == "nt", 'Windows-specific test') - @xfail def test_1703286_B(self): # Since on winXP 64-bit advapi32 loads like described # above, the (arbitrarily selected) CloseEventLog function diff --git a/rpython/rlib/rvmprof/src/shared/vmp_stack.c b/rpython/rlib/rvmprof/src/shared/vmp_stack.c --- a/rpython/rlib/rvmprof/src/shared/vmp_stack.c +++ b/rpython/rlib/rvmprof/src/shared/vmp_stack.c @@ -280,7 +280,7 @@ // this is possible because compiler align to 8 bytes. // if (func_addr != 0x0) { - depth = _write_native_stack((void*)(((uint64_t)func_addr) | 0x1), result, depth, max_depth); + depth = _write_native_stack((void*)(((intptr_t)func_addr) | 0x1), result, depth, max_depth); } } diff --git a/rpython/rlib/rvmprof/test/test_file.py b/rpython/rlib/rvmprof/test/test_file.py --- a/rpython/rlib/rvmprof/test/test_file.py +++ b/rpython/rlib/rvmprof/test/test_file.py @@ -11,10 +11,11 @@ def get_list_of_files(shared): files = list(shared.visit('*.[ch]')) # in PyPy we checkin the result of ./configure; as such, these files are - # not in github and can be skipped + # not in github or different and can be skipped files.remove(shared.join('libbacktrace', 'config-x86_32.h')) files.remove(shared.join('libbacktrace', 'config-x86_64.h')) files.remove(shared.join('libbacktrace', 'gstdint.h')) + files.remove(shared.join('libbacktrace', 'config.h')) return files def test_same_file(): From pypy.commits at gmail.com Mon Jul 1 07:54:01 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 01 Jul 2019 04:54:01 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: hg merge cc5fc1bad809 (step-by-step merging with default) Message-ID: <5d19f459.1c69fb81.8bb8a.44f5@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96893:a2bc01dcf303 Date: 2019-07-01 13:39 +0200 http://bitbucket.org/pypy/pypy/changeset/a2bc01dcf303/ Log: hg merge cc5fc1bad809 (step-by-step merging with default) diff --git a/pypy/module/cpyext/test/array.c b/pypy/module/cpyext/test/array.c --- a/pypy/module/cpyext/test/array.c +++ b/pypy/module/cpyext/test/array.c @@ -3017,6 +3017,11 @@ Py_RETURN_NONE; } +static PyObject * +passthrough(PyObject *self, PyObject* args) { + Py_INCREF(args); + return args; +} /*********************** Install Module **************************/ static PyMethodDef a_methods[] = { @@ -3030,6 +3035,7 @@ {"same_dealloc", (PyCFunction)same_dealloc, METH_VARARGS, NULL}, {"getitem", (PyCFunction)getitem, METH_VARARGS, NULL}, {"subclass_with_attribute", (PyCFunction)subclass_with_attribute, METH_VARARGS, NULL}, + {"passthrough", (PyCFunction)passthrough, METH_O, NULL}, {NULL, NULL, 0, NULL} /* Sentinel */ }; diff --git a/pypy/module/cpyext/test/test_arraymodule.py b/pypy/module/cpyext/test/test_arraymodule.py --- a/pypy/module/cpyext/test/test_arraymodule.py +++ b/pypy/module/cpyext/test/test_arraymodule.py @@ -67,6 +67,9 @@ else: expected = b'\x01\0\0\0\x02\0\0\0\x03\0\0\0\x04\0\0\0' assert bytes(buf) == expected + # make sure memory_attach is called + buf2 = module.passthrough(buf) + assert str(buf2) == str(buf) def test_releasebuffer(self): module = self.import_module(name='array') From pypy.commits at gmail.com Mon Jul 1 07:54:03 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 01 Jul 2019 04:54:03 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: hg merge 9831511d5e3e (step-by-step merging with default) Message-ID: <5d19f45b.1c69fb81.a95d2.ff51@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96894:58a21b8e9445 Date: 2019-07-01 13:41 +0200 http://bitbucket.org/pypy/pypy/changeset/58a21b8e9445/ Log: hg merge 9831511d5e3e (step-by-step merging with default) diff --git a/pypy/interpreter/pyparser/pyparse.py b/pypy/interpreter/pyparser/pyparse.py --- a/pypy/interpreter/pyparser/pyparse.py +++ b/pypy/interpreter/pyparser/pyparse.py @@ -121,7 +121,7 @@ # If an encoding is explicitly given check that it is utf-8. decl_enc = _check_for_encoding(bytessrc) explicit_encoding = (decl_enc is not None) - if decl_enc and decl_enc != "utf-8": + if decl_enc and _normalize_encoding(decl_enc) != "utf-8": raise error.SyntaxError("UTF-8 BOM with %s coding cookie" % decl_enc, filename=compile_info.filename) textsrc = bytessrc diff --git a/pypy/interpreter/pyparser/test/test_pyparse.py b/pypy/interpreter/pyparser/test/test_pyparse.py --- a/pypy/interpreter/pyparser/test/test_pyparse.py +++ b/pypy/interpreter/pyparser/test/test_pyparse.py @@ -57,6 +57,8 @@ input = "\xEF\xBB\xBF# coding: latin-1\nx" exc = py.test.raises(SyntaxError, self.parse, input).value assert exc.msg == "UTF-8 BOM with latin-1 coding cookie" + input = "\xEF\xBB\xBF# coding: UtF-8-yadda-YADDA\nx" + self.parse(input) # this does not raise input = "# coding: not-here" exc = py.test.raises(SyntaxError, self.parse, input).value assert exc.msg == "Unknown encoding: not-here" From pypy.commits at gmail.com Mon Jul 1 07:54:05 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 01 Jul 2019 04:54:05 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: hg merge 886d3fec1ad3 (step-by-step merging with default) Message-ID: <5d19f45d.1c69fb81.7f033.79f9@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96895:8ea11eeeb117 Date: 2019-07-01 13:44 +0200 http://bitbucket.org/pypy/pypy/changeset/8ea11eeeb117/ Log: hg merge 886d3fec1ad3 (step-by-step merging with default) diff --git a/pypy/module/cpyext/slotdefs.py b/pypy/module/cpyext/slotdefs.py --- a/pypy/module/cpyext/slotdefs.py +++ b/pypy/module/cpyext/slotdefs.py @@ -833,8 +833,7 @@ return slot_tp_descr_set -missing_wrappers = ['wrap_indexargfunc', 'wrap_del'] -for name in missing_wrappers: +def _make_missing_wrapper(name): assert name not in globals() class missing_wrapper(W_PyCWrapperObject): def call(self, space, w_self, __args__): @@ -843,6 +842,10 @@ missing_wrapper.__name__ = name globals()[name] = missing_wrapper +missing_wrappers = ['wrap_indexargfunc', 'wrap_del'] +for name in missing_wrappers: + _make_missing_wrapper(name) + def make_missing_slot(space, typedef, name, attr): return None 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 @@ -532,22 +532,26 @@ def gen_shadowstack_header(self, gcrootmap): # lr = shadow stack top addr - # ip = *lr + # r4 = *lr rst = gcrootmap.get_root_stack_top_addr() self.mc.gen_load_int(r.lr.value, rst) - self.load_reg(self.mc, r.ip, r.lr) - # *ip = r.fp - self.store_reg(self.mc, r.fp, r.ip) + self.load_reg(self.mc, r.r4, r.lr) + # *r4 = 1 + # the '1' is to benefit from the shadowstack 'is_minor' optimization + self.mc.gen_load_int(r.ip.value, 1) + self.store_reg(self.mc, r.ip, r.r4) + # *(r4+WORD) = r.fp + self.store_reg(self.mc, r.fp, r.r4, WORD) # - self.mc.ADD_ri(r.ip.value, r.ip.value, WORD) - # *lr = ip + WORD - self.store_reg(self.mc, r.ip, r.lr) + self.mc.ADD_ri(r.r4.value, r.r4.value, 2 * WORD) + # *lr = r4 + 2 * WORD + self.store_reg(self.mc, r.r4, r.lr) def gen_footer_shadowstack(self, gcrootmap, mc): rst = gcrootmap.get_root_stack_top_addr() mc.gen_load_int(r.ip.value, rst) self.load_reg(mc, r.r4, r.ip) - mc.SUB_ri(r.r4.value, r.r4.value, WORD) + mc.SUB_ri(r.r4.value, r.r4.value, 2 * WORD) self.store_reg(mc, r.r4, r.ip) def _dump(self, ops, type='loop'): From pypy.commits at gmail.com Mon Jul 1 08:38:53 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 01 Jul 2019 05:38:53 -0700 (PDT) Subject: [pypy-commit] pypy default: Speed up 'bytearray += bytes' and other similar combinations Message-ID: <5d19fedd.1c69fb81.5e3c6.7b02@mx.google.com> Author: Armin Rigo Branch: Changeset: r96896:4dbe00e72d76 Date: 2019-07-01 14:26 +0200 http://bitbucket.org/pypy/pypy/changeset/4dbe00e72d76/ Log: Speed up 'bytearray += bytes' and other similar combinations diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -109,6 +109,8 @@ @staticmethod def _op_val(space, w_other, strict=None): # bytearray does not enforce the strict restriction (on strip at least) + if isinstance(w_other, W_BytesObject): + return w_other.str_w(space) return space.buffer_w(w_other, space.BUF_SIMPLE).as_str() def _chr(self, char): @@ -333,7 +335,7 @@ other_len = len(other) cmp = _memcmp(value, other, min(len(value), len(other))) elif isinstance(w_other, W_BytesObject): - other = self._op_val(space, w_other) + other = w_other.str_w(space) other_len = len(other) cmp = _memcmp(value, other, min(len(value), len(other))) else: @@ -380,18 +382,9 @@ self._data += w_other.getdata() return self - if isinstance(w_other, W_BytesObject): - self._inplace_add(self._op_val(space, w_other)) - else: - self._inplace_add(_get_buffer(space, w_other)) + self._data += self._op_val(space, w_other) return self - @specialize.argtype(1) - def _inplace_add(self, other): - resizelist_hint(self._data, len(self._data) + len(other)) - for i in range(len(other)): - self._data.append(other[i]) - def descr_inplace_mul(self, space, w_times): try: times = space.getindex_w(w_times, space.w_OverflowError) @@ -452,8 +445,10 @@ def descr_extend(self, space, w_other): if isinstance(w_other, W_BytearrayObject): self._data += w_other.getdata() + elif isinstance(w_other, W_BytesObject): # performance only + self._data += w_other.str_w(space) else: - self._inplace_add(makebytearraydata_w(space, w_other)) + self._data += makebytearraydata_w(space, w_other) def descr_insert(self, space, w_idx, w_other): where = space.int_w(w_idx) @@ -492,20 +487,13 @@ if isinstance(w_other, W_BytearrayObject): return self._new(self.getdata() + w_other.getdata()) - if isinstance(w_other, W_BytesObject): - return self._add(self._op_val(space, w_other)) - try: - buffer = _get_buffer(space, w_other) + byte_string = self._op_val(space, w_other) except OperationError as e: if e.match(space, space.w_TypeError): return space.w_NotImplemented raise - return self._add(buffer) - - @specialize.argtype(1) - def _add(self, other): - return self._new(self.getdata() + [other[i] for i in range(len(other))]) + return self._new(self.getdata() + list(byte_string)) def descr_reverse(self, space): self.getdata().reverse() diff --git a/pypy/objspace/std/test/test_bytearrayobject.py b/pypy/objspace/std/test/test_bytearrayobject.py --- a/pypy/objspace/std/test/test_bytearrayobject.py +++ b/pypy/objspace/std/test/test_bytearrayobject.py @@ -380,11 +380,19 @@ assert b == bytearray('obe') def test_iadd(self): - b = bytearray('abc') + b = b0 = bytearray('abc') b += 'def' assert b == 'abcdef' - assert isinstance(b, bytearray) + assert b is b0 raises(TypeError, b.__iadd__, u"") + # + b += bytearray('XX') + assert b == 'abcdefXX' + assert b is b0 + # + b += memoryview('ABC') + assert b == 'abcdefXXABC' + assert b is b0 def test_add(self): b1 = bytearray("abc") @@ -448,6 +456,10 @@ raises(TypeError, b.extend, [object()]) raises(TypeError, b.extend, u"unicode") + b = bytearray('abc') + b.extend(memoryview('def')) + assert b == bytearray('abcdef') + def test_extend_calls_len_or_lengthhint(self): class BadLen(object): def __iter__(self): return iter(range(10)) diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -4665,6 +4665,17 @@ a = self.RPythonAnnotator() assert a.build_types(h, [int]).const == 456 + def test_list_plus_equal_string(self): + def f(n): + lst = [chr(n), chr(n + 1)] + if n < 100: + lst.append(chr(n + 2)) + lst += str(n) + return lst + a = self.RPythonAnnotator() + s = a.build_types(f, [int]) + assert isinstance(listitem(s), annmodel.SomeChar) + def g(n): return [0, 1, 2, n] diff --git a/rpython/rtyper/test/test_rstr.py b/rpython/rtyper/test/test_rstr.py --- a/rpython/rtyper/test/test_rstr.py +++ b/rpython/rtyper/test/test_rstr.py @@ -1059,7 +1059,7 @@ l = [const('a'), const('b')] else: l = [const('a')] - l += y + l += y # list += string return const('').join(l) assert self.ll_to_string(self.interpret(f, [1, From pypy.commits at gmail.com Mon Jul 1 08:38:55 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 01 Jul 2019 05:38:55 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: hg merge default Message-ID: <5d19fedf.1c69fb81.7b460.e743@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96897:4effc72e379f Date: 2019-07-01 14:38 +0200 http://bitbucket.org/pypy/pypy/changeset/4effc72e379f/ Log: hg merge default diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py --- a/pypy/objspace/std/bytearrayobject.py +++ b/pypy/objspace/std/bytearrayobject.py @@ -316,7 +316,7 @@ other_len = len(other) cmp = _memcmp(value, other, min(len(value), len(other))) elif isinstance(w_other, W_BytesObject): - other = self._op_val(space, w_other) + other = w_other.bytes_w(space) other_len = len(other) cmp = _memcmp(value, other, min(len(value), len(other))) else: @@ -360,18 +360,9 @@ self._data += w_other.getdata() return self - if isinstance(w_other, W_BytesObject): - self._inplace_add(self._op_val(space, w_other)) - else: - self._inplace_add(space.readbuf_w(w_other)) + self._data += self._op_val(space, w_other) return self - @specialize.argtype(1) - def _inplace_add(self, other): - resizelist_hint(self._data, len(self._data) + len(other)) - for i in range(len(other)): - self._data.append(other[i]) - def descr_inplace_mul(self, space, w_times): try: times = space.getindex_w(w_times, space.w_OverflowError) @@ -430,8 +421,10 @@ def descr_extend(self, space, w_other): if isinstance(w_other, W_BytearrayObject): self._data += w_other.getdata() + elif isinstance(w_other, W_BytesObject): # performance only + self._data += w_other.bytes_w(space) else: - self._inplace_add(makebytesdata_w(space, w_other)) + self._data += makebytesdata_w(space, w_other) def descr_insert(self, space, w_idx, w_other): where = space.int_w(w_idx) @@ -462,20 +455,13 @@ if isinstance(w_other, W_BytearrayObject): return self._new(self.getdata() + w_other.getdata()) - if isinstance(w_other, W_BytesObject): - return self._add(self._op_val(space, w_other)) - try: - buffer = space.readbuf_w(w_other) + byte_string = self._op_val(space, w_other) except OperationError as e: if e.match(space, space.w_TypeError): return space.w_NotImplemented raise - return self._add(buffer) - - @specialize.argtype(1) - def _add(self, other): - return self._new(self.getdata() + [other[i] for i in range(len(other))]) + return self._new(self.getdata() + list(byte_string)) def descr_reverse(self, space): self.getdata().reverse() diff --git a/pypy/objspace/std/test/test_bytearrayobject.py b/pypy/objspace/std/test/test_bytearrayobject.py --- a/pypy/objspace/std/test/test_bytearrayobject.py +++ b/pypy/objspace/std/test/test_bytearrayobject.py @@ -398,11 +398,19 @@ assert b == bytearray(b'obe') def test_iadd(self): - b = bytearray(b'abc') + b = b0 = bytearray(b'abc') b += b'def' assert b == b'abcdef' - assert isinstance(b, bytearray) + assert b is b0 raises(TypeError, b.__iadd__, "") + # + b += bytearray(b'XX') + assert b == b'abcdefXX' + assert b is b0 + # + b += memoryview(b'ABC') + assert b == b'abcdefXXABC' + assert b is b0 def test_add(self): b1 = bytearray(b"abc") @@ -471,6 +479,10 @@ raises(TypeError, b.extend, [object()]) raises(TypeError, b.extend, "unicode") + b = bytearray(b'abc') + b.extend(memoryview(b'def')) + assert b == bytearray(b'abcdef') + def test_extend_calls_len_or_lengthhint(self): class BadLen(object): def __iter__(self): return iter(range(10)) diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -4665,6 +4665,17 @@ a = self.RPythonAnnotator() assert a.build_types(h, [int]).const == 456 + def test_list_plus_equal_string(self): + def f(n): + lst = [chr(n), chr(n + 1)] + if n < 100: + lst.append(chr(n + 2)) + lst += str(n) + return lst + a = self.RPythonAnnotator() + s = a.build_types(f, [int]) + assert isinstance(listitem(s), annmodel.SomeChar) + def g(n): return [0, 1, 2, n] diff --git a/rpython/rtyper/test/test_rstr.py b/rpython/rtyper/test/test_rstr.py --- a/rpython/rtyper/test/test_rstr.py +++ b/rpython/rtyper/test/test_rstr.py @@ -1059,7 +1059,7 @@ l = [const('a'), const('b')] else: l = [const('a')] - l += y + l += y # list += string return const('').join(l) assert self.ll_to_string(self.interpret(f, [1, From pypy.commits at gmail.com Mon Jul 1 11:16:38 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 01 Jul 2019 08:16:38 -0700 (PDT) Subject: [pypy-commit] pypy arm64: cargo cult GC support Message-ID: <5d1a23d6.1c69fb81.2fb38.3b1b@mx.google.com> Author: fijal Branch: arm64 Changeset: r96898:2dc82443969a Date: 2019-07-01 17:15 +0200 http://bitbucket.org/pypy/pypy/changeset/2dc82443969a/ Log: cargo cult GC support diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -9,7 +9,7 @@ CoreRegisterManager, VFPRegisterManager) from rpython.jit.backend.aarch64 import registers as r from rpython.jit.backend.arm import conditions as c -from rpython.jit.backend.llsupport import jitframe +from rpython.jit.backend.llsupport import jitframe, rewrite from rpython.jit.backend.llsupport.assembler import BaseAssembler from rpython.jit.backend.llsupport.regalloc import get_scale, valid_addressing_size from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper @@ -571,6 +571,270 @@ mc.RET_r(r.ip0.value) return mc.materialize(self.cpu, []) + def _build_malloc_slowpath(self, kind): + """ While arriving on slowpath, we have a gcpattern on stack 0. + The arguments are passed in r0 and r10, as follows: + + kind == 'fixed': nursery_head in r0 and the size in r1 - r0. + + kind == 'str/unicode': length of the string to allocate in r0. + + kind == 'var': length to allocate in r1, tid in r0, + and itemsize on the stack. + + This function must preserve all registers apart from r0 and r1. + """ + assert kind in ['fixed', 'str', 'unicode', 'var'] + mc = InstrBuilder() + # + self._push_all_regs_to_jitframe(mc, [r.x0, r.x1], True) + # + if kind == 'fixed': + addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr() + elif kind == 'str': + addr = self.cpu.gc_ll_descr.get_malloc_fn_addr('malloc_str') + elif kind == 'unicode': + addr = self.cpu.gc_ll_descr.get_malloc_fn_addr('malloc_unicode') + else: + addr = self.cpu.gc_ll_descr.get_malloc_slowpath_array_addr() + if kind == 'fixed': + # At this point we know that the values we need to compute the size + # are stored in x0 and x1. + mc.SUB_rr(r.x0.value, r.x1.value, r.x0.value) # compute the size we want + + if hasattr(self.cpu.gc_ll_descr, 'passes_frame'): + mc.MOV_rr(r.x1.value, r.fp.value) + elif kind == 'str' or kind == 'unicode': + mc.MOV_rr(r.x0.value, r.x1.value) + else: # var + # tid is in x0 + # length is in x1 + # gcmap in ip1 + # itemsize in ip0 + mc.MOV_rr(r.x2.value, r.x1.value) + mc.MOV_rr(r.x1.value, r.x0.value) + mc.MOV_rr(r.x0.value, r.ip0.value) # load itemsize, ip0 now free + # store the gc pattern + ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + mc.STR_ri(r.ip1.value, r.fp.value, ofs) + # + # We need to push two registers here because we are going to make a + # call an therefore the stack needs to be 8-byte aligned + mc.SUB_ri(r.sp.value, r.sp.value, 2 * WORD) + mc.STR_ri(r.lr.value, r.sp.value, 0) + # + mc.BL(addr) + # + # If the slowpath malloc failed, we raise a MemoryError that + # always interrupts the current loop, as a "good enough" + # approximation. + mc.CMP_ri(r.x0.value, 0) + mc.B_ofs_cond(4 * 6, c.NE) + mc.B(self.propagate_exception_path) + # jump here + self._reload_frame_if_necessary(mc) + self._pop_all_regs_from_jitframe(mc, [r.x0, r.x1], self.cpu.supports_floats) + # + nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr() + mc.gen_load_int(r.x1.value, nursery_free_adr) + mc.LDR_ri(r.x1.value, r.x1.value) + # clear the gc pattern + mc.gen_load_int(r.ip.value, 0) + self.store_reg(mc, r.ip0, r.fp, ofs) + # return + mc.LDR_ri(r.lr.value, r.sp.value, 0) + mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) + mc.RET_r(r.lr.value) + + # + rawstart = mc.materialize(self.cpu, []) + return rawstart + + def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, gcmap): + assert size & (WORD-1) == 0 + + self.mc.gen_load_int(r.x0.value, nursery_free_adr) + self.mc.LDR_ri(r.x0.value, r.x0.value) + + if check_imm_arg(size): + self.mc.ADD_ri(r.x1.value, r.x0.value, size) + else: + self.mc.gen_load_int(r.x1.value, size) + self.mc.ADD_rr(r.x1.value, r.x0.value, r.x1.value) + + self.mc.gen_load_int(r.ip0.value, nursery_top_adr) + self.mc.LDR_ri(r.ip0.value, r.ip0.value) + + self.mc.CMP_rr(r.x1.value, r.ip0.value) + + # We load into r0 the address stored at nursery_free_adr We calculate + # the new value for nursery_free_adr and store in r1 The we load the + # address stored in nursery_top_adr into IP If the value in r1 is + # (unsigned) bigger than the one in ip we conditionally call + # malloc_slowpath in case we called malloc_slowpath, which returns the + # new value of nursery_free_adr in r1 and the adr of the new object in + # r0. + + self.mc.B_ofs_cond(10 * 4, c.LO) # 4 for gcmap load, 5 for BL, 1 for B_ofs_cond + self.mc.gen_load_int_full(r.ip1.value, gcmap) + + self.mc.BL(self.malloc_slowpath) + + self.mc.gen_load_int(r.ip0.value, nursery_free_adr) + self.mc.STR_ri(r.x1.value, r.ip0.value) + + def malloc_cond_varsize_frame(self, nursery_free_adr, nursery_top_adr, + sizeloc, gcmap): + if sizeloc is r.x0: + self.mc.MOV_rr(r.x1.value, r.x0.value) + sizeloc = r.x1 + self.mc.gen_load_int(r.x0.value, nursery_free_adr) + self.mc.LDR_ri(r.x0.value, r.x0.value) + # + self.mc.ADD_rr(r.x1.value, r.x0.value, sizeloc.value) + # + self.mc.gen_load_int(r.ip0.value, nursery_top_adr) + self.mc.LDR_ri(r.ip0.value, r.ip0.value) + + self.mc.CMP_rr(r.x1.value, r.ip0.value) + # + self.mc.B_ofs_cond(40, c.LO) # see calculations in malloc_cond + self.mc.gen_load_int_full(r.ip1.value, gcmap) + + self.mc.BL(self.malloc_slowpath) + + self.mc.gen_load_int(r.ip0.value, nursery_free_adr) + self.mc.STR_ri(r.x1.value, r.ip0.value) + + def malloc_cond_varsize(self, kind, nursery_free_adr, nursery_top_adr, + lengthloc, itemsize, maxlength, gcmap, + arraydescr): + from rpython.jit.backend.llsupport.descr import ArrayDescr + assert isinstance(arraydescr, ArrayDescr) + + # lengthloc is the length of the array, which we must not modify! + assert lengthloc is not r.x0 and lengthloc is not r.x1 + if lengthloc.is_core_reg(): + varsizeloc = lengthloc + else: + assert lengthloc.is_stack() + self.regalloc_mov(lengthloc, r.x1) + varsizeloc = r.x1 + # + if check_imm_arg(maxlength): + self.mc.CMP_ri(varsizeloc.value, maxlength) + else: + self.mc.gen_load_int(r.ip0.value, maxlength) + self.mc.CMP_rr(varsizeloc.value, r.ip0.value) + jmp_adr0 = self.mc.currpos() # jump to (large) + self.mc.BKPT() + # + self.mc.gen_load_int(r.x0.value, nursery_free_adr) + self.mc.LDR_ri(r.x0.value, r.x0.value) + + + if valid_addressing_size(itemsize): + shiftsize = get_scale(itemsize) + else: + shiftsize = self._mul_const_scaled(self.mc, r.lr, varsizeloc, + itemsize) + varsizeloc = r.lr + # now varsizeloc is a register != x0. The size of + # the variable part of the array is (varsizeloc << shiftsize) + assert arraydescr.basesize >= self.gc_minimal_size_in_nursery + constsize = arraydescr.basesize + self.gc_size_of_header + force_realignment = (itemsize % WORD) != 0 + if force_realignment: + constsize += WORD - 1 + self.mc.gen_load_int(r.ip0.value, constsize) + # constsize + (varsizeloc << shiftsize) + self.mc.ADD_rr_shifted(r.x1.value, r.ip0.value, varsizeloc.value, + shiftsize) + self.mc.ADD_rr(r.x1.value, r.x1.value, r.x0.value) + if force_realignment: + self.mc.MVN_rr_shifted(r.ip0.value, r.ip0.value, WORD - 1) + self.mc.AND_rr(r.x1.value, r.x1.value, r.ip0.value) + # now x1 contains the total size in bytes, rounded up to a multiple + # of WORD, plus nursery_free_adr + # + self.mc.gen_load_int(r.ip0.value, nursery_top_adr) + self.mc.LDR_ri(r.ip0.value, r.ip0.value) + + self.mc.CMP_rr(r.x1.value, r.ip0.value) + jmp_adr1 = self.mc.currpos() # jump to (after-call) + self.mc.BKPT() + # + # (large) + currpos = self.mc.currpos() + pmc = OverwritingBuilder(self.mc, jmp_adr0, WORD) + pmc.B_ofs_cond(currpos - jmp_adr0, c.GT) + # + # save the gcmap + self.mc.gen_load_int_full(r.ip1.value, gcmap) + # + + if kind == rewrite.FLAG_ARRAY: + self.mc.gen_load_int(r.r0.value, arraydescr.tid) + self.regalloc_mov(lengthloc, r.x1) + self.gen_load_int(r.ip0.value, imm(itemsize)) + addr = self.malloc_slowpath_varsize + else: + if kind == rewrite.FLAG_STR: + addr = self.malloc_slowpath_str + else: + assert kind == rewrite.FLAG_UNICODE + addr = self.malloc_slowpath_unicode + self.regalloc_mov(lengthloc, r.x1) + self.mc.BL(addr) + # + jmp_location = self.mc.currpos() # jump to (done) + self.mc.BKPT() + # (after-call) + currpos = self.mc.currpos() + pmc = OverwritingBuilder(self.mc, jmp_adr1, WORD) + pmc.B_ofs_cond(currpos - jmp_adr1, c.LS) + # + # write down the tid, but not if it's the result of the CALL + self.mc.gen_load_int(r.ip0.value, arraydescr.tid) + self.mc.STR_ri(r.ip0.value, r.x0.value) + + # while we're at it, this line is not needed if we've done the CALL + self.mc.gen_load_int(r.ip0.value, nursery_free_adr) + self.mc.STR_ri(r.x1.value, r.ip0.value) + # (done) + # skip instructions after call + currpos = self.mc.currpos() + pmc = OverwritingBuilder(self.mc, jmp_location, WORD) + pmc.B_ofs(currpos - jmp_location) + + def _mul_const_scaled(self, mc, targetreg, sourcereg, itemsize): + """Produce one operation to do roughly + targetreg = sourcereg * itemsize + except that the targetreg may still need shifting by 0,1,2,3. + """ + if (itemsize & 7) == 0: + shiftsize = 3 + elif (itemsize & 3) == 0: + shiftsize = 2 + elif (itemsize & 1) == 0: + shiftsize = 1 + else: + shiftsize = 0 + itemsize >>= shiftsize + # + if valid_addressing_size(itemsize - 1): + self.mc.ADD_rr_shifted(targetreg.value, sourcereg.value, sourcereg.value, + get_scale(itemsize - 1)) + elif valid_addressing_size(itemsize): + self.mc.LSL_ri(targetreg.value, sourcereg.value, + get_scale(itemsize)) + else: + mc.gen_load_int(targetreg.value, itemsize) + mc.MUL_rr(targetreg.value, sourcereg.value, targetreg.value) + # + return shiftsize + + def _build_stack_check_slowpath(self): self.stack_check_slowpath = 0 #XXX diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -227,6 +227,12 @@ base = 0b10001011000 | (s << 8) self.write32((base << 21) | (rm << 16) | (rn << 5) | (rd)) + def ADD_rr_shifted(self, rd, rn, rm, imm): + # shifttype is LSL + base = 0b10001011000 + assert 0 <= imm < 64 + self.write32((base << 21) | (rm << 16) | (imm << 10) | (rn << 5) | (rd)) + def FMOV_dd(self, rd, rn): base = 0b0001111001100000010000 self.write32((base << 10) | (rn << 5) | rd) diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -946,6 +946,86 @@ prepare_op_cond_call_gc_wb_array = prepare_op_cond_call_gc_wb + def prepare_op_call_malloc_nursery(self, op, fcond): + size_box = op.getarg(0) + assert isinstance(size_box, ConstInt) + # hint: try to move unrelated registers away from x0 and x1 now + self.rm.spill_or_move_registers_before_call([r.x0, r.x1]) + + self.rm.force_allocate_reg(op, selected_reg=r.x0) + t = TempInt() + self.rm.force_allocate_reg(t, selected_reg=r.x1) + + sizeloc = size_box.getint() + gc_ll_descr = self.cpu.gc_ll_descr + gcmap = self.get_gcmap([r.x0, r.x1]) + self.possibly_free_var(t) + self.assembler.malloc_cond( + gc_ll_descr.get_nursery_free_addr(), + gc_ll_descr.get_nursery_top_addr(), + sizeloc, + gcmap + ) + + def prepare_op_call_malloc_nursery_varsize_frame(self, op, fcond): + size_box = op.getarg(0) + assert not isinstance(size_box, ConstInt) # we cannot have a const here! + # sizeloc must be in a register, but we can free it now + # (we take care explicitly of conflicts with r0 or r1) + sizeloc = self.rm.make_sure_var_in_reg(size_box) + self.rm.spill_or_move_registers_before_call([r.x0, r.x1]) # sizeloc safe + self.rm.possibly_free_var(size_box) + # + self.rm.force_allocate_reg(op, selected_reg=r.x0) + # + t = TempInt() + self.rm.force_allocate_reg(t, selected_reg=r.x1) + # + gcmap = self.get_gcmap([r.x0, r.x1]) + self.possibly_free_var(t) + # + gc_ll_descr = self.cpu.gc_ll_descr + self.assembler.malloc_cond_varsize_frame( + gc_ll_descr.get_nursery_free_addr(), + gc_ll_descr.get_nursery_top_addr(), + sizeloc, + gcmap + ) + + def prepare_op_call_malloc_nursery_varsize(self, op, fcond): + gc_ll_descr = self.cpu.gc_ll_descr + if not hasattr(gc_ll_descr, 'max_size_of_young_obj'): + raise Exception("unreachable code") + # for boehm, this function should never be called + arraydescr = op.getdescr() + length_box = op.getarg(2) + assert not isinstance(length_box, Const) # we cannot have a const here! + # can only use spill_or_move_registers_before_call() as a hint if + # we are sure that length_box stays alive and won't be freed now + # (it should always be the case, see below, but better safe than sorry) + if self.rm.stays_alive(length_box): + self.rm.spill_or_move_registers_before_call([r.x0, r.x1]) + # the result will be in r0 + self.rm.force_allocate_reg(op, selected_reg=r.x0) + # we need r1 as a temporary + tmp_box = TempVar() + self.rm.force_allocate_reg(tmp_box, selected_reg=r.x1) + gcmap = self.get_gcmap([r.x0, r.x1]) # allocate the gcmap *before* + self.rm.possibly_free_var(tmp_box) + # length_box always survives: it's typically also present in the + # next operation that will copy it inside the new array. It's + # fine to load it from the stack too, as long as it's != x0, x1. + lengthloc = self.rm.loc(length_box) + self.rm.possibly_free_var(length_box) + # + itemsize = op.getarg(1).getint() + maxlength = (gc_ll_descr.max_size_of_young_obj - WORD * 2) / itemsize + self.assembler.malloc_cond_varsize( + op.getarg(0).getint(), + gc_ll_descr.get_nursery_free_addr(), + gc_ll_descr.get_nursery_top_addr(), + lengthloc, itemsize, maxlength, gcmap, arraydescr) + def force_allocate_reg(self, var, forbidden_vars=[], selected_reg=None): if var.type == FLOAT: return self.vfprm.force_allocate_reg(var, forbidden_vars, From pypy.commits at gmail.com Mon Jul 1 11:21:00 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 01 Jul 2019 08:21:00 -0700 (PDT) Subject: [pypy-commit] pypy arm64: necessary parameter Message-ID: <5d1a24dc.1c69fb81.a4178.9324@mx.google.com> Author: fijal Branch: arm64 Changeset: r96899:6225288fecdb Date: 2019-07-01 17:20 +0200 http://bitbucket.org/pypy/pypy/changeset/6225288fecdb/ Log: necessary parameter diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -637,9 +637,9 @@ # nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr() mc.gen_load_int(r.x1.value, nursery_free_adr) - mc.LDR_ri(r.x1.value, r.x1.value) + mc.LDR_ri(r.x1.value, r.x1.value, 0) # clear the gc pattern - mc.gen_load_int(r.ip.value, 0) + mc.gen_load_int(r.ip0.value, 0) self.store_reg(mc, r.ip0, r.fp, ofs) # return mc.LDR_ri(r.lr.value, r.sp.value, 0) @@ -654,7 +654,7 @@ assert size & (WORD-1) == 0 self.mc.gen_load_int(r.x0.value, nursery_free_adr) - self.mc.LDR_ri(r.x0.value, r.x0.value) + self.mc.LDR_ri(r.x0.value, r.x0.value, 0) if check_imm_arg(size): self.mc.ADD_ri(r.x1.value, r.x0.value, size) @@ -663,7 +663,7 @@ self.mc.ADD_rr(r.x1.value, r.x0.value, r.x1.value) self.mc.gen_load_int(r.ip0.value, nursery_top_adr) - self.mc.LDR_ri(r.ip0.value, r.ip0.value) + self.mc.LDR_ri(r.ip0.value, r.ip0.value, 0) self.mc.CMP_rr(r.x1.value, r.ip0.value) @@ -681,7 +681,7 @@ self.mc.BL(self.malloc_slowpath) self.mc.gen_load_int(r.ip0.value, nursery_free_adr) - self.mc.STR_ri(r.x1.value, r.ip0.value) + self.mc.STR_ri(r.x1.value, r.ip0.value, 0) def malloc_cond_varsize_frame(self, nursery_free_adr, nursery_top_adr, sizeloc, gcmap): @@ -689,12 +689,12 @@ self.mc.MOV_rr(r.x1.value, r.x0.value) sizeloc = r.x1 self.mc.gen_load_int(r.x0.value, nursery_free_adr) - self.mc.LDR_ri(r.x0.value, r.x0.value) + self.mc.LDR_ri(r.x0.value, r.x0.value, 0) # self.mc.ADD_rr(r.x1.value, r.x0.value, sizeloc.value) # self.mc.gen_load_int(r.ip0.value, nursery_top_adr) - self.mc.LDR_ri(r.ip0.value, r.ip0.value) + self.mc.LDR_ri(r.ip0.value, r.ip0.value, 0) self.mc.CMP_rr(r.x1.value, r.ip0.value) # @@ -704,7 +704,7 @@ self.mc.BL(self.malloc_slowpath) self.mc.gen_load_int(r.ip0.value, nursery_free_adr) - self.mc.STR_ri(r.x1.value, r.ip0.value) + self.mc.STR_ri(r.x1.value, r.ip0.value, 0) def malloc_cond_varsize(self, kind, nursery_free_adr, nursery_top_adr, lengthloc, itemsize, maxlength, gcmap, @@ -730,7 +730,7 @@ self.mc.BKPT() # self.mc.gen_load_int(r.x0.value, nursery_free_adr) - self.mc.LDR_ri(r.x0.value, r.x0.value) + self.mc.LDR_ri(r.x0.value, r.x0.value, 0) if valid_addressing_size(itemsize): @@ -758,7 +758,7 @@ # of WORD, plus nursery_free_adr # self.mc.gen_load_int(r.ip0.value, nursery_top_adr) - self.mc.LDR_ri(r.ip0.value, r.ip0.value) + self.mc.LDR_ri(r.ip0.value, r.ip0.value, 0) self.mc.CMP_rr(r.x1.value, r.ip0.value) jmp_adr1 = self.mc.currpos() # jump to (after-call) @@ -796,11 +796,11 @@ # # write down the tid, but not if it's the result of the CALL self.mc.gen_load_int(r.ip0.value, arraydescr.tid) - self.mc.STR_ri(r.ip0.value, r.x0.value) + self.mc.STR_ri(r.ip0.value, r.x0.value, 0) # while we're at it, this line is not needed if we've done the CALL self.mc.gen_load_int(r.ip0.value, nursery_free_adr) - self.mc.STR_ri(r.x1.value, r.ip0.value) + self.mc.STR_ri(r.x1.value, r.ip0.value, 0) # (done) # skip instructions after call currpos = self.mc.currpos() @@ -1006,10 +1006,10 @@ endaddr, lengthaddr, _ = self.cpu.insert_stack_check() # load stack end self.mc.gen_load_int(r.ip0.value, endaddr) # load ip0, [end] - self.mc.LDR_ri(r.ip0.value, r.ip0.value) # LDR ip0, ip0 + self.mc.LDR_ri(r.ip0.value, r.ip0.value, 0) # LDR ip0, ip0 # load stack length self.mc.gen_load_int(r.ip1.value, lengthaddr) # load ip1, lengh - self.mc.LDR_ri(r.ip1.value, r.ip1.value) # ldr ip1, *lengh + self.mc.LDR_ri(r.ip1.value, r.ip1.value, 0) # ldr ip1, *lengh # calculate ofs self.mc.SUB_rr(r.ip0.value, r.ip0.value, r.sp.value) # SUB ip, current # if ofs From pypy.commits at gmail.com Mon Jul 1 11:24:04 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 01 Jul 2019 08:24:04 -0700 (PDT) Subject: [pypy-commit] pypy arm64: egh Message-ID: <5d1a2594.1c69fb81.91484.3717@mx.google.com> Author: fijal Branch: arm64 Changeset: r96900:6a7b47ffb5b4 Date: 2019-07-01 17:23 +0200 http://bitbucket.org/pypy/pypy/changeset/6a7b47ffb5b4/ Log: egh diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -946,7 +946,7 @@ prepare_op_cond_call_gc_wb_array = prepare_op_cond_call_gc_wb - def prepare_op_call_malloc_nursery(self, op, fcond): + def prepare_op_call_malloc_nursery(self, op): size_box = op.getarg(0) assert isinstance(size_box, ConstInt) # hint: try to move unrelated registers away from x0 and x1 now @@ -967,7 +967,7 @@ gcmap ) - def prepare_op_call_malloc_nursery_varsize_frame(self, op, fcond): + def prepare_op_call_malloc_nursery_varsize_frame(self, op): size_box = op.getarg(0) assert not isinstance(size_box, ConstInt) # we cannot have a const here! # sizeloc must be in a register, but we can free it now @@ -992,7 +992,7 @@ gcmap ) - def prepare_op_call_malloc_nursery_varsize(self, op, fcond): + def prepare_op_call_malloc_nursery_varsize(self, op): gc_ll_descr = self.cpu.gc_ll_descr if not hasattr(gc_ll_descr, 'max_size_of_young_obj'): raise Exception("unreachable code") From pypy.commits at gmail.com Mon Jul 1 11:30:49 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 01 Jul 2019 08:30:49 -0700 (PDT) Subject: [pypy-commit] pypy arm64: add some casts Message-ID: <5d1a2729.1c69fb81.e1352.c0fc@mx.google.com> Author: fijal Branch: arm64 Changeset: r96902:b96f44a61156 Date: 2019-07-01 17:29 +0200 http://bitbucket.org/pypy/pypy/changeset/b96f44a61156/ Log: add some casts diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -676,7 +676,7 @@ # r0. self.mc.B_ofs_cond(10 * 4, c.LO) # 4 for gcmap load, 5 for BL, 1 for B_ofs_cond - self.mc.gen_load_int_full(r.ip1.value, gcmap) + self.mc.gen_load_int_full(r.ip1.value, rffi.cast(lltype.Signed, gcmap)) self.mc.BL(self.malloc_slowpath) @@ -699,7 +699,7 @@ self.mc.CMP_rr(r.x1.value, r.ip0.value) # self.mc.B_ofs_cond(40, c.LO) # see calculations in malloc_cond - self.mc.gen_load_int_full(r.ip1.value, gcmap) + self.mc.gen_load_int_full(r.ip1.value, rffi.cast(lltype.Signed, gcmap)) self.mc.BL(self.malloc_slowpath) @@ -770,7 +770,7 @@ pmc.B_ofs_cond(currpos - jmp_adr0, c.GT) # # save the gcmap - self.mc.gen_load_int_full(r.ip1.value, gcmap) + self.mc.gen_load_int_full(r.ip1.value, rffi.cast(lltype.Signed, gcmap)) # if kind == rewrite.FLAG_ARRAY: From pypy.commits at gmail.com Mon Jul 1 11:33:59 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 01 Jul 2019 08:33:59 -0700 (PDT) Subject: [pypy-commit] pypy arm64: one missing one Message-ID: <5d1a27e7.1c69fb81.f8686.e3c8@mx.google.com> Author: fijal Branch: arm64 Changeset: r96903:d841bd0c34b4 Date: 2019-07-01 17:33 +0200 http://bitbucket.org/pypy/pypy/changeset/d841bd0c34b4/ Log: one missing one diff --git a/rpython/jit/backend/aarch64/callbuilder.py b/rpython/jit/backend/aarch64/callbuilder.py --- a/rpython/jit/backend/aarch64/callbuilder.py +++ b/rpython/jit/backend/aarch64/callbuilder.py @@ -143,7 +143,7 @@ if gcrootmap: rst = gcrootmap.get_root_stack_top_addr() self.mc.gen_load_int(r.x19.value, rst) - self.mc.LDR_ri(r.x20.value, r.x19.value) + self.mc.LDR_ri(r.x20.value, r.x19.value, 0) # change 'rpy_fastgil' to 0 (it should be non-zero right now) self.mc.DMB() @@ -227,7 +227,7 @@ # thread. So here we check if the shadowstack pointer # is still the same as before we released the GIL (saved # in 'x20'), and if not, we fall back to 'reacqgil_addr'. - self.mc.LDR_ri(r.ip0.value, r.x19.value) + self.mc.LDR_ri(r.ip0.value, r.x19.value, 0) self.mc.CMP_rr(r.ip0.value, r.x20.value) XXX b1_location = self.mc.currpos() From pypy.commits at gmail.com Mon Jul 1 11:38:01 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 01 Jul 2019 08:38:01 -0700 (PDT) Subject: [pypy-commit] pypy arm64: renamed Message-ID: <5d1a28d9.1c69fb81.2ef44.b5db@mx.google.com> Author: fijal Branch: arm64 Changeset: r96904:7c273adb042d Date: 2019-07-01 17:37 +0200 http://bitbucket.org/pypy/pypy/changeset/7c273adb042d/ Log: renamed diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -727,7 +727,7 @@ self.mc.gen_load_int(r.ip0.value, maxlength) self.mc.CMP_rr(varsizeloc.value, r.ip0.value) jmp_adr0 = self.mc.currpos() # jump to (large) - self.mc.BKPT() + self.mc.BRK() # self.mc.gen_load_int(r.x0.value, nursery_free_adr) self.mc.LDR_ri(r.x0.value, r.x0.value, 0) @@ -762,7 +762,7 @@ self.mc.CMP_rr(r.x1.value, r.ip0.value) jmp_adr1 = self.mc.currpos() # jump to (after-call) - self.mc.BKPT() + self.mc.BRK() # # (large) currpos = self.mc.currpos() @@ -788,7 +788,7 @@ self.mc.BL(addr) # jmp_location = self.mc.currpos() # jump to (done) - self.mc.BKPT() + self.mc.BRK() # (after-call) currpos = self.mc.currpos() pmc = OverwritingBuilder(self.mc, jmp_adr1, WORD) From pypy.commits at gmail.com Mon Jul 1 11:41:47 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 01 Jul 2019 08:41:47 -0700 (PDT) Subject: [pypy-commit] pypy arm64: name fixes Message-ID: <5d1a29bb.1c69fb81.c64e5.2a1d@mx.google.com> Author: fijal Branch: arm64 Changeset: r96905:9581673169cb Date: 2019-07-01 17:40 +0200 http://bitbucket.org/pypy/pypy/changeset/9581673169cb/ Log: name fixes diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -776,7 +776,7 @@ if kind == rewrite.FLAG_ARRAY: self.mc.gen_load_int(r.x0.value, arraydescr.tid) self.regalloc_mov(lengthloc, r.x1) - self.gen_load_int(r.ip0.value, imm(itemsize)) + self.mc.gen_load_int(r.ip0.value, itemsize) addr = self.malloc_slowpath_varsize else: if kind == rewrite.FLAG_STR: diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -364,7 +364,7 @@ base = 0b10101010001 self.write32((base << 21) | (rm << 16) | (0b11111 << 5)| rd) - def MVN_rr_shift(self, rd, rm, shift=0, shifttype=0): # defaults to LSL + def MVN_rr_shifted(self, rd, rm, shift=0, shifttype=0): # defaults to LSL base = 0b10101010 assert 0 <= shift < 64 self.write32((base << 24) | (shifttype << 22) | (1 << 21) | From pypy.commits at gmail.com Mon Jul 1 12:01:26 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 01 Jul 2019 09:01:26 -0700 (PDT) Subject: [pypy-commit] pypy arm64: we don't support negative offsets for STR Message-ID: <5d1a2e56.1c69fb81.a4672.b7d6@mx.google.com> Author: fijal Branch: arm64 Changeset: r96907:8a81fd7acc58 Date: 2019-07-01 18:00 +0200 http://bitbucket.org/pypy/pypy/changeset/8a81fd7acc58/ Log: we don't support negative offsets for STR diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -447,7 +447,8 @@ if gcrootmap and gcrootmap.is_shadow_stack: self._load_shadowstack_top(mc, r.x19, gcrootmap) # store the new jitframe addr in the shadowstack - mc.STR_ri(r.x0.value, r.x19.value, -WORD) + mc.SUB_ri(r.x19.value, r.x19.value, WORD) + mc.STR_ri(r.x0.value, r.x19.value, 0) # reset the jf_gcmap field in the jitframe mc.gen_load_int(r.ip0.value, 0) From pypy.commits at gmail.com Mon Jul 1 12:16:21 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 01 Jul 2019 09:16:21 -0700 (PDT) Subject: [pypy-commit] pypy arm64: one more loading of negative offsets Message-ID: <5d1a31d5.1c69fb81.a3efc.038b@mx.google.com> Author: fijal Branch: arm64 Changeset: r96908:9d79ae703c08 Date: 2019-07-01 18:15 +0200 http://bitbucket.org/pypy/pypy/changeset/9d79ae703c08/ Log: one more loading of negative offsets diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -888,7 +888,8 @@ rst = gcrootmap.get_root_stack_top_addr() mc.gen_load_int(r.ip0.value, rst) self.load_reg(mc, r.ip0, r.ip0) - self.load_reg(mc, r.fp, r.ip0, -WORD) + mc.SUB_ri(r.ip0, r.ip0, WORD) + mc.LDR_ri(r.fp, r.ip0, 0) wbdescr = self.cpu.gc_ll_descr.write_barrier_descr if gcrootmap and wbdescr: # frame never uses card marking, so we enforce this is not From pypy.commits at gmail.com Mon Jul 1 12:17:37 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 01 Jul 2019 09:17:37 -0700 (PDT) Subject: [pypy-commit] pypy arm64: typo Message-ID: <5d1a3221.1c69fb81.1e3c0.eb8d@mx.google.com> Author: fijal Branch: arm64 Changeset: r96909:b16bba1b07a5 Date: 2019-07-01 18:16 +0200 http://bitbucket.org/pypy/pypy/changeset/b16bba1b07a5/ Log: typo diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -888,8 +888,8 @@ rst = gcrootmap.get_root_stack_top_addr() mc.gen_load_int(r.ip0.value, rst) self.load_reg(mc, r.ip0, r.ip0) - mc.SUB_ri(r.ip0, r.ip0, WORD) - mc.LDR_ri(r.fp, r.ip0, 0) + mc.SUB_ri(r.ip0.value, r.ip0.value, WORD) + mc.LDR_ri(r.fp.value, r.ip0.value, 0) wbdescr = self.cpu.gc_ll_descr.write_barrier_descr if gcrootmap and wbdescr: # frame never uses card marking, so we enforce this is not From pypy.commits at gmail.com Tue Jul 2 02:36:30 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 01 Jul 2019 23:36:30 -0700 (PDT) Subject: [pypy-commit] pypy arm64: ugh why is this hardcoded to WORD Message-ID: <5d1afb6e.1c69fb81.ede96.b7f7@mx.google.com> Author: fijal Branch: arm64 Changeset: r96911:2574a06ba591 Date: 2019-07-02 08:35 +0200 http://bitbucket.org/pypy/pypy/changeset/2574a06ba591/ Log: ugh why is this hardcoded to WORD diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -901,7 +901,8 @@ startpos = self.mc.currpos() faildescrindex, target = self.store_info_on_descr(startpos, guardtok) self.load_from_gc_table(r.ip0.value, faildescrindex) - self.store_reg(self.mc, r.ip0, r.fp, WORD) + ofs = self.cpu.get_ofs_of_frame_field('jf_descr') + self.store_reg(self.mc, r.ip0, r.fp, ofs) self.push_gcmap(self.mc, gcmap=guardtok.gcmap) assert target self.mc.BL(target) From pypy.commits at gmail.com Tue Jul 2 03:54:47 2019 From: pypy.commits at gmail.com (fijal) Date: Tue, 02 Jul 2019 00:54:47 -0700 (PDT) Subject: [pypy-commit] pypy arm64: missing stack adjustment Message-ID: <5d1b0dc7.1c69fb81.fb1b7.30fe@mx.google.com> Author: fijal Branch: arm64 Changeset: r96912:371da80e47bf Date: 2019-07-02 09:54 +0200 http://bitbucket.org/pypy/pypy/changeset/371da80e47bf/ Log: missing stack adjustment diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -382,6 +382,8 @@ assert exc0 is not None assert exc1 is not None + mc.ADD_ri(r.sp.value, r.sp.value, (len(r.caller_resp) + 2 + len(r.caller_vfp_resp)) * WORD) + # if withcards: # A final TEST8 before the RET, for the caller. Careful to From pypy.commits at gmail.com Tue Jul 2 04:22:21 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Jul 2019 01:22:21 -0700 (PDT) Subject: [pypy-commit] pypy arm64: add a potential optimization Message-ID: <5d1b143d.1c69fb81.d3539.99db@mx.google.com> Author: Armin Rigo Branch: arm64 Changeset: r96913:9426b24f72b6 Date: 2019-07-02 10:21 +0200 http://bitbucket.org/pypy/pypy/changeset/9426b24f72b6/ Log: add a potential optimization diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO --- a/rpython/jit/backend/aarch64/TODO +++ b/rpython/jit/backend/aarch64/TODO @@ -3,3 +3,10 @@ * guard_nonnull_class - think about a better way * cond_call and following guard_exception * stack check + + +We can try to make generate_quick_failure() emit two instructions less: +the two store_reg() [one in generate_quick_failure and the other in +push_gcmap]. Instead we'd load the values in known unused registers, +and the store_regs would occur inside self.failure_recovery_code +(which 'target' points to). From pypy.commits at gmail.com Tue Jul 2 06:14:05 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Jul 2019 03:14:05 -0700 (PDT) Subject: [pypy-commit] pypy arm64: passing a value to a helper via ip0 is not going to work, Message-ID: <5d1b2e6d.1c69fb81.c5046.2f19@mx.google.com> Author: Armin Rigo Branch: arm64 Changeset: r96914:06dff6a3c763 Date: 2019-07-02 12:13 +0200 http://bitbucket.org/pypy/pypy/changeset/06dff6a3c763/ Log: passing a value to a helper via ip0 is not going to work, because ip0 is overwritten by the BL diff --git a/rpython/jit/backend/aarch64/arch.py b/rpython/jit/backend/aarch64/arch.py --- a/rpython/jit/backend/aarch64/arch.py +++ b/rpython/jit/backend/aarch64/arch.py @@ -8,5 +8,7 @@ # A jitframe is a jit.backend.llsupport.llmodel.jitframe.JITFRAME # Stack frame fixed area # Currently only the force_index -JITFRAME_FIXED_SIZE = 16 + 2 + 8 -# 18 GPR + 8 VFP Regs # 20 if we want to use 4 extra x19..x22 +NUM_MANAGED_REGS = 16 +NUM_VFP_REGS = 8 +JITFRAME_FIXED_SIZE = NUM_MANAGED_REGS + NUM_VFP_REGS +# 16 GPR + 8 VFP Regs, for now diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -613,10 +613,10 @@ # tid is in x0 # length is in x1 # gcmap in ip1 - # itemsize in ip0 + # itemsize in ip2 mc.MOV_rr(r.x2.value, r.x1.value) mc.MOV_rr(r.x1.value, r.x0.value) - mc.MOV_rr(r.x0.value, r.ip0.value) # load itemsize, ip0 now free + mc.MOV_rr(r.x0.value, r.ip2.value) # load itemsize, ip2 now free # store the gc pattern ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') mc.STR_ri(r.ip1.value, r.fp.value, ofs) @@ -779,7 +779,7 @@ if kind == rewrite.FLAG_ARRAY: self.mc.gen_load_int(r.x0.value, arraydescr.tid) self.regalloc_mov(lengthloc, r.x1) - self.mc.gen_load_int(r.ip0.value, itemsize) + self.mc.gen_load_int(r.ip2.value, itemsize) addr = self.malloc_slowpath_varsize else: if kind == rewrite.FLAG_STR: diff --git a/rpython/jit/backend/aarch64/registers.py b/rpython/jit/backend/aarch64/registers.py --- a/rpython/jit/backend/aarch64/registers.py +++ b/rpython/jit/backend/aarch64/registers.py @@ -11,7 +11,7 @@ vfpregisters = [VFPRegisterLocation(i) for i in range(32)] all_vfp_regs = vfpregisters[:8] -all_regs = registers[:16]+ [x19, x20] #, x21, x22] +all_regs = registers[:14]+ [x19, x20] #, x21, x22] lr = x30 fp = x29 @@ -20,6 +20,8 @@ # nor we use them for regalloc ip1 = x17 ip0 = x16 +ip2 = x15 +ip3 = x14 # not used so far, but 'caller_resp' needs to be even-length anyway callee_saved_registers = [x19, x20] # , x21, x22] vfp_argument_regs = caller_vfp_resp = all_vfp_regs[:8] @@ -31,4 +33,4 @@ argument_regs = [x0, x1, x2, x3, x4, x5, x6, x7] callee_resp = [x19, x20] # ,x21, x22] -caller_resp = argument_regs + [x8, x9, x10, x11, x12, x13, x14, x15] +caller_resp = argument_regs + [x8, x9, x10, x11, x12, x13] diff --git a/rpython/jit/backend/aarch64/runner.py b/rpython/jit/backend/aarch64/runner.py --- a/rpython/jit/backend/aarch64/runner.py +++ b/rpython/jit/backend/aarch64/runner.py @@ -10,7 +10,7 @@ """ARM 64""" backend_name = "aarch64" frame_reg = r.fp - all_reg_indexes = range(16) + [-1, -1, -1, 16, 17] + all_reg_indexes = range(14) + [-1, -1, -1, -1, -1, 14, 15] gen_regs = r.all_regs float_regs = VFPRegisterManager.all_regs supports_floats = True @@ -61,3 +61,9 @@ return CPU_ARM64.cast_adr_to_int(adr) cast_ptr_to_int._annspecialcase_ = 'specialize:arglltype(0)' cast_ptr_to_int = staticmethod(cast_ptr_to_int) + + +for _i, _r in enumerate(r.all_regs): + assert CPU_ARM64.all_reg_indexes[_r.value] == _i +from rpython.jit.backend.aarch64 import arch +assert arch.NUM_MANAGED_REGS == len(r.all_regs) From pypy.commits at gmail.com Tue Jul 2 06:34:58 2019 From: pypy.commits at gmail.com (fijal) Date: Tue, 02 Jul 2019 03:34:58 -0700 (PDT) Subject: [pypy-commit] pypy arm64: kill some untrue comments and unnecessary pushes Message-ID: <5d1b3352.1c69fb81.ceec.1cb6@mx.google.com> Author: fijal Branch: arm64 Changeset: r96915:1a07024b9dd4 Date: 2019-07-02 11:31 +0200 http://bitbucket.org/pypy/pypy/changeset/1a07024b9dd4/ Log: kill some untrue comments and unnecessary pushes diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -336,7 +336,6 @@ mc = InstrBuilder() # mc.SUB_ri(r.sp.value, r.sp.value, 2 * WORD) - mc.STR_ri(r.ip0.value, r.sp.value, WORD) mc.STR_ri(r.lr.value, r.sp.value, 0) if not for_frame: self._push_all_regs_to_jitframe(mc, [], withfloats, callee_only=True) @@ -393,7 +392,6 @@ mc.MOVZ_r_u16(r.ip1.value, 0x80, 0) mc.TST_rr_shift(r.ip0.value, r.ip1.value, 0) # - mc.LDR_ri(r.ip0.value, r.sp.value, WORD) mc.LDR_ri(r.ip1.value, r.sp.value, 0) mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) mc.RET_r(r.ip1.value) @@ -621,8 +619,6 @@ ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') mc.STR_ri(r.ip1.value, r.fp.value, ofs) # - # We need to push two registers here because we are going to make a - # call an therefore the stack needs to be 8-byte aligned mc.SUB_ri(r.sp.value, r.sp.value, 2 * WORD) mc.STR_ri(r.lr.value, r.sp.value, 0) # @@ -1314,7 +1310,6 @@ self.store_reg(mc, r.ip1, r.ip0) def store_reg(self, mc, source, base, ofs=0, helper=None): - # uses r.ip1 as a temporary if source.is_vfp_reg(): return self._store_vfp_reg(mc, source, base, ofs) else: @@ -1325,7 +1320,6 @@ mc.STR_di(source.value, base.value, ofs) def _store_core_reg(self, mc, source, base, ofs): - # uses r.ip1 as a temporary # XXX fix: assert ofs & 0x7 == 0 assert 0 <= ofs < 32768 From pypy.commits at gmail.com Tue Jul 2 06:35:00 2019 From: pypy.commits at gmail.com (fijal) Date: Tue, 02 Jul 2019 03:35:00 -0700 (PDT) Subject: [pypy-commit] pypy arm64: merge Message-ID: <5d1b3354.1c69fb81.17cfd.d1be@mx.google.com> Author: fijal Branch: arm64 Changeset: r96916:c6d1d6d6b8c4 Date: 2019-07-02 12:34 +0200 http://bitbucket.org/pypy/pypy/changeset/c6d1d6d6b8c4/ Log: merge diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO --- a/rpython/jit/backend/aarch64/TODO +++ b/rpython/jit/backend/aarch64/TODO @@ -3,3 +3,10 @@ * guard_nonnull_class - think about a better way * cond_call and following guard_exception * stack check + + +We can try to make generate_quick_failure() emit two instructions less: +the two store_reg() [one in generate_quick_failure and the other in +push_gcmap]. Instead we'd load the values in known unused registers, +and the store_regs would occur inside self.failure_recovery_code +(which 'target' points to). diff --git a/rpython/jit/backend/aarch64/arch.py b/rpython/jit/backend/aarch64/arch.py --- a/rpython/jit/backend/aarch64/arch.py +++ b/rpython/jit/backend/aarch64/arch.py @@ -8,5 +8,7 @@ # A jitframe is a jit.backend.llsupport.llmodel.jitframe.JITFRAME # Stack frame fixed area # Currently only the force_index -JITFRAME_FIXED_SIZE = 16 + 2 + 8 -# 18 GPR + 8 VFP Regs # 20 if we want to use 4 extra x19..x22 +NUM_MANAGED_REGS = 16 +NUM_VFP_REGS = 8 +JITFRAME_FIXED_SIZE = NUM_MANAGED_REGS + NUM_VFP_REGS +# 16 GPR + 8 VFP Regs, for now diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -611,10 +611,10 @@ # tid is in x0 # length is in x1 # gcmap in ip1 - # itemsize in ip0 + # itemsize in ip2 mc.MOV_rr(r.x2.value, r.x1.value) mc.MOV_rr(r.x1.value, r.x0.value) - mc.MOV_rr(r.x0.value, r.ip0.value) # load itemsize, ip0 now free + mc.MOV_rr(r.x0.value, r.ip2.value) # load itemsize, ip2 now free # store the gc pattern ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') mc.STR_ri(r.ip1.value, r.fp.value, ofs) @@ -775,7 +775,7 @@ if kind == rewrite.FLAG_ARRAY: self.mc.gen_load_int(r.x0.value, arraydescr.tid) self.regalloc_mov(lengthloc, r.x1) - self.mc.gen_load_int(r.ip0.value, itemsize) + self.mc.gen_load_int(r.ip2.value, itemsize) addr = self.malloc_slowpath_varsize else: if kind == rewrite.FLAG_STR: diff --git a/rpython/jit/backend/aarch64/registers.py b/rpython/jit/backend/aarch64/registers.py --- a/rpython/jit/backend/aarch64/registers.py +++ b/rpython/jit/backend/aarch64/registers.py @@ -11,7 +11,7 @@ vfpregisters = [VFPRegisterLocation(i) for i in range(32)] all_vfp_regs = vfpregisters[:8] -all_regs = registers[:16]+ [x19, x20] #, x21, x22] +all_regs = registers[:14]+ [x19, x20] #, x21, x22] lr = x30 fp = x29 @@ -20,6 +20,8 @@ # nor we use them for regalloc ip1 = x17 ip0 = x16 +ip2 = x15 +ip3 = x14 # not used so far, but 'caller_resp' needs to be even-length anyway callee_saved_registers = [x19, x20] # , x21, x22] vfp_argument_regs = caller_vfp_resp = all_vfp_regs[:8] @@ -31,4 +33,4 @@ argument_regs = [x0, x1, x2, x3, x4, x5, x6, x7] callee_resp = [x19, x20] # ,x21, x22] -caller_resp = argument_regs + [x8, x9, x10, x11, x12, x13, x14, x15] +caller_resp = argument_regs + [x8, x9, x10, x11, x12, x13] diff --git a/rpython/jit/backend/aarch64/runner.py b/rpython/jit/backend/aarch64/runner.py --- a/rpython/jit/backend/aarch64/runner.py +++ b/rpython/jit/backend/aarch64/runner.py @@ -10,7 +10,7 @@ """ARM 64""" backend_name = "aarch64" frame_reg = r.fp - all_reg_indexes = range(16) + [-1, -1, -1, 16, 17] + all_reg_indexes = range(14) + [-1, -1, -1, -1, -1, 14, 15] gen_regs = r.all_regs float_regs = VFPRegisterManager.all_regs supports_floats = True @@ -61,3 +61,9 @@ return CPU_ARM64.cast_adr_to_int(adr) cast_ptr_to_int._annspecialcase_ = 'specialize:arglltype(0)' cast_ptr_to_int = staticmethod(cast_ptr_to_int) + + +for _i, _r in enumerate(r.all_regs): + assert CPU_ARM64.all_reg_indexes[_r.value] == _i +from rpython.jit.backend.aarch64 import arch +assert arch.NUM_MANAGED_REGS == len(r.all_regs) From pypy.commits at gmail.com Tue Jul 2 06:50:56 2019 From: pypy.commits at gmail.com (fijal) Date: Tue, 02 Jul 2019 03:50:56 -0700 (PDT) Subject: [pypy-commit] pypy arm64: swap lr and fp, maybe we can see now the stack in gdb Message-ID: <5d1b3710.1c69fb81.c5046.3c90@mx.google.com> Author: fijal Branch: arm64 Changeset: r96917:b8ce2916a65f Date: 2019-07-02 12:50 +0200 http://bitbucket.org/pypy/pypy/changeset/b8ce2916a65f/ Log: swap lr and fp, maybe we can see now the stack in gdb diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -1020,7 +1020,7 @@ def _call_header(self): stack_size = (len(r.callee_saved_registers) + 4) * WORD - self.mc.STP_rr_preindex(r.fp.value, r.lr.value, r.sp.value, -stack_size) + self.mc.STP_rr_preindex(r.lr.value, r.fp.value, r.sp.value, -stack_size) for i in range(0, len(r.callee_saved_registers), 2): self.mc.STP_rri(r.callee_saved_registers[i].value, r.callee_saved_registers[i + 1].value, @@ -1281,7 +1281,7 @@ r.callee_saved_registers[i + 1].value, r.sp.value, (i + 4) * WORD) - mc.LDP_rr_postindex(r.fp.value, r.lr.value, r.sp.value, stack_size) + mc.LDP_rr_postindex(r.lr.value, r.fp.value, r.sp.value, stack_size) mc.RET_r(r.lr.value) From pypy.commits at gmail.com Tue Jul 2 07:04:13 2019 From: pypy.commits at gmail.com (fijal) Date: Tue, 02 Jul 2019 04:04:13 -0700 (PDT) Subject: [pypy-commit] pypy arm64: I *think* necessary fix for cond_call Message-ID: <5d1b3a2d.1c69fb81.1bfa1.d45d@mx.google.com> Author: fijal Branch: arm64 Changeset: r96918:a05434b893c9 Date: 2019-07-02 13:03 +0200 http://bitbucket.org/pypy/pypy/changeset/a05434b893c9/ Log: I *think* necessary fix for cond_call diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -562,10 +562,11 @@ mc.STR_ri(r.ip0.value, r.sp.value, WORD) mc.STR_ri(r.lr.value, r.sp.value, 0) mc.BLR_r(r.ip1.value) - mc.MOV_rr(r.ip1.value, r.x0.value) # return comes back in ip1 - self._reload_frame_if_necessary(mc) + # callee saved + self._reload_frame_if_necessary(mc) # <- this will not touch x0 + mc.MOV_rr(r.ip1.value, r.x0.value) self._pop_all_regs_from_jitframe(mc, [], supports_floats, - callee_only) + callee_only) # <- this does not touch ip1 # return mc.LDR_ri(r.ip0.value, r.sp.value, 0) mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) From pypy.commits at gmail.com Tue Jul 2 07:54:11 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Jul 2019 04:54:11 -0700 (PDT) Subject: [pypy-commit] pypy arm64: update on the locking instructions Message-ID: <5d1b45e3.1c69fb81.9955c.4982@mx.google.com> Author: Armin Rigo Branch: arm64 Changeset: r96919:1109c1cd0a1e Date: 2019-07-02 13:53 +0200 http://bitbucket.org/pypy/pypy/changeset/1109c1cd0a1e/ Log: update on the locking instructions diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO --- a/rpython/jit/backend/aarch64/TODO +++ b/rpython/jit/backend/aarch64/TODO @@ -10,3 +10,22 @@ push_gcmap]. Instead we'd load the values in known unused registers, and the store_regs would occur inside self.failure_recovery_code (which 'target' points to). + +* here's what gcc uses to acquire and release a lock, instead of mc.DMB + in callbuilder.py. It would make the control flow mess easier, too, + because we can simply loop back to .L2 (rare case) instead of trying + to handle it as a 3rd path. + - to release a lock: + (x0 is the address of the lock) + stlr xzr, [x0] + - to acquire a lock: + (x1 is the address of the lock) + mov x2, 1 + .L2: ldxr x0, [x1] + stxr w3, x2, [x1] + cbnz w3, .L2 (I think it's a rare case when it follows .L2) + dmb ish (see below) + (we're left with x0 being the old value in the lock, 0 or 1) + - note that "dmb" only appears sometimes, depending on the exact gcc + intrinsic I use. I *think* that it can be safely removed, and so + it should be. From pypy.commits at gmail.com Tue Jul 2 08:31:38 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Jul 2019 05:31:38 -0700 (PDT) Subject: [pypy-commit] pypy arm64: more missing optimizations Message-ID: <5d1b4eaa.1c69fb81.a0e84.e800@mx.google.com> Author: Armin Rigo Branch: arm64 Changeset: r96920:b9d8f82099f7 Date: 2019-07-02 14:30 +0200 http://bitbucket.org/pypy/pypy/changeset/b9d8f82099f7/ Log: more missing optimizations diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO --- a/rpython/jit/backend/aarch64/TODO +++ b/rpython/jit/backend/aarch64/TODO @@ -5,11 +5,15 @@ * stack check -We can try to make generate_quick_failure() emit two instructions less: -the two store_reg() [one in generate_quick_failure and the other in -push_gcmap]. Instead we'd load the values in known unused registers, -and the store_regs would occur inside self.failure_recovery_code -(which 'target' points to). +* We can try to make generate_quick_failure() emit two instructions less: + the two store_reg() [one in generate_quick_failure and the other in + push_gcmap]. Instead we'd load the values in ip2 and ip3, and the + store_regs would occur inside self.failure_recovery_code + (which 'target' points to). + + +* use STP instead of STR in all long sequences of STR. Same with LDR + * here's what gcc uses to acquire and release a lock, instead of mc.DMB in callbuilder.py. It would make the control flow mess easier, too, From pypy.commits at gmail.com Tue Jul 2 11:11:49 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Jul 2019 08:11:49 -0700 (PDT) Subject: [pypy-commit] pypy arm64: fix the next bug Message-ID: <5d1b7435.1c69fb81.71004.18cb@mx.google.com> Author: Armin Rigo Branch: arm64 Changeset: r96921:2486e872ccdf Date: 2019-07-02 17:10 +0200 http://bitbucket.org/pypy/pypy/changeset/2486e872ccdf/ Log: fix the next bug diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -752,7 +752,8 @@ shiftsize) self.mc.ADD_rr(r.x1.value, r.x1.value, r.x0.value) if force_realignment: - self.mc.MVN_rr_shifted(r.ip0.value, r.ip0.value, WORD - 1) + # -WORD = 0xfffffffffffffff8 + self.mc.gen_load_int(r.ip0.value, -WORD) self.mc.AND_rr(r.x1.value, r.x1.value, r.ip0.value) # now x1 contains the total size in bytes, rounded up to a multiple # of WORD, plus nursery_free_adr From pypy.commits at gmail.com Tue Jul 2 11:11:51 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Jul 2019 08:11:51 -0700 (PDT) Subject: [pypy-commit] pypy arm64: tweaks Message-ID: <5d1b7437.1c69fb81.93d95.fd82@mx.google.com> Author: Armin Rigo Branch: arm64 Changeset: r96922:838a6988dd0e Date: 2019-07-02 17:10 +0200 http://bitbucket.org/pypy/pypy/changeset/838a6988dd0e/ Log: tweaks diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO --- a/rpython/jit/backend/aarch64/TODO +++ b/rpython/jit/backend/aarch64/TODO @@ -14,6 +14,10 @@ * use STP instead of STR in all long sequences of STR. Same with LDR +* use "STR xzr, [..]" instead of "gen_load_int(ip, 0); STR ip, [..]". + Search around for gen_load_int(...0): it occurs at least in pop_gcmap() + _build_failure_recovery(), build_frame_realloc_slowpath(), etc. + * here's what gcc uses to acquire and release a lock, instead of mc.DMB in callbuilder.py. It would make the control flow mess easier, too, diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -472,7 +472,10 @@ register""" # XXX optimize! if value < 0: - self.gen_load_int_full(r, value) + if value < -65536: + self.gen_load_int_full(r, value) + else: + self.MOVN_r_u16(r, ~value) return self.MOVZ_r_u16(r, value & 0xFFFF, 0) value = value >> 16 From pypy.commits at gmail.com Tue Jul 2 12:10:15 2019 From: pypy.commits at gmail.com (fijal) Date: Tue, 02 Jul 2019 09:10:15 -0700 (PDT) Subject: [pypy-commit] pypy arm64: undo the previous checkin Message-ID: <5d1b81e7.1c69fb81.41704.8f28@mx.google.com> Author: fijal Branch: arm64 Changeset: r96924:63cad80b3380 Date: 2019-07-02 18:09 +0200 http://bitbucket.org/pypy/pypy/changeset/63cad80b3380/ Log: undo the previous checkin diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -1125,7 +1125,7 @@ self.mc.gen_load_int(loc.value, value.getint()) elif value.is_imm_float(): self.mc.gen_load_int(r.ip0.value, value.getint()) - self.mc.FMOV_dr(loc.value, r.ip0.value) + self.mc.LDR_di(loc.value, r.ip0.value, 0) def _mov_stack_to_loc(self, prev_loc, loc): offset = prev_loc.value From pypy.commits at gmail.com Tue Jul 2 12:26:41 2019 From: pypy.commits at gmail.com (fijal) Date: Tue, 02 Jul 2019 09:26:41 -0700 (PDT) Subject: [pypy-commit] pypy arm64: bah Message-ID: <5d1b85c1.1c69fb81.1bfa1.4549@mx.google.com> Author: fijal Branch: arm64 Changeset: r96925:8c7dd5b87a48 Date: 2019-07-02 18:25 +0200 http://bitbucket.org/pypy/pypy/changeset/8c7dd5b87a48/ Log: bah diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -477,7 +477,7 @@ def prepare_two_regs_op(self, op): loc1 = self.make_sure_var_in_reg(op.getarg(0)) - loc2 = self.make_sure_var_in_reg(op.getarg(1)) + loc2 = self.make_sure_var_in_reg(op.getarg(1), op.getarglist()) self.possibly_free_vars_for_op(op) self.free_temp_vars() res = self.force_allocate_reg(op) From pypy.commits at gmail.com Tue Jul 2 17:49:07 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 02 Jul 2019 14:49:07 -0700 (PDT) Subject: [pypy-commit] pypy arm64: another comment Message-ID: <5d1bd153.1c69fb81.e3ac1.2864@mx.google.com> Author: Armin Rigo Branch: arm64 Changeset: r96926:89739b45ddb0 Date: 2019-07-02 23:48 +0200 http://bitbucket.org/pypy/pypy/changeset/89739b45ddb0/ Log: another comment diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO --- a/rpython/jit/backend/aarch64/TODO +++ b/rpython/jit/backend/aarch64/TODO @@ -37,3 +37,11 @@ - note that "dmb" only appears sometimes, depending on the exact gcc intrinsic I use. I *think* that it can be safely removed, and so it should be. + + +* malloc_cond() and malloc_cond_varsize_frame() hard-code forward jump + distances by guessing the number of instructions that follows. Bad + idea because some of these instructions could easily be optimized in + the future to be a bit shorter. Rewrite this two places to use the + proper way instead of a magic "40" (or at least assert that it was + really 40). From pypy.commits at gmail.com Wed Jul 3 03:53:03 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 03 Jul 2019 00:53:03 -0700 (PDT) Subject: [pypy-commit] pypy arm64: simplify control flow and hopefully finish the shadowstack Message-ID: <5d1c5edf.1c69fb81.ef6a3.60f1@mx.google.com> Author: fijal Branch: arm64 Changeset: r96927:3d49fb7bb1a5 Date: 2019-07-03 09:51 +0200 http://bitbucket.org/pypy/pypy/changeset/3d49fb7bb1a5/ Log: simplify control flow and hopefully finish the shadowstack diff --git a/rpython/jit/backend/aarch64/callbuilder.py b/rpython/jit/backend/aarch64/callbuilder.py --- a/rpython/jit/backend/aarch64/callbuilder.py +++ b/rpython/jit/backend/aarch64/callbuilder.py @@ -6,6 +6,7 @@ from rpython.jit.backend.arm import conditions as c from rpython.jit.backend.aarch64.jump import remap_frame_layout # we use arm algo from rpython.jit.backend.llsupport import llerrno +from rpython.jit.backend.aarch64.codebuilder import OverwritingBuilder from rpython.rlib.objectmodel import we_are_translated from rpython.rtyper.lltypesystem import rffi @@ -203,24 +204,22 @@ # x20 == previous value of root_stack_top self.mc.gen_load_int(r.ip1.value, fastgil) self.mc.LDAXR(r.x1.value, r.ip1.value) # load the lock value - self.mc.MOVZ_r_u16(r.ip0.value, 1, 0) self.mc.CMP_ri(r.x1.value, 0) # is the lock free? - if self.asm.cpu.gc_ll_descr.gcrootmap: - jump_val = 0 # XXX - else: - jump_val = 3 * 4 - self.mc.B_ofs_cond(jump_val, c.NE) + + b1_location = self.mc.currpos() + self.mc.BRK() # B.ne to the call + # jump over the next few instructions directly to the call self.mc.STLXR(r.ip0.value, r.ip1.value, r.x1.value) # try to claim the lock self.mc.CMP_wi(r.x1.value, 0) # did this succeed? - self.mc.DMB() # <- previous jump here - self.mc.B_ofs_cond((8 + 4)* 4, c.EQ) # jump over the call - # the success of the lock acquisition is defined by - # 'EQ is true', or equivalently by 'r3 == 0'. + self.mc.DMB() # + + b2_location = self.mc.currpos() + self.mc.BRK() # B.ne to the call + # if self.asm.cpu.gc_ll_descr.gcrootmap: - raise Exception("not implemented yet") # When doing a call_release_gil with shadowstack, there # is the risk that the 'rpy_fastgil' was free but the # current shadowstack can be the one of a different @@ -229,18 +228,26 @@ # in 'x20'), and if not, we fall back to 'reacqgil_addr'. self.mc.LDR_ri(r.ip0.value, r.x19.value, 0) self.mc.CMP_rr(r.ip0.value, r.x20.value) - XXX - b1_location = self.mc.currpos() - self.mc.BKPT() # BEQ below - # there are two cases here: either EQ was false from - # the beginning, or EQ was true at first but the CMP - # made it false. In the second case we need to - # release the fastgil here. We know which case it is - # by checking again r3. - self.mc.CMP_ri(r.r3.value, 0) - self.mc.STR_ri(r.r3.value, r.r6.value, cond=c.EQ) + b3_location = self.mc.currpos() + self.mc.BRK() # B.ne to the call + else: + b3_location = 0 # + + self.mc.B_ofs((4 + 7) * 4) + # <- this is where we jump to + jmp_ofs = self.mc.currpos() + + pmc = OverwritingBuilder(self.mc, b1_location, WORD) + pmc.B_ofs_cond(jmp_ofs - b1_location, c.NE) + pmc = OverwritingBuilder(self.mc, b1_location, WORD) + pmc.B_ofs_cond(jmp_ofs - b2_location, c.NE) + if self.asm.cpu.gc_ll_descr.gcrootmap: + pmc = OverwritingBuilder(self.mc, b1_location, WORD) + pmc.B_ofs_cond(jmp_ofs - b3_location, c.NE) + # save the result we just got + # call reacquire_gil self.mc.SUB_ri(r.sp.value, r.sp.value, 2 * WORD) self.mc.STR_di(r.d0.value, r.sp.value, 0) self.mc.STR_ri(r.x0.value, r.sp.value, WORD) diff --git a/rpython/jit/backend/aarch64/test/test_ztranslation_call_assembler.py b/rpython/jit/backend/aarch64/test/test_ztranslation_call_assembler.py --- a/rpython/jit/backend/aarch64/test/test_ztranslation_call_assembler.py +++ b/rpython/jit/backend/aarch64/test/test_ztranslation_call_assembler.py @@ -12,4 +12,4 @@ class TestTranslationCallAssemblerAarch64(TranslationTestCallAssembler): - pass \ No newline at end of file + pass From pypy.commits at gmail.com Wed Jul 3 03:53:05 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 03 Jul 2019 00:53:05 -0700 (PDT) Subject: [pypy-commit] pypy arm64: merge Message-ID: <5d1c5ee1.1c69fb81.ba6a8.b537@mx.google.com> Author: fijal Branch: arm64 Changeset: r96928:5f279830a34a Date: 2019-07-03 09:52 +0200 http://bitbucket.org/pypy/pypy/changeset/5f279830a34a/ Log: merge diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO --- a/rpython/jit/backend/aarch64/TODO +++ b/rpython/jit/backend/aarch64/TODO @@ -37,3 +37,11 @@ - note that "dmb" only appears sometimes, depending on the exact gcc intrinsic I use. I *think* that it can be safely removed, and so it should be. + + +* malloc_cond() and malloc_cond_varsize_frame() hard-code forward jump + distances by guessing the number of instructions that follows. Bad + idea because some of these instructions could easily be optimized in + the future to be a bit shorter. Rewrite this two places to use the + proper way instead of a magic "40" (or at least assert that it was + really 40). From pypy.commits at gmail.com Wed Jul 3 03:54:29 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 03 Jul 2019 00:54:29 -0700 (PDT) Subject: [pypy-commit] pypy arm64: don't encode magic numbers Message-ID: <5d1c5f35.1c69fb81.f6ea1.46b2@mx.google.com> Author: fijal Branch: arm64 Changeset: r96929:38ea4c7a77e8 Date: 2019-07-03 09:53 +0200 http://bitbucket.org/pypy/pypy/changeset/38ea4c7a77e8/ Log: don't encode magic numbers diff --git a/rpython/jit/backend/aarch64/callbuilder.py b/rpython/jit/backend/aarch64/callbuilder.py --- a/rpython/jit/backend/aarch64/callbuilder.py +++ b/rpython/jit/backend/aarch64/callbuilder.py @@ -234,7 +234,8 @@ b3_location = 0 # - self.mc.B_ofs((4 + 7) * 4) + jmp_pos = self.mc.currpos() + self.mc.BRK() # <- this is where we jump to jmp_ofs = self.mc.currpos() @@ -256,6 +257,9 @@ self.mc.LDR_ri(r.x0.value, r.sp.value, WORD) self.mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) + pmc = OverwritingBuilder(self.mc, jmp_pos, WORD) + pmc.B_ofs(self.mc.currpos() - jmp_pos, c.NE) + if not we_are_translated(): # for testing: now we can accesss self.mc.SUB_ri(r.fp.value, r.fp.value, 1) # fp again From pypy.commits at gmail.com Wed Jul 3 03:59:07 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 03 Jul 2019 00:59:07 -0700 (PDT) Subject: [pypy-commit] pypy arm64: (arigo) Message-ID: <5d1c604b.1c69fb81.ac1cf.f901@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96930:c13e72242f19 Date: 2019-07-03 07:58 +0000 http://bitbucket.org/pypy/pypy/changeset/c13e72242f19/ Log: (arigo) Add the newer synchronization instructions to use diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -411,11 +411,25 @@ base = 0b11101010000 self.write32((base << 21) | (rm << 16) | (shift << 10) | (rn << 5) | 0b11111) + def STLR(self, rt, rn): + base = 0b11001000100 + self.write32((base << 21) | (0b11111 << 16) | (0b111111 << 10) | (rn << 5) | rt) + + def LDXR(self, rt, rn): + base = 0b1100100001011111011111 + self.write32((base << 10) | (rn << 5) | rt) + + def STXR(self, rs, rt, rn): + base = 0b11001000000 + self.write32((base << 21) | (rs << 16) | (0b011111 << 10) | (rn << 5) | rt) + def LDAXR(self, rt, rn): + # XXX DON'T USE base = 0b1100100001011111111111 self.write32((base << 10) | (rn << 5) | rt) def STLXR(self, rt, rn, rs): + # XXX DON'T USE base = 0b11001000000 self.write32((base << 21) | (rs << 16) | (0b111111 << 10) | (rn << 5) | rt) @@ -463,6 +477,7 @@ self.write32(0b11010100001 << 21) def DMB(self): + # XXX DON'T USE self.write32(0b11010101000000110011111110111111) def gen_load_int_full(self, r, value): diff --git a/rpython/jit/backend/aarch64/test/test_instr_builder.py b/rpython/jit/backend/aarch64/test/test_instr_builder.py --- a/rpython/jit/backend/aarch64/test/test_instr_builder.py +++ b/rpython/jit/backend/aarch64/test/test_instr_builder.py @@ -157,3 +157,18 @@ cb = CodeBuilder() cb.BRK() assert cb.hexdump() == assemble("BRK 0") + + def test_STLR(self): + cb = CodeBuilder() + cb.STLR(r.x11.value, r.x22.value) + assert cb.hexdump() == assemble("STLR x11, [x22]") + + def test_LDXR(self): + cb = CodeBuilder() + cb.LDXR(r.x11.value, r.x22.value) + assert cb.hexdump() == assemble("LDXR x11, [x22]") + + def test_STXR(self): + cb = CodeBuilder() + cb.STXR(r.x6.value, r.x11.value, r.x22.value) + assert cb.hexdump() == assemble("STXR w6, x11, [x22]") From pypy.commits at gmail.com Wed Jul 3 03:59:39 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 03 Jul 2019 00:59:39 -0700 (PDT) Subject: [pypy-commit] pypy arm64: fixes Message-ID: <5d1c606b.1c69fb81.fd44.79e8@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96931:1acfb96abd34 Date: 2019-07-03 07:59 +0000 http://bitbucket.org/pypy/pypy/changeset/1acfb96abd34/ Log: fixes diff --git a/rpython/jit/backend/aarch64/callbuilder.py b/rpython/jit/backend/aarch64/callbuilder.py --- a/rpython/jit/backend/aarch64/callbuilder.py +++ b/rpython/jit/backend/aarch64/callbuilder.py @@ -241,10 +241,10 @@ pmc = OverwritingBuilder(self.mc, b1_location, WORD) pmc.B_ofs_cond(jmp_ofs - b1_location, c.NE) - pmc = OverwritingBuilder(self.mc, b1_location, WORD) + pmc = OverwritingBuilder(self.mc, b2_location, WORD) pmc.B_ofs_cond(jmp_ofs - b2_location, c.NE) if self.asm.cpu.gc_ll_descr.gcrootmap: - pmc = OverwritingBuilder(self.mc, b1_location, WORD) + pmc = OverwritingBuilder(self.mc, b3_location, WORD) pmc.B_ofs_cond(jmp_ofs - b3_location, c.NE) # save the result we just got @@ -258,7 +258,7 @@ self.mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) pmc = OverwritingBuilder(self.mc, jmp_pos, WORD) - pmc.B_ofs(self.mc.currpos() - jmp_pos, c.NE) + pmc.B_ofs(self.mc.currpos() - jmp_pos) if not we_are_translated(): # for testing: now we can accesss self.mc.SUB_ri(r.fp.value, r.fp.value, 1) # fp again From pypy.commits at gmail.com Wed Jul 3 04:03:21 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 03 Jul 2019 01:03:21 -0700 (PDT) Subject: [pypy-commit] pypy arm64: remove a refcount test and add a release gil zrpy test Message-ID: <5d1c6149.1c69fb81.82012.b467@mx.google.com> Author: fijal Branch: arm64 Changeset: r96932:564128af831e Date: 2019-07-03 10:02 +0200 http://bitbucket.org/pypy/pypy/changeset/564128af831e/ Log: remove a refcount test and add a release gil zrpy test diff --git a/rpython/jit/backend/aarch64/test/test_zrpy_releasegil.py b/rpython/jit/backend/aarch64/test/test_zrpy_releasegil.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/aarch64/test/test_zrpy_releasegil.py @@ -0,0 +1,5 @@ +from rpython.jit.backend.llsupport.test.zrpy_releasegil_test import ReleaseGILTests + + +class TestShadowStack(ReleaseGILTests): + gcrootfinder = "shadowstack" diff --git a/rpython/jit/backend/aarch64/test/test_ztranslation_external_exception.py b/rpython/jit/backend/aarch64/test/test_ztranslation_external_exception.py deleted file mode 100644 --- a/rpython/jit/backend/aarch64/test/test_ztranslation_external_exception.py +++ /dev/null @@ -1,9 +0,0 @@ -from rpython.jit.backend.llsupport.test.ztranslation_test import TranslationRemoveTypePtrTest -from rpython.translator.translator import TranslationContext - -class TestTranslationRemoveTypePtrAarch64(TranslationRemoveTypePtrTest): - def _get_TranslationContext(self): - t = TranslationContext() - t.config.translation.list_comprehension_operations = True - t.config.translation.gcremovetypeptr = True - return t From pypy.commits at gmail.com Wed Jul 3 05:26:59 2019 From: pypy.commits at gmail.com (arigo) Date: Wed, 03 Jul 2019 02:26:59 -0700 (PDT) Subject: [pypy-commit] pypy default: Backed out changeset ed056c08b76f Message-ID: <5d1c74e3.1c69fb81.9dfcc.9a1b@mx.google.com> Author: Armin Rigo Branch: Changeset: r96933:e394c7fa2106 Date: 2019-07-03 11:26 +0200 http://bitbucket.org/pypy/pypy/changeset/e394c7fa2106/ Log: Backed out changeset ed056c08b76f It fails for reasons that I cannot understand at all 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 @@ -532,26 +532,22 @@ def gen_shadowstack_header(self, gcrootmap): # lr = shadow stack top addr - # r4 = *lr + # ip = *lr rst = gcrootmap.get_root_stack_top_addr() self.mc.gen_load_int(r.lr.value, rst) - self.load_reg(self.mc, r.r4, r.lr) - # *r4 = 1 - # the '1' is to benefit from the shadowstack 'is_minor' optimization - self.mc.gen_load_int(r.ip.value, 1) - self.store_reg(self.mc, r.ip, r.r4) - # *(r4+WORD) = r.fp - self.store_reg(self.mc, r.fp, r.r4, WORD) + self.load_reg(self.mc, r.ip, r.lr) + # *ip = r.fp + self.store_reg(self.mc, r.fp, r.ip) # - self.mc.ADD_ri(r.r4.value, r.r4.value, 2 * WORD) - # *lr = r4 + 2 * WORD - self.store_reg(self.mc, r.r4, r.lr) + self.mc.ADD_ri(r.ip.value, r.ip.value, WORD) + # *lr = ip + WORD + self.store_reg(self.mc, r.ip, r.lr) def gen_footer_shadowstack(self, gcrootmap, mc): rst = gcrootmap.get_root_stack_top_addr() mc.gen_load_int(r.ip.value, rst) self.load_reg(mc, r.r4, r.ip) - mc.SUB_ri(r.r4.value, r.r4.value, 2 * WORD) + mc.SUB_ri(r.r4.value, r.r4.value, WORD) self.store_reg(mc, r.r4, r.ip) def _dump(self, ops, type='loop'): From pypy.commits at gmail.com Wed Jul 3 06:02:42 2019 From: pypy.commits at gmail.com (arigo) Date: Wed, 03 Jul 2019 03:02:42 -0700 (PDT) Subject: [pypy-commit] pypy arm64: Optimize call_release_gil (and fix a wrong detail I think) Message-ID: <5d1c7d42.1c69fb81.91bc5.a2ba@mx.google.com> Author: Armin Rigo Branch: arm64 Changeset: r96934:ecd3b6d0775b Date: 2019-07-03 10:02 +0000 http://bitbucket.org/pypy/pypy/changeset/ecd3b6d0775b/ Log: Optimize call_release_gil (and fix a wrong detail I think) diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO --- a/rpython/jit/backend/aarch64/TODO +++ b/rpython/jit/backend/aarch64/TODO @@ -45,3 +45,15 @@ the future to be a bit shorter. Rewrite this two places to use the proper way instead of a magic "40" (or at least assert that it was really 40). + + +* use "CBNZ register, offset" (compare-and-branch-if-not-zero) + instead of a CMP+BNE pair. Same with CBZ instead of CMP+BEQ + + +* when we need to save things on the stack, we typically push two words + and pop them later. It would be cheaper if we reserved two locations + in the stack from _call_header, then we could just write there. + *OR* + maybe it's enough if we use the form "str x0, [sp, !#offset]" which + combines in a single instruction the "str" with the change of sp diff --git a/rpython/jit/backend/aarch64/callbuilder.py b/rpython/jit/backend/aarch64/callbuilder.py --- a/rpython/jit/backend/aarch64/callbuilder.py +++ b/rpython/jit/backend/aarch64/callbuilder.py @@ -138,19 +138,19 @@ def call_releasegil_addr_and_move_real_arguments(self, fastgil): assert self.is_call_release_gil assert not self.asm._is_asmgcc() + RFASTGILPTR = r.x19 # constant &rpy_fastgil + RSHADOWOLD = r.x20 # old value of the shadowstack pointer, + # which we save here for later comparison - # Save this thread's shadowstack pointer into r7, for later comparison gcrootmap = self.asm.cpu.gc_ll_descr.gcrootmap if gcrootmap: rst = gcrootmap.get_root_stack_top_addr() - self.mc.gen_load_int(r.x19.value, rst) - self.mc.LDR_ri(r.x20.value, r.x19.value, 0) + self.mc.gen_load_int(r.ip1.value, rst) + self.mc.LDR_ri(RSHADOWOLD.value, r.ip1.value, 0) # change 'rpy_fastgil' to 0 (it should be non-zero right now) - self.mc.DMB() - self.mc.gen_load_int(r.ip1.value, fastgil) - self.mc.MOVZ_r_u16(r.ip0.value, 0, 0) - self.mc.STR_ri(r.ip0.value, r.ip1.value, 0) + self.mc.gen_load_int(RFASTGILPTR.value, fastgil) + self.mc.STLR(r.xzr.value, RFASTGILPTR.value) if not we_are_translated(): # for testing: we should not access self.mc.ADD_ri(r.fp.value, r.fp.value, 1) # fp any more @@ -199,66 +199,82 @@ self.mc.STR_ri(r.ip0.value, r.x3.value, rpy_errno) def move_real_result_and_call_reacqgil_addr(self, fastgil): - # try to reacquire the lock. - # x19 == &root_stack_top - # x20 == previous value of root_stack_top - self.mc.gen_load_int(r.ip1.value, fastgil) - self.mc.LDAXR(r.x1.value, r.ip1.value) # load the lock value - self.mc.CMP_ri(r.x1.value, 0) # is the lock free? + # try to reacquire the lock. The following two values are saved + # across the call and are still alive now: + RFASTGILPTR = r.x19 # constant &rpy_fastgil + RSHADOWOLD = r.x20 # old value of the shadowstack pointer + + # this comes from gcc compiling this code: + # while (__atomic_test_and_set(&lock, __ATOMIC_ACQUIRE)) + # ; + self.mc.gen_load_int(r.x2.value, 1) + self.mc.LDXR(r.x1.value, RFASTGILPTR.value) + self.mc.STXR(r.x3.value, r.x2.value, RFASTGILPTR.value) + self.mc.CBNZ_w(r.x3.value, -8) + # now x1 is the old value of the lock, and the lock contains 1 b1_location = self.mc.currpos() - self.mc.BRK() # B.ne to the call + self.mc.BRK() # boehm: patched with a CBZ (jump if x1 == 0) + # shadowstack: patched with CBNZ instead - # jump over the next few instructions directly to the call - self.mc.STLXR(r.ip0.value, r.ip1.value, r.x1.value) - # try to claim the lock - self.mc.CMP_wi(r.x1.value, 0) # did this succeed? - self.mc.DMB() # - - b2_location = self.mc.currpos() - self.mc.BRK() # B.ne to the call - - # - if self.asm.cpu.gc_ll_descr.gcrootmap: + gcrootmap = self.asm.cpu.gc_ll_descr.gcrootmap + if gcrootmap: # When doing a call_release_gil with shadowstack, there # is the risk that the 'rpy_fastgil' was free but the # current shadowstack can be the one of a different # thread. So here we check if the shadowstack pointer # is still the same as before we released the GIL (saved # in 'x20'), and if not, we fall back to 'reacqgil_addr'. - self.mc.LDR_ri(r.ip0.value, r.x19.value, 0) - self.mc.CMP_rr(r.ip0.value, r.x20.value) + rst = gcrootmap.get_root_stack_top_addr() + self.mc.gen_load_int(r.ip1.value, rst) + self.mc.LDR_ri(r.ip0.value, r.ip1.value, 0) # new shadowstack + self.mc.CMP_rr(r.ip0.value, RSHADOWOLD.value) b3_location = self.mc.currpos() - self.mc.BRK() # B.ne to the call + self.mc.BRK() # B.eq forward + + # revert the rpy_fastgil acquired above, so that the + # general 'reacqgil_addr' below can acquire it again... + self.mc.STR_ri(r.xzr.value, RFASTGILPTR.value, 0) + + # patch the b1_location above, with "CBNZ here" + pmc = OverwritingBuilder(self.mc, b1_location, WORD) + pmc.CBNZ(r.x1.value, self.mc.currpos() - b1_location) + + open_location = b3_location else: - b3_location = 0 - # + open_location = b1_location - jmp_pos = self.mc.currpos() - self.mc.BRK() - # <- this is where we jump to - jmp_ofs = self.mc.currpos() + # Yes, we need to call the reacqgil() function. + # save the result we just got + RSAVEDRES = RFASTGILPTR # can reuse this reg here to save things + reg = self.resloc + if reg is not None: + if reg.is_core_reg(): + self.mc.MOV_rr(RSAVEDRES.value, reg.value) + elif reg.is_vfp_reg(): + self.mc.SUB_ri(r.sp.value, r.sp.value, 2 * WORD) + self.mc.STR_di(reg.value, r.sp.value, 0) - pmc = OverwritingBuilder(self.mc, b1_location, WORD) - pmc.B_ofs_cond(jmp_ofs - b1_location, c.NE) - pmc = OverwritingBuilder(self.mc, b2_location, WORD) - pmc.B_ofs_cond(jmp_ofs - b2_location, c.NE) - if self.asm.cpu.gc_ll_descr.gcrootmap: - pmc = OverwritingBuilder(self.mc, b3_location, WORD) - pmc.B_ofs_cond(jmp_ofs - b3_location, c.NE) + # call the function + self.mc.BL(self.asm.reacqgil_addr) - # save the result we just got - # call reacquire_gil - self.mc.SUB_ri(r.sp.value, r.sp.value, 2 * WORD) - self.mc.STR_di(r.d0.value, r.sp.value, 0) - self.mc.STR_ri(r.x0.value, r.sp.value, WORD) - self.mc.BL(self.asm.reacqgil_addr) - self.mc.LDR_di(r.d0.value, r.sp.value, 0) - self.mc.LDR_ri(r.x0.value, r.sp.value, WORD) - self.mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) + # restore the saved register + if reg is not None: + if reg.is_core_reg(): + self.mc.MOV_rr(reg.value, RSAVEDRES.value) + elif reg.is_vfp_reg(): + self.mc.LDR_di(reg.value, r.sp.value, 0) + self.mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) - pmc = OverwritingBuilder(self.mc, jmp_pos, WORD) - pmc.B_ofs(self.mc.currpos() - jmp_pos) + # now patch the still-open jump above: + # boehm: patch b1_location with a CBZ(x1) + # shadowstack: patch b3_location with BEQ + pmc = OverwritingBuilder(self.mc, open_location, WORD) + offset = self.mc.currpos() - open_location + if gcrootmap: + pmc.B_ofs_cond(offset, c.EQ) + else: + pmc.CBZ(r.x1.value, offset) if not we_are_translated(): # for testing: now we can accesss self.mc.SUB_ri(r.fp.value, r.fp.value, 1) # fp again diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py --- a/rpython/jit/backend/aarch64/codebuilder.py +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -423,15 +423,15 @@ base = 0b11001000000 self.write32((base << 21) | (rs << 16) | (0b011111 << 10) | (rn << 5) | rt) - def LDAXR(self, rt, rn): - # XXX DON'T USE - base = 0b1100100001011111111111 - self.write32((base << 10) | (rn << 5) | rt) + #def LDAXR(self, rt, rn): + # don't use any more + # base = 0b1100100001011111111111 + # self.write32((base << 10) | (rn << 5) | rt) - def STLXR(self, rt, rn, rs): - # XXX DON'T USE - base = 0b11001000000 - self.write32((base << 21) | (rs << 16) | (0b111111 << 10) | (rn << 5) | rt) + #def STLXR(self, rt, rn, rs): + # don't use any more + # base = 0b11001000000 + # self.write32((base << 21) | (rs << 16) | (0b111111 << 10) | (rn << 5) | rt) def NOP(self): self.write32(0b11010101000000110010000000011111) @@ -439,7 +439,7 @@ def B_ofs(self, ofs): base = 0b000101 assert ofs & 0x3 == 0 - assert -(1 << (26 + 2)) < ofs < 1<<(26 + 2) + assert -(1 << (26 + 2)) <= ofs < 1<<(26 + 2) if ofs < 0: ofs = (1 << 26) - (-ofs >> 2) else: @@ -449,11 +449,33 @@ def B_ofs_cond(self, ofs, cond): base = 0b01010100 assert ofs & 0x3 == 0 - assert -1 << 21 < ofs < 1 << 21 + assert -1 << 21 <= ofs < 1 << 21 imm = ofs >> 2 assert imm > 0 # we seem not to need the - jump self.write32((base << 24) | (imm << 5) | cond) + def CBNZ(self, rt, ofs): + base = 0b10110101 + assert -1 << 21 <= ofs < 1 << 21 + imm = ofs >> 2 + imm &= (1 << 19) - 1 + self.write32((base << 24) | (imm << 5) | rt) + + def CBNZ_w(self, rt, ofs): + # checks the 'w' part of the register (32 bits) + base = 0b00110101 + assert -1 << 21 <= ofs < 1 << 21 + imm = ofs >> 2 + imm &= (1 << 19) - 1 + self.write32((base << 24) | (imm << 5) | rt) + + def CBZ(self, rt, ofs): + base = 0b10110100 + assert -1 << 21 <= ofs < 1 << 21 + imm = ofs >> 2 + imm &= (1 << 19) - 1 + self.write32((base << 24) | (imm << 5) | rt) + def B(self, target): target = rffi.cast(lltype.Signed, target) self.gen_load_int_full(r.ip0.value, target) @@ -476,9 +498,9 @@ def BRK(self): self.write32(0b11010100001 << 21) - def DMB(self): - # XXX DON'T USE - self.write32(0b11010101000000110011111110111111) + #def DMB(self): + # don't use any more + # self.write32(0b11010101000000110011111110111111) def gen_load_int_full(self, r, value): self.MOVZ_r_u16(r, value & 0xFFFF, 0) diff --git a/rpython/jit/backend/aarch64/test/test_instr_builder.py b/rpython/jit/backend/aarch64/test/test_instr_builder.py --- a/rpython/jit/backend/aarch64/test/test_instr_builder.py +++ b/rpython/jit/backend/aarch64/test/test_instr_builder.py @@ -172,3 +172,18 @@ cb = CodeBuilder() cb.STXR(r.x6.value, r.x11.value, r.x22.value) assert cb.hexdump() == assemble("STXR w6, x11, [x22]") + + def test_CBNZ(self): + cb = CodeBuilder() + cb.CBNZ(r.x6.value, -8) + assert cb.hexdump() == assemble("CBNZ x6, -8") + + def test_CBNZ_w(self): + cb = CodeBuilder() + cb.CBNZ_w(r.x6.value, -8) + assert cb.hexdump() == assemble("CBNZ w6, -8") + + def test_CBZ(self): + cb = CodeBuilder() + cb.CBZ(r.x25.value, -888) + assert cb.hexdump() == assemble("CBZ x25, -888") From pypy.commits at gmail.com Wed Jul 3 06:15:57 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 03 Jul 2019 03:15:57 -0700 (PDT) Subject: [pypy-commit] pypy arm64: fix Message-ID: <5d1c805d.1c69fb81.204cc.231b@mx.google.com> Author: Maciej Fijalkowski Branch: arm64 Changeset: r96935:2f5fcf2a36d4 Date: 2019-07-03 10:15 +0000 http://bitbucket.org/pypy/pypy/changeset/2f5fcf2a36d4/ Log: fix diff --git a/rpython/jit/backend/detect_cpu.py b/rpython/jit/backend/detect_cpu.py --- a/rpython/jit/backend/detect_cpu.py +++ b/rpython/jit/backend/detect_cpu.py @@ -146,6 +146,7 @@ MODEL_X86_NO_SSE2: ['longlong'], MODEL_X86_64: ['floats', 'singlefloats'], MODEL_ARM: ['floats', 'singlefloats', 'longlong'], + MODEL_ARM64: ['floats'], MODEL_PPC_64: ['floats'], MODEL_S390_64: ['floats'], }[backend_name] From pypy.commits at gmail.com Wed Jul 3 10:32:55 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 03 Jul 2019 07:32:55 -0700 (PDT) Subject: [pypy-commit] pypy arm64: fix Message-ID: <5d1cbc97.1c69fb81.f85a6.9874@mx.google.com> Author: fijal Branch: arm64 Changeset: r96938:3a6979dda07b Date: 2019-07-03 16:32 +0200 http://bitbucket.org/pypy/pypy/changeset/3a6979dda07b/ Log: fix diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -593,7 +593,7 @@ # Note that the typeid half-word is at offset 0 on a little-endian # machine; it would be at offset 2 or 4 on a big-endian machine. assert self.cpu.supports_guard_gc_type - self.mc.LDRH_ri(r.ip0.value, loc_ptr.value) + self.mc.LDRH_ri(r.ip0.value, loc_ptr.value, 0) self.mc.gen_load_int(r.ip1.value, expected_typeid) self.mc.CMP_rr(r.ip0.value, r.ip1.value) From pypy.commits at gmail.com Wed Jul 3 11:14:07 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 03 Jul 2019 08:14:07 -0700 (PDT) Subject: [pypy-commit] pypy arm64: missing bits maybe Message-ID: <5d1cc63f.1c69fb81.53490.370d@mx.google.com> Author: fijal Branch: arm64 Changeset: r96939:bec4fcbdada0 Date: 2019-07-03 17:13 +0200 http://bitbucket.org/pypy/pypy/changeset/bec4fcbdada0/ Log: missing bits maybe diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -2,6 +2,7 @@ from rpython.rlib.objectmodel import we_are_translated from rpython.rlib.rarithmetic import r_uint from rpython.rtyper.lltypesystem import rffi, lltype +from rpython.rtyper import rclass from rpython.jit.metainterp.history import (AbstractFailDescr, ConstInt, INT, FLOAT, REF, VOID) from rpython.jit.backend.aarch64 import registers as r @@ -623,6 +624,70 @@ self._cmp_guard_gc_type(arglocs[0], arglocs[1].value) self._emit_guard(op, c.EQ, arglocs[2:]) + def emit_op_guard_is_object(self, op, arglocs): + assert self.cpu.supports_guard_gc_type + loc_object = arglocs[0] + # idea: read the typeid, fetch one byte of the field 'infobits' from + # the big typeinfo table, and check the flag 'T_IS_RPYTHON_INSTANCE'. + self.mc.LDRH_ri(r.ip0.value, loc_object.value, 0) + # + + base_type_info, shift_by, sizeof_ti = ( + self.cpu.gc_ll_descr.get_translated_info_for_typeinfo()) + infobits_offset, IS_OBJECT_FLAG = ( + self.cpu.gc_ll_descr.get_translated_info_for_guard_is_object()) + + self.mc.gen_load_int(r.ip1.value, base_type_info + infobits_offset) + if shift_by > 0: + self.mc.LSL_ri(r.ip0.value, r.ip0.value, shift_by) + self.mc.LDRB_rr(r.ip0.value, r.ip0.value, r.ip1.value) + self.mc.MOVZ_r_u16(r.ip1.value, IS_OBJECT_FLAG & 0xff, 0) + self.mc.TST_rr_shift(r.ip0.value, r.ip1.value, 0) + self._emit_guard(op, c.NE, arglocs[1:]) + + def emit_op_guard_subclass(self, op, arglocs): + assert self.cpu.supports_guard_gc_type + loc_object = arglocs[0] + loc_check_against_class = arglocs[1] + offset = self.cpu.vtable_offset + offset2 = self.cpu.subclassrange_min_offset + if offset is not None: + # read this field to get the vtable pointer + self.mc.LDR_ri(r.ip0.value, loc_object.value, offset) + # read the vtable's subclassrange_min field + self.mc.LDR_ri(r.ip0.value, r.ip0.value, offset2) + else: + # read the typeid + self.mc.LDRH_ri(r.ip0.value, loc_object.value, 0) + # read the vtable's subclassrange_min field, as a single + # step with the correct offset + base_type_info, shift_by, sizeof_ti = ( + self.cpu.gc_ll_descr.get_translated_info_for_typeinfo()) + + self.mc.gen_load_int(r.ip1.value, + base_type_info + sizeof_ti + offset2) + if shift_by > 0: + self.mc.LSL_ri(r.ip0.value, r.ip0.value, shift_by) + self.mc.LDR_rr(r.ip0.value, r.ip0.value, r.ip1.value) + + # get the two bounds to check against + vtable_ptr = loc_check_against_class.getint() + vtable_ptr = rffi.cast(rclass.CLASSTYPE, vtable_ptr) + check_min = vtable_ptr.subclassrange_min + check_max = vtable_ptr.subclassrange_max + assert check_max > check_min + check_diff = check_max - check_min - 1 + # check by doing the unsigned comparison (tmp - min) < (max - min) + self.mc.gen_load_int(r.ip1.value, check_min) + self.mc.SUB_rr(r.ip0.value, r.ip0.value, r.ip1.value) + if check_diff <= 0xff: + self.mc.CMP_ri(r.ip0.value, check_diff) + else: + self.mc.gen_load_int(r.ip1.value, check_diff) + self.mc.CMP_rr(r.ip0.value, r.ip1.value) + # the guard passes if we get a result of "below or equal" + self._emit_guard(op, c.LS, arglocs[2:]) + def emit_op_guard_exception(self, op, arglocs): loc, resloc, pos_exc_value, pos_exception = arglocs[:4] failargs = arglocs[4:] diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -829,6 +829,10 @@ prepare_op_guard_gc_type = prepare_op_guard_class prepare_op_guard_subclass = prepare_op_guard_class + def prepare_op_guard_is_object(self, op, fcond): + loc_object = self.make_sure_var_in_reg(op.getarg(0)) + return [loc_object] + self._guard_impl(op) + def prepare_op_guard_not_invalidated(self, op): return self._guard_impl(op) From pypy.commits at gmail.com Wed Jul 3 11:15:58 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 03 Jul 2019 08:15:58 -0700 (PDT) Subject: [pypy-commit] pypy arm64: fix Message-ID: <5d1cc6ae.1c69fb81.33211.f561@mx.google.com> Author: fijal Branch: arm64 Changeset: r96940:631e17507546 Date: 2019-07-03 17:14 +0200 http://bitbucket.org/pypy/pypy/changeset/631e17507546/ Log: fix diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -829,7 +829,7 @@ prepare_op_guard_gc_type = prepare_op_guard_class prepare_op_guard_subclass = prepare_op_guard_class - def prepare_op_guard_is_object(self, op, fcond): + def prepare_op_guard_is_object(self, op): loc_object = self.make_sure_var_in_reg(op.getarg(0)) return [loc_object] + self._guard_impl(op) From pypy.commits at gmail.com Wed Jul 3 12:28:47 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 03 Jul 2019 09:28:47 -0700 (PDT) Subject: [pypy-commit] pypy arm64: argh. means it's completely untested I fear Message-ID: <5d1cd7bf.1c69fb81.3fbcc.0c6e@mx.google.com> Author: fijal Branch: arm64 Changeset: r96941:17610251267d Date: 2019-07-03 18:28 +0200 http://bitbucket.org/pypy/pypy/changeset/17610251267d/ Log: argh. means it's completely untested I fear diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -618,7 +618,7 @@ expected_typeid = (self.cpu.gc_ll_descr .get_typeid_from_classptr_if_gcremovetypeptr(arglocs[1].value)) self._cmp_guard_gc_type(arglocs[0], expected_typeid) - self._emit_guard(op, c.EQ, arglocs[2:], extra_offset, c.NE) + self._emit_guard(op, c.EQ, arglocs[2:], False, extra_offset, c.NE) def emit_op_guard_gc_type(self, op, arglocs): self._cmp_guard_gc_type(arglocs[0], arglocs[1].value) From pypy.commits at gmail.com Wed Jul 3 12:31:47 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 03 Jul 2019 09:31:47 -0700 (PDT) Subject: [pypy-commit] pypy arm64: try to test guard_nonnull_class Message-ID: <5d1cd873.1c69fb81.7c32d.52bc@mx.google.com> Author: fijal Branch: arm64 Changeset: r96942:5c1c80752f24 Date: 2019-07-03 18:31 +0200 http://bitbucket.org/pypy/pypy/changeset/5c1c80752f24/ Log: try to test guard_nonnull_class diff --git a/rpython/jit/backend/llsupport/test/test_zrpy_gc_direct.py b/rpython/jit/backend/llsupport/test/test_zrpy_gc_direct.py --- a/rpython/jit/backend/llsupport/test/test_zrpy_gc_direct.py +++ b/rpython/jit/backend/llsupport/test/test_zrpy_gc_direct.py @@ -66,6 +66,14 @@ 'faildescr': faildescr, 'vtable_B': vtable_B}) + loop1a = parse(""" + [p0] + guard_class(p0, ConstInt(vtable_B), descr=faildescr) [] + finish(descr=finaldescr) + """, namespace={'finaldescr': finaldescr, + 'faildescr': faildescr, + 'vtable_B': vtable_B}) + loop2 = parse(""" [p0] guard_gc_type(p0, ConstInt(typeid_B), descr=faildescr) [] @@ -92,10 +100,12 @@ def g(): cpu.setup_once() token1 = JitCellToken() + token1a = JitCellToken() token2 = JitCellToken() token3 = JitCellToken() token4 = JitCellToken() cpu.compile_loop(loop1.inputargs, loop1.operations, token1) + cpu.compile_loop(loop1a.inputargs, loop1a.operations, token1a) cpu.compile_loop(loop2.inputargs, loop2.operations, token2) cpu.compile_loop(loop3.inputargs, loop3.operations, token3) cpu.compile_loop(loop4.inputargs, loop4.operations, token4) @@ -105,6 +115,11 @@ (token1, rffi.cast(llmemory.GCREF, B())), (token1, rffi.cast(llmemory.GCREF, C())), + (token1a, rffi.cast(llmemory.GCREF, A())), + (token1a, lltype.nullptr(llmemory.GCREF.TO)), + (token1a, rffi.cast(llmemory.GCREF, B())), + (token1a, rffi.cast(llmemory.GCREF, C())), + (token2, rffi.cast(llmemory.GCREF, A())), (token2, rffi.cast(llmemory.GCREF, B())), (token2, rffi.cast(llmemory.GCREF, C())), @@ -175,6 +190,11 @@ 'match\n' 'fail\n' + 'fail\n' + 'fail\n' + 'match\n' + 'fail\n' + 'fail\n' '0\n' 'match\n' '1\n' 'fail\n' '0\n' From pypy.commits at gmail.com Wed Jul 3 12:36:27 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 03 Jul 2019 09:36:27 -0700 (PDT) Subject: [pypy-commit] pypy arm64: oops Message-ID: <5d1cd98b.1c69fb81.3751d.431f@mx.google.com> Author: fijal Branch: arm64 Changeset: r96943:2fd129b4699f Date: 2019-07-03 18:35 +0200 http://bitbucket.org/pypy/pypy/changeset/2fd129b4699f/ Log: oops diff --git a/rpython/jit/backend/llsupport/test/test_zrpy_gc_direct.py b/rpython/jit/backend/llsupport/test/test_zrpy_gc_direct.py --- a/rpython/jit/backend/llsupport/test/test_zrpy_gc_direct.py +++ b/rpython/jit/backend/llsupport/test/test_zrpy_gc_direct.py @@ -68,7 +68,7 @@ loop1a = parse(""" [p0] - guard_class(p0, ConstInt(vtable_B), descr=faildescr) [] + guard_nonnull_class(p0, ConstInt(vtable_B), descr=faildescr) [] finish(descr=finaldescr) """, namespace={'finaldescr': finaldescr, 'faildescr': faildescr, From pypy.commits at gmail.com Thu Jul 4 04:01:08 2019 From: pypy.commits at gmail.com (fijal) Date: Thu, 04 Jul 2019 01:01:08 -0700 (PDT) Subject: [pypy-commit] pypy arm64: I think fix the loading of TID Message-ID: <5d1db244.1c69fb81.9a54.430e@mx.google.com> Author: fijal Branch: arm64 Changeset: r96944:ba8b89938369 Date: 2019-07-04 10:00 +0200 http://bitbucket.org/pypy/pypy/changeset/ba8b89938369/ Log: I think fix the loading of TID diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -594,7 +594,7 @@ # Note that the typeid half-word is at offset 0 on a little-endian # machine; it would be at offset 2 or 4 on a big-endian machine. assert self.cpu.supports_guard_gc_type - self.mc.LDRH_ri(r.ip0.value, loc_ptr.value, 0) + self.mc.LDR_uint32_ri(r.ip0.value, loc_ptr.value, 0) self.mc.gen_load_int(r.ip1.value, expected_typeid) self.mc.CMP_rr(r.ip0.value, r.ip1.value) @@ -629,7 +629,7 @@ loc_object = arglocs[0] # idea: read the typeid, fetch one byte of the field 'infobits' from # the big typeinfo table, and check the flag 'T_IS_RPYTHON_INSTANCE'. - self.mc.LDRH_ri(r.ip0.value, loc_object.value, 0) + self.mc.LDR_uint32_ri(r.ip0.value, loc_object.value, 0) # base_type_info, shift_by, sizeof_ti = ( @@ -658,7 +658,7 @@ self.mc.LDR_ri(r.ip0.value, r.ip0.value, offset2) else: # read the typeid - self.mc.LDRH_ri(r.ip0.value, loc_object.value, 0) + self.mc.LDR_uint32_ri(r.ip0.value, loc_object.value, 0) # read the vtable's subclassrange_min field, as a single # step with the correct offset base_type_info, shift_by, sizeof_ti = ( From pypy.commits at gmail.com Thu Jul 4 06:28:30 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 04 Jul 2019 03:28:30 -0700 (PDT) Subject: [pypy-commit] pypy arm64: probable fix (untested) Message-ID: <5d1dd4ce.1c69fb81.ef18c.5403@mx.google.com> Author: Armin Rigo Branch: arm64 Changeset: r96945:aaf0d2d39b30 Date: 2019-07-04 12:27 +0200 http://bitbucket.org/pypy/pypy/changeset/aaf0d2d39b30/ Log: probable fix (untested) diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -1091,7 +1091,7 @@ if box.type == REF and self.rm.is_still_alive(box): assert not noregs assert loc.is_core_reg() - val = loc.value + val = self.cpu.all_reg_indexes[loc.value] gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) for box, loc in self.fm.bindings.iteritems(): if box.type == REF and self.rm.is_still_alive(box): @@ -1137,4 +1137,4 @@ if hasattr(Regalloc, methname): func = getattr(Regalloc, methname).im_func comp_operations[value] = func - \ No newline at end of file + From pypy.commits at gmail.com Thu Jul 4 06:33:55 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 04 Jul 2019 03:33:55 -0700 (PDT) Subject: [pypy-commit] pypy default: Add a comment in case somebody else copies get_gcmap() from the arm backend Message-ID: <5d1dd613.1c69fb81.cbb98.b726@mx.google.com> Author: Armin Rigo Branch: Changeset: r96946:589aba948fbb Date: 2019-07-04 12:33 +0200 http://bitbucket.org/pypy/pypy/changeset/589aba948fbb/ Log: Add a comment in case somebody else copies get_gcmap() from the arm backend 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 @@ -373,6 +373,10 @@ if box.type == REF and self.rm.is_still_alive(box): assert not noregs assert loc.is_core_reg() + #val = self.cpu.all_reg_indexes[loc.value] + # ^^^ That is the correct way to write it down, but as a + # special case in the arm backend only, this is equivalent + # to just the line below: val = loc.value gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) for box, loc in self.fm.bindings.iteritems(): From pypy.commits at gmail.com Thu Jul 4 10:14:33 2019 From: pypy.commits at gmail.com (stevie_92) Date: Thu, 04 Jul 2019 07:14:33 -0700 (PDT) Subject: [pypy-commit] pypy cpyext-gc-cycle: Fixed some issues with rrc finalizers Message-ID: <5d1e09c9.1c69fb81.82012.3225@mx.google.com> Author: Stefan Beyer Branch: cpyext-gc-cycle Changeset: r96947:b048d08d615e Date: 2019-06-30 19:41 +0200 http://bitbucket.org/pypy/pypy/changeset/b048d08d615e/ Log: Fixed some issues with rrc finalizers diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py --- a/rpython/memory/gc/incminimark.py +++ b/rpython/memory/gc/incminimark.py @@ -3456,7 +3456,11 @@ self._rrc_mark_garbage() self._rrc_debug_check_consistency(print_label="end-legacy-fin") self.rrc_state = self.RAWREFCOUNT_STATE_DEFAULT - use_cylicrc = not self._rrc_find_finalizer() # modern finalizers + found_finalizer = self._rrc_find_finalizer() # modern finalizers + if found_finalizer: + self._rrc_gc_list_move(self.rrc_pyobj_old_list, + self.rrc_pyobj_isolate_list) + use_cylicrc = not found_finalizer self._rrc_debug_check_consistency(print_label="end-mark-cyclic") else: use_cylicrc = False # don't sweep any objects in cyclic isolates @@ -3820,15 +3824,18 @@ def _rrc_check_finalizer(self): # Check, if the cyclic isolate from the last collection cycle # is reachable from outside, after the finalizers have been - # executed. - self._rrc_collect_roots(self.rrc_pyobj_old_list) - found_alive = False - gchdr = self.rrc_pyobj_old_list.c_gc_next - while gchdr <> self.rrc_pyobj_old_list: - if (gchdr.c_gc_refs >> self.RAWREFCOUNT_REFS_SHIFT) > 0: - found_alive = True - break - gchdr = gchdr.c_gc_next + # executed (and if all finalizers have been executed). + found_alive = self._rrc_gc_list_is_empty(self.rrc_pyobj_isolate_list) + if not found_alive: + found_alive = self._rrc_find_finalizer() + if not found_alive: + self._rrc_collect_roots(self.rrc_pyobj_old_list) + gchdr = self.rrc_pyobj_old_list.c_gc_next + while gchdr <> self.rrc_pyobj_old_list: + if (gchdr.c_gc_refs >> self.RAWREFCOUNT_REFS_SHIFT) > 0: + found_alive = True + break + gchdr = gchdr.c_gc_next if found_alive: self._rrc_gc_list_merge(self.rrc_pyobj_old_list, self.rrc_pyobj_list) @@ -3840,17 +3847,13 @@ return True def _rrc_find_finalizer(self): - found_finalizer = False gchdr = self.rrc_pyobj_old_list.c_gc_next while gchdr <> self.rrc_pyobj_old_list: if self.rrc_finalizer_type(gchdr) == \ self.RAWREFCOUNT_FINALIZER_MODERN: - found_finalizer = True + return True gchdr = gchdr.c_gc_next - if found_finalizer: - self._rrc_gc_list_move(self.rrc_pyobj_old_list, - self.rrc_pyobj_isolate_list) - return found_finalizer + return False def _rrc_visit(pyobj, self_ptr): from rpython.rtyper.annlowlevel import cast_adr_to_nongc_instance diff --git a/rpython/memory/gc/test/test_rawrefcount.py b/rpython/memory/gc/test/test_rawrefcount.py --- a/rpython/memory/gc/test/test_rawrefcount.py +++ b/rpython/memory/gc/test/test_rawrefcount.py @@ -62,10 +62,9 @@ def rawrefcount_finalizer_type(gc): pyobj = self.pyobjs[self.gcobjs.index(gc)] - if pyobj in self.pyobjs and \ - self.pyobj_finalizer.has_key(self.pyobjs.index(pyobj)): - # TODO: improve test, so that NONE is returned, if finalizer - # has already been called (only for modern) + index = self.pyobjs.index(pyobj) + if pyobj in self.pyobjs and self.pyobj_finalizer.has_key(index) \ + and not self.pyobj_finalized.has_key(index): return self.pyobj_finalizer[self.pyobjs.index(pyobj)] else: return RAWREFCOUNT_FINALIZER_NONE From pypy.commits at gmail.com Thu Jul 4 10:14:35 2019 From: pypy.commits at gmail.com (stevie_92) Date: Thu, 04 Jul 2019 07:14:35 -0700 (PDT) Subject: [pypy-commit] pypy cpyext-gc-cycle: Fixed issue with linked, non-gc rrc objects (weakrefs dicts, ...) Message-ID: <5d1e09cb.1c69fb81.45c4c.4f35@mx.google.com> Author: Stefan Beyer Branch: cpyext-gc-cycle Changeset: r96948:7b33b39c8a06 Date: 2019-07-04 16:13 +0200 http://bitbucket.org/pypy/pypy/changeset/7b33b39c8a06/ Log: Fixed issue with linked, non-gc rrc objects (weakrefs dicts, ...) diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py --- a/rpython/memory/gc/incminimark.py +++ b/rpython/memory/gc/incminimark.py @@ -3142,6 +3142,7 @@ self.rrc_p_dict_nurs = self.AddressDict() # nursery keys only self.rrc_dealloc_trigger_callback = dealloc_trigger_callback self.rrc_dealloc_pending = self.AddressStack() + self.rrc_refcnt_dict = self.AddressDict() self.rrc_tp_traverse = tp_traverse self.rrc_pyobj_list = self._pygchdr(pyobj_list) self.rrc_tuple_list = self._pygchdr(tuple_list) @@ -3231,10 +3232,6 @@ gchdr = self._rrc_gc_list_pop(self.rrc_pyobj_isolate_list) self._rrc_gc_list_add(self.rrc_pyobj_old_list, gchdr) return llmemory.cast_ptr_to_adr(self.rrc_gc_as_pyobj(gchdr)) -# if not self._rrc_gc_list_is_empty(self.rrc_tuple_isolate_list): -# gchdr = self._rrc_gc_list_pop(self.rrc_tuple_isolate_list) -# self._rrc_gc_list_add(self.rrc_tuple_old_list, gchdr) -# return llmemory.cast_ptr_to_adr(self.rrc_gc_as_pyobj(gchdr)) return llmemory.NULL def rawrefcount_cyclic_garbage_head(self): @@ -3297,8 +3294,6 @@ if self.rrc_enabled and (self.rrc_dealloc_pending.non_empty() or not self._rrc_gc_list_is_empty( self.rrc_pyobj_isolate_list) or -# not self._rrc_gc_list_is_empty( -# self.rrc_tuple_isolate_list) or not self._rrc_gc_list_is_empty( self.rrc_pyobj_dead_list) or not self._rrc_gc_list_is_empty( @@ -3470,6 +3465,17 @@ self.rrc_p_list_old.foreach(self._rrc_major_trace, use_cylicrc) self._rrc_debug_check_consistency(print_label="end-mark") + # fix refcnt back + self.rrc_refcnt_dict.foreach(self._rrc_fix_refcnt_back, None) + self.rrc_refcnt_dict.delete() + self.rrc_refcnt_dict = self.AddressDict() + + def _rrc_fix_refcnt_back(self, pyobject, link, ignore): + pyobj = self._pyobj(pyobject) + link_int = llmemory.cast_adr_to_int(link, "symbolic") + pyobj.c_ob_refcnt = pyobj.c_ob_pypy_link + pyobj.c_ob_pypy_link = link_int + def _rrc_major_trace(self, pyobject, use_cylicrefcnt): from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY_LIGHT @@ -3495,8 +3501,7 @@ # force the corresponding object to be alive debug_print("pyobj stays alive", pyobj, "rc", rc, "cyclic_rc", cyclic_rc) - intobj = pyobj.c_ob_pypy_link - obj = llmemory.cast_int_to_adr(intobj) + obj = self.rrc_refcnt_dict.get(pyobject) self.objects_to_trace.append(obj) self.visit_all_objects() @@ -3519,8 +3524,9 @@ else: # force the corresponding object to be alive debug_print("pyobj stays alive", pyobj, "rc", rc) - intobj = pyobj.c_ob_pypy_link - obj = llmemory.cast_int_to_adr(intobj) + #intobj = pyobj.c_ob_pypy_link + #obj = llmemory.cast_int_to_adr(intobj) + obj = self.rrc_refcnt_dict.get(pyobject) self.objects_to_trace.append(obj) self.visit_all_objects() @@ -3556,6 +3562,7 @@ # Look for any weakrefs within the trash cycle and remove the callback. # This is only needed for weakrefs created from rawrefcounted objects # because weakrefs from gc-managed objects are going away anyway. + return list = self.rrc_pyobj_old_list gchdr = list.c_gc_next while gchdr <> list: @@ -3622,6 +3629,14 @@ # Initialize the cyclic refcount with the real refcount. self._rrc_collect_roots_init_list(pygclist) + # Save the real refcount of objects at border + self.rrc_p_list_old.foreach(self._rrc_obj_save_refcnt, None) + self.rrc_o_list_old.foreach(self._rrc_obj_save_refcnt, None) + + # Subtract all internal refcounts from the cyclic refcount + # of rawrefcounted objects + self._rrc_collect_roots_subtract_internal(pygclist) + # For all non-gc pyobjects which have a refcount > 0, # mark all reachable objects on the pypy side self.rrc_p_list_old.foreach(self._rrc_major_trace_nongc, None) @@ -3631,10 +3646,6 @@ self.rrc_p_list_old.foreach(self._rrc_obj_fix_refcnt, None) self.rrc_o_list_old.foreach(self._rrc_obj_fix_refcnt, None) - # Subtract all internal refcounts from the cyclic refcount - # of rawrefcounted objects - self._rrc_collect_roots_subtract_internal(pygclist) - # now all rawrefcounted roots or live border objects have a # refcount > 0 self._rrc_debug_check_consistency(print_label="rc-initialized") @@ -3664,28 +3675,28 @@ pygchdr.c_gc_refs &= self.RAWREFCOUNT_REFS_MASK_FINALIZED pygchdr.c_gc_refs |= refcnt << self.RAWREFCOUNT_REFS_SHIFT + def _rrc_obj_save_refcnt(self, pyobject, ignore): + pyobj = self._pyobj(pyobject) + link = llmemory.cast_int_to_adr(pyobj.c_ob_pypy_link) + self.rrc_refcnt_dict.setitem(pyobject, link) + pyobj.c_ob_pypy_link = pyobj.c_ob_refcnt + def _rrc_obj_fix_refcnt(self, pyobject, ignore): - from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY - from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY_LIGHT - # pyobj = self._pyobj(pyobject) - intobj = pyobj.c_ob_pypy_link - obj = llmemory.cast_int_to_adr(intobj) + #intobj = pyobj.c_ob_pypy_link + #obj = llmemory.cast_int_to_adr(intobj) + obj = self.rrc_refcnt_dict.get(pyobject) gchdr = self.rrc_pyobj_as_gc(pyobj) if gchdr <> lltype.nullptr(self.PYOBJ_GC_HDR): rc = gchdr.c_gc_refs - refcnt = pyobj.c_ob_refcnt + refcnt = gchdr.c_gc_refs >> self.RAWREFCOUNT_REFS_SHIFT if rc == self.RAWREFCOUNT_REFS_UNTRACKED: debug_print("gc obj not tracked", gchdr, ": obj", obj, - "real-rc", refcnt, "cyclic-rc", rc) + "cyclic-rc", rc) else: debug_print("gc obj tracked", gchdr, ": obj", obj, "real-rc", - refcnt, "cyclic-rc", rc, "gc-next", + refcnt, "gc-next", gchdr.c_gc_next, "gc-prev", gchdr.c_gc_prev) - if refcnt >= REFCNT_FROM_PYPY_LIGHT: - refcnt -= REFCNT_FROM_PYPY_LIGHT - elif refcnt >= REFCNT_FROM_PYPY: - refcnt -= REFCNT_FROM_PYPY if self.header(obj).tid & (GCFLAG_VISITED | GCFLAG_NO_HEAP_PTRS): refcnt += 1 @@ -3717,9 +3728,12 @@ def _rrc_mark_rawrefcount_obj(self, gchdr, gchdr_move): alive = (gchdr.c_gc_refs >> self.RAWREFCOUNT_REFS_SHIFT) > 0 pyobj = self.rrc_gc_as_pyobj(gchdr) + obj = llmemory.NULL if pyobj.c_ob_pypy_link <> 0: - intobj = pyobj.c_ob_pypy_link - obj = llmemory.cast_int_to_adr(intobj) + #intobj = pyobj.c_ob_pypy_link + #obj = llmemory.cast_int_to_adr(intobj) + pyobject = llmemory.cast_ptr_to_adr(pyobj) + obj = self.rrc_refcnt_dict.get(pyobject) if not alive and self.header(obj).tid & ( GCFLAG_VISITED | GCFLAG_NO_HEAP_PTRS): # add fake refcount, to mark it as live @@ -3736,8 +3750,8 @@ self._rrc_traverse(pyobj, 1) # mark recursively, if it is a pypyobj if pyobj.c_ob_pypy_link <> 0: - intobj = pyobj.c_ob_pypy_link - obj = llmemory.cast_int_to_adr(intobj) + #intobj = pyobj.c_ob_pypy_link + #obj = llmemory.cast_int_to_adr(intobj) self.objects_to_trace.append(obj) self.visit_all_objects() return alive @@ -3766,8 +3780,10 @@ alive = (gchdr.c_gc_refs >> self.RAWREFCOUNT_REFS_SHIFT) > 0 pyobj = self.rrc_gc_as_pyobj(gchdr) if pyobj.c_ob_pypy_link <> 0: - intobj = pyobj.c_ob_pypy_link - obj = llmemory.cast_int_to_adr(intobj) + #intobj = pyobj.c_ob_pypy_link + #obj = llmemory.cast_int_to_adr(intobj) + pyobject = llmemory.cast_ptr_to_adr(pyobj) + obj = self.rrc_refcnt_dict.get(pyobject) if not alive and self.header(obj).tid & ( GCFLAG_VISITED | GCFLAG_NO_HEAP_PTRS): # add fake refcount, to mark it as live @@ -3797,8 +3813,10 @@ # refcount of zero or an unmarked linked pypy object) self._rrc_traverse(pyobj, 1) if pyobj.c_ob_pypy_link <> 0: - intobj = pyobj.c_ob_pypy_link - obj = llmemory.cast_int_to_adr(intobj) + #intobj = pyobj.c_ob_pypy_link + pyobject = llmemory.cast_ptr_to_adr(pyobj) + obj = self.rrc_refcnt_dict.get(pyobject) + #obj = llmemory.cast_int_to_adr(intobj) self.rrc_garbage_to_trace.append(obj) self.objects_to_trace.append(obj) self.visit_all_objects() @@ -3869,6 +3887,15 @@ if pygchdr.c_gc_refs != self.RAWREFCOUNT_REFS_UNTRACKED: pygchdr.c_gc_refs += self.rrc_refcnt_add << \ self.RAWREFCOUNT_REFS_SHIFT + elif pyobj.c_ob_pypy_link != 0: + pyobj.c_ob_refcnt += self.rrc_refcnt_add + if self.rrc_refcnt_add > 0: + #intobj = pyobj.c_ob_pypy_link + #obj = llmemory.cast_int_to_adr(intobj) + pyobject = llmemory.cast_ptr_to_adr(pyobj) + obj = self.rrc_refcnt_dict.get(pyobject) + self.objects_to_trace.append(obj) + self.visit_all_objects() def _rrc_traverse(self, pyobj, refcnt_add): from rpython.rlib.objectmodel import we_are_translated @@ -3963,11 +3990,11 @@ gchdr.c_gc_refs >> self.RAWREFCOUNT_REFS_SHIFT, "refcnt", pyobj.c_ob_refcnt, "link", intobj) - if intobj: - obj = llmemory.cast_int_to_adr(intobj) - marked = self.header(obj).tid & \ - (GCFLAG_VISITED | GCFLAG_NO_HEAP_PTRS) - debug_print(" linked obj", obj, ": marked", marked) + #if intobj: TODO fix + # obj = llmemory.cast_int_to_adr(intobj) + # marked = self.header(obj).tid & \ + # (GCFLAG_VISITED | GCFLAG_NO_HEAP_PTRS) + # debug_print(" linked obj", obj, ": marked", marked) ll_assert(gchdr.c_gc_next != lltype.nullptr(self.PYOBJ_GC_HDR), "gc_next is null") diff --git a/rpython/memory/gc/test/test_rawrefcount.py b/rpython/memory/gc/test/test_rawrefcount.py --- a/rpython/memory/gc/test/test_rawrefcount.py +++ b/rpython/memory/gc/test/test_rawrefcount.py @@ -683,7 +683,8 @@ finalize_modern(pyobj) if pyobj.c_ob_refcnt == 0: gchdr = self.gc.rrc_pyobj_as_gc(pyobj) - if gchdr.c_gc_refs != RAWREFCOUNT_REFS_UNTRACKED: + if gchdr != lltype.nullptr(PYOBJ_GC_HDR) and \ + gchdr.c_gc_refs != RAWREFCOUNT_REFS_UNTRACKED: next = gchdr.c_gc_next next.c_gc_prev = gchdr.c_gc_prev gchdr.c_gc_prev.c_gc_next = next @@ -780,7 +781,8 @@ # https://github.com/python/cpython/blob/master/Modules/gc_weakref.txt for weakrefs in self.pyobj_weakrefs: for weakref in weakrefs: - assert weakref.callback_cleared == weakref.clear_callback + pass # TODO fix + #assert weakref.callback_cleared == weakref.clear_callback # check if unreachable objects in cyclic structures with legacy # finalizers and all otherwise unreachable objects reachable from them From pypy.commits at gmail.com Thu Jul 4 12:01:25 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 04 Jul 2019 09:01:25 -0700 (PDT) Subject: [pypy-commit] pypy arm64: Support for aarch64 in slacklet Message-ID: <5d1e22d5.1c69fb81.745b1.37d4@mx.google.com> Author: Armin Rigo Branch: arm64 Changeset: r96949:dbada42ae261 Date: 2019-07-04 16:00 +0000 http://bitbucket.org/pypy/pypy/changeset/dbada42ae261/ Log: Support for aarch64 in slacklet diff --git a/rpython/translator/c/src/stacklet/slp_platformselect.h b/rpython/translator/c/src/stacklet/slp_platformselect.h --- a/rpython/translator/c/src/stacklet/slp_platformselect.h +++ b/rpython/translator/c/src/stacklet/slp_platformselect.h @@ -10,6 +10,8 @@ #include "switch_x86_gcc.h" /* gcc on X86 */ #elif defined(__GNUC__) && defined(__arm__) #include "switch_arm_gcc.h" /* gcc on arm */ +#elif defined(__GNUC__) && defined(__aarch64__) +#include "switch_aarch64_gcc.h" /* gcc on aarch64 */ #elif defined(__GNUC__) && defined(__PPC64__) #include "switch_ppc64_gcc.h" /* gcc on ppc64 */ #elif defined(__GNUC__) && defined(__mips__) && defined(_ABI64) diff --git a/rpython/translator/c/src/stacklet/switch_aarch64_gcc.h b/rpython/translator/c/src/stacklet/switch_aarch64_gcc.h new file mode 100644 --- /dev/null +++ b/rpython/translator/c/src/stacklet/switch_aarch64_gcc.h @@ -0,0 +1,117 @@ + +static void *slp_switch(void *(*save_state)(void*, void*), + void *(*restore_state)(void*, void*), + void *extra) __attribute__((noinline)); + +static void *slp_switch(void *(*save_state)(void*, void*), + void *(*restore_state)(void*, void*), + void *extra) +{ + void *result; + /* + registers to preserve: x18-x28, x29(fp), x30(lr), and v8-v15 + registers marked as clobbered: x0-x18 + + Note that x18 appears in both lists; see below. + + Don't assume gcc saves any register for us when generating + code for slp_switch(). + + The values 'save_state', 'restore_state' and 'extra' are first moved + by gcc to some registers that are not marked as clobbered, so >= x19. + Similarly, gcc expects 'result' to be in a register >= x19. + We don't want x18 to be used here, because of some special meaning + it might have. + + This means that three of the values we happen to save and restore + will, in fact, contain the three arguments, and one of these values + will, in fact, not be restored at all but receive 'result'. + + The following two points may no longer be true, because "x30" is + now present in the clobbered list, but the extra workarounds we + do might be safer just in case: + + (1) Careful writing "blr %[...]": if gcc resolves it to x30---and it + can!---then you're in trouble, because "blr x30" does not jump + anywhere at all (it probably loads the current position into x30 + before it jumps to x30...) + + (2) Also, because "%[...]" can resolve to x30, we can't use that after + the first call. Instead, we need to copy the values somewhere + safe, like x24 and x25. We do that in such an order that it should + work even if any of the "%[...]" expressions becomes x24 or x25 too. + */ + + __asm__ volatile ( + + /* The stack is supposed to be aligned as necessary already. + Save 13 registers from x18 to x30, plus 8 from v8 to v15 */ + + "stp x29, x30, [sp, -176]!\n" + "stp x18, x19, [sp, 16]\n" + "stp x20, x21, [sp, 32]\n" + "stp x22, x23, [sp, 48]\n" + "stp x24, x25, [sp, 64]\n" + "stp x26, x27, [sp, 80]\n" + "str x28, [sp, 96]\n" + "str d8, [sp, 104]\n" + "str d9, [sp, 112]\n" + "str d10, [sp, 120]\n" + "str d11, [sp, 128]\n" + "str d12, [sp, 136]\n" + "str d13, [sp, 144]\n" + "str d14, [sp, 152]\n" + "str d15, [sp, 160]\n" + + "mov x0, sp\n" /* arg 1: current (old) stack pointer */ + "mov x1, %[extra]\n" /* arg 2: extra, from >= x18 */ + "mov x3, %[save_state]\n" + "mov x24, %[restore_state]\n" /* save restore_state => x24 */ + "mov x25, x1\n" /* save extra => x25 */ + "blr x3\n" /* call save_state() */ + + /* skip the rest if the return value is null */ + "cbz x0, zero\n" + + "mov sp, x0\n" /* change the stack pointer */ + + /* From now on, the stack pointer is modified, but the content of the + stack is not restored yet. It contains only garbage here. */ + "mov x1, x25\n" /* arg 2: extra */ + /* arg 1: current (new) stack pointer is already in x0*/ + "blr x24\n" /* call restore_state() */ + + /* The stack's content is now restored. */ + "zero:\n" + + /* Restore all saved registers */ + "ldp x18, x19, [sp, 16]\n" + "ldp x20, x21, [sp, 32]\n" + "ldp x22, x23, [sp, 48]\n" + "ldp x24, x25, [sp, 64]\n" + "ldp x26, x27, [sp, 80]\n" + "ldr x28, [sp, 96]\n" + "ldr d8, [sp, 104]\n" + "ldr d9, [sp, 112]\n" + "ldr d10, [sp, 120]\n" + "ldr d11, [sp, 128]\n" + "ldr d12, [sp, 136]\n" + "ldr d13, [sp, 144]\n" + "ldr d14, [sp, 152]\n" + "ldr d15, [sp, 160]\n" + "ldp x29, x30, [sp], 176\n" + + /* Move x0 into the final location of 'result' */ + "mov %[result], x0\n" + + : [result]"=r"(result) /* output variables */ + /* input variables */ + : [restore_state]"r"(restore_state), + [save_state]"r"(save_state), + [extra]"r"(extra) + : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", + "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", + "memory", "cc", "x30" // x30==lr + ); + return result; +} From pypy.commits at gmail.com Fri Jul 5 01:35:41 2019 From: pypy.commits at gmail.com (fijal) Date: Thu, 04 Jul 2019 22:35:41 -0700 (PDT) Subject: [pypy-commit] pypy arm64: those are done Message-ID: <5d1ee1ad.1c69fb81.d56d6.9280@mx.google.com> Author: fijal Branch: arm64 Changeset: r96950:3d9636d8cea7 Date: 2019-07-05 07:34 +0200 http://bitbucket.org/pypy/pypy/changeset/3d9636d8cea7/ Log: those are done diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO --- a/rpython/jit/backend/aarch64/TODO +++ b/rpython/jit/backend/aarch64/TODO @@ -1,6 +1,3 @@ -* int_add - IMM -* int_cmp - IMM -* guard_nonnull_class - think about a better way * cond_call and following guard_exception * stack check From pypy.commits at gmail.com Fri Jul 5 01:35:43 2019 From: pypy.commits at gmail.com (fijal) Date: Thu, 04 Jul 2019 22:35:43 -0700 (PDT) Subject: [pypy-commit] pypy arm64: merge Message-ID: <5d1ee1af.1c69fb81.9f9da.bd3b@mx.google.com> Author: fijal Branch: arm64 Changeset: r96951:88dea7ad32c8 Date: 2019-07-05 07:34 +0200 http://bitbucket.org/pypy/pypy/changeset/88dea7ad32c8/ Log: merge diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -1091,7 +1091,7 @@ if box.type == REF and self.rm.is_still_alive(box): assert not noregs assert loc.is_core_reg() - val = loc.value + val = self.cpu.all_reg_indexes[loc.value] gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) for box, loc in self.fm.bindings.iteritems(): if box.type == REF and self.rm.is_still_alive(box): @@ -1137,4 +1137,4 @@ if hasattr(Regalloc, methname): func = getattr(Regalloc, methname).im_func comp_operations[value] = func - \ No newline at end of file + diff --git a/rpython/translator/c/src/stacklet/slp_platformselect.h b/rpython/translator/c/src/stacklet/slp_platformselect.h --- a/rpython/translator/c/src/stacklet/slp_platformselect.h +++ b/rpython/translator/c/src/stacklet/slp_platformselect.h @@ -10,6 +10,8 @@ #include "switch_x86_gcc.h" /* gcc on X86 */ #elif defined(__GNUC__) && defined(__arm__) #include "switch_arm_gcc.h" /* gcc on arm */ +#elif defined(__GNUC__) && defined(__aarch64__) +#include "switch_aarch64_gcc.h" /* gcc on aarch64 */ #elif defined(__GNUC__) && defined(__PPC64__) #include "switch_ppc64_gcc.h" /* gcc on ppc64 */ #elif defined(__GNUC__) && defined(__mips__) && defined(_ABI64) diff --git a/rpython/translator/c/src/stacklet/switch_aarch64_gcc.h b/rpython/translator/c/src/stacklet/switch_aarch64_gcc.h new file mode 100644 --- /dev/null +++ b/rpython/translator/c/src/stacklet/switch_aarch64_gcc.h @@ -0,0 +1,117 @@ + +static void *slp_switch(void *(*save_state)(void*, void*), + void *(*restore_state)(void*, void*), + void *extra) __attribute__((noinline)); + +static void *slp_switch(void *(*save_state)(void*, void*), + void *(*restore_state)(void*, void*), + void *extra) +{ + void *result; + /* + registers to preserve: x18-x28, x29(fp), x30(lr), and v8-v15 + registers marked as clobbered: x0-x18 + + Note that x18 appears in both lists; see below. + + Don't assume gcc saves any register for us when generating + code for slp_switch(). + + The values 'save_state', 'restore_state' and 'extra' are first moved + by gcc to some registers that are not marked as clobbered, so >= x19. + Similarly, gcc expects 'result' to be in a register >= x19. + We don't want x18 to be used here, because of some special meaning + it might have. + + This means that three of the values we happen to save and restore + will, in fact, contain the three arguments, and one of these values + will, in fact, not be restored at all but receive 'result'. + + The following two points may no longer be true, because "x30" is + now present in the clobbered list, but the extra workarounds we + do might be safer just in case: + + (1) Careful writing "blr %[...]": if gcc resolves it to x30---and it + can!---then you're in trouble, because "blr x30" does not jump + anywhere at all (it probably loads the current position into x30 + before it jumps to x30...) + + (2) Also, because "%[...]" can resolve to x30, we can't use that after + the first call. Instead, we need to copy the values somewhere + safe, like x24 and x25. We do that in such an order that it should + work even if any of the "%[...]" expressions becomes x24 or x25 too. + */ + + __asm__ volatile ( + + /* The stack is supposed to be aligned as necessary already. + Save 13 registers from x18 to x30, plus 8 from v8 to v15 */ + + "stp x29, x30, [sp, -176]!\n" + "stp x18, x19, [sp, 16]\n" + "stp x20, x21, [sp, 32]\n" + "stp x22, x23, [sp, 48]\n" + "stp x24, x25, [sp, 64]\n" + "stp x26, x27, [sp, 80]\n" + "str x28, [sp, 96]\n" + "str d8, [sp, 104]\n" + "str d9, [sp, 112]\n" + "str d10, [sp, 120]\n" + "str d11, [sp, 128]\n" + "str d12, [sp, 136]\n" + "str d13, [sp, 144]\n" + "str d14, [sp, 152]\n" + "str d15, [sp, 160]\n" + + "mov x0, sp\n" /* arg 1: current (old) stack pointer */ + "mov x1, %[extra]\n" /* arg 2: extra, from >= x18 */ + "mov x3, %[save_state]\n" + "mov x24, %[restore_state]\n" /* save restore_state => x24 */ + "mov x25, x1\n" /* save extra => x25 */ + "blr x3\n" /* call save_state() */ + + /* skip the rest if the return value is null */ + "cbz x0, zero\n" + + "mov sp, x0\n" /* change the stack pointer */ + + /* From now on, the stack pointer is modified, but the content of the + stack is not restored yet. It contains only garbage here. */ + "mov x1, x25\n" /* arg 2: extra */ + /* arg 1: current (new) stack pointer is already in x0*/ + "blr x24\n" /* call restore_state() */ + + /* The stack's content is now restored. */ + "zero:\n" + + /* Restore all saved registers */ + "ldp x18, x19, [sp, 16]\n" + "ldp x20, x21, [sp, 32]\n" + "ldp x22, x23, [sp, 48]\n" + "ldp x24, x25, [sp, 64]\n" + "ldp x26, x27, [sp, 80]\n" + "ldr x28, [sp, 96]\n" + "ldr d8, [sp, 104]\n" + "ldr d9, [sp, 112]\n" + "ldr d10, [sp, 120]\n" + "ldr d11, [sp, 128]\n" + "ldr d12, [sp, 136]\n" + "ldr d13, [sp, 144]\n" + "ldr d14, [sp, 152]\n" + "ldr d15, [sp, 160]\n" + "ldp x29, x30, [sp], 176\n" + + /* Move x0 into the final location of 'result' */ + "mov %[result], x0\n" + + : [result]"=r"(result) /* output variables */ + /* input variables */ + : [restore_state]"r"(restore_state), + [save_state]"r"(save_state), + [extra]"r"(extra) + : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", + "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", + "memory", "cc", "x30" // x30==lr + ); + return result; +} From pypy.commits at gmail.com Fri Jul 5 02:36:20 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 04 Jul 2019 23:36:20 -0700 (PDT) Subject: [pypy-commit] pypy arm64: This is done Message-ID: <5d1eefe4.1c69fb81.7cf2.7c5e@mx.google.com> Author: Armin Rigo Branch: arm64 Changeset: r96952:dbb6f23ca77d Date: 2019-07-05 08:35 +0200 http://bitbucket.org/pypy/pypy/changeset/dbb6f23ca77d/ Log: This is done diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO --- a/rpython/jit/backend/aarch64/TODO +++ b/rpython/jit/backend/aarch64/TODO @@ -16,26 +16,6 @@ _build_failure_recovery(), build_frame_realloc_slowpath(), etc. -* here's what gcc uses to acquire and release a lock, instead of mc.DMB - in callbuilder.py. It would make the control flow mess easier, too, - because we can simply loop back to .L2 (rare case) instead of trying - to handle it as a 3rd path. - - to release a lock: - (x0 is the address of the lock) - stlr xzr, [x0] - - to acquire a lock: - (x1 is the address of the lock) - mov x2, 1 - .L2: ldxr x0, [x1] - stxr w3, x2, [x1] - cbnz w3, .L2 (I think it's a rare case when it follows .L2) - dmb ish (see below) - (we're left with x0 being the old value in the lock, 0 or 1) - - note that "dmb" only appears sometimes, depending on the exact gcc - intrinsic I use. I *think* that it can be safely removed, and so - it should be. - - * malloc_cond() and malloc_cond_varsize_frame() hard-code forward jump distances by guessing the number of instructions that follows. Bad idea because some of these instructions could easily be optimized in From pypy.commits at gmail.com Fri Jul 5 02:56:31 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 04 Jul 2019 23:56:31 -0700 (PDT) Subject: [pypy-commit] pypy arm64: Clean up code and comments, no longer doing copies that I've now understood are Message-ID: <5d1ef49f.1c69fb81.f2415.3d7a@mx.google.com> Author: Armin Rigo Branch: arm64 Changeset: r96953:aac1bb032282 Date: 2019-07-05 06:55 +0000 http://bitbucket.org/pypy/pypy/changeset/aac1bb032282/ Log: Clean up code and comments, no longer doing copies that I've now understood are pointless diff --git a/rpython/translator/c/src/stacklet/switch_aarch64_gcc.h b/rpython/translator/c/src/stacklet/switch_aarch64_gcc.h --- a/rpython/translator/c/src/stacklet/switch_aarch64_gcc.h +++ b/rpython/translator/c/src/stacklet/switch_aarch64_gcc.h @@ -9,66 +9,51 @@ { void *result; /* - registers to preserve: x18-x28, x29(fp), x30(lr), and v8-v15 - registers marked as clobbered: x0-x18 + registers to preserve: x18-x28, x29(fp), and v8-v15 + registers marked as clobbered: x0-x18, x30 - Note that x18 appears in both lists; see below. + Note that x18 appears in both lists; see below. We also save + x30 although it's also marked as clobbered, which might not + be necessary but doesn't hurt. Don't assume gcc saves any register for us when generating code for slp_switch(). The values 'save_state', 'restore_state' and 'extra' are first moved - by gcc to some registers that are not marked as clobbered, so >= x19. - Similarly, gcc expects 'result' to be in a register >= x19. - We don't want x18 to be used here, because of some special meaning - it might have. + by gcc to some registers that are not marked as clobbered, so between + x19 and x29. Similarly, gcc expects 'result' to be in a register + between x19 and x29. We don't want x18 to be used here, because of + some special meaning it might have. We don't want x30 to be used + here, because it is clobbered by the first "blr". This means that three of the values we happen to save and restore will, in fact, contain the three arguments, and one of these values will, in fact, not be restored at all but receive 'result'. - - The following two points may no longer be true, because "x30" is - now present in the clobbered list, but the extra workarounds we - do might be safer just in case: - - (1) Careful writing "blr %[...]": if gcc resolves it to x30---and it - can!---then you're in trouble, because "blr x30" does not jump - anywhere at all (it probably loads the current position into x30 - before it jumps to x30...) - - (2) Also, because "%[...]" can resolve to x30, we can't use that after - the first call. Instead, we need to copy the values somewhere - safe, like x24 and x25. We do that in such an order that it should - work even if any of the "%[...]" expressions becomes x24 or x25 too. */ __asm__ volatile ( /* The stack is supposed to be aligned as necessary already. - Save 13 registers from x18 to x30, plus 8 from v8 to v15 */ + Save 12 registers from x18 to x29, plus 8 from v8 to v15 */ - "stp x29, x30, [sp, -176]!\n" - "stp x18, x19, [sp, 16]\n" - "stp x20, x21, [sp, 32]\n" - "stp x22, x23, [sp, 48]\n" - "stp x24, x25, [sp, 64]\n" - "stp x26, x27, [sp, 80]\n" - "str x28, [sp, 96]\n" - "str d8, [sp, 104]\n" - "str d9, [sp, 112]\n" - "str d10, [sp, 120]\n" - "str d11, [sp, 128]\n" - "str d12, [sp, 136]\n" - "str d13, [sp, 144]\n" - "str d14, [sp, 152]\n" - "str d15, [sp, 160]\n" + "stp x18, x19, [sp, -160]!\n" + "stp x20, x11, [sp, 16]\n" + "stp x22, x23, [sp, 32]\n" + "stp x24, x25, [sp, 48]\n" + "stp x26, x27, [sp, 64]\n" + "stp x28, x29, [sp, 80]\n" + "str d8, [sp, 96]\n" + "str d9, [sp, 104]\n" + "str d10, [sp, 112]\n" + "str d11, [sp, 120]\n" + "str d12, [sp, 128]\n" + "str d13, [sp, 136]\n" + "str d14, [sp, 144]\n" + "str d15, [sp, 152]\n" "mov x0, sp\n" /* arg 1: current (old) stack pointer */ - "mov x1, %[extra]\n" /* arg 2: extra, from >= x18 */ - "mov x3, %[save_state]\n" - "mov x24, %[restore_state]\n" /* save restore_state => x24 */ - "mov x25, x1\n" /* save extra => x25 */ - "blr x3\n" /* call save_state() */ + "mov x1, %[extra]\n" /* arg 2: extra, from x19-x28 */ + "blr %[save_state]\n" /* call save_state(), from x19-x28 */ /* skip the rest if the return value is null */ "cbz x0, zero\n" @@ -77,29 +62,28 @@ /* From now on, the stack pointer is modified, but the content of the stack is not restored yet. It contains only garbage here. */ - "mov x1, x25\n" /* arg 2: extra */ + "mov x1, %[extra]\n" /* arg 2: extra, still from x19-x28 */ /* arg 1: current (new) stack pointer is already in x0*/ - "blr x24\n" /* call restore_state() */ + "blr %[restore_state]\n"/* call restore_state() */ /* The stack's content is now restored. */ "zero:\n" /* Restore all saved registers */ - "ldp x18, x19, [sp, 16]\n" - "ldp x20, x21, [sp, 32]\n" - "ldp x22, x23, [sp, 48]\n" - "ldp x24, x25, [sp, 64]\n" - "ldp x26, x27, [sp, 80]\n" - "ldr x28, [sp, 96]\n" - "ldr d8, [sp, 104]\n" - "ldr d9, [sp, 112]\n" - "ldr d10, [sp, 120]\n" - "ldr d11, [sp, 128]\n" - "ldr d12, [sp, 136]\n" - "ldr d13, [sp, 144]\n" - "ldr d14, [sp, 152]\n" - "ldr d15, [sp, 160]\n" - "ldp x29, x30, [sp], 176\n" + "ldp x20, x11, [sp, 16]\n" + "ldp x22, x23, [sp, 32]\n" + "ldp x24, x25, [sp, 48]\n" + "ldp x26, x27, [sp, 64]\n" + "ldp x28, x29, [sp, 80]\n" + "ldr d8, [sp, 96]\n" + "ldr d9, [sp, 104]\n" + "ldr d10, [sp, 112]\n" + "ldr d11, [sp, 120]\n" + "ldr d12, [sp, 128]\n" + "ldr d13, [sp, 136]\n" + "ldr d14, [sp, 144]\n" + "ldr d15, [sp, 152]\n" + "ldp x18, x19, [sp], 160\n" /* Move x0 into the final location of 'result' */ "mov %[result], x0\n" From pypy.commits at gmail.com Fri Jul 5 03:12:54 2019 From: pypy.commits at gmail.com (fijal) Date: Fri, 05 Jul 2019 00:12:54 -0700 (PDT) Subject: [pypy-commit] pypy arm64: cond_call_value_r Message-ID: <5d1ef876.1c69fb81.5fe18.c92e@mx.google.com> Author: fijal Branch: arm64 Changeset: r96954:873065b05b7d Date: 2019-07-05 09:12 +0200 http://bitbucket.org/pypy/pypy/changeset/873065b05b7d/ Log: cond_call_value_r diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -886,6 +886,7 @@ def emit_op_cond_call_value_i(self, op, arglocs): self._emit_op_cond_call(op, arglocs, c.NE) + emit_op_cond_call_value_r = emit_op_cond_call_value_i def emit_guard_op_cond_call(self, prevop, op, fcond, arglocs): self._emit_op_cond_call(op, arglocs, c.get_opposite_of(fcond)) diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -750,7 +750,8 @@ return self._prepare_op_cond_call(op, False) def prepare_op_cond_call_value_i(self, op): - return self._prepare_op_cond_call(op, False) + return self._prepare_op_cond_call(op, False) + prepare_op_cond_call_value_r = prepare_op_cond_call_value_i def prepare_guard_op_cond_call(self, op, prevop): fcond = self.assembler.dispatch_comparison(prevop) From pypy.commits at gmail.com Mon Jul 8 03:19:10 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 08 Jul 2019 00:19:10 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: #3007 Message-ID: <5d22ee6e.1c69fb81.29f93.49a8@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96955:a3e2d215641c Date: 2019-07-08 09:18 +0200 http://bitbucket.org/pypy/pypy/changeset/a3e2d215641c/ Log: #3007 More tweak: enable universal newline mode even in -u mode on Windows diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -350,13 +350,13 @@ raw = buf.raw if buffering else buf raw.name = name # We normally use newline='\n' below, which turns off any translation. - # However, on Windows, and if unbuffered is false, then we must enable + # However, on Windows (independently of -u), then we must enable # the Universal Newline mode (set by newline = None): on input, \r\n # is translated into \n; on output, \n is translated into \r\n. # We must never enable the Universal Newline mode on POSIX: CPython # never interprets '\r\n' in stdin as meaning just '\n', unlike what # it does if you explicitly open a file in text mode. - newline = None if sys.platform == 'win32' and not unbuffered else '\n' + newline = None if sys.platform == 'win32' else '\n' stream = _io.TextIOWrapper(buf, encoding, errors, newline=newline, line_buffering=unbuffered or raw.isatty()) stream.mode = mode From pypy.commits at gmail.com Tue Jul 9 04:58:42 2019 From: pypy.commits at gmail.com (cfbolz) Date: Tue, 09 Jul 2019 01:58:42 -0700 (PDT) Subject: [pypy-commit] extradoc extradoc: preserve full notes (will extract tasks too) Message-ID: <5d245742.1c69fb81.4e42a.e001@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: extradoc Changeset: r5948:4ee007fa782d Date: 2019-02-14 10:45 +0100 http://bitbucket.org/pypy/extradoc/changeset/4ee007fa782d/ Log: preserve full notes (will extract tasks too) diff --git a/sprintinfo/ddorf2019/planning.txt b/sprintinfo/ddorf2019/planning.txt new file mode 100644 --- /dev/null +++ b/sprintinfo/ddorf2019/planning.txt @@ -0,0 +1,262 @@ +# PyPy sprint + +https://piratenpad.de/p/IkjitZdh +https://hackmd.io/1eT6t4_lReigSw0-4pEyQw + +## People + +Tim +Stefan +Andy +Ronan +Manuel +Alexander +Julian +Carl Friedrich +John +Maciej +Armin +Łukasz +Matti +Anto +Mercurial devs (Wednesday) +some external people + +## Tasks - Mon + +- intro talk (CF, John, Julian, Andy, Stefan) + + + +## Tasks - Tues +- Start the ARM64 backend (Armin, fijal) STARTED+DISCUSSIONS +- Merging regalloc branch (CF, fijal, Armin) +- Set up benchmarking machine (fijal, Matti) +- Triage 3.6 failures and progress on them (Łukasz, Ronan) https://bitbucket.org/pypy/pypy/wiki/Status%20of%20PyPy3%20support%20for%203.6 + - re and csv failures are done + - removed duplicate code + - next: fspath + +- zlib missing methods pypy2/3 (Julian, Anto) RZLIB DONE + - new failing tests: http://buildbot.pypy.org/summary?category=linux64&branch=%3Ctrunk%3E&recentrev=95849:c5c3ad13d149 + - app-level test: when run on top of compiled PyPy, can't call function defined on interp-level + - lib-python test: .flush() sets .stream to nullptr, .copy() calls deflateCopy() with nullptr, it segfaults in RZlibError.fromstream() + - subtle difference: on CPython, z_stream is part of structure and can't become nullptr + - possible fixes: either handle .stream == nullptr in pypy module, or make RZlibError.fromstream() robust agains nullptr + - TESTS fixed? py3 problems +- Fix RevDB (Manuel, Armin around) DONE + +- investigate struct.unpack weirdness (Antocuni, Julian) + +- Look into Windows failures on 3.5 (Manuel, Andy, Ronan around) - NANs are not consistent DONE + +- Windows installer (Andy, Matti) WORKS, needs adding to package.py + + + +## Tasks +- Release 7.0 (Anto) reports version 7.1 :( +- utf-8 progress/merging (Matti looking, Ronan will help) + NEEDS REVIEW. Benchmarks are [here](https://gist.github.com/mattip/05951f44e41224e36f00b62ebb4e2444) and [here](https://gist.github.com/mattip/d25536cd88ffe0361feca7760745a524). `logging.warn`, which is slow on py3.5 has gotten even worse SATURDAY + +- still one failing test in zlib branch untranslated (Ronan) + +- cpyext performance (Tim, Ronan around) Carl will ask Tim what is going on and file an issue + +- math-improvements branch (Alex to start) (REVIEW DONE, needs to be merged into default after the release, more bugs, benchmark on Py3?) (CF to merge into default/py3.5) + +- memoryview/ctypes bug https://bitbucket.org/pypy/pypy/issues/2930 (Matti, Armin around) + +- pypeg (lpeg reimplementation in RPython) (Stefan, Tim around, +?) + +- Tracker gardening + +- CFFI OS X bug (Maciej, Armin around) + +- finish fspath stuff (Łukasz, CF around) + +- look at test_compile.py (Łukasz, CF around) + +- asynio on Windows (Andy) + +- ARM32 build server (David, Matti, Maciek, Armin) + +- Answer Stefan Beyer email on pypy-dev + + +## Tasks Saturday + +* let's look at spectral_norm after regalloc merge +* utf-8 (Armin, CF, Matti, Maciek around) +* progress on ARM64 (Maciek, David, Rodolph) + + +## Discussions Done + +- Think about Windows support - conclusion is to keep muddling along: + + - There is money from SFC - who will do the work? + - Maybe the Microsoft people?????? + - Andy has a first-attempt at a MSI packager + - Try to have green buildbots and not much more? + +- Funding + - SFC - $69,000, $300 in OpenCollective + - Karen (SFC) Seem to be ready for us to part ways. + - We should spend the money. There are no marked funds. + - PLC needs to approve expenses. + - Python3.6/3.7/3.8: Ronan, Carl, Lucasz $30,000, incl. travel, salary + - Next sprint: summer? + - Cpyext: Antonio, Ronan $30,000, incl. travel, salary + - Buildbots: machines and website update $10,000 + - pypy.org $2,000 +- Catching up with 3.6/3.7/3.8 - stop with py3.5 + +- Intro talk (DONE) +- Web Assembly (DONE) +- Collaboration possibilities GraalPython around numpy stack TODAY +- Scientific Stack +- VMProf AFTER LUNCH +- Unstuck Benchmarking - do it!! (decision made) +- Packaging (wheels and conda) situation + +## Discussions +- Infrastructure, testing: Travis, Azure Pipelines (1800 minutes per month) FRI MORNING +- State and Future of PyPy +- apptest-file branch merge (Ronan) +- focused sprint: when, where + +### Webassembly and PyPy + +### pyodide + +Python as an ecosystem is bad suited? + +PyPy should wait for GC support and DOM support. + + +## Cython and GraalPython + +* Problem for GraalPython and PyPy (and numba) is that numpy is a black box +* Other problem: handling expressions as a unit to not need to compute intermediate values +* Numpy discussions around PyIR +* Use (subset of) Cython or Cython-like to make [PyIR](https://docs.google.com/document/d/1jGksgI96LdYQODa9Fca7EttFEGQfNODphVmbCX0DD1k/edit#) real + * Cython is used by numeric people already, they are used to it + * as much Cython as possible + * compilable to something sensible +* Cython is a tiny bit messy, it's a one-pass compiler +* can we make Cython better designed? +* potentially ask Oracle for funding + +## PyPy and the Numeric Stack + +* Important to support well, it's what many people use Python for +* Problems: + * they don't use PyPy yet! + * numpy code tends to not be fast on PyPy + * the big libraries are hard to install + * we don't support wheels + * we don't support conda +* Performance problems: + * cpyext speedups + * long term plans around cython or similar +* maybe building wheels is going to be easier with manylinux2010? +* let's try to build pypy on the right manylinux2010 +* conda doesn't care about us +* they want us to do work? +* but we would need changes in conda and deep understanding on their side + * Open issue with design proposal: https://github.com/conda/conda/issues/6950 +* contrete tasks: + * try to build manylinux2010 pypy + * talk to conda people? + + +## ``VMProf`` + +* Problems with vmprof: + * frontend: graphs are hard to understand + * kills buildbot host + * we need to maintain it + * huge RAM usage + * backend: + * rpython functions not profiled correctly + * what's the scope of vmprof? + * no "customers"/motivation + +* Scope: + * ??? +* Frontend: + * Can we make our life easier by using somebody else's frontend? + * Chrome devtools + * PyCharm + * https://github.com/KDAB/hotspot + +* Backend: + * profiling in production + * make it cheap enough + * make it easy to turn on and off + * make it possible to deal with data in-process + * the vmprof pure python modules is badly implemented + * boring parts: rpython functions + + * steps: + * improve the vmprof module to not suck + * make ``_vmprof`` should always provide reliable data + * make local deployment very simple + +* we should be able to connect source code and traces +* unique identifiers for loops from the JIT + * what happens if the loop is formed before `_vmprof` is on + * just have it always on ;-) + * how to connect pieces of traces to source code? Offets, pieces of loops, code in memory do not always map back to source file + * exposes bugs that probably already exist but we don't care + * blackhole, generated code, tracing, ... + * debug_merge_point is not necesssarily always correct +* when you have correct input you see correct output, but when you do not have correct input do not show garbage + +##### Summary + +* Can we make an improved JitViewer with statistical profiling info? Will it be helpful? + * what about tracing? blackhole? Function repitition? Fix it in `_vmprof` ! + +* Possible architecture: + * _vmprof feeds data to a socket + * separate program reads the data and distills it into a known format + * that is presented in a known frontend + +* Better packaging and API + * callback hook function what to do with the info: socket, file, + * on/off per block, + * on/off generally which would not necessarily add overhead but would allow later on/off on a lower level. + * allow self-reporting of global/per-thread/per-green thread state of the app + +## Discussion: State and Future of PyPy +* Let's try to have team-internal "office hours" Monday 10.00-13.00 to deal with the reduced availability of people +* How can we constructively interact with CPython-dev? + * maybe a PEP? + * what are concrete things that would be good to have in there? + * something about C-API? + * having cpython implementation details marked as such in the regression tests + * have people from other implementations be invited to lang summit +* when PyPy 3.6 is out, we should get other projects to run their tests on PyPy +* How do we grow the community? + * Advertise sprints more widely + * steal some cpython devs? + * move away from bitbucket.org? + * beginner mentoring program + * blog posts, videos + * "PyPy internals for CPython devs" + * twitch streams? + * docs are a mess + * success stories on the web page +* What can we stop doing (brainstorming) + * dropping platforms? + * maintain own fork of pytest + * using less custom infrastructure + +## disjointed benchmarking notes +* ask whether we can use speed.python.org +* run benchmarks weekly +* + +## dummy From pypy.commits at gmail.com Tue Jul 9 04:58:45 2019 From: pypy.commits at gmail.com (cfbolz) Date: Tue, 09 Jul 2019 01:58:45 -0700 (PDT) Subject: [pypy-commit] extradoc extradoc: extract some tasks from sprint notes Message-ID: <5d245745.1c69fb81.a02b0.b751@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: extradoc Changeset: r5949:403b76c0b9d3 Date: 2019-02-14 13:51 +0100 http://bitbucket.org/pypy/extradoc/changeset/403b76c0b9d3/ Log: extract some tasks from sprint notes diff --git a/planning/sprint-düsseldorf-2019-notes.md b/planning/sprint-düsseldorf-2019-notes.md new file mode 100644 --- /dev/null +++ b/planning/sprint-düsseldorf-2019-notes.md @@ -0,0 +1,30 @@ +## Tasks + +- Let's try to have team-internal "office hours" Monday 10.00-13.00 (CET) + to deal with the reduced availability of people + +- Set up benchmarking machine + - ask whether we can use speed.python.org + - run benchmarks weekly + +- Write Py3 SFC proposal +- Write CPyExt SFC proposal +- Write website SFC proposal +- Write buildbots/infrastructure SFC proposal? + +- Bring Cython Oracle collaboration forward + +- try to build pypy on manylinux2010 +- talk to conda people about pypy on conda? + +- write a PEP about inter-implementation issues + +- get big projects to add PyPy 3.6 to their testing infrastructure + +- set up ARM32 builder via chroot on ARM64 machine + + +- look at examples for C-extensions on python.org and make sure they work on + PyPy + +- progress on vmprof From pypy.commits at gmail.com Tue Jul 9 04:58:47 2019 From: pypy.commits at gmail.com (cfbolz) Date: Tue, 09 Jul 2019 01:58:47 -0700 (PDT) Subject: [pypy-commit] extradoc extradoc: merge heads Message-ID: <5d245747.1c69fb81.486ae.d126@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: extradoc Changeset: r5950:35ad47c08926 Date: 2019-07-09 10:58 +0200 http://bitbucket.org/pypy/extradoc/changeset/35ad47c08926/ Log: merge heads diff --git a/talk/synerise2019/talk.key b/talk/synerise2019/talk.key new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5bb346ed50268b9dd456d2cc1505d2f05caab4d1 GIT binary patch [cut] diff --git a/talk/synerise2019/talk.pdf b/talk/synerise2019/talk.pdf new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..3745b05f0578ffeb7c1a931dd1c4110bede1e840 GIT binary patch [cut] From pypy.commits at gmail.com Tue Jul 9 09:11:16 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 09 Jul 2019 06:11:16 -0700 (PDT) Subject: [pypy-commit] pypy arm64: Disable '__thread'. Seems to fix things on aarch64, but we'll see if it's just Message-ID: <5d249274.1c69fb81.67af8.0dbd@mx.google.com> Author: Armin Rigo Branch: arm64 Changeset: r96956:a5c8b974cdfc Date: 2019-07-09 15:10 +0200 http://bitbucket.org/pypy/pypy/changeset/a5c8b974cdfc/ Log: Disable '__thread'. Seems to fix things on aarch64, but we'll see if it's just cause by random memory corruption or is really related. diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py --- a/rpython/config/translationoption.py +++ b/rpython/config/translationoption.py @@ -1,5 +1,6 @@ import sys import os +import platform as _stdlib_platform from rpython.config.config import OptionDescription, BoolOption, IntOption, ArbitraryOption, FloatOption from rpython.config.config import ChoiceOption, StrOption, Config, ConflictConfigError from rpython.config.config import ConfigError @@ -30,7 +31,9 @@ False) # Windows doesn't work. Please # add other platforms here if it works on them. - +MACHINE = _stdlib_platform.machine() +if MACHINE == 'aarch64': + SUPPORT__THREAD = False # (*) NOTE: __thread on OS/X does not work together with # pthread_key_create(): when the destructor is called, the __thread is # already freed! From pypy.commits at gmail.com Wed Jul 10 15:21:00 2019 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 10 Jul 2019 12:21:00 -0700 (PDT) Subject: [pypy-commit] pypy default: (Luanna, cfbolz): add rbigint.gcd to compute the greatest common divisor of two Message-ID: <5d263a9c.1c69fb81.3caa6.1fc7@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: Changeset: r96957:bf3310921e45 Date: 2019-07-10 13:38 +0200 http://bitbucket.org/pypy/pypy/changeset/bf3310921e45/ Log: (Luanna, cfbolz): add rbigint.gcd to compute the greatest common divisor of two rbigint instances using Lehmer's algorithm: https://bitbucket.org/pypy/pypy/issues/3031/mathgcd-much-slower- than-cpython https://en.wikipedia.org/wiki/Lehmer's_GCD_algorithm diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py --- a/rpython/rlib/rbigint.py +++ b/rpython/rlib/rbigint.py @@ -1423,6 +1423,12 @@ bits = ovfcheck((i-1) * SHIFT) + msd_bits return bits + def gcd(self, other): + """ Compute the (always positive) greatest common divisor of self and + other """ + return gcd_lehmer(self.abs(), other.abs()) + + def __repr__(self): return "" % (self._digits, self.sign, self.numdigits(), len(self._digits), @@ -2960,3 +2966,88 @@ z.setdigit(pdigit, accum) z._normalize() return z + + +def gcd_binary(a, b): + if a == 0: + return b + + if b == 0: + return a + + a, b = abs(a), abs(b) + + shift = 0 + while (a | b) & 1 == 0: + a >>= 1 + b >>= 1 + shift += 1 + + while a & 1 == 0: + a >>= 1 + + while b & 1 == 0: + b >>= 1 + + while a != b: + a, b = abs(a - b), min(a, b) + while a & 1 == 0: + a >>= 1 + + return a << shift + +def lehmer_xgcd(a, b): + s_old, s_new = 1, 0 + t_old, t_new = 0, 1 + while b >> (SHIFT >> 1): + q, r = a // b, a % b + + a, b = b, r + s_old, s_new = s_new, s_old - q * s_new + t_old, t_new = t_new, t_old - q * t_new + + return s_old, t_old, s_new, t_new + +def gcd_lehmer(a, b): + if a.lt(b): + a, b = b, a + + while b.size > 1: + a_ms = a.digit(a.size-1) + + x = 0 + while a_ms & (0xFF << SHIFT-8) == 0: + a_ms <<= 8 + x += 8 + + while a_ms & (1 << SHIFT-1) == 0: + a_ms <<= 1 + x += 1 + + a_ms |= a.digit(a.size-2) >> SHIFT-x + + if a.size == b.size: + b_ms = (b.digit(b.size-1) << x) | (b.digit(b.size-2) >> SHIFT-x) + elif a.size == b.size+1: + b_ms = b.digit(b.size-1) >> SHIFT-x + else: + b_ms = 0 + + if b_ms >> (SHIFT+1 >> 1) == 0: + a, b = b, a.mod(b) + continue + + s_old, t_old, s_new, t_new = lehmer_xgcd(a_ms, b_ms) + + n_a = a.int_mul(s_new).add(b.int_mul(t_new)).abs() + b = a.int_mul(s_old).add(b.int_mul(t_old)).abs() + a = n_a + + if a.lt(b): + a, b = b, a + + if not b.tobool(): + return a + + a = a.mod(b) + return rbigint.fromint(gcd_binary(b.toint(), a.toint())) diff --git a/rpython/rlib/test/test_rbigint.py b/rpython/rlib/test/test_rbigint.py --- a/rpython/rlib/test/test_rbigint.py +++ b/rpython/rlib/test/test_rbigint.py @@ -11,12 +11,13 @@ from rpython.rlib import rbigint as lobj from rpython.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask from rpython.rlib.rbigint import (rbigint, SHIFT, MASK, KARATSUBA_CUTOFF, - _store_digit, _mask_digit, InvalidEndiannessError, InvalidSignednessError) + _store_digit, _mask_digit, InvalidEndiannessError, InvalidSignednessError, + gcd_lehmer, lehmer_xgcd, gcd_binary) from rpython.rlib.rfloat import NAN from rpython.rtyper.test.test_llinterp import interpret from rpython.translator.c.test.test_standalone import StandaloneTests -from hypothesis import given, strategies, example +from hypothesis import given, strategies, example, settings longs = strategies.builds( long, strategies.integers()) @@ -836,6 +837,27 @@ t = bigint.tobytes(len(s), byteorder=byteorder, signed=signed) assert s == t + def test_gcd(self): + assert gcd_binary(2*3*7**2, 2**2*7) == 2*7 + assert gcd_binary(-2*3*7**2, 2**2*7) == 2*7 + assert gcd_binary(2*3*7**2, -2**2*7) == 2*7 + assert gcd_binary(-2*3*7**2, -2**2*7) == 2*7 + assert gcd_binary(1234, 5678) == 2 + assert gcd_binary(13, 13**6) == 13 + assert gcd_binary(12, 0) == 12 + assert gcd_binary(0, 0) == 0 + + x = rbigint.fromlong(9969216677189303386214405760200) + y = rbigint.fromlong(16130531424904581415797907386349) + g = x.gcd(y) + assert g == rbigint.fromlong(1) + + for x in gen_signs([12843440367927679363613699686751681643652809878241019930204617606850071260822269719878805]): + x = rbigint.fromlong(x) + for y in gen_signs([12372280584571061381380725743231391746505148712246738812788540537514927882776203827701778968535]): + y = rbigint.fromlong(y) + g = x.gcd(y) + assert g.tolong() == 18218089570126697993340888567155155527541105 class TestInternalFunctions(object): @@ -1255,3 +1277,52 @@ assert lx.lt(ly) == (x < y) assert lx.eq(ly) == (x == y) assert lx.le(ly) == (x <= y) + + @given(ints, ints, ints) + def test_gcd_binary(self, x, y, z): + x, y, z = abs(x), abs(y), abs(z) + + def test(a, b, res): + g = gcd_binary(a, b) + + assert g == res + + a, b = x, y + while b: + a, b = b, a % b + + gcd_x_y = a + + test(x, y, gcd_x_y) + test(x, 0, x) + test(0, x, x) + test(x * z, y * z, gcd_x_y * z) + test(x * z, z, z) + test(z, y * z, z) + + @given(biglongs, biglongs, biglongs) + @example(112233445566778899112233445566778899112233445566778899, + 13579246801357924680135792468013579246801, + 99887766554433221113) + @settings(max_examples=10) + def test_gcd(self, x, y, z): + print(x, y, z) + x, y, z = abs(x), abs(y), abs(z) + + def test(a, b, res): + g = rbigint.fromlong(a).gcd(rbigint.fromlong(b)).tolong() + + assert g == res + + a, b = x, y + while b: + a, b = b, a % b + + gcd_x_y = a + + test(x, y, gcd_x_y) + test(x * z, y * z, gcd_x_y * z) + test(x * z, z, z) + test(z, y * z, z) + test(x, 0, x) + test(0, x, x) diff --git a/rpython/translator/goal/targetbigintbenchmark.py b/rpython/translator/goal/targetbigintbenchmark.py --- a/rpython/translator/goal/targetbigintbenchmark.py +++ b/rpython/translator/goal/targetbigintbenchmark.py @@ -251,8 +251,19 @@ sumTime += _time print "v = v + v", _time + x = rbigint.fromstr("13579246801357924680135792468013579246801") + y = rbigint.fromstr("112233445566778899112233445566778899112233445566778899") + t = time() + for i in range(5000): + x.gcd(y) + x = x.int_mul(2).int_add(1) + _time = time() - t + print "gcd", _time + + sumTime += _time + print "Sum: ", sumTime - + return 0 # _____ Define and setup target ___ From pypy.commits at gmail.com Wed Jul 10 15:21:02 2019 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 10 Jul 2019 12:21:02 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: merge default Message-ID: <5d263a9e.1c69fb81.d2d9f.03a0@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r96958:5a7ab6765acf Date: 2019-07-10 13:38 +0200 http://bitbucket.org/pypy/pypy/changeset/5a7ab6765acf/ Log: merge default 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 @@ -532,26 +532,22 @@ def gen_shadowstack_header(self, gcrootmap): # lr = shadow stack top addr - # r4 = *lr + # ip = *lr rst = gcrootmap.get_root_stack_top_addr() self.mc.gen_load_int(r.lr.value, rst) - self.load_reg(self.mc, r.r4, r.lr) - # *r4 = 1 - # the '1' is to benefit from the shadowstack 'is_minor' optimization - self.mc.gen_load_int(r.ip.value, 1) - self.store_reg(self.mc, r.ip, r.r4) - # *(r4+WORD) = r.fp - self.store_reg(self.mc, r.fp, r.r4, WORD) + self.load_reg(self.mc, r.ip, r.lr) + # *ip = r.fp + self.store_reg(self.mc, r.fp, r.ip) # - self.mc.ADD_ri(r.r4.value, r.r4.value, 2 * WORD) - # *lr = r4 + 2 * WORD - self.store_reg(self.mc, r.r4, r.lr) + self.mc.ADD_ri(r.ip.value, r.ip.value, WORD) + # *lr = ip + WORD + self.store_reg(self.mc, r.ip, r.lr) def gen_footer_shadowstack(self, gcrootmap, mc): rst = gcrootmap.get_root_stack_top_addr() mc.gen_load_int(r.ip.value, rst) self.load_reg(mc, r.r4, r.ip) - mc.SUB_ri(r.r4.value, r.r4.value, 2 * WORD) + mc.SUB_ri(r.r4.value, r.r4.value, WORD) self.store_reg(mc, r.r4, r.ip) def _dump(self, ops, type='loop'): 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 @@ -373,6 +373,10 @@ if box.type == REF and self.rm.is_still_alive(box): assert not noregs assert loc.is_core_reg() + #val = self.cpu.all_reg_indexes[loc.value] + # ^^^ That is the correct way to write it down, but as a + # special case in the arm backend only, this is equivalent + # to just the line below: val = loc.value gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8)) for box, loc in self.fm.bindings.iteritems(): diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py --- a/rpython/rlib/rbigint.py +++ b/rpython/rlib/rbigint.py @@ -1423,6 +1423,12 @@ bits = ovfcheck((i-1) * SHIFT) + msd_bits return bits + def gcd(self, other): + """ Compute the (always positive) greatest common divisor of self and + other """ + return gcd_lehmer(self.abs(), other.abs()) + + def __repr__(self): return "" % (self._digits, self.sign, self.numdigits(), len(self._digits), @@ -2960,3 +2966,88 @@ z.setdigit(pdigit, accum) z._normalize() return z + + +def gcd_binary(a, b): + if a == 0: + return b + + if b == 0: + return a + + a, b = abs(a), abs(b) + + shift = 0 + while (a | b) & 1 == 0: + a >>= 1 + b >>= 1 + shift += 1 + + while a & 1 == 0: + a >>= 1 + + while b & 1 == 0: + b >>= 1 + + while a != b: + a, b = abs(a - b), min(a, b) + while a & 1 == 0: + a >>= 1 + + return a << shift + +def lehmer_xgcd(a, b): + s_old, s_new = 1, 0 + t_old, t_new = 0, 1 + while b >> (SHIFT >> 1): + q, r = a // b, a % b + + a, b = b, r + s_old, s_new = s_new, s_old - q * s_new + t_old, t_new = t_new, t_old - q * t_new + + return s_old, t_old, s_new, t_new + +def gcd_lehmer(a, b): + if a.lt(b): + a, b = b, a + + while b.size > 1: + a_ms = a.digit(a.size-1) + + x = 0 + while a_ms & (0xFF << SHIFT-8) == 0: + a_ms <<= 8 + x += 8 + + while a_ms & (1 << SHIFT-1) == 0: + a_ms <<= 1 + x += 1 + + a_ms |= a.digit(a.size-2) >> SHIFT-x + + if a.size == b.size: + b_ms = (b.digit(b.size-1) << x) | (b.digit(b.size-2) >> SHIFT-x) + elif a.size == b.size+1: + b_ms = b.digit(b.size-1) >> SHIFT-x + else: + b_ms = 0 + + if b_ms >> (SHIFT+1 >> 1) == 0: + a, b = b, a.mod(b) + continue + + s_old, t_old, s_new, t_new = lehmer_xgcd(a_ms, b_ms) + + n_a = a.int_mul(s_new).add(b.int_mul(t_new)).abs() + b = a.int_mul(s_old).add(b.int_mul(t_old)).abs() + a = n_a + + if a.lt(b): + a, b = b, a + + if not b.tobool(): + return a + + a = a.mod(b) + return rbigint.fromint(gcd_binary(b.toint(), a.toint())) diff --git a/rpython/rlib/test/test_rbigint.py b/rpython/rlib/test/test_rbigint.py --- a/rpython/rlib/test/test_rbigint.py +++ b/rpython/rlib/test/test_rbigint.py @@ -11,12 +11,13 @@ from rpython.rlib import rbigint as lobj from rpython.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask from rpython.rlib.rbigint import (rbigint, SHIFT, MASK, KARATSUBA_CUTOFF, - _store_digit, _mask_digit, InvalidEndiannessError, InvalidSignednessError) + _store_digit, _mask_digit, InvalidEndiannessError, InvalidSignednessError, + gcd_lehmer, lehmer_xgcd, gcd_binary) from rpython.rlib.rfloat import NAN from rpython.rtyper.test.test_llinterp import interpret from rpython.translator.c.test.test_standalone import StandaloneTests -from hypothesis import given, strategies, example +from hypothesis import given, strategies, example, settings longs = strategies.builds( long, strategies.integers()) @@ -836,6 +837,27 @@ t = bigint.tobytes(len(s), byteorder=byteorder, signed=signed) assert s == t + def test_gcd(self): + assert gcd_binary(2*3*7**2, 2**2*7) == 2*7 + assert gcd_binary(-2*3*7**2, 2**2*7) == 2*7 + assert gcd_binary(2*3*7**2, -2**2*7) == 2*7 + assert gcd_binary(-2*3*7**2, -2**2*7) == 2*7 + assert gcd_binary(1234, 5678) == 2 + assert gcd_binary(13, 13**6) == 13 + assert gcd_binary(12, 0) == 12 + assert gcd_binary(0, 0) == 0 + + x = rbigint.fromlong(9969216677189303386214405760200) + y = rbigint.fromlong(16130531424904581415797907386349) + g = x.gcd(y) + assert g == rbigint.fromlong(1) + + for x in gen_signs([12843440367927679363613699686751681643652809878241019930204617606850071260822269719878805]): + x = rbigint.fromlong(x) + for y in gen_signs([12372280584571061381380725743231391746505148712246738812788540537514927882776203827701778968535]): + y = rbigint.fromlong(y) + g = x.gcd(y) + assert g.tolong() == 18218089570126697993340888567155155527541105 class TestInternalFunctions(object): @@ -1255,3 +1277,52 @@ assert lx.lt(ly) == (x < y) assert lx.eq(ly) == (x == y) assert lx.le(ly) == (x <= y) + + @given(ints, ints, ints) + def test_gcd_binary(self, x, y, z): + x, y, z = abs(x), abs(y), abs(z) + + def test(a, b, res): + g = gcd_binary(a, b) + + assert g == res + + a, b = x, y + while b: + a, b = b, a % b + + gcd_x_y = a + + test(x, y, gcd_x_y) + test(x, 0, x) + test(0, x, x) + test(x * z, y * z, gcd_x_y * z) + test(x * z, z, z) + test(z, y * z, z) + + @given(biglongs, biglongs, biglongs) + @example(112233445566778899112233445566778899112233445566778899, + 13579246801357924680135792468013579246801, + 99887766554433221113) + @settings(max_examples=10) + def test_gcd(self, x, y, z): + print(x, y, z) + x, y, z = abs(x), abs(y), abs(z) + + def test(a, b, res): + g = rbigint.fromlong(a).gcd(rbigint.fromlong(b)).tolong() + + assert g == res + + a, b = x, y + while b: + a, b = b, a % b + + gcd_x_y = a + + test(x, y, gcd_x_y) + test(x * z, y * z, gcd_x_y * z) + test(x * z, z, z) + test(z, y * z, z) + test(x, 0, x) + test(0, x, x) diff --git a/rpython/translator/goal/targetbigintbenchmark.py b/rpython/translator/goal/targetbigintbenchmark.py --- a/rpython/translator/goal/targetbigintbenchmark.py +++ b/rpython/translator/goal/targetbigintbenchmark.py @@ -251,8 +251,19 @@ sumTime += _time print "v = v + v", _time + x = rbigint.fromstr("13579246801357924680135792468013579246801") + y = rbigint.fromstr("112233445566778899112233445566778899112233445566778899") + t = time() + for i in range(5000): + x.gcd(y) + x = x.int_mul(2).int_add(1) + _time = time() - t + print "gcd", _time + + sumTime += _time + print "Sum: ", sumTime - + return 0 # _____ Define and setup target ___ From pypy.commits at gmail.com Wed Jul 10 15:21:04 2019 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 10 Jul 2019 12:21:04 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: (Luanna): integrate new gcd algorithm into the pypy math module Message-ID: <5d263aa0.1c69fb81.ba0a4.6a36@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r96959:aa95fe7b71b4 Date: 2019-07-10 13:46 +0200 http://bitbucket.org/pypy/pypy/changeset/aa95fe7b71b4/ Log: (Luanna): integrate new gcd algorithm into the pypy math module diff --git a/pypy/module/math/__init__.py b/pypy/module/math/__init__.py --- a/pypy/module/math/__init__.py +++ b/pypy/module/math/__init__.py @@ -5,7 +5,6 @@ class Module(MixedModule): appleveldefs = { 'factorial' : 'app_math.factorial', - 'gcd' : 'app_math.gcd', } interpleveldefs = { @@ -57,5 +56,6 @@ 'gamma' : 'interp_math.gamma', 'lgamma' : 'interp_math.lgamma', 'isclose' : 'interp_math.isclose', + 'gcd' : 'interp_math.gcd', } diff --git a/pypy/module/math/app_math.py b/pypy/module/math/app_math.py --- a/pypy/module/math/app_math.py +++ b/pypy/module/math/app_math.py @@ -47,10 +47,3 @@ res, _, shift = _fac1(x) return res << shift -def gcd(x, y): - """greatest common divisor of x and y""" - x = abs(index(x)) - y = abs(index(y)) - while x > 0: - x, y = y % x, x - return y diff --git a/pypy/module/math/interp_math.py b/pypy/module/math/interp_math.py --- a/pypy/module/math/interp_math.py +++ b/pypy/module/math/interp_math.py @@ -484,3 +484,23 @@ diff <= math.fabs(rel_tol * a)) or diff <= abs_tol) return space.newbool(result) + + +def gcd(space, w_a, w_b): + """greatest common divisor of a and b""" + from rpython.rlib import rbigint + w_a = space.abs(space.index(w_a)) + w_b = space.abs(space.index(w_b)) + try: + a = space.int_w(w_a) + b = space.int_w(w_b) + g = rbigint.gcd_binary(a, b) + return space.newint(g) + except OperationError as e: + if not e.match(space, space.w_OverflowError): + raise + + a = space.bigint_w(w_a) + b = space.bigint_w(w_b) + g = a.gcd(b) + return space.newlong_from_rbigint(g) diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -371,6 +371,8 @@ assert math.gcd(0, -10) == 10 assert math.gcd(0, 0) == 0 raises(TypeError, math.gcd, 0, 0.0) + assert math.gcd(-3**10*5**20*11**8, 2**5*3**5*7**20) == 3**5 + assert math.gcd(64, 200) == 8 def test_inf_nan(self): import math From pypy.commits at gmail.com Wed Jul 10 15:21:06 2019 From: pypy.commits at gmail.com (cfbolz) Date: Wed, 10 Jul 2019 12:21:06 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: no need to call abs twice Message-ID: <5d263aa2.1c69fb81.f6d50.d3e3@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r96960:de29534e71f5 Date: 2019-07-10 15:11 +0200 http://bitbucket.org/pypy/pypy/changeset/de29534e71f5/ Log: no need to call abs twice diff --git a/pypy/module/math/interp_math.py b/pypy/module/math/interp_math.py --- a/pypy/module/math/interp_math.py +++ b/pypy/module/math/interp_math.py @@ -489,8 +489,8 @@ def gcd(space, w_a, w_b): """greatest common divisor of a and b""" from rpython.rlib import rbigint - w_a = space.abs(space.index(w_a)) - w_b = space.abs(space.index(w_b)) + w_a = space.index(w_a) + w_b = space.index(w_b) try: a = space.int_w(w_a) b = space.int_w(w_b) From pypy.commits at gmail.com Wed Jul 10 16:42:11 2019 From: pypy.commits at gmail.com (Stian Andreassen) Date: Wed, 10 Jul 2019 13:42:11 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: ~1% speedup to GCD. Message-ID: <5d264da3.1c69fb81.8ac23.3ca8@mx.google.com> Author: Stian Andreassen Branch: py3.6 Changeset: r96961:ab71ab09aca2 Date: 2019-07-10 22:41 +0200 http://bitbucket.org/pypy/pypy/changeset/ab71ab09aca2/ Log: ~1% speedup to GCD. diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py --- a/rpython/rlib/rbigint.py +++ b/rpython/rlib/rbigint.py @@ -3013,7 +3013,7 @@ a, b = b, a while b.size > 1: - a_ms = a.digit(a.size-1) + a_ms = a.digit(abs(a.size-1)) x = 0 while a_ms & (0xFF << SHIFT-8) == 0: @@ -3024,12 +3024,12 @@ a_ms <<= 1 x += 1 - a_ms |= a.digit(a.size-2) >> SHIFT-x + a_ms |= a.digit(abs(a.size-2)) >> SHIFT-x if a.size == b.size: - b_ms = (b.digit(b.size-1) << x) | (b.digit(b.size-2) >> SHIFT-x) + b_ms = (b.digit(abs(b.size-1)) << x) | (b.digit(abs(b.size-2)) >> SHIFT-x) elif a.size == b.size+1: - b_ms = b.digit(b.size-1) >> SHIFT-x + b_ms = b.digit(abs(b.size-1)) >> SHIFT-x else: b_ms = 0 From pypy.commits at gmail.com Thu Jul 11 04:46:35 2019 From: pypy.commits at gmail.com (Raemi) Date: Thu, 11 Jul 2019 01:46:35 -0700 (PDT) Subject: [pypy-commit] benchmarks multithread-runner: There is possibly a bug in the printstream implementation when running Message-ID: <5d26f76b.1c69fb81.0ac3.82ed@mx.google.com> Author: Remi Meier Branch: multithread-runner Changeset: r381:fdeed4fc15f1 Date: 2016-07-14 09:06 +0200 http://bitbucket.org/pypy/benchmarks/changeset/fdeed4fc15f1/ Log: There is possibly a bug in the printstream implementation when running richards on many threads. Thus, for now, we do less printing. diff --git a/multithread/richards/richards.py b/multithread/richards/richards.py --- a/multithread/richards/richards.py +++ b/multithread/richards/richards.py @@ -371,12 +371,12 @@ self.finished_lock.acquire() def run_and_unlock(self, count): - print 'running...' + #print 'running...' iterations = 0 self.result = True for i in range(count): self.result = self.run() - print 'done, iterations=%d, result=%r' % (count, self.result) + #print 'done, iterations=%d, result=%r' % (count, self.result) self.finished_lock.release() def run(self): From pypy.commits at gmail.com Thu Jul 11 04:46:37 2019 From: pypy.commits at gmail.com (Raemi) Date: Thu, 11 Jul 2019 01:46:37 -0700 (PDT) Subject: [pypy-commit] benchmarks multithread-runner: initial adaption for running multithreaded on JIT Message-ID: <5d26f76d.1c69fb81.d5363.9843@mx.google.com> Author: Remi Meier Branch: multithread-runner Changeset: r382:5f5a5345c51c Date: 2016-07-14 09:47 +0200 http://bitbucket.org/pypy/benchmarks/changeset/5f5a5345c51c/ Log: initial adaption for running multithreaded on JIT diff --git a/multithread/btree/btree.py b/multithread/btree/btree.py --- a/multithread/btree/btree.py +++ b/multithread/btree/btree.py @@ -312,7 +312,7 @@ ###################################################################### CONFLICTING = [BTree.insert, BTree.remove] -OPS = [BTree.__contains__] * 198 + CONFLICTING +OPS = [BTree.__contains__] * 1998 + CONFLICTING ITEM_RANGE = 10000 diff --git a/multithread/config-all-long.json b/multithread/config-all-long.json new file mode 100644 --- /dev/null +++ b/multithread/config-all-long.json @@ -0,0 +1,68 @@ +{ + "defaults": { + "file": null, + "threads": [1, 2, 4, 8], + "vmstarts": 1, + "warmiters": 1, + "PYTHONPATH": ".", + "args": [], + "cwd": "." + }, + + "benchs": { + "nqueens": { + "file": "nqueens/nqueens.py", + "PYTHONPATH": "..", + "args": ["10"] + }, + + "parsible-bench": { + "file": "parsible-bench/parsible-bench.py", + "PYTHONPATH": ".." + }, + + "mersenne": { + "file": "mersenne/mersenne.py", + "PYTHONPATH": "..", + "args": ["3000"] + }, + + "richards": { + "file": "richards/richards.py", + "PYTHONPATH": "..", + "args": ["10000"] + }, + + "mandelbrot": { + "file": "mandelbrot/mandelbrot.py", + "PYTHONPATH": "..", + "args": ["128", "4096", "2048"] + }, + + "btree": { + "file": "btree/btree.py", + "PYTHONPATH": "..", + "args": ["32", "8000000"] + }, + + "skiplist": { + "file": "skiplist/skiplist.py", + "PYTHONPATH": "..", + "args": ["32", "6000000"] + }, + + "raytrace": { + "file": "raytrace/raytrace.py", + "PYTHONPATH": "..", + "args": ["4096", "4096"] + }, + + "perlin": { + "file": "perlin_noise/perlin_noise.py", + "PYTHONPATH": "..", + "args": ["5"] + } + + } + +} diff --git a/multithread/nqueens/nqueens.py b/multithread/nqueens/nqueens.py --- a/multithread/nqueens/nqueens.py +++ b/multithread/nqueens/nqueens.py @@ -74,7 +74,7 @@ print "params (iters, threads, n):", warmiters, threads, n print "do warmup:" - for i in range(3): + for i in range(4): t = run(threads, n) print "iter", i, "time:", t diff --git a/multithread/parsible-bench/parsible-bench.py b/multithread/parsible-bench/parsible-bench.py --- a/multithread/parsible-bench/parsible-bench.py +++ b/multithread/parsible-bench/parsible-bench.py @@ -35,7 +35,7 @@ print "params (iters, threads):", warmiters, threads print "do warmup:" - for i in range(4): + for i in range(6): print "iter", i, "time:", run(threads) print "turn off jitting" diff --git a/multithread/perlin_noise/perlin_noise.py b/multithread/perlin_noise/perlin_noise.py --- a/multithread/perlin_noise/perlin_noise.py +++ b/multithread/perlin_noise/perlin_noise.py @@ -99,7 +99,9 @@ print "params (iters, threads, n):", warmiters, threads, n print "do warmup:" - for i in range(2): + # JIT compiles *tons* of bridges for the perlin_noise function + # turning it off after /some/ warmup speeds it up by 10x + for i in range(1): t = time.time() run(threads, n) print "iter", i, "time:", time.time() - t diff --git a/multithread/richards/richards.py b/multithread/richards/richards.py --- a/multithread/richards/richards.py +++ b/multithread/richards/richards.py @@ -8,7 +8,10 @@ # Outer loop added by Alex Jacoby import thread, os -from common.abstract_threading import atomic, hint_commit_soon +from common.abstract_threading import ( + atomic, Future, set_thread_pool, ThreadPool, + hint_commit_soon, turn_jitting_off) + # Task IDs I_IDLE = 1 @@ -442,7 +445,12 @@ print "params:", warmiters, threads, iterations print "do warmup:" - result, startTime, endTime = entry_point(4, threads) + entry_point(iterations, threads) + entry_point(iterations, threads) + entry_point(iterations, threads) + + print "turn off jitting" + turn_jitting_off() print "do", warmiters, "real iters:" times = [] diff --git a/multithread/skiplist/skiplist.py b/multithread/skiplist/skiplist.py --- a/multithread/skiplist/skiplist.py +++ b/multithread/skiplist/skiplist.py @@ -91,7 +91,7 @@ CONFLICTING = [SkipList.insert, SkipList.remove] -OPS = [SkipList.find] * 198 + CONFLICTING +OPS = [SkipList.find] * 1998 + CONFLICTING ITEM_RANGE = 1000000 def task(id, slist, ops): From pypy.commits at gmail.com Thu Jul 11 04:46:40 2019 From: pypy.commits at gmail.com (Raemi) Date: Thu, 11 Jul 2019 01:46:40 -0700 (PDT) Subject: [pypy-commit] benchmarks multithread-runner: add benchmark from benchmarksgame Message-ID: <5d26f770.1c69fb81.969b3.8458@mx.google.com> Author: Remi Meier Branch: multithread-runner Changeset: r383:6a08892ee056 Date: 2016-07-22 09:08 +0200 http://bitbucket.org/pypy/benchmarks/changeset/6a08892ee056/ Log: add benchmark from benchmarksgame diff too long, truncating to 2000 out of 111978 lines diff --git a/multithread/regex-dna/regex-dna.py b/multithread/regex-dna/regex-dna.py new file mode 100644 --- /dev/null +++ b/multithread/regex-dna/regex-dna.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- + +import gc +import sys +import time +from common.abstract_threading import ( + atomic, Future, set_thread_pool, ThreadPool, + hint_commit_soon, turn_jitting_off) + + +# Revised BSD license +# This is a specific instance of the Open Source Initiative (OSI) BSD license template. +# Copyright (c) 2004-2008 Brent Fulgham, 2005-2016 Isaac Gouy +# All rights reserved. +# The Computer Language Benchmarks Game +# http://shootout.alioth.debian.org/ +# contributed by Dominique Wahli +# 2to3 +# mp by Ahmad Syukri +# modified by Justin Peel + +from sys import stdin +from re import sub, findall + + +def var_find(f, seq): + return len(findall(f, seq)) + +def main_b(): + with open('regexdna-inputYYY.txt', 'r') as f: + seq = f.read() + ilen = len(seq) + + seq = sub('>.*\n|\n', '', seq) + clen = len(seq) + + + variants = ( + 'agggtaaa|tttaccct', + '[cgt]gggtaaa|tttaccc[acg]', + 'a[act]ggtaaa|tttacc[agt]t', + 'ag[act]gtaaa|tttac[agt]ct', + 'agg[act]taaa|ttta[agt]cct', + 'aggg[acg]aaa|ttt[cgt]ccct', + 'agggt[cgt]aa|tt[acg]accct', + 'agggta[cgt]a|t[acg]taccct', + 'agggtaa[cgt]|[acg]ttaccct') + + t = time.time() + fs = [Future(var_find, v, seq) for v in variants] + for f in zip(variants, fs): + print(f[0], f[1]()) + t = time.time() - t + + subst = { + 'B' : '(c|g|t)', 'D' : '(a|g|t)', 'H' : '(a|c|t)', 'K' : '(g|t)', + 'M' : '(a|c)', 'N' : '(a|c|g|t)', 'R' : '(a|g)', 'S' : '(c|g)', + 'V' : '(a|c|g)', 'W' : '(a|t)', 'Y' : '(c|t)'} + for f, r in list(subst.items()): + seq = sub(f, r, seq) + + print() + print(ilen) + print(clen) + print(len(seq)) + return t + + +def run(threads=2): + threads = int(threads) + + set_thread_pool(ThreadPool(threads)) + + t = main_b() + + # shutdown current pool + set_thread_pool(None) + return t + +def main(argv): + # warmiters threads args... + warmiters = int(argv[0]) + threads = int(argv[1]) + + print "params (iters, threads):", warmiters, threads + + print "do warmup:" + for i in range(4): + t = run(threads) + print "iter", i, "time:", t + + print "turn off jitting" + turn_jitting_off() + print "do", warmiters, "real iters:" + times = [] + for i in range(warmiters): + gc.collect() + + t = run(threads) + times.append(t) + print "warmiters:", times + +if __name__ == "__main__": + import sys + main(sys.argv[1:]) diff --git a/multithread/regex-dna/regexdna-input10000.txt b/multithread/regex-dna/regexdna-input10000.txt new file mode 100644 --- /dev/null +++ b/multithread/regex-dna/regexdna-input10000.txt @@ -0,0 +1,1671 @@ +>ONE Homo sapiens alu +GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA +TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT +AAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG +GCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG +CCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT +GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA +GGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA +TTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG +AATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA +GCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGT +AATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACC +AGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTG +GTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACC +CGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAG +AGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTT +TGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACA +TGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCT +GTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGG +TTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGT +CTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGG +CGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCG +TCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTA +CTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCG +AGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCG +GGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACC +TGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAA +TACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGA +GGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACT +GCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTC +ACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGT +TCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGC +CGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCG +CTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTG +GGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCC +CAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCT +GGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGC +GCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGA +GGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGA +GACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGA +GGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTG +AAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT +CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCA +GTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAA +AAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGC +GGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCT +ACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGG +GAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATC +GCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGC +GGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGG +TCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAA +AAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAG +GAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACT +CCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCC +TGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAG +ACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGC +GTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGA +ACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGA +CAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCA +CTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCA +ACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCG +CCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGG +AGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTC +CGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCG +AGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACC +CCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAG +CTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAG +CCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGG +CCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATC +ACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAA +AAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGC +TGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCC +ACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGG +CTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGG +AGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATT +AGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAA +TCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGC +CTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAA +TCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAG +CCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGT +GGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCG +GGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAG +CGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG +GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATG +GTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGT +AATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTT +GCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCT +CAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCG +GGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTC +TCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACT +CGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAG +ATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGG +CGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTG +AGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATA +CAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGG +CAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGC +ACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCAC +GCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTC +GAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCG +GGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCT +TGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGG +CGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCA +GCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGG +CCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGC +GCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGG +CGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGA +CTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGG +CCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAA +ACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCC +CAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGT +GAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAA +AGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGG +ATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTAC +TAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGA +GGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGC +GCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGG +TGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTC +AGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAA +ATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGA +GAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC +AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTG +TAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGAC +CAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGT +GGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC +CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACA +GAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACT +TTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAAC +ATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCC +TGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAG +GTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCG +TCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAG +GCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCC +GTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCT +ACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCC +GAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCC +GGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCAC +CTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAA +ATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTG +AGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCAC +TGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCT +CACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAG +TTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAG +CCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATC +GCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCT +GGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATC +CCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCC +TGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGG +CGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG +AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCG +AGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGG +AGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGT +GAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAA +TCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGC +AGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCA +AAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGG +CGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTC +TACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCG +GGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGAT +CGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCG +CGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAG +GTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACA +AAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCA +GGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCAC +TCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGC +CTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA +GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGG +CGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTG +AACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCG +ACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGC +ACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCC +AACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGC +GCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCG +GAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACT +CCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCC +GAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAAC +CCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA +GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGA +GCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAG +GCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGAT +CACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTA +AAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGG +CTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGC +CACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTG +GCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAG +GAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAAT +TAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGA +ATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAG +CCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTA +ATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCA +GCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGG +TGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCC +GGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGA +GCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTT +GGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACAT +GGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTG +TAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGT +TGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTC +TCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGC +GGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGT +CTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTAC +TCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGA +GATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGG +GCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCT +GAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT +ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAG +GCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG +CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCA +CGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTT +CGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCC +GGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGC +TTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGG +GCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCC +AGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTG +GCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCG +CGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAG +GCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAG +ACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAG +GCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGA +AACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATC +CCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAG +TGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAA +AAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCG +GATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTA +CTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGG +AGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCG +CGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCG +GTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGT +CAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAA +AATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGG +AGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTC +CAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCT +GTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA +CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCG +TGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAA +CCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGAC +AGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCAC +TTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAA +CATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGC +CTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGA +GGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCC +GTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGA +GGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCC +CGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGC +TACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGC +CGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGC +CGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCA +CCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAA +AATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCT +GAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCA +CTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGC +TCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGA +GTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTA +GCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAAT +CGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCC +TGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAAT +CCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGC +CTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTG +GCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGG +GAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGC +GAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG +GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGG +TGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTA +ATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTG +CAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTC +AAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGG +GCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCT +CTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTC +GGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGA +TCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGC +GCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGA +GGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATAC +AAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGC +AGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCA +CTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACG +CCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCG +AGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGG +GCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTT +GAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGC +GACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAG +CACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGC +CAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCG +CGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGC +GGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGAC +TCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGC +CGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAA +CCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCC +AGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTG +AGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA +GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA +TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT +AAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG +GCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG +CCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT +GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA +GGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA +TTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG +AATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA +GCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGT +AATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACC +AGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTG +GTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACC +CGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAG +AGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTT +TGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACA +TGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCT +GTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGG +TTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGT +CTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGG +CGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCG +TCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTA +CTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCG +AGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCG +GGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACC +TGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAA +TACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGA +GGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACT +GCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTC +ACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGT +TCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGC +CGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCG +CTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTG +GGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCC +CAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCT +GGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGC +GCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGA +GGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGA +GACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGA +GGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTG +AAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT +CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCA +GTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAA +AAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGC +GGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCT +ACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGG +GAGGCTGAGGCAGGAGAATC +>TWO IUB ambiguity codes +cttBtatcatatgctaKggNcataaaSatgtaaaDcDRtBggDtctttataattcBgtcg +tactDtDagcctatttSVHtHttKtgtHMaSattgWaHKHttttagacatWatgtRgaaa +NtactMcSMtYtcMgRtacttctWBacgaaatatagScDtttgaagacacatagtVgYgt +cattHWtMMWcStgttaggKtSgaYaaccWStcgBttgcgaMttBYatcWtgacaYcaga +gtaBDtRacttttcWatMttDBcatWtatcttactaBgaYtcttgttttttttYaaScYa +HgtgttNtSatcMtcVaaaStccRcctDaataataStcYtRDSaMtDttgttSagtRRca +tttHatSttMtWgtcgtatSSagactYaaattcaMtWatttaSgYttaRgKaRtccactt +tattRggaMcDaWaWagttttgacatgttctacaaaRaatataataaMttcgDacgaSSt +acaStYRctVaNMtMgtaggcKatcttttattaaaaagVWaHKYagtttttatttaacct +tacgtVtcVaattVMBcttaMtttaStgacttagattWWacVtgWYagWVRctDattBYt +gtttaagaagattattgacVatMaacattVctgtBSgaVtgWWggaKHaatKWcBScSWa +accRVacacaaactaccScattRatatKVtactatatttHttaagtttSKtRtacaaagt +RDttcaaaaWgcacatWaDgtDKacgaacaattacaRNWaatHtttStgttattaaMtgt +tgDcgtMgcatBtgcttcgcgaDWgagctgcgaggggVtaaScNatttacttaatgacag +cccccacatYScaMgtaggtYaNgttctgaMaacNaMRaacaaacaKctacatagYWctg +ttWaaataaaataRattagHacacaagcgKatacBttRttaagtatttccgatctHSaat +actcNttMaagtattMtgRtgaMgcataatHcMtaBSaRattagttgatHtMttaaKagg +YtaaBataSaVatactWtataVWgKgttaaaacagtgcgRatatacatVtHRtVYataSa +KtWaStVcNKHKttactatccctcatgWHatWaRcttactaggatctataDtDHBttata +aaaHgtacVtagaYttYaKcctattcttcttaataNDaaggaaaDYgcggctaaWSctBa +aNtgctggMBaKctaMVKagBaactaWaDaMaccYVtNtaHtVWtKgRtcaaNtYaNacg +gtttNattgVtttctgtBaWgtaattcaagtcaVWtactNggattctttaYtaaagccgc +tcttagHVggaYtgtNcDaVagctctctKgacgtatagYcctRYHDtgBattDaaDgccK +tcHaaStttMcctagtattgcRgWBaVatHaaaataYtgtttagMDMRtaataaggatMt +ttctWgtNtgtgaaaaMaatatRtttMtDgHHtgtcattttcWattRSHcVagaagtacg +ggtaKVattKYagactNaatgtttgKMMgYNtcccgSKttctaStatatNVataYHgtNa +BKRgNacaactgatttcctttaNcgatttctctataScaHtataRagtcRVttacDSDtt +aRtSatacHgtSKacYagttMHtWataggatgactNtatSaNctataVtttRNKtgRacc +tttYtatgttactttttcctttaaacatacaHactMacacggtWataMtBVacRaSaatc +cgtaBVttccagccBcttaRKtgtgcctttttRtgtcagcRttKtaaacKtaaatctcac +aattgcaNtSBaaccgggttattaaBcKatDagttactcttcattVtttHaaggctKKga +tacatcBggScagtVcacattttgaHaDSgHatRMaHWggtatatRgccDttcgtatcga +aacaHtaagttaRatgaVacttagattVKtaaYttaaatcaNatccRttRRaMScNaaaD +gttVHWgtcHaaHgacVaWtgttScactaagSgttatcttagggDtaccagWattWtRtg +ttHWHacgattBtgVcaYatcggttgagKcWtKKcaVtgaYgWctgYggVctgtHgaNcV +taBtWaaYatcDRaaRtSctgaHaYRttagatMatgcatttNattaDttaattgttctaa +ccctcccctagaWBtttHtBccttagaVaatMcBHagaVcWcagBVttcBtaYMccagat +gaaaaHctctaacgttagNWRtcggattNatcRaNHttcagtKttttgWatWttcSaNgg +gaWtactKKMaacatKatacNattgctWtatctaVgagctatgtRaHtYcWcttagccaa +tYttWttaWSSttaHcaaaaagVacVgtaVaRMgattaVcDactttcHHggHRtgNcctt +tYatcatKgctcctctatVcaaaaKaaaagtatatctgMtWtaaaacaStttMtcgactt +taSatcgDataaactaaacaagtaaVctaggaSccaatMVtaaSKNVattttgHccatca +cBVctgcaVatVttRtactgtVcaattHgtaaattaaattttYtatattaaRSgYtgBag +aHSBDgtagcacRHtYcBgtcacttacactaYcgctWtattgSHtSatcataaatataHt +cgtYaaMNgBaatttaRgaMaatatttBtttaaaHHKaatctgatWatYaacttMctctt +ttVctagctDaaagtaVaKaKRtaacBgtatccaaccactHHaagaagaaggaNaaatBW +attccgStaMSaMatBttgcatgRSacgttVVtaaDMtcSgVatWcaSatcttttVatag +ttactttacgatcaccNtaDVgSRcgVcgtgaacgaNtaNatatagtHtMgtHcMtagaa +attBgtataRaaaacaYKgtRccYtatgaagtaataKgtaaMttgaaRVatgcagaKStc +tHNaaatctBBtcttaYaBWHgtVtgacagcaRcataWctcaBcYacYgatDgtDHccta +aagacYRcaggattHaYgtKtaatgcVcaataMYacccatatcacgWDBtgaatcBaata +cKcttRaRtgatgaBDacggtaattaaYtataStgVHDtDctgactcaaatKtacaatgc +gYatBtRaDatHaactgtttatatDttttaaaKVccYcaaccNcBcgHaaVcattHctcg +attaaatBtatgcaaaaatYMctSactHatacgaWacattacMBgHttcgaatVaaaaca +BatatVtctgaaaaWtctRacgBMaatSgRgtgtcgactatcRtattaScctaStagKga +DcWgtYtDDWKRgRtHatRtggtcgaHgggcgtattaMgtcagccaBggWVcWctVaaat +tcgNaatcKWagcNaHtgaaaSaaagctcYctttRVtaaaatNtataaccKtaRgtttaM +tgtKaBtRtNaggaSattHatatWactcagtgtactaKctatttgRYYatKatgtccgtR +tttttatttaatatVgKtttgtatgtNtataRatWYNgtRtHggtaaKaYtKSDcatcKg +taaYatcSRctaVtSMWtVtRWHatttagataDtVggacagVcgKWagBgatBtaaagNc +aRtagcataBggactaacacRctKgttaatcctHgDgttKHHagttgttaatgHBtatHc +DaagtVaBaRccctVgtgDtacRHSctaagagcggWYaBtSaKtHBtaaactYacgNKBa +VYgtaacttagtVttcttaatgtBtatMtMtttaattaatBWccatRtttcatagVgMMt +agctStKctaMactacDNYgKYHgaWcgaHgagattacVgtttgtRaSttaWaVgataat +gtgtYtaStattattMtNgWtgttKaccaatagNYttattcgtatHcWtctaaaNVYKKt +tWtggcDtcgaagtNcagatacgcattaagaccWctgcagcttggNSgaNcHggatgtVt +catNtRaaBNcHVagagaaBtaaSggDaatWaatRccaVgggStctDaacataKttKatt +tggacYtattcSatcttagcaatgaVBMcttDattctYaaRgatgcattttNgVHtKcYR +aatRKctgtaaacRatVSagctgtWacBtKVatctgttttKcgtctaaDcaagtatcSat +aWVgcKKataWaYttcccSaatgaaaacccWgcRctWatNcWtBRttYaattataaNgac +acaatagtttVNtataNaYtaatRaVWKtBatKagtaatataDaNaaaaataMtaagaaS +tccBcaatNgaataWtHaNactgtcDtRcYaaVaaaaaDgtttRatctatgHtgttKtga +aNSgatactttcgagWaaatctKaaDaRttgtggKKagcDgataaattgSaacWaVtaNM +acKtcaDaaatttctRaaVcagNacaScRBatatctRatcctaNatWgRtcDcSaWSgtt +RtKaRtMtKaatgttBHcYaaBtgatSgaSWaScMgatNtctcctatttctYtatMatMt +RRtSaattaMtagaaaaStcgVgRttSVaScagtgDtttatcatcatacRcatatDctta +tcatVRtttataaHtattcYtcaaaatactttgVctagtaaYttagatagtSYacKaaac +gaaKtaaatagataatSatatgaaatSgKtaatVtttatcctgKHaatHattagaaccgt +YaaHactRcggSBNgtgctaaBagBttgtRttaaattYtVRaaaattgtaatVatttctc +ttcatgBcVgtgKgaHaaatattYatagWacNctgaaMcgaattStagWaSgtaaKagtt +ttaagaDgatKcctgtaHtcatggKttVDatcaaggtYcgccagNgtgcVttttagagat +gctaccacggggtNttttaSHaNtatNcctcatSaaVgtactgBHtagcaYggYVKNgta +KBcRttgaWatgaatVtagtcgattYgatgtaatttacDacSctgctaaaStttaWMagD +aaatcaVYctccgggcgaVtaaWtStaKMgDtttcaaMtVgBaatccagNaaatcYRMBg +gttWtaaScKttMWtYataRaDBMaDataatHBcacDaaKDactaMgagttDattaHatH +taYatDtattDcRNStgaatattSDttggtattaaNSYacttcDMgYgBatWtaMagact +VWttctttgYMaYaacRgHWaattgRtaagcattctMKVStatactacHVtatgatcBtV +NataaBttYtSttacKgggWgYDtgaVtYgatDaacattYgatggtRDaVDttNactaSa +MtgNttaacaaSaBStcDctaccacagacgcaHatMataWKYtaYattMcaMtgSttDag +cHacgatcaHttYaKHggagttccgatYcaatgatRaVRcaagatcagtatggScctata +ttaNtagcgacgtgKaaWaactSgagtMYtcttccaKtStaacggMtaagNttattatcg +tctaRcactctctDtaacWYtgaYaSaagaWtNtatttRacatgNaatgttattgWDDcN +aHcctgaaHacSgaataaRaataMHttatMtgaSDSKatatHHaNtacagtccaYatWtc +actaactatKDacSaStcggataHgYatagKtaatKagStaNgtatactatggRHacttg +tattatgtDVagDVaRctacMYattDgtttYgtctatggtKaRSttRccRtaaccttaga +gRatagSaaMaacgcaNtatgaaatcaRaagataatagatactcHaaYKBctccaagaRa +BaStNagataggcgaatgaMtagaatgtcaKttaaatgtaWcaBttaatRcggtgNcaca +aKtttScRtWtgcatagtttWYaagBttDKgcctttatMggNttattBtctagVtacata +aaYttacacaaRttcYtWttgHcaYYtaMgBaBatctNgcDtNttacgacDcgataaSat +YaSttWtcctatKaatgcagHaVaacgctgcatDtgttaSataaaaYSNttatagtaNYt +aDaaaNtggggacttaBggcHgcgtNtaaMcctggtVtaKcgNacNtatVaSWctWtgaW +cggNaBagctctgaYataMgaagatBSttctatacttgtgtKtaattttRagtDtacata +tatatgatNHVgBMtKtaKaNttDHaagatactHaccHtcatttaaagttVaMcNgHata +tKtaNtgYMccttatcaaNagctggacStttcNtggcaVtattactHaSttatgNMVatt +MMDtMactattattgWMSgtHBttStStgatatRaDaagattttctatMtaaaaaggtac +taaVttaSacNaatactgMttgacHaHRttgMacaaaatagttaatatWKRgacDgaRta +tatttattatcYttaWtgtBRtWatgHaaattHataagtVaDtWaVaWtgStcgtMSgaS +RgMKtaaataVacataatgtaSaatttagtcgaaHtaKaatgcacatcggRaggSKctDc +agtcSttcccStYtccRtctctYtcaaKcgagtaMttttcRaYDttgttatctaatcata +NctctgctatcaMatactataggDaHaaSttMtaDtcNatataattctMcStaaBYtaNa +gatgtaatHagagSttgWHVcttatKaYgDctcttggtgttMcRaVgSgggtagacaata +aDtaattSaDaNaHaBctattgNtaccaaRgaVtKNtaaYggHtaKKgHcatctWtctDt +ttctttggSDtNtaStagttataaacaattgcaBaBWggHgcaaaBtYgctaatgaaatW +cDcttHtcMtWWattBHatcatcaaatctKMagtDNatttWaBtHaaaNgMttaaStagt +tctctaatDtcRVaYttgttMtRtgtcaSaaYVgSWDRtaatagctcagDgcWWaaaBaa +RaBctgVgggNgDWStNaNBKcBctaaKtttDcttBaaggBttgaccatgaaaNgttttt +tttatctatgttataccaaDRaaSagtaVtDtcaWatBtacattaWacttaSgtattggD +gKaaatScaattacgWcagKHaaccaYcRcaRttaDttRtttHgaHVggcttBaRgtccc +tDatKaVtKtcRgYtaKttacgtatBtStaagcaattaagaRgBagSaattccSWYttta +ttVaataNctgHgttaaNBgcVYgtRtcccagWNaaaacaDNaBcaaaaRVtcWMgBagM +tttattacgDacttBtactatcattggaaatVccggttRttcatagttVYcatYaSHaHc +ttaaagcNWaHataaaRWtctVtRYtagHtaaaYMataHYtNBctNtKaatattStgaMc +BtRgctaKtgcScSttDgYatcVtggaaKtaagatWccHccgKYctaNNctacaWctttt +gcRtgtVcgaKttcMRHgctaHtVaataaDtatgKDcttatBtDttggNtacttttMtga +acRattaaNagaactcaaaBBVtcDtcgaStaDctgaaaSgttMaDtcgttcaccaaaag +gWtcKcgSMtcDtatgtttStaaBtatagDcatYatWtaaaBacaKgcaDatgRggaaYc +taRtccagattDaWtttggacBaVcHtHtaacDacYgtaatataMagaatgHMatcttat +acgtatttttatattacHactgttataMgStYaattYaccaattgagtcaaattaYtgta +tcatgMcaDcgggtcttDtKgcatgWRtataatatRacacNRBttcHtBgcRttgtgcgt +catacMtttBctatctBaatcattMttMYgattaaVYatgDaatVagtattDacaacDMa +tcMtHcccataagatgBggaccattVWtRtSacatgctcaaggggYtttDtaaNgNtaaB +atggaatgtctRtaBgBtcNYatatNRtagaacMgagSaSDDSaDcctRagtVWSHtVSR +ggaacaBVaccgtttaStagaacaMtactccagtttVctaaRaaHttNcttagcaattta +ttaatRtaaaatctaacDaBttggSagagctacHtaaRWgattcaaBtctRtSHaNtgta +cattVcaHaNaagtataccacaWtaRtaaVKgMYaWgttaKggKMtKcgWatcaDatYtK +SttgtacgaccNctSaattcDcatcttcaaaDKttacHtggttHggRRaRcaWacaMtBW +VHSHgaaMcKattgtaRWttScNattBBatYtaNRgcggaagacHSaattRtttcYgacc +BRccMacccKgatgaacttcgDgHcaaaaaRtatatDtatYVtttttHgSHaSaatagct +NYtaHYaVYttattNtttgaaaYtaKttWtctaNtgagaaaNctNDctaaHgttagDcRt +tatagccBaacgcaRBtRctRtggtaMYYttWtgataatcgaataattattataVaaaaa +ttacNRVYcaaMacNatRttcKatMctgaagactaattataaYgcKcaSYaatMNctcaa +cgtgatttttBacNtgatDccaattattKWWcattttatatatgatBcDtaaaagttgaa +VtaHtaHHtBtataRBgtgDtaataMttRtDgDcttattNtggtctatctaaBcatctaR +atgNacWtaatgaagtcMNaacNgHttatactaWgcNtaStaRgttaaHacccgaYStac +aaaatWggaYaWgaattattcMaactcBKaaaRVNcaNRDcYcgaBctKaacaaaaaSgc +tccYBBHYaVagaatagaaaacagYtctVccaMtcgtttVatcaatttDRtgWctagtac +RttMctgtDctttcKtWttttataaatgVttgBKtgtKWDaWagMtaaagaaattDVtag +gttacatcatttatgtcgMHaVcttaBtVRtcgtaYgBRHatttHgaBcKaYWaatcNSc +tagtaaaaatttacaatcactSWacgtaatgKttWattagttttNaggtctcaagtcact +attcttctaagKggaataMgtttcataagataaaaatagattatDgcBVHWgaBKttDgc +atRHaagcaYcRaattattatgtMatatattgHDtcaDtcaaaHctStattaatHaccga +cNattgatatattttgtgtDtRatagSacaMtcRtcattcccgacacSattgttKaWatt +NHcaacttccgtttSRtgtctgDcgctcaaMagVtBctBMcMcWtgtaacgactctcttR +ggRKSttgYtYatDccagttDgaKccacgVatWcataVaaagaataMgtgataaKYaaat +cHDaacgataYctRtcYatcgcaMgtNttaBttttgatttaRtStgcaacaaaataccVg +aaDgtVgDcStctatatttattaaaaRKDatagaaagaKaaYYcaYSgKStctccSttac +agtcNactttDVttagaaagMHttRaNcSaRaMgBttattggtttaRMggatggcKDgWR +tNaataataWKKacttcKWaaagNaBttaBatMHtccattaacttccccYtcBcYRtaga +ttaagctaaYBDttaNtgaaaccHcaRMtKtaaHMcNBttaNaNcVcgVttWNtDaBatg +ataaVtcWKcttRggWatcattgaRagHgaattNtatttctctattaattaatgaDaaMa +tacgttgggcHaYVaaNaDDttHtcaaHtcVVDgBVagcMacgtgttaaBRNtatRtcag +taagaggtttaagacaVaaggttaWatctccgtVtaDtcDatttccVatgtacNtttccg +tHttatKgScBatgtVgHtYcWagcaKtaMYaaHgtaattaSaHcgcagtWNaatNccNN +YcacgVaagaRacttctcattcccRtgtgtaattagcSttaaStWaMtctNNcSMacatt +ataaactaDgtatWgtagtttaagaaaattgtagtNagtcaataaatttgatMMYactaa +tatcggBWDtVcYttcDHtVttatacYaRgaMaacaStaatcRttttVtagaDtcacWat +ttWtgaaaagaaagNRacDtttStVatBaDNtaactatatcBSMcccaSttccggaMatg +attaaWatKMaBaBatttgataNctgttKtVaagtcagScgaaaDggaWgtgttttKtWt +atttHaatgtagttcactaaKMagttSYBtKtaYgaactcagagRtatagtVtatcaaaW +YagcgNtaDagtacNSaaYDgatBgtcgataacYDtaaactacagWDcYKaagtttatta +gcatcgagttKcatDaattgattatDtcagRtWSKtcgNtMaaaaacaMttKcaWcaaSV +MaaaccagMVtaMaDtMaHaBgaacataBBVtaatVYaNSWcSgNtDNaaKacacBttta +tKtgtttcaaHaMctcagtaacgtcgYtactDcgcctaNgagagcYgatattttaaattt +ccattttacatttDaaRctattttWctttacgtDatYtttcagacgcaaVttagtaaKaa +aRtgVtccataBggacttatttgtttaWNtgttVWtaWNVDaattgtatttBaagcBtaa +BttaaVatcHcaVgacattccNggtcgacKttaaaRtagRtctWagaYggtgMtataatM +tgaaRttattttgWcttNtDRRgMDKacagaaaaggaaaRStcccagtYccVattaNaaK +StNWtgacaVtagaagcttSaaDtcacaacgDYacWDYtgtttKatcVtgcMaDaSKStV +cgtagaaWaKaagtttcHaHgMgMtctataagBtKaaaKKcactggagRRttaagaBaaN +atVVcgRcKSttDaactagtSttSattgttgaaRYatggttVttaataaHttccaagDtg +atNWtaagHtgcYtaactRgcaatgMgtgtRaatRaNaacHKtagactactggaatttcg +ccataacgMctRgatgttaccctaHgtgWaYcactcacYaattcttaBtgacttaaacct +gYgaWatgBttcttVttcgttWttMcNYgtaaaatctYgMgaaattacNgaHgaacDVVM +tttggtHtctaaRgtacagacgHtVtaBMNBgattagcttaRcttacaHcRctgttcaaD +BggttKaacatgKtttYataVaNattccgMcgcgtagtRaVVaattaKaatggttRgaMc +agtatcWBttNtHagctaatctagaaNaaacaYBctatcgcVctBtgcaaagDgttVtga +HtactSNYtaaNccatgtgDacgaVtDcgKaRtacDcttgctaagggcagMDagggtBWR +tttSgccttttttaacgtcHctaVtVDtagatcaNMaVtcVacatHctDWNaataRgcgt +aVHaggtaaaaSgtttMtattDgBtctgatSgtRagagYtctSaKWaataMgattRKtaa +catttYcgtaacacattRWtBtcggtaaatMtaaacBatttctKagtcDtttgcBtKYYB +aKttctVttgttaDtgattttcttccacttgSaaacggaaaNDaattcYNNaWcgaaYat +tttMgcBtcatRtgtaaagatgaWtgaccaYBHgaatagataVVtHtttVgYBtMctaMt +cctgaDcYttgtccaaaRNtacagcMctKaaaggatttacatgtttaaWSaYaKttBtag +DacactagctMtttNaKtctttcNcSattNacttggaacaatDagtattRtgSHaataat +gccVgacccgatactatccctgtRctttgagaSgatcatatcgDcagWaaHSgctYYWta +tHttggttctttatVattatcgactaagtgtagcatVgtgHMtttgtttcgttaKattcM +atttgtttWcaaStNatgtHcaaaDtaagBaKBtRgaBgDtSagtatMtaacYaatYtVc +KatgtgcaacVaaaatactKcRgtaYtgtNgBBNcKtcttaccttKgaRaYcaNKtactt +tgagSBtgtRagaNgcaaaNcacagtVtttHWatgttaNatBgtttaatNgVtctgaata +tcaRtattcttttttttRaaKcRStctcggDgKagattaMaaaKtcaHacttaataataK +taRgDtKVBttttcgtKaggHHcatgttagHggttNctcgtatKKagVagRaaaggaaBt +NatttVKcRttaHctaHtcaaatgtaggHccaBataNaNaggttgcWaatctgatYcaaa +HaatWtaVgaaBttagtaagaKKtaaaKtRHatMaDBtBctagcatWtatttgWttVaaa +ScMNattRactttgtYtttaaaagtaagtMtaMaSttMBtatgaBtttaKtgaatgagYg +tNNacMtcNRacMMHcttWtgtRtctttaacaacattattcYaMagBaacYttMatcttK +cRMtgMNccattaRttNatHaHNaSaaHMacacaVaatacaKaSttHatattMtVatWga +ttttttaYctttKttHgScWaacgHtttcaVaaMgaacagNatcgttaacaaaaagtaca +HBNaattgttKtcttVttaaBtctgctacgBgcWtttcaggacacatMgacatcccagcg +gMgaVKaBattgacttaatgacacacaaaaaatRKaaBctacgtRaDcgtagcVBaacDS +BHaaaaSacatatacagacRNatcttNaaVtaaaataHattagtaaaaSWccgtatWatg +gDttaactattgcccatcttHaSgYataBttBaactattBtcHtgatcaataSttaBtat +KSHYttWggtcYtttBttaataccRgVatStaHaKagaatNtagRMNgtcttYaaSaact +cagDSgagaaYtMttDtMRVgWKWtgMaKtKaDttttgactatacataatcNtatNaHat +tVagacgYgatatatttttgtStWaaatctWaMgagaRttRatacgStgattcttaagaD +taWccaaatRcagcagaaNKagtaaDggcgccBtYtagSBMtactaaataMataBSacRM +gDgattMMgtcHtcaYDtRaDaacggttDaggcMtttatgttaNctaattaVacgaaMMt +aatDccSgtattgaRtWWaccaccgagtactMcgVNgctDctaMScatagcgtcaactat +acRacgHRttgctatttaatgaattataYKttgtaagWgtYttgcHgMtaMattWaWVta +RgcttgYgttBHtYataSccStBtgtagMgtDtggcVaaSBaatagDttgBgtctttctc +attttaNagtHKtaMWcYactVcgcgtatMVtttRacVagDaatcttgctBBcRDgcaac +KttgatSKtYtagBMagaRtcgBattHcBWcaactgatttaatttWDccatttatcgagS +KaWttataHactaHMttaatHtggaHtHagaatgtKtaaRactgtttMatacgatcaagD +gatKaDctataMggtHDtggHacctttRtatcttYattttgacttgaaSaataaatYcgB +aaaaccgNatVBttMacHaKaataagtatKgtcaagactcttaHttcggaattgttDtct +aaccHttttWaaatgaaatataaaWattccYDtKtaaaacggtgaggWVtctattagtga +ctattaagtMgtttaagcatttgSgaaatatccHaaggMaaaattttcWtatKctagDtY +tMcctagagHcactttactatacaaacattaacttaHatcVMYattYgVgtMttaaRtga +aataaDatcaHgtHHatKcDYaatcttMtNcgatYatgSaMaNtcttKcWataScKggta +tcttacgcttWaaagNatgMgHtctttNtaacVtgttcMaaRatccggggactcMtttaY +MtcWRgNctgNccKatcttgYDcMgattNYaRagatHaaHgKctcataRDttacatBatc +cattgDWttatttaWgtcggagaaaaatacaatacSNtgggtttccttacSMaagBatta +caMaNcactMttatgaRBacYcYtcaaaWtagctSaacttWgDMHgaggatgBVgcHaDt +ggaactttggtcNatNgtaKaBcccaNtaagttBaacagtatacDYttcctNgWgcgSMc +acatStctHatgRcNcgtacacaatRttMggaNKKggataaaSaYcMVcMgtaMaHtgat +tYMatYcggtcttcctHtcDccgtgRatcattgcgccgatatMaaYaataaYSggatagc +gcBtNtaaaScaKgttBgagVagttaKagagtatVaactaSacWactSaKatWccaKaaa +atBKgaaKtDMattttgtaaatcRctMatcaaMagMttDgVatggMaaWgttcgaWatga +aatttgRtYtattaWHKcRgctacatKttctaccaaHttRatctaYattaaWatVNccat +NgagtcKttKataStRaatatattcctRWatDctVagttYDgSBaatYgttttgtVaatt +taatagcagMatRaacttBctattgtMagagattaaactaMatVtHtaaatctRgaaaaa +aaatttWacaacaYccYDSaattMatgaccKtaBKWBattgtcaagcHKaagttMMtaat +ttcKcMagNaaKagattggMagaggtaatttYacatcWaaDgatMgKHacMacgcVaaca +DtaDatatYggttBcgtatgWgaSatttgtagaHYRVacaRtctHaaRtatgaactaata +tctSSBgggaaHMWtcaagatKgagtDaSatagttgattVRatNtctMtcSaagaSHaat +aNataataRaaRgattctttaataaagWaRHcYgcatgtWRcttgaaggaMcaataBRaa +ccagStaaacNtttcaatataYtaatatgHaDgcStcWttaacctaRgtYaRtataKtgM +ttttatgactaaaatttacYatcccRWtttHRtattaaatgtttatatttgttYaatMca +RcSVaaDatcgtaYMcatgtagacatgaaattgRtcaaYaaYtRBatKacttataccaNa +aattVaBtctggacaagKaaYaaatatWtMtatcYaaVNtcgHaactBaagKcHgtctac +aatWtaDtSgtaHcataHtactgataNctRgttMtDcDttatHtcgtacatcccaggStt +aBgtcacacWtccNMcNatMVaVgtccDYStatMaccDatggYaRKaaagataRatttHK +tSaaatDgataaacttaHgttgVBtcttVttHgDacgaKatgtatatNYataactctSat +atatattgcHRRYttStggaactHgttttYtttaWtatMcttttctatctDtagVHYgMR +BgtHttcctaatYRttKtaagatggaVRataKDctaMtKBNtMtHNtWtttYcVtattMc +gRaacMcctNSctcatttaaagDcaHtYccSgatgcaatYaaaaDcttcgtaWtaattct +cgttttScttggtaatctttYgtctaactKataHacctMctcttacHtKataacacagcN +RatgKatttttSaaatRYcgDttaMRcgaaattactMtgcgtaagcgttatBtttttaat +taagtNacatHgttcRgacKcBBtVgatKttcgaBaatactDRgtRtgaNacWtcacYtt +aaKcgttctHaKttaNaMgWgWaggtctRgaKgWttSttBtDcNtgtttacaaatYcDRt +gVtgcctattcNtctaaaDMNttttNtggctgagaVctDaacVtWccaagtaacacaNct +gaScattccDHcVBatcgatgtMtaatBgHaatDctMYgagaatgYWKcctaatNaStHa +aaKccgHgcgtYaaYtattgtStgtgcaaRtattaKatattagaWVtcaMtBagttatta +gNaWHcVgcaattttDcMtgtaRHVYtHtctgtaaaaHVtMKacatcgNaatttMatatg +ttgttactagWYtaRacgataKagYNKcattataNaRtgaacKaYgcaaYYacaNccHat +MatDcNgtHttRaWttagaaDcaaaaaatagggtKDtStaDaRtaVtHWKNtgtattVct +SVgRgataDaRaWataBgaagaaKtaataaYgDcaStaNgtaDaaggtattHaRaWMYaY +aWtggttHYgagVtgtgcttttcaaDKcagVcgttagacNaaWtagtaataDttctggtt +VcatcataaagtgKaaaNaMtaBBaattaatWaattgctHaVKaSgDaaVKaHtatatat +HatcatSBagNgHtatcHYMHgttDgtaHtBttWatcgtttaRaattgStKgSKNWKatc +agDtctcagatttctRtYtBatBgHHtKaWtgYBgacVVWaKtacKcDttKMaKaVcggt +gttataagaataaHaatattagtataatMHgttYgaRttagtaRtcaaVatacggtcMcg +agtaaRttacWgactKRYataaaagSattYaWgagatYagKagatgSaagKgttaatMgg +tataatgttWYttatgagaaacctNVataatHcccKtDctcctaatactggctHggaSag +gRtKHaWaattcgSatMatttagaggcYtctaMcgctcataSatatgRagacNaaDagga +VBagaYttKtacNaKgtSYtagttggaWcatcWttaatctatgaVtcgtgtMtatcaYcg +tRccaaYgDctgcMgtgtWgacWtgataacacgcgctBtgttaKtYDtatDcatcagKaV +MctaatcttgVcaaRgcRMtDcgattaHttcaNatgaatMtactacVgtRgatggaWttt +actaaKatgagSaaKggtaNtactVaYtaaKRagaacccacaMtaaMtKtatBcttgtaa +WBtMctaataaVcDaaYtcRHBtcgttNtaaHatttBNgRStVDattBatVtaagttaYa +tVattaagaBcacggtSgtVtatttaRattgatgtaHDKgcaatattKtggcctatgaWD +KRYcggattgRctatNgatacaatMNttctgtcRBYRaaaHctNYattcHtaWcaattct +BtMKtVgYataatMgYtcagcttMDataVtggRtKtgaatgccNcRttcaMtRgattaac +attRcagcctHtWMtgtDRagaKaBtgDttYaaaaKatKgatctVaaYaacWcgcatagB +VtaNtRtYRaggBaaBtgKgttacataagagcatgtRattccacttaccatRaaatgWgD +aMHaYVgVtaSctatcgKaatatattaDgacccYagtgtaYNaaatKcagtBRgagtcca +tgKgaaaccBgaagBtgSttWtacgatWHaYatcgatttRaaNRgcaNaKVacaNtDgat +tgHVaatcDaagcgtatgcNttaDataatcSataaKcaataaHWataBtttatBtcaKtK +tatagttaDgSaYctacaRatNtaWctSaatatttYaKaKtaccWtatcRagacttaYtt +VcKgSDcgagaagatccHtaattctSttatggtKYgtMaHagVaBRatttctgtRgtcta +tgggtaHKgtHacHtSYacgtacacHatacKaaBaVaccaDtatcSaataaHaagagaat +ScagactataaRttagcaaVcaHataKgDacatWccccaagcaBgagWatctaYttgaaa +tctVNcYtttWagHcgcgcDcVaaatgttKcHtNtcaatagtgtNRaactttttcaatgg +WgBcgDtgVgtttctacMtaaataaaRggaaacWaHttaRtNtgctaaRRtVBctYtVta +tDcattDtgaccYatagatYRKatNYKttNgcctagtaWtgaactaMVaacctgaStttc +tgaKVtaaVaRKDttVtVctaDNtataaaDtccccaagtWtcgatcactDgYaBcatcct +MtVtacDaaBtYtMaKNatNtcaNacgDatYcatcgcaRatWBgaacWttKttagYtaat +tcggttgSWttttDWctttacYtatatWtcatDtMgtBttgRtVDggttaacYtacgtac +atgaattgaaWcttMStaDgtatattgaDtcRBcattSgaaVBRgagccaaKtttcDgcg +aSMtatgWattaKttWtgDBMaggBBttBaatWttRtgcNtHcgttttHtKtcWtagHSt +aacagttgatatBtaWSaWggtaataaMttaKacDaatactcBttcaatatHttcBaaSa +aatYggtaRtatNtHcaatcaHtagVtgtattataNggaMtcttHtNagctaaaggtaga +YctMattNaMVNtcKtactBKcaHHcBttaSagaKacataYgctaKaYgttYcgacWVtt +WtSagcaacatcccHaccKtcttaacgaKttcacKtNtacHtatatRtaaatacactaBt +ttgaHaRttggttWtatYagcatYDatcggagagcWBataagRtacctataRKgtBgatg +aDatataSttagBaHtaatNtaDWcWtgtaattacagKttcNtMagtattaNgtctcgtc +ctcttBaHaKcKccgtRcaaYagSattaagtKataDatatatagtcDtaacaWHcaKttD +gaaRcgtgYttgtcatatNtatttttatggccHtgDtYHtWgttatYaacaattcaWtat +NgctcaaaSttRgctaatcaaatNatcgtttaBtNNVtgttataagcaaagattBacgtD +atttNatttaaaDcBgtaSKgacgtagataatttcHMVNttgttBtDtgtaWKaaRMcKM +tHtaVtagataWctccNNaSWtVaHatctcMgggDgtNHtDaDttatatVWttgttattt +aacctttcacaaggaSaDcggttttttatatVtctgVtaacaStDVaKactaMtttaSNa +gtgaaattaNacttSKctattcctctaSagKcaVttaagNaVcttaVaaRNaHaaHttat +gtHttgtgatMccaggtaDcgaccgtWgtWMtttaHcRtattgScctatttKtaaccaag +tYagaHgtWcHaatgccKNRtttagtMYSgaDatctgtgaWDtccMNcgHgcaaacNDaa +aRaStDWtcaaaaHKtaNBctagBtgtattaactaattttVctagaatggcWSatMaccc +ttHttaSgSgtgMRcatRVKtatctgaaaccDNatYgaaVHNgatMgHRtacttaaaRta +tStRtDtatDttYatattHggaBcttHgcgattgaKcKtttcRataMtcgaVttWacatN +catacctRataDDatVaWNcggttgaHtgtMacVtttaBHtgagVttMaataattatgtt +cttagtttgtgcDtSatttgBtcaacHattaaBagVWcgcaSYttMgcttacYKtVtatc +aYaKctgBatgcgggcYcaaaaacgNtctagKBtattatctttKtaVttatagtaYtRag +NtaYataaVtgaatatcHgcaaRataHtacacatgtaNtgtcgYatWMatttgaactacR +ctaWtWtatacaatctBatatgYtaagtatgtgtatSttactVatcttYtaBcKgRaSgg +RaaaaatgcagtaaaWgtaRgcgataatcBaataccgtatttttccatcNHtatWYgatH +SaaaDHttgctgtccHtggggcctaataatttttctatattYWtcattBtgBRcVttaVM +RSgctaatMagtYtttaaaaatBRtcBttcaaVtaacagctccSaaSttKNtHtKYcagc +agaaaccccRtttttaaDcDtaStatccaagcgctHtatcttaDRYgatDHtWcaaaBcW +gKWHttHataagHacgMNKttMKHccaYcatMVaacgttaKgYcaVaaBtacgcaacttt +MctaaHaatgtBatgagaSatgtatgSRgHgWaVWgataaatatttccKagVgataattW +aHNcYggaaatgctHtKtaDtctaaagtMaatVDVactWtSaaWaaMtaHtaSKtcBRaN +cttStggtBttacNagcatagRgtKtgcgaacaacBcgKaatgataagatgaaaattgta +ctgcgggtccHHWHaaNacaBttNKtKtcaaBatatgctaHNgtKcDWgtttatNgVDHg +accaacWctKaaggHttgaRgYaatHcaBacaatgagcaaattactgtaVaaYaDtagat +tgagNKggtggtgKtWKaatacagDRtatRaMRtgattDggtcaaYRtatttNtagaDtc +acaaSDctDtataatcgtactaHttatacaatYaacaaHttHatHtgcgatRRttNgcat +SVtacWWgaaggagtatVMaVaaattScDDKNcaYBYaDatHgtctatBagcaacaagaa +tgagaaRcataaKNaRtBDatcaaacgcattttttaaBtcSgtacaRggatgtMNaattg +gatatWtgagtattaaaVctgcaYMtatgatttttYgaHtgtcttaagWBttHttgtctt +attDtcgtatWtataataSgctaHagcDVcNtaatcaagtaBDaWaDgtttagYctaNcc +DtaKtaHcttaataacccaRKtacaVaatNgcWRaMgaattatgaBaaagattVYaHMDc +aDHtcRcgYtcttaaaWaaaVKgatacRtttRRKYgaatacaWVacVcRtatMacaBtac +tggMataaattttHggNagSctacHgtBagcgtcgtgattNtttgatSaaggMttctttc +ttNtYNagBtaaacaaatttMgaccttacataattgYtcgacBtVMctgStgMDtagtaR +ctHtatgttcatatVRNWataDKatWcgaaaaagttaaaagcacgHNacgtaatctttMR +tgacttttDacctataaacgaaatatgattagaactccSYtaBctttaataacWgaaaYa +tagatgWttcatKtNgatttttcaagHtaYgaaRaDaagtaggagcttatVtagtctttc +attaaaatcgKtattaRttacagVaDatgcatVgattgggtctttHVtagKaaRBtaHta +aggccccaaaaKatggtttaMWgtBtaaacttcactttKHtcgatctccctaYaBacMgt +cttBaBaNgcgaaacaatctagtHccHtKttcRtRVttccVctttcatacYagMVtMcag +aMaaacaataBctgYtaatRaaagattaaccatVRatHtaRagcgcaBcgDttStttttc +VtttaDtKgcaaWaaaaatSccMcVatgtKgtaKgcgatatgtagtSaaaDttatacaaa +catYaRRcVRHctKtcgacKttaaVctaDaatgttMggRcWaacttttHaDaKaDaBctg +taggcgtttaHBccatccattcNHtDaYtaataMttacggctNVaacDattgatatttta +cVttSaattacaaRtataNDgacVtgaacataVRttttaDtcaaacataYDBtttaatBa +DtttYDaDaMccMttNBttatatgagaaMgaNtattHccNataattcaHagtgaaggDga +tgtatatatgYatgaStcataaBStWacgtcccataRMaaDattggttaaattcMKtctM +acaBSactcggaatDDgatDgcWctaacaccgggaVcacWKVacggtaNatatacctMta +tgatagtgcaKagggVaDtgtaacttggagtcKatatcgMcttRaMagcattaBRaStct +YSggaHYtacaactMBaagDcaBDRaaacMYacaHaattagcattaaaHgcgctaaggSc +cKtgaaKtNaBtatDDcKBSaVtgatVYaagVtctSgMctacgttaacWaaattctSgtD +actaaStaaattgcagBBRVctaatatacctNttMcRggctttMttagacRaHcaBaacV +KgaataHttttMgYgattcYaNRgttMgcVaaacaVVcDHaatttgKtMYgtatBtVVct +WgVtatHtacaaHttcacgatagcagtaaNattBatatatttcVgaDagcggttMaagtc +ScHagaaatgcYNggcgtttttMtStggtRatctacttaaatVVtBacttHNttttaRca +aatcacagHgagagtMgatcSWaNRacagDtatactaaDKaSRtgattctccatSaaRtt +aaYctacacNtaRtaactggatgaccYtacactttaattaattgattYgttcagDtNKtt +agDttaaaaaaaBtttaaNaYWKMBaaaacVcBMtatWtgBatatgaacVtattMtYatM +NYDKNcKgDttDaVtaaaatgggatttctgtaaatWtctcWgtVVagtcgRgacttcccc +taDcacagcRcagagtgtWSatgtacatgttaaSttgtaaHcgatgggMagtgaacttat +RtttaVcaccaWaMgtactaatSSaHtcMgaaYtatcgaaggYgggcgtgaNDtgttMNg +aNDMtaattcgVttttaacatgVatgtWVMatatcaKgaaattcaBcctccWcttgaaWH +tWgHtcgNWgaRgctcBgSgaattgcaaHtgattgtgNagtDttHHgBttaaWcaaWagc +aSaHHtaaaVctRaaMagtaDaatHtDMtcVaWMtagSagcttHSattaacaaagtRacM +tRtctgttagcMtcaBatVKtKtKacgagaSNatSactgtatatcBctgagVtYactgta +aattaaaggcYgDHgtaacatSRDatMMccHatKgttaacgactKtgKagtcttcaaHRV +tccttKgtSataatttacaactggatDNgaacttcaRtVaagDcaWatcBctctHYatHa +DaaatttagYatSatccaWtttagaaatVaacBatHcatcgtacaatatcgcNYRcaata +YaRaYtgattVttgaatgaVaactcRcaNStgtgtattMtgaggtNttBaDRcgaaaagc +tNgBcWaWgtSaDcVtgVaatMKBtttcgtttctaaHctaaagYactgMtatBDtcStga +ccgtSDattYaataHctgggaYYttcggttaWaatctggtRagWMaDagtaacBccacta +cgHWMKaatgatWatcctgHcaBaSctVtcMtgtDttacctaVgatYcWaDRaaaaRtag +atcgaMagtggaRaWctctgMgcWttaagKBRtaaDaaWtctgtaagYMttactaHtaat +cttcataacggcacBtSgcgttNHtgtHccatgttttaaagtatcgaKtMttVcataYBB +aKtaMVaVgtattNDSataHcagtWMtaggtaSaaKgttgBtVtttgttatcatKcgHac +acRtctHatNVagSBgatgHtgaRaSgttRcctaacaaattDNttgacctaaYtBgaaaa +tagttattactcttttgatgtNNtVtgtatMgtcttRttcatttgatgacacttcHSaaa +ccaWWDtWagtaRDDVNacVaRatgttBccttaatHtgtaaacStcVNtcacaSRttcYa +gacagaMMttttgMcNttBcgWBtactgVtaRttctccaaYHBtaaagaBattaYacgat +ttacatctgtaaMKaRYtttttactaaVatWgctBtttDVttctggcDaHaggDaagtcg +aWcaagtagtWttHtgKtVataStccaMcWcaagataagatcactctHatgtcYgaKcat +cagatactaagNSStHcctRRNtattgtccttagttagMVgtatagactaactctVcaat +MctgtttgtgttgccttatWgtaBVtttctggMcaaKgDWtcgtaaYStgSactatttHg +atctgKagtagBtVacRaagRtMctatgggcaaaKaaaatacttcHctaRtgtDcttDat +taggaaatttcYHaRaaBttaatggcacKtgctHVcaDcaaaVDaaaVcgMttgtNagcg +taDWgtcgttaatDgKgagcSatatcSHtagtagttggtgtHaWtaHKtatagctgtVga +ttaBVaatgaataagtaatVatSttaHctttKtttgtagttaccttaatcgtagtcctgB +cgactatttVcMacHaaaggaatgDatggKtaHtgStatattaaSagctWcctccRtata +BaDYcgttgcNaagaggatRaaaYtaWgNtSMcaatttactaacatttaaWttHtatBat +tgtcgacaatNgattgcNgtMaaaKaBDattHacttggtRtttaYaacgVactBtaBaKt +gBttatgVttgtVttcaatcWcNctDBaaBgaDHacBttattNtgtDtatttVSaaacag +gatgcRatSgtaSaNtgBatagttcHBgcBBaaattaHgtDattatDaKaatBaaYaaMa +ataaataKtttYtagtBgMatNcatgtttgaNagtgttgtgKaNaSagtttgaSMaYBca +aaacDStagttVacaaaaactaaWttBaagtctgtgcgtMgtaattctcctacctcaNtt +taaccaaaaVtBcacataacaccccBcWMtatVtggaatgaWtcaaWaaaaaaaaWtDta +atatRcctDWtcctaccMtVVatKttaWaaKaaatataaagScHBagaggBaSMtaWaVt +atattactSaaaKNaactatNatccttgaYctattcaaaVgatttYHcRagattttaSat +aggttattcVtaaagaKgtattattKtRttNcggcRgtgtgtWYtaacHgKatKgatYta +cYagDtWcHBDctctgRaYKaYagcactKcacSaRtBttttBHKcMtNtcBatttatttt +tgSatVgaaagaWtcDtagDatatgMacaacRgatatatgtttgtKtNRaatatNatgYc +aHtgHataacKtgagtagtaacYttaNccaaatHcacaacaVDtagtaYtccagcattNt +acKtBtactaaagaBatVtKaaHBctgStgtBgtatgaSNtgDataaccctgtagcaBgt +gatcttaDataStgaMaccaSBBgWagtacKcgattgaDgNNaaaacacagtSatBacKD +gcgtataBKcatacactaSaatYtYcDaactHttcatRtttaatcaattataRtttgtaa +gMcgNttcatcBtYBagtNWNMtSHcattcRctttttRWgaKacKttgggagBcgttcgc +MaWHtaatactgtctctatttataVgtttaBScttttaBMaNaatMacactYtBMggtHa +cMagtaRtctgcatttaHtcaaaatttgagKtgNtactBacaHtcgtatttctMaSRagc +agttaatgtNtaaattgagagWcKtaNttagVtacgatttgaatttcgRtgtWcVatcgt +taaDVctgtttBWgaccagaaagtcSgtVtatagaBccttttcctaaattgHtatcggRa +ttttcaaggcYSKaagWaWtRactaaaacccBatMtttBaatYtaagaactSttcgaaSc +aatagtattgaccaagtgttttctaacatgtttNVaatcaaagagaaaNattaaRtttta +VaaaccgcaggNMtatattVctcaagaggaacgBgtttaacaagttcKcYaatatactaa +ccBaaaSggttcNtattctagttRtBacgScVctcaatttaatYtaaaaaaatgSaatga +tagaMBRatgRcMcgttgaWHtcaVYgaatYtaatctttYttatRaWtctgBtDcgatNa +tcKaBaDgatgtaNatWKctccgatattaacattNaaacDatgBgttctgtDtaaaMggt +gaBaSHataacgccSctaBtttaRBtcNHcDatcDcctagagtcRtaBgWttDRVHagat +tYatgtatcWtaHtttYcattWtaaagtctNgtStggRNcgcggagSSaaagaaaatYcH +DtcgctttaatgYcKBVSgtattRaYBaDaaatBgtatgaHtaaRaRgcaSWNtagatHa +acttNctBtcaccatctMcatattccaSatttgcgaDagDgtatYtaaaVDtaagtttWV +aagtagYatRttaagDcNgacKBcScagHtattatcDaDactaaaaaYgHttBcgaDttg +gataaaKSRcBMaBcgaBSttcWtgNBatRaccgattcatttataacggHVtaattcaca +agagVttaaRaatVVRKcgWtVgacctgDgYaaHaWtctttcacMagggatVgactagMa +aataKaaNWagKatagNaaWtaaaatttgaattttatttgctaaVgaHatBatcaaBWcB +gttcMatcgBaaNgttcgSNaggSaRtttgHtRtattaNttcDcatSaVttttcgaaaaa +ttgHatctaRaggSaNatMDaaatDcacgattttagaHgHaWtYgattaatHNSttatMS +gggNtcKtYatRggtttgtMWVtttaYtagcagBagHaYagttatatggtBacYcattaR +SataBatMtttaaatctHcaaaSaaaagttNSaaWcWRccRtKaagtBWtcaaattSttM +tattggaaaccttaacgttBtWatttatatWcDaatagattcctScacctaagggRaaYt +aNaatgVtBcttaaBaacaMVaaattatStYgRcctgtactatcMcVKatttcgSgatRH +MaaaHtagtaaHtVgcaaataatatcgKKtgccaatBNgaaWcVttgagttaKatagttc +aggKDatDtattgaKaVcaKtaataDataataHSaHcattagttaatRVYcNaHtaRcaa +ggtNHcgtcaaccaBaaagYtHWaaaRcKgaYaaDttgcWYtataRgaatatgtYtgcKt +aNttWacatYHctRaDtYtattcBttttatcSataYaYgttWaRagcacHMgtttHtYtt +YaatcggtatStttcgtRSattaaDaKMaatatactaNBaWgctacacYtgaYVgtgHta +aaRaaRgHtagtWattataaaSDaaWtgMattatcgaaaagtaYRSaWtSgNtBgagcRY +aMDtactaacttaWgtatctagacaagNtattHggataatYttYatcataDcgHgttBtt +ctttVttgccgaaWtaaaacgKgtatctaaaaaNtccDtaDatBMaMggaatNKtatBaa +atVtccRaHtaSacataHattgtttKVYattcataVaattWtcgtgMttcttKtgtctaa +cVtatctatatBRataactcgKatStatattcatHHRttKtccaacgtgggtgRgtgaMt +attattggctatcgtgacMtRcBDtcttgtactaatRHttttaagatcgVMDStattatY +BtttDttgtBtNttgRcMtYtgBacHaWaBaatDKctaagtgaaactaatgRaaKgatcc +aagNaaaatattaggWNtaagtatacttttKcgtcggSYtcttgRctataYcttatataa +agtatattaatttataVaacacaDHatctatttttKYVatHRactttaBHccaWagtact +BtcacgaVgcgttRtttttttSVgtSagtBaaattctgaHgactcttgMcattttagVta +agaattHctHtcaDaaNtaacRggWatagttcgtSttgaDatcNgNagctagDgatcNtt +KgttgtaDtctttRaaYStRatDtgMggactSttaDtagSaVtBDttgtDgccatcacaM +attaaaMtNacaVcgSWcVaaDatcaHaatgaattaMtatccVtctBtaattgtWattat +BRcWcaatgNNtactWYtDaKttaaatcactcagtRaaRgatggtKgcgccaaHgaggat +StattYcaNMtcaBttacttatgagDaNtaMgaaWtgtttcttctaHtMNgttatctaWW +atMtBtaaatagDVatgtBYtatcggcttaagacMRtaHScgatatYgRDtcattatSDa +HggaaataNgaWSRRaaaBaatagBattaDctttgHWNttacaataaaaaaatacggttt +gHgVtaHtWMttNtBtctagtMcgKMgHgYtataHaNagWtcaacYattaataYRgtaWK +gaBctataaccgatttaHaNBRaRaMtccggtNgacMtctcatttgcaattcWgMactta +caaDaaNtactWatVtttagccttMaatcagVaagtctVaaDaBtattaattaYtNaYtg +gattaKtaKctYaMtattYgatattataatKtVgDcttatatNBtcgttgtStttttMag +aggttaHYSttcKgtcKtDNtataagttataagSgttatDtRttattgttttSNggRtca +aKMNatgaatattgtBWtaMacctgggYgaSgaagYataagattacgagaatBtggtRcV +HtgYggaDgaYaKagWagctatagacgaaHgtWaNgacttHRatVaWacKYtgRVNgVcS +gRWctacatcKSactctgWYtBggtataagcttNRttVtgRcaWaaatDMatYattaact +ttcgaagRatSctgccttgcRKaccHtttSNVagtagHagBagttagaccaRtataBcca +taatSHatRtcHagacBWatagcaMtacaRtgtgaaBatctKRtScttccaNaatcNgta +atatWtcaMgactctBtWtaaNactHaaaaRctcgcatggctMcaaNtcagaaaaacaca +gtggggWttRttagtaagaVctVMtcgaatcttcMaaaHcaHBttcgattatgtcaDagc +YRtBtYcgacMgtDcagcgaNgttaataatagcagKYYtcgtaBtYctMaRtaRtDagaa +aacacatgYaBttgattattcgaaNttBctSataaMataWRgaHtttccgtDgaYtatgg +tDgHKgMtatttVtMtVagttaRatMattRagataaccctKctMtSttgaHagtcStcta +tttccSagatgttccacgaggYNttHRacgattcDatatDcataaaatBBttatcgaHtN +HaaatatDNaggctgaNcaaggagttBttMgRagVatBcRtaWgatgBtSgaKtcgHttt +gaatcaaDaHttcSBgHcagtVaaSttDcagccgttNBtgttHagYtattctttRWaaVt +SttcatatKaaRaaaNacaVtVctMtSDtDtRHRcgtaatgctcttaaatSacacaatcg +HattcaWcttaaaatHaaatcNctWttaNMcMtaKctVtcctaagYgatgatcYaaaRac +tctaRDaYagtaacgtDgaggaaatctcaaacatcaScttcKttNtaccatNtaNataca +tttHaaDHgcaDatMWaaBttcRggctMaagctVYcacgatcaDttatYtaatcKatWat +caatVYtNagatttgattgaYttttYgacttVtcKaRagaaaHVgDtaMatKYagagttN +atWttaccNtYtcDWgSatgaRgtMatgKtcgacaagWtacttaagtcgKtgatccttNc +ttatagMatHVggtagcgHctatagccctYttggtaattKNaacgaaYatatVctaataM +aaaYtgVtcKaYtaataacagaatHcacVagatYWHttagaaSMaatWtYtgtaaagNaa +acaVgaWtcacNWgataNttcaSagctMDaRttgNactaccgataMaaatgtttattDtc +aagacgctDHYYatggttcaagccNctccttcMctttagacBtaaWtaWVHggaaaaNat +ttaDtDtgctaaHHtMtatNtMtagtcatttgcaaaRatacagRHtatDNtgtDgaatVg +tVNtcaaatYBMaaaagcaKgtgatgatMgWWMaHttttMgMagatDtataaattaacca +actMtacataaattgRataatacgBtKtaataattRgtatDagDtcRDacctatRcagag +cSHatNtcaScNtttggacNtaaggaccgtgKNttgttNcttgaaRgYgRtNtcagttBc +ttttcHtKtgcttYaaNgYagtaaatgaatggWaMattBHtatctatSgtcYtgcHtaat +tHgaaMtHcagaaSatggtatgccaHBtYtcNattWtgtNgctttaggtttgtWatNtgH +tgcDttactttttttgcNtactKtWRaVcttcatagtgSNKaNccgaataaBttataata +YtSagctttaaatSttggctaaKSaatRccgWHgagDttaaatcatgagMtcgagtVtaD +ggaBtatttgDacataaacgtagYRagBWtgDStKDgatgaagttcattatttaKWcata +aatWRgatataRgttRacaaNKttNtKagaaYaStaactScattattaacgatttaaatg +DtaattagatHgaYataaactatggggatVHtgccgtNgatNYcaStRtagaccacWcaM +tatRagHgVactYtWHtcttcatgatWgagaKggagtatgaWtDtVtNaNtcgYYgtaaa +ctttaDtBactagtaDctatagtaatatttatatataacgHaaaRagKattSagttYtSt +>THREE Homo sapiens frequency +agagagacgatgaaaattaatcgtcaatacgctggcgaacactgagggggacccaatgct +cttctcggtctaaaaaggaatgtgtcagaaattggtcagttcaaaagtagaccggatctt +tgcggagaacaattcacggaacgtagcgttgggaaatatcctttctaccacacatcggat +tttcgccctctcccattatttattgtgttctcacatagaattattgtttagacatccctc +gttgtatggagagttgcccgagcgtaaaggcataatccatataccgccgggtgagtgacc +tgaaattgtttttagttgggatttcgctatggattagcttacacgaagagattctaatgg +tactataggataattataatgctgcgtggcgcagtacaccgttacaaacgtcgttcgcat +atgtggctaacacggtgaaaatacctacatcgtatttgcaatttcggtcgtttcatagag +cgcattgaattactcaaaaattatatatgttgattatttgattagactgcgtggaaagaa +ggggtactcaagccatttgtaaaagctgcatctcgcttaagtttgagagcttacattagt +ctatttcagtcttctaggaaatgtctgtgtgagtggttgtcgtccataggtcactggcat +atgcgattcatgacatgctaaactaagaaagtagattactattaccggcatgcctaatgc +gattgcactgctatgaaggtgcggacgtcgcgcccatgtagccctgataataccaatact +tacatttggtcagcaattctgacattatacctagcacccataaatttactcagacttgag +gacaggctcttggagtcgatcttctgtttgtatgcatgtgatcatatagatgaataagcg +atgcgactagttagggcatagtatagatctgtgtatacagttcagctgaacgtccgcgag +tggaagtacagctgagatctatcctaaaatgcaaccatatcgttcacacatgatatgaac +ccagggggaaacattgagttcagttaaattggcagcgaatcccccaagaagaaggcggag +tgacgttgaacgggcttatggtttttcagtacttcctccgtataagttgagcgaaatgta +aacagaataatcgttgtgttaacaacattaaaatcgcggaatatgatgagaatacacagt +gtgagcatttcacttgtaaaatatctttggtagaacttactttgctttaaatatgttaaa +ccgatctaataatctacaaaacggtagattttgcctagcacattgcgtccttctctattc +agatagaggcaatactcagaaggttttatccaaagcactgtgttgactaacctaagtttt +agtctaataatcatgattgattataggtgccgtggactacatgactcgtccacaaataat +acttagcagatcagcaattggccaagcacccgacttttatttaatggttgtgcaatagtc +cagattcgtattcgggactctttcaaataatagtttcctggcatctaagtaagaaaagct +cataaggaagcgatattatgacacgctcttccgccgctgttttgaaacttgagtattgct +cgtccgaaattgagggtcacttcaaaatttactgagaagacgaagatcgactaaagttaa +aatgctagtccacagttggtcaagttgaattcatccacgagttatatagctattttaatt +tatagtcgagtgtacaaaaaacatccacaataagatttatcttagaataacaacccccgt +atcatcgaaatcctccgttatggcctgactcctcgagcttatagcatttgtgctggcgct +cttgccaggaacttgctcgcgaggtggtgacgagtgagatgatcagtttcattatgatga +tacgattttatcgcgactagttaatcatcatagcaagtaaaatttgaattatgtcattat +catgctccattaacaggttatttaattgatactgacgaaattttttcacaatgggttttc +tagaatttaatatcagtaattgaagccttcataggggtcctactagtatcctacacgacg +caggtccgcagtatcctggagggacgtgttactgattaaaagggtcaaaggaatgaaggc +tcacaatgttacctgcttcaccatagtgagccgatgagttttacattagtactaaatccc +aaatcatactttacgatgaggcttgctagcgctaaagagaatacatacaccaccacatag +aattgttagcgatgatatcaaatagactcctggaagtgtcagggggaaactgttcaatat +ttcgtccacaggactgaccaggcatggaaaagactgacgttggaaactataccatctcac +gcccgacgcttcactaattgatgatccaaaaaatatagcccggattcctgattagcaaag +ggttcacagagaaagatattatcgacgtatatcccaaaaaacagacgtaatgtgcatctt +cgaatcgggatgaatacttgtatcataaaaatgtgacctctagtatacaggttaatgtta +gtgatacacaatactcgtgggccatgggttctcaaataaaatgtaatattgcgtcgatca +ctcacccacgtatttggtctaattatgttttatttagtgacaatccaatagataaccggt +cctattaagggctatatttttagcgaccacgcgtttaaacaaaggattgtatgtagatgg +taccagtttaattgccagtgggcaatcctaagcaaaatgagattctatcctaaagtttgg +gcttgatataagatttcggatgtatgggttttataatcgttggagagctcaatcatgagc +taatacatggatttcgctacctcaccgagagaccttgcatgaagaattctaaccaaaagt +ttaataggccggattggattgagttaattaagaccttgttcagtcatagtaaaaaccctt +aaattttaccgattgacaaagtgagcagtcgcaataccctatgcgaaacgcctcgatagt +gactaggtatacaaggtttttgagttcctttgaaatagttaactaatttaaaattaatta +acgacatggaaatcacagaacctaatgctttgtaggagttatttatgctgtttactgcct +ctacaaccctaataaagcagtcctaagaatgaaacgcatcttttagttcagaaagtggta +tccagggtggtcaatttaataaattcaacatcgggtctcaggatattcggtcatataatt +tattaagggctcttcgagtcttactctgagtgaaattggaaacagtcatccttttcgttg +tgaggcatcttacaccgctatcgatatacaatgcattccaccgcggtgtcccgtacacaa +ggaaacttgttaccttggggatataagaaaactcacacgtctcattattaaactgagtac +aatttttgcacgagaaagtaatgcaatacaatatgatgaaagccagctaatgaaaaggga +tggaacgcacctcggatctgttgcactggattaaaatccgattatttttaaaaatattca +gtgctagagcatatcaggtctacttttttatctggtatgtaaagcccacggagcgatagt +gagatccttacgactcaacgaaaagttataacataactcccgttagccaaagcccaatcc +cgattactgccctaccctaacgtctgccatctaaatatcgaacttgttatgatcaatgtg +actacctcccaccctttccccttcatttgttccactggggataagctagcgttttcagaa +tcaatgcaataagaatagccaattgtctcacttcatcagagctcttggcaattccaggcg +ctacgtggttctggaatatattcatttttcaaatagtaatacgtttagtgttgctattgt +ctacacgtttggatattacgttatgtgagcggacatcaatagttgtctaactctttagta +agccagagatagcactcttagcgaatggataccatcttccataagtttagttaatagtcc +gaaacaactgcttcgagcatatttgaacctccttgtaggcaaatagcctcttcaaagcaa +tcttactaatagatagagtttgttttaagggactactagaaatgggacaatcttaatagt +atgacctaaactgacatttaaagatatatccaggtggcaagcataaagatcattgcgcca +cctccaccgtgggattacttatcagtcgatatcctatatgctaagtttgcgacggcagaa +tacaaactaagctgagttgatgctaaccttacctatgataccccattggaccggttaaca +gccctacttattccaaataaaagaacttttatgctgtagaagctattatagtgatgcctg +gtaacttcagtatattaaaatgacacacatacgccatatagagctcctggaactttgaat +aatgagcgaacttcgaagttgaagagcaagaaaccatatgtcacggttgcctaaagcccg +gtaaccagacatgtgctatcattgatcattatcgaggttttcataaccttgacccattat +cggctgtgcgcggacaagtacttaaatcactagtttcttcacctgcttatcggtaagaaa +taaggttggcaaagaatcgcataagacggacgtagagccgcagcgttgtgcgagtccagg +tgcatgcgcagcaataggattttaaattttgttccatttttaatttagccgtaaggatgt +ccgtaaatgattgaaaattggattcaatctttgggcctatgctactggaacctgatcgac +aaaatttcaaacatacgttaactccgaaagaccgtatttttgcggctagaatagtcagtc +gcttggagccatataccttaccacttaaacgacgtgctcctgtagttgaaatataaacag +aacacaaagactaccgatcatatcaactgaagatctttgtaactttgaggcgaagcaccc +tcttcgagacaactaagagtaaagtaccgggcgccgcaaggagtcgattgggaccctaaa +tcttgacgaattgctaagaggctcagagctaccactgtaatttctctagagcccataata +aatgaacgatacatccgtaggtagcacctaagggattataatggaagccaaatgcagtta +ataatattatatactggcgtacacgattcgacggatctctcacatagtgattcacgaccc +ccccctttgattgacacagcgtcagcattttgcaagaacgatcttctgcatagggtgcgc +caccgtaaggatgacgtcgaagctacaactgggtataatttaccatgcttccctgatgct +gagtgcaatacactaagaatgagtttttaccccatatcaccagtatttgttctgttattg +cgaagaaatggctatgctgagttggcgactaaagtcacccatcctttttattaggtaacc +ccctcccttaaactaactgatttgctggagctgccctgcatacatatactttatcattta +tggacgtccgtgacgcttattatccaccatagtcgatatgctacacggattcattaatgg +atcgtaggagtttaagttatatttactaagatcggtctcggctactatcccgccttaccc +ggcgctatttacggccatttttaatatattgacggtaattattcctatggtttcgaccgc +acgtccttggacaagaaagaatggcaaaaaaaatgtaaaagaaaaaaaatattgagtccc +taccatcatataaaaaatatgtgatgagtaacttgacgaaatgttagtggttattaaaga +ctatctattacaccttttgttttctgtcgtagtatattaaagtctagaagccttacagga +aaatcagggttatacagccgatactccgcagcatgaatcatcgaggaggtgtcctaccat +cgcgccttgtaatcttgtctgtgtatactgtatttagaccttttatacaaagtaaatatc +tcggctttatgtgattgggaggggcctactcaaacatgatgacttgacctaataatcact +gtgcgggcgtcttatgactagctattccttgaaatccaccaccaaatggttaatatgtaa +aaactttgacgatgaaacaaggtgaatgtgtagttactttgtgtaattagctgcgtcgag +cattgcttgtaaaaccgtcaatcgcacacgttacttccataaaatttctacgaatacacc +cttcttaaaaaaaacgtaggaattcacgagtttaacaaacgataactgtataaagtggaa +gtccgaagaaagcagatgcccgaactactcgaagatgtttcgttttcttaaccatagggg +cttcttaatggcccactacgcacattttgttcaagcccgagagggacatccccattacgg +gagtattactaaaactgttccgtaatacgttcagcaagggatgaaaaaggccactgctca +agttattgacgtgggagtattacatcggaagcctgaatcccacactatgatggtctgtac +aggcctagggactgcgtctagacggtattaccggcttctaatcatacgatcgtgagtctt +aacgggaagtaaggctcacacctaccccaaaccatttatctatgtaagtataaaattgtg +cgtaagtgttcaaagtggacaataaagacgtggcaaaaacccccgcacataagccgcttt +agatttcacaaataccaatgcggttaaaaacatccttgagtcgtacatacaccatactcg +cgttaaacggatataacagaagataataaatccggatgtggagtcggtgtaactatagaa +agccaagtgaaataatgcttaccagtcatttagctatacggctttcatttcatgtcaaga +gggtggagtttgacctgtacagttgatatatcaccgatacttagaactcacctaaagcta +aaattgctcgcagcgtgtaatccgcatattacaaacaatagatgggattcattatacata +agacacgatgatctgctttttcaggttgcgagatgttgcctatcgtcaatcgagtcctgc +cttacaccacttaaacaaaagtattgacagggaacctattttcgaggtattatatagtcc +agcttgaatatcaatttgacagttaacctagtgaaaatcagtaagaggaaatacgccaca +ttctccagtgaaattctacgggttatcgtctagtccaactatcaattataactcacgaga +tataagtaaattctcgtacttggcctgatttttattatactttggatccttagtaaacag +gaagggagaaaccttcaacgaaaaacactggattttgttttactctcaaagctcttatat +gacggaaataccctgtcaagtcttaactttattactagactaatgaaatgggcttggggt +ggccagaatcatagtacaatttagcggatacactattcggactttcctatcggctgtctg +gttggataagtatggggactaataggctagacatacctatacttaaactatacaggcgtc +atctatctctgcaactttggagttccctgatgttctcccgccctttgggttcacatcttc +tataccgacacccctaataacgattagtttgtgggttagagtaaattaatacggttaata +ttaatgtatcgttgaaaagctggtgtcgccaataaggtaaccggctaggcagagtatatg +tcacgaagtataactaccctaatgataagctgtaggaataaaattaatgctgtctctaag +cgaagagatatttccgactctgttttaatgacgaatctcattacttctgacttgcaaatg +ttcaatatggcacggtttcacggcacctttgtgacgcatataatgaacttagaagattat +aacgacggaactttatatgataatccgttacgattaaagaatctgttaaatatcataatg +gcattcagttctagaccgtgcatcatggtaaacttactttctctgcatggcgacatacat +ttcgctattcaaattcgcgtgtggttacacccactcgcacctttggaatattaagagaag +atgatcagaaaatccattcgctcaatttttctgacgtacgtctaatttatcctaggagac +aaatcgttttatgtctctcacatttttgaagaaaggttcgagagacaatactcaggtcct +gaactgctagaagatactcggtggagcgtggcaacaatgaaaaactcgtgacataaatga +atgatacttttccaagttcagttaagtgaatatgtttaacatacccggcttttcgatctt +aagctgacgctggacgtgcgagtaatgtcagtctcttacatacactagtgactccaagtt +tcgtcaaaaacgccccctcccttctcgagcccactcacgctatgtattgacgcgaacttg +ttcgggatcagacttttcaggagttcggtcgcgtgtccctatgtgctaatatataagtta +gatcgcattagatgctaatctgaatacttatagacgaccttcaacgagaacgggtaccac +cttgaggctagagttaggtgtgaaacgacaggtagggacatataaaatttgagtgcggct +ttagttaagggtttaattacctactcaaacatcacgctcgcgcccttcgtacgtaatcga +ccatctagaggctaaggggactgtactaggtagtgattaatgatatcctagacgcacgtg +ccttagatcttcagactctgatggtccgcgatcaccgtaattgtagtcctccaactcgat +cactttgttggcgtcaaagaaattacgatatctaaatacttataatacaataaccaagga +tgagaatgactcatcgcgttggagttatattgcttgaagttctatggaatgaaagcacgt +tatctgccgtcccaatatctccagtgagctaattcattggacggtccactttgatcaatc +cccgaggagatgttcggacactttagtctgtaacacttagcgttgagaccacgaacaatt +gattactcagtcttgaaggtgttttccaaagttcattttaaataagactacgataggcct +ttcctattgatataaactacccggctctgttgttcgtgtgagtcgtacttctctgtgttt +ttctgattatagcaagattcgattcttagtgtaaacagcgatttttatttgacccgtcaa +tgagaagcgcataggatctaagcaaaattatcaagttgtgccacaaggtaagatctttcc +agttattgcaggtaggatgtatcccacgttgatagtatgaggtctgacgtcaactgtcta +ggagagttgaccgcgtgcgggtacaccggatttgcatcgatgttgagaacgcagaactcc +cactgtcgtggcggcgttcctgatatttagcaagaggcgttgataaagccctcatcatct +agatctcgacctcatctgccctcttgctccatcattttctacacagactactttcctatc +tacgttagtataattgctttctatcttagtatcatttagagcttctccgtcaacaggttc +gtgctattaaagttagtacgaaagggacaacttgtagcaacgcatttaatcggttttcga +ctacttcgcacaaaatcagataaagaagtttgtcattctattagacattgaattgcgcaa +ttgacttgtaccacttatgatcgaacactgaatcaagactgtgattaactaaaatagaca +agccactatatcaactaataaaaacgcccctggtggtcgaacatagttgactacaggata +attaattggactggagccattacattctctacaatcgtatcacttcccaagtagacaact +ttgaccttgtagtttcatgtacaaaaaaatgctttcgcaggagcacattggtagttcaat +agtttcatgggaacctcttgagccgtcttctgtgggtgtgttcggatagtaggtactgat +aaagtcgtgtcgctttcgatgagagggaattcaccggaaaacaccttggttaacaggata +gtctatgtaaacttcgagacatgtttaagagttaccagcttaatccacggtgctctacta +gtatcatcagctgtcttgcctcgcctagaaatatgcattctatcgttatcctatcaacgg +ttgccgtactgagcagccttattgtggaagagtaatatataaatgtagtcttgtctttac +gaagcagacgtaagtaataatgacttggaataccaaaactaaacatagtggattatcata +ctcaagaactctccagataaataacagtttttacgatacgtcaccaatgagcttaaagat +taggatcctcaaaactgatacaaacgctaattcatttgttattggatccagtatcagtta +aactgaatggagtgaagattgtagaatgttgttctggcctcgcatggggtctaggtgata +tacaatttctcatacttacacggtagtggaaatctgattctagcttcgtagctgactata +ctcaaggaaccactgctcaaggtaggagactagttccgaccctacagtcaaagtggccga +agcttaaactatagactagttgttaaatgctgatttcaagatatcatctatatacagttt +ggacaattatgtgtgcgaaactaaaattcatgctattcagatggatttcacttatgcctt +agaaacagatattgcccgagctcaatcaacagttttagccggaaacaatcgaagcatagg +gacaatgtatcttttcctaaattgccatgtgcagatttctgagtgtcacgaagcgcataa +tagaatcttgtgttgcctcaactcgttgaaaagtttaaaacaatcgcagcagtctttttg +gggtctactgtgtgtttgcaaaataactgaaagaaacgcttgaacaactctgaagtagct +cgagtactcattaaagtgtaacacattagtgaatatcggccaatgaaccaaacgcttccc +ggtacgctatctctctcatcgggaggcgatgtgcaggttatctacgaaagcatcccttta +cgttgagagtgtcgatgcatgaacctcattgtaacaatagcccagcaaattctcatacgt +gcctcagggtccgggcgtactcctccatggaagggcgcgcatctagtgttataccaactc +gctttttaactactatgctgtagttctacaggcatagtggccagtattttctaacttctc +tggatagatgctctcactcctcatccatcacggcttcagtttacgtcttacttgcttgtt +cagcaacggatggaggcattaagtatcttcactgttccctaaaattgctgttcaatatca +aagtaaggacgatacagggaaagctcaagcacactcattgaatactgccccagttgcaac +ctcacttaatctgacaaaaataatgactactctaagtgttgcggaagcagtctcttccac +gagcttgtctgtatcacttcgtataggcatgtaactcgatagacacgaacaccgagtgag +aaactatattcttgcttccgtgtgtgtgacaccaggtaattgatgcggatataagctgga +gatcactcacgcccacacaaggcgctgctacctctttattccaatgtgtaagaatttgct +aacttcatttctagaccgcagctttgcggtcataatttcacggtacggacccttgggtta +gagacttgataacacacttcgcagtttccaccgcgcacatgttttagtggcttctaacat +agaatttttgttgtgacataaagagtgcgtgggagacttgcccgaccgttaagccataat +caattgaaagccccgtgagtcacatctaattggttgtactgcgcatttagctatccttta +gctgactcgaagagattcgattcctaatataggttaattagatggctgccgcgcgaagta +aaacgtgaaaaacgtagtgcgcagatctgcataactcgcgcttaattacttatgagtagt +tccaagttcgctacgttatgagagagattggaattaagcaaatatgttttatggtgattt +tgggatgagaaggactgctaagtacggctactaaacaaatttctaaaaccgccatctacc +ttatcttggagacatttaagttgtatatgtcactagtctagcttttgtctgtgggacgcg +ttctcggaatgagggaaatgcaagagccgattcatcaaatgcttatctaagaaagtagtg +gactattacaccaagcacgaatgccagggaactgctttcttgctcaggacctcgcgacaa +ggtaccccgcataagtcctagaattacatttggtcagcaatgctgacatttgaccgtgaa +aacataattttaatcagaaggcagctcacccgcttgctctagatcttatctttgtatgaa +tgtcagaatttactgcaatatccgttccgaatagtgagggcttagtatagttctctgtat +acaggtcacatcaaactccccctgtcctagtacagctctgagctttaattaattgcatac +atttccttcaatcatcagatgaaaacaccgcgaatcatgctcttctcgtatagggcaaga +gaagcaacaaacaactagcccgactcacgttcatccgccgtatccttgttcagttcttac +tccgtattaggtcagcgaaatctaatcagaataatcggtcgcgtatcaaaattaaaatcc +cgcttgaggttgacaattaaaacgctgagcagttatcggctattagatagtggggtgaaa +gtaattggctggaattatgttaaaacgtgatattaagctaaaatacgctacttgttgccg +acctaattcagtcattcgatattcagttagagccaagaataacaagcttgtataaattga +acggggtgcactaaacgatgtgttactctaatattcagcttggagtatacctgaaggcga +attcatgtatcggccaataataagacgttgaagatcacaatttggactagcaaaagaagg +tgatttatgcgtggggattgagtccactgtacgagtacggtctctggaaaattataggtt +cagggaatataaggaagtaaagataattaccaagagatttttggtatcgctatgacccag +aggtgttctaacgtctgttttgatccgcagaatttctgcctcaatgcatatttgacggac +ttgaactagagcctctaaagttaaatggcgacgcaactgttcctaaacttcaattattac +tactctttttttcctagggtattgtagaggccagtggacaaaataaatcaaatttaagat +gtttcggacattaacatcccccgtagcatagaaatcatcagttatccaatctctcatcga +gcttttacaatttctgctggcgctatggacagcatatgccgcgagacctccgcaagactc +acttgatcactgtaagtatcttcattagaggttagagcctatagttaagctgctgaccta +gtaaaattggtattttctaattttattgctcaagttaaaggttagtgaagggataatgac +gttatttttgaacaatgggttgtattcaattttatatcacgaatggaacccttcattccc +ggcataatactagacgacacgaacaagctccgatctatcagccaggcacgtgttaaggtt +taattccggcaaaccaatgaagcatcaaaaggtgacctgatgcaacttagggtcacgatg +agtttttcaggactacttattacctattaataagttaacatgagccttcataccccgtaa +gacaatacatactccaccaattagaattctgagccatcttatctttttgtatcatcgaag +ggtatggccgaataggttaattagttactcctaacgtctctacaggcatgcatttgacgc +accttcgaaaatagtcaatctctcgccacacgcgtctagtatgcagcatcaaaaatatag +tccacggtttccggattaccaaacgcggcaaagagaaacattgtatcgacggagataact +taatacagaaggaaggggcatcttcgaatacggatgaataattctatctgtttattctga +catcttgttttcaggttaatcttacgcattcaaatgacgcctgccccatgcgtgcgcaat +tattttctaatattgacgagagcaatctcactccttttgggtctatttatgttttattga +ggcacaagcctatacagaacaggtactattaaggccgtgagtgtgagactcaaaccgtgg +aaacaaaggatgggttgttcttggtacaagttttagtgcatgtgggcaatccttaccaaa +atcagatgctatccttaactttgggctgcatttaagatggcggttggaggcctgtgagaa +tcctgcgtgtcatctttaatgaccgaattcatccatgtagattcagatcacacactcatt +ccttgatgttgtctaaacaaaagttgttgtggacgcattggagggagttaagtaacaact +tgggatcgcatacttataaaaattatatgttaaactttcacaaacgctgaagtccaaagt +aactagcccaaacgcctcgagagtcactaggtattaatggtgtttgagttcctgtgaaat +agtgttcgaaggtaaaatttatgtaccaaatcgaaagaacacttaataaggcttgcttgc +acggaggtatgatgtttactgactctacaaccctaattttccagtacgtacattcattcc +aataggttagttctcaaagtgctatacaggctcctcaattgatgatatgcttcagccgct +ctatggatattagctcattttatttaggaagcccgcttagaggcttactatgagggaaat +gccaaaatgtcatacttttcggtgtgtcccatatgacaccgctttacatagaatttgaat +taaaacgcgctctcccgttcactaccatacttggtaccgtgcgcatattacatatagata +taggatcattttttaaagctgtactaggtttgatcgacaatcttatgctatactatatga +tgtaaccctcataatcaataccgatcgtacgatcctagcataggtggcaagcgattttat +gccgattattgtgttaaatagtctgtgagtgtgattatcagggctacgttggtagagggg +ttgtatagacctcgcacacattgtgacatacttaacaatatacgaaaactgatataataa +atccccttacccaaacaccaatcccgttgaatcaactaccataacgtctcccatataaat +tgcctacttgtttgcataaatctgaatacataacaccattgcaccttcttgtgttccaat +cccgttaagattgccttgtcagatgatatgcaagaacaatagcatttgctagcaattatt +aacagctcttcgaattgcctccacataacgcgggagggtatattttaatttggcaaatac +taagtactgttggcgtcatatgctattaacggttggatattaagttatgtcagccgtaag +caagagtgggcgaaatattttgttacccagtgagagcactcttagagtttggatacaata +ggccatatgttgacttaagaggacgtaactacgccgtacaccattgttcaaccgacttct +tggcaaatagaatcgtattagcaatcttaagaatagagacacgttcgtgttagggtatac +tacaaatccgaaaatcttaagaggatcacctaaactgaaatttatacatatttcaacgtg +gatagatttaacataattcagccacctccaacctgggagtaattttcagtagatttacta +gatgattagtggcccaacgcacttgactatataagatctggggatcctaacctgacctat +gagacaaaattggaaacgttaacagcccttatgtgtacaaagaaaagtaagttgttgctg +ttcaacagatgatagtcatgacgcgtaacttcactatagtaaattgaaacaaatacgcaa +tttagacagaatggtacggtcatgaatgacagtaattcgaagtgctagaccaacttaaaa +taggtaaacgtgcccgaaaccccccttaacagaaagctgctatcatggtgcagtatcgac +gtgttcagaaacttgtaacttttgagcaggtccgagcacatggaagtatatcacgtgttt +ctgaaccggcttatccctaagatatatccgtcgcaaactttcgatttagtcccacgtaga +gcccaagcgttgtgcgactccacgtgcatgcccagaaatacgagtttaaatttggttaca +tggttaattttgaccgaagcatcgcactttatgattgataattggattcaatatgtcgcc +ctatgcgaatgcaacatgatccacaatttggctataagacgtttaatccgtatcacactt +tgtttgcggctagtatagtaacgcccgtgcaccaagagtcagtaacaattataagtactc +cgcaggtacttcaaatataaaaactaatcaaacacgacccatatgatcatctgaagatat +ttggaactttctcgacaaccaccctcgtactcaatacttacactaatcgacaggcacacg +caacgtgtacagtcgcaccatattgagtcaagatttgcttagtggcgatgagcgtacacg +cttatttctctagtcacaattagttatctacgagacatcacgagggagcaaataagcgat +gttatggctacacataggcacgtatgaatatgatataagccagttaaacagtcgaaccat +cgagcaaattctcatgcaccaacccacacgttgaggcacaaagagtaagctgtttgaatg +taacttcttctgctgagcgggccccaacgtaaggatcaactagaagagaaaactcggtat +tagtttaaatgcgtcacggagcatgagtgcatttcactaagaatgtctgtgtaaccaata +taacatctatttgttatctgattgcctacttatggctttgcggtcgtggcgactaatgtc +tccaatccttttgaggtcggtaccaactccctttaaattacgctgtgcaggctcatgcac +tgcatacatatacggtagcaggtagggacctcacgcacccttattataatcaatagtagt +tatcagtcaacgaggcaggaatgctgaggtcgaggtgttggtatattttctatgtgccgt +ctaggcgactatcacgcattaccaggcgagatttaagccaattttgaatatagtcaacgt +aatttttactatgggttccaccgaaacgccttgcacaactaagaatcccataaaatatcg +atatcaaataaaagattgtgtcaataccttcatatatattttttcggttgactaacgtga +actaaggttaggggttttgtatgtctatataggaaacagtttcttttctgtcctacttta +gtaaagtcttcaagccttactccaaaatcacggtgattaagccgttactcagcagcatga +ttctgcctgctcgggtcctaaaatccagccttgtaagagtcgctgtgtattagctaggga +gacctttgttaaaaaggatatatcgcggcgggatgtgagtgcgtggcgcatactcaatct +tcagctcgtgtcattataatatctctcccccacgcttttcactagatatgccgtgtaagc +aaacaccttatgcttaatttcgaaaatattggtacttgaaaaaagctgtaggggtactta +atgtctggtaggagatcaggagagaattgagtgtaaaaccgtaaagccctcacctgactt +catgtaaatggcttagaagactccatgatttaataaatactacgaaggaaagactggatc +taaagataactctagtaaggccaactcccttcaatgctgttgccagttataatccaagag +ctgtccttttctgaaccatagcggcttctgaagcgaactagaagcaaagttggttctagc +cagacagccacataccctgtacgggtgtattactaaaactggtccggtattagttcacca +agggaggaattaggcaaaggatctaggtatgcaagtcggagtattacatccctaccctga +atccatcaataggttcctctgtactggccttcgcaatgagtattcaaggttgtacagccg +tataataataagatagtgactatgaacgggaagtaacccgctcaccttccccaaaacatt +gttatatctaagtattaaagtctgccgtagtgttaatactcgaaaataaacaactggcaa +attacaccgcacttaagccgcttttgatttatatttttccaatgcgcttttaaaaataat +tcagtcctacatactaattaagacccttaaacggagatatcacaagttaagttttaacca +tctcgactaggtggaactatagatacccaactcaatttatcattacctgtaatgttccta +gaaggattgcatttcatgtcaagacggtggagtttcacagcgaaacttcagtgtgaacag +attctgagaaatcacctaaacctattagtcagagcacccggttagaaccagttgtcaaaa +aatagagcggttgcatgagacagaagtaacgatgagatccgttgtaacgttgagacatct +ggcctatcgtcaatacagtcctcccttaaaaatatttttaaatactaggcaaacccaaca +taggttagtcctatgtgatacgccacatggtatatcattttgtaacgttacctagggata +atcaggaagtggaattacgcaaaagtagacagtgaaatgcttagggttatagtctagtcc +aaagataaaggataaagcacgtcagagaactatattagccgaatgggaatcattgttagg +agactgtggatcatgtctaaaaagcaacgcagaaacagtcatcgaaaaaatctcgttttt +gtttgaatctaaaagagctttgatgaccgatagtacctgtatactagttactgtattacg +tgtctaatgatttcggattggggtccccagaatcagacgtcattgtagacgattcaagtt +taccaatttaatttcccagctctccttggagaactatcgccaataattgcagtcactttc +cttttctgaaacgataaagccgtcagagttctctgcaacgttggacttacctgaggttct +aacccactttcggttctaatagtagttaacgacacaacgaataacctttactgtggggct +ttcacgatattttttcgcttattattaatggttacgtcataagctggtgtccaaattaag +gttaccggcttcgcagagtagttgtatccaagtataacttccctaatcataagatcgagg +tagaaaattaatgctgtctctaaccgaacagatatgtcccactatgtggtatggacgttg +ctaattacttctgaagggaaattggtcattatggatacgtgtctaccatcaggtcggacg +cagatatggttctgtcttcagttgatccaccgttctttataggataataactgacgatta +aagattatggtaaatagattaagccaattctcttcttgtcagtgaagcatccttaactga +cttgctctgcagcccctcatacatttagctattcaaagtaccggctcgtttcaaactctc +ccacctttggaagaggttgtcaacttgataagtatatcatttacagcattttttcggacg +tacctctaatgtttcattgcagaaaattagttttttctatcgcacattttgcaagtaacg +ttagagacacaattatctgcgaatgaactgctagatctgacgaccgggagcctcgcaaat +atcaaaaaagactgacatatatcaaggagtcgttgacaagtgctggtaagtcaattggtt +tatctgtcccggcgtttcgatcttaagctgaccatgcacggcagagtaatgtcactctcg +ttcttacaagtctgtctccaagggtcggcaaaaaagacccctccattctcgagcccactc +acgatatgtagggacgacaacttgtgcggcttatgaattgtctggactgcgggcgagggt +ccatatctccgaagttagaagggacatacctttagatgataagatcaattcttattgacg +aaattcatccacaacggggaacaacttcaccctagacttacgtctgaaaagacacctagc +gtcttataaaaggtcagtgccccgtttcgtaaggctggaattacctacgcaaacttaaac +ctcgcgcccttccttacgtatcgacaagatagaggctatcgcgaatgtactacggaggca +tgaatcatatactagaaccaagtgcctgtgatattaacaagatgatccgacgcgagcacc +gtaattctaggcataaaactccagcaatttgggggccgaaaacaaatgacgttagctaat +taattatatgacatgatcaaaggaggtcaatcacgcatcgagttcgacgtatattcattg +aacttcgtgcgtttgaaagaaacttttatgaaggcaaaattgatcctgtctcctatttca +tgcgtacctcctagttgataattccccgagcagtggttaggacacttttgtcggtatcaa +gttccggtctcaaaacgtaaaattctgtaatctgtatggatggtctgtgaattagttaat +ttttatgaagtcgtcgagacgcagttcctattgatttattctaaacggagatgtgcttcg +tgggactcggaagtagatctgtgtttatgattattgctactttagatgctgactgttaac +tccgtgttgtttttcaaccgtatatcacaaccgaattggatagaacctatagtttcaagt +tctgccacaaggtatcatatttacagttagtgctggttgcttctttcaaacgtggtgagt +ttgtgctatcacgtcaacggtagagctcagtggaccgagtgcgcgttcaaccctgttcca +gagagggtgtgatagcacatataccacgctcgtcgaggcgttcatgatagtttgcaagag +ccggtgttaaacacatattattattgttatccaactaatcggacctatgcataaagcatt +gtctaaacagaataattgcctatatacggtagttttagtgatttatatcttagtatcagt +tagagcttcgaactcttcaggttcctcatatttaacgttcttcgaaagcgaaaacttcta +caaacgaatgtaagcggttttccaagtagtacctataaatcacagaaagatctgtctcag +tatagttgaaatggtattcagctagtgacgtgtaccaattatcatagttcactcaagcaa +gacgctcattaacgaatatagacaagacactatatcatataataaaaaagaacatggtgc +tcgaacatagttgaattcaccatattgaaggggaatgctgacatgtaattcgctactaga +cgatcaattccctacttgtcaaagttgaactggtacgttcttggaattaaatatgattgc +gctggaccaaattgcgacttcttgagtttcagggcaaacgattgagccggaggatgtccg +tctcttacctttcttgcttatgataaacgacggtccctgtacatcactgggaattctcag +caaaaataattgggtaaatcgagactcgatgtattcggccacaaaggtgttagacgttaa +agattattcaacggggcgataataggatcataaccggtatgcaagcgcattgaaagagcc +atgagatccttatccgataaacgctgcacggtatgtgcagccttattgtcgatcacgaat +ttataaatgtagtctgggctgtaagttgaagacctaagttataatgaagtgcaataccaa +atcgattcatagtggattatcagactcaagatatctcctgataaattacagttgttaaga +tacggataaaatgagatttaagattagcagcctctaatctgtttcaatcccgttggaatg +tggtatgcgatcaaggttaagttaaaatcaagcctgtcttcagtcttgattcttgttctg +ccatcgcatgcggtctacgtgagttaatatgtagcttacgttctagcttgtgctaatctg +agtatagattcgtagaggaatattatcaagcttccacgcctcaacgtacgtgtattggtc +acacaagacactaaaagtggaagtagcgtaaactatagtctagttgttaaatgctcagtt +cttgttatattcgatatactcttggctaatttatgtctgagtatataaaattaatgatat +taacttgcatttcacggatcccttagaaaaagattttgaccgagcgcattataaacggtt +acaccgaatcaatagaagcatacccaatagctttctttgaatttattgcctgcgcaactt +ggctgactctctagatccgaataattctatatggtcgtgacgaaactagttcattactgt +ttaaaatgccaacatgtcttttgggccgataatggctctttgcaaaattactcaatgata +cgattgatcaaagcggtagttgctagtggtagcatgtaagtctatcaaatgtctgattat +ccgaaaatcttccaaaagagtccacgtaccatatctatctcatagcgacgcgaggggaac +cttatctaactatcattccatttaccgggtgactctcgatgcaggatccgattgggataa +attgcccagaaatggctcattcctgactaagggtaaggccgttctcagcaagggaacccc +gcgaatctaggcttataccatctagattgttaactacttgcctgtagttctacagccata +ctggacagttgtttctaaatgatcgggattcatgctagcactcctctgaatgcaccgcgt +aagtttaactattacgtccgtgggcagataaggatggaggctgtatgtatcttaactgtt +acctaatatggctggtaattatcaaagtaaggaccttaatgccatagcgctagcaatcgc +tttgtatactgaccatgtgccaacctctcttaatctgtaaaatataatgtcttagctaac +tgtggacgatcatgtctctgcctagagcttcgctgtatcaattcctatagccagcgtact +agtgacacaacaacaccgtgtgagaaaagatattagtccttacgtctgtctctctacagc +ttattgatgaggattgaacatggacatatagctccccctcaaaagcagatgctacctctt +tattccattctcgaacatttgccgaacttaatttcgacaaacctgaggtcacgtcttaat +ttatcggtaacgtcacgtccctttgagactggataaatatattaccaggggccaacgagc +aattgttggaggcgcttctataatacaaggtgtcttgtcaaagaaagacggcgtgcgtct +cgtgcaactcacttaaccaatattaatgtgaaacccccctctctcacatcttatgcggtg +tactgccctggtacatttcctgtacaggactccaacagtgtagattcctaagatagctgt +tggagttgcctcacgccagatcgaaaaactgaataaactagtgagctgagctgcagaaat +accgcttaattacttatgactagttcaaagggacctacgtgatgtcagacattgcaagga +agaaattaggtttgtgcgtcattttggctggactagcactccttacttcccctactattc +aaatgtcgtaaacagcatgagacaggatcgtgctgacatttaaggtctattgggaacgag +gctacctttggtcgcgcgctcgcgttctccgaatgaccgaaatgcatgagcacagtatgc +aattgcttatagatctaaggtctggtcgttgaaaccaagcacgtaggcctgggaaatcag +ttcttcctcagcaactacacaaaagcgtccaagcattagtacttgtagtaaatgtccgaa +cctatgcgctcatttgaaagtcaaaaaatatttttaagcagtaggcacctaacccgattc +ctctacttagtagctttctttgattctcagaattgactgcaatatcactgcacaattctg +tgccattactagacttctctgtattaacgtctcatcttactaacactcgcctaggacaca +tctgagagtgaagtatttcaatacatttactgaaatcttcagttctaaaatccccgaata +aggctcttatcggtttggccaacacaagaaaaaaacttcttgcaccactcaccttcatac +gcaggagcctggggaacttagtaataactatttcggcagacaaagcttataacaagttgc +cggcgcgtataatatttaaaagaccccttgagctgctcaattaaaacgctcacctggtat +aggctattagatagtgccgtcttagtaaggggcgggaattatcggataaactgatatttt +gataaaataaccgacttgttcacgacataagtcactaaggagattttatctttctccaaa +gtatatcttccttggataatttcaaagcgctgcaatttaagttctgttactagtttatgc +tgctgggaggtgaccggaaggcgtagtaatctagaggcaaattataagaagttcatcata +tcattttcgactacaaaaacaaggtgttgtatgccggcgcattgtgtaaactggacgagt +accctagatggaaaattatacgttaagccaagatttcgatgtaatgataattacctacac +atttttgctatccataggaacaagagctgttctataggctcgtggcatacgaacatttgc +tgccgctatgaatattggaagctcttcaactacagactctattcttaattgccgtcgaaa +atgggccgaatcggctattattaatactcggtttttccgaggggattgttgtcgacagtc +gtaattattattaatattgatgttggtgaggtcatttaaatacaaccttgcagacaatga +ataagggatccaatctctcatactccttttacaattgctcatgcccctatgcaaacctta +tgccgccacacctccgcaactctctcttctgaactgtaagtagcttcattactggtttga +gactatactgaagctgatgacattctaaaatggctattttcgaatgtgattcataatgtt +tatcgtttgggatggcagaatcacgttatttttgatatagcccgggtattctattgtata +gaacgtatgctacaagtcattccccgaagaagactagaagtaaacaacatgcgaccatcg +ttaagccacgcaaggctgtagctttatttcccgataacctatcttccataaatagcggac +agcaggatactgacgctcaacatcagtggttatggtctaatttttaacttttaataaggt +aacttcagcaggcatacacagtaactctttaatttataatcaaattagaagtctgacact +tcttatatttttctatcatccaacgcgatcgcccattagcttattgtgttactaataacg +tatctaaaccaatccttttcaagctactgcctatattgtcaatatatacaaacaacagga +tagtaggctgcttaaaaaatattgtcaaccgtgtacgctttacaatacccggaaatcaca +aactttgtagacaacgagtgaaatttatacactacgaagggccagcgtacaagacccatg +aattaggcgatatgtttattctgacatattggtttatccttaatctgtcgctgtaaaatg +aagccgcccccatccctgcgaattttttttcgaagattcacgactgaaatataaatacgt +ttggctatatttatgttggagggaggcaatagcctttactgttaaccgaagatttagcca +gtgagtgtgacactaaaacactggaataaatgcaggcgttcttctgggtaaaaggtttag +tcaatctcgcctataagttcatatagctctggatataattatctggcccatgcatttatc +atggcgcttggtgccctgtgtgaagccggcctctcatattgaaggtccgaagtattccat +gtacattaagatcactctctcattcatgcatcttggcttaacaaatctggttgtccaagc +tttccaggcacgtatggtacaaattcggatcgaatacttataaaaatgatatgttaaact +gtctaaaacgctcatctacaaagtaaagtgcactaaccaatagagtctcaagaccgtgta +atgctggtgcactgaatgtgtaatacggttagaagggattagttatgttacaaatccatt +gaaaacttaagaagcattgcgtgctcggagggtgcatcttttatcaagagactaacatta +ttttcaacgacgtacatgctttacaatagggtacttatcaaacgccgagaaacgcgccta +tagtgatgttatgattatgacccgatatccattggaccgaattttatgtaggttcccagc +gtactcgcgtaatatctcggtattgccataatgtaatacttgtcggtctctcccagatga +aaaagcgttacagagtatttcaatgaaaaacagcgcgcaacgtcaatacctttaggggta +acggccgctgatttcatatagatatacgataagttggtatagctctactaggtggcatcc +acaatcgttgcatttactatagctggttacaatcataatctataccgttccttacatact +accatagcgggatagcgtttttttgccgttgattgggtttaagaggatgtcagtctcatt +atatccgattcggtgggagagccgttgttttcaaatcgcacactttgtgacataatgtac +aagataacaaaactgatataagatataaactgtcaatatcaccttgacacttgaatcaaa +gtaaattaactcgcaaatataatttgactaattgggtgcagatttctcaattaataaaaa +aatggcaccggatgggcttacaagccccttatcattcacttgtatcatgatttccaagaa +caatagaatttgctagcaagtatgaacagagattcgaattgcatccacagtacgccggag +cgtttattttaatgtggatatgacgatgtactgttggcggcatttgctagtaaccggtcc +ttatttacgtagcgcacacgtaagcatgtctgggagaaatatggtggtacaatctcagag +aaagattacagtttggtttaaataggacttatcgggtcggaagtggaacttaataagcag +tacacaattgggcaacagacgtcttgcctattacaataggattacaatgcgttagatttc +agacacgttcgtgtttggctattcgtcaattccctaaatagttagacgatcaactattat +caaagtgattctttgttcatcctccattcatgtaacagatggcacactacgcataacgcc +gaggaattttaacgagatttaagagagcagttcgggcacaacccacttgactttataaca +gctcggcagcataaacggtaatatgtgacaaatttccaaacgttataagaacgtatgtgt +acttagaaaactaagtggttcatgttcaacagatgtgacgcagcaagcctaacttatcta +ttggttttgctataaaagaacaaagttacacagaatcctaagggcttgtttcacacttat +gcctagtgcttcaccatcttaaaatagcgaaaccggcacgaatcaaaccttaaaacaatg +cgcagatattggtgatggtgactccgggtatgataatggtaactgttgaccagcgcccac +ctcatcgaagtatagaaagtggttaggataaggatgagaccgaacttatttccggccata +actttagattttctacctagtacacaacatcagggcggacacgaaaccgccatcacatca +tataccaggtttaatttgcttaatgggggaagtgtcaacgaaccttcgaactttagcagg +catatggccattatatatggccccagagcagaatgctacagcagacaaaatttggattta +tgtagtttaatacctatcaaacttggtgtgaccatacttgtctaacgacagtgcacaaag +tgtaagttacaattattactactcagcagcttctgcaatgataaaatcttatcatacacg +tcacatatgataatatctacttagggggaacgggctccacaacctacatagtactcaata +cttacactattcgacaggcacaccaaacctgtacagtcccaaaagattgagtcaactttg +cagtactgcagatcacagtaatagcttagttagcgagtcaaaattagttttctacgagac +tgcacgaccgtgcaaatttccgatgtgttggctacaaatagcaacgtatgaatttgtttg +aagccacgtaaactgtacaaccttagagataagtctcaggctactaaaaacacgttgtgg +cactaacaggatcatggttgattcttacttattcggctgaccggcccaataagtaacctt +caactagaacagaataatcgggagtagtttaattcagtcaaggtgcaggtctcattgtaa +ctaacaagctctgtgtaaccaagttaaaatcgttttcttagcggattccctacttatgga +tttgagctcgtccacaatattcgatacaagaagtttgtggtccgtaacaacgaaatttta +attacgctgtgcagcctcatccaaggaattaatagaaggttgatggtaggctccgaacgc +tccatgattataatcaagtggactgtgcagtaaacgaggaaggtatcctgacgtcgtggt +gttcgtttttgttatttgtgccctatacgagtagataaaccatgaacagcacagtgtgaa +cccatggttgattttaggctaccttatttttaatttccgttacacagaaacgaattccac +aactaacatgccattaatttttcgatatcttataaaagatggtcgaaattcattcattta +ttttttttcggttctcgaaagtcaactaagctgtcgcgttttgtttctctttagaggtaa +aagtggctttgatctcctacgtttggatactagtcaaccattactccatttgatccgtga +gtatcacctgtctaacatccagcattatgactcctcggcgaagaaaagacacacttctta +gagtcgatgtgtattagctagggacacagttgtttaatacgatagtgagcccagggaggg +cagtgcgtcccccagtagatttattcagctagtgtaagtataagatatctcacccacgag +gttcaagtgatatgcagtcttagaataatacttatcctgaatttcgatattatgggtact +tcaataatccgctagcgctactttatgtctcgttggacagcaggacacatggcagtctta +aacactaaagacatcacctgaatgaatgtaatgggattacaagaatcaatgaggtattat +atacgacgtaggaaactctggatatatacagtaatctagttacgccatcgcacttcattc +ctctggaaacttagaagacatcagctgtacgtggaggaaccagacccccgtatgtagcca +aatagaaccaaagttgcttatacaaacacacccaatgacaatggaccgctggagttcgta +aactcggaacgtagtactgcacaaacccagcatttagcaataggagctacgtatgcaact +cccacgtggtaataccttcaagctatcaatatataggtgcctagctaatcgcattcgcaa +gcagtattcaagcttgtaaaccagtataataattacagaggctctatgaaacccaacttt +ccagctaaaagtcccaattaaatggttatttcgtacttttaaagtcgcccgttctgttat +tacgcgaattgattctactccaaaattaaacacaaattatcaaccgtttcatttatattt +gtcaatgcagctgtttaaaataaggctctactaaattataattaagacacttattaccag +atttctctagttaagtttgaaccagctcgactaccgcgaaagatacattcccttctctat +ttttcagttcatctatgggtcagagaagcattgaatttattctattcaccctcgtcgttc +acagcgaatcgtcagtgtgatcagtgtatgagaaatatcctaaaccgtttagtcagacca +cacgcttagaacaagtggtctaaaaagactgccctggaaggagtaagaagtatacagctg +atccggtgtatccttcagtcatctgccctatactaattacacgacgcaaggaaaaatagg +tttattttctaggcaaacccttcataggtgactccgatgtgttacgaatcatgcttgaga +atgtgctatcgttaccgacggataataacgatctccaatgaaccaaatgtagaatgtcta +ttgattacccttttactattcgacttagagataggagatagaacctcagtgtactttttt +agccgaatgggaatctttgggaggtgaatggccataaggtcgtaaatccaaccctcttaa +agtcttccatattatatcgttgttcgtggaatcgataacagatttgttgacccatagtaa +atgtatactagtttatgttgtaagtgtagattgttttccgattgccgtccaaactttatg +tcgtaattgtagaccagtaaagttgaccaaggtaagtgcccagcgatcctgcgagatcga +tcgccaatttttccagtcactgtaagtgtaggtttagataaagccgtatgagttatatca +taagggcctcggaaagcagcttcgaaccaaagttcccttataatagtagtttaactataa +aagtatatactggtctgtcgccctttcacgatttgttttaccggtttatgaagcgttacg +tcattagagcggctccaatttaaggttaacggcttccatgtgtagttgtatacaaggata +acttaaagtatctgttcagcgagctagttaagttatcctcgatagaacacaactcagagg +tcccaagatcgggtttgcaacttgctaatttattctcaaggcaaattgggaattatcgat +acctgtataccataaggtcgctcgatgtgatgcttatgtcttctggtgatcctaccttag +ttagtgctgattaacggaacattaatgtttatcgttttgagatttagccaattctctgat +tctaactcaagatgccttatctgacgtgctatgcagcccctaagtattttacattgtaat +aggacacgctcctttaaaactcgccaaaaggtcgttgtggttctctactggttaactata +taatttacagctttgttgagctagttcctctttggtttaagtcctcaatattagttggtt +cgagcgataagttggctagttaccttagtcactatattagatccgaatgttatgcttcat +ctgaagaccgccaccctccaaaatttcttttaagactcacttattgcaaggtgtaggtga +attcggctcgtttctcaagtggtgtatctgtacacgagtttccatattttcatcaacagc +caccgcacacttatgtcactctaggtattaaaagtcgctctacaaggggacgcaattaag +aaacagacatgctagtcaaaaataaacatagcgaggcaccactaattcggccgcttatca +atgggatgctctgcgcgagacgcgccagagctcagtagttagttcggacatacatttact +tcagatgatcaattagttttctacaaatgcttactctaccccgaaaaaagtcaccagact +cttacgtctctttagtatccttccgtcttatataaggtcagtcccccgtttcggtaccct +ggaatttactaagaataatgaaacagcccccaaggacgtacgtttacaaatgatagacca +gatcgcctagcttattccgacgcatgttgcatagaattgaaccaacggaatgtgagagta +actagatgagccgaccacagcacccgtttgcgtcgcagaatacgcctgatagttcggcca +cgaaatcatatgtcctttgagtattaagtatttgtaatgatcaatcgagctcaagcaagc +ttacacttcctcggatattcagggaacttagtgcctttgaaagatacgttgatcaacgaa +aaattgataatggctcatatggaatgcctacctcatagtgctgaattaacacagcactgc +ggacctaacttttcgaggtttcaagttcacgtctcaaaacctaataggctggaatatgta +gggatcctcggtgaatttgtgattgggtttgttgtagtactgaccaagtgaatattcttt +ttttctaaaagcagatctgctgccgggcactacgaaggagatctctgtgtatcattattg +cttcttgacatgatgactcttaaatcactgtgggtgtgcaaaacgatagcacaacccaat +tcgatagtacatattgttgatacttcgcactaaaccgttcatatttaaaggttgtgctcc +ttccttcgttaaatactggtgacttggtcctatctactattagctagacctctggggaac +cacgcccccgtaaaacctgtgcaagagagggggtcatacatcttagacatcgcgcctcca +ccagggaagcattgggtgattgaccaggtgtgtaacaaatatgattattcttatactaat +attagcaaagatgcataatgatttgtattaaatgtataattgaattgataagggtctttt +agtcagtgatagagtagtataaggtagacattagaactcttaaccggacgcagatttttc +ggtcttagtaagccaattagtcgacaaaacaaggtaagagcggttactagtagtacctat +aatgcactgaatcttcggtcgaagtatagttctaatgctatgcagattgtgacggcgaca +aatgttcagacttatatcatgaaacaagctcttgtaagtattgacaaatgaaaagattga +atatttttaaatacaaaatgcgcctacttattaggggaattaaccagattgaaggccaat +cctcacatgtaatgagataatagacgataaatgaaattcttgtaatagttgaactgctac +gtgatgggtattatatatgattgagatcctccaattgccgacgtcttgtcttgatgccca +aaagattgtcaacgaggagctccctcgcgtacctgtcgtccgtatcataaacgacgcgac +atgtacagcactccgaagtataagcaataataatgcgggtaatccagactagatcttttc +ggactcaatgcggtttcacggtaaacatgattaataccggagagtagtcgagcttatcag +cgatgcaagcgaattcattgtgccaggagatacgttgcagataaaaccggcaacgtatgt +caacaagttttggcgatctcgttgtttgtattcgacgaggcgcgggaacttcaagaacta +tcgtatattcaagtccattaccttttagtttcagactggtggagctgactaaagttatat +catcattttgtacactggtttagttaacgataatttcagatttaacatgaccagacgata +atcgctgtatatccagttggaatgtggtttgccagaaaggttaacttataatcaagcctc +tcttcagtcttgattcgtcgtatcccatccattgcgctatacctcagtgtatttggagct +gtagttataccgtgtgctaagatcagtagacatgacgagagcaatattatctaccttaca +agcatcaacggacgtctagtcggaacaaaagactctaaaactcgaacttcaggttaatat +actatagttctgtattcagcagttattcttatattcgatattatcttgcctattggatgt +ctgactttagtatattaatcatagtatctgccatgtaaaggtgccagtactaaatctgtt +tcacagtgcgaattataaacggttacaaccattaaagacaacaagaccctatagctttat +ttgaattttgtcaatgcgcaacttggagctcgcgatacatcccaattagtctatagggtc +gggacgattctacggcatttctggttataatgacaacatggattgtggcccgagaatcgc +tctttcattaattaagcaatcattacagtcttataagcgctacttccgagtggtagcagg +taactcgatataaggtcgcatgagccgaatagcttaaaaaacaggccaccgaacattgat +agagaataccgaccacagcgcaacctttgattactttcattaaattgtacggctcactcg +acatcaagcttaagattgcgataatgtgaactcaaatggatcagtactgaagaaccgtaa +cccacttcgcagaaagcgtacccagagaagatacgctgttacaatatacagggtgaaatt +attgcctgttcttcgtaaccatttcgccaaacttggttagaaatgatagccattcatgat +agaaataagctgaatgataccagtatctttaactatgtagtcagggggaagataacgatg +gtccatgtatgtttctgatatgtgacagtattggccgcgtaatttgctaacgaagctact +taatgcctttgagcttcatatagatttctttaatcaaaatcggcaaaaagatagtatgag +ctataatatatgctagtagagaactctggaccatcatctatatgaatactgattcgagcg +tgcaattactttagcctgcgtactactgactctacaaaacactctgagataagtttgtag +tcagtaagtcgctctctataaaccttttggatgaccattgtacagccacttatagatccc +aataaatagcacaggagacagagtttttcaatgctcgatcatttgccgatagtattttcg +tctaacctcagggcacctattatttgatacctaacctaacggccctttcacaatggagaa +atatatgacatcgggacaaacacaaatggtgggtggccaggagatatgacatggtggcgt +ctctaagaaacacggactccctctaggcaaactcacgtaaccaattttaatgtcaaacaa +aacgctcgaaaagattttgccgtgtaatgacctggtacattgactggtcaggaatacatc +actgtagttgccgtagtgtcctgttggtgttccatcaagacacatcgtataacgcaattt +acgacggacatcagatcaagttatacagattatttaagtatcacgtgtgcattgggacat +aagggatctcacacatgccttggaacatttttgctttgtgccgctttttcgctgcactac +caatccttacttaccagtatattcaaaggtcgttaacagaatgagaaaggttagggctct +aagttatcgtcgattgggatagacgagacatttgcgagcgccctccacggatacgaatct +cccatatcaatgtgaactggatgctatgcagtttagttcttacgtctcctagtggtaaaa +atcaaagtagcactcgcatagcagttattcagaacctaatacacaaaaccgtcaaacatt +ttctaattctaggtatgggccgatcataggagctaaggtgaaactcataaatgttttgtt +agatctagcatcctaaaaagatgcatatactgagtagctggcgtgcattctctcaattgt +atcctttttaactgaactagtcggtcccatttcgtgactgagatctattaaccgataaga +ttaataacactcgcattcgtatcagctcagagtgaagtttttcaataatttgactgatat +attaacttctaaaataaccctttaagcctcggatccgtttcccaatcacatcaaaaattc +ttattccaactatctacggattaacaacgtgcatggggatcgtagtaagaacttgttccg +atcactttgagtatatcaagttgacggcccggttattattgaatagaaacattcacctgc +taaattaaataccgcacatcggatacccgatttcagagggccgtcttactaagggcaggc +tttgttcggtttaactgagatgttcattattttacagtatgcttcaactaatatgtaacg +aaggacagtggatctgtctccatagtagatcttcagtcgtgaatttcataccgctcctat +ttaagttcgcgttcgagttgttgatcatggcacgtgaaagcaacccctagtattctagac +gaaaattttttctagttcatctgataatttgccaattcaaaaacaaccgctggtttcccg +gcgcattctctaaaatggaagtcgaacctagagccattatttgtcggtaacccatgagtt +ccttcttttcagaagttaatacactgtggtcctatacagaggaaaaacagcggttatata +cgatcgtggcataacaacattggatcaagatagcaatttggctacctattctaattctca +ctagattcggtattccactacaatatcggcagattaggattggatgaataatcggtgttt +aagtccggttgcgtctccaatctcctaatttttattaatattgatcttggtgacctattg +taaataaaaacttcaagactttgaataacggtgaaaagatagaagactcatttgaaaatg +gatcatccacagatccaaacattagcaagacactaatccccaactagctattctgatcgc +gatcgtgctgcagtactcctgtcacaatagtctgttcatgatctaattctttttgggctt +tgttcgatggtgattcagaatctttatccggtcgcttccctgtagctactttgtggggat +attgcccggggattatagggttgagatcgtttcctaaaagtatttaaaccaagtagactt +caactaaactacatcagaacatcgtgaagacaccatacgcggtacctttatttaccgata +acatttcttcaagaaataccggtaagcagcataatgaccctaaacagctcggggtatcgt +cgtagttttaaattttatttaggttactgctcaaggaataaaaactaactatttaattta +taataatattacaaggctcacactgattagatttgtctataagacttcgcgatcccccat +taccggattgtcttaagaataaactagataaaccatgcattttctagataaggcctttag +tctaattagatacaaaaaacacgatagttgcatccttaatttattgtgtcaaacctggaa +ccttttaattacccgcaaatcactttatgtcgagactacctctgaaatttattatctacc +taccgcatgaggacttgaaccatcttgtaggagttatgtttattagctaagattcgttta +tcctgtagcggtccatgtatattcaacaagcaaaaagcactcagaattgtttttagttga +gtcaagactgatatataaataagtttccctagttttttcgtggtgggacgatattgaatt +gaatcttaaccgaagagtttcccactctgtcgcacaataatacacgccaatatttccagc +cctgcttatgccttaatcggttactcaatctcccattgaagttcattttgatctgcatag +aagtttcgggcccagccttttttctgccaccttcctccaagctctgtagacgcactctaa +gattgatgctcacatgtattaattctacattaacataaatatataagtcatgcatcttcg +agtaaaatatctggttctccaacatgtcctggcacgtatcgttataatgcccatacatgt +agtattaaaatgattgggttaactggatattaagatcatcgaaattgtaaagtcaaatta +acaatactgtctcaagaccgtgtattcctcgtgctcggaagggctattacgcttacttcc +gttttggtatcttaatatgactttcaaaaattaagttgcagtgagtcctacctgcgtgca +tcggttagcaagagtataaaagttgtttaaacgaactacttgctttacaataccggtcgt +atatatcgccgtgaatccagaagattgtcttctttggattatcaaccgagatcctgtgga +ccgatgttttgggaccttcacagaggactccaggtagagctcgcttttgcattaatctaa +gaattgtacctctctaaaagatctaaaacagtgaatgtgtatttcatggaaaaacacaga +gaaacgtaaattactttaggccgaaaggcacatgagttattatacatatacgagatggtg +gtatacatcgaattcggggcatacactatagttgcattgtatttagctgctttaaataat +atgatattaccttccttacataagacattaccggcataccctggttttcaacttgtgggg +ctttttgacgatcgcactctcatttgatccgagtagggcggtgacccctgcttttcaaat +acaaaaatttcgctatgaaggtaatagattacttttcgctgttatgatagaaacggtaaa +tttaaaattgaaacttctagaaaagtaaagtaacgagaaatgattttgtgaataatgcgg +tcatgattgcgcaagtaagaaaaaaaggcaaaaggatgcgcggaatagaaacttatcagt +cacgggtatcttgatttcattcttcttgtcaattgccgacataggatgaaatcagattcc +aatgcaatacacagtaacccccacccttgattgtaatgtcgatttgaagttgtacgcgtc +gacgaagtggatagtatacgggccttttgtacggtgcgatcaactatgaatctcggcgag +ttagatggtcgtacaatctcacacatagaggtcacttgcctgtaatgacgaattttcggc +taggtactcgaactttattagaagtaaaaatgtgggcaaaagaaggattccattttacaa +gacgattacaatgagttacatgtctctcaacgtagtctttccctagtagtctttgaacta +tttaggtactccagaaaattttagcaaagggtttctgtgtgaatccgccattcatgttta +tgatggaacaataagaataacgccctcgtatgttatcgacagtgaagtcagcagttcggc +caaaaacatattcaatttagtacagatccccagaagttaagctaagtgctctaaaatggc +ctaaacggttatcaaagtaggtctaattactatactaacgggtgcatcgtaataactgct +gtcgatgcaacactatatgatagtgtcgttttgctatatatgtacaatgtgacaaagaag +ccttagcgattcttgcaaacttaggacttcggattctcaatcttaaatgtccgaaaacgc +aaagattcaaaaatttaatctatgagcagatatgcctgatggtgactacgcgtatgttaa +ggctaaatgttgacaaccgcacacataatcgaactattgatagtcgggagcataaccagg +tgaacgtactttgttcacgacatttattgacatgttctaaatacgtctcaaaatcacggc +gcactagaaaacgcaatcaaatcattgtcctggtttaagggccgtaatgccggtagtgtc +aaacttcatgagaactttagctggcttttggccagtatttagggaccaagagcactagcc +ttaagctgaatattttgccatttatctactgttataactttaaaacttggtggcaccaga +cttgtcgatacacacgcatcaatctgtaacgtaaaaggtttactaagaacaagcgtagga +attgagtttatattatatttaaactaaaagatgatattagcttctgagggcgatagggct +ccaaatcataaagaggaatatattattacacgattagaaacccacaacatacctcgaatc +gcccaaaagtttgacgaaacttggcagtactccacatctcagtaatacagttgggagagt +ctcaaatgttgttttattactcaatgaaccaccctcataatttcactgctgttccattaa +atttgcaaacgatcatttgctttgaagaaacgtaaaatcgacaaaattacagataagtag +atgcataataaaaaaaactgctcgctataacacgatcatcgtgcattcttacttaggagc +atcacccgcacaataacgtaccttaaactacaacactattagaccgagtactgtaattca +cgaaagctcaagctcgcattgtaaagaacttgctctctcgtaaaatgtgataatagtttg +cggagaggattcaattattttccattgcacctactccactagattcgataaaagaaggtg +gtcctcccttaaaaagaaatgttaagtaacatcggaaccataagcaaagcatgtaagtga +accgtcatccttccctaagaaacataaaggtttttaataatgtcgactgtgaactataac +tgcatcctttcctgacctactccggttccttgttgttatttctgaacgagaccagtagat +aaacaatgtaaaccacagtgggtaccaatggtgcatgtgacgctaccgttgttttaagtg +cccgtacaaacataagaagtcataatcttacttgaaattaattttgccttttattttttt +tcaggctcgaaattaatgatttgttttttttgaccttctagttacgctaatatgcggtcg +cctgtggtttctattgagtcctataacgggatgggatctaatacgtttggttactagtaa +acaaggtataaatttgataccggagtatcaactgtataacatcaagctttatgactcata +cgcgaagtaatgacacaaggctttcaggagatcgcgagtacagagccactaaggggtgta +ttacgatagtgacaccaccgagcgcactcactccccaagtagatttatgatcctacgcta +agtattagatatataaccaaagaggttctagtcagtgcaactcttagaataataattagc +cggttttgcctttttaggcctaatgcaatattcagctagcccttatgtatctcgcgttcc +acagcaccactcatggcacgcgtttaaactaatcaaatataatctatgaatgttatgcca +gtacttgaataaatcaggttttttataagtccttgcatactctcgttatatactgttaga +gtcttaccccatagaaattctttcatctgcaaacttagaagaattctcagctacggggag +cataaagtccccaggatgttgacaaatacaacaaatgtggcttatacaaacactccatat +gaaaatcgaaccctcgtggtagttttagccgaaccttgtacggataaatccctccatttt +ccaatagcagatacctatcctactacctcgtggtattaaattaaagcttgaaatatagag +ctgcatagcttatccaattcccaagcacgagtctaccgtcgtaaccacgatttgatttac +agacgctagagcaaacccatctttaaacatataagtaaaaattaaagggtgagtgcgtac +gtgtttactagcaacttcgcttattaagacaattgtttataagccataattaaaaacata +tgttcaacaggttcattgatatttgtaattgcacaggtttttaataaggatctacgtaag +tataatgaacaaactttttaccagagttatattctgtactttgaaaatgctcctctaccg +ccttagagactttcaattagattttttgcagttaatctatgcgtaagtgaaccatgcaag +ggatgcgattcaaccgcctcgtgctaaccctatcgtctgtctcataactgtaggtctaat +ataattttcagttttcgaacacataaccctttgaaaatctgctatttaatgtctcacctg +catgcactatcttctatactgctcagaacggctatacgtcactatgctccaagtgacgat +ttaaacgaagcaaggaataataggtttattttagtgcaaaacaattaagtgcggactacg +tgctctttacaataagccttgtgattgggctataggttaagtcccatattaacgatctcc +aatgtacaaaatcgacaatcgctttgcattacccggttactagtcgaattacagatagct +gttagatactcactctaattttggacaacaatcccaatcttggggtcgtctatcgcctga +agctcgtaaatccttccatcttaaacgattacatattatagacttgttcggggtagagat +atcacagttgtgcaaacattgtaaatcgatactagtttatgttggtagtctagttgcttt +taccattccccgaaaaacttgatctactatttcgacaacagtaaacttgaactaggtaag +tgaaaacagagaatgcctcatagtgccactatttgtccactatatgtaagtgtagcttta +cataatccactatgactgagatcattacggcctaggaaagcagcgtagaaaaaaagggcc +cggatattacgactgtaactataaaactagttactggtagcgcgccatgtatagatttgt +tttaccggttgtggttgcgttaacgaatttcagccgcgaaaattgatccgttaaccagtc +catctcgacttctataaaacgataaagtaaagttgatgttcagcctccttcttatggttg +catcgagagtacactactcagtgggaaatagatcggggttcctacttcagattgtattat +ctaggcaattgccgattgtgccatacctggataaaataagctacctacatgtgatgctta +tctattatcgtcatactaccttagggtgtcctgttgaacgctacattaatctttagccgt +ttgagatgttccaatggataggagtctaacgcatgatgaagtttaggaaggcagagcatc +ccactaagtatgtgacagtgtatttcgaaacgagacgttataaatagaaaaaaggtcctt +ctggttctattctgctgaactattgaatggaaagattggttgacctacgtactatttgct +tgaagtcatcaatttgacggggtgagagacatatggtgcatactttacggactctatatt +ttagatcagaagcttagcagtcttctctacaccccctcacgacataattgcttttaagaa +tctatgtttgattcctctacgggaattcggatccgttcgcatgtgcggtttatctaaacc +aggggacatatgttcagctaaagcatacgaacactttgctaactagacgtatgtatagta +gctataaatcccgacgatatttacaaaaagaaatgagactcaaatatatacatagcgacc +ctacacttattcgcaccctgatctaggcgatcctagcacccacacccgaaagtgagcact +agtgtcttccgtattaaatttactgcagttgagattttagttgtctactaaggattactc +taacccgtaataaggatcaagactcggtactagctttactatcattccctatgtgttttc +ctaactcacaagggtacgtaccagcctatgtaattacaataatgataaagacacaaagga +agtaactttacaaatgagtctccagttacactagcttagtccctcccatcttgctttgaa +gtctaaatacgcaatctctgaggatatacagcagaagaacactcataacgttggagtcca +agaattagactcatagggcccccaacatttaatatgtactgtgagtttgaaggtgttcta +ttgttaattcctgctcttgatacatgacacgtactccgtgtttaaggcttcggactgact +ttctttcataagttgagcaacgaaaatttcagaatcgataagttggattcactaactaat +acggctgattgaaaactccactccggacctatatggtcgacctttatacgtaaccgatat +aaaacttataggctggtatatcgagccttcctagcgcaatttcggatggggtttcttcta +ctactcaacaacggaatagtctttgtttagtaaaccagagctcaggacgcccaatacgta +ggagagcgctgtggagcatgtgtcattatggactggagcactcttaaatcactctgcgtg +tgctaaacgatagatcataacatgtcctgagtaaattttcttgatacgtcgcaatatacc +gttattagttaaacgttctcatccgtcatgcgtgaaatacggctgtcgtgctcagatata +ctattagcgactcatctcgcctaacacgcacacgtataaactcggaatgactgccgctct +tacatattagaaatacagactacaccacggaagcattgggtcattctcaaccgctgtata +aaagatgattagtcttataataagattaccaaagaggcagaatcatgggtagtaaatcta +ttattcaagtgattaccgtcgtgtaggcagggagtgaggacgagatggtactcaggacaa +atattaaccggacgaagtggtttacgtcgtactttcactattagtagtaaatacaaggta +acaccggggaatagtactaaatataatgatatctatcttcgggagaacgagtcgtctatt +gctttgaacattctcaaggcgtaaaatgtgctgacttatagcatgatacaaccgattgtt +acttttgtctattcaaaagattgaatagttttttatacaaaagccgcatacttatgacgg +ctagtatacagtttcatcccctagcatcaatgctatggacagtattgaacttataggaaa +ttcttctaatagggcaaatccgtcgtgatgcctattttttttcagtcacatcctcaaatg +gcactagtattgtcgggatcccattaacaggctcaaccacgagctcacgcgaggacatgt +agtccgtatctttaacgaagcgacagcgacagaactcccatggataaccaattataaggc +ccgtaatcctctagacatcgtttaccaataaatccgctttctccgtaatcatgttgaata +ccccagagtagtccagatgataaccgatgaaacacaagtctttctcaatgcacttacggt +gaacttattaccgccaacgtagctcatcaaggttgcgacatctagttgtgtgtttgcgac +gagcccagcgaacttcatcaactttcgtatattcaacgccttgtaattttactttaagac +gcctggtgatgtagattcttagataatcagtttgttatcggctgtactttaccataattt +cacaggtttcaggtcaagaagattatagctgtatatacagttccatgctcggtgcacaga +aacgtgatcggataataatcaatcgcttatgtcgtctttaggcgtatccaatacatgccc +cgataccgcagtgtatttcgacatgtaggtataccgtcgcatttgagctcgagtcaggac +gtcagctagattagattccttaatagaatataccgacctctagtccgaactaaactatag +ataacgccaacttcaggttaattgtctagtcgtctgtttgcagatgggattcttagatga +gtgagtatcggccatattggttcgagcactttagtttttgatgcataggatatgcaatgt +atagctgaaagtactttatctgtttcaaactcacattgattaaaccggtaaacctttaaa +gactacaagaaaatattcagtgagggcaattttgtcaatcacaatcttccagctagagat +acttcacaatttgtcttgaggctacgcaacattagacggattttcgcgttttattgaaat +aatcgaggggcccaagagtatccatagttcattttgtaagatttctttacaggcttatta +cagcttcttcagactcctacatgcttacgagttatatgctagcatgtgaacaatagatta +atatacaggaaaacgtacattgagagagatgaccctacacagcgcaaccgttgagtactt +tcattaaagggtaacgctctcgagacagcatccttaagatggccttattgtcaaatcatt +tgcagaagtacgcaagatccctaaccaacgtagaagaatccctacaaacacatgagacgc +ggtgaaaatagacagggtgttagtattcaatcttcggagtatcaatttcgccaatcttgg +tgagaaagcataccctttcttcagagaaagaagatcaatcataacactatctttaacgag +gtacgcacgcgcatcattacctgcctccatggatctttaggatagcggaaagtattggca +gcgtattgtgatttcgttcctactttatcaatttcacattcatatacatgtcttttatca +aaatcgccaataagataggatgagctatattagatgctagtagagttcgcgccaacatca +tcgataggaatactcaggacagcgtgataggacttttcaatccctaatactctctataat +tataactctctcttaagtttggaggcagtaacgcgctctatataatcagtttgctgcacc +attcttcagcctctgatacatacaaataaattccacagcagtaagagggtttaattgaga +catcttgggaacttaggattttactctaacatcaccgaaacgattattggataccgtacc +taaacgaactttctcaaggcagtaatataggacatccgcaataacacaaatgctgcctcc +ccaggagttatgtcttcctggaggctatatcttacacccactcactataggcaaactaaa +gtttaaatgttgattgtctaaaaaaaagatagataagagttggccggcgtagcacatgcg +aaagtgaatcgtaagctataattctctggacttgaagttctgtcctgttcctctgcaaga +aacaaacttcctttaaagctatttacgacgcacatctcagcaagttataaacatgttgga +agtttctagtcggaattcccaaagaacggatctatctaatgcattcctacatttttcctg +tctgccgatggtgccatcctattcaaagaatttcttaaaagtagattaaatgggactttt +aacaatgagtaaccttacgcctctaagggttcctcgagtgccatacaccagtcaggtccg +agccacatacacggagaacattctaacatagcattctcaactcgatcatttgcaggttac +ttctttcctatcctagtgctaaaaatcatacttgcaatcccatagcacggattaagaacc +taagaaacaattcagtaaaacatgttcgaattcttggtatgggaacatcattgcagctat +ggtctaacgcattaatgtttgggtacatcttccatcatataaacaggaagagtctgacga +cagggagtgcttgcgatcatgtctatcattgtgaaatcaaattgtagctcacatgtcgtc +tatgagagcgtgtatccgataagatttagaaaaatagaagtcgtataagatctcactgaa +cttttgaatgaatgtgaagcatatatgatctgctttaataaaactttatccataggatac +gtttccaaatcaattcaataattattagtcaaaatagataaggatgaacaacctgaaggc +cgatcggacgtagaaagtggtcccatcactttgagttgatattgttgaaccacacgttat +tatggttttcaaacagtctcaggatattgtatatacagataatccgataccagttgtctg +acgcccctcttacgtaccccaccctttgtgacgtttaaagcagttgttcagtattttaaa +ctaggcggcaactaatttggaaagaagcacagtggatatgtctaaattcttgttattcag +gcctgaatttaatacaccgcatagttaacttcgcggtagagttgttcatcatgcctcctc +taagctaccacttctatgatacaccaatagttgttctacggaatctgataattggccaag +tcataaacttccgctgcgttcaacccccttgctcgaatatccaactcgaaaagacagcct +tttggtgtccggaacaaatcagttacttcttttctgatgttaattctctgtggtcagata +cagaccaaaaactccgcggatttaccatcctccaagaacaaatttgcatcaacatagcat +tttggctacatattctaagtctcaatagtttaggttttcaactacattatcccaacatta +ggattggaggaataatagctgggtaagtccccttgcgtctacaatcgactattttttatg +aatatgcttctgccgcacctatggttattaaaaaagtcatgactttgaagaaccctgaaa +agatagatgaatcaggtgtaatggcagcagccaaagagcatataattagcaacactctaa +gaacattatagatatgatgatagcgatcgtcatgatgttatccggtcacaatagtagctt +catcagctaattcgttttgccagtggtgacttgcgctggaagaatcgttatacggtccct +tccctcttgatacggtgggggcttattcaaccgcgtggattgggttgtcatacttgcatt +aaacgatgtaaaccatctagtagtcaactatactaaatcacaaaatagtgatcaatacat +acccgcttcatggttttaaccatttaattgattaaagatattccgctaagaaccattatc +tacctaaactgatcgccgtatcctagtagtttgaaatttgatgtaccgtaatgatcaacg +aagtaaaacgttatattgtatgtagaataataggtcttggagctaaatgatgtgattggt +agtgaagacttacccttacaactttaccggtttctcggaagaatatactagagaatcaat +gcatgggctacataagcactttagtctaatgagataaaaaatacacgagtcttccatcat +gaattttttgtcgaaaaactcgaacctggtaatttaaaccatatatctttatgtcgtcaa +taactctcatatgttttatataacttcccaatcacgacttgtaactgcttgttcgactga +gctgtttgagctatgaggccgggatccggttgagctacatctatttgctacaagaaaaat +gaaagcacatttgttgggagttctggctacactcatagagaaataagtggcccgagtggg +tgcggcctgcctccatattcaagtgtatcttaaaccaagtggttccaacgctcgcgctaa +agaattaaagcctttatttcctccacggagtagcccgtaatccggttcgaaagagaccat +tgaagttaattttcatatccagtgaagtttaggcacaagcatgtgttctgccacatgcct +caaagcgctcttcaaccaagatatgattcatcctaacttcgatgaatgcgtctgtaacat +aaatatagaaggaatgattcggcgagttaattttcgccttctccaacatggcatccctac +gttcgttataaggaccatacatgtaggttttaaaggtttgcggttaatcgatatttacat +catagaaattctatagtcaaatttacaagactctagatactcactcgttgcagccggcta +ggaagcgctttgtaccttacttcccttttcgttgcgtaatatgaatttcatatagtaagt +tcaaggcactcatacctccgtgaagagggtagatagactattaaagttgtttaatagtac +gtattgatggaaatgacccgtaggagatttaccactcaatccacaagattcgctgctgtg +cattatcaaaacagtgcatgtcgaaacatgggttgggtccttcaaacacgaatccaggta +gagatacctttgcaattttt diff --git a/multithread/regex-dna/regexdna-inputYYY.txt b/multithread/regex-dna/regexdna-inputYYY.txt new file mode 100644 --- /dev/null +++ b/multithread/regex-dna/regexdna-inputYYY.txt @@ -0,0 +1,110187 @@ +>ONE Homo sapiens alu +GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA +TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT +AAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG +GCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG +CCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT +GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA +GGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA +TTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG +AATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA +GCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGT +AATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACC +AGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTG +GTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACC +CGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAG +AGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTT +TGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACA +TGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCT +GTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGG +TTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGT +CTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGG +CGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCG +TCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTA +CTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCG +AGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCG +GGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACC +TGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAA +TACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGA +GGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACT +GCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTC +ACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGT +TCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGC +CGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCG +CTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTG +GGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCC +CAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCT +GGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGC +GCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGA +GGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGA +GACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGA +GGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTG +AAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT +CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCA +GTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAA +AAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGC +GGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCT +ACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGG +GAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATC +GCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGC +GGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGG +TCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAA +AAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAG +GAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACT +CCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCC +TGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAG +ACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGC +GTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGA +ACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGA +CAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCA +CTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCA +ACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCG +CCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGG +AGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTC +CGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCG +AGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACC +CCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAG +CTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAG +CCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGG +CCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATC +ACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAA +AAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGC +TGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCC +ACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGG +CTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGG +AGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATT +AGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAA +TCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGC +CTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAA +TCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAG +CCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGT +GGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCG +GGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAG +CGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG +GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATG +GTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGT +AATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTT +GCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCT +CAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCG +GGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTC +TCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACT +CGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAG +ATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGG +CGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTG +AGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATA +CAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGG +CAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGC +ACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCAC +GCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTC +GAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCG +GGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCT +TGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGG +CGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCA +GCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGG +CCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGC +GCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGG +CGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGA +CTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGG +CCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAA +ACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCC +CAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGT +GAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAA +AGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGG +ATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTAC +TAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGA +GGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGC +GCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGG +TGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTC +AGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAA +ATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGA +GAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC +AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTG +TAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGAC +CAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGT +GGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC +CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACA +GAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACT +TTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAAC +ATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCC +TGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAG +GTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCG +TCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAG +GCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCC +GTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCT +ACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCC +GAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCC +GGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCAC +CTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAA +ATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTG +AGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCAC +TGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCT +CACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAG +TTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAG +CCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATC +GCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCT +GGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATC +CCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCC +TGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGG +CGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG +AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCG +AGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGG +AGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGT +GAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAA +TCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGC +AGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCA +AAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGG +CGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTC +TACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCG +GGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGAT +CGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCG +CGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAG +GTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACA +AAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCA +GGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCAC +TCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGC +CTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA +GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGG +CGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTG +AACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCG +ACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGC +ACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCC +AACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGC +GCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCG +GAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACT +CCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCC +GAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAAC +CCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA +GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGA +GCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAG +GCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGAT +CACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTA +AAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGG +CTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGC +CACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTG +GCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAG +GAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAAT +TAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGA +ATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAG +CCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTA +ATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCA +GCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGG +TGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCC +GGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGA +GCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTT +GGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACAT +GGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTG +TAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGT +TGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTC +TCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGC +GGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGT +CTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTAC +TCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGA +GATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGG +GCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCT +GAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT +ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAG +GCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG +CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCA +CGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTT +CGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCC From pypy.commits at gmail.com Thu Jul 11 04:46:42 2019 From: pypy.commits at gmail.com (Raemi) Date: Thu, 11 Jul 2019 01:46:42 -0700 (PDT) Subject: [pypy-commit] benchmarks multithread-runner: add benchmark from benchmarksgame Message-ID: <5d26f772.1c69fb81.be40b.3740@mx.google.com> Author: Remi Meier Branch: multithread-runner Changeset: r384:8da3fde3e933 Date: 2016-07-22 09:59 +0200 http://bitbucket.org/pypy/benchmarks/changeset/8da3fde3e933/ Log: add benchmark from benchmarksgame diff too long, truncating to 2000 out of 35126 lines diff --git a/multithread/k-nucleotide/k-nucleotide.py b/multithread/k-nucleotide/k-nucleotide.py new file mode 100644 --- /dev/null +++ b/multithread/k-nucleotide/k-nucleotide.py @@ -0,0 +1,115 @@ +# -*- coding: utf-8 -*- +import gc +import sys +import time +from common.abstract_threading import ( + atomic, Future, set_thread_pool, ThreadPool, + hint_commit_soon, turn_jitting_off) + + +# Revised BSD license +# This is a specific instance of the Open Source Initiative (OSI) BSD license template. +# Copyright (c) 2004-2008 Brent Fulgham, 2005-2016 Isaac Gouy +# All rights reserved. + +# The Computer Language Benchmarks Game +# http://benchmarksgame.alioth.debian.org/ +# +# submitted by Ian Osgood +# modified by Sokolov Yura +# modified by bearophile +# modified by jacek2v: few changes in algorytm, added multiprocessing, used str.count (nucleo newer overlapping) + +from collections import defaultdict + +def gen_freq(seq, frame): + frequences = defaultdict(int) + ns = len(seq) + 1 - frame + for ii in range(ns): + frequences[seq[ii:ii + frame]] += 1 + return ns, frequences + +def sort_seq(seq, length): + n, frequences = gen_freq(seq, length) + #l = sorted(frequences.items(), reverse=True, key=lambda (seq,freq): (freq,seq)) + l = sorted(list(frequences.items()), reverse=True, key=lambda seq_freq: (seq_freq[1],seq_freq[0])) + return [(st, 100.0*fr/n) for st, fr in l] + +def find_seq(seq, nucleo): + count = seq.count(nucleo) + return nucleo, count + +def load(): + with open('knucleotide-inputYYY.txt', 'r') as infile: + for line in infile: + if line[0:3] == ">TH": + break + seq = [] + for line in infile: + if line[0] in ">;": + break + seq.append( line[:-1] ) + return seq + +def main_b(): + # ORIGINAL version looked only for these: + # nucleos = "GGT GGTA GGTATT GGTATTTTAATT GGTATTTTAATTTATAGT" + nucleos = "GGT AGT GGTA AGGA GGTATT TTGAT GGTATTTTAATT GGATTATGAAAT GGTATTTTAATTTATAGT" + sequence = "".join(load()).upper() + plres = [] + + t = time.time() + # ORIGINAL version only looked for 1, 2 sequences + for nl in 1, 2, 3, 4, 5, 6, 7, 8: + plres.append(Future(sort_seq, sequence, nl)) + + for se in nucleos.split(): + plres.append(Future(find_seq, sequence, se)) + + [p() for p in plres] + t = time.time() - t + + # for ii in 0, 1, 2, 3, 4, 5, 6, 7: + # print('\n'.join("%s %.3f" % (st, fr) for st,fr in plres[ii]())) + # print('') + # for ii in range(8, len(nucleos.split()) + 8): + # print("%d\t%s" % (plres[ii]()[1], plres[ii]()[0])) + return t + +def run(threads=2): + threads = int(threads) + + set_thread_pool(ThreadPool(threads)) + + t = main_b() + + # shutdown current pool + set_thread_pool(None) + return t + +def main(argv): + # warmiters threads args... + warmiters = int(argv[0]) + threads = int(argv[1]) + + print "params (iters, threads):", warmiters, threads + + print "do warmup:" + for i in range(4): + t = run(threads) + print "iter", i, "time:", t + + print "turn off jitting" + turn_jitting_off() + print "do", warmiters, "real iters:" + times = [] + for i in range(warmiters): + gc.collect() + + t = run(threads) + times.append(t) + print "warmiters:", times + +if __name__ == "__main__": + import sys + main(sys.argv[1:]) diff --git a/multithread/k-nucleotide/knucleotide-input10000.txt b/multithread/k-nucleotide/knucleotide-input10000.txt new file mode 100644 --- /dev/null +++ b/multithread/k-nucleotide/knucleotide-input10000.txt @@ -0,0 +1,1671 @@ +>ONE Homo sapiens alu +GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA +TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT +AAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG +GCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG +CCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT +GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA +GGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA +TTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG +AATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA +GCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGT +AATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACC +AGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTG +GTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACC +CGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAG +AGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTT +TGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACA +TGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCT +GTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGG +TTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGT +CTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGG +CGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCG +TCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTA +CTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCG +AGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCG +GGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACC +TGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAA +TACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGA +GGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACT +GCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTC +ACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGT +TCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGC +CGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCG +CTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTG +GGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCC +CAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCT +GGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGC +GCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGA +GGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGA +GACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGA +GGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTG +AAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT +CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCA +GTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAA +AAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGC +GGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCT +ACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGG +GAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATC +GCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGC +GGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGG +TCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAA +AAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAG +GAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACT +CCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCC +TGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAG +ACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGC +GTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGA +ACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGA +CAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCA +CTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCA +ACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCG +CCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGG +AGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTC +CGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCG +AGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACC +CCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAG +CTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAG +CCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGG +CCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATC +ACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAA +AAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGC +TGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCC +ACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGG +CTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGG +AGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATT +AGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAA +TCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGC +CTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAA +TCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAG +CCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGT +GGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCG +GGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAG +CGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG +GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATG +GTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGT +AATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTT +GCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCT +CAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCG +GGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTC +TCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACT +CGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAG +ATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGG +CGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTG +AGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATA +CAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGG +CAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGC +ACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCAC +GCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTC +GAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCG +GGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCT +TGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGG +CGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCA +GCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGG +CCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGC +GCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGG +CGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGA +CTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGG +CCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAA +ACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCC +CAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGT +GAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAA +AGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGG +ATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTAC +TAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGA +GGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGC +GCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGG +TGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTC +AGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAA +ATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGA +GAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC +AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTG +TAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGAC +CAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGT +GGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC +CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACA +GAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACT +TTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAAC +ATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCC +TGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAG +GTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCG +TCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAG +GCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCC +GTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCT +ACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCC +GAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCC +GGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCAC +CTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAA +ATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTG +AGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCAC +TGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCT +CACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAG +TTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAG +CCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATC +GCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCT +GGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATC +CCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCC +TGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGG +CGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG +AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCG +AGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGG +AGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGT +GAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAA +TCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGC +AGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCA +AAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGG +CGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTC +TACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCG +GGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGAT +CGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCG +CGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAG +GTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACA +AAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCA +GGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCAC +TCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGC +CTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA +GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGG +CGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTG +AACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCG +ACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGC +ACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCC +AACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGC +GCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCG +GAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACT +CCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCC +GAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAAC +CCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA +GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGA +GCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAG +GCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGAT +CACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTA +AAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGG +CTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGC +CACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTG +GCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAG +GAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAAT +TAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGA +ATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAG +CCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTA +ATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCA +GCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGG +TGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCC +GGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGA +GCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTT +GGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACAT +GGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTG +TAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGT +TGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTC +TCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGC +GGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGT +CTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTAC +TCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGA +GATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGG +GCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCT +GAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT +ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAG +GCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG +CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCA +CGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTT +CGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCC +GGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGC +TTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGG +GCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCC +AGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTG +GCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCG +CGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAG +GCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAG +ACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAG +GCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGA +AACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATC +CCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAG +TGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAA +AAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCG +GATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTA +CTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGG +AGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCG +CGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCG +GTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGT +CAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAA +AATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGG +AGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTC +CAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCT +GTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA +CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCG +TGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAA +CCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGAC +AGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCAC +TTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAA +CATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGC +CTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGA +GGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCC +GTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGA +GGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCC +CGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGC +TACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGC +CGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGC +CGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCA +CCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAA +AATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCT +GAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCA +CTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGC +TCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGA +GTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTA +GCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAAT +CGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCC +TGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAAT +CCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGC +CTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTG +GCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGG +GAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGC +GAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG +GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGG +TGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTA +ATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTG +CAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTC +AAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGG +GCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCT +CTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTC +GGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGA +TCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGC +GCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGA +GGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATAC +AAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGC +AGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCA +CTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACG +CCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCG +AGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGG +GCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTT +GAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGC +GACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAG +CACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGC +CAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCG +CGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGC +GGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGAC +TCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGC +CGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAA +CCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCC +AGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTG +AGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA +GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA +TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT +AAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG +GCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG +CCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT +GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA +GGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA +TTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG +AATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA +GCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGT +AATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACC +AGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTG +GTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACC +CGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAG +AGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTT +TGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACA +TGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCT +GTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGG +TTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGT +CTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGG +CGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCG +TCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTA +CTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCG +AGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCG +GGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACC +TGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAA +TACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGA +GGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACT +GCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTC +ACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGT +TCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGC +CGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCG +CTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTG +GGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCC +CAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCT +GGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGC +GCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGA +GGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGA +GACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGA +GGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTG +AAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT +CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCA +GTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAA +AAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGC +GGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCT +ACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGG +GAGGCTGAGGCAGGAGAATC +>TWO IUB ambiguity codes +cttBtatcatatgctaKggNcataaaSatgtaaaDcDRtBggDtctttataattcBgtcg +tactDtDagcctatttSVHtHttKtgtHMaSattgWaHKHttttagacatWatgtRgaaa +NtactMcSMtYtcMgRtacttctWBacgaaatatagScDtttgaagacacatagtVgYgt +cattHWtMMWcStgttaggKtSgaYaaccWStcgBttgcgaMttBYatcWtgacaYcaga +gtaBDtRacttttcWatMttDBcatWtatcttactaBgaYtcttgttttttttYaaScYa +HgtgttNtSatcMtcVaaaStccRcctDaataataStcYtRDSaMtDttgttSagtRRca +tttHatSttMtWgtcgtatSSagactYaaattcaMtWatttaSgYttaRgKaRtccactt +tattRggaMcDaWaWagttttgacatgttctacaaaRaatataataaMttcgDacgaSSt +acaStYRctVaNMtMgtaggcKatcttttattaaaaagVWaHKYagtttttatttaacct +tacgtVtcVaattVMBcttaMtttaStgacttagattWWacVtgWYagWVRctDattBYt +gtttaagaagattattgacVatMaacattVctgtBSgaVtgWWggaKHaatKWcBScSWa +accRVacacaaactaccScattRatatKVtactatatttHttaagtttSKtRtacaaagt +RDttcaaaaWgcacatWaDgtDKacgaacaattacaRNWaatHtttStgttattaaMtgt +tgDcgtMgcatBtgcttcgcgaDWgagctgcgaggggVtaaScNatttacttaatgacag +cccccacatYScaMgtaggtYaNgttctgaMaacNaMRaacaaacaKctacatagYWctg +ttWaaataaaataRattagHacacaagcgKatacBttRttaagtatttccgatctHSaat +actcNttMaagtattMtgRtgaMgcataatHcMtaBSaRattagttgatHtMttaaKagg +YtaaBataSaVatactWtataVWgKgttaaaacagtgcgRatatacatVtHRtVYataSa +KtWaStVcNKHKttactatccctcatgWHatWaRcttactaggatctataDtDHBttata +aaaHgtacVtagaYttYaKcctattcttcttaataNDaaggaaaDYgcggctaaWSctBa +aNtgctggMBaKctaMVKagBaactaWaDaMaccYVtNtaHtVWtKgRtcaaNtYaNacg +gtttNattgVtttctgtBaWgtaattcaagtcaVWtactNggattctttaYtaaagccgc +tcttagHVggaYtgtNcDaVagctctctKgacgtatagYcctRYHDtgBattDaaDgccK +tcHaaStttMcctagtattgcRgWBaVatHaaaataYtgtttagMDMRtaataaggatMt +ttctWgtNtgtgaaaaMaatatRtttMtDgHHtgtcattttcWattRSHcVagaagtacg +ggtaKVattKYagactNaatgtttgKMMgYNtcccgSKttctaStatatNVataYHgtNa +BKRgNacaactgatttcctttaNcgatttctctataScaHtataRagtcRVttacDSDtt +aRtSatacHgtSKacYagttMHtWataggatgactNtatSaNctataVtttRNKtgRacc +tttYtatgttactttttcctttaaacatacaHactMacacggtWataMtBVacRaSaatc +cgtaBVttccagccBcttaRKtgtgcctttttRtgtcagcRttKtaaacKtaaatctcac +aattgcaNtSBaaccgggttattaaBcKatDagttactcttcattVtttHaaggctKKga +tacatcBggScagtVcacattttgaHaDSgHatRMaHWggtatatRgccDttcgtatcga +aacaHtaagttaRatgaVacttagattVKtaaYttaaatcaNatccRttRRaMScNaaaD +gttVHWgtcHaaHgacVaWtgttScactaagSgttatcttagggDtaccagWattWtRtg +ttHWHacgattBtgVcaYatcggttgagKcWtKKcaVtgaYgWctgYggVctgtHgaNcV +taBtWaaYatcDRaaRtSctgaHaYRttagatMatgcatttNattaDttaattgttctaa +ccctcccctagaWBtttHtBccttagaVaatMcBHagaVcWcagBVttcBtaYMccagat +gaaaaHctctaacgttagNWRtcggattNatcRaNHttcagtKttttgWatWttcSaNgg +gaWtactKKMaacatKatacNattgctWtatctaVgagctatgtRaHtYcWcttagccaa +tYttWttaWSSttaHcaaaaagVacVgtaVaRMgattaVcDactttcHHggHRtgNcctt +tYatcatKgctcctctatVcaaaaKaaaagtatatctgMtWtaaaacaStttMtcgactt +taSatcgDataaactaaacaagtaaVctaggaSccaatMVtaaSKNVattttgHccatca +cBVctgcaVatVttRtactgtVcaattHgtaaattaaattttYtatattaaRSgYtgBag +aHSBDgtagcacRHtYcBgtcacttacactaYcgctWtattgSHtSatcataaatataHt +cgtYaaMNgBaatttaRgaMaatatttBtttaaaHHKaatctgatWatYaacttMctctt +ttVctagctDaaagtaVaKaKRtaacBgtatccaaccactHHaagaagaaggaNaaatBW +attccgStaMSaMatBttgcatgRSacgttVVtaaDMtcSgVatWcaSatcttttVatag +ttactttacgatcaccNtaDVgSRcgVcgtgaacgaNtaNatatagtHtMgtHcMtagaa +attBgtataRaaaacaYKgtRccYtatgaagtaataKgtaaMttgaaRVatgcagaKStc +tHNaaatctBBtcttaYaBWHgtVtgacagcaRcataWctcaBcYacYgatDgtDHccta +aagacYRcaggattHaYgtKtaatgcVcaataMYacccatatcacgWDBtgaatcBaata +cKcttRaRtgatgaBDacggtaattaaYtataStgVHDtDctgactcaaatKtacaatgc +gYatBtRaDatHaactgtttatatDttttaaaKVccYcaaccNcBcgHaaVcattHctcg +attaaatBtatgcaaaaatYMctSactHatacgaWacattacMBgHttcgaatVaaaaca +BatatVtctgaaaaWtctRacgBMaatSgRgtgtcgactatcRtattaScctaStagKga +DcWgtYtDDWKRgRtHatRtggtcgaHgggcgtattaMgtcagccaBggWVcWctVaaat +tcgNaatcKWagcNaHtgaaaSaaagctcYctttRVtaaaatNtataaccKtaRgtttaM +tgtKaBtRtNaggaSattHatatWactcagtgtactaKctatttgRYYatKatgtccgtR +tttttatttaatatVgKtttgtatgtNtataRatWYNgtRtHggtaaKaYtKSDcatcKg +taaYatcSRctaVtSMWtVtRWHatttagataDtVggacagVcgKWagBgatBtaaagNc +aRtagcataBggactaacacRctKgttaatcctHgDgttKHHagttgttaatgHBtatHc +DaagtVaBaRccctVgtgDtacRHSctaagagcggWYaBtSaKtHBtaaactYacgNKBa +VYgtaacttagtVttcttaatgtBtatMtMtttaattaatBWccatRtttcatagVgMMt +agctStKctaMactacDNYgKYHgaWcgaHgagattacVgtttgtRaSttaWaVgataat +gtgtYtaStattattMtNgWtgttKaccaatagNYttattcgtatHcWtctaaaNVYKKt +tWtggcDtcgaagtNcagatacgcattaagaccWctgcagcttggNSgaNcHggatgtVt +catNtRaaBNcHVagagaaBtaaSggDaatWaatRccaVgggStctDaacataKttKatt +tggacYtattcSatcttagcaatgaVBMcttDattctYaaRgatgcattttNgVHtKcYR +aatRKctgtaaacRatVSagctgtWacBtKVatctgttttKcgtctaaDcaagtatcSat +aWVgcKKataWaYttcccSaatgaaaacccWgcRctWatNcWtBRttYaattataaNgac +acaatagtttVNtataNaYtaatRaVWKtBatKagtaatataDaNaaaaataMtaagaaS +tccBcaatNgaataWtHaNactgtcDtRcYaaVaaaaaDgtttRatctatgHtgttKtga +aNSgatactttcgagWaaatctKaaDaRttgtggKKagcDgataaattgSaacWaVtaNM +acKtcaDaaatttctRaaVcagNacaScRBatatctRatcctaNatWgRtcDcSaWSgtt +RtKaRtMtKaatgttBHcYaaBtgatSgaSWaScMgatNtctcctatttctYtatMatMt +RRtSaattaMtagaaaaStcgVgRttSVaScagtgDtttatcatcatacRcatatDctta +tcatVRtttataaHtattcYtcaaaatactttgVctagtaaYttagatagtSYacKaaac +gaaKtaaatagataatSatatgaaatSgKtaatVtttatcctgKHaatHattagaaccgt +YaaHactRcggSBNgtgctaaBagBttgtRttaaattYtVRaaaattgtaatVatttctc +ttcatgBcVgtgKgaHaaatattYatagWacNctgaaMcgaattStagWaSgtaaKagtt +ttaagaDgatKcctgtaHtcatggKttVDatcaaggtYcgccagNgtgcVttttagagat +gctaccacggggtNttttaSHaNtatNcctcatSaaVgtactgBHtagcaYggYVKNgta +KBcRttgaWatgaatVtagtcgattYgatgtaatttacDacSctgctaaaStttaWMagD +aaatcaVYctccgggcgaVtaaWtStaKMgDtttcaaMtVgBaatccagNaaatcYRMBg +gttWtaaScKttMWtYataRaDBMaDataatHBcacDaaKDactaMgagttDattaHatH +taYatDtattDcRNStgaatattSDttggtattaaNSYacttcDMgYgBatWtaMagact +VWttctttgYMaYaacRgHWaattgRtaagcattctMKVStatactacHVtatgatcBtV +NataaBttYtSttacKgggWgYDtgaVtYgatDaacattYgatggtRDaVDttNactaSa +MtgNttaacaaSaBStcDctaccacagacgcaHatMataWKYtaYattMcaMtgSttDag +cHacgatcaHttYaKHggagttccgatYcaatgatRaVRcaagatcagtatggScctata +ttaNtagcgacgtgKaaWaactSgagtMYtcttccaKtStaacggMtaagNttattatcg +tctaRcactctctDtaacWYtgaYaSaagaWtNtatttRacatgNaatgttattgWDDcN +aHcctgaaHacSgaataaRaataMHttatMtgaSDSKatatHHaNtacagtccaYatWtc +actaactatKDacSaStcggataHgYatagKtaatKagStaNgtatactatggRHacttg +tattatgtDVagDVaRctacMYattDgtttYgtctatggtKaRSttRccRtaaccttaga +gRatagSaaMaacgcaNtatgaaatcaRaagataatagatactcHaaYKBctccaagaRa +BaStNagataggcgaatgaMtagaatgtcaKttaaatgtaWcaBttaatRcggtgNcaca +aKtttScRtWtgcatagtttWYaagBttDKgcctttatMggNttattBtctagVtacata +aaYttacacaaRttcYtWttgHcaYYtaMgBaBatctNgcDtNttacgacDcgataaSat +YaSttWtcctatKaatgcagHaVaacgctgcatDtgttaSataaaaYSNttatagtaNYt +aDaaaNtggggacttaBggcHgcgtNtaaMcctggtVtaKcgNacNtatVaSWctWtgaW +cggNaBagctctgaYataMgaagatBSttctatacttgtgtKtaattttRagtDtacata +tatatgatNHVgBMtKtaKaNttDHaagatactHaccHtcatttaaagttVaMcNgHata +tKtaNtgYMccttatcaaNagctggacStttcNtggcaVtattactHaSttatgNMVatt +MMDtMactattattgWMSgtHBttStStgatatRaDaagattttctatMtaaaaaggtac +taaVttaSacNaatactgMttgacHaHRttgMacaaaatagttaatatWKRgacDgaRta +tatttattatcYttaWtgtBRtWatgHaaattHataagtVaDtWaVaWtgStcgtMSgaS +RgMKtaaataVacataatgtaSaatttagtcgaaHtaKaatgcacatcggRaggSKctDc +agtcSttcccStYtccRtctctYtcaaKcgagtaMttttcRaYDttgttatctaatcata +NctctgctatcaMatactataggDaHaaSttMtaDtcNatataattctMcStaaBYtaNa +gatgtaatHagagSttgWHVcttatKaYgDctcttggtgttMcRaVgSgggtagacaata +aDtaattSaDaNaHaBctattgNtaccaaRgaVtKNtaaYggHtaKKgHcatctWtctDt +ttctttggSDtNtaStagttataaacaattgcaBaBWggHgcaaaBtYgctaatgaaatW +cDcttHtcMtWWattBHatcatcaaatctKMagtDNatttWaBtHaaaNgMttaaStagt +tctctaatDtcRVaYttgttMtRtgtcaSaaYVgSWDRtaatagctcagDgcWWaaaBaa +RaBctgVgggNgDWStNaNBKcBctaaKtttDcttBaaggBttgaccatgaaaNgttttt +tttatctatgttataccaaDRaaSagtaVtDtcaWatBtacattaWacttaSgtattggD +gKaaatScaattacgWcagKHaaccaYcRcaRttaDttRtttHgaHVggcttBaRgtccc +tDatKaVtKtcRgYtaKttacgtatBtStaagcaattaagaRgBagSaattccSWYttta +ttVaataNctgHgttaaNBgcVYgtRtcccagWNaaaacaDNaBcaaaaRVtcWMgBagM +tttattacgDacttBtactatcattggaaatVccggttRttcatagttVYcatYaSHaHc +ttaaagcNWaHataaaRWtctVtRYtagHtaaaYMataHYtNBctNtKaatattStgaMc +BtRgctaKtgcScSttDgYatcVtggaaKtaagatWccHccgKYctaNNctacaWctttt +gcRtgtVcgaKttcMRHgctaHtVaataaDtatgKDcttatBtDttggNtacttttMtga +acRattaaNagaactcaaaBBVtcDtcgaStaDctgaaaSgttMaDtcgttcaccaaaag +gWtcKcgSMtcDtatgtttStaaBtatagDcatYatWtaaaBacaKgcaDatgRggaaYc +taRtccagattDaWtttggacBaVcHtHtaacDacYgtaatataMagaatgHMatcttat +acgtatttttatattacHactgttataMgStYaattYaccaattgagtcaaattaYtgta +tcatgMcaDcgggtcttDtKgcatgWRtataatatRacacNRBttcHtBgcRttgtgcgt +catacMtttBctatctBaatcattMttMYgattaaVYatgDaatVagtattDacaacDMa +tcMtHcccataagatgBggaccattVWtRtSacatgctcaaggggYtttDtaaNgNtaaB +atggaatgtctRtaBgBtcNYatatNRtagaacMgagSaSDDSaDcctRagtVWSHtVSR +ggaacaBVaccgtttaStagaacaMtactccagtttVctaaRaaHttNcttagcaattta +ttaatRtaaaatctaacDaBttggSagagctacHtaaRWgattcaaBtctRtSHaNtgta +cattVcaHaNaagtataccacaWtaRtaaVKgMYaWgttaKggKMtKcgWatcaDatYtK +SttgtacgaccNctSaattcDcatcttcaaaDKttacHtggttHggRRaRcaWacaMtBW +VHSHgaaMcKattgtaRWttScNattBBatYtaNRgcggaagacHSaattRtttcYgacc +BRccMacccKgatgaacttcgDgHcaaaaaRtatatDtatYVtttttHgSHaSaatagct +NYtaHYaVYttattNtttgaaaYtaKttWtctaNtgagaaaNctNDctaaHgttagDcRt +tatagccBaacgcaRBtRctRtggtaMYYttWtgataatcgaataattattataVaaaaa +ttacNRVYcaaMacNatRttcKatMctgaagactaattataaYgcKcaSYaatMNctcaa +cgtgatttttBacNtgatDccaattattKWWcattttatatatgatBcDtaaaagttgaa +VtaHtaHHtBtataRBgtgDtaataMttRtDgDcttattNtggtctatctaaBcatctaR +atgNacWtaatgaagtcMNaacNgHttatactaWgcNtaStaRgttaaHacccgaYStac +aaaatWggaYaWgaattattcMaactcBKaaaRVNcaNRDcYcgaBctKaacaaaaaSgc +tccYBBHYaVagaatagaaaacagYtctVccaMtcgtttVatcaatttDRtgWctagtac +RttMctgtDctttcKtWttttataaatgVttgBKtgtKWDaWagMtaaagaaattDVtag +gttacatcatttatgtcgMHaVcttaBtVRtcgtaYgBRHatttHgaBcKaYWaatcNSc +tagtaaaaatttacaatcactSWacgtaatgKttWattagttttNaggtctcaagtcact +attcttctaagKggaataMgtttcataagataaaaatagattatDgcBVHWgaBKttDgc +atRHaagcaYcRaattattatgtMatatattgHDtcaDtcaaaHctStattaatHaccga +cNattgatatattttgtgtDtRatagSacaMtcRtcattcccgacacSattgttKaWatt +NHcaacttccgtttSRtgtctgDcgctcaaMagVtBctBMcMcWtgtaacgactctcttR +ggRKSttgYtYatDccagttDgaKccacgVatWcataVaaagaataMgtgataaKYaaat +cHDaacgataYctRtcYatcgcaMgtNttaBttttgatttaRtStgcaacaaaataccVg +aaDgtVgDcStctatatttattaaaaRKDatagaaagaKaaYYcaYSgKStctccSttac +agtcNactttDVttagaaagMHttRaNcSaRaMgBttattggtttaRMggatggcKDgWR +tNaataataWKKacttcKWaaagNaBttaBatMHtccattaacttccccYtcBcYRtaga +ttaagctaaYBDttaNtgaaaccHcaRMtKtaaHMcNBttaNaNcVcgVttWNtDaBatg +ataaVtcWKcttRggWatcattgaRagHgaattNtatttctctattaattaatgaDaaMa +tacgttgggcHaYVaaNaDDttHtcaaHtcVVDgBVagcMacgtgttaaBRNtatRtcag +taagaggtttaagacaVaaggttaWatctccgtVtaDtcDatttccVatgtacNtttccg +tHttatKgScBatgtVgHtYcWagcaKtaMYaaHgtaattaSaHcgcagtWNaatNccNN +YcacgVaagaRacttctcattcccRtgtgtaattagcSttaaStWaMtctNNcSMacatt +ataaactaDgtatWgtagtttaagaaaattgtagtNagtcaataaatttgatMMYactaa +tatcggBWDtVcYttcDHtVttatacYaRgaMaacaStaatcRttttVtagaDtcacWat +ttWtgaaaagaaagNRacDtttStVatBaDNtaactatatcBSMcccaSttccggaMatg +attaaWatKMaBaBatttgataNctgttKtVaagtcagScgaaaDggaWgtgttttKtWt +atttHaatgtagttcactaaKMagttSYBtKtaYgaactcagagRtatagtVtatcaaaW +YagcgNtaDagtacNSaaYDgatBgtcgataacYDtaaactacagWDcYKaagtttatta +gcatcgagttKcatDaattgattatDtcagRtWSKtcgNtMaaaaacaMttKcaWcaaSV +MaaaccagMVtaMaDtMaHaBgaacataBBVtaatVYaNSWcSgNtDNaaKacacBttta +tKtgtttcaaHaMctcagtaacgtcgYtactDcgcctaNgagagcYgatattttaaattt +ccattttacatttDaaRctattttWctttacgtDatYtttcagacgcaaVttagtaaKaa +aRtgVtccataBggacttatttgtttaWNtgttVWtaWNVDaattgtatttBaagcBtaa +BttaaVatcHcaVgacattccNggtcgacKttaaaRtagRtctWagaYggtgMtataatM +tgaaRttattttgWcttNtDRRgMDKacagaaaaggaaaRStcccagtYccVattaNaaK +StNWtgacaVtagaagcttSaaDtcacaacgDYacWDYtgtttKatcVtgcMaDaSKStV +cgtagaaWaKaagtttcHaHgMgMtctataagBtKaaaKKcactggagRRttaagaBaaN +atVVcgRcKSttDaactagtSttSattgttgaaRYatggttVttaataaHttccaagDtg +atNWtaagHtgcYtaactRgcaatgMgtgtRaatRaNaacHKtagactactggaatttcg +ccataacgMctRgatgttaccctaHgtgWaYcactcacYaattcttaBtgacttaaacct +gYgaWatgBttcttVttcgttWttMcNYgtaaaatctYgMgaaattacNgaHgaacDVVM +tttggtHtctaaRgtacagacgHtVtaBMNBgattagcttaRcttacaHcRctgttcaaD +BggttKaacatgKtttYataVaNattccgMcgcgtagtRaVVaattaKaatggttRgaMc +agtatcWBttNtHagctaatctagaaNaaacaYBctatcgcVctBtgcaaagDgttVtga +HtactSNYtaaNccatgtgDacgaVtDcgKaRtacDcttgctaagggcagMDagggtBWR +tttSgccttttttaacgtcHctaVtVDtagatcaNMaVtcVacatHctDWNaataRgcgt +aVHaggtaaaaSgtttMtattDgBtctgatSgtRagagYtctSaKWaataMgattRKtaa +catttYcgtaacacattRWtBtcggtaaatMtaaacBatttctKagtcDtttgcBtKYYB +aKttctVttgttaDtgattttcttccacttgSaaacggaaaNDaattcYNNaWcgaaYat +tttMgcBtcatRtgtaaagatgaWtgaccaYBHgaatagataVVtHtttVgYBtMctaMt +cctgaDcYttgtccaaaRNtacagcMctKaaaggatttacatgtttaaWSaYaKttBtag +DacactagctMtttNaKtctttcNcSattNacttggaacaatDagtattRtgSHaataat +gccVgacccgatactatccctgtRctttgagaSgatcatatcgDcagWaaHSgctYYWta +tHttggttctttatVattatcgactaagtgtagcatVgtgHMtttgtttcgttaKattcM +atttgtttWcaaStNatgtHcaaaDtaagBaKBtRgaBgDtSagtatMtaacYaatYtVc +KatgtgcaacVaaaatactKcRgtaYtgtNgBBNcKtcttaccttKgaRaYcaNKtactt +tgagSBtgtRagaNgcaaaNcacagtVtttHWatgttaNatBgtttaatNgVtctgaata +tcaRtattcttttttttRaaKcRStctcggDgKagattaMaaaKtcaHacttaataataK +taRgDtKVBttttcgtKaggHHcatgttagHggttNctcgtatKKagVagRaaaggaaBt +NatttVKcRttaHctaHtcaaatgtaggHccaBataNaNaggttgcWaatctgatYcaaa +HaatWtaVgaaBttagtaagaKKtaaaKtRHatMaDBtBctagcatWtatttgWttVaaa +ScMNattRactttgtYtttaaaagtaagtMtaMaSttMBtatgaBtttaKtgaatgagYg +tNNacMtcNRacMMHcttWtgtRtctttaacaacattattcYaMagBaacYttMatcttK +cRMtgMNccattaRttNatHaHNaSaaHMacacaVaatacaKaSttHatattMtVatWga +ttttttaYctttKttHgScWaacgHtttcaVaaMgaacagNatcgttaacaaaaagtaca +HBNaattgttKtcttVttaaBtctgctacgBgcWtttcaggacacatMgacatcccagcg +gMgaVKaBattgacttaatgacacacaaaaaatRKaaBctacgtRaDcgtagcVBaacDS +BHaaaaSacatatacagacRNatcttNaaVtaaaataHattagtaaaaSWccgtatWatg +gDttaactattgcccatcttHaSgYataBttBaactattBtcHtgatcaataSttaBtat +KSHYttWggtcYtttBttaataccRgVatStaHaKagaatNtagRMNgtcttYaaSaact +cagDSgagaaYtMttDtMRVgWKWtgMaKtKaDttttgactatacataatcNtatNaHat +tVagacgYgatatatttttgtStWaaatctWaMgagaRttRatacgStgattcttaagaD +taWccaaatRcagcagaaNKagtaaDggcgccBtYtagSBMtactaaataMataBSacRM +gDgattMMgtcHtcaYDtRaDaacggttDaggcMtttatgttaNctaattaVacgaaMMt +aatDccSgtattgaRtWWaccaccgagtactMcgVNgctDctaMScatagcgtcaactat +acRacgHRttgctatttaatgaattataYKttgtaagWgtYttgcHgMtaMattWaWVta +RgcttgYgttBHtYataSccStBtgtagMgtDtggcVaaSBaatagDttgBgtctttctc +attttaNagtHKtaMWcYactVcgcgtatMVtttRacVagDaatcttgctBBcRDgcaac +KttgatSKtYtagBMagaRtcgBattHcBWcaactgatttaatttWDccatttatcgagS +KaWttataHactaHMttaatHtggaHtHagaatgtKtaaRactgtttMatacgatcaagD +gatKaDctataMggtHDtggHacctttRtatcttYattttgacttgaaSaataaatYcgB +aaaaccgNatVBttMacHaKaataagtatKgtcaagactcttaHttcggaattgttDtct +aaccHttttWaaatgaaatataaaWattccYDtKtaaaacggtgaggWVtctattagtga +ctattaagtMgtttaagcatttgSgaaatatccHaaggMaaaattttcWtatKctagDtY +tMcctagagHcactttactatacaaacattaacttaHatcVMYattYgVgtMttaaRtga +aataaDatcaHgtHHatKcDYaatcttMtNcgatYatgSaMaNtcttKcWataScKggta +tcttacgcttWaaagNatgMgHtctttNtaacVtgttcMaaRatccggggactcMtttaY +MtcWRgNctgNccKatcttgYDcMgattNYaRagatHaaHgKctcataRDttacatBatc +cattgDWttatttaWgtcggagaaaaatacaatacSNtgggtttccttacSMaagBatta +caMaNcactMttatgaRBacYcYtcaaaWtagctSaacttWgDMHgaggatgBVgcHaDt +ggaactttggtcNatNgtaKaBcccaNtaagttBaacagtatacDYttcctNgWgcgSMc +acatStctHatgRcNcgtacacaatRttMggaNKKggataaaSaYcMVcMgtaMaHtgat +tYMatYcggtcttcctHtcDccgtgRatcattgcgccgatatMaaYaataaYSggatagc +gcBtNtaaaScaKgttBgagVagttaKagagtatVaactaSacWactSaKatWccaKaaa +atBKgaaKtDMattttgtaaatcRctMatcaaMagMttDgVatggMaaWgttcgaWatga +aatttgRtYtattaWHKcRgctacatKttctaccaaHttRatctaYattaaWatVNccat +NgagtcKttKataStRaatatattcctRWatDctVagttYDgSBaatYgttttgtVaatt +taatagcagMatRaacttBctattgtMagagattaaactaMatVtHtaaatctRgaaaaa +aaatttWacaacaYccYDSaattMatgaccKtaBKWBattgtcaagcHKaagttMMtaat +ttcKcMagNaaKagattggMagaggtaatttYacatcWaaDgatMgKHacMacgcVaaca +DtaDatatYggttBcgtatgWgaSatttgtagaHYRVacaRtctHaaRtatgaactaata +tctSSBgggaaHMWtcaagatKgagtDaSatagttgattVRatNtctMtcSaagaSHaat +aNataataRaaRgattctttaataaagWaRHcYgcatgtWRcttgaaggaMcaataBRaa +ccagStaaacNtttcaatataYtaatatgHaDgcStcWttaacctaRgtYaRtataKtgM +ttttatgactaaaatttacYatcccRWtttHRtattaaatgtttatatttgttYaatMca +RcSVaaDatcgtaYMcatgtagacatgaaattgRtcaaYaaYtRBatKacttataccaNa +aattVaBtctggacaagKaaYaaatatWtMtatcYaaVNtcgHaactBaagKcHgtctac +aatWtaDtSgtaHcataHtactgataNctRgttMtDcDttatHtcgtacatcccaggStt +aBgtcacacWtccNMcNatMVaVgtccDYStatMaccDatggYaRKaaagataRatttHK +tSaaatDgataaacttaHgttgVBtcttVttHgDacgaKatgtatatNYataactctSat +atatattgcHRRYttStggaactHgttttYtttaWtatMcttttctatctDtagVHYgMR +BgtHttcctaatYRttKtaagatggaVRataKDctaMtKBNtMtHNtWtttYcVtattMc +gRaacMcctNSctcatttaaagDcaHtYccSgatgcaatYaaaaDcttcgtaWtaattct +cgttttScttggtaatctttYgtctaactKataHacctMctcttacHtKataacacagcN +RatgKatttttSaaatRYcgDttaMRcgaaattactMtgcgtaagcgttatBtttttaat +taagtNacatHgttcRgacKcBBtVgatKttcgaBaatactDRgtRtgaNacWtcacYtt +aaKcgttctHaKttaNaMgWgWaggtctRgaKgWttSttBtDcNtgtttacaaatYcDRt +gVtgcctattcNtctaaaDMNttttNtggctgagaVctDaacVtWccaagtaacacaNct +gaScattccDHcVBatcgatgtMtaatBgHaatDctMYgagaatgYWKcctaatNaStHa +aaKccgHgcgtYaaYtattgtStgtgcaaRtattaKatattagaWVtcaMtBagttatta +gNaWHcVgcaattttDcMtgtaRHVYtHtctgtaaaaHVtMKacatcgNaatttMatatg +ttgttactagWYtaRacgataKagYNKcattataNaRtgaacKaYgcaaYYacaNccHat +MatDcNgtHttRaWttagaaDcaaaaaatagggtKDtStaDaRtaVtHWKNtgtattVct +SVgRgataDaRaWataBgaagaaKtaataaYgDcaStaNgtaDaaggtattHaRaWMYaY +aWtggttHYgagVtgtgcttttcaaDKcagVcgttagacNaaWtagtaataDttctggtt +VcatcataaagtgKaaaNaMtaBBaattaatWaattgctHaVKaSgDaaVKaHtatatat +HatcatSBagNgHtatcHYMHgttDgtaHtBttWatcgtttaRaattgStKgSKNWKatc +agDtctcagatttctRtYtBatBgHHtKaWtgYBgacVVWaKtacKcDttKMaKaVcggt +gttataagaataaHaatattagtataatMHgttYgaRttagtaRtcaaVatacggtcMcg +agtaaRttacWgactKRYataaaagSattYaWgagatYagKagatgSaagKgttaatMgg +tataatgttWYttatgagaaacctNVataatHcccKtDctcctaatactggctHggaSag +gRtKHaWaattcgSatMatttagaggcYtctaMcgctcataSatatgRagacNaaDagga +VBagaYttKtacNaKgtSYtagttggaWcatcWttaatctatgaVtcgtgtMtatcaYcg +tRccaaYgDctgcMgtgtWgacWtgataacacgcgctBtgttaKtYDtatDcatcagKaV +MctaatcttgVcaaRgcRMtDcgattaHttcaNatgaatMtactacVgtRgatggaWttt +actaaKatgagSaaKggtaNtactVaYtaaKRagaacccacaMtaaMtKtatBcttgtaa +WBtMctaataaVcDaaYtcRHBtcgttNtaaHatttBNgRStVDattBatVtaagttaYa +tVattaagaBcacggtSgtVtatttaRattgatgtaHDKgcaatattKtggcctatgaWD +KRYcggattgRctatNgatacaatMNttctgtcRBYRaaaHctNYattcHtaWcaattct +BtMKtVgYataatMgYtcagcttMDataVtggRtKtgaatgccNcRttcaMtRgattaac +attRcagcctHtWMtgtDRagaKaBtgDttYaaaaKatKgatctVaaYaacWcgcatagB +VtaNtRtYRaggBaaBtgKgttacataagagcatgtRattccacttaccatRaaatgWgD +aMHaYVgVtaSctatcgKaatatattaDgacccYagtgtaYNaaatKcagtBRgagtcca +tgKgaaaccBgaagBtgSttWtacgatWHaYatcgatttRaaNRgcaNaKVacaNtDgat +tgHVaatcDaagcgtatgcNttaDataatcSataaKcaataaHWataBtttatBtcaKtK +tatagttaDgSaYctacaRatNtaWctSaatatttYaKaKtaccWtatcRagacttaYtt +VcKgSDcgagaagatccHtaattctSttatggtKYgtMaHagVaBRatttctgtRgtcta +tgggtaHKgtHacHtSYacgtacacHatacKaaBaVaccaDtatcSaataaHaagagaat +ScagactataaRttagcaaVcaHataKgDacatWccccaagcaBgagWatctaYttgaaa +tctVNcYtttWagHcgcgcDcVaaatgttKcHtNtcaatagtgtNRaactttttcaatgg +WgBcgDtgVgtttctacMtaaataaaRggaaacWaHttaRtNtgctaaRRtVBctYtVta +tDcattDtgaccYatagatYRKatNYKttNgcctagtaWtgaactaMVaacctgaStttc +tgaKVtaaVaRKDttVtVctaDNtataaaDtccccaagtWtcgatcactDgYaBcatcct +MtVtacDaaBtYtMaKNatNtcaNacgDatYcatcgcaRatWBgaacWttKttagYtaat +tcggttgSWttttDWctttacYtatatWtcatDtMgtBttgRtVDggttaacYtacgtac +atgaattgaaWcttMStaDgtatattgaDtcRBcattSgaaVBRgagccaaKtttcDgcg +aSMtatgWattaKttWtgDBMaggBBttBaatWttRtgcNtHcgttttHtKtcWtagHSt +aacagttgatatBtaWSaWggtaataaMttaKacDaatactcBttcaatatHttcBaaSa +aatYggtaRtatNtHcaatcaHtagVtgtattataNggaMtcttHtNagctaaaggtaga +YctMattNaMVNtcKtactBKcaHHcBttaSagaKacataYgctaKaYgttYcgacWVtt +WtSagcaacatcccHaccKtcttaacgaKttcacKtNtacHtatatRtaaatacactaBt +ttgaHaRttggttWtatYagcatYDatcggagagcWBataagRtacctataRKgtBgatg +aDatataSttagBaHtaatNtaDWcWtgtaattacagKttcNtMagtattaNgtctcgtc +ctcttBaHaKcKccgtRcaaYagSattaagtKataDatatatagtcDtaacaWHcaKttD +gaaRcgtgYttgtcatatNtatttttatggccHtgDtYHtWgttatYaacaattcaWtat +NgctcaaaSttRgctaatcaaatNatcgtttaBtNNVtgttataagcaaagattBacgtD +atttNatttaaaDcBgtaSKgacgtagataatttcHMVNttgttBtDtgtaWKaaRMcKM +tHtaVtagataWctccNNaSWtVaHatctcMgggDgtNHtDaDttatatVWttgttattt +aacctttcacaaggaSaDcggttttttatatVtctgVtaacaStDVaKactaMtttaSNa +gtgaaattaNacttSKctattcctctaSagKcaVttaagNaVcttaVaaRNaHaaHttat +gtHttgtgatMccaggtaDcgaccgtWgtWMtttaHcRtattgScctatttKtaaccaag +tYagaHgtWcHaatgccKNRtttagtMYSgaDatctgtgaWDtccMNcgHgcaaacNDaa +aRaStDWtcaaaaHKtaNBctagBtgtattaactaattttVctagaatggcWSatMaccc +ttHttaSgSgtgMRcatRVKtatctgaaaccDNatYgaaVHNgatMgHRtacttaaaRta +tStRtDtatDttYatattHggaBcttHgcgattgaKcKtttcRataMtcgaVttWacatN +catacctRataDDatVaWNcggttgaHtgtMacVtttaBHtgagVttMaataattatgtt +cttagtttgtgcDtSatttgBtcaacHattaaBagVWcgcaSYttMgcttacYKtVtatc +aYaKctgBatgcgggcYcaaaaacgNtctagKBtattatctttKtaVttatagtaYtRag +NtaYataaVtgaatatcHgcaaRataHtacacatgtaNtgtcgYatWMatttgaactacR +ctaWtWtatacaatctBatatgYtaagtatgtgtatSttactVatcttYtaBcKgRaSgg +RaaaaatgcagtaaaWgtaRgcgataatcBaataccgtatttttccatcNHtatWYgatH +SaaaDHttgctgtccHtggggcctaataatttttctatattYWtcattBtgBRcVttaVM +RSgctaatMagtYtttaaaaatBRtcBttcaaVtaacagctccSaaSttKNtHtKYcagc +agaaaccccRtttttaaDcDtaStatccaagcgctHtatcttaDRYgatDHtWcaaaBcW +gKWHttHataagHacgMNKttMKHccaYcatMVaacgttaKgYcaVaaBtacgcaacttt +MctaaHaatgtBatgagaSatgtatgSRgHgWaVWgataaatatttccKagVgataattW +aHNcYggaaatgctHtKtaDtctaaagtMaatVDVactWtSaaWaaMtaHtaSKtcBRaN +cttStggtBttacNagcatagRgtKtgcgaacaacBcgKaatgataagatgaaaattgta +ctgcgggtccHHWHaaNacaBttNKtKtcaaBatatgctaHNgtKcDWgtttatNgVDHg +accaacWctKaaggHttgaRgYaatHcaBacaatgagcaaattactgtaVaaYaDtagat +tgagNKggtggtgKtWKaatacagDRtatRaMRtgattDggtcaaYRtatttNtagaDtc +acaaSDctDtataatcgtactaHttatacaatYaacaaHttHatHtgcgatRRttNgcat +SVtacWWgaaggagtatVMaVaaattScDDKNcaYBYaDatHgtctatBagcaacaagaa +tgagaaRcataaKNaRtBDatcaaacgcattttttaaBtcSgtacaRggatgtMNaattg +gatatWtgagtattaaaVctgcaYMtatgatttttYgaHtgtcttaagWBttHttgtctt +attDtcgtatWtataataSgctaHagcDVcNtaatcaagtaBDaWaDgtttagYctaNcc +DtaKtaHcttaataacccaRKtacaVaatNgcWRaMgaattatgaBaaagattVYaHMDc +aDHtcRcgYtcttaaaWaaaVKgatacRtttRRKYgaatacaWVacVcRtatMacaBtac +tggMataaattttHggNagSctacHgtBagcgtcgtgattNtttgatSaaggMttctttc +ttNtYNagBtaaacaaatttMgaccttacataattgYtcgacBtVMctgStgMDtagtaR +ctHtatgttcatatVRNWataDKatWcgaaaaagttaaaagcacgHNacgtaatctttMR +tgacttttDacctataaacgaaatatgattagaactccSYtaBctttaataacWgaaaYa +tagatgWttcatKtNgatttttcaagHtaYgaaRaDaagtaggagcttatVtagtctttc +attaaaatcgKtattaRttacagVaDatgcatVgattgggtctttHVtagKaaRBtaHta +aggccccaaaaKatggtttaMWgtBtaaacttcactttKHtcgatctccctaYaBacMgt +cttBaBaNgcgaaacaatctagtHccHtKttcRtRVttccVctttcatacYagMVtMcag +aMaaacaataBctgYtaatRaaagattaaccatVRatHtaRagcgcaBcgDttStttttc +VtttaDtKgcaaWaaaaatSccMcVatgtKgtaKgcgatatgtagtSaaaDttatacaaa +catYaRRcVRHctKtcgacKttaaVctaDaatgttMggRcWaacttttHaDaKaDaBctg +taggcgtttaHBccatccattcNHtDaYtaataMttacggctNVaacDattgatatttta +cVttSaattacaaRtataNDgacVtgaacataVRttttaDtcaaacataYDBtttaatBa +DtttYDaDaMccMttNBttatatgagaaMgaNtattHccNataattcaHagtgaaggDga +tgtatatatgYatgaStcataaBStWacgtcccataRMaaDattggttaaattcMKtctM +acaBSactcggaatDDgatDgcWctaacaccgggaVcacWKVacggtaNatatacctMta +tgatagtgcaKagggVaDtgtaacttggagtcKatatcgMcttRaMagcattaBRaStct +YSggaHYtacaactMBaagDcaBDRaaacMYacaHaattagcattaaaHgcgctaaggSc +cKtgaaKtNaBtatDDcKBSaVtgatVYaagVtctSgMctacgttaacWaaattctSgtD +actaaStaaattgcagBBRVctaatatacctNttMcRggctttMttagacRaHcaBaacV +KgaataHttttMgYgattcYaNRgttMgcVaaacaVVcDHaatttgKtMYgtatBtVVct +WgVtatHtacaaHttcacgatagcagtaaNattBatatatttcVgaDagcggttMaagtc +ScHagaaatgcYNggcgtttttMtStggtRatctacttaaatVVtBacttHNttttaRca +aatcacagHgagagtMgatcSWaNRacagDtatactaaDKaSRtgattctccatSaaRtt +aaYctacacNtaRtaactggatgaccYtacactttaattaattgattYgttcagDtNKtt +agDttaaaaaaaBtttaaNaYWKMBaaaacVcBMtatWtgBatatgaacVtattMtYatM +NYDKNcKgDttDaVtaaaatgggatttctgtaaatWtctcWgtVVagtcgRgacttcccc +taDcacagcRcagagtgtWSatgtacatgttaaSttgtaaHcgatgggMagtgaacttat +RtttaVcaccaWaMgtactaatSSaHtcMgaaYtatcgaaggYgggcgtgaNDtgttMNg +aNDMtaattcgVttttaacatgVatgtWVMatatcaKgaaattcaBcctccWcttgaaWH +tWgHtcgNWgaRgctcBgSgaattgcaaHtgattgtgNagtDttHHgBttaaWcaaWagc +aSaHHtaaaVctRaaMagtaDaatHtDMtcVaWMtagSagcttHSattaacaaagtRacM +tRtctgttagcMtcaBatVKtKtKacgagaSNatSactgtatatcBctgagVtYactgta +aattaaaggcYgDHgtaacatSRDatMMccHatKgttaacgactKtgKagtcttcaaHRV +tccttKgtSataatttacaactggatDNgaacttcaRtVaagDcaWatcBctctHYatHa +DaaatttagYatSatccaWtttagaaatVaacBatHcatcgtacaatatcgcNYRcaata +YaRaYtgattVttgaatgaVaactcRcaNStgtgtattMtgaggtNttBaDRcgaaaagc +tNgBcWaWgtSaDcVtgVaatMKBtttcgtttctaaHctaaagYactgMtatBDtcStga +ccgtSDattYaataHctgggaYYttcggttaWaatctggtRagWMaDagtaacBccacta +cgHWMKaatgatWatcctgHcaBaSctVtcMtgtDttacctaVgatYcWaDRaaaaRtag +atcgaMagtggaRaWctctgMgcWttaagKBRtaaDaaWtctgtaagYMttactaHtaat +cttcataacggcacBtSgcgttNHtgtHccatgttttaaagtatcgaKtMttVcataYBB +aKtaMVaVgtattNDSataHcagtWMtaggtaSaaKgttgBtVtttgttatcatKcgHac +acRtctHatNVagSBgatgHtgaRaSgttRcctaacaaattDNttgacctaaYtBgaaaa +tagttattactcttttgatgtNNtVtgtatMgtcttRttcatttgatgacacttcHSaaa +ccaWWDtWagtaRDDVNacVaRatgttBccttaatHtgtaaacStcVNtcacaSRttcYa +gacagaMMttttgMcNttBcgWBtactgVtaRttctccaaYHBtaaagaBattaYacgat +ttacatctgtaaMKaRYtttttactaaVatWgctBtttDVttctggcDaHaggDaagtcg +aWcaagtagtWttHtgKtVataStccaMcWcaagataagatcactctHatgtcYgaKcat +cagatactaagNSStHcctRRNtattgtccttagttagMVgtatagactaactctVcaat +MctgtttgtgttgccttatWgtaBVtttctggMcaaKgDWtcgtaaYStgSactatttHg +atctgKagtagBtVacRaagRtMctatgggcaaaKaaaatacttcHctaRtgtDcttDat +taggaaatttcYHaRaaBttaatggcacKtgctHVcaDcaaaVDaaaVcgMttgtNagcg +taDWgtcgttaatDgKgagcSatatcSHtagtagttggtgtHaWtaHKtatagctgtVga +ttaBVaatgaataagtaatVatSttaHctttKtttgtagttaccttaatcgtagtcctgB +cgactatttVcMacHaaaggaatgDatggKtaHtgStatattaaSagctWcctccRtata +BaDYcgttgcNaagaggatRaaaYtaWgNtSMcaatttactaacatttaaWttHtatBat +tgtcgacaatNgattgcNgtMaaaKaBDattHacttggtRtttaYaacgVactBtaBaKt +gBttatgVttgtVttcaatcWcNctDBaaBgaDHacBttattNtgtDtatttVSaaacag +gatgcRatSgtaSaNtgBatagttcHBgcBBaaattaHgtDattatDaKaatBaaYaaMa +ataaataKtttYtagtBgMatNcatgtttgaNagtgttgtgKaNaSagtttgaSMaYBca +aaacDStagttVacaaaaactaaWttBaagtctgtgcgtMgtaattctcctacctcaNtt +taaccaaaaVtBcacataacaccccBcWMtatVtggaatgaWtcaaWaaaaaaaaWtDta +atatRcctDWtcctaccMtVVatKttaWaaKaaatataaagScHBagaggBaSMtaWaVt +atattactSaaaKNaactatNatccttgaYctattcaaaVgatttYHcRagattttaSat +aggttattcVtaaagaKgtattattKtRttNcggcRgtgtgtWYtaacHgKatKgatYta +cYagDtWcHBDctctgRaYKaYagcactKcacSaRtBttttBHKcMtNtcBatttatttt +tgSatVgaaagaWtcDtagDatatgMacaacRgatatatgtttgtKtNRaatatNatgYc +aHtgHataacKtgagtagtaacYttaNccaaatHcacaacaVDtagtaYtccagcattNt +acKtBtactaaagaBatVtKaaHBctgStgtBgtatgaSNtgDataaccctgtagcaBgt +gatcttaDataStgaMaccaSBBgWagtacKcgattgaDgNNaaaacacagtSatBacKD +gcgtataBKcatacactaSaatYtYcDaactHttcatRtttaatcaattataRtttgtaa +gMcgNttcatcBtYBagtNWNMtSHcattcRctttttRWgaKacKttgggagBcgttcgc +MaWHtaatactgtctctatttataVgtttaBScttttaBMaNaatMacactYtBMggtHa +cMagtaRtctgcatttaHtcaaaatttgagKtgNtactBacaHtcgtatttctMaSRagc +agttaatgtNtaaattgagagWcKtaNttagVtacgatttgaatttcgRtgtWcVatcgt +taaDVctgtttBWgaccagaaagtcSgtVtatagaBccttttcctaaattgHtatcggRa +ttttcaaggcYSKaagWaWtRactaaaacccBatMtttBaatYtaagaactSttcgaaSc +aatagtattgaccaagtgttttctaacatgtttNVaatcaaagagaaaNattaaRtttta +VaaaccgcaggNMtatattVctcaagaggaacgBgtttaacaagttcKcYaatatactaa +ccBaaaSggttcNtattctagttRtBacgScVctcaatttaatYtaaaaaaatgSaatga +tagaMBRatgRcMcgttgaWHtcaVYgaatYtaatctttYttatRaWtctgBtDcgatNa +tcKaBaDgatgtaNatWKctccgatattaacattNaaacDatgBgttctgtDtaaaMggt +gaBaSHataacgccSctaBtttaRBtcNHcDatcDcctagagtcRtaBgWttDRVHagat +tYatgtatcWtaHtttYcattWtaaagtctNgtStggRNcgcggagSSaaagaaaatYcH +DtcgctttaatgYcKBVSgtattRaYBaDaaatBgtatgaHtaaRaRgcaSWNtagatHa +acttNctBtcaccatctMcatattccaSatttgcgaDagDgtatYtaaaVDtaagtttWV +aagtagYatRttaagDcNgacKBcScagHtattatcDaDactaaaaaYgHttBcgaDttg +gataaaKSRcBMaBcgaBSttcWtgNBatRaccgattcatttataacggHVtaattcaca +agagVttaaRaatVVRKcgWtVgacctgDgYaaHaWtctttcacMagggatVgactagMa +aataKaaNWagKatagNaaWtaaaatttgaattttatttgctaaVgaHatBatcaaBWcB +gttcMatcgBaaNgttcgSNaggSaRtttgHtRtattaNttcDcatSaVttttcgaaaaa +ttgHatctaRaggSaNatMDaaatDcacgattttagaHgHaWtYgattaatHNSttatMS +gggNtcKtYatRggtttgtMWVtttaYtagcagBagHaYagttatatggtBacYcattaR +SataBatMtttaaatctHcaaaSaaaagttNSaaWcWRccRtKaagtBWtcaaattSttM +tattggaaaccttaacgttBtWatttatatWcDaatagattcctScacctaagggRaaYt +aNaatgVtBcttaaBaacaMVaaattatStYgRcctgtactatcMcVKatttcgSgatRH +MaaaHtagtaaHtVgcaaataatatcgKKtgccaatBNgaaWcVttgagttaKatagttc +aggKDatDtattgaKaVcaKtaataDataataHSaHcattagttaatRVYcNaHtaRcaa +ggtNHcgtcaaccaBaaagYtHWaaaRcKgaYaaDttgcWYtataRgaatatgtYtgcKt +aNttWacatYHctRaDtYtattcBttttatcSataYaYgttWaRagcacHMgtttHtYtt +YaatcggtatStttcgtRSattaaDaKMaatatactaNBaWgctacacYtgaYVgtgHta +aaRaaRgHtagtWattataaaSDaaWtgMattatcgaaaagtaYRSaWtSgNtBgagcRY +aMDtactaacttaWgtatctagacaagNtattHggataatYttYatcataDcgHgttBtt +ctttVttgccgaaWtaaaacgKgtatctaaaaaNtccDtaDatBMaMggaatNKtatBaa +atVtccRaHtaSacataHattgtttKVYattcataVaattWtcgtgMttcttKtgtctaa +cVtatctatatBRataactcgKatStatattcatHHRttKtccaacgtgggtgRgtgaMt +attattggctatcgtgacMtRcBDtcttgtactaatRHttttaagatcgVMDStattatY +BtttDttgtBtNttgRcMtYtgBacHaWaBaatDKctaagtgaaactaatgRaaKgatcc +aagNaaaatattaggWNtaagtatacttttKcgtcggSYtcttgRctataYcttatataa +agtatattaatttataVaacacaDHatctatttttKYVatHRactttaBHccaWagtact +BtcacgaVgcgttRtttttttSVgtSagtBaaattctgaHgactcttgMcattttagVta +agaattHctHtcaDaaNtaacRggWatagttcgtSttgaDatcNgNagctagDgatcNtt +KgttgtaDtctttRaaYStRatDtgMggactSttaDtagSaVtBDttgtDgccatcacaM +attaaaMtNacaVcgSWcVaaDatcaHaatgaattaMtatccVtctBtaattgtWattat +BRcWcaatgNNtactWYtDaKttaaatcactcagtRaaRgatggtKgcgccaaHgaggat +StattYcaNMtcaBttacttatgagDaNtaMgaaWtgtttcttctaHtMNgttatctaWW +atMtBtaaatagDVatgtBYtatcggcttaagacMRtaHScgatatYgRDtcattatSDa +HggaaataNgaWSRRaaaBaatagBattaDctttgHWNttacaataaaaaaatacggttt +gHgVtaHtWMttNtBtctagtMcgKMgHgYtataHaNagWtcaacYattaataYRgtaWK +gaBctataaccgatttaHaNBRaRaMtccggtNgacMtctcatttgcaattcWgMactta +caaDaaNtactWatVtttagccttMaatcagVaagtctVaaDaBtattaattaYtNaYtg +gattaKtaKctYaMtattYgatattataatKtVgDcttatatNBtcgttgtStttttMag +aggttaHYSttcKgtcKtDNtataagttataagSgttatDtRttattgttttSNggRtca +aKMNatgaatattgtBWtaMacctgggYgaSgaagYataagattacgagaatBtggtRcV +HtgYggaDgaYaKagWagctatagacgaaHgtWaNgacttHRatVaWacKYtgRVNgVcS +gRWctacatcKSactctgWYtBggtataagcttNRttVtgRcaWaaatDMatYattaact +ttcgaagRatSctgccttgcRKaccHtttSNVagtagHagBagttagaccaRtataBcca +taatSHatRtcHagacBWatagcaMtacaRtgtgaaBatctKRtScttccaNaatcNgta +atatWtcaMgactctBtWtaaNactHaaaaRctcgcatggctMcaaNtcagaaaaacaca +gtggggWttRttagtaagaVctVMtcgaatcttcMaaaHcaHBttcgattatgtcaDagc +YRtBtYcgacMgtDcagcgaNgttaataatagcagKYYtcgtaBtYctMaRtaRtDagaa +aacacatgYaBttgattattcgaaNttBctSataaMataWRgaHtttccgtDgaYtatgg +tDgHKgMtatttVtMtVagttaRatMattRagataaccctKctMtSttgaHagtcStcta +tttccSagatgttccacgaggYNttHRacgattcDatatDcataaaatBBttatcgaHtN +HaaatatDNaggctgaNcaaggagttBttMgRagVatBcRtaWgatgBtSgaKtcgHttt +gaatcaaDaHttcSBgHcagtVaaSttDcagccgttNBtgttHagYtattctttRWaaVt +SttcatatKaaRaaaNacaVtVctMtSDtDtRHRcgtaatgctcttaaatSacacaatcg +HattcaWcttaaaatHaaatcNctWttaNMcMtaKctVtcctaagYgatgatcYaaaRac +tctaRDaYagtaacgtDgaggaaatctcaaacatcaScttcKttNtaccatNtaNataca +tttHaaDHgcaDatMWaaBttcRggctMaagctVYcacgatcaDttatYtaatcKatWat +caatVYtNagatttgattgaYttttYgacttVtcKaRagaaaHVgDtaMatKYagagttN +atWttaccNtYtcDWgSatgaRgtMatgKtcgacaagWtacttaagtcgKtgatccttNc +ttatagMatHVggtagcgHctatagccctYttggtaattKNaacgaaYatatVctaataM +aaaYtgVtcKaYtaataacagaatHcacVagatYWHttagaaSMaatWtYtgtaaagNaa +acaVgaWtcacNWgataNttcaSagctMDaRttgNactaccgataMaaatgtttattDtc +aagacgctDHYYatggttcaagccNctccttcMctttagacBtaaWtaWVHggaaaaNat +ttaDtDtgctaaHHtMtatNtMtagtcatttgcaaaRatacagRHtatDNtgtDgaatVg +tVNtcaaatYBMaaaagcaKgtgatgatMgWWMaHttttMgMagatDtataaattaacca +actMtacataaattgRataatacgBtKtaataattRgtatDagDtcRDacctatRcagag +cSHatNtcaScNtttggacNtaaggaccgtgKNttgttNcttgaaRgYgRtNtcagttBc +ttttcHtKtgcttYaaNgYagtaaatgaatggWaMattBHtatctatSgtcYtgcHtaat +tHgaaMtHcagaaSatggtatgccaHBtYtcNattWtgtNgctttaggtttgtWatNtgH +tgcDttactttttttgcNtactKtWRaVcttcatagtgSNKaNccgaataaBttataata +YtSagctttaaatSttggctaaKSaatRccgWHgagDttaaatcatgagMtcgagtVtaD +ggaBtatttgDacataaacgtagYRagBWtgDStKDgatgaagttcattatttaKWcata +aatWRgatataRgttRacaaNKttNtKagaaYaStaactScattattaacgatttaaatg +DtaattagatHgaYataaactatggggatVHtgccgtNgatNYcaStRtagaccacWcaM +tatRagHgVactYtWHtcttcatgatWgagaKggagtatgaWtDtVtNaNtcgYYgtaaa +ctttaDtBactagtaDctatagtaatatttatatataacgHaaaRagKattSagttYtSt +>THREE Homo sapiens frequency +agagagacgatgaaaattaatcgtcaatacgctggcgaacactgagggggacccaatgct +cttctcggtctaaaaaggaatgtgtcagaaattggtcagttcaaaagtagaccggatctt +tgcggagaacaattcacggaacgtagcgttgggaaatatcctttctaccacacatcggat +tttcgccctctcccattatttattgtgttctcacatagaattattgtttagacatccctc +gttgtatggagagttgcccgagcgtaaaggcataatccatataccgccgggtgagtgacc +tgaaattgtttttagttgggatttcgctatggattagcttacacgaagagattctaatgg +tactataggataattataatgctgcgtggcgcagtacaccgttacaaacgtcgttcgcat +atgtggctaacacggtgaaaatacctacatcgtatttgcaatttcggtcgtttcatagag +cgcattgaattactcaaaaattatatatgttgattatttgattagactgcgtggaaagaa +ggggtactcaagccatttgtaaaagctgcatctcgcttaagtttgagagcttacattagt +ctatttcagtcttctaggaaatgtctgtgtgagtggttgtcgtccataggtcactggcat +atgcgattcatgacatgctaaactaagaaagtagattactattaccggcatgcctaatgc +gattgcactgctatgaaggtgcggacgtcgcgcccatgtagccctgataataccaatact +tacatttggtcagcaattctgacattatacctagcacccataaatttactcagacttgag +gacaggctcttggagtcgatcttctgtttgtatgcatgtgatcatatagatgaataagcg +atgcgactagttagggcatagtatagatctgtgtatacagttcagctgaacgtccgcgag +tggaagtacagctgagatctatcctaaaatgcaaccatatcgttcacacatgatatgaac +ccagggggaaacattgagttcagttaaattggcagcgaatcccccaagaagaaggcggag +tgacgttgaacgggcttatggtttttcagtacttcctccgtataagttgagcgaaatgta +aacagaataatcgttgtgttaacaacattaaaatcgcggaatatgatgagaatacacagt +gtgagcatttcacttgtaaaatatctttggtagaacttactttgctttaaatatgttaaa +ccgatctaataatctacaaaacggtagattttgcctagcacattgcgtccttctctattc +agatagaggcaatactcagaaggttttatccaaagcactgtgttgactaacctaagtttt +agtctaataatcatgattgattataggtgccgtggactacatgactcgtccacaaataat +acttagcagatcagcaattggccaagcacccgacttttatttaatggttgtgcaatagtc +cagattcgtattcgggactctttcaaataatagtttcctggcatctaagtaagaaaagct +cataaggaagcgatattatgacacgctcttccgccgctgttttgaaacttgagtattgct +cgtccgaaattgagggtcacttcaaaatttactgagaagacgaagatcgactaaagttaa +aatgctagtccacagttggtcaagttgaattcatccacgagttatatagctattttaatt +tatagtcgagtgtacaaaaaacatccacaataagatttatcttagaataacaacccccgt +atcatcgaaatcctccgttatggcctgactcctcgagcttatagcatttgtgctggcgct +cttgccaggaacttgctcgcgaggtggtgacgagtgagatgatcagtttcattatgatga +tacgattttatcgcgactagttaatcatcatagcaagtaaaatttgaattatgtcattat +catgctccattaacaggttatttaattgatactgacgaaattttttcacaatgggttttc +tagaatttaatatcagtaattgaagccttcataggggtcctactagtatcctacacgacg +caggtccgcagtatcctggagggacgtgttactgattaaaagggtcaaaggaatgaaggc +tcacaatgttacctgcttcaccatagtgagccgatgagttttacattagtactaaatccc +aaatcatactttacgatgaggcttgctagcgctaaagagaatacatacaccaccacatag +aattgttagcgatgatatcaaatagactcctggaagtgtcagggggaaactgttcaatat +ttcgtccacaggactgaccaggcatggaaaagactgacgttggaaactataccatctcac +gcccgacgcttcactaattgatgatccaaaaaatatagcccggattcctgattagcaaag +ggttcacagagaaagatattatcgacgtatatcccaaaaaacagacgtaatgtgcatctt +cgaatcgggatgaatacttgtatcataaaaatgtgacctctagtatacaggttaatgtta +gtgatacacaatactcgtgggccatgggttctcaaataaaatgtaatattgcgtcgatca +ctcacccacgtatttggtctaattatgttttatttagtgacaatccaatagataaccggt +cctattaagggctatatttttagcgaccacgcgtttaaacaaaggattgtatgtagatgg +taccagtttaattgccagtgggcaatcctaagcaaaatgagattctatcctaaagtttgg +gcttgatataagatttcggatgtatgggttttataatcgttggagagctcaatcatgagc +taatacatggatttcgctacctcaccgagagaccttgcatgaagaattctaaccaaaagt +ttaataggccggattggattgagttaattaagaccttgttcagtcatagtaaaaaccctt +aaattttaccgattgacaaagtgagcagtcgcaataccctatgcgaaacgcctcgatagt +gactaggtatacaaggtttttgagttcctttgaaatagttaactaatttaaaattaatta +acgacatggaaatcacagaacctaatgctttgtaggagttatttatgctgtttactgcct +ctacaaccctaataaagcagtcctaagaatgaaacgcatcttttagttcagaaagtggta +tccagggtggtcaatttaataaattcaacatcgggtctcaggatattcggtcatataatt +tattaagggctcttcgagtcttactctgagtgaaattggaaacagtcatccttttcgttg +tgaggcatcttacaccgctatcgatatacaatgcattccaccgcggtgtcccgtacacaa +ggaaacttgttaccttggggatataagaaaactcacacgtctcattattaaactgagtac +aatttttgcacgagaaagtaatgcaatacaatatgatgaaagccagctaatgaaaaggga +tggaacgcacctcggatctgttgcactggattaaaatccgattatttttaaaaatattca +gtgctagagcatatcaggtctacttttttatctggtatgtaaagcccacggagcgatagt +gagatccttacgactcaacgaaaagttataacataactcccgttagccaaagcccaatcc +cgattactgccctaccctaacgtctgccatctaaatatcgaacttgttatgatcaatgtg +actacctcccaccctttccccttcatttgttccactggggataagctagcgttttcagaa +tcaatgcaataagaatagccaattgtctcacttcatcagagctcttggcaattccaggcg +ctacgtggttctggaatatattcatttttcaaatagtaatacgtttagtgttgctattgt +ctacacgtttggatattacgttatgtgagcggacatcaatagttgtctaactctttagta +agccagagatagcactcttagcgaatggataccatcttccataagtttagttaatagtcc +gaaacaactgcttcgagcatatttgaacctccttgtaggcaaatagcctcttcaaagcaa +tcttactaatagatagagtttgttttaagggactactagaaatgggacaatcttaatagt +atgacctaaactgacatttaaagatatatccaggtggcaagcataaagatcattgcgcca +cctccaccgtgggattacttatcagtcgatatcctatatgctaagtttgcgacggcagaa +tacaaactaagctgagttgatgctaaccttacctatgataccccattggaccggttaaca +gccctacttattccaaataaaagaacttttatgctgtagaagctattatagtgatgcctg +gtaacttcagtatattaaaatgacacacatacgccatatagagctcctggaactttgaat +aatgagcgaacttcgaagttgaagagcaagaaaccatatgtcacggttgcctaaagcccg +gtaaccagacatgtgctatcattgatcattatcgaggttttcataaccttgacccattat +cggctgtgcgcggacaagtacttaaatcactagtttcttcacctgcttatcggtaagaaa +taaggttggcaaagaatcgcataagacggacgtagagccgcagcgttgtgcgagtccagg +tgcatgcgcagcaataggattttaaattttgttccatttttaatttagccgtaaggatgt +ccgtaaatgattgaaaattggattcaatctttgggcctatgctactggaacctgatcgac +aaaatttcaaacatacgttaactccgaaagaccgtatttttgcggctagaatagtcagtc +gcttggagccatataccttaccacttaaacgacgtgctcctgtagttgaaatataaacag +aacacaaagactaccgatcatatcaactgaagatctttgtaactttgaggcgaagcaccc +tcttcgagacaactaagagtaaagtaccgggcgccgcaaggagtcgattgggaccctaaa +tcttgacgaattgctaagaggctcagagctaccactgtaatttctctagagcccataata +aatgaacgatacatccgtaggtagcacctaagggattataatggaagccaaatgcagtta +ataatattatatactggcgtacacgattcgacggatctctcacatagtgattcacgaccc +ccccctttgattgacacagcgtcagcattttgcaagaacgatcttctgcatagggtgcgc +caccgtaaggatgacgtcgaagctacaactgggtataatttaccatgcttccctgatgct +gagtgcaatacactaagaatgagtttttaccccatatcaccagtatttgttctgttattg +cgaagaaatggctatgctgagttggcgactaaagtcacccatcctttttattaggtaacc +ccctcccttaaactaactgatttgctggagctgccctgcatacatatactttatcattta +tggacgtccgtgacgcttattatccaccatagtcgatatgctacacggattcattaatgg +atcgtaggagtttaagttatatttactaagatcggtctcggctactatcccgccttaccc +ggcgctatttacggccatttttaatatattgacggtaattattcctatggtttcgaccgc +acgtccttggacaagaaagaatggcaaaaaaaatgtaaaagaaaaaaaatattgagtccc +taccatcatataaaaaatatgtgatgagtaacttgacgaaatgttagtggttattaaaga +ctatctattacaccttttgttttctgtcgtagtatattaaagtctagaagccttacagga +aaatcagggttatacagccgatactccgcagcatgaatcatcgaggaggtgtcctaccat +cgcgccttgtaatcttgtctgtgtatactgtatttagaccttttatacaaagtaaatatc +tcggctttatgtgattgggaggggcctactcaaacatgatgacttgacctaataatcact +gtgcgggcgtcttatgactagctattccttgaaatccaccaccaaatggttaatatgtaa +aaactttgacgatgaaacaaggtgaatgtgtagttactttgtgtaattagctgcgtcgag +cattgcttgtaaaaccgtcaatcgcacacgttacttccataaaatttctacgaatacacc +cttcttaaaaaaaacgtaggaattcacgagtttaacaaacgataactgtataaagtggaa +gtccgaagaaagcagatgcccgaactactcgaagatgtttcgttttcttaaccatagggg +cttcttaatggcccactacgcacattttgttcaagcccgagagggacatccccattacgg +gagtattactaaaactgttccgtaatacgttcagcaagggatgaaaaaggccactgctca +agttattgacgtgggagtattacatcggaagcctgaatcccacactatgatggtctgtac +aggcctagggactgcgtctagacggtattaccggcttctaatcatacgatcgtgagtctt +aacgggaagtaaggctcacacctaccccaaaccatttatctatgtaagtataaaattgtg +cgtaagtgttcaaagtggacaataaagacgtggcaaaaacccccgcacataagccgcttt +agatttcacaaataccaatgcggttaaaaacatccttgagtcgtacatacaccatactcg +cgttaaacggatataacagaagataataaatccggatgtggagtcggtgtaactatagaa +agccaagtgaaataatgcttaccagtcatttagctatacggctttcatttcatgtcaaga +gggtggagtttgacctgtacagttgatatatcaccgatacttagaactcacctaaagcta +aaattgctcgcagcgtgtaatccgcatattacaaacaatagatgggattcattatacata +agacacgatgatctgctttttcaggttgcgagatgttgcctatcgtcaatcgagtcctgc +cttacaccacttaaacaaaagtattgacagggaacctattttcgaggtattatatagtcc +agcttgaatatcaatttgacagttaacctagtgaaaatcagtaagaggaaatacgccaca +ttctccagtgaaattctacgggttatcgtctagtccaactatcaattataactcacgaga +tataagtaaattctcgtacttggcctgatttttattatactttggatccttagtaaacag +gaagggagaaaccttcaacgaaaaacactggattttgttttactctcaaagctcttatat +gacggaaataccctgtcaagtcttaactttattactagactaatgaaatgggcttggggt +ggccagaatcatagtacaatttagcggatacactattcggactttcctatcggctgtctg +gttggataagtatggggactaataggctagacatacctatacttaaactatacaggcgtc +atctatctctgcaactttggagttccctgatgttctcccgccctttgggttcacatcttc +tataccgacacccctaataacgattagtttgtgggttagagtaaattaatacggttaata +ttaatgtatcgttgaaaagctggtgtcgccaataaggtaaccggctaggcagagtatatg +tcacgaagtataactaccctaatgataagctgtaggaataaaattaatgctgtctctaag +cgaagagatatttccgactctgttttaatgacgaatctcattacttctgacttgcaaatg +ttcaatatggcacggtttcacggcacctttgtgacgcatataatgaacttagaagattat +aacgacggaactttatatgataatccgttacgattaaagaatctgttaaatatcataatg +gcattcagttctagaccgtgcatcatggtaaacttactttctctgcatggcgacatacat +ttcgctattcaaattcgcgtgtggttacacccactcgcacctttggaatattaagagaag +atgatcagaaaatccattcgctcaatttttctgacgtacgtctaatttatcctaggagac +aaatcgttttatgtctctcacatttttgaagaaaggttcgagagacaatactcaggtcct +gaactgctagaagatactcggtggagcgtggcaacaatgaaaaactcgtgacataaatga +atgatacttttccaagttcagttaagtgaatatgtttaacatacccggcttttcgatctt +aagctgacgctggacgtgcgagtaatgtcagtctcttacatacactagtgactccaagtt +tcgtcaaaaacgccccctcccttctcgagcccactcacgctatgtattgacgcgaacttg +ttcgggatcagacttttcaggagttcggtcgcgtgtccctatgtgctaatatataagtta +gatcgcattagatgctaatctgaatacttatagacgaccttcaacgagaacgggtaccac +cttgaggctagagttaggtgtgaaacgacaggtagggacatataaaatttgagtgcggct +ttagttaagggtttaattacctactcaaacatcacgctcgcgcccttcgtacgtaatcga +ccatctagaggctaaggggactgtactaggtagtgattaatgatatcctagacgcacgtg +ccttagatcttcagactctgatggtccgcgatcaccgtaattgtagtcctccaactcgat +cactttgttggcgtcaaagaaattacgatatctaaatacttataatacaataaccaagga +tgagaatgactcatcgcgttggagttatattgcttgaagttctatggaatgaaagcacgt +tatctgccgtcccaatatctccagtgagctaattcattggacggtccactttgatcaatc +cccgaggagatgttcggacactttagtctgtaacacttagcgttgagaccacgaacaatt +gattactcagtcttgaaggtgttttccaaagttcattttaaataagactacgataggcct +ttcctattgatataaactacccggctctgttgttcgtgtgagtcgtacttctctgtgttt +ttctgattatagcaagattcgattcttagtgtaaacagcgatttttatttgacccgtcaa +tgagaagcgcataggatctaagcaaaattatcaagttgtgccacaaggtaagatctttcc +agttattgcaggtaggatgtatcccacgttgatagtatgaggtctgacgtcaactgtcta +ggagagttgaccgcgtgcgggtacaccggatttgcatcgatgttgagaacgcagaactcc +cactgtcgtggcggcgttcctgatatttagcaagaggcgttgataaagccctcatcatct +agatctcgacctcatctgccctcttgctccatcattttctacacagactactttcctatc +tacgttagtataattgctttctatcttagtatcatttagagcttctccgtcaacaggttc +gtgctattaaagttagtacgaaagggacaacttgtagcaacgcatttaatcggttttcga +ctacttcgcacaaaatcagataaagaagtttgtcattctattagacattgaattgcgcaa +ttgacttgtaccacttatgatcgaacactgaatcaagactgtgattaactaaaatagaca +agccactatatcaactaataaaaacgcccctggtggtcgaacatagttgactacaggata +attaattggactggagccattacattctctacaatcgtatcacttcccaagtagacaact +ttgaccttgtagtttcatgtacaaaaaaatgctttcgcaggagcacattggtagttcaat +agtttcatgggaacctcttgagccgtcttctgtgggtgtgttcggatagtaggtactgat +aaagtcgtgtcgctttcgatgagagggaattcaccggaaaacaccttggttaacaggata +gtctatgtaaacttcgagacatgtttaagagttaccagcttaatccacggtgctctacta +gtatcatcagctgtcttgcctcgcctagaaatatgcattctatcgttatcctatcaacgg +ttgccgtactgagcagccttattgtggaagagtaatatataaatgtagtcttgtctttac +gaagcagacgtaagtaataatgacttggaataccaaaactaaacatagtggattatcata +ctcaagaactctccagataaataacagtttttacgatacgtcaccaatgagcttaaagat +taggatcctcaaaactgatacaaacgctaattcatttgttattggatccagtatcagtta +aactgaatggagtgaagattgtagaatgttgttctggcctcgcatggggtctaggtgata +tacaatttctcatacttacacggtagtggaaatctgattctagcttcgtagctgactata +ctcaaggaaccactgctcaaggtaggagactagttccgaccctacagtcaaagtggccga +agcttaaactatagactagttgttaaatgctgatttcaagatatcatctatatacagttt +ggacaattatgtgtgcgaaactaaaattcatgctattcagatggatttcacttatgcctt +agaaacagatattgcccgagctcaatcaacagttttagccggaaacaatcgaagcatagg +gacaatgtatcttttcctaaattgccatgtgcagatttctgagtgtcacgaagcgcataa +tagaatcttgtgttgcctcaactcgttgaaaagtttaaaacaatcgcagcagtctttttg +gggtctactgtgtgtttgcaaaataactgaaagaaacgcttgaacaactctgaagtagct +cgagtactcattaaagtgtaacacattagtgaatatcggccaatgaaccaaacgcttccc +ggtacgctatctctctcatcgggaggcgatgtgcaggttatctacgaaagcatcccttta +cgttgagagtgtcgatgcatgaacctcattgtaacaatagcccagcaaattctcatacgt +gcctcagggtccgggcgtactcctccatggaagggcgcgcatctagtgttataccaactc +gctttttaactactatgctgtagttctacaggcatagtggccagtattttctaacttctc +tggatagatgctctcactcctcatccatcacggcttcagtttacgtcttacttgcttgtt +cagcaacggatggaggcattaagtatcttcactgttccctaaaattgctgttcaatatca +aagtaaggacgatacagggaaagctcaagcacactcattgaatactgccccagttgcaac +ctcacttaatctgacaaaaataatgactactctaagtgttgcggaagcagtctcttccac +gagcttgtctgtatcacttcgtataggcatgtaactcgatagacacgaacaccgagtgag +aaactatattcttgcttccgtgtgtgtgacaccaggtaattgatgcggatataagctgga +gatcactcacgcccacacaaggcgctgctacctctttattccaatgtgtaagaatttgct +aacttcatttctagaccgcagctttgcggtcataatttcacggtacggacccttgggtta +gagacttgataacacacttcgcagtttccaccgcgcacatgttttagtggcttctaacat +agaatttttgttgtgacataaagagtgcgtgggagacttgcccgaccgttaagccataat +caattgaaagccccgtgagtcacatctaattggttgtactgcgcatttagctatccttta +gctgactcgaagagattcgattcctaatataggttaattagatggctgccgcgcgaagta +aaacgtgaaaaacgtagtgcgcagatctgcataactcgcgcttaattacttatgagtagt +tccaagttcgctacgttatgagagagattggaattaagcaaatatgttttatggtgattt +tgggatgagaaggactgctaagtacggctactaaacaaatttctaaaaccgccatctacc +ttatcttggagacatttaagttgtatatgtcactagtctagcttttgtctgtgggacgcg +ttctcggaatgagggaaatgcaagagccgattcatcaaatgcttatctaagaaagtagtg +gactattacaccaagcacgaatgccagggaactgctttcttgctcaggacctcgcgacaa +ggtaccccgcataagtcctagaattacatttggtcagcaatgctgacatttgaccgtgaa +aacataattttaatcagaaggcagctcacccgcttgctctagatcttatctttgtatgaa +tgtcagaatttactgcaatatccgttccgaatagtgagggcttagtatagttctctgtat +acaggtcacatcaaactccccctgtcctagtacagctctgagctttaattaattgcatac +atttccttcaatcatcagatgaaaacaccgcgaatcatgctcttctcgtatagggcaaga +gaagcaacaaacaactagcccgactcacgttcatccgccgtatccttgttcagttcttac +tccgtattaggtcagcgaaatctaatcagaataatcggtcgcgtatcaaaattaaaatcc +cgcttgaggttgacaattaaaacgctgagcagttatcggctattagatagtggggtgaaa +gtaattggctggaattatgttaaaacgtgatattaagctaaaatacgctacttgttgccg +acctaattcagtcattcgatattcagttagagccaagaataacaagcttgtataaattga +acggggtgcactaaacgatgtgttactctaatattcagcttggagtatacctgaaggcga +attcatgtatcggccaataataagacgttgaagatcacaatttggactagcaaaagaagg +tgatttatgcgtggggattgagtccactgtacgagtacggtctctggaaaattataggtt +cagggaatataaggaagtaaagataattaccaagagatttttggtatcgctatgacccag +aggtgttctaacgtctgttttgatccgcagaatttctgcctcaatgcatatttgacggac +ttgaactagagcctctaaagttaaatggcgacgcaactgttcctaaacttcaattattac +tactctttttttcctagggtattgtagaggccagtggacaaaataaatcaaatttaagat +gtttcggacattaacatcccccgtagcatagaaatcatcagttatccaatctctcatcga +gcttttacaatttctgctggcgctatggacagcatatgccgcgagacctccgcaagactc +acttgatcactgtaagtatcttcattagaggttagagcctatagttaagctgctgaccta +gtaaaattggtattttctaattttattgctcaagttaaaggttagtgaagggataatgac +gttatttttgaacaatgggttgtattcaattttatatcacgaatggaacccttcattccc +ggcataatactagacgacacgaacaagctccgatctatcagccaggcacgtgttaaggtt +taattccggcaaaccaatgaagcatcaaaaggtgacctgatgcaacttagggtcacgatg +agtttttcaggactacttattacctattaataagttaacatgagccttcataccccgtaa +gacaatacatactccaccaattagaattctgagccatcttatctttttgtatcatcgaag +ggtatggccgaataggttaattagttactcctaacgtctctacaggcatgcatttgacgc +accttcgaaaatagtcaatctctcgccacacgcgtctagtatgcagcatcaaaaatatag +tccacggtttccggattaccaaacgcggcaaagagaaacattgtatcgacggagataact +taatacagaaggaaggggcatcttcgaatacggatgaataattctatctgtttattctga +catcttgttttcaggttaatcttacgcattcaaatgacgcctgccccatgcgtgcgcaat +tattttctaatattgacgagagcaatctcactccttttgggtctatttatgttttattga +ggcacaagcctatacagaacaggtactattaaggccgtgagtgtgagactcaaaccgtgg +aaacaaaggatgggttgttcttggtacaagttttagtgcatgtgggcaatccttaccaaa +atcagatgctatccttaactttgggctgcatttaagatggcggttggaggcctgtgagaa +tcctgcgtgtcatctttaatgaccgaattcatccatgtagattcagatcacacactcatt +ccttgatgttgtctaaacaaaagttgttgtggacgcattggagggagttaagtaacaact +tgggatcgcatacttataaaaattatatgttaaactttcacaaacgctgaagtccaaagt +aactagcccaaacgcctcgagagtcactaggtattaatggtgtttgagttcctgtgaaat +agtgttcgaaggtaaaatttatgtaccaaatcgaaagaacacttaataaggcttgcttgc +acggaggtatgatgtttactgactctacaaccctaattttccagtacgtacattcattcc +aataggttagttctcaaagtgctatacaggctcctcaattgatgatatgcttcagccgct +ctatggatattagctcattttatttaggaagcccgcttagaggcttactatgagggaaat +gccaaaatgtcatacttttcggtgtgtcccatatgacaccgctttacatagaatttgaat +taaaacgcgctctcccgttcactaccatacttggtaccgtgcgcatattacatatagata +taggatcattttttaaagctgtactaggtttgatcgacaatcttatgctatactatatga +tgtaaccctcataatcaataccgatcgtacgatcctagcataggtggcaagcgattttat +gccgattattgtgttaaatagtctgtgagtgtgattatcagggctacgttggtagagggg +ttgtatagacctcgcacacattgtgacatacttaacaatatacgaaaactgatataataa +atccccttacccaaacaccaatcccgttgaatcaactaccataacgtctcccatataaat +tgcctacttgtttgcataaatctgaatacataacaccattgcaccttcttgtgttccaat +cccgttaagattgccttgtcagatgatatgcaagaacaatagcatttgctagcaattatt +aacagctcttcgaattgcctccacataacgcgggagggtatattttaatttggcaaatac +taagtactgttggcgtcatatgctattaacggttggatattaagttatgtcagccgtaag +caagagtgggcgaaatattttgttacccagtgagagcactcttagagtttggatacaata +ggccatatgttgacttaagaggacgtaactacgccgtacaccattgttcaaccgacttct +tggcaaatagaatcgtattagcaatcttaagaatagagacacgttcgtgttagggtatac +tacaaatccgaaaatcttaagaggatcacctaaactgaaatttatacatatttcaacgtg +gatagatttaacataattcagccacctccaacctgggagtaattttcagtagatttacta +gatgattagtggcccaacgcacttgactatataagatctggggatcctaacctgacctat +gagacaaaattggaaacgttaacagcccttatgtgtacaaagaaaagtaagttgttgctg +ttcaacagatgatagtcatgacgcgtaacttcactatagtaaattgaaacaaatacgcaa +tttagacagaatggtacggtcatgaatgacagtaattcgaagtgctagaccaacttaaaa +taggtaaacgtgcccgaaaccccccttaacagaaagctgctatcatggtgcagtatcgac +gtgttcagaaacttgtaacttttgagcaggtccgagcacatggaagtatatcacgtgttt +ctgaaccggcttatccctaagatatatccgtcgcaaactttcgatttagtcccacgtaga +gcccaagcgttgtgcgactccacgtgcatgcccagaaatacgagtttaaatttggttaca +tggttaattttgaccgaagcatcgcactttatgattgataattggattcaatatgtcgcc +ctatgcgaatgcaacatgatccacaatttggctataagacgtttaatccgtatcacactt +tgtttgcggctagtatagtaacgcccgtgcaccaagagtcagtaacaattataagtactc +cgcaggtacttcaaatataaaaactaatcaaacacgacccatatgatcatctgaagatat +ttggaactttctcgacaaccaccctcgtactcaatacttacactaatcgacaggcacacg +caacgtgtacagtcgcaccatattgagtcaagatttgcttagtggcgatgagcgtacacg +cttatttctctagtcacaattagttatctacgagacatcacgagggagcaaataagcgat +gttatggctacacataggcacgtatgaatatgatataagccagttaaacagtcgaaccat +cgagcaaattctcatgcaccaacccacacgttgaggcacaaagagtaagctgtttgaatg +taacttcttctgctgagcgggccccaacgtaaggatcaactagaagagaaaactcggtat +tagtttaaatgcgtcacggagcatgagtgcatttcactaagaatgtctgtgtaaccaata +taacatctatttgttatctgattgcctacttatggctttgcggtcgtggcgactaatgtc +tccaatccttttgaggtcggtaccaactccctttaaattacgctgtgcaggctcatgcac +tgcatacatatacggtagcaggtagggacctcacgcacccttattataatcaatagtagt +tatcagtcaacgaggcaggaatgctgaggtcgaggtgttggtatattttctatgtgccgt +ctaggcgactatcacgcattaccaggcgagatttaagccaattttgaatatagtcaacgt +aatttttactatgggttccaccgaaacgccttgcacaactaagaatcccataaaatatcg +atatcaaataaaagattgtgtcaataccttcatatatattttttcggttgactaacgtga +actaaggttaggggttttgtatgtctatataggaaacagtttcttttctgtcctacttta +gtaaagtcttcaagccttactccaaaatcacggtgattaagccgttactcagcagcatga +ttctgcctgctcgggtcctaaaatccagccttgtaagagtcgctgtgtattagctaggga +gacctttgttaaaaaggatatatcgcggcgggatgtgagtgcgtggcgcatactcaatct +tcagctcgtgtcattataatatctctcccccacgcttttcactagatatgccgtgtaagc +aaacaccttatgcttaatttcgaaaatattggtacttgaaaaaagctgtaggggtactta +atgtctggtaggagatcaggagagaattgagtgtaaaaccgtaaagccctcacctgactt +catgtaaatggcttagaagactccatgatttaataaatactacgaaggaaagactggatc +taaagataactctagtaaggccaactcccttcaatgctgttgccagttataatccaagag +ctgtccttttctgaaccatagcggcttctgaagcgaactagaagcaaagttggttctagc +cagacagccacataccctgtacgggtgtattactaaaactggtccggtattagttcacca +agggaggaattaggcaaaggatctaggtatgcaagtcggagtattacatccctaccctga +atccatcaataggttcctctgtactggccttcgcaatgagtattcaaggttgtacagccg +tataataataagatagtgactatgaacgggaagtaacccgctcaccttccccaaaacatt +gttatatctaagtattaaagtctgccgtagtgttaatactcgaaaataaacaactggcaa +attacaccgcacttaagccgcttttgatttatatttttccaatgcgcttttaaaaataat +tcagtcctacatactaattaagacccttaaacggagatatcacaagttaagttttaacca +tctcgactaggtggaactatagatacccaactcaatttatcattacctgtaatgttccta +gaaggattgcatttcatgtcaagacggtggagtttcacagcgaaacttcagtgtgaacag +attctgagaaatcacctaaacctattagtcagagcacccggttagaaccagttgtcaaaa +aatagagcggttgcatgagacagaagtaacgatgagatccgttgtaacgttgagacatct +ggcctatcgtcaatacagtcctcccttaaaaatatttttaaatactaggcaaacccaaca +taggttagtcctatgtgatacgccacatggtatatcattttgtaacgttacctagggata +atcaggaagtggaattacgcaaaagtagacagtgaaatgcttagggttatagtctagtcc +aaagataaaggataaagcacgtcagagaactatattagccgaatgggaatcattgttagg +agactgtggatcatgtctaaaaagcaacgcagaaacagtcatcgaaaaaatctcgttttt +gtttgaatctaaaagagctttgatgaccgatagtacctgtatactagttactgtattacg +tgtctaatgatttcggattggggtccccagaatcagacgtcattgtagacgattcaagtt +taccaatttaatttcccagctctccttggagaactatcgccaataattgcagtcactttc +cttttctgaaacgataaagccgtcagagttctctgcaacgttggacttacctgaggttct +aacccactttcggttctaatagtagttaacgacacaacgaataacctttactgtggggct +ttcacgatattttttcgcttattattaatggttacgtcataagctggtgtccaaattaag +gttaccggcttcgcagagtagttgtatccaagtataacttccctaatcataagatcgagg +tagaaaattaatgctgtctctaaccgaacagatatgtcccactatgtggtatggacgttg +ctaattacttctgaagggaaattggtcattatggatacgtgtctaccatcaggtcggacg +cagatatggttctgtcttcagttgatccaccgttctttataggataataactgacgatta +aagattatggtaaatagattaagccaattctcttcttgtcagtgaagcatccttaactga +cttgctctgcagcccctcatacatttagctattcaaagtaccggctcgtttcaaactctc +ccacctttggaagaggttgtcaacttgataagtatatcatttacagcattttttcggacg +tacctctaatgtttcattgcagaaaattagttttttctatcgcacattttgcaagtaacg +ttagagacacaattatctgcgaatgaactgctagatctgacgaccgggagcctcgcaaat +atcaaaaaagactgacatatatcaaggagtcgttgacaagtgctggtaagtcaattggtt +tatctgtcccggcgtttcgatcttaagctgaccatgcacggcagagtaatgtcactctcg +ttcttacaagtctgtctccaagggtcggcaaaaaagacccctccattctcgagcccactc +acgatatgtagggacgacaacttgtgcggcttatgaattgtctggactgcgggcgagggt +ccatatctccgaagttagaagggacatacctttagatgataagatcaattcttattgacg +aaattcatccacaacggggaacaacttcaccctagacttacgtctgaaaagacacctagc +gtcttataaaaggtcagtgccccgtttcgtaaggctggaattacctacgcaaacttaaac +ctcgcgcccttccttacgtatcgacaagatagaggctatcgcgaatgtactacggaggca +tgaatcatatactagaaccaagtgcctgtgatattaacaagatgatccgacgcgagcacc +gtaattctaggcataaaactccagcaatttgggggccgaaaacaaatgacgttagctaat +taattatatgacatgatcaaaggaggtcaatcacgcatcgagttcgacgtatattcattg +aacttcgtgcgtttgaaagaaacttttatgaaggcaaaattgatcctgtctcctatttca +tgcgtacctcctagttgataattccccgagcagtggttaggacacttttgtcggtatcaa +gttccggtctcaaaacgtaaaattctgtaatctgtatggatggtctgtgaattagttaat +ttttatgaagtcgtcgagacgcagttcctattgatttattctaaacggagatgtgcttcg +tgggactcggaagtagatctgtgtttatgattattgctactttagatgctgactgttaac +tccgtgttgtttttcaaccgtatatcacaaccgaattggatagaacctatagtttcaagt +tctgccacaaggtatcatatttacagttagtgctggttgcttctttcaaacgtggtgagt +ttgtgctatcacgtcaacggtagagctcagtggaccgagtgcgcgttcaaccctgttcca +gagagggtgtgatagcacatataccacgctcgtcgaggcgttcatgatagtttgcaagag +ccggtgttaaacacatattattattgttatccaactaatcggacctatgcataaagcatt +gtctaaacagaataattgcctatatacggtagttttagtgatttatatcttagtatcagt +tagagcttcgaactcttcaggttcctcatatttaacgttcttcgaaagcgaaaacttcta +caaacgaatgtaagcggttttccaagtagtacctataaatcacagaaagatctgtctcag +tatagttgaaatggtattcagctagtgacgtgtaccaattatcatagttcactcaagcaa +gacgctcattaacgaatatagacaagacactatatcatataataaaaaagaacatggtgc +tcgaacatagttgaattcaccatattgaaggggaatgctgacatgtaattcgctactaga +cgatcaattccctacttgtcaaagttgaactggtacgttcttggaattaaatatgattgc +gctggaccaaattgcgacttcttgagtttcagggcaaacgattgagccggaggatgtccg +tctcttacctttcttgcttatgataaacgacggtccctgtacatcactgggaattctcag +caaaaataattgggtaaatcgagactcgatgtattcggccacaaaggtgttagacgttaa +agattattcaacggggcgataataggatcataaccggtatgcaagcgcattgaaagagcc +atgagatccttatccgataaacgctgcacggtatgtgcagccttattgtcgatcacgaat +ttataaatgtagtctgggctgtaagttgaagacctaagttataatgaagtgcaataccaa +atcgattcatagtggattatcagactcaagatatctcctgataaattacagttgttaaga +tacggataaaatgagatttaagattagcagcctctaatctgtttcaatcccgttggaatg +tggtatgcgatcaaggttaagttaaaatcaagcctgtcttcagtcttgattcttgttctg +ccatcgcatgcggtctacgtgagttaatatgtagcttacgttctagcttgtgctaatctg +agtatagattcgtagaggaatattatcaagcttccacgcctcaacgtacgtgtattggtc +acacaagacactaaaagtggaagtagcgtaaactatagtctagttgttaaatgctcagtt +cttgttatattcgatatactcttggctaatttatgtctgagtatataaaattaatgatat +taacttgcatttcacggatcccttagaaaaagattttgaccgagcgcattataaacggtt +acaccgaatcaatagaagcatacccaatagctttctttgaatttattgcctgcgcaactt +ggctgactctctagatccgaataattctatatggtcgtgacgaaactagttcattactgt +ttaaaatgccaacatgtcttttgggccgataatggctctttgcaaaattactcaatgata +cgattgatcaaagcggtagttgctagtggtagcatgtaagtctatcaaatgtctgattat +ccgaaaatcttccaaaagagtccacgtaccatatctatctcatagcgacgcgaggggaac +cttatctaactatcattccatttaccgggtgactctcgatgcaggatccgattgggataa +attgcccagaaatggctcattcctgactaagggtaaggccgttctcagcaagggaacccc +gcgaatctaggcttataccatctagattgttaactacttgcctgtagttctacagccata +ctggacagttgtttctaaatgatcgggattcatgctagcactcctctgaatgcaccgcgt +aagtttaactattacgtccgtgggcagataaggatggaggctgtatgtatcttaactgtt +acctaatatggctggtaattatcaaagtaaggaccttaatgccatagcgctagcaatcgc +tttgtatactgaccatgtgccaacctctcttaatctgtaaaatataatgtcttagctaac +tgtggacgatcatgtctctgcctagagcttcgctgtatcaattcctatagccagcgtact +agtgacacaacaacaccgtgtgagaaaagatattagtccttacgtctgtctctctacagc +ttattgatgaggattgaacatggacatatagctccccctcaaaagcagatgctacctctt +tattccattctcgaacatttgccgaacttaatttcgacaaacctgaggtcacgtcttaat +ttatcggtaacgtcacgtccctttgagactggataaatatattaccaggggccaacgagc +aattgttggaggcgcttctataatacaaggtgtcttgtcaaagaaagacggcgtgcgtct +cgtgcaactcacttaaccaatattaatgtgaaacccccctctctcacatcttatgcggtg +tactgccctggtacatttcctgtacaggactccaacagtgtagattcctaagatagctgt +tggagttgcctcacgccagatcgaaaaactgaataaactagtgagctgagctgcagaaat +accgcttaattacttatgactagttcaaagggacctacgtgatgtcagacattgcaagga +agaaattaggtttgtgcgtcattttggctggactagcactccttacttcccctactattc +aaatgtcgtaaacagcatgagacaggatcgtgctgacatttaaggtctattgggaacgag +gctacctttggtcgcgcgctcgcgttctccgaatgaccgaaatgcatgagcacagtatgc +aattgcttatagatctaaggtctggtcgttgaaaccaagcacgtaggcctgggaaatcag +ttcttcctcagcaactacacaaaagcgtccaagcattagtacttgtagtaaatgtccgaa +cctatgcgctcatttgaaagtcaaaaaatatttttaagcagtaggcacctaacccgattc +ctctacttagtagctttctttgattctcagaattgactgcaatatcactgcacaattctg +tgccattactagacttctctgtattaacgtctcatcttactaacactcgcctaggacaca +tctgagagtgaagtatttcaatacatttactgaaatcttcagttctaaaatccccgaata +aggctcttatcggtttggccaacacaagaaaaaaacttcttgcaccactcaccttcatac +gcaggagcctggggaacttagtaataactatttcggcagacaaagcttataacaagttgc +cggcgcgtataatatttaaaagaccccttgagctgctcaattaaaacgctcacctggtat +aggctattagatagtgccgtcttagtaaggggcgggaattatcggataaactgatatttt +gataaaataaccgacttgttcacgacataagtcactaaggagattttatctttctccaaa +gtatatcttccttggataatttcaaagcgctgcaatttaagttctgttactagtttatgc +tgctgggaggtgaccggaaggcgtagtaatctagaggcaaattataagaagttcatcata +tcattttcgactacaaaaacaaggtgttgtatgccggcgcattgtgtaaactggacgagt +accctagatggaaaattatacgttaagccaagatttcgatgtaatgataattacctacac +atttttgctatccataggaacaagagctgttctataggctcgtggcatacgaacatttgc +tgccgctatgaatattggaagctcttcaactacagactctattcttaattgccgtcgaaa +atgggccgaatcggctattattaatactcggtttttccgaggggattgttgtcgacagtc +gtaattattattaatattgatgttggtgaggtcatttaaatacaaccttgcagacaatga +ataagggatccaatctctcatactccttttacaattgctcatgcccctatgcaaacctta +tgccgccacacctccgcaactctctcttctgaactgtaagtagcttcattactggtttga +gactatactgaagctgatgacattctaaaatggctattttcgaatgtgattcataatgtt +tatcgtttgggatggcagaatcacgttatttttgatatagcccgggtattctattgtata +gaacgtatgctacaagtcattccccgaagaagactagaagtaaacaacatgcgaccatcg +ttaagccacgcaaggctgtagctttatttcccgataacctatcttccataaatagcggac +agcaggatactgacgctcaacatcagtggttatggtctaatttttaacttttaataaggt +aacttcagcaggcatacacagtaactctttaatttataatcaaattagaagtctgacact +tcttatatttttctatcatccaacgcgatcgcccattagcttattgtgttactaataacg +tatctaaaccaatccttttcaagctactgcctatattgtcaatatatacaaacaacagga +tagtaggctgcttaaaaaatattgtcaaccgtgtacgctttacaatacccggaaatcaca +aactttgtagacaacgagtgaaatttatacactacgaagggccagcgtacaagacccatg +aattaggcgatatgtttattctgacatattggtttatccttaatctgtcgctgtaaaatg +aagccgcccccatccctgcgaattttttttcgaagattcacgactgaaatataaatacgt +ttggctatatttatgttggagggaggcaatagcctttactgttaaccgaagatttagcca +gtgagtgtgacactaaaacactggaataaatgcaggcgttcttctgggtaaaaggtttag +tcaatctcgcctataagttcatatagctctggatataattatctggcccatgcatttatc +atggcgcttggtgccctgtgtgaagccggcctctcatattgaaggtccgaagtattccat +gtacattaagatcactctctcattcatgcatcttggcttaacaaatctggttgtccaagc +tttccaggcacgtatggtacaaattcggatcgaatacttataaaaatgatatgttaaact +gtctaaaacgctcatctacaaagtaaagtgcactaaccaatagagtctcaagaccgtgta +atgctggtgcactgaatgtgtaatacggttagaagggattagttatgttacaaatccatt +gaaaacttaagaagcattgcgtgctcggagggtgcatcttttatcaagagactaacatta +ttttcaacgacgtacatgctttacaatagggtacttatcaaacgccgagaaacgcgccta +tagtgatgttatgattatgacccgatatccattggaccgaattttatgtaggttcccagc +gtactcgcgtaatatctcggtattgccataatgtaatacttgtcggtctctcccagatga +aaaagcgttacagagtatttcaatgaaaaacagcgcgcaacgtcaatacctttaggggta +acggccgctgatttcatatagatatacgataagttggtatagctctactaggtggcatcc +acaatcgttgcatttactatagctggttacaatcataatctataccgttccttacatact +accatagcgggatagcgtttttttgccgttgattgggtttaagaggatgtcagtctcatt +atatccgattcggtgggagagccgttgttttcaaatcgcacactttgtgacataatgtac +aagataacaaaactgatataagatataaactgtcaatatcaccttgacacttgaatcaaa +gtaaattaactcgcaaatataatttgactaattgggtgcagatttctcaattaataaaaa +aatggcaccggatgggcttacaagccccttatcattcacttgtatcatgatttccaagaa +caatagaatttgctagcaagtatgaacagagattcgaattgcatccacagtacgccggag +cgtttattttaatgtggatatgacgatgtactgttggcggcatttgctagtaaccggtcc +ttatttacgtagcgcacacgtaagcatgtctgggagaaatatggtggtacaatctcagag +aaagattacagtttggtttaaataggacttatcgggtcggaagtggaacttaataagcag +tacacaattgggcaacagacgtcttgcctattacaataggattacaatgcgttagatttc +agacacgttcgtgtttggctattcgtcaattccctaaatagttagacgatcaactattat +caaagtgattctttgttcatcctccattcatgtaacagatggcacactacgcataacgcc +gaggaattttaacgagatttaagagagcagttcgggcacaacccacttgactttataaca +gctcggcagcataaacggtaatatgtgacaaatttccaaacgttataagaacgtatgtgt +acttagaaaactaagtggttcatgttcaacagatgtgacgcagcaagcctaacttatcta +ttggttttgctataaaagaacaaagttacacagaatcctaagggcttgtttcacacttat +gcctagtgcttcaccatcttaaaatagcgaaaccggcacgaatcaaaccttaaaacaatg +cgcagatattggtgatggtgactccgggtatgataatggtaactgttgaccagcgcccac +ctcatcgaagtatagaaagtggttaggataaggatgagaccgaacttatttccggccata +actttagattttctacctagtacacaacatcagggcggacacgaaaccgccatcacatca +tataccaggtttaatttgcttaatgggggaagtgtcaacgaaccttcgaactttagcagg +catatggccattatatatggccccagagcagaatgctacagcagacaaaatttggattta +tgtagtttaatacctatcaaacttggtgtgaccatacttgtctaacgacagtgcacaaag +tgtaagttacaattattactactcagcagcttctgcaatgataaaatcttatcatacacg +tcacatatgataatatctacttagggggaacgggctccacaacctacatagtactcaata +cttacactattcgacaggcacaccaaacctgtacagtcccaaaagattgagtcaactttg +cagtactgcagatcacagtaatagcttagttagcgagtcaaaattagttttctacgagac +tgcacgaccgtgcaaatttccgatgtgttggctacaaatagcaacgtatgaatttgtttg +aagccacgtaaactgtacaaccttagagataagtctcaggctactaaaaacacgttgtgg +cactaacaggatcatggttgattcttacttattcggctgaccggcccaataagtaacctt +caactagaacagaataatcgggagtagtttaattcagtcaaggtgcaggtctcattgtaa +ctaacaagctctgtgtaaccaagttaaaatcgttttcttagcggattccctacttatgga +tttgagctcgtccacaatattcgatacaagaagtttgtggtccgtaacaacgaaatttta +attacgctgtgcagcctcatccaaggaattaatagaaggttgatggtaggctccgaacgc +tccatgattataatcaagtggactgtgcagtaaacgaggaaggtatcctgacgtcgtggt +gttcgtttttgttatttgtgccctatacgagtagataaaccatgaacagcacagtgtgaa +cccatggttgattttaggctaccttatttttaatttccgttacacagaaacgaattccac +aactaacatgccattaatttttcgatatcttataaaagatggtcgaaattcattcattta +ttttttttcggttctcgaaagtcaactaagctgtcgcgttttgtttctctttagaggtaa +aagtggctttgatctcctacgtttggatactagtcaaccattactccatttgatccgtga +gtatcacctgtctaacatccagcattatgactcctcggcgaagaaaagacacacttctta +gagtcgatgtgtattagctagggacacagttgtttaatacgatagtgagcccagggaggg +cagtgcgtcccccagtagatttattcagctagtgtaagtataagatatctcacccacgag +gttcaagtgatatgcagtcttagaataatacttatcctgaatttcgatattatgggtact +tcaataatccgctagcgctactttatgtctcgttggacagcaggacacatggcagtctta +aacactaaagacatcacctgaatgaatgtaatgggattacaagaatcaatgaggtattat +atacgacgtaggaaactctggatatatacagtaatctagttacgccatcgcacttcattc +ctctggaaacttagaagacatcagctgtacgtggaggaaccagacccccgtatgtagcca +aatagaaccaaagttgcttatacaaacacacccaatgacaatggaccgctggagttcgta +aactcggaacgtagtactgcacaaacccagcatttagcaataggagctacgtatgcaact +cccacgtggtaataccttcaagctatcaatatataggtgcctagctaatcgcattcgcaa +gcagtattcaagcttgtaaaccagtataataattacagaggctctatgaaacccaacttt +ccagctaaaagtcccaattaaatggttatttcgtacttttaaagtcgcccgttctgttat +tacgcgaattgattctactccaaaattaaacacaaattatcaaccgtttcatttatattt +gtcaatgcagctgtttaaaataaggctctactaaattataattaagacacttattaccag +atttctctagttaagtttgaaccagctcgactaccgcgaaagatacattcccttctctat +ttttcagttcatctatgggtcagagaagcattgaatttattctattcaccctcgtcgttc +acagcgaatcgtcagtgtgatcagtgtatgagaaatatcctaaaccgtttagtcagacca +cacgcttagaacaagtggtctaaaaagactgccctggaaggagtaagaagtatacagctg +atccggtgtatccttcagtcatctgccctatactaattacacgacgcaaggaaaaatagg +tttattttctaggcaaacccttcataggtgactccgatgtgttacgaatcatgcttgaga +atgtgctatcgttaccgacggataataacgatctccaatgaaccaaatgtagaatgtcta +ttgattacccttttactattcgacttagagataggagatagaacctcagtgtactttttt +agccgaatgggaatctttgggaggtgaatggccataaggtcgtaaatccaaccctcttaa +agtcttccatattatatcgttgttcgtggaatcgataacagatttgttgacccatagtaa +atgtatactagtttatgttgtaagtgtagattgttttccgattgccgtccaaactttatg +tcgtaattgtagaccagtaaagttgaccaaggtaagtgcccagcgatcctgcgagatcga +tcgccaatttttccagtcactgtaagtgtaggtttagataaagccgtatgagttatatca +taagggcctcggaaagcagcttcgaaccaaagttcccttataatagtagtttaactataa +aagtatatactggtctgtcgccctttcacgatttgttttaccggtttatgaagcgttacg +tcattagagcggctccaatttaaggttaacggcttccatgtgtagttgtatacaaggata +acttaaagtatctgttcagcgagctagttaagttatcctcgatagaacacaactcagagg +tcccaagatcgggtttgcaacttgctaatttattctcaaggcaaattgggaattatcgat +acctgtataccataaggtcgctcgatgtgatgcttatgtcttctggtgatcctaccttag +ttagtgctgattaacggaacattaatgtttatcgttttgagatttagccaattctctgat +tctaactcaagatgccttatctgacgtgctatgcagcccctaagtattttacattgtaat +aggacacgctcctttaaaactcgccaaaaggtcgttgtggttctctactggttaactata +taatttacagctttgttgagctagttcctctttggtttaagtcctcaatattagttggtt +cgagcgataagttggctagttaccttagtcactatattagatccgaatgttatgcttcat +ctgaagaccgccaccctccaaaatttcttttaagactcacttattgcaaggtgtaggtga +attcggctcgtttctcaagtggtgtatctgtacacgagtttccatattttcatcaacagc +caccgcacacttatgtcactctaggtattaaaagtcgctctacaaggggacgcaattaag +aaacagacatgctagtcaaaaataaacatagcgaggcaccactaattcggccgcttatca +atgggatgctctgcgcgagacgcgccagagctcagtagttagttcggacatacatttact +tcagatgatcaattagttttctacaaatgcttactctaccccgaaaaaagtcaccagact +cttacgtctctttagtatccttccgtcttatataaggtcagtcccccgtttcggtaccct +ggaatttactaagaataatgaaacagcccccaaggacgtacgtttacaaatgatagacca +gatcgcctagcttattccgacgcatgttgcatagaattgaaccaacggaatgtgagagta +actagatgagccgaccacagcacccgtttgcgtcgcagaatacgcctgatagttcggcca +cgaaatcatatgtcctttgagtattaagtatttgtaatgatcaatcgagctcaagcaagc +ttacacttcctcggatattcagggaacttagtgcctttgaaagatacgttgatcaacgaa +aaattgataatggctcatatggaatgcctacctcatagtgctgaattaacacagcactgc +ggacctaacttttcgaggtttcaagttcacgtctcaaaacctaataggctggaatatgta +gggatcctcggtgaatttgtgattgggtttgttgtagtactgaccaagtgaatattcttt +ttttctaaaagcagatctgctgccgggcactacgaaggagatctctgtgtatcattattg +cttcttgacatgatgactcttaaatcactgtgggtgtgcaaaacgatagcacaacccaat +tcgatagtacatattgttgatacttcgcactaaaccgttcatatttaaaggttgtgctcc +ttccttcgttaaatactggtgacttggtcctatctactattagctagacctctggggaac +cacgcccccgtaaaacctgtgcaagagagggggtcatacatcttagacatcgcgcctcca +ccagggaagcattgggtgattgaccaggtgtgtaacaaatatgattattcttatactaat +attagcaaagatgcataatgatttgtattaaatgtataattgaattgataagggtctttt +agtcagtgatagagtagtataaggtagacattagaactcttaaccggacgcagatttttc +ggtcttagtaagccaattagtcgacaaaacaaggtaagagcggttactagtagtacctat +aatgcactgaatcttcggtcgaagtatagttctaatgctatgcagattgtgacggcgaca +aatgttcagacttatatcatgaaacaagctcttgtaagtattgacaaatgaaaagattga +atatttttaaatacaaaatgcgcctacttattaggggaattaaccagattgaaggccaat +cctcacatgtaatgagataatagacgataaatgaaattcttgtaatagttgaactgctac +gtgatgggtattatatatgattgagatcctccaattgccgacgtcttgtcttgatgccca +aaagattgtcaacgaggagctccctcgcgtacctgtcgtccgtatcataaacgacgcgac +atgtacagcactccgaagtataagcaataataatgcgggtaatccagactagatcttttc +ggactcaatgcggtttcacggtaaacatgattaataccggagagtagtcgagcttatcag +cgatgcaagcgaattcattgtgccaggagatacgttgcagataaaaccggcaacgtatgt +caacaagttttggcgatctcgttgtttgtattcgacgaggcgcgggaacttcaagaacta +tcgtatattcaagtccattaccttttagtttcagactggtggagctgactaaagttatat +catcattttgtacactggtttagttaacgataatttcagatttaacatgaccagacgata +atcgctgtatatccagttggaatgtggtttgccagaaaggttaacttataatcaagcctc +tcttcagtcttgattcgtcgtatcccatccattgcgctatacctcagtgtatttggagct +gtagttataccgtgtgctaagatcagtagacatgacgagagcaatattatctaccttaca +agcatcaacggacgtctagtcggaacaaaagactctaaaactcgaacttcaggttaatat +actatagttctgtattcagcagttattcttatattcgatattatcttgcctattggatgt +ctgactttagtatattaatcatagtatctgccatgtaaaggtgccagtactaaatctgtt +tcacagtgcgaattataaacggttacaaccattaaagacaacaagaccctatagctttat +ttgaattttgtcaatgcgcaacttggagctcgcgatacatcccaattagtctatagggtc +gggacgattctacggcatttctggttataatgacaacatggattgtggcccgagaatcgc +tctttcattaattaagcaatcattacagtcttataagcgctacttccgagtggtagcagg +taactcgatataaggtcgcatgagccgaatagcttaaaaaacaggccaccgaacattgat +agagaataccgaccacagcgcaacctttgattactttcattaaattgtacggctcactcg +acatcaagcttaagattgcgataatgtgaactcaaatggatcagtactgaagaaccgtaa +cccacttcgcagaaagcgtacccagagaagatacgctgttacaatatacagggtgaaatt +attgcctgttcttcgtaaccatttcgccaaacttggttagaaatgatagccattcatgat +agaaataagctgaatgataccagtatctttaactatgtagtcagggggaagataacgatg +gtccatgtatgtttctgatatgtgacagtattggccgcgtaatttgctaacgaagctact +taatgcctttgagcttcatatagatttctttaatcaaaatcggcaaaaagatagtatgag +ctataatatatgctagtagagaactctggaccatcatctatatgaatactgattcgagcg +tgcaattactttagcctgcgtactactgactctacaaaacactctgagataagtttgtag +tcagtaagtcgctctctataaaccttttggatgaccattgtacagccacttatagatccc +aataaatagcacaggagacagagtttttcaatgctcgatcatttgccgatagtattttcg +tctaacctcagggcacctattatttgatacctaacctaacggccctttcacaatggagaa +atatatgacatcgggacaaacacaaatggtgggtggccaggagatatgacatggtggcgt +ctctaagaaacacggactccctctaggcaaactcacgtaaccaattttaatgtcaaacaa +aacgctcgaaaagattttgccgtgtaatgacctggtacattgactggtcaggaatacatc +actgtagttgccgtagtgtcctgttggtgttccatcaagacacatcgtataacgcaattt +acgacggacatcagatcaagttatacagattatttaagtatcacgtgtgcattgggacat +aagggatctcacacatgccttggaacatttttgctttgtgccgctttttcgctgcactac +caatccttacttaccagtatattcaaaggtcgttaacagaatgagaaaggttagggctct +aagttatcgtcgattgggatagacgagacatttgcgagcgccctccacggatacgaatct +cccatatcaatgtgaactggatgctatgcagtttagttcttacgtctcctagtggtaaaa +atcaaagtagcactcgcatagcagttattcagaacctaatacacaaaaccgtcaaacatt +ttctaattctaggtatgggccgatcataggagctaaggtgaaactcataaatgttttgtt +agatctagcatcctaaaaagatgcatatactgagtagctggcgtgcattctctcaattgt +atcctttttaactgaactagtcggtcccatttcgtgactgagatctattaaccgataaga +ttaataacactcgcattcgtatcagctcagagtgaagtttttcaataatttgactgatat +attaacttctaaaataaccctttaagcctcggatccgtttcccaatcacatcaaaaattc +ttattccaactatctacggattaacaacgtgcatggggatcgtagtaagaacttgttccg +atcactttgagtatatcaagttgacggcccggttattattgaatagaaacattcacctgc +taaattaaataccgcacatcggatacccgatttcagagggccgtcttactaagggcaggc +tttgttcggtttaactgagatgttcattattttacagtatgcttcaactaatatgtaacg +aaggacagtggatctgtctccatagtagatcttcagtcgtgaatttcataccgctcctat +ttaagttcgcgttcgagttgttgatcatggcacgtgaaagcaacccctagtattctagac +gaaaattttttctagttcatctgataatttgccaattcaaaaacaaccgctggtttcccg +gcgcattctctaaaatggaagtcgaacctagagccattatttgtcggtaacccatgagtt +ccttcttttcagaagttaatacactgtggtcctatacagaggaaaaacagcggttatata +cgatcgtggcataacaacattggatcaagatagcaatttggctacctattctaattctca +ctagattcggtattccactacaatatcggcagattaggattggatgaataatcggtgttt +aagtccggttgcgtctccaatctcctaatttttattaatattgatcttggtgacctattg +taaataaaaacttcaagactttgaataacggtgaaaagatagaagactcatttgaaaatg +gatcatccacagatccaaacattagcaagacactaatccccaactagctattctgatcgc +gatcgtgctgcagtactcctgtcacaatagtctgttcatgatctaattctttttgggctt +tgttcgatggtgattcagaatctttatccggtcgcttccctgtagctactttgtggggat +attgcccggggattatagggttgagatcgtttcctaaaagtatttaaaccaagtagactt +caactaaactacatcagaacatcgtgaagacaccatacgcggtacctttatttaccgata +acatttcttcaagaaataccggtaagcagcataatgaccctaaacagctcggggtatcgt +cgtagttttaaattttatttaggttactgctcaaggaataaaaactaactatttaattta +taataatattacaaggctcacactgattagatttgtctataagacttcgcgatcccccat +taccggattgtcttaagaataaactagataaaccatgcattttctagataaggcctttag +tctaattagatacaaaaaacacgatagttgcatccttaatttattgtgtcaaacctggaa +ccttttaattacccgcaaatcactttatgtcgagactacctctgaaatttattatctacc +taccgcatgaggacttgaaccatcttgtaggagttatgtttattagctaagattcgttta +tcctgtagcggtccatgtatattcaacaagcaaaaagcactcagaattgtttttagttga +gtcaagactgatatataaataagtttccctagttttttcgtggtgggacgatattgaatt +gaatcttaaccgaagagtttcccactctgtcgcacaataatacacgccaatatttccagc +cctgcttatgccttaatcggttactcaatctcccattgaagttcattttgatctgcatag +aagtttcgggcccagccttttttctgccaccttcctccaagctctgtagacgcactctaa +gattgatgctcacatgtattaattctacattaacataaatatataagtcatgcatcttcg +agtaaaatatctggttctccaacatgtcctggcacgtatcgttataatgcccatacatgt +agtattaaaatgattgggttaactggatattaagatcatcgaaattgtaaagtcaaatta +acaatactgtctcaagaccgtgtattcctcgtgctcggaagggctattacgcttacttcc +gttttggtatcttaatatgactttcaaaaattaagttgcagtgagtcctacctgcgtgca +tcggttagcaagagtataaaagttgtttaaacgaactacttgctttacaataccggtcgt +atatatcgccgtgaatccagaagattgtcttctttggattatcaaccgagatcctgtgga +ccgatgttttgggaccttcacagaggactccaggtagagctcgcttttgcattaatctaa +gaattgtacctctctaaaagatctaaaacagtgaatgtgtatttcatggaaaaacacaga +gaaacgtaaattactttaggccgaaaggcacatgagttattatacatatacgagatggtg +gtatacatcgaattcggggcatacactatagttgcattgtatttagctgctttaaataat +atgatattaccttccttacataagacattaccggcataccctggttttcaacttgtgggg +ctttttgacgatcgcactctcatttgatccgagtagggcggtgacccctgcttttcaaat +acaaaaatttcgctatgaaggtaatagattacttttcgctgttatgatagaaacggtaaa +tttaaaattgaaacttctagaaaagtaaagtaacgagaaatgattttgtgaataatgcgg +tcatgattgcgcaagtaagaaaaaaaggcaaaaggatgcgcggaatagaaacttatcagt +cacgggtatcttgatttcattcttcttgtcaattgccgacataggatgaaatcagattcc +aatgcaatacacagtaacccccacccttgattgtaatgtcgatttgaagttgtacgcgtc +gacgaagtggatagtatacgggccttttgtacggtgcgatcaactatgaatctcggcgag +ttagatggtcgtacaatctcacacatagaggtcacttgcctgtaatgacgaattttcggc +taggtactcgaactttattagaagtaaaaatgtgggcaaaagaaggattccattttacaa +gacgattacaatgagttacatgtctctcaacgtagtctttccctagtagtctttgaacta +tttaggtactccagaaaattttagcaaagggtttctgtgtgaatccgccattcatgttta +tgatggaacaataagaataacgccctcgtatgttatcgacagtgaagtcagcagttcggc +caaaaacatattcaatttagtacagatccccagaagttaagctaagtgctctaaaatggc +ctaaacggttatcaaagtaggtctaattactatactaacgggtgcatcgtaataactgct +gtcgatgcaacactatatgatagtgtcgttttgctatatatgtacaatgtgacaaagaag +ccttagcgattcttgcaaacttaggacttcggattctcaatcttaaatgtccgaaaacgc +aaagattcaaaaatttaatctatgagcagatatgcctgatggtgactacgcgtatgttaa +ggctaaatgttgacaaccgcacacataatcgaactattgatagtcgggagcataaccagg +tgaacgtactttgttcacgacatttattgacatgttctaaatacgtctcaaaatcacggc +gcactagaaaacgcaatcaaatcattgtcctggtttaagggccgtaatgccggtagtgtc +aaacttcatgagaactttagctggcttttggccagtatttagggaccaagagcactagcc +ttaagctgaatattttgccatttatctactgttataactttaaaacttggtggcaccaga +cttgtcgatacacacgcatcaatctgtaacgtaaaaggtttactaagaacaagcgtagga +attgagtttatattatatttaaactaaaagatgatattagcttctgagggcgatagggct +ccaaatcataaagaggaatatattattacacgattagaaacccacaacatacctcgaatc +gcccaaaagtttgacgaaacttggcagtactccacatctcagtaatacagttgggagagt +ctcaaatgttgttttattactcaatgaaccaccctcataatttcactgctgttccattaa +atttgcaaacgatcatttgctttgaagaaacgtaaaatcgacaaaattacagataagtag +atgcataataaaaaaaactgctcgctataacacgatcatcgtgcattcttacttaggagc +atcacccgcacaataacgtaccttaaactacaacactattagaccgagtactgtaattca +cgaaagctcaagctcgcattgtaaagaacttgctctctcgtaaaatgtgataatagtttg +cggagaggattcaattattttccattgcacctactccactagattcgataaaagaaggtg +gtcctcccttaaaaagaaatgttaagtaacatcggaaccataagcaaagcatgtaagtga +accgtcatccttccctaagaaacataaaggtttttaataatgtcgactgtgaactataac +tgcatcctttcctgacctactccggttccttgttgttatttctgaacgagaccagtagat +aaacaatgtaaaccacagtgggtaccaatggtgcatgtgacgctaccgttgttttaagtg +cccgtacaaacataagaagtcataatcttacttgaaattaattttgccttttattttttt +tcaggctcgaaattaatgatttgttttttttgaccttctagttacgctaatatgcggtcg +cctgtggtttctattgagtcctataacgggatgggatctaatacgtttggttactagtaa +acaaggtataaatttgataccggagtatcaactgtataacatcaagctttatgactcata +cgcgaagtaatgacacaaggctttcaggagatcgcgagtacagagccactaaggggtgta +ttacgatagtgacaccaccgagcgcactcactccccaagtagatttatgatcctacgcta +agtattagatatataaccaaagaggttctagtcagtgcaactcttagaataataattagc +cggttttgcctttttaggcctaatgcaatattcagctagcccttatgtatctcgcgttcc +acagcaccactcatggcacgcgtttaaactaatcaaatataatctatgaatgttatgcca +gtacttgaataaatcaggttttttataagtccttgcatactctcgttatatactgttaga +gtcttaccccatagaaattctttcatctgcaaacttagaagaattctcagctacggggag +cataaagtccccaggatgttgacaaatacaacaaatgtggcttatacaaacactccatat +gaaaatcgaaccctcgtggtagttttagccgaaccttgtacggataaatccctccatttt +ccaatagcagatacctatcctactacctcgtggtattaaattaaagcttgaaatatagag +ctgcatagcttatccaattcccaagcacgagtctaccgtcgtaaccacgatttgatttac +agacgctagagcaaacccatctttaaacatataagtaaaaattaaagggtgagtgcgtac +gtgtttactagcaacttcgcttattaagacaattgtttataagccataattaaaaacata +tgttcaacaggttcattgatatttgtaattgcacaggtttttaataaggatctacgtaag +tataatgaacaaactttttaccagagttatattctgtactttgaaaatgctcctctaccg +ccttagagactttcaattagattttttgcagttaatctatgcgtaagtgaaccatgcaag +ggatgcgattcaaccgcctcgtgctaaccctatcgtctgtctcataactgtaggtctaat +ataattttcagttttcgaacacataaccctttgaaaatctgctatttaatgtctcacctg +catgcactatcttctatactgctcagaacggctatacgtcactatgctccaagtgacgat +ttaaacgaagcaaggaataataggtttattttagtgcaaaacaattaagtgcggactacg +tgctctttacaataagccttgtgattgggctataggttaagtcccatattaacgatctcc +aatgtacaaaatcgacaatcgctttgcattacccggttactagtcgaattacagatagct +gttagatactcactctaattttggacaacaatcccaatcttggggtcgtctatcgcctga +agctcgtaaatccttccatcttaaacgattacatattatagacttgttcggggtagagat +atcacagttgtgcaaacattgtaaatcgatactagtttatgttggtagtctagttgcttt +taccattccccgaaaaacttgatctactatttcgacaacagtaaacttgaactaggtaag +tgaaaacagagaatgcctcatagtgccactatttgtccactatatgtaagtgtagcttta +cataatccactatgactgagatcattacggcctaggaaagcagcgtagaaaaaaagggcc +cggatattacgactgtaactataaaactagttactggtagcgcgccatgtatagatttgt +tttaccggttgtggttgcgttaacgaatttcagccgcgaaaattgatccgttaaccagtc +catctcgacttctataaaacgataaagtaaagttgatgttcagcctccttcttatggttg +catcgagagtacactactcagtgggaaatagatcggggttcctacttcagattgtattat +ctaggcaattgccgattgtgccatacctggataaaataagctacctacatgtgatgctta +tctattatcgtcatactaccttagggtgtcctgttgaacgctacattaatctttagccgt +ttgagatgttccaatggataggagtctaacgcatgatgaagtttaggaaggcagagcatc +ccactaagtatgtgacagtgtatttcgaaacgagacgttataaatagaaaaaaggtcctt +ctggttctattctgctgaactattgaatggaaagattggttgacctacgtactatttgct +tgaagtcatcaatttgacggggtgagagacatatggtgcatactttacggactctatatt +ttagatcagaagcttagcagtcttctctacaccccctcacgacataattgcttttaagaa +tctatgtttgattcctctacgggaattcggatccgttcgcatgtgcggtttatctaaacc +aggggacatatgttcagctaaagcatacgaacactttgctaactagacgtatgtatagta +gctataaatcccgacgatatttacaaaaagaaatgagactcaaatatatacatagcgacc +ctacacttattcgcaccctgatctaggcgatcctagcacccacacccgaaagtgagcact +agtgtcttccgtattaaatttactgcagttgagattttagttgtctactaaggattactc +taacccgtaataaggatcaagactcggtactagctttactatcattccctatgtgttttc +ctaactcacaagggtacgtaccagcctatgtaattacaataatgataaagacacaaagga +agtaactttacaaatgagtctccagttacactagcttagtccctcccatcttgctttgaa +gtctaaatacgcaatctctgaggatatacagcagaagaacactcataacgttggagtcca +agaattagactcatagggcccccaacatttaatatgtactgtgagtttgaaggtgttcta +ttgttaattcctgctcttgatacatgacacgtactccgtgtttaaggcttcggactgact +ttctttcataagttgagcaacgaaaatttcagaatcgataagttggattcactaactaat +acggctgattgaaaactccactccggacctatatggtcgacctttatacgtaaccgatat +aaaacttataggctggtatatcgagccttcctagcgcaatttcggatggggtttcttcta +ctactcaacaacggaatagtctttgtttagtaaaccagagctcaggacgcccaatacgta +ggagagcgctgtggagcatgtgtcattatggactggagcactcttaaatcactctgcgtg +tgctaaacgatagatcataacatgtcctgagtaaattttcttgatacgtcgcaatatacc +gttattagttaaacgttctcatccgtcatgcgtgaaatacggctgtcgtgctcagatata +ctattagcgactcatctcgcctaacacgcacacgtataaactcggaatgactgccgctct +tacatattagaaatacagactacaccacggaagcattgggtcattctcaaccgctgtata +aaagatgattagtcttataataagattaccaaagaggcagaatcatgggtagtaaatcta +ttattcaagtgattaccgtcgtgtaggcagggagtgaggacgagatggtactcaggacaa +atattaaccggacgaagtggtttacgtcgtactttcactattagtagtaaatacaaggta +acaccggggaatagtactaaatataatgatatctatcttcgggagaacgagtcgtctatt +gctttgaacattctcaaggcgtaaaatgtgctgacttatagcatgatacaaccgattgtt +acttttgtctattcaaaagattgaatagttttttatacaaaagccgcatacttatgacgg +ctagtatacagtttcatcccctagcatcaatgctatggacagtattgaacttataggaaa +ttcttctaatagggcaaatccgtcgtgatgcctattttttttcagtcacatcctcaaatg +gcactagtattgtcgggatcccattaacaggctcaaccacgagctcacgcgaggacatgt +agtccgtatctttaacgaagcgacagcgacagaactcccatggataaccaattataaggc +ccgtaatcctctagacatcgtttaccaataaatccgctttctccgtaatcatgttgaata +ccccagagtagtccagatgataaccgatgaaacacaagtctttctcaatgcacttacggt +gaacttattaccgccaacgtagctcatcaaggttgcgacatctagttgtgtgtttgcgac +gagcccagcgaacttcatcaactttcgtatattcaacgccttgtaattttactttaagac +gcctggtgatgtagattcttagataatcagtttgttatcggctgtactttaccataattt +cacaggtttcaggtcaagaagattatagctgtatatacagttccatgctcggtgcacaga +aacgtgatcggataataatcaatcgcttatgtcgtctttaggcgtatccaatacatgccc +cgataccgcagtgtatttcgacatgtaggtataccgtcgcatttgagctcgagtcaggac +gtcagctagattagattccttaatagaatataccgacctctagtccgaactaaactatag +ataacgccaacttcaggttaattgtctagtcgtctgtttgcagatgggattcttagatga +gtgagtatcggccatattggttcgagcactttagtttttgatgcataggatatgcaatgt +atagctgaaagtactttatctgtttcaaactcacattgattaaaccggtaaacctttaaa +gactacaagaaaatattcagtgagggcaattttgtcaatcacaatcttccagctagagat +acttcacaatttgtcttgaggctacgcaacattagacggattttcgcgttttattgaaat +aatcgaggggcccaagagtatccatagttcattttgtaagatttctttacaggcttatta +cagcttcttcagactcctacatgcttacgagttatatgctagcatgtgaacaatagatta +atatacaggaaaacgtacattgagagagatgaccctacacagcgcaaccgttgagtactt +tcattaaagggtaacgctctcgagacagcatccttaagatggccttattgtcaaatcatt +tgcagaagtacgcaagatccctaaccaacgtagaagaatccctacaaacacatgagacgc +ggtgaaaatagacagggtgttagtattcaatcttcggagtatcaatttcgccaatcttgg +tgagaaagcataccctttcttcagagaaagaagatcaatcataacactatctttaacgag +gtacgcacgcgcatcattacctgcctccatggatctttaggatagcggaaagtattggca +gcgtattgtgatttcgttcctactttatcaatttcacattcatatacatgtcttttatca +aaatcgccaataagataggatgagctatattagatgctagtagagttcgcgccaacatca +tcgataggaatactcaggacagcgtgataggacttttcaatccctaatactctctataat +tataactctctcttaagtttggaggcagtaacgcgctctatataatcagtttgctgcacc +attcttcagcctctgatacatacaaataaattccacagcagtaagagggtttaattgaga +catcttgggaacttaggattttactctaacatcaccgaaacgattattggataccgtacc +taaacgaactttctcaaggcagtaatataggacatccgcaataacacaaatgctgcctcc +ccaggagttatgtcttcctggaggctatatcttacacccactcactataggcaaactaaa +gtttaaatgttgattgtctaaaaaaaagatagataagagttggccggcgtagcacatgcg +aaagtgaatcgtaagctataattctctggacttgaagttctgtcctgttcctctgcaaga +aacaaacttcctttaaagctatttacgacgcacatctcagcaagttataaacatgttgga +agtttctagtcggaattcccaaagaacggatctatctaatgcattcctacatttttcctg +tctgccgatggtgccatcctattcaaagaatttcttaaaagtagattaaatgggactttt +aacaatgagtaaccttacgcctctaagggttcctcgagtgccatacaccagtcaggtccg +agccacatacacggagaacattctaacatagcattctcaactcgatcatttgcaggttac +ttctttcctatcctagtgctaaaaatcatacttgcaatcccatagcacggattaagaacc +taagaaacaattcagtaaaacatgttcgaattcttggtatgggaacatcattgcagctat +ggtctaacgcattaatgtttgggtacatcttccatcatataaacaggaagagtctgacga +cagggagtgcttgcgatcatgtctatcattgtgaaatcaaattgtagctcacatgtcgtc +tatgagagcgtgtatccgataagatttagaaaaatagaagtcgtataagatctcactgaa +cttttgaatgaatgtgaagcatatatgatctgctttaataaaactttatccataggatac +gtttccaaatcaattcaataattattagtcaaaatagataaggatgaacaacctgaaggc +cgatcggacgtagaaagtggtcccatcactttgagttgatattgttgaaccacacgttat +tatggttttcaaacagtctcaggatattgtatatacagataatccgataccagttgtctg +acgcccctcttacgtaccccaccctttgtgacgtttaaagcagttgttcagtattttaaa +ctaggcggcaactaatttggaaagaagcacagtggatatgtctaaattcttgttattcag +gcctgaatttaatacaccgcatagttaacttcgcggtagagttgttcatcatgcctcctc +taagctaccacttctatgatacaccaatagttgttctacggaatctgataattggccaag +tcataaacttccgctgcgttcaacccccttgctcgaatatccaactcgaaaagacagcct +tttggtgtccggaacaaatcagttacttcttttctgatgttaattctctgtggtcagata +cagaccaaaaactccgcggatttaccatcctccaagaacaaatttgcatcaacatagcat +tttggctacatattctaagtctcaatagtttaggttttcaactacattatcccaacatta +ggattggaggaataatagctgggtaagtccccttgcgtctacaatcgactattttttatg +aatatgcttctgccgcacctatggttattaaaaaagtcatgactttgaagaaccctgaaa +agatagatgaatcaggtgtaatggcagcagccaaagagcatataattagcaacactctaa +gaacattatagatatgatgatagcgatcgtcatgatgttatccggtcacaatagtagctt +catcagctaattcgttttgccagtggtgacttgcgctggaagaatcgttatacggtccct +tccctcttgatacggtgggggcttattcaaccgcgtggattgggttgtcatacttgcatt +aaacgatgtaaaccatctagtagtcaactatactaaatcacaaaatagtgatcaatacat +acccgcttcatggttttaaccatttaattgattaaagatattccgctaagaaccattatc +tacctaaactgatcgccgtatcctagtagtttgaaatttgatgtaccgtaatgatcaacg +aagtaaaacgttatattgtatgtagaataataggtcttggagctaaatgatgtgattggt +agtgaagacttacccttacaactttaccggtttctcggaagaatatactagagaatcaat +gcatgggctacataagcactttagtctaatgagataaaaaatacacgagtcttccatcat +gaattttttgtcgaaaaactcgaacctggtaatttaaaccatatatctttatgtcgtcaa +taactctcatatgttttatataacttcccaatcacgacttgtaactgcttgttcgactga +gctgtttgagctatgaggccgggatccggttgagctacatctatttgctacaagaaaaat +gaaagcacatttgttgggagttctggctacactcatagagaaataagtggcccgagtggg +tgcggcctgcctccatattcaagtgtatcttaaaccaagtggttccaacgctcgcgctaa +agaattaaagcctttatttcctccacggagtagcccgtaatccggttcgaaagagaccat +tgaagttaattttcatatccagtgaagtttaggcacaagcatgtgttctgccacatgcct +caaagcgctcttcaaccaagatatgattcatcctaacttcgatgaatgcgtctgtaacat +aaatatagaaggaatgattcggcgagttaattttcgccttctccaacatggcatccctac +gttcgttataaggaccatacatgtaggttttaaaggtttgcggttaatcgatatttacat +catagaaattctatagtcaaatttacaagactctagatactcactcgttgcagccggcta +ggaagcgctttgtaccttacttcccttttcgttgcgtaatatgaatttcatatagtaagt +tcaaggcactcatacctccgtgaagagggtagatagactattaaagttgtttaatagtac +gtattgatggaaatgacccgtaggagatttaccactcaatccacaagattcgctgctgtg +cattatcaaaacagtgcatgtcgaaacatgggttgggtccttcaaacacgaatccaggta +gagatacctttgcaattttt diff --git a/multithread/k-nucleotide/knucleotide-inputYYY.txt b/multithread/k-nucleotide/knucleotide-inputYYY.txt new file mode 100644 --- /dev/null +++ b/multithread/k-nucleotide/knucleotide-inputYYY.txt @@ -0,0 +1,33325 @@ +>ONE Homo sapiens alu +GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA +TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT +AAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG +GCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG +CCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT +GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA +GGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA +TTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG +AATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA +GCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGT +AATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACC +AGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTG +GTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACC +CGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAG +AGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTT +TGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACA +TGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCT +GTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGG +TTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGT +CTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGG +CGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCG +TCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTA +CTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCG +AGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCG +GGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACC +TGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAA +TACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGA +GGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACT +GCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTC +ACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGT +TCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGC +CGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCG +CTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTG +GGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCC +CAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCT +GGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGC +GCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGA +GGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGA +GACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGA +GGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTG +AAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT +CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCA +GTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAA +AAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGC +GGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCT +ACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGG +GAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATC +GCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGC +GGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGG +TCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAA +AAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAG +GAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACT +CCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCC +TGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAG +ACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGC +GTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGA +ACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGA +CAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCA +CTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCA +ACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCG +CCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGG +AGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTC +CGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCG +AGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACC +CCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAG +CTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAG +CCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGG +CCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATC +ACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAA +AAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGC +TGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCC +ACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGG +CTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGG +AGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATT +AGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAA +TCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGC +CTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAA +TCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAG +CCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGT +GGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCG +GGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAG +CGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG +GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATG +GTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGT +AATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTT +GCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCT +CAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCG +GGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTC +TCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACT +CGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAG +ATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGG +CGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTG +AGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATA +CAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGG +CAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGC +ACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCAC +GCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTC +GAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCG +GGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCT +TGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGG +CGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCA +GCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGG +CCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGC +GCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGG +CGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGA +CTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGG +CCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAA +ACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCC +CAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGT +GAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAA +AGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGG +ATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTAC +TAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGA +GGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGC +GCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGG +TGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTC +AGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAA +ATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGA +GAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC +AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTG +TAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGAC +CAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGT +GGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC +CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACA +GAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACT +TTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAAC +ATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCC +TGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAG +GTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCG +TCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAG +GCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCC +GTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCT +ACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCC +GAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCC +GGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCAC +CTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAA +ATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTG +AGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCAC +TGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCT +CACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAG +TTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAG +CCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATC +GCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCT +GGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATC +CCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCC +TGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGG +CGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG +AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCG +AGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGG +AGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGT +GAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAA +TCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGC +AGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCA +AAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGG +CGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTC +TACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCG +GGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGAT +CGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCG +CGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAG +GTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACA +AAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCA +GGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCAC +TCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGC +CTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA +GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGG +CGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTG +AACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCG +ACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGC +ACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCC +AACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGC +GCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCG +GAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACT +CCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCC +GAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAAC +CCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA +GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGA +GCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAG +GCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGAT +CACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTA +AAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGG +CTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGC +CACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTG +GCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAG +GAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAAT +TAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGA +ATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAG +CCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTA +ATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCA +GCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGG +TGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCC +GGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGA +GCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTT +GGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACAT +GGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTG +TAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGT +TGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTC +TCAAAAAGGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGC +GGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGT From pypy.commits at gmail.com Thu Jul 11 04:46:44 2019 From: pypy.commits at gmail.com (Raemi) Date: Thu, 11 Jul 2019 01:46:44 -0700 (PDT) Subject: [pypy-commit] benchmarks multithread-runner: add benchmark from benchmarksgame Message-ID: <5d26f774.1c69fb81.9b46c.35dc@mx.google.com> Author: Remi Meier Branch: multithread-runner Changeset: r385:06b36af4f84d Date: 2016-07-22 10:10 +0200 http://bitbucket.org/pypy/benchmarks/changeset/06b36af4f84d/ Log: add benchmark from benchmarksgame diff --git a/multithread/fannkuch-redux/fannkuch-redux.py b/multithread/fannkuch-redux/fannkuch-redux.py new file mode 100644 --- /dev/null +++ b/multithread/fannkuch-redux/fannkuch-redux.py @@ -0,0 +1,157 @@ +# -*- coding: utf-8 -*- +import gc +import sys +import time +from common.abstract_threading import ( + atomic, Future, set_thread_pool, ThreadPool, + hint_commit_soon, turn_jitting_off) + + +# Revised BSD license +# This is a specific instance of the Open Source Initiative (OSI) BSD license template. +# Copyright (c) 2004-2008 Brent Fulgham, 2005-2016 Isaac Gouy +# All rights reserved. + +# The Computer Language Benchmarks Game +# http://benchmarksgame.alioth.debian.org/ +# +# contributed by Joerg Baumann +# many thanks to Oleg Mazurov for his helpful description + +from sys import argv +from math import factorial +from itertools import islice, starmap + +def permutations(n, start, size): + p = bytearray(range(n)) + count = bytearray(n) + + remainder = start + for v in range(n - 1, 0, -1): + count[v], remainder = divmod(remainder, factorial(v)) + for _ in range(count[v]): + p[:v], p[v] = p[1:v + 1], p[0] + + assert(count[1] == 0) + assert(size < 2 or (size % 2 == 0)) + + if size < 2: + yield p[:] + else: + rotation_swaps = [None] * n + for i in range(1, n): + r = list(range(n)) + for v in range(1, i + 1): + r[:v], r[v] = r[1:v + 1], r[0] + swaps = [] + for dst, src in enumerate(r): + if dst != src: + swaps.append((dst, src)) + rotation_swaps[i] = tuple(swaps) + + while True: + yield p[:] + p[0], p[1] = p[1], p[0] + yield p[:] + i = 2 + while count[i] >= i: + count[i] = 0 + i += 1 + else: + count[i] += 1 + t = p[:] + for dst, src in rotation_swaps[i]: + p[dst] = t[src] + +def alternating_flips_generator(n, start, size): + maximum_flips = 0 + alternating_factor = 1 + for permutation in islice(permutations(n, start, size), size): + first = permutation[0] + if first: + flips_count = 1 + while True: + permutation[:first + 1] = permutation[first::-1] + first = permutation[0] + if not first: break + flips_count += 1 + if maximum_flips < flips_count: + maximum_flips = flips_count + yield flips_count * alternating_factor + else: + yield 0 + alternating_factor = -alternating_factor + yield maximum_flips + +def task(n, start, size): + alternating_flips = alternating_flips_generator(n, start, size) + return sum(islice(alternating_flips, size)), next(alternating_flips) + +def fannkuch(n): + assert(n > 0) + + task_count = 16 + total = factorial(n) + task_size = (total + task_count - 1) // task_count + + if task_size < 20000: + task_size = total + task_count = 1 + + assert(task_size % 2 == 0) + + task_args = [(n, i * task_size, task_size) for i in range(task_count)] + + t = time.time() + fs = [] + for args in task_args: + fs.append(Future(task, *args)) + checksums, maximums = zip(*[f() for f in fs]) + # with Pool() as pool: + # checksums, maximums = zip(*pool.starmap(task, task_args)) + + checksum, maximum = sum(checksums), max(maximums) + t = time.time() - t + print("{0}\nPfannkuchen({1}) = {2}".format(checksum, n, maximum)) + return t + + +def run(threads=2, n=9): + threads = int(threads) + n = int(n) + + set_thread_pool(ThreadPool(threads)) + + t = fannkuch(n) + + # shutdown current pool + set_thread_pool(None) + return t + +def main(argv): + # warmiters threads args... + warmiters = int(argv[0]) + threads = int(argv[1]) + n = int(argv[2]) + + print "params (iters, threads, n):", warmiters, threads, n + + print "do warmup:" + for i in range(4): + t = run(threads, n) + print "iter", i, "time:", t + + print "turn off jitting" + turn_jitting_off() + print "do", warmiters, "real iters:" + times = [] + for i in range(warmiters): + gc.collect() + + t = run(threads, n) + times.append(t) + print "warmiters:", times + +if __name__ == "__main__": + import sys + main(sys.argv[1:]) From pypy.commits at gmail.com Thu Jul 11 04:46:46 2019 From: pypy.commits at gmail.com (Raemi) Date: Thu, 11 Jul 2019 01:46:46 -0700 (PDT) Subject: [pypy-commit] benchmarks multithread-runner: add configs for new benchmarks Message-ID: <5d26f776.1c69fb81.a2d84.a1c8@mx.google.com> Author: Remi Meier Branch: multithread-runner Changeset: r386:6ce1f76df158 Date: 2016-07-22 10:16 +0200 http://bitbucket.org/pypy/benchmarks/changeset/6ce1f76df158/ Log: add configs for new benchmarks diff --git a/multithread/config-all-long.json b/multithread/config-all-long.json --- a/multithread/config-all-long.json +++ b/multithread/config-all-long.json @@ -61,6 +61,22 @@ "file": "perlin_noise/perlin_noise.py", "PYTHONPATH": "..", "args": ["5"] + }, + + "regex-dna": { + "file": "regex-dna/regex-dna.py", + "PYTHONPATH": ".." + }, + + "fannkuch-redux": { + "file": "fannkuch-redux/fannkuch-redux.py", + "PYTHONPATH": "..", + "args": ["10"] + }, + + "k-nucleotide": { + "file": "k-nucleotide/k-nucleotide.py", + "PYTHONPATH": ".." } } diff --git a/multithread/config-all-short.json b/multithread/config-all-short.json --- a/multithread/config-all-short.json +++ b/multithread/config-all-short.json @@ -61,6 +61,22 @@ "file": "perlin_noise/perlin_noise.py", "PYTHONPATH": "..", "args": ["4"] + }, + + "regex-dna": { + "file": "regex-dna/regex-dna.py", + "PYTHONPATH": ".." + }, + + "fannkuch-redux": { + "file": "fannkuch-redux/fannkuch-redux.py", + "PYTHONPATH": "..", + "args": ["9"] + }, + + "k-nucleotide": { + "file": "k-nucleotide/k-nucleotide.py", + "PYTHONPATH": ".." } } diff --git a/multithread/config-fannkuch-redux.json b/multithread/config-fannkuch-redux.json new file mode 100644 --- /dev/null +++ b/multithread/config-fannkuch-redux.json @@ -0,0 +1,21 @@ +{ + "defaults": { + "file": null, + "threads": [1, 2, 4, 8], + "vmstarts": 3, + "warmiters": 3, + "PYTHONPATH": ".", + "args": [], + "cwd": "." + }, + + "benchs": { + "fannkuch-redux": { + "file": "fannkuch-redux/fannkuch-redux.py", + "PYTHONPATH": "..", + "vmstarts": 3, + "warmiters": 3, + "args": ["9"] + } + } +} diff --git a/multithread/config-k-nucleotide.json b/multithread/config-k-nucleotide.json new file mode 100644 --- /dev/null +++ b/multithread/config-k-nucleotide.json @@ -0,0 +1,20 @@ +{ + "defaults": { + "file": null, + "threads": [1, 2, 4, 8], + "vmstarts": 3, + "warmiters": 3, + "PYTHONPATH": ".", + "args": [], + "cwd": "." + }, + + "benchs": { + "k-nucleotide": { + "file": "k-nucleotide/k-nucleotide.py", + "PYTHONPATH": "..", + "vmstarts": 3, + "warmiters": 3 + } + } +} diff --git a/multithread/config-regex-dna.json b/multithread/config-regex-dna.json new file mode 100644 --- /dev/null +++ b/multithread/config-regex-dna.json @@ -0,0 +1,20 @@ +{ + "defaults": { + "file": null, + "threads": [1, 2, 4, 8], + "vmstarts": 3, + "warmiters": 3, + "PYTHONPATH": ".", + "args": [], + "cwd": "." + }, + + "benchs": { + "regex-dna": { + "file": "regex-dna/regex-dna.py", + "PYTHONPATH": "..", + "vmstarts": 3, + "warmiters": 3 + } + } +} diff --git a/multithread/config-shootout-benchs-short.json b/multithread/config-shootout-benchs-short.json new file mode 100644 --- /dev/null +++ b/multithread/config-shootout-benchs-short.json @@ -0,0 +1,31 @@ +{ + "defaults": { + "file": null, + "threads": [1, 2, 4, 8], + "vmstarts": 1, + "warmiters": 1, + "PYTHONPATH": ".", + "args": [], + "cwd": "." + }, + + "benchs": { + "regex-dna": { + "file": "regex-dna/regex-dna.py", + "PYTHONPATH": ".." + }, + + "fannkuch-redux": { + "file": "fannkuch-redux/fannkuch-redux.py", + "PYTHONPATH": "..", + "args": ["9"] + }, + + "k-nucleotide": { + "file": "k-nucleotide/k-nucleotide.py", + "PYTHONPATH": ".." + } + + } + +} From pypy.commits at gmail.com Thu Jul 11 04:46:47 2019 From: pypy.commits at gmail.com (Raemi) Date: Thu, 11 Jul 2019 01:46:47 -0700 (PDT) Subject: [pypy-commit] benchmarks multithread-runner: add full license to benchmark-game benchs Message-ID: <5d26f777.1c69fb81.a8d34.feeb@mx.google.com> Author: Remi Meier Branch: multithread-runner Changeset: r387:53d8c201ee55 Date: 2016-07-29 14:40 +0200 http://bitbucket.org/pypy/benchmarks/changeset/53d8c201ee55/ Log: add full license to benchmark-game benchs diff --git a/multithread/fannkuch-redux/fannkuch-redux.py b/multithread/fannkuch-redux/fannkuch-redux.py --- a/multithread/fannkuch-redux/fannkuch-redux.py +++ b/multithread/fannkuch-redux/fannkuch-redux.py @@ -11,6 +11,28 @@ # This is a specific instance of the Open Source Initiative (OSI) BSD license template. # Copyright (c) 2004-2008 Brent Fulgham, 2005-2016 Isaac Gouy # All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, this list +# of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this +# list of conditions and the following disclaimer in the documentation and/or +# other materials provided with the distribution. +# * Neither the name of "The Computer Language Benchmarks Game" nor the name of "The +# Computer Language Shootout Benchmarks" nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +# SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. # The Computer Language Benchmarks Game # http://benchmarksgame.alioth.debian.org/ diff --git a/multithread/k-nucleotide/k-nucleotide.py b/multithread/k-nucleotide/k-nucleotide.py --- a/multithread/k-nucleotide/k-nucleotide.py +++ b/multithread/k-nucleotide/k-nucleotide.py @@ -11,6 +11,28 @@ # This is a specific instance of the Open Source Initiative (OSI) BSD license template. # Copyright (c) 2004-2008 Brent Fulgham, 2005-2016 Isaac Gouy # All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, this list +# of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this +# list of conditions and the following disclaimer in the documentation and/or +# other materials provided with the distribution. +# * Neither the name of "The Computer Language Benchmarks Game" nor the name of "The +# Computer Language Shootout Benchmarks" nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +# SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. # The Computer Language Benchmarks Game # http://benchmarksgame.alioth.debian.org/ diff --git a/multithread/regex-dna/regex-dna.py b/multithread/regex-dna/regex-dna.py --- a/multithread/regex-dna/regex-dna.py +++ b/multithread/regex-dna/regex-dna.py @@ -12,6 +12,30 @@ # This is a specific instance of the Open Source Initiative (OSI) BSD license template. # Copyright (c) 2004-2008 Brent Fulgham, 2005-2016 Isaac Gouy # All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are +# permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright notice, this list +# of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this +# list of conditions and the following disclaimer in the documentation and/or +# other materials provided with the distribution. +# * Neither the name of "The Computer Language Benchmarks Game" nor the name of "The +# Computer Language Shootout Benchmarks" nor the names of its contributors may be +# used to endorse or promote products derived from this software without specific +# prior written permission. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +# SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. + + # The Computer Language Benchmarks Game # http://shootout.alioth.debian.org/ # contributed by Dominique Wahli From pypy.commits at gmail.com Thu Jul 11 04:46:49 2019 From: pypy.commits at gmail.com (Raemi) Date: Thu, 11 Jul 2019 01:46:49 -0700 (PDT) Subject: [pypy-commit] benchmarks multithread-runner: recent updates to the benchmarks Message-ID: <5d26f779.1c69fb81.5e5bf.9297@mx.google.com> Author: Remi Meier Branch: multithread-runner Changeset: r388:0db2fd012b7e Date: 2019-07-11 10:40 +0200 http://bitbucket.org/pypy/benchmarks/changeset/0db2fd012b7e/ Log: recent updates to the benchmarks diff --git a/multithread/common/abstract_threading.py b/multithread/common/abstract_threading.py --- a/multithread/common/abstract_threading.py +++ b/multithread/common/abstract_threading.py @@ -4,6 +4,8 @@ try: from pypystm import atomic, getsegmentlimit, hint_commit_soon + # don't use atomic-feature + atomic = RLock() except ImportError: print "NON-STM EXECUTION" atomic = RLock() diff --git a/multithread/get_results.py b/multithread/get_results.py --- a/multithread/get_results.py +++ b/multithread/get_results.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 import os import sys @@ -9,7 +9,7 @@ # group timings by thread (multiple vmstarts) res_over_run = all_res[run_key] grouped = {} - for bench_key, timings in res_over_run.items(): + for bench_key, timings in list(res_over_run.items()): for t in timings: per_bench = grouped.setdefault(bench_key, {}) per_bench.setdefault(t['threads'], []).extend(t['warmiters']) @@ -17,30 +17,30 @@ return grouped def retrieve_data(results): - print "RUNS:", len(results) + print("RUNS:", len(results)) all_res = {} - for run_key, run in results.iteritems(): + for run_key, run in results.items(): res_over_run = {} - print "###", "RUN", run_key, "###" - print "python:", run['python'] - print "python-version:", run['python-version'].strip() - print "hg-id:", run['hg-id'].strip() + print("###", "RUN", run_key, "###") + print("python:", run['python']) + print("python-version:", run['python-version'].strip()) + print("hg-id:", run['hg-id'].strip()) run_results = run['results'] - print "RESULTS:", len(run_results) + print("RESULTS:", len(run_results)) - print "BENCHMARKS:", run_results.keys() - for bench_key, bench_res in run_results.items(): - print "BENCHMARK:", bench_key + print("BENCHMARKS:", list(run_results.keys())) + for bench_key, bench_res in list(run_results.items()): + print("BENCHMARK:", bench_key) if 'fail_reason' in bench_res: - print "FAILED:", bench_res + print("FAILED:", bench_res) else: timings = bench_res['timings'] failures = bench_res['failures'] - print "timings:", len(timings), "failures:", len(failures) + print("timings:", len(timings), "failures:", len(failures)) res_over_run.setdefault(bench_key, []).extend(timings) if failures: - print "############# THERE ARE FAILURES! #############" + print("############# THERE ARE FAILURES! #############") #print "fail reasons:", failures #import pdb;pdb.set_trace() # print "" @@ -52,8 +52,8 @@ # for ts in sorted(per_bench.keys()): # if per_bench[ts]: # print "TS:", ts, "times:", per_bench[ts] - print "" - print "" + print("") + print("") return all_res @@ -62,12 +62,12 @@ grouped = collect_warmiters(all_res, run_key) cols = len(grouped) * 2 + 1 # "threads" + avg, stddev for each benchmark - rows = len(grouped.values()[0]) + 1 # name + threads + rows = len(list(grouped.values())[0]) + 1 # name + threads table = [["" for _ in range(cols)] for _ in range(rows)] # t[row][col] table[0][0] = "Threads" for bench_num, (b, per_bench) in enumerate(grouped.items()): - print "BENCH", b + print("BENCH", b) table[0][1 + bench_num * 2] = b ts_index = 0 for ts in sorted(per_bench.keys()): @@ -78,7 +78,7 @@ else: assert table[row][0] == ts - print "TS:", ts, "times:", per_bench[ts] + print("TS:", ts, "times:", per_bench[ts]) col = 1 + bench_num * 2 table[row][col] = np.mean(per_bench[ts]) table[row][col+1] = np.std(per_bench[ts]) @@ -86,24 +86,24 @@ # print table: for r in range(rows): - line = ",\t".join(map(str, table[r])) - print line + line = ";".join(map(str, table[r])) + print(line) def print_latex_table(all_res, gil_run_key, stm_run_key): - print "" - print r"\footnotesize" - print r"\begin{tabularx}{\textwidth}{l|r@{\hspace{5pt}}r@{\hspace{5pt}}r@{\hspace{5pt}}r|r@{\hspace{5pt}}r@{\hspace{5pt}}r@{\hspace{5pt}}r|r}" + print("") + print(r"\footnotesize") + print(r"\begin{tabularx}{\textwidth}{l|r@{\hspace{5pt}}r@{\hspace{5pt}}r@{\hspace{5pt}}r|r@{\hspace{5pt}}r@{\hspace{5pt}}r@{\hspace{5pt}}r|r}") #print r"\hline" - print r"\textbf{Python VM} & \multicolumn{4}{c|}{\textbf{PyPy-GIL}} & \multicolumn{4}{c}{\textbf{PyPy-STM}} & \multicolumn{1}{|p{2cm}}{\textbf{Max. speedup}} \\ \hline" - print r"\textbf{Threads} & \multicolumn{1}{c}{\textbf{1}} & \multicolumn{1}{c}{\textbf{2}} & \multicolumn{1}{c}{\textbf{4}} & \multicolumn{1}{c|}{\textbf{8}} & \multicolumn{1}{c}{\textbf{1}} & \multicolumn{1}{c}{\textbf{2}} & \multicolumn{1}{c}{\textbf{4}} & \multicolumn{1}{c}{\textbf{8}} & \multicolumn{1}{|c}{*} \\ \hline" + print(r"\textbf{Python VM} & \multicolumn{4}{c|}{\textbf{PyPy-GIL}} & \multicolumn{4}{c}{\textbf{PyPy-STM}} & \multicolumn{1}{|p{2cm}}{\textbf{Max. speedup}} \\ \hline") + print(r"\textbf{Threads} & \multicolumn{1}{c}{\textbf{1}} & \multicolumn{1}{c}{\textbf{2}} & \multicolumn{1}{c}{\textbf{4}} & \multicolumn{1}{c|}{\textbf{8}} & \multicolumn{1}{c}{\textbf{1}} & \multicolumn{1}{c}{\textbf{2}} & \multicolumn{1}{c}{\textbf{4}} & \multicolumn{1}{c}{\textbf{8}} & \multicolumn{1}{|c}{*} \\ \hline") gil_grouped = collect_warmiters(all_res, gil_run_key) stm_grouped = collect_warmiters(all_res, stm_run_key) - assert stm_grouped.keys() == gil_grouped.keys() + assert list(stm_grouped.keys()) == list(gil_grouped.keys()) warnings = "" lines = 1 - for bench_key in stm_grouped.keys(): + for bench_key in list(stm_grouped.keys()): elems = [] gil_bench = gil_grouped[bench_key] stm_bench = stm_grouped[bench_key] @@ -134,14 +134,14 @@ # speedup = min_gil / min_stm cells.append(r"\multicolumn{1}{c}{$%.2f\times$}" % speedup) - print r"%s & " % bench_key + " & ".join(cells) + r" \\" + ( - r" \hdashline[0.5pt/5pt]{}" if lines % 3 == 0 else "") + print(r"%s & " % bench_key + " & ".join(cells) + r" \\" + ( + r" \hdashline[0.5pt/5pt]{}" if lines % 3 == 0 else "")) lines += 1 - print r"\hline" - print r"\end{tabularx}" - print r"\normalsize" - print "" - print warnings + print(r"\hline") + print(r"\end{tabularx}") + print(r"\normalsize") + print("") + print(warnings) def main(argv): results_file = argv[0] @@ -152,12 +152,12 @@ all_res = retrieve_data(results) while True: - print "select gil and stm run (e.g., 0,1):" - runs = all_res.keys() + print("select gil and stm run (e.g., 0,1):") + runs = list(all_res.keys()) choices = ["%s: %s (%s)" % (i, r, results[r]['python']) for i, r in enumerate(runs)] - print "\n".join(choices) - choice = raw_input() + print("\n".join(choices)) + choice = input() gil_run_key, stm_run_key = [runs[int(c)] for c in choice.split(',')] print_csv(all_res, gil_run_key) diff --git a/multithread/k-nucleotide/k-nucleotide.py b/multithread/k-nucleotide/k-nucleotide.py --- a/multithread/k-nucleotide/k-nucleotide.py +++ b/multithread/k-nucleotide/k-nucleotide.py @@ -80,9 +80,13 @@ sequence = "".join(load()).upper() plres = [] + # to increase benchmark time without changing input size, repeat the nuclei to + # look for + nucleos = nucleos * 10 + t = time.time() # ORIGINAL version only looked for 1, 2 sequences - for nl in 1, 2, 3, 4, 5, 6, 7, 8: + for nl in range(1, 20): plres.append(Future(sort_seq, sequence, nl)) for se in nucleos.split(): diff --git a/multithread/parsible-bench/parsible-bench.py b/multithread/parsible-bench/parsible-bench.py --- a/multithread/parsible-bench/parsible-bench.py +++ b/multithread/parsible-bench/parsible-bench.py @@ -17,6 +17,10 @@ pid_file="/tmp/parsible.pid", debug=False, batch=True, auto_reload=False) t = time.time() + # run several times instead of adding more log-data to this repo + p.main(128) + p.main(128) + p.main(128) p.main(128) parallel_time = time.time() - t diff --git a/multithread/perlin_ex/perlin_noise.py b/multithread/perlin_ex/perlin_noise.py new file mode 100644 --- /dev/null +++ b/multithread/perlin_ex/perlin_noise.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# from http://rosettacode.org/wiki/Perlin_noise#Python + +import sys +import time, random +from common.abstract_threading import (atomic, Future, set_thread_pool, + ThreadPool, hint_commit_soon, + print_abort_info, turn_jitting_off) + +import itertools +from collections import deque + +p = [None] * 512 +permutation = [ + 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, + 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, + 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, + 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, + 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, + 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, + 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, + 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, + 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, + 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, + 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, + 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, + 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, + 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, + 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, + 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 +] + +for i in range(256): + p[256 + i] = p[i] = permutation[i] + + +def perlin_noise(x, y, z): + X = int(x) & 255 # FIND UNIT CUBE THAT + Y = int(y) & 255 # CONTAINS POINT. + Z = int(z) & 255 + x -= int(x) # FIND RELATIVE X,Y,Z + y -= int(y) # OF POINT IN CUBE. + z -= int(z) + u = fade(x) # COMPUTE FADE CURVES + v = fade(y) # FOR EACH OF X,Y,Z. + w = fade(z) + A = p[X] + Y + AA = p[A] + Z + AB = p[A + 1] + Z # HASH COORDINATES OF + B = p[X + 1] + Y + BA = p[B] + Z + BB = p[B + 1] + Z # THE 8 CUBE CORNERS, + + return lerp( + w, + lerp( + v, + lerp( + u, + grad(p[AA], x, y, z), # AND ADD + grad(p[BA], x - 1, y, z)), # BLENDED + lerp( + u, + grad(p[AB], x, y - 1, z), # RESULTS + grad(p[BB], x - 1, y - 1, z))), # FROM 8 + lerp( + v, + lerp( + u, + grad(p[AA + 1], x, y, z - 1), # CORNERS + grad(p[BA + 1], x - 1, y, z - 1)), # OF CUBE + lerp(u, grad(p[AB + 1], x, y - 1, z - 1), + grad(p[BB + 1], x - 1, y - 1, z - 1)))) + + +def fade(t): + return t**3 * (t * (t * 6 - 15) + 10) + + +def lerp(t, a, b): + return a + t * (b - a) + + +def grad(hash, x, y, z): + h = hash & 15 # CONVERT LO 4 BITS OF HASH CODE + # u = x if h < 8 else y # INTO 12 GRADIENT DIRECTIONS. + hs = h < 8 + u = x * hs + y * (not hs) + + hs = h < 4 + hin = h in (12, 14) + # v = y if hs else (x if hin else z) + v = y * hs + (not hs) * (x * hin + z * (not hin)) + + heven = (h & 1) == 0 + hfour = (h & 2) == 0 + # return (u if heven else -u) + (v if hfour else -v) + return (u * heven + (-u) * (not heven)) + (v * hfour + (-v) * (not hfour)) + + +def work(n, x): + res = [] + #hint_commit_soon() + for y in xrange(n): + for z in xrange(n): + res.append(perlin_noise(x / 3., y / 3., z / 3.)) + #hint_commit_soon() + return res + + +def run(threads=2, n=5): + threads = int(threads) + n = int(n) + + set_thread_pool(ThreadPool(threads)) + + res = [] + for x in range(n): + res.append(Future(work, 200, x)) + res = [f() for f in res] + # shutdown current pool + set_thread_pool(None) + + +def main(argv): + # warmiters threads args... + warmiters = int(argv[0]) + threads = int(argv[1]) + n = int(argv[2]) + + print "params (iters, threads, n):", warmiters, threads, n + + print "do warmup:" + # JIT compiles *tons* of bridges for the perlin_noise function + # turning it off after /some/ warmup speeds it up by 10x + for i in range(1): + t = time.time() + run(threads, n) + print "iter", i, "time:", time.time() - t + + print "turn off jitting" + import gc + turn_jitting_off() + print "do", warmiters, "real iters:" + times = [] + for i in range(warmiters): + gc.collect() + t = time.time() + run(threads, n) + times.append(time.time() - t) + print "warmiters:", times + + +if __name__ == "__main__": + import sys + main(sys.argv[1:]) diff --git a/multithread/perlin_noise/perlin_noise.py b/multithread/perlin_noise/perlin_noise.py --- a/multithread/perlin_noise/perlin_noise.py +++ b/multithread/perlin_noise/perlin_noise.py @@ -83,7 +83,7 @@ res = [] for x in range(n): - res.append(Future(work, 400, x)) + res.append(Future(work, 200, x)) res = [f() for f in res] # shutdown current pool diff --git a/multithread/regex-dna/regex-dna.py b/multithread/regex-dna/regex-dna.py --- a/multithread/regex-dna/regex-dna.py +++ b/multithread/regex-dna/regex-dna.py @@ -50,16 +50,17 @@ def var_find(f, seq): return len(findall(f, seq)) -def main_b(): - with open('regexdna-inputYYY.txt', 'r') as f: - seq = f.read() +def main_b(small=False): + f = 'regexdna-inputYYY.txt' if not small else 'regexdna-input10000.txt' + with open(f, 'r') as f: + seq = f.read().lower() ilen = len(seq) seq = sub('>.*\n|\n', '', seq) clen = len(seq) - variants = ( + variants = [ 'agggtaaa|tttaccct', '[cgt]gggtaaa|tttaccc[acg]', 'a[act]ggtaaa|tttacc[agt]t', @@ -68,12 +69,15 @@ 'aggg[acg]aaa|ttt[cgt]ccct', 'agggt[cgt]aa|tt[acg]accct', 'agggta[cgt]a|t[acg]taccct', - 'agggtaa[cgt]|[acg]ttaccct') + 'agggtaa[cgt]|[acg]ttaccct'] + # instead of increasing input data, just search for the variants + # multiple times: + variants = 40 * variants t = time.time() fs = [Future(var_find, v, seq) for v in variants] for f in zip(variants, fs): - print(f[0], f[1]()) + print(f[1]()) t = time.time() - t subst = { @@ -90,12 +94,12 @@ return t -def run(threads=2): +def run(threads=2, small=False): threads = int(threads) set_thread_pool(ThreadPool(threads)) - t = main_b() + t = main_b(small) # shutdown current pool set_thread_pool(None) @@ -105,12 +109,14 @@ # warmiters threads args... warmiters = int(argv[0]) threads = int(argv[1]) + small = len(argv) == 3 + print "params (iters, threads):", warmiters, threads print "do warmup:" - for i in range(4): - t = run(threads) + for i in range(3): + t = run(threads, small) print "iter", i, "time:", t print "turn off jitting" @@ -120,7 +126,7 @@ for i in range(warmiters): gc.collect() - t = run(threads) + t = run(threads, small) times.append(t) print "warmiters:", times diff --git a/multithread/runner.py b/multithread/runner.py --- a/multithread/runner.py +++ b/multithread/runner.py @@ -5,10 +5,13 @@ import json import time import os, sys +import psutil import copy import pprint from subprocess import Popen, PIPE +import select +STM_LOG = False WITH_NUMACTL = True MAX_RETRY = 100 # per bench @@ -20,18 +23,33 @@ return [float(t) for t in times.split(',')] return None -def run_benchmark(python_exec, bench_config): +def read_all_so_far(stream, res=''): + while select.select([stream], [], [], 0.0)[0] != []: + c = stream.read(1) + if c == "": # EOF + break + res += c + return res + +def run_benchmark(bench_name, python_exec, bench_config): vmstarts = bench_config['vmstarts'] threads = bench_config['threads'] print "## run_benchmark", bench_config + if bench_config['skipvm'] and bench_config['skipvm'] in python_exec: + print "skip benchmark on VM: skipvm =", bench_config['skipvm'] + return [{'cmd': 'none', 'exception': 'skipvm'}], [] failures = [] timings = [] - retries = 0 for ts in threads: + timeout = False vm = 0 + retries = 0 while vm < vmstarts: print "threads: %s, vm: %s" % (ts, vm) + if timeout: + print "stop", bench_name, "because of timeout" + break bench_file = os.path.abspath(bench_config['file']) cmd = ([python_exec, @@ -41,31 +59,57 @@ + bench_config['args']) if WITH_NUMACTL: # run on node 2, allocate preferrably on node 2 - cmd = ["numactl", "-N2", "--preferred=2"] + cmd + cmd = ["numactl", "-N1", "--preferred=1"] + cmd cmd_str = " ".join(cmd) cwd, _ = os.path.split(bench_file) cwd = os.path.join(cwd, bench_config['cwd']) env = os.environ.copy() env['PYTHONPATH'] = bench_config['PYTHONPATH'] + env['JYTHONPATH'] = bench_config['PYTHONPATH'] + env['IRONPYTHONPATH'] = bench_config['PYTHONPATH'] + if STM_LOG: + env['PYPYSTM'] = "log-%s-%s-%s.pypystm" % ( + bench_name, ts, vm) print "running:", cmd_str try: p = Popen(cmd, stdout=PIPE, stderr=PIPE, env=env, cwd=cwd) - # XXX: process could deadlock if stdout pipe is full -> never terminate -> timeout start_time = time.time() + stdout, stderr = "", "" + mems = [] while p.poll() is None: time.sleep(0.5) - if time.time() - start_time > 30 * 60: + stdout += read_all_so_far(p.stdout) + stderr += read_all_so_far(p.stderr) + + try: + process = psutil.Process(p.pid) + mem = process.memory_info().rss + for child in process.children(recursive=True): + mem += child.memory_info().rss + mems.append(mem) + except psutil.NoSuchProcess as e: + print "psutil didn't find the process" + + if time.time() - start_time > 60 * 60: # kill after 30min + print "KILLED AFTER 30min!" + timeout = True p.kill() + raise Exception("Timeout30min") + + stdout += read_all_so_far(p.stdout) + stderr += read_all_so_far(p.stderr) if p.wait() != 0: # error - stdout, stderr = p.stdout.read(), p.stderr.read() + print stdout + print stderr failure = { 'cmd': cmd_str, 'exitcode': p.returncode, + 'mems': mems, 'stdout': stdout, 'stderr': stderr, } @@ -77,13 +121,13 @@ retries += 1 continue # w/o incrementing 'vm' else: - stdout, stderr = p.stdout.read(), p.stderr.read() print stdout iter_times = extract_iter_times(stdout) times = { 'cmd': " ".join(cmd), 'threads': ts, 'vmstarts': vm, + 'mems': mems, 'stdout': stdout, 'stderr': stderr, 'warmiters': iter_times, @@ -110,18 +154,22 @@ bench_config.update(temp_config) try: - failures, timings = run_benchmark( + failures, timings = run_benchmark(bench_key, results['python'], bench_config) except Exception as e: all_results[bench_key] = { 'fail_reason': str(e)} + except KeyboardInterrupt as e: + all_results[bench_key] = { + 'fail_reason': str(e)} else: all_results[bench_key] = { 'failures': failures, 'timings': timings} print bench_key, bench_config - + print "cooldown..." + time.sleep(20) # cooldown @@ -141,7 +189,7 @@ else: results = {} - p = Popen([python_exec, "--version"], + p = Popen([python_exec, "-V"], stdout=PIPE, stderr=PIPE) _, python_version = p.communicate() assert p.returncode == 0 From pypy.commits at gmail.com Thu Jul 11 05:26:19 2019 From: pypy.commits at gmail.com (Stian Andreassen) Date: Thu, 11 Jul 2019 02:26:19 -0700 (PDT) Subject: [pypy-commit] pypy default: ~1% speedup to GCD. Message-ID: <5d2700bb.1c69fb81.8c1f9.7572@mx.google.com> Author: Stian Andreassen Branch: Changeset: r96962:f138227813b8 Date: 2019-07-10 22:41 +0200 http://bitbucket.org/pypy/pypy/changeset/f138227813b8/ Log: ~1% speedup to GCD. diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py --- a/rpython/rlib/rbigint.py +++ b/rpython/rlib/rbigint.py @@ -3013,7 +3013,7 @@ a, b = b, a while b.size > 1: - a_ms = a.digit(a.size-1) + a_ms = a.digit(abs(a.size-1)) x = 0 while a_ms & (0xFF << SHIFT-8) == 0: @@ -3024,12 +3024,12 @@ a_ms <<= 1 x += 1 - a_ms |= a.digit(a.size-2) >> SHIFT-x + a_ms |= a.digit(abs(a.size-2)) >> SHIFT-x if a.size == b.size: - b_ms = (b.digit(b.size-1) << x) | (b.digit(b.size-2) >> SHIFT-x) + b_ms = (b.digit(abs(b.size-1)) << x) | (b.digit(abs(b.size-2)) >> SHIFT-x) elif a.size == b.size+1: - b_ms = b.digit(b.size-1) >> SHIFT-x + b_ms = b.digit(abs(b.size-1)) >> SHIFT-x else: b_ms = 0 From pypy.commits at gmail.com Thu Jul 11 05:26:22 2019 From: pypy.commits at gmail.com (cfbolz) Date: Thu, 11 Jul 2019 02:26:22 -0700 (PDT) Subject: [pypy-commit] pypy default: make gcd_binary not support negative arguments, because abs(-sys.maxint-1) Message-ID: <5d2700be.1c69fb81.d637e.7c14@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: Changeset: r96963:48b1e608e2a2 Date: 2019-07-11 11:18 +0200 http://bitbucket.org/pypy/pypy/changeset/48b1e608e2a2/ Log: make gcd_binary not support negative arguments, because abs(-sys.maxint-1) overflows. raise ValueError instead. diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py --- a/rpython/rlib/rbigint.py +++ b/rpython/rlib/rbigint.py @@ -2969,13 +2969,16 @@ def gcd_binary(a, b): + """ Compute the greatest common divisor of non-negative integers a and b + using the binary GCD algorithm. Raises ValueError on negative input. """ if a == 0: return b if b == 0: return a - a, b = abs(a), abs(b) + if a < 0 or b < 0: + raise ValueError shift = 0 while (a | b) & 1 == 0: diff --git a/rpython/rlib/test/test_rbigint.py b/rpython/rlib/test/test_rbigint.py --- a/rpython/rlib/test/test_rbigint.py +++ b/rpython/rlib/test/test_rbigint.py @@ -839,13 +839,13 @@ def test_gcd(self): assert gcd_binary(2*3*7**2, 2**2*7) == 2*7 - assert gcd_binary(-2*3*7**2, 2**2*7) == 2*7 assert gcd_binary(2*3*7**2, -2**2*7) == 2*7 - assert gcd_binary(-2*3*7**2, -2**2*7) == 2*7 assert gcd_binary(1234, 5678) == 2 assert gcd_binary(13, 13**6) == 13 assert gcd_binary(12, 0) == 12 assert gcd_binary(0, 0) == 0 + assert pytest.raises(ValueError, gcd_binary, -10, 0) + assert pytest.raises(ValueError, gcd_binary, 10, -10) x = rbigint.fromlong(9969216677189303386214405760200) y = rbigint.fromlong(16130531424904581415797907386349) From pypy.commits at gmail.com Thu Jul 11 05:26:24 2019 From: pypy.commits at gmail.com (cfbolz) Date: Thu, 11 Jul 2019 02:26:24 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: merge default Message-ID: <5d2700c0.1c69fb81.536f7.a901@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r96964:fb80c6375d86 Date: 2019-07-11 11:21 +0200 http://bitbucket.org/pypy/pypy/changeset/fb80c6375d86/ Log: merge default diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py --- a/rpython/rlib/rbigint.py +++ b/rpython/rlib/rbigint.py @@ -2969,13 +2969,16 @@ def gcd_binary(a, b): + """ Compute the greatest common divisor of non-negative integers a and b + using the binary GCD algorithm. Raises ValueError on negative input. """ if a == 0: return b if b == 0: return a - a, b = abs(a), abs(b) + if a < 0 or b < 0: + raise ValueError shift = 0 while (a | b) & 1 == 0: diff --git a/rpython/rlib/test/test_rbigint.py b/rpython/rlib/test/test_rbigint.py --- a/rpython/rlib/test/test_rbigint.py +++ b/rpython/rlib/test/test_rbigint.py @@ -839,13 +839,13 @@ def test_gcd(self): assert gcd_binary(2*3*7**2, 2**2*7) == 2*7 - assert gcd_binary(-2*3*7**2, 2**2*7) == 2*7 assert gcd_binary(2*3*7**2, -2**2*7) == 2*7 - assert gcd_binary(-2*3*7**2, -2**2*7) == 2*7 assert gcd_binary(1234, 5678) == 2 assert gcd_binary(13, 13**6) == 13 assert gcd_binary(12, 0) == 12 assert gcd_binary(0, 0) == 0 + assert pytest.raises(ValueError, gcd_binary, -10, 0) + assert pytest.raises(ValueError, gcd_binary, 10, -10) x = rbigint.fromlong(9969216677189303386214405760200) y = rbigint.fromlong(16130531424904581415797907386349) From pypy.commits at gmail.com Thu Jul 11 05:26:25 2019 From: pypy.commits at gmail.com (cfbolz) Date: Thu, 11 Jul 2019 02:26:25 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: (cfbolz, Luanna): fix subtle bug I introduced: abs(-sys.maxint-1) overflows, Message-ID: <5d2700c1.1c69fb81.8eca7.e657@mx.google.com> Author: Carl Friedrich Bolz-Tereick Branch: py3.6 Changeset: r96965:287ec611c0dc Date: 2019-07-11 11:25 +0200 http://bitbucket.org/pypy/pypy/changeset/287ec611c0dc/ Log: (cfbolz, Luanna): fix subtle bug I introduced: abs(-sys.maxint-1) overflows, the the bigint version of the code needs to be used for it. Thanks Luanna for pointing that out. diff --git a/pypy/module/math/interp_math.py b/pypy/module/math/interp_math.py --- a/pypy/module/math/interp_math.py +++ b/pypy/module/math/interp_math.py @@ -489,13 +489,11 @@ def gcd(space, w_a, w_b): """greatest common divisor of a and b""" from rpython.rlib import rbigint - w_a = space.index(w_a) - w_b = space.index(w_b) + w_a = space.abs(space.index(w_a)) + w_b = space.abs(space.index(w_b)) try: a = space.int_w(w_a) b = space.int_w(w_b) - g = rbigint.gcd_binary(a, b) - return space.newint(g) except OperationError as e: if not e.match(space, space.w_OverflowError): raise @@ -504,3 +502,6 @@ b = space.bigint_w(w_b) g = a.gcd(b) return space.newlong_from_rbigint(g) + else: + g = rbigint.gcd_binary(a, b) + return space.newint(g) diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -1,6 +1,5 @@ -from __future__ import with_statement - import py +import sys from pypy.interpreter.function import Function from pypy.interpreter.gateway import BuiltinCode from pypy.module.math.test import test_direct @@ -18,6 +17,7 @@ filename = filename[:-1] space = cls.space cls.w_math_cases = space.wrap(filename) + cls.w_maxint = space.wrap(sys.maxint) @classmethod def make_callable_wrapper(cls, func): @@ -374,6 +374,9 @@ assert math.gcd(-3**10*5**20*11**8, 2**5*3**5*7**20) == 3**5 assert math.gcd(64, 200) == 8 + assert math.gcd(-self.maxint-1, 3) == 1 + assert math.gcd(-self.maxint-1, -self.maxint-1) == self.maxint+1 + def test_inf_nan(self): import math assert math.isinf(math.inf) From pypy.commits at gmail.com Fri Jul 12 08:28:54 2019 From: pypy.commits at gmail.com (arigo) Date: Fri, 12 Jul 2019 05:28:54 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Issue #3043 Message-ID: <5d287d06.1c69fb81.c6489.cbda@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96966:17c92b183a23 Date: 2019-07-12 14:27 +0200 http://bitbucket.org/pypy/pypy/changeset/17c92b183a23/ Log: Issue #3043 Support Py_RETURN_NOTIMPLEMENTED diff --git a/pypy/module/cpyext/include/object.h b/pypy/module/cpyext/include/object.h --- a/pypy/module/cpyext/include/object.h +++ b/pypy/module/cpyext/include/object.h @@ -13,6 +13,8 @@ #define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1) #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None +#define Py_RETURN_NOTIMPLEMENTED \ + return Py_INCREF(Py_NotImplemented), Py_NotImplemented /* CPython has this for backwards compatibility with really old extensions, and now From pypy.commits at gmail.com Sat Jul 13 05:43:34 2019 From: pypy.commits at gmail.com (fijal) Date: Sat, 13 Jul 2019 02:43:34 -0700 (PDT) Subject: [pypy-commit] pypy arm64: write stack check slowpath Message-ID: <5d29a7c6.1c69fb81.11a25.d823@mx.google.com> Author: fijal Branch: arm64 Changeset: r96967:1c73a29467e5 Date: 2019-07-13 11:42 +0200 http://bitbucket.org/pypy/pypy/changeset/1c73a29467e5/ Log: write stack check slowpath diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -837,7 +837,60 @@ def _build_stack_check_slowpath(self): - self.stack_check_slowpath = 0 #XXX + _, _, slowpathaddr = self.cpu.insert_stack_check() + if slowpathaddr == 0 or not self.cpu.propagate_exception_descr: + return # no stack check (for tests, or non-translated) + # + # make a "function" that is called immediately at the start of + # an assembler function. In particular, the stack looks like: + # + # | retaddr of caller | <-- aligned to a multiple of 16 + # | saved argument regs | + # | my own retaddr | <-- sp + # +-----------------------+ + # + mc = InstrBuilder() + # save argument registers and return address + mc.SUB_ri(r.sp.value, r.sp.value, (len(r.argument_regs) + 2) * WORD) + mc.STR_ri(r.lr.value, r.sp.value, 0) + for i in range(0, len(r.argument_regs), 2): + mc.STP_rri(r.argument_regs[i].value, r.argument_regs[i + 1].value, + r.sp.value, (i + 2) * WORD) + # stack is aligned here + # Pass current stack pointer as argument to the call + mc.MOV_rr(r.x0.value, r.sp.value) + # + mc.BL(slowpathaddr) + + # check for an exception + mc.gen_load_int(r.x0.value, self.cpu.pos_exception()) + mc.LDR_ri(r.x0.value, r.x0.value, 0) + mc.TST_rr_shift(r.x0.value, r.x0.value, 0) + # + # restore registers and return + # We check for c.EQ here, meaning all bits zero in this case + + jmp = mc.currpos() + mc.BRK() + + for i in range(0, len(r.argument_regs), 2): + mc.LDP_rri(r.argument_regs[i].value, r.argument_regs[i + 1].value, + r.sp.value, (i + 2) * WORD) + mc.LDR_ri(r.ip0.value, r.sp.value, 0) + mc.ADD_ri(r.sp.value, r.sp.value, (len(r.argument_regs) + 2) * WORD) + mc.RET_r(r.ip0.value) + + # jump here + + mc.ADD_ri(r.sp.value, r.sp.value, (len(r.argument_regs) + 2) * WORD) + mc.B(self.propagate_exception_path) + # + + pmc = OverwritingBuilder(mc, jmp, WORD) + pmc.B_ofs_cond(mc.currpos() - mc, c.NE) + + rawstart = mc.materialize(self.cpu, []) + self.stack_check_slowpath = rawstart def _check_frame_depth_debug(self, mc): pass From pypy.commits at gmail.com Sat Jul 13 05:51:16 2019 From: pypy.commits at gmail.com (fijal) Date: Sat, 13 Jul 2019 02:51:16 -0700 (PDT) Subject: [pypy-commit] pypy arm64: oops Message-ID: <5d29a994.1c69fb81.f0936.1aab@mx.google.com> Author: fijal Branch: arm64 Changeset: r96968:2deb2cef5345 Date: 2019-07-13 11:50 +0200 http://bitbucket.org/pypy/pypy/changeset/2deb2cef5345/ Log: oops diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -887,7 +887,7 @@ # pmc = OverwritingBuilder(mc, jmp, WORD) - pmc.B_ofs_cond(mc.currpos() - mc, c.NE) + pmc.B_ofs_cond(mc.currpos() - jmp, c.NE) rawstart = mc.materialize(self.cpu, []) self.stack_check_slowpath = rawstart From pypy.commits at gmail.com Sat Jul 13 06:09:46 2019 From: pypy.commits at gmail.com (fijal) Date: Sat, 13 Jul 2019 03:09:46 -0700 (PDT) Subject: [pypy-commit] pypy arm64: fix the jump Message-ID: <5d29adea.1c69fb81.32e4f.f404@mx.google.com> Author: fijal Branch: arm64 Changeset: r96969:b7c685938bc8 Date: 2019-07-13 12:09 +0200 http://bitbucket.org/pypy/pypy/changeset/b7c685938bc8/ Log: fix the jump diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -1076,8 +1076,11 @@ self.mc.SUB_rr(r.ip0.value, r.ip0.value, r.sp.value) # SUB ip, current # if ofs self.mc.CMP_rr(r.ip0.value, r.ip1.value) # CMP ip, lr - self.mc.B_ofs_cond(4 + 2, c.LS) + pos = self.mc.currpos() + self.mc.BRK() self.mc.B(self.stack_check_slowpath) # call if ip > lr + pmc = OverwritingBuilder(self.mc, pos, WORD) + pmc.B_ofs_cond(self.mc.currpos() - pos, c.LS) def _call_header(self): stack_size = (len(r.callee_saved_registers) + 4) * WORD From pypy.commits at gmail.com Sat Jul 13 06:54:51 2019 From: pypy.commits at gmail.com (fijal) Date: Sat, 13 Jul 2019 03:54:51 -0700 (PDT) Subject: [pypy-commit] pypy arm64: we can't use sp here, rewrite' Message-ID: <5d29b87b.1c69fb81.4e1ae.37fe@mx.google.com> Author: fijal Branch: arm64 Changeset: r96971:b0b99e2d256f Date: 2019-07-13 12:54 +0200 http://bitbucket.org/pypy/pypy/changeset/b0b99e2d256f/ Log: we can't use sp here, rewrite' diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -888,7 +888,7 @@ mc.ADD_ri(r.sp.value, r.sp.value, (len(r.argument_regs) + 2) * WORD) mc.B(self.propagate_exception_path) # - + rawstart = mc.materialize(self.cpu, []) self.stack_check_slowpath = rawstart @@ -1067,18 +1067,19 @@ else: endaddr, lengthaddr, _ = self.cpu.insert_stack_check() # load stack end - self.mc.gen_load_int(r.ip0.value, endaddr) # load ip0, [end] - self.mc.LDR_ri(r.ip0.value, r.ip0.value, 0) # LDR ip0, ip0 + self.mc.gen_load_int(r.lr.value, endaddr) # load lr, [end] + self.mc.LDR_ri(r.lr.value, r.lr.value, 0) # LDR lr, lr # load stack length self.mc.gen_load_int(r.ip1.value, lengthaddr) # load ip1, lengh self.mc.LDR_ri(r.ip1.value, r.ip1.value, 0) # ldr ip1, *lengh # calculate ofs - self.mc.SUB_rr(r.ip0.value, r.ip0.value, r.sp.value) # SUB ip, current + self.mc.SUB_ri(r.ip0.value, r.sp.value, 0) # ip0 = sp, otherwise we can't use sp + self.mc.SUB_rr(r.lr.value, r.lr.value, r.ip0.value) # lr = lr - ip0 # if ofs - self.mc.CMP_rr(r.ip0.value, r.ip1.value) # CMP ip, lr + self.mc.CMP_rr(r.lr.value, r.ip1.value) # CMP ip0, ip1 pos = self.mc.currpos() self.mc.BRK() - self.mc.B(self.stack_check_slowpath) # call if ip > lr + self.mc.B(self.stack_check_slowpath) # call if ip0 > ip1 pmc = OverwritingBuilder(self.mc, pos, WORD) pmc.B_ofs_cond(self.mc.currpos() - pos, c.LS) From pypy.commits at gmail.com Sat Jul 13 07:29:27 2019 From: pypy.commits at gmail.com (fijal) Date: Sat, 13 Jul 2019 04:29:27 -0700 (PDT) Subject: [pypy-commit] pypy arm64: make this encodable Message-ID: <5d29c097.1c69fb81.c9c31.750e@mx.google.com> Author: fijal Branch: arm64 Changeset: r96973:2417f925ce94 Date: 2019-07-13 13:28 +0200 http://bitbucket.org/pypy/pypy/changeset/2417f925ce94/ Log: make this encodable diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -1076,7 +1076,7 @@ # note that we use a small constant here, because in unlikely circumstances, # the LL_stack_too_big is called with some stack consumed so it goes *just* # past that and the check is below 0 - self.mc.SUB_ri(r.ip0.value, r.sp.value, 4096) # ip0 = sp - small_const, + self.mc.SUB_ri(r.ip0.value, r.sp.value, 4095) # ip0 = sp - small_const, # otherwise we can't use sp self.mc.SUB_rr(r.lr.value, r.lr.value, r.ip0.value) # lr = lr - ip0 # if ofs From pypy.commits at gmail.com Sat Jul 13 08:10:09 2019 From: pypy.commits at gmail.com (rlamy) Date: Sat, 13 Jul 2019 05:10:09 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Merged in csernazs/pypy/py3.6-socket-fix (pull request #650) Message-ID: <5d29ca21.1c69fb81.cc93b.3469@mx.google.com> Author: Ronan Lamy Branch: py3.6 Changeset: r96975:d21bd7fc4483 Date: 2019-07-13 12:09 +0000 http://bitbucket.org/pypy/pypy/changeset/d21bd7fc4483/ Log: Merged in csernazs/pypy/py3.6-socket-fix (pull request #650) fix AppTestSocket.().test_invalid_fd diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -198,16 +198,16 @@ self.register_finalizer(space) @unwrap_spec(family=int, type=int, proto=int, - w_fdobj=WrappedDefault(None)) + w_fileno=WrappedDefault(None)) def descr_init(self, space, family=AF_INET, type=SOCK_STREAM, proto=0, - w_fdobj=None): + w_fileno=None): try: - if not space.is_w(w_fdobj, space.w_None): - if _WIN32 and space.isinstance_w(w_fdobj, space.w_bytes): + if not space.is_w(w_fileno, space.w_None): + if _WIN32 and space.isinstance_w(w_fileno, space.w_bytes): from rpython.rlib.rsocket import _c # it is possible to pass some bytes representing a socket # in the file descriptor object on winodws - fdobj = space.bytes_w(w_fdobj) + fdobj = space.bytes_w(w_fileno) info_charptr = rffi.str2charp(fdobj) try: info_ptr = rffi.cast(lltype.Ptr(_c.WSAPROTOCOL_INFOW), info_charptr) @@ -220,7 +220,7 @@ lltype.free(info_charptr, flavor='raw') else: sock = RSocket(family, type, proto, - fd=space.c_filedescriptor_w(w_fdobj)) + fd=space.c_filedescriptor_w(w_fileno)) else: sock = RSocket(family, type, proto, inheritable=False) W_Socket.__init__(self, space, sock) From pypy.commits at gmail.com Sat Jul 13 08:10:18 2019 From: pypy.commits at gmail.com (csernazs) Date: Sat, 13 Jul 2019 05:10:18 -0700 (PDT) Subject: [pypy-commit] pypy py3.6-socket-fix: fix AppTestSocket.().test_invalid_fd Message-ID: <5d29ca2a.1c69fb81.ae4ad.92a8@mx.google.com> Author: Zsolt Cserna Branch: py3.6-socket-fix Changeset: r96974:cb0f4d2e2faf Date: 2019-07-13 11:52 +0200 http://bitbucket.org/pypy/pypy/changeset/cb0f4d2e2faf/ Log: fix AppTestSocket.().test_invalid_fd Rename the kwarg from fdobj to fileno. fdobj comes from the C implementation of _socket in cpython but the test specifies it by keyword so it needs to be changed accordingly. diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py --- a/pypy/module/_socket/interp_socket.py +++ b/pypy/module/_socket/interp_socket.py @@ -198,16 +198,16 @@ self.register_finalizer(space) @unwrap_spec(family=int, type=int, proto=int, - w_fdobj=WrappedDefault(None)) + w_fileno=WrappedDefault(None)) def descr_init(self, space, family=AF_INET, type=SOCK_STREAM, proto=0, - w_fdobj=None): + w_fileno=None): try: - if not space.is_w(w_fdobj, space.w_None): - if _WIN32 and space.isinstance_w(w_fdobj, space.w_bytes): + if not space.is_w(w_fileno, space.w_None): + if _WIN32 and space.isinstance_w(w_fileno, space.w_bytes): from rpython.rlib.rsocket import _c # it is possible to pass some bytes representing a socket # in the file descriptor object on winodws - fdobj = space.bytes_w(w_fdobj) + fdobj = space.bytes_w(w_fileno) info_charptr = rffi.str2charp(fdobj) try: info_ptr = rffi.cast(lltype.Ptr(_c.WSAPROTOCOL_INFOW), info_charptr) @@ -220,7 +220,7 @@ lltype.free(info_charptr, flavor='raw') else: sock = RSocket(family, type, proto, - fd=space.c_filedescriptor_w(w_fdobj)) + fd=space.c_filedescriptor_w(w_fileno)) else: sock = RSocket(family, type, proto, inheritable=False) W_Socket.__init__(self, space, sock) From pypy.commits at gmail.com Sat Jul 13 10:33:08 2019 From: pypy.commits at gmail.com (rlamy) Date: Sat, 13 Jul 2019 07:33:08 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Merged in ykiprov/pypy/remove_array_with_char_test (pull request #651) Message-ID: <5d29eba4.1c69fb81.409b9.bf3c@mx.google.com> Author: Ronan Lamy Branch: py3.6 Changeset: r96977:a822ed1ebccb Date: 2019-07-13 14:32 +0000 http://bitbucket.org/pypy/pypy/changeset/a822ed1ebccb/ Log: Merged in ykiprov/pypy/remove_array_with_char_test (pull request #651) removed array of chars test as this was removed in python3 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 @@ -892,13 +892,6 @@ assert repr(mya('i', [1, 2, 3])) == "array('i', [1, 2, 3])" assert repr(mya('i', (1, 2, 3))) == "array('i', [1, 2, 3])" - def test_array_of_chars_equality(self): - input_bytes = '\x01\x63a\x00!' - a = self.array('c', input_bytes) - b = self.array('c', input_bytes) - b.byteswap() - assert a == b - def test_unicode_outofrange(self): input_unicode = u'\x01\u263a\x00\ufeff' a = self.array('u', input_unicode) From pypy.commits at gmail.com Sat Jul 13 10:33:15 2019 From: pypy.commits at gmail.com (ykiprov) Date: Sat, 13 Jul 2019 07:33:15 -0700 (PDT) Subject: [pypy-commit] pypy remove_array_with_char_test: removed test_array_of_chars_equality as it's not supported in python 3 Message-ID: <5d29ebab.1c69fb81.39b2e.fad7@mx.google.com> Author: Yasen Kiprov Branch: remove_array_with_char_test Changeset: r96976:11a99a383873 Date: 2019-07-13 08:12 -0400 http://bitbucket.org/pypy/pypy/changeset/11a99a383873/ Log: removed test_array_of_chars_equality as it's not supported in python 3 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 @@ -892,13 +892,6 @@ assert repr(mya('i', [1, 2, 3])) == "array('i', [1, 2, 3])" assert repr(mya('i', (1, 2, 3))) == "array('i', [1, 2, 3])" - def test_array_of_chars_equality(self): - input_bytes = '\x01\x63a\x00!' - a = self.array('c', input_bytes) - b = self.array('c', input_bytes) - b.byteswap() - assert a == b - def test_unicode_outofrange(self): input_unicode = u'\x01\u263a\x00\ufeff' a = self.array('u', input_unicode) From pypy.commits at gmail.com Sat Jul 13 10:35:06 2019 From: pypy.commits at gmail.com (rlamy) Date: Sat, 13 Jul 2019 07:35:06 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Merged in mkuffa/pypy/fix-importerror (pull request #652) Message-ID: <5d29ec1a.1c69fb81.ae4ad.a857@mx.google.com> Author: Ronan Lamy Branch: py3.6 Changeset: r96981:d8a0f174215c Date: 2019-07-13 14:34 +0000 http://bitbucket.org/pypy/pypy/changeset/d8a0f174215c/ Log: Merged in mkuffa/pypy/fix-importerror (pull request #652) Fix ImportError invalid arguments error wording diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -96,7 +96,7 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.pytraceback import PyTraceback, check_traceback -from rpython.rlib import rwin32 +from rpython.rlib import rwin32, jit def readwrite_attrproperty_w(name, cls): @@ -323,14 +323,20 @@ w_name = None w_path = None + @jit.unroll_safe def descr_init(self, space, __args__): args_w, kw_w = __args__.unpack() self.w_name = kw_w.pop('name', space.w_None) self.w_path = kw_w.pop('path', space.w_None) if kw_w: - # CPython displays this, but it's not quite right. - raise oefmt(space.w_TypeError, - "ImportError does not take keyword arguments") + for keyword in __args__.keywords: + if keyword in kw_w: + raise oefmt( + space.w_TypeError, + "'%s' is an invalid keyword argument for this function" % ( + keyword + ) + ) W_Exception.descr_init(self, space, args_w) diff --git a/pypy/module/exceptions/test/test_exc.py b/pypy/module/exceptions/test/test_exc.py --- a/pypy/module/exceptions/test/test_exc.py +++ b/pypy/module/exceptions/test/test_exc.py @@ -437,3 +437,24 @@ exc = raises(SyntaxError, exec_, source) assert (custom_msg not in exc.value.msg) == ( ('print (' in source or 'exec (' in source)) + + def test_importerror_kwarg_error(self): + msg = "'invalid' is an invalid keyword argument for this function" + exc = raises(TypeError, + ImportError, + 'test', invalid='keyword', another=True) + assert str(exc.value) == msg + + exc = raises(TypeError, ImportError, 'test', invalid='keyword') + assert str(exc.value) == msg + + exc = raises(TypeError, + ImportError, + 'test', name='name', invalid='keyword') + assert str(exc.value) == msg + + exc = raises(TypeError, + ImportError, + 'test', path='path', invalid='keyword') + assert str(exc.value) == msg + From pypy.commits at gmail.com Sat Jul 13 10:35:15 2019 From: pypy.commits at gmail.com (beezz) Date: Sat, 13 Jul 2019 07:35:15 -0700 (PDT) Subject: [pypy-commit] pypy fix-importerror: Fix ImportError invalid arguments error wording Message-ID: <5d29ec23.1c69fb81.95a61.ef0e@mx.google.com> Author: Michal Kuffa Branch: fix-importerror Changeset: r96978:5f86d11cfec0 Date: 2019-07-13 14:58 +0200 http://bitbucket.org/pypy/pypy/changeset/5f86d11cfec0/ Log: Fix ImportError invalid arguments error wording diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -328,9 +328,14 @@ self.w_name = kw_w.pop('name', space.w_None) self.w_path = kw_w.pop('path', space.w_None) if kw_w: - # CPython displays this, but it's not quite right. - raise oefmt(space.w_TypeError, - "ImportError does not take keyword arguments") + for keyword in __args__.keywords: + if keyword in kw_w: + raise oefmt( + space.w_TypeError, + "'%s' is an invalid keyword argument for this function" % ( + keyword + ) + ) W_Exception.descr_init(self, space, args_w) diff --git a/pypy/module/exceptions/test/test_exc.py b/pypy/module/exceptions/test/test_exc.py --- a/pypy/module/exceptions/test/test_exc.py +++ b/pypy/module/exceptions/test/test_exc.py @@ -437,3 +437,24 @@ exc = raises(SyntaxError, exec_, source) assert (custom_msg not in exc.value.msg) == ( ('print (' in source or 'exec (' in source)) + + def test_importerror_kwarg_error(self): + msg = "'invalid' is an invalid keyword argument for this function" + exc = raises(TypeError, + ImportError, + 'test', invalid='keyword', another=True) + assert str(exc.value) == msg + + exc = raises(TypeError, ImportError, 'test', invalid='keyword') + assert str(exc.value) == msg + + exc = raises(TypeError, + ImportError, + 'test', name='name', invalid='keyword') + assert str(exc.value) == msg + + exc = raises(TypeError, + ImportError, + 'test', path='path', invalid='keyword') + assert str(exc.value) == msg + From pypy.commits at gmail.com Sat Jul 13 10:35:16 2019 From: pypy.commits at gmail.com (beezz) Date: Sat, 13 Jul 2019 07:35:16 -0700 (PDT) Subject: [pypy-commit] pypy fix-importerror: Fix ImportError invalid arguments error wording Message-ID: <5d29ec24.1c69fb81.f0936.ba7b@mx.google.com> Author: Michal Kuffa Branch: fix-importerror Changeset: r96979:01e15fee01df Date: 2019-07-13 14:58 +0200 http://bitbucket.org/pypy/pypy/changeset/01e15fee01df/ Log: Fix ImportError invalid arguments error wording diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -96,7 +96,7 @@ from pypy.interpreter.gateway import interp2app, unwrap_spec from pypy.interpreter.error import OperationError, oefmt from pypy.interpreter.pytraceback import PyTraceback, check_traceback -from rpython.rlib import rwin32 +from rpython.rlib import rwin32, jit def readwrite_attrproperty_w(name, cls): @@ -323,14 +323,20 @@ w_name = None w_path = None + @jit.unroll_safe def descr_init(self, space, __args__): args_w, kw_w = __args__.unpack() self.w_name = kw_w.pop('name', space.w_None) self.w_path = kw_w.pop('path', space.w_None) if kw_w: - # CPython displays this, but it's not quite right. - raise oefmt(space.w_TypeError, - "ImportError does not take keyword arguments") + for keyword in __args__.keywords: + if keyword in kw_w: + raise oefmt( + space.w_TypeError, + "'%s' is an invalid keyword argument for this function" % ( + keyword + ) + ) W_Exception.descr_init(self, space, args_w) diff --git a/pypy/module/exceptions/test/test_exc.py b/pypy/module/exceptions/test/test_exc.py --- a/pypy/module/exceptions/test/test_exc.py +++ b/pypy/module/exceptions/test/test_exc.py @@ -437,3 +437,24 @@ exc = raises(SyntaxError, exec_, source) assert (custom_msg not in exc.value.msg) == ( ('print (' in source or 'exec (' in source)) + + def test_importerror_kwarg_error(self): + msg = "'invalid' is an invalid keyword argument for this function" + exc = raises(TypeError, + ImportError, + 'test', invalid='keyword', another=True) + assert str(exc.value) == msg + + exc = raises(TypeError, ImportError, 'test', invalid='keyword') + assert str(exc.value) == msg + + exc = raises(TypeError, + ImportError, + 'test', name='name', invalid='keyword') + assert str(exc.value) == msg + + exc = raises(TypeError, + ImportError, + 'test', path='path', invalid='keyword') + assert str(exc.value) == msg + From pypy.commits at gmail.com Sat Jul 13 10:35:18 2019 From: pypy.commits at gmail.com (mkuffa) Date: Sat, 13 Jul 2019 07:35:18 -0700 (PDT) Subject: [pypy-commit] pypy fix-importerror: Merge heads Message-ID: <5d29ec26.1c69fb81.d2d83.7e77@mx.google.com> Author: mkuffa Branch: fix-importerror Changeset: r96980:b4a2954b5ff9 Date: 2019-07-13 16:19 +0200 http://bitbucket.org/pypy/pypy/changeset/b4a2954b5ff9/ Log: Merge heads From pypy.commits at gmail.com Sun Jul 14 03:40:26 2019 From: pypy.commits at gmail.com (fijal) Date: Sun, 14 Jul 2019 00:40:26 -0700 (PDT) Subject: [pypy-commit] pypy arm64: remove small constant and use BL instead of B Message-ID: <5d2adc6a.1c69fb81.9f97b.baaf@mx.google.com> Author: fijal Branch: arm64 Changeset: r96982:79faaac359a0 Date: 2019-07-14 09:39 +0200 http://bitbucket.org/pypy/pypy/changeset/79faaac359a0/ Log: remove small constant and use BL instead of B diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -1073,17 +1073,14 @@ self.mc.gen_load_int(r.ip1.value, lengthaddr) # load ip1, lengh self.mc.LDR_ri(r.ip1.value, r.ip1.value, 0) # ldr ip1, *lengh # calculate ofs - # note that we use a small constant here, because in unlikely circumstances, - # the LL_stack_too_big is called with some stack consumed so it goes *just* - # past that and the check is below 0 - self.mc.SUB_ri(r.ip0.value, r.sp.value, 4095) # ip0 = sp - small_const, + self.mc.SUB_ri(r.ip0.value, r.sp.value, 0) # ip0 = sp # otherwise we can't use sp self.mc.SUB_rr(r.lr.value, r.lr.value, r.ip0.value) # lr = lr - ip0 # if ofs self.mc.CMP_rr(r.lr.value, r.ip1.value) # CMP ip0, ip1 pos = self.mc.currpos() self.mc.BRK() - self.mc.B(self.stack_check_slowpath) # call if ip0 > ip1 + self.mc.BL(self.stack_check_slowpath) # call if ip0 > ip1 pmc = OverwritingBuilder(self.mc, pos, WORD) pmc.B_ofs_cond(self.mc.currpos() - pos, c.LS) From pypy.commits at gmail.com Sun Jul 14 04:11:41 2019 From: pypy.commits at gmail.com (rlamy) Date: Sun, 14 Jul 2019 01:11:41 -0700 (PDT) Subject: [pypy-commit] pypy default: Merged in ivan257/pypy/fix_darwin_list_dir_test (pull request #653) Message-ID: <5d2ae3bd.1c69fb81.d6304.a253@mx.google.com> Author: Ronan Lamy Branch: Changeset: r96984:4e0d2e9d1e7d Date: 2019-07-14 08:11 +0000 http://bitbucket.org/pypy/pypy/changeset/4e0d2e9d1e7d/ Log: Merged in ivan257/pypy/fix_darwin_list_dir_test (pull request #653) Fix test_list_dir_unicode on macOS utf-8 encoded systems diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -372,15 +372,24 @@ result = posix.listdir(unicode_dir) typed_result = [(type(x), x) for x in result] assert (unicode, u'somefile') in typed_result + file_system_encoding = sys.getfilesystemencoding() try: - u = "caf\xe9".decode(sys.getfilesystemencoding()) + u = "caf\xe9".decode(file_system_encoding) except UnicodeDecodeError: # Could not decode, listdir returned the byte string if sys.platform != 'darwin': assert (str, "caf\xe9") in typed_result else: - # darwin 'normalized' it - assert (unicode, 'caf%E9') in typed_result + # if the test is being run in an utf-8 encoded macOS + # the posix.listdir function is returning the name of + # the file properly. + # This test should be run in multiple macOS platforms to + # be sure that is working as expected. + if file_system_encoding == 'UTF-8': + assert (unicode, 'cafxe9') in typed_result + else: + # darwin 'normalized' it + assert (unicode, 'caf%E9') in typed_result else: assert (unicode, u) in typed_result From pypy.commits at gmail.com Sun Jul 14 04:11:49 2019 From: pypy.commits at gmail.com (ivan257) Date: Sun, 14 Jul 2019 01:11:49 -0700 (PDT) Subject: [pypy-commit] pypy fix_darwin_list_dir_test: Fix test_list_dir_unicode on macOS utf-8 encoded systems Message-ID: <5d2ae3c5.1c69fb81.74c54.1dba@mx.google.com> Author: Ivan Branch: fix_darwin_list_dir_test Changeset: r96983:d1ec1e6fa480 Date: 2019-07-13 17:13 +0200 http://bitbucket.org/pypy/pypy/changeset/d1ec1e6fa480/ Log: Fix test_list_dir_unicode on macOS utf-8 encoded systems diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py --- a/pypy/module/posix/test/test_posix2.py +++ b/pypy/module/posix/test/test_posix2.py @@ -372,15 +372,24 @@ result = posix.listdir(unicode_dir) typed_result = [(type(x), x) for x in result] assert (unicode, u'somefile') in typed_result + file_system_encoding = sys.getfilesystemencoding() try: - u = "caf\xe9".decode(sys.getfilesystemencoding()) + u = "caf\xe9".decode(file_system_encoding) except UnicodeDecodeError: # Could not decode, listdir returned the byte string if sys.platform != 'darwin': assert (str, "caf\xe9") in typed_result else: - # darwin 'normalized' it - assert (unicode, 'caf%E9') in typed_result + # if the test is being run in an utf-8 encoded macOS + # the posix.listdir function is returning the name of + # the file properly. + # This test should be run in multiple macOS platforms to + # be sure that is working as expected. + if file_system_encoding == 'UTF-8': + assert (unicode, 'cafxe9') in typed_result + else: + # darwin 'normalized' it + assert (unicode, 'caf%E9') in typed_result else: assert (unicode, u) in typed_result From pypy.commits at gmail.com Sun Jul 14 04:13:49 2019 From: pypy.commits at gmail.com (rlamy) Date: Sun, 14 Jul 2019 01:13:49 -0700 (PDT) Subject: [pypy-commit] pypy default: Merged in jesdi/pypy/fix-test-vmprof-closed-file (pull request #654) Message-ID: <5d2ae43d.1c69fb81.f48b6.3b8c@mx.google.com> Author: Ronan Lamy Branch: Changeset: r96986:a9166640dc56 Date: 2019-07-14 08:13 +0000 http://bitbucket.org/pypy/pypy/changeset/a9166640dc56/ Log: Merged in jesdi/pypy/fix-test-vmprof-closed-file (pull request #654) Fix test reading file not open. diff --git a/pypy/module/_vmprof/test/test__vmprof.py b/pypy/module/_vmprof/test/test__vmprof.py --- a/pypy/module/_vmprof/test/test__vmprof.py +++ b/pypy/module/_vmprof/test/test__vmprof.py @@ -111,14 +111,17 @@ @py.test.mark.xfail(sys.platform.startswith('freebsd'), reason = "not implemented") def test_get_profile_path(self): import _vmprof - tmpfile = open(self.tmpfilename, 'wb') - assert _vmprof.get_profile_path() is None - _vmprof.enable(tmpfile.fileno(), 0.01, 0, 0, 0, 0) - path = _vmprof.get_profile_path() + with open(self.tmpfilename, "wb") as tmpfile: + assert _vmprof.get_profile_path() is None + _vmprof.enable(tmpfile.fileno(), 0.01, 0, 0, 0, 0) + path = _vmprof.get_profile_path() + _vmprof.disable() + if path != tmpfile.name: with open(path, "rb") as fd1: - assert fd1.read() == tmpfile.read() - _vmprof.disable() + with open(self.tmpfilename, "rb") as fd2: + assert fd1.read() == fd2.read() + assert _vmprof.get_profile_path() is None def test_stop_sampling(self): From pypy.commits at gmail.com Sun Jul 14 04:13:58 2019 From: pypy.commits at gmail.com (jesdi) Date: Sun, 14 Jul 2019 01:13:58 -0700 (PDT) Subject: [pypy-commit] pypy fix-test-vmprof-closed-file: Fix test. Open file for reading Message-ID: <5d2ae446.1c69fb81.8f6ca.ac20@mx.google.com> Author: Jesdi Branch: fix-test-vmprof-closed-file Changeset: r96985:ea52b93b8671 Date: 2019-07-13 17:56 +0200 http://bitbucket.org/pypy/pypy/changeset/ea52b93b8671/ Log: Fix test. Open file for reading diff --git a/pypy/module/_vmprof/test/test__vmprof.py b/pypy/module/_vmprof/test/test__vmprof.py --- a/pypy/module/_vmprof/test/test__vmprof.py +++ b/pypy/module/_vmprof/test/test__vmprof.py @@ -111,14 +111,17 @@ @py.test.mark.xfail(sys.platform.startswith('freebsd'), reason = "not implemented") def test_get_profile_path(self): import _vmprof - tmpfile = open(self.tmpfilename, 'wb') - assert _vmprof.get_profile_path() is None - _vmprof.enable(tmpfile.fileno(), 0.01, 0, 0, 0, 0) - path = _vmprof.get_profile_path() + with open(self.tmpfilename, "wb") as tmpfile: + assert _vmprof.get_profile_path() is None + _vmprof.enable(tmpfile.fileno(), 0.01, 0, 0, 0, 0) + path = _vmprof.get_profile_path() + _vmprof.disable() + if path != tmpfile.name: with open(path, "rb") as fd1: - assert fd1.read() == tmpfile.read() - _vmprof.disable() + with open(self.tmpfilename, "rb") as fd2: + assert fd1.read() == fd2.read() + assert _vmprof.get_profile_path() is None def test_stop_sampling(self): From pypy.commits at gmail.com Sun Jul 14 04:51:31 2019 From: pypy.commits at gmail.com (rlamy) Date: Sun, 14 Jul 2019 01:51:31 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: fix translation Message-ID: <5d2aed13.1c69fb81.d6304.a775@mx.google.com> Author: Ronan Lamy Branch: py3.6 Changeset: r96987:1131d56115b8 Date: 2019-07-14 10:48 +0200 http://bitbucket.org/pypy/pypy/changeset/1131d56115b8/ Log: fix translation diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py --- a/pypy/module/exceptions/interp_exceptions.py +++ b/pypy/module/exceptions/interp_exceptions.py @@ -333,10 +333,8 @@ if keyword in kw_w: raise oefmt( space.w_TypeError, - "'%s' is an invalid keyword argument for this function" % ( - keyword - ) - ) + "'%s' is an invalid keyword argument for this function", + keyword) W_Exception.descr_init(self, space, args_w) From pypy.commits at gmail.com Sun Jul 14 04:51:52 2019 From: pypy.commits at gmail.com (arigo) Date: Sun, 14 Jul 2019 01:51:52 -0700 (PDT) Subject: [pypy-commit] pypy default: Fix the test and the implementation of gcd_binary() Message-ID: <5d2aed28.1c69fb81.afdf0.487f@mx.google.com> Author: Armin Rigo Branch: Changeset: r96988:c79c569bdd04 Date: 2019-07-14 10:50 +0200 http://bitbucket.org/pypy/pypy/changeset/c79c569bdd04/ Log: Fix the test and the implementation of gcd_binary() diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py --- a/rpython/rlib/rbigint.py +++ b/rpython/rlib/rbigint.py @@ -2971,15 +2971,15 @@ def gcd_binary(a, b): """ Compute the greatest common divisor of non-negative integers a and b using the binary GCD algorithm. Raises ValueError on negative input. """ + if a < 0 or b < 0: + raise ValueError + if a == 0: return b if b == 0: return a - if a < 0 or b < 0: - raise ValueError - shift = 0 while (a | b) & 1 == 0: a >>= 1 diff --git a/rpython/rlib/test/test_rbigint.py b/rpython/rlib/test/test_rbigint.py --- a/rpython/rlib/test/test_rbigint.py +++ b/rpython/rlib/test/test_rbigint.py @@ -839,7 +839,7 @@ def test_gcd(self): assert gcd_binary(2*3*7**2, 2**2*7) == 2*7 - assert gcd_binary(2*3*7**2, -2**2*7) == 2*7 + pytest.raises(ValueError, gcd_binary, 2*3*7**2, -2**2*7) assert gcd_binary(1234, 5678) == 2 assert gcd_binary(13, 13**6) == 13 assert gcd_binary(12, 0) == 12 From pypy.commits at gmail.com Sun Jul 14 05:03:00 2019 From: pypy.commits at gmail.com (fijal) Date: Sun, 14 Jul 2019 02:03:00 -0700 (PDT) Subject: [pypy-commit] pypy arm64: oops Message-ID: <5d2aefc4.1c69fb81.97ed0.f46b@mx.google.com> Author: fijal Branch: arm64 Changeset: r96989:38b3537f3c3f Date: 2019-07-14 11:02 +0200 http://bitbucket.org/pypy/pypy/changeset/38b3537f3c3f/ Log: oops diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -858,7 +858,7 @@ r.sp.value, (i + 2) * WORD) # stack is aligned here # Pass current stack pointer as argument to the call - mc.MOV_rr(r.x0.value, r.sp.value) + mc.SUB_ri(r.x0.value, r.sp.value, 0) # mc.BL(slowpathaddr) From pypy.commits at gmail.com Sun Jul 14 06:56:32 2019 From: pypy.commits at gmail.com (rlamy) Date: Sun, 14 Jul 2019 03:56:32 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Merged in joachim-ballmann/pypy/fix_test_unicode_outofrange (pull request #656) Message-ID: <5d2b0a60.1c69fb81.71575.f4b2@mx.google.com> Author: Ronan Lamy Branch: py3.6 Changeset: r96991:167742e47bab Date: 2019-07-14 10:56 +0000 http://bitbucket.org/pypy/pypy/changeset/167742e47bab/ Log: Merged in joachim-ballmann/pypy/fix_test_unicode_outofrange (pull request #656) Fix test_unicode_outofrange 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 @@ -899,16 +899,22 @@ b.byteswap() assert b[2] == u'\u0000' assert a != b - e = raises(ValueError, "b[0]") # doesn't work - assert str(e.value) == ( - "cannot operate on this array('u') because it contains" - " character U+1000000 not in range [U+0000; U+10ffff]" - " at index 0") + if b.itemsize == 4: + e = raises(ValueError, "b[0]") # doesn't work + assert str(e.value) == ( + "cannot operate on this array('u') because it contains" + " character U+1000000 not in range [U+0000; U+10ffff]" + " at index 0") + assert str(b) == ("array('u', )") + raises(ValueError, b.tounicode) # doesn't work + elif b.itemsize == 2: + assert b[0] == u'\u0100' + byteswaped_unicode = u'\u0100\u3a26\x00\ufffe' + assert str(b) == "array('u', %r)" % (byteswaped_unicode,) + assert b.tounicode() == byteswaped_unicode assert str(a) == "array('u', %r)" % (input_unicode,) - assert str(b) == ("array('u', )") assert a.tounicode() == input_unicode - raises(ValueError, b.tounicode) # doesn't work def test_unicode_surrogate(self): a = self.array('u', u'\ud800') From pypy.commits at gmail.com Sun Jul 14 06:56:41 2019 From: pypy.commits at gmail.com (joac...@bitbucket.org) Date: Sun, 14 Jul 2019 03:56:41 -0700 (PDT) Subject: [pypy-commit] pypy fix_test_unicode_outofrange: fix test_unicode_outofrange in case itemsize == 2 Message-ID: <5d2b0a69.1c69fb81.8ac23.7701@mx.google.com> Author: joachim-ballmann at bitbucket.org Branch: fix_test_unicode_outofrange Changeset: r96990:35c679b16018 Date: 2019-07-14 12:40 +0200 http://bitbucket.org/pypy/pypy/changeset/35c679b16018/ Log: fix test_unicode_outofrange in case itemsize == 2 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 @@ -899,16 +899,22 @@ b.byteswap() assert b[2] == u'\u0000' assert a != b - e = raises(ValueError, "b[0]") # doesn't work - assert str(e.value) == ( - "cannot operate on this array('u') because it contains" - " character U+1000000 not in range [U+0000; U+10ffff]" - " at index 0") + if b.itemsize == 4: + e = raises(ValueError, "b[0]") # doesn't work + assert str(e.value) == ( + "cannot operate on this array('u') because it contains" + " character U+1000000 not in range [U+0000; U+10ffff]" + " at index 0") + assert str(b) == ("array('u', )") + raises(ValueError, b.tounicode) # doesn't work + elif b.itemsize == 2: + assert b[0] == u'\u0100' + byteswaped_unicode = u'\u0100\u3a26\x00\ufffe' + assert str(b) == "array('u', %r)" % (byteswaped_unicode,) + assert b.tounicode() == byteswaped_unicode assert str(a) == "array('u', %r)" % (input_unicode,) - assert str(b) == ("array('u', )") assert a.tounicode() == input_unicode - raises(ValueError, b.tounicode) # doesn't work def test_unicode_surrogate(self): a = self.array('u', u'\ud800') From pypy.commits at gmail.com Sun Jul 14 06:57:18 2019 From: pypy.commits at gmail.com (rlamy) Date: Sun, 14 Jul 2019 03:57:18 -0700 (PDT) Subject: [pypy-commit] pypy default: Clean up uses of pytest.raises() Message-ID: <5d2b0a8e.1c69fb81.4eff3.e031@mx.google.com> Author: Ronan Lamy Branch: Changeset: r96992:519a04c0f373 Date: 2019-07-14 12:50 +0200 http://bitbucket.org/pypy/pypy/changeset/519a04c0f373/ Log: Clean up uses of pytest.raises() diff --git a/rpython/rlib/test/test_rbigint.py b/rpython/rlib/test/test_rbigint.py --- a/rpython/rlib/test/test_rbigint.py +++ b/rpython/rlib/test/test_rbigint.py @@ -3,9 +3,8 @@ import operator import sys import math -from random import random, randint, sample, seed +from random import random, randint, sample -import py import pytest from rpython.rlib import rbigint as lobj @@ -111,7 +110,8 @@ r2 = op1 // op2 assert r1.tolong() == r2 - assert pytest.raises(ZeroDivisionError, r.int_floordiv, 0) + with pytest.raises(ZeroDivisionError): + r.int_floordiv(0) # Error pointed out by Armin Rigo n = sys.maxint+1 @@ -142,7 +142,8 @@ for op2 in gen_signs(long_vals): rl_op2 = rbigint.fromlong(op2) if not op2: - py.test.raises(ZeroDivisionError, rl_op1.truediv, rl_op2) + with pytest.raises(ZeroDivisionError): + rl_op1.truediv(rl_op2) continue r1 = rl_op1.truediv(rl_op2) r2 = op1 / op2 @@ -173,7 +174,8 @@ op1 = rbigint.fromlong(overflowing) op2 = rbigint.fromlong(1) - py.test.raises(OverflowError, op1.truediv, op2) + with pytest.raises(OverflowError): + op1.truediv(op2) def test_truediv_overflow2(self): overflowing = 2**1024 - 2**(1024-53-1) @@ -191,7 +193,8 @@ for op2 in gen_signs(long_vals): rl_op2 = rbigint.fromlong(op2) if not op2: - py.test.raises(ZeroDivisionError, rl_op1.mod, rl_op2) + with pytest.raises(ZeroDivisionError): + rl_op1.mod(rl_op2) continue r1 = rl_op1.mod(rl_op2) r2 = op1 % op2 @@ -203,7 +206,8 @@ op1 = rbigint.fromlong(x) for y in signed_int_vals: if not y: - py.test.raises(ZeroDivisionError, op1.int_mod, 0) + with pytest.raises(ZeroDivisionError): + op1.int_mod(0) continue r1 = op1.int_mod(y) r2 = x % y @@ -245,8 +249,10 @@ def test_pow_raises(self): r1 = rbigint.fromint(2) r0 = rbigint.fromint(0) - py.test.raises(ValueError, r1.int_pow, 2, r0) - py.test.raises(ValueError, r1.pow, r1, r0) + with pytest.raises(ValueError): + r1.int_pow(2, r0) + with pytest.raises(ValueError): + r1.pow(r1, r0) def test_touint(self): result = r_uint(sys.maxint + 42) @@ -340,8 +346,10 @@ from rpython.rlib.rstring import ParseStringError assert rbigint.fromstr('123L').tolong() == 123 assert rbigint.fromstr('123L ').tolong() == 123 - py.test.raises(ParseStringError, rbigint.fromstr, 'L') - py.test.raises(ParseStringError, rbigint.fromstr, 'L ') + with pytest.raises(ParseStringError): + rbigint.fromstr('L') + with pytest.raises(ParseStringError): + rbigint.fromstr('L ') assert rbigint.fromstr('123L', 4).tolong() == 27 assert rbigint.fromstr('123L', 30).tolong() == 27000 + 1800 + 90 + 21 assert rbigint.fromstr('123L', 22).tolong() == 10648 + 968 + 66 + 21 @@ -358,8 +366,8 @@ s = "077777777777777777777777777777" parser = NumberStringParser(s, s, 0, "long", no_implicit_octal=True) - py.test.raises(ParseStringError, rbigint._from_numberstring_parser, - parser) + with pytest.raises(ParseStringError): + rbigint._from_numberstring_parser(parser) parser = NumberStringParser("000", "000", 0, "long", no_implicit_octal=True) assert rbigint._from_numberstring_parser(parser).tolong() == 0 @@ -423,7 +431,8 @@ assert d == float(x) x = x ** 100 f1 = rbigint.fromlong(x) - assert py.test.raises(OverflowError, f1.tofloat) + with pytest.raises(OverflowError): + f1.tofloat() f2 = rbigint.fromlong(2097152 << SHIFT) d = f2.tofloat() assert d == float(2097152 << SHIFT) @@ -456,8 +465,10 @@ # XXX don't use such consts. marshal doesn't handle them right. x = 12345.6789e200 x *= x - assert py.test.raises(OverflowError, rbigint.fromfloat, x) - assert py.test.raises(ValueError, rbigint.fromfloat, NAN) + with pytest.raises(OverflowError): + rbigint.fromfloat(x) + with pytest.raises(ValueError): + rbigint.fromfloat(NAN) # f1 = rbigint.fromfloat(9007199254740991.0) assert f1.tolong() == 9007199254740991 @@ -547,7 +558,8 @@ assert u == v assert type(u) is r_uint else: - py.test.raises(ValueError, l.touint) + with pytest.raises(ValueError): + l.touint() toobig_lv1 = rbigint.fromlong(sys.maxint+1) assert toobig_lv1.tolong() == sys.maxint+1 @@ -557,7 +569,8 @@ assert toobig_lv3.tolong() == -sys.maxint-2 for lv in (toobig_lv1, toobig_lv2, toobig_lv3): - py.test.raises(OverflowError, lv.toint) + with pytest.raises(OverflowError): + lv.toint() lmaxuint = rbigint.fromlong(2*sys.maxint+1) toobig_lv4 = rbigint.fromlong(2*sys.maxint+2) @@ -565,8 +578,10 @@ u = lmaxuint.touint() assert u == 2*sys.maxint+1 - py.test.raises(ValueError, toobig_lv3.touint) - py.test.raises(OverflowError, toobig_lv4.touint) + with pytest.raises(ValueError): + toobig_lv3.touint() + with pytest.raises(OverflowError): + toobig_lv4.touint() def test_pow_lll(self): @@ -584,10 +599,12 @@ # f1, f2, f3 = [rbigint.fromlong(i) for i in (10L, -1L, 42L)] - py.test.raises(TypeError, f1.pow, f2, f3) + with pytest.raises(TypeError): + f1.pow(f2, f3) f1, f2, f3 = [rbigint.fromlong(i) for i in (10L, 5L, 0L)] - py.test.raises(ValueError, f1.pow, f2, f3) + with pytest.raises(ValueError): + f1.pow(f2, f3) def test_pow_lll_bug(self): two = rbigint.fromint(2) @@ -645,8 +662,10 @@ masks_list = [int((1 << i) - 1) for i in range(1, r_uint.BITS-1)] for x in gen_signs([3L ** 30L, 5L ** 20L, 7 ** 300, 0L, 1L]): f1 = rbigint.fromlong(x) - py.test.raises(ValueError, f1.lshift, negative) - py.test.raises(ValueError, f1.rshift, negative) + with pytest.raises(ValueError): + f1.lshift(negative) + with pytest.raises(ValueError): + f1.rshift(negative) for y in [0L, 1L, 32L, 2304L, 11233L, 3 ** 9]: res1 = f1.lshift(int(y)).tolong() res2 = f1.rshift(int(y)).tolong() @@ -785,7 +804,8 @@ for op in long_vals: for base in [0, 2, 4, 8, 16, 10, math.e]: if not op: - py.test.raises(ValueError, rbigint.fromlong(op).log, base) + with pytest.raises(ValueError): + rbigint.fromlong(op).log(base) continue l = rbigint.fromlong(op).log(base) if base: @@ -809,15 +829,16 @@ s = "\xFF\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\xFF" bigint = rbigint.frombytes(s, byteorder="big", signed=False) assert s == bigint.tobytes(16, byteorder="big", signed=False) - py.test.raises(InvalidEndiannessError, bigint.frombytes, '\xFF', 'foo', - signed=True) + with pytest.raises(InvalidEndiannessError): + bigint.frombytes('\xFF', 'foo', signed=True) bigint = rbigint.frombytes('\x82', byteorder='big', signed=True) assert bigint.tolong() == -126 def test_tobytes(self): assert rbigint.fromint(0).tobytes(1, 'big', signed=True) == '\x00' assert rbigint.fromint(1).tobytes(2, 'big', signed=True) == '\x00\x01' - py.test.raises(OverflowError, rbigint.fromint(255).tobytes, 1, 'big', signed=True) + with pytest.raises(OverflowError): + rbigint.fromint(255).tobytes(1, 'big', signed=True) assert rbigint.fromint(-129).tobytes(2, 'big', signed=True) == '\xff\x7f' assert rbigint.fromint(-129).tobytes(2, 'little', signed=True) == '\x7f\xff' assert rbigint.fromint(65535).tobytes(3, 'big', signed=True) == '\x00\xff\xff' @@ -825,9 +846,12 @@ assert rbigint.fromint(65535).tobytes(2, 'big', signed=False) == '\xff\xff' assert rbigint.fromint(-8388608).tobytes(3, 'little', signed=True) == '\x00\x00\x80' i = rbigint.fromint(-8388608) - py.test.raises(InvalidEndiannessError, i.tobytes, 3, 'foo', signed=True) - py.test.raises(InvalidSignednessError, i.tobytes, 3, 'little', signed=False) - py.test.raises(OverflowError, i.tobytes, 2, 'little', signed=True) + with pytest.raises(InvalidEndiannessError): + i.tobytes(3, 'foo', signed=True) + with pytest.raises(InvalidSignednessError): + i.tobytes(3, 'little', signed=False) + with pytest.raises(OverflowError): + i.tobytes(2, 'little', signed=True) @given(strategies.binary(), strategies.booleans(), strategies.booleans()) def test_frombytes_tobytes_hypothesis(self, s, big, signed): @@ -844,8 +868,10 @@ assert gcd_binary(13, 13**6) == 13 assert gcd_binary(12, 0) == 12 assert gcd_binary(0, 0) == 0 - assert pytest.raises(ValueError, gcd_binary, -10, 0) - assert pytest.raises(ValueError, gcd_binary, 10, -10) + with pytest.raises(ValueError): + gcd_binary(-10, 0) + with pytest.raises(ValueError): + gcd_binary(10, -10) x = rbigint.fromlong(9969216677189303386214405760200) y = rbigint.fromlong(16130531424904581415797907386349) @@ -939,7 +965,8 @@ _div, _rem = divmod(sx, sy) assert div.tolong() == _div assert rem.tolong() == _rem - py.test.raises(ZeroDivisionError, rbigint.fromlong(x).divmod, rbigint.fromlong(0)) + with pytest.raises(ZeroDivisionError): + rbigint.fromlong(x).divmod(rbigint.fromlong(0)) # an explicit example for a very rare case in _x_divrem: # "add w back if q was too large (this branch taken rarely)" @@ -972,7 +999,8 @@ assert rem1.tolong() == _rem assert div.tolong() == _div assert rem.tolong() == _rem - py.test.raises(ZeroDivisionError, rbigint.fromlong(x).int_divmod, 0) + with pytest.raises(ZeroDivisionError): + rbigint.fromlong(x).int_divmod(0) # testing Karatsuba stuff def test__v_iadd(self): @@ -1013,8 +1041,10 @@ f4 = rbigint.fromlong(-max-1) # overflows assert f1.tolonglong() == max-1 assert f2.tolonglong() == -max - py.test.raises(OverflowError, f3.tolonglong) - py.test.raises(OverflowError, f4.tolonglong) + with pytest.raises(OverflowError): + f3.tolonglong() + with pytest.raises(OverflowError): + f4.tolonglong() def test_uintmask(self): assert rbigint.fromint(-1).uintmask() == r_uint(-1) @@ -1175,7 +1205,8 @@ try: res = pow(x, y, z) except Exception as e: - pytest.raises(type(e), f1.pow, f2, f3) + with pytest.raises(type(e)): + f1.pow(f2, f3) else: v1 = f1.pow(f2, f3) try: @@ -1198,7 +1229,8 @@ try: res = divmod(x, y) except Exception as e: - pytest.raises(type(e), f1.divmod, f2) + with pytest.raises(type(e)): + f1.divmod(f2) else: print x, y a, b = f1.divmod(f2) @@ -1210,7 +1242,8 @@ try: res = divmod(x, iy) except Exception as e: - pytest.raises(type(e), f1.int_divmod, iy) + with pytest.raises(type(e)): + f1.int_divmod(iy) else: print x, iy a, b = f1.int_divmod(iy) @@ -1241,7 +1274,8 @@ ra = rbigint.fromlong(a) rb = rbigint.fromlong(b) if not b: - pytest.raises(ZeroDivisionError, ra.truediv, rb) + with pytest.raises(ZeroDivisionError): + ra.truediv(rb) else: assert ra.truediv(rb) == a / b @@ -1271,7 +1305,7 @@ assert lx.int_le(y) == (x <= y) @given(longs, longs) - def test_int_comparison(self, x, y): + def test_int_comparison2(self, x, y): lx = rbigint.fromlong(x) ly = rbigint.fromlong(y) assert lx.lt(ly) == (x < y) From pypy.commits at gmail.com Sun Jul 14 08:14:10 2019 From: pypy.commits at gmail.com (arigo) Date: Sun, 14 Jul 2019 05:14:10 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Merged in vxgmichel/pypy/bpo-35409 (pull request #655) Message-ID: <5d2b1c92.1c69fb81.e3cfb.1102@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96995:0c8150a9aba8 Date: 2019-07-14 12:13 +0000 http://bitbucket.org/pypy/pypy/changeset/0c8150a9aba8/ Log: Merged in vxgmichel/pypy/bpo-35409 (pull request #655) Ignore GeneratorExit when throwing into the aclose coroutine of an asynchronous generator diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -661,15 +661,7 @@ return self.do_send(w_arg) def descr_throw(self, w_type, w_val=None, w_tb=None): - space = self.space - if self.state == self.ST_CLOSED: - raise OperationError(space.w_StopIteration, space.w_None) - try: - w_value = self.async_gen.throw(w_type, w_val, w_tb) - return self.unwrap_value(w_value) - except OperationError as e: - self.state = self.ST_CLOSED - raise + return self.do_throw(w_type, w_val, w_tb) def descr_close(self): self.state = self.ST_CLOSED @@ -715,6 +707,17 @@ self.state = self.ST_CLOSED raise + def do_throw(self, w_type, w_val, w_tb): + space = self.space + if self.state == self.ST_CLOSED: + raise OperationError(space.w_StopIteration, space.w_None) + try: + w_value = self.async_gen.throw(w_type, w_val, w_tb) + return self.unwrap_value(w_value) + except OperationError as e: + self.state = self.ST_CLOSED + raise + class AsyncGenAThrow(AsyncGenABase): @@ -756,21 +759,31 @@ w_value = self.async_gen.send_ex(w_arg_or_err) return self.unwrap_value(w_value) except OperationError as e: - if e.match(space, space.w_StopAsyncIteration): - self.state = self.ST_CLOSED - if self.w_exc_type is None: - # When aclose() is called we don't want to propagate - # StopAsyncIteration; just raise StopIteration, signalling - # that 'aclose()' is done. - raise OperationError(space.w_StopIteration, space.w_None) - if e.match(space, space.w_GeneratorExit): - self.state = self.ST_CLOSED - # Ignore this error. - raise OperationError(space.w_StopIteration, space.w_None) - raise + self.handle_error(e) - def descr_throw(self, w_type, w_val=None, w_tb=None): + def do_throw(self, w_type, w_val, w_tb): + space = self.space if self.state == self.ST_INIT: raise OperationError(self.space.w_RuntimeError, - self.space.newtext("can't do async_generator.athrow().throw()")) - return AsyncGenABase.descr_throw(self, w_type, w_val, w_tb) + space.newtext("can't do async_generator.athrow().throw()")) + if self.state == self.ST_CLOSED: + raise OperationError(space.w_StopIteration, space.w_None) + try: + w_value = self.async_gen.throw(w_type, w_val, w_tb) + return self.unwrap_value(w_value) + except OperationError as e: + self.handle_error(e) + + def handle_error(self, e): + space = self.space + self.state = self.ST_CLOSED + if e.match(space, space.w_StopAsyncIteration): + if self.w_exc_type is None: + # When aclose() is called we don't want to propagate + # StopAsyncIteration; just raise StopIteration, signalling + # that 'aclose()' is done. + raise OperationError(space.w_StopIteration, space.w_None) + if e.match(space, space.w_GeneratorExit): + # Ignore this error. + raise OperationError(space.w_StopIteration, space.w_None) + raise e diff --git a/pypy/interpreter/test/test_coroutine.py b/pypy/interpreter/test/test_coroutine.py --- a/pypy/interpreter/test/test_coroutine.py +++ b/pypy/interpreter/test/test_coroutine.py @@ -453,6 +453,15 @@ assert ex.value.args == expected """ + def test_async_yield_athrow_send_after_exception(self): """ + async def ag(): + yield 42 + + athrow_coro = ag().athrow(ValueError) + raises(ValueError, athrow_coro.send, None) + raises(StopIteration, athrow_coro.send, None) + """ + def test_async_yield_athrow_throw(self): """ async def ag(): yield 42 @@ -558,6 +567,42 @@ assert state == 2 """ + def test_async_aclose_await_in_finally_with_exception(self): """ + import types + + @types.coroutine + def coro(): + yield 'coro' + + state = 0 + async def ag(): + nonlocal state + try: + yield + finally: + state = 1 + try: + await coro() + except Exception as exc: + state = exc + + async def run(): + a = ag() + async for i in a: + break + await a.aclose() + a = run() + assert state == 0 + assert a.send(None) == 'coro' + assert state == 1 + exc = RuntimeError() + try: + a.throw(exc) + except StopIteration: + pass + assert state == exc + """ + def test_async_aclose_in_finalize_hook_await_in_finally(self): """ import gc import sys From pypy.commits at gmail.com Sun Jul 14 08:14:18 2019 From: pypy.commits at gmail.com (vxgmichel) Date: Sun, 14 Jul 2019 05:14:18 -0700 (PDT) Subject: [pypy-commit] pypy bpo-35409: Ignore GeneratorExit when throwing into the aclose coroutine of an asynchronous generator Message-ID: <5d2b1c9a.1c69fb81.e5628.0c67@mx.google.com> Author: Vincent Michel Branch: bpo-35409 Changeset: r96993:f29b8a6e72dd Date: 2019-07-13 18:12 +0200 http://bitbucket.org/pypy/pypy/changeset/f29b8a6e72dd/ Log: Ignore GeneratorExit when throwing into the aclose coroutine of an asynchronous generator Related issues and pull requests on cpython: - https://bugs.python.org/issue35409 - https://github.com/python/cpython/pull/14755 diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -770,7 +770,20 @@ raise def descr_throw(self, w_type, w_val=None, w_tb=None): + space = self.space if self.state == self.ST_INIT: raise OperationError(self.space.w_RuntimeError, - self.space.newtext("can't do async_generator.athrow().throw()")) - return AsyncGenABase.descr_throw(self, w_type, w_val, w_tb) + space.newtext("can't do async_generator.athrow().throw()")) + try: + return AsyncGenABase.descr_throw(self, w_type, w_val, w_tb) + except OperationError as e: + if e.match(space, space.w_StopAsyncIteration): + if self.w_exc_type is None: + # When aclose() is called we don't want to propagate + # StopAsyncIteration; just raise StopIteration, signalling + # that 'aclose()' is done. + raise OperationError(space.w_StopIteration, space.w_None) + if e.match(space, space.w_GeneratorExit): + # Ignore this error. + raise OperationError(space.w_StopIteration, space.w_None) + raise diff --git a/pypy/interpreter/test/test_coroutine.py b/pypy/interpreter/test/test_coroutine.py --- a/pypy/interpreter/test/test_coroutine.py +++ b/pypy/interpreter/test/test_coroutine.py @@ -558,6 +558,42 @@ assert state == 2 """ + def test_async_aclose_await_in_finally_with_exception(self): """ + import types + + @types.coroutine + def coro(): + yield 'coro' + + state = 0 + async def ag(): + nonlocal state + try: + yield + finally: + state = 1 + try: + await coro() + except Exception as exc: + state = exc + + async def run(): + a = ag() + async for i in a: + break + await a.aclose() + a = run() + assert state == 0 + assert a.send(None) == 'coro' + assert state == 1 + exc = RuntimeError() + try: + a.throw(exc) + except StopIteration: + pass + assert state == exc + """ + def test_async_aclose_in_finalize_hook_await_in_finally(self): """ import gc import sys From pypy.commits at gmail.com Sun Jul 14 08:14:20 2019 From: pypy.commits at gmail.com (vxgmichel) Date: Sun, 14 Jul 2019 05:14:20 -0700 (PDT) Subject: [pypy-commit] pypy bpo-35409: Make sure the athrow coroutine of an asynchronous generator gets Message-ID: <5d2b1c9c.1c69fb81.57582.6d87@mx.google.com> Author: Vincent Michel Branch: bpo-35409 Changeset: r96994:3c32e9b24388 Date: 2019-07-14 14:09 +0200 http://bitbucket.org/pypy/pypy/changeset/3c32e9b24388/ Log: Make sure the athrow coroutine of an asynchronous generator gets closed when the underlying generator raises an exception diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py --- a/pypy/interpreter/generator.py +++ b/pypy/interpreter/generator.py @@ -661,15 +661,7 @@ return self.do_send(w_arg) def descr_throw(self, w_type, w_val=None, w_tb=None): - space = self.space - if self.state == self.ST_CLOSED: - raise OperationError(space.w_StopIteration, space.w_None) - try: - w_value = self.async_gen.throw(w_type, w_val, w_tb) - return self.unwrap_value(w_value) - except OperationError as e: - self.state = self.ST_CLOSED - raise + return self.do_throw(w_type, w_val, w_tb) def descr_close(self): self.state = self.ST_CLOSED @@ -715,6 +707,17 @@ self.state = self.ST_CLOSED raise + def do_throw(self, w_type, w_val, w_tb): + space = self.space + if self.state == self.ST_CLOSED: + raise OperationError(space.w_StopIteration, space.w_None) + try: + w_value = self.async_gen.throw(w_type, w_val, w_tb) + return self.unwrap_value(w_value) + except OperationError as e: + self.state = self.ST_CLOSED + raise + class AsyncGenAThrow(AsyncGenABase): @@ -756,34 +759,31 @@ w_value = self.async_gen.send_ex(w_arg_or_err) return self.unwrap_value(w_value) except OperationError as e: - if e.match(space, space.w_StopAsyncIteration): - self.state = self.ST_CLOSED - if self.w_exc_type is None: - # When aclose() is called we don't want to propagate - # StopAsyncIteration; just raise StopIteration, signalling - # that 'aclose()' is done. - raise OperationError(space.w_StopIteration, space.w_None) - if e.match(space, space.w_GeneratorExit): - self.state = self.ST_CLOSED - # Ignore this error. - raise OperationError(space.w_StopIteration, space.w_None) - raise + self.handle_error(e) - def descr_throw(self, w_type, w_val=None, w_tb=None): + def do_throw(self, w_type, w_val, w_tb): space = self.space if self.state == self.ST_INIT: raise OperationError(self.space.w_RuntimeError, space.newtext("can't do async_generator.athrow().throw()")) + if self.state == self.ST_CLOSED: + raise OperationError(space.w_StopIteration, space.w_None) try: - return AsyncGenABase.descr_throw(self, w_type, w_val, w_tb) + w_value = self.async_gen.throw(w_type, w_val, w_tb) + return self.unwrap_value(w_value) except OperationError as e: - if e.match(space, space.w_StopAsyncIteration): - if self.w_exc_type is None: - # When aclose() is called we don't want to propagate - # StopAsyncIteration; just raise StopIteration, signalling - # that 'aclose()' is done. - raise OperationError(space.w_StopIteration, space.w_None) - if e.match(space, space.w_GeneratorExit): - # Ignore this error. + self.handle_error(e) + + def handle_error(self, e): + space = self.space + self.state = self.ST_CLOSED + if e.match(space, space.w_StopAsyncIteration): + if self.w_exc_type is None: + # When aclose() is called we don't want to propagate + # StopAsyncIteration; just raise StopIteration, signalling + # that 'aclose()' is done. raise OperationError(space.w_StopIteration, space.w_None) - raise + if e.match(space, space.w_GeneratorExit): + # Ignore this error. + raise OperationError(space.w_StopIteration, space.w_None) + raise e diff --git a/pypy/interpreter/test/test_coroutine.py b/pypy/interpreter/test/test_coroutine.py --- a/pypy/interpreter/test/test_coroutine.py +++ b/pypy/interpreter/test/test_coroutine.py @@ -453,6 +453,15 @@ assert ex.value.args == expected """ + def test_async_yield_athrow_send_after_exception(self): """ + async def ag(): + yield 42 + + athrow_coro = ag().athrow(ValueError) + raises(ValueError, athrow_coro.send, None) + raises(StopIteration, athrow_coro.send, None) + """ + def test_async_yield_athrow_throw(self): """ async def ag(): yield 42 From pypy.commits at gmail.com Sun Jul 14 10:15:38 2019 From: pypy.commits at gmail.com (joac...@bitbucket.org) Date: Sun, 14 Jul 2019 07:15:38 -0700 (PDT) Subject: [pypy-commit] pypy default: fix test_unicode_outofrange in case itemsize == 2 Message-ID: <5d2b390a.1c69fb81.74dae.0566@mx.google.com> Author: joachim-ballmann at bitbucket.org Branch: Changeset: r96996:961477b88452 Date: 2019-07-14 12:40 +0200 http://bitbucket.org/pypy/pypy/changeset/961477b88452/ Log: fix test_unicode_outofrange in case itemsize == 2 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 @@ -860,16 +860,22 @@ b.byteswap() assert b[2] == u'\u0000' assert a != b - e = raises(ValueError, "b[0]") # doesn't work - assert str(e.value) == ( - "cannot operate on this array('u') because it contains" - " character U+1000000 not in range [U+0000; U+10ffff]" - " at index 0") + if b.itemsize == 4: + e = raises(ValueError, "b[0]") # doesn't work + assert str(e.value) == ( + "cannot operate on this array('u') because it contains" + " character U+1000000 not in range [U+0000; U+10ffff]" + " at index 0") + assert str(b) == ("array('u', )") + raises(ValueError, b.tounicode) # doesn't work + elif b.itemsize == 2: + assert b[0] == u'\u0100' + byteswaped_unicode = u'\u0100\u3a26\x00\ufffe' + assert str(b) == "array('u', %r)" % (byteswaped_unicode,) + assert b.tounicode() == byteswaped_unicode assert str(a) == "array('u', %r)" % (input_unicode,) - assert str(b) == ("array('u', )") assert a.tounicode() == input_unicode - raises(ValueError, b.tounicode) # doesn't work def test_unicode_surrogate(self): a = self.array('u', u'\ud800') From pypy.commits at gmail.com Sun Jul 14 11:38:31 2019 From: pypy.commits at gmail.com (arigo) Date: Sun, 14 Jul 2019 08:38:31 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Use uniformly the technique of @jit.elidable on a family of unicode Message-ID: <5d2b4c77.1c69fb81.589e1.8ca6@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96997:6601328a5b4a Date: 2019-07-14 16:36 +0100 http://bitbucket.org/pypy/pypy/changeset/6601328a5b4a/ Log: Use uniformly the technique of @jit.elidable on a family of unicode methods. Fixes one test in test_pypy_c diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py b/pypy/module/pypyjit/test_pypy_c/test_string.py --- a/pypy/module/pypyjit/test_pypy_c/test_string.py +++ b/pypy/module/pypyjit/test_pypy_c/test_string.py @@ -191,8 +191,9 @@ loops = log.loops_by_filename(self.filepath) loop, = loops assert loop.match_by_id('callone', ''' - p114 = call_r(ConstClass(ll_lower__rpy_stringPtr), p113, descr=) + p114 = call_r(ConstClass(_lower_unicode), p113, descr=) guard_no_exception(descr=...) + guard_nonnull_class(p114, ConstClass(W_UnicodeObject), descr=...) ''') assert loop.match_by_id('calltwo', '') # nothing diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -398,46 +398,54 @@ return mod_format(space, w_values, self, fmt_type=FORMAT_UNICODE) def descr_swapcase(self, space): - value = self._utf8 + return W_UnicodeObject._swapcase_unicode(self._utf8) + + @staticmethod + @jit.elidable + def _swapcase_unicode(value): + if len(value) == 0: + return W_UnicodeObject.EMPTY builder = rutf8.Utf8StringBuilder(len(value)) for ch, pos in rutf8.Utf8StringPosIterator(value): if unicodedb.isupper(ch): - codes = self._lower_char(ch, value, pos) + codes = W_UnicodeObject._lower_char(ch, value, pos) elif unicodedb.islower(ch): codes = unicodedb.toupper_full(ch) else: codes = [ch,] for c in codes: builder.append_code(c) - return self.from_utf8builder(builder) + return W_UnicodeObject.from_utf8builder(builder) def descr_title(self, space): - if len(self._utf8) == 0: - return self - return self.title_unicode() + return W_UnicodeObject._title_unicode(self._utf8) + @staticmethod @jit.elidable - def title_unicode(self): - value = self._utf8 + def _title_unicode(value): + if len(value) == 0: + return W_UnicodeObject.EMPTY builder = rutf8.Utf8StringBuilder(len(value)) previous_is_cased = False for ch, pos in rutf8.Utf8StringPosIterator(value): if previous_is_cased: - codes = self._lower_char(ch, value, pos) + codes = W_UnicodeObject._lower_char(ch, value, pos) else: codes = unicodedb.totitle_full(ch) for c in codes: builder.append_code(c) previous_is_cased = unicodedb.iscased(ch) - return self.from_utf8builder(builder) + return W_UnicodeObject.from_utf8builder(builder) - def _lower_char(self, ch, value, bytepos): + @staticmethod + def _lower_char(ch, value, bytepos): if ch == 0x3a3: - return [self._handle_capital_sigma(value, bytepos), ] + return [W_UnicodeObject._handle_capital_sigma(value, bytepos), ] else: return unicodedb.tolower_full(ch) - def _handle_capital_sigma(self, value, bytepos): + @staticmethod + def _handle_capital_sigma(value, bytepos): # U+03A3 is in the Final_Sigma context when, it is found like this: #\p{cased} \p{case-ignorable}* U+03A3 not(\p{case-ignorable}* \p{cased}) # where \p{xxx} is a character with property xxx. @@ -585,7 +593,13 @@ return space.is_w(space.type(w_obj), space.w_unicode) def descr_casefold(self, space): - value = self._utf8 + return W_UnicodeObject._casefold_unicode(self._utf8) + + @staticmethod + @jit.elidable + def _casefold_unicode(value): + if len(value) == 0: + return W_UnicodeObject.EMPTY builder = rutf8.Utf8StringBuilder(len(value)) for ch in rutf8.Utf8StringIterator(value): folded = unicodedb.casefold_lookup(ch) @@ -594,16 +608,22 @@ else: for r in folded: builder.append_code(r) - return self.from_utf8builder(builder) + return W_UnicodeObject.from_utf8builder(builder) def descr_lower(self, space): - value = self._utf8 + return W_UnicodeObject._lower_unicode(self._utf8) + + @staticmethod + @jit.elidable + def _lower_unicode(value): + if len(value) == 0: + return W_UnicodeObject.EMPTY builder = rutf8.Utf8StringBuilder(len(value)) for ch, pos in rutf8.Utf8StringPosIterator(value): - codes = self._lower_char(ch, value, pos) + codes = W_UnicodeObject._lower_char(ch, value, pos) for c in codes: builder.append_code(c) - return self.from_utf8builder(builder) + return W_UnicodeObject.from_utf8builder(builder) def descr_isdecimal(self, space): return self._is_generic(space, '_isdecimal') @@ -770,12 +790,19 @@ return space.newlist(strs_w) def descr_upper(self, space): - builder = rutf8.Utf8StringBuilder(len(self._utf8)) - for ch in rutf8.Utf8StringIterator(self._utf8): + return W_UnicodeObject._upper_unicode(self._utf8) + + @staticmethod + @jit.elidable + def _upper_unicode(value): + if len(value) == 0: + return W_UnicodeObject.EMPTY + builder = rutf8.Utf8StringBuilder(len(value)) + for ch in rutf8.Utf8StringIterator(value): codes = unicodedb.toupper_full(ch) for c in codes: builder.append_code(c) - return self.from_utf8builder(builder) + return W_UnicodeObject.from_utf8builder(builder) @unwrap_spec(width=int) def descr_zfill(self, space, width): @@ -874,10 +901,13 @@ return W_UnicodeObject(self._utf8[byte_start:byte_stop], stop - start) def descr_capitalize(self, space): - if self._len() == 0: - return self._empty() + return W_UnicodeObject._capitalize_unicode(self._utf8) - value = self._utf8 + @staticmethod + @jit.elidable + def _capitalize_unicode(value): + if len(value) == 0: + return W_UnicodeObject.EMPTY builder = rutf8.Utf8StringBuilder(len(value)) it = rutf8.Utf8StringPosIterator(value) uchar, _ = it.next() @@ -886,10 +916,10 @@ for c in codes: builder.append_code(c) for ch, pos in it: - codes = self._lower_char(ch, value, pos) + codes = W_UnicodeObject._lower_char(ch, value, pos) for c in codes: builder.append_code(c) - return self.from_utf8builder(builder) + return W_UnicodeObject.from_utf8builder(builder) @unwrap_spec(width=int, w_fillchar=WrappedDefault(u' ')) def descr_center(self, space, width, w_fillchar): From pypy.commits at gmail.com Sun Jul 14 12:37:37 2019 From: pypy.commits at gmail.com (arigo) Date: Sun, 14 Jul 2019 09:37:37 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Write down the result of investigating this failure Message-ID: <5d2b5a51.1c69fb81.367fd.5505@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96998:41876ed51727 Date: 2019-07-14 18:36 +0200 http://bitbucket.org/pypy/pypy/changeset/41876ed51727/ Log: Write down the result of investigating this failure diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py b/pypy/module/pypyjit/test_pypy_c/test_string.py --- a/pypy/module/pypyjit/test_pypy_c/test_string.py +++ b/pypy/module/pypyjit/test_pypy_c/test_string.py @@ -198,7 +198,11 @@ assert loop.match_by_id('calltwo', '') # nothing def test_move_method_call_out_of_loop(self): - # XXX not implemented: lower() on unicodes is not considered elidable + # XXX this does not work: _lower_unicode() is found to be elidable, + # but it can raise (because of 'raise StopIteration' in + # Utf8StringIterator.next()---we don't detect that such an exception + # is always caught in the caller). Raising elidable calls are not + # unroll-removed: see issue #2015. def main(n): lst = [] s = 'Hello %d' % n From pypy.commits at gmail.com Sun Jul 14 12:52:54 2019 From: pypy.commits at gmail.com (arigo) Date: Sun, 14 Jul 2019 09:52:54 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: fix test Message-ID: <5d2b5de6.1c69fb81.1e7af.9a83@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r96999:57c274368925 Date: 2019-07-14 17:52 +0100 http://bitbucket.org/pypy/pypy/changeset/57c274368925/ Log: fix test diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py b/pypy/module/pypyjit/test_pypy_c/test_string.py --- a/pypy/module/pypyjit/test_pypy_c/test_string.py +++ b/pypy/module/pypyjit/test_pypy_c/test_string.py @@ -168,7 +168,10 @@ guard_no_exception(descr=...) p95 = call_r(..., descr=) # ll_build guard_no_exception(descr=...) - i96 = strlen(p95) + i96 = call_i(ConstClass(codepoints_in_utf8), p95, 0, _, descr=) + guard_no_exception(descr=...) + i969 = int_lt(i96, 0) + guard_false(i969, descr=...) i97 = int_add_ovf(i71, i96) guard_no_overflow(descr=...) i98 = int_sub(i74, 1) From pypy.commits at gmail.com Sun Jul 14 13:00:25 2019 From: pypy.commits at gmail.com (arigo) Date: Sun, 14 Jul 2019 10:00:25 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: fix test Message-ID: <5d2b5fa9.1c69fb81.32ef2.a308@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r97000:fdddd234e7d2 Date: 2019-07-14 17:59 +0100 http://bitbucket.org/pypy/pypy/changeset/fdddd234e7d2/ Log: fix test diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py b/pypy/module/pypyjit/test_pypy_c/test_string.py --- a/pypy/module/pypyjit/test_pypy_c/test_string.py +++ b/pypy/module/pypyjit/test_pypy_c/test_string.py @@ -110,15 +110,13 @@ i87 = int_mul(i85, 10) i19 = int_sub(i6, i87) - i23 = unicodegetitem(ConstPtr(ptr92), i19) - p25 = newtext(1) - unicodesetitem(p25, 0, i23) - p97 = call_r(ConstClass(_rpy_unicode_to_decimal_w), p25, descr=) - guard_no_exception(descr=...) - i98 = unicodelen(p97) - p104 = call_r(ConstClass(unicode_encode_utf_8), p97, i98, ConstPtr(ptr94), 1, descr=) - guard_no_exception(descr=...) - i107 = call_i(ConstClass(string_to_int), p104, 16, descr=) + i23 = strgetitem(ConstPtr(ptr92), i19) + i83 = int_le(i23, 127) + guard_true(i83, descr=...) + i85 = int_add(i19, 1) # not used + p25 = newstr(1) + strsetitem(p25, 0, i23) + i107 = call_i(ConstClass(string_to_int), p25, 16, 1, 1, descr=) guard_no_exception(descr=...) i95 = int_add_ovf(i6, i107) guard_no_overflow(descr=...) From pypy.commits at gmail.com Sun Jul 14 13:15:51 2019 From: pypy.commits at gmail.com (arigo) Date: Sun, 14 Jul 2019 10:15:51 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: fix test Message-ID: <5d2b6347.1c69fb81.9ae25.2ece@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r97001:f4f950bdca7d Date: 2019-07-14 18:14 +0100 http://bitbucket.org/pypy/pypy/changeset/f4f950bdca7d/ Log: fix test diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py b/pypy/module/pypyjit/test_pypy_c/test_string.py --- a/pypy/module/pypyjit/test_pypy_c/test_string.py +++ b/pypy/module/pypyjit/test_pypy_c/test_string.py @@ -65,15 +65,27 @@ i97 = int_ge(i94, i53) guard_false(i97, descr=...) i98 = strgetitem(p52, i94) + p1 = force_token() p103 = newstr(1) strsetitem(p103, 0, i98) - p296 = call_r(ConstClass(str_decode_utf_8), p103, 1, ConstPtr(null), 1, ConstClass(raise_unicode_exception_decode), 0, descr=) + setfield_gc(p0, p1, descr=) + p296 = call_may_force_r(ConstClass(str_decode_utf8), p103, ConstPtr(null), 1, _, 0, descr=) + guard_not_forced(descr=...) guard_no_exception(descr=...) - p116 = getfield_gc_r(p296, descr=) + p116 = getfield_gc_r(p296, descr=) + i107 = getfield_gc_i(p296, descr=) + i109 = int_lt(i107, 0) + guard_false(i109, descr=...) + guard_not_invalidated(descr=...) i99 = int_ge(i94, i46) guard_false(i99, descr=...) - i120 = unicodegetitem(p45, i94) - i122 = call_i(ConstClass(_ll_2_str_eq_nonnull_char__rpy_unicodePtr_UniChar), p116, i120, descr=) + i120 = strgetitem(p45, i94) + i113 = int_le(i120, 127) + guard_true(i113, descr=...) + i115 = int_add(i94, 1) + i116 = int_gt(i115, i71) + guard_false(i116, descr=...) + i122 = call_i(ConstClass(_ll_2_str_eq_checknull_char__rpy_stringPtr_Char), p116, i120, descr=) guard_true(i122, descr=...) i124 = int_add(i83, 1) --TICK-- From pypy.commits at gmail.com Sun Jul 14 13:34:08 2019 From: pypy.commits at gmail.com (arigo) Date: Sun, 14 Jul 2019 10:34:08 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: fix test Message-ID: <5d2b6790.1c69fb81.367fd.5cfa@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r97002:3086088b38f5 Date: 2019-07-14 18:33 +0100 http://bitbucket.org/pypy/pypy/changeset/3086088b38f5/ Log: fix test diff --git a/pypy/module/pypyjit/test_pypy_c/test_ffi.py b/pypy/module/pypyjit/test_pypy_c/test_ffi.py --- a/pypy/module/pypyjit/test_pypy_c/test_ffi.py +++ b/pypy/module/pypyjit/test_pypy_c/test_ffi.py @@ -392,6 +392,8 @@ guard_value(p122, ConstPtr(ptr123), descr=...) p125 = getfield_gc_r(p16, descr=...) guard_nonnull_class(p125, ..., descr=...) + p999 = getfield_gc_r(p125, descr=...) + guard_isnull(p999, descr=...) p127 = getfield_gc_r(p125, descr=...) guard_value(p127, ConstPtr(ptr128), descr=...) p129 = getfield_gc_r(p127, descr=...) @@ -428,6 +430,7 @@ i160 = int_sub(i158, 16) setfield_raw(#, i160, descr=...) setfield_gc(p48, p49, descr=...) + setfield_gc(p48, p50, descr=...) setfield_gc(p134, ConstPtr(null), descr=...) i160 = int_lt(i160, 0) guard_false(i160, descr=...) From pypy.commits at gmail.com Mon Jul 15 07:53:01 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 15 Jul 2019 04:53:01 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Generate a file that hopefully covers all corner cases of startswith() Message-ID: <5d2c691d.1c69fb81.4bb98.0ded@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r97003:7b256d2286ec Date: 2019-07-15 13:52 +0200 http://bitbucket.org/pypy/pypy/changeset/7b256d2286ec/ Log: Generate a file that hopefully covers all corner cases of startswith() and endswith() on bytes, bytearrays and unicodes. Fix. diff --git a/pypy/objspace/std/test/startswith.py b/pypy/objspace/std/test/startswith.py new file mode 100644 --- /dev/null +++ b/pypy/objspace/std/test/startswith.py @@ -0,0 +1,1657 @@ +# # This file is generated by running the following code on top of the +# # target version of CPython: +# +# import sys +# with open(sys.argv[0]) as f: +# for line in f: +# print('# ' + line.rstrip()) +# +# ranges = [None] + list(range(-4, 5)) +# +# print('') +# print('def check(s1, s2, start, end, bitmask):') +# print(' b1 = bytes(s1, "ascii")') +# print(' b2 = bytes(s2, "ascii")') +# print(' a1 = bytearray(s1, "ascii")') +# print(' a2 = bytearray(s2, "ascii")') +# print(' assert s1.startswith(s2, start, end) == ((bitmask & 1) != 0)') +# print(' assert b1.startswith(b2, start, end) == ((bitmask & 2) != 0)') +# print(' assert a1.startswith(a2, start, end) == ((bitmask & 4) != 0)') +# print(' assert s1.endswith(s2, start, end) == ((bitmask & 8) != 0)') +# print(' assert b1.endswith(b2, start, end) == ((bitmask & 16) != 0)') +# print(' assert a1.endswith(a2, start, end) == ((bitmask & 32) != 0)') +# print('') +# for len1 in range(0, 4): +# s1 = ''.join(chr(48+n) for n in range(len1)) +# for len2 in range(0, 4): +# for start in ranges: +# for end in ranges: +# s2 = s1[start:end] +# r = 0 +# b1 = bytes(s1, 'ascii') +# b2 = bytes(s2, 'ascii') +# a1 = bytearray(s1, 'ascii') +# a2 = bytearray(s2, 'ascii') +# if s1.startswith(s2, start, end): r |= 1 +# if b1.startswith(b2, start, end): r |= 2 +# if a1.startswith(a2, start, end): r |= 4 +# if s1.endswith(s2, start, end): r |= 8 +# if b1.endswith(b2, start, end): r |= 16 +# if a1.endswith(a2, start, end): r |= 32 +# line = 'check(%r, %r, %r, %r, %d)' % (s1, s2, start, end, r) +# if r != 0 and r != 63: +# line += ' # IRREGULAR' +# print(line) + +def check(s1, s2, start, end, bitmask): + b1 = bytes(s1, "ascii") + b2 = bytes(s2, "ascii") + a1 = bytearray(s1, "ascii") + a2 = bytearray(s2, "ascii") + assert s1.startswith(s2, start, end) == ((bitmask & 1) != 0) + assert b1.startswith(b2, start, end) == ((bitmask & 2) != 0) + assert a1.startswith(a2, start, end) == ((bitmask & 4) != 0) + assert s1.endswith(s2, start, end) == ((bitmask & 8) != 0) + assert b1.endswith(b2, start, end) == ((bitmask & 16) != 0) + assert a1.endswith(a2, start, end) == ((bitmask & 32) != 0) + +check('', '', None, None, 63) +check('', '', None, -4, 63) +check('', '', None, -3, 63) +check('', '', None, -2, 63) +check('', '', None, -1, 63) +check('', '', None, 0, 63) +check('', '', None, 1, 63) +check('', '', None, 2, 63) +check('', '', None, 3, 63) +check('', '', None, 4, 63) +check('', '', -4, None, 63) +check('', '', -4, -4, 63) +check('', '', -4, -3, 63) +check('', '', -4, -2, 63) +check('', '', -4, -1, 63) +check('', '', -4, 0, 63) +check('', '', -4, 1, 63) +check('', '', -4, 2, 63) +check('', '', -4, 3, 63) +check('', '', -4, 4, 63) +check('', '', -3, None, 63) +check('', '', -3, -4, 63) +check('', '', -3, -3, 63) +check('', '', -3, -2, 63) +check('', '', -3, -1, 63) +check('', '', -3, 0, 63) +check('', '', -3, 1, 63) +check('', '', -3, 2, 63) +check('', '', -3, 3, 63) +check('', '', -3, 4, 63) +check('', '', -2, None, 63) +check('', '', -2, -4, 63) +check('', '', -2, -3, 63) +check('', '', -2, -2, 63) +check('', '', -2, -1, 63) +check('', '', -2, 0, 63) +check('', '', -2, 1, 63) +check('', '', -2, 2, 63) +check('', '', -2, 3, 63) +check('', '', -2, 4, 63) +check('', '', -1, None, 63) +check('', '', -1, -4, 63) +check('', '', -1, -3, 63) +check('', '', -1, -2, 63) +check('', '', -1, -1, 63) +check('', '', -1, 0, 63) +check('', '', -1, 1, 63) +check('', '', -1, 2, 63) +check('', '', -1, 3, 63) +check('', '', -1, 4, 63) +check('', '', 0, None, 63) +check('', '', 0, -4, 63) +check('', '', 0, -3, 63) +check('', '', 0, -2, 63) +check('', '', 0, -1, 63) +check('', '', 0, 0, 63) +check('', '', 0, 1, 63) +check('', '', 0, 2, 63) +check('', '', 0, 3, 63) +check('', '', 0, 4, 63) +check('', '', 1, None, 0) +check('', '', 1, -4, 0) +check('', '', 1, -3, 0) +check('', '', 1, -2, 0) +check('', '', 1, -1, 0) +check('', '', 1, 0, 0) +check('', '', 1, 1, 0) +check('', '', 1, 2, 0) +check('', '', 1, 3, 0) +check('', '', 1, 4, 0) +check('', '', 2, None, 0) +check('', '', 2, -4, 0) +check('', '', 2, -3, 0) +check('', '', 2, -2, 0) +check('', '', 2, -1, 0) +check('', '', 2, 0, 0) +check('', '', 2, 1, 0) +check('', '', 2, 2, 0) +check('', '', 2, 3, 0) +check('', '', 2, 4, 0) +check('', '', 3, None, 0) +check('', '', 3, -4, 0) +check('', '', 3, -3, 0) +check('', '', 3, -2, 0) +check('', '', 3, -1, 0) +check('', '', 3, 0, 0) +check('', '', 3, 1, 0) +check('', '', 3, 2, 0) +check('', '', 3, 3, 0) +check('', '', 3, 4, 0) +check('', '', 4, None, 0) +check('', '', 4, -4, 0) +check('', '', 4, -3, 0) +check('', '', 4, -2, 0) +check('', '', 4, -1, 0) +check('', '', 4, 0, 0) +check('', '', 4, 1, 0) +check('', '', 4, 2, 0) +check('', '', 4, 3, 0) +check('', '', 4, 4, 0) +check('', '', None, None, 63) +check('', '', None, -4, 63) +check('', '', None, -3, 63) +check('', '', None, -2, 63) +check('', '', None, -1, 63) +check('', '', None, 0, 63) +check('', '', None, 1, 63) +check('', '', None, 2, 63) +check('', '', None, 3, 63) +check('', '', None, 4, 63) +check('', '', -4, None, 63) +check('', '', -4, -4, 63) +check('', '', -4, -3, 63) +check('', '', -4, -2, 63) +check('', '', -4, -1, 63) +check('', '', -4, 0, 63) +check('', '', -4, 1, 63) +check('', '', -4, 2, 63) +check('', '', -4, 3, 63) +check('', '', -4, 4, 63) +check('', '', -3, None, 63) +check('', '', -3, -4, 63) +check('', '', -3, -3, 63) +check('', '', -3, -2, 63) +check('', '', -3, -1, 63) +check('', '', -3, 0, 63) +check('', '', -3, 1, 63) +check('', '', -3, 2, 63) +check('', '', -3, 3, 63) +check('', '', -3, 4, 63) +check('', '', -2, None, 63) +check('', '', -2, -4, 63) +check('', '', -2, -3, 63) +check('', '', -2, -2, 63) +check('', '', -2, -1, 63) +check('', '', -2, 0, 63) +check('', '', -2, 1, 63) +check('', '', -2, 2, 63) +check('', '', -2, 3, 63) +check('', '', -2, 4, 63) +check('', '', -1, None, 63) +check('', '', -1, -4, 63) +check('', '', -1, -3, 63) +check('', '', -1, -2, 63) +check('', '', -1, -1, 63) +check('', '', -1, 0, 63) +check('', '', -1, 1, 63) +check('', '', -1, 2, 63) +check('', '', -1, 3, 63) +check('', '', -1, 4, 63) +check('', '', 0, None, 63) +check('', '', 0, -4, 63) +check('', '', 0, -3, 63) +check('', '', 0, -2, 63) +check('', '', 0, -1, 63) +check('', '', 0, 0, 63) +check('', '', 0, 1, 63) +check('', '', 0, 2, 63) +check('', '', 0, 3, 63) +check('', '', 0, 4, 63) +check('', '', 1, None, 0) +check('', '', 1, -4, 0) +check('', '', 1, -3, 0) +check('', '', 1, -2, 0) +check('', '', 1, -1, 0) +check('', '', 1, 0, 0) +check('', '', 1, 1, 0) +check('', '', 1, 2, 0) +check('', '', 1, 3, 0) +check('', '', 1, 4, 0) +check('', '', 2, None, 0) +check('', '', 2, -4, 0) +check('', '', 2, -3, 0) +check('', '', 2, -2, 0) +check('', '', 2, -1, 0) +check('', '', 2, 0, 0) +check('', '', 2, 1, 0) +check('', '', 2, 2, 0) +check('', '', 2, 3, 0) +check('', '', 2, 4, 0) +check('', '', 3, None, 0) +check('', '', 3, -4, 0) +check('', '', 3, -3, 0) +check('', '', 3, -2, 0) +check('', '', 3, -1, 0) +check('', '', 3, 0, 0) +check('', '', 3, 1, 0) +check('', '', 3, 2, 0) +check('', '', 3, 3, 0) +check('', '', 3, 4, 0) +check('', '', 4, None, 0) +check('', '', 4, -4, 0) +check('', '', 4, -3, 0) +check('', '', 4, -2, 0) +check('', '', 4, -1, 0) +check('', '', 4, 0, 0) +check('', '', 4, 1, 0) +check('', '', 4, 2, 0) +check('', '', 4, 3, 0) +check('', '', 4, 4, 0) +check('', '', None, None, 63) +check('', '', None, -4, 63) +check('', '', None, -3, 63) +check('', '', None, -2, 63) +check('', '', None, -1, 63) +check('', '', None, 0, 63) +check('', '', None, 1, 63) +check('', '', None, 2, 63) +check('', '', None, 3, 63) +check('', '', None, 4, 63) +check('', '', -4, None, 63) +check('', '', -4, -4, 63) +check('', '', -4, -3, 63) +check('', '', -4, -2, 63) +check('', '', -4, -1, 63) +check('', '', -4, 0, 63) +check('', '', -4, 1, 63) +check('', '', -4, 2, 63) +check('', '', -4, 3, 63) +check('', '', -4, 4, 63) +check('', '', -3, None, 63) +check('', '', -3, -4, 63) +check('', '', -3, -3, 63) +check('', '', -3, -2, 63) +check('', '', -3, -1, 63) +check('', '', -3, 0, 63) +check('', '', -3, 1, 63) +check('', '', -3, 2, 63) +check('', '', -3, 3, 63) +check('', '', -3, 4, 63) +check('', '', -2, None, 63) +check('', '', -2, -4, 63) +check('', '', -2, -3, 63) +check('', '', -2, -2, 63) +check('', '', -2, -1, 63) +check('', '', -2, 0, 63) +check('', '', -2, 1, 63) +check('', '', -2, 2, 63) +check('', '', -2, 3, 63) +check('', '', -2, 4, 63) +check('', '', -1, None, 63) +check('', '', -1, -4, 63) +check('', '', -1, -3, 63) +check('', '', -1, -2, 63) +check('', '', -1, -1, 63) +check('', '', -1, 0, 63) +check('', '', -1, 1, 63) +check('', '', -1, 2, 63) +check('', '', -1, 3, 63) +check('', '', -1, 4, 63) +check('', '', 0, None, 63) +check('', '', 0, -4, 63) +check('', '', 0, -3, 63) +check('', '', 0, -2, 63) +check('', '', 0, -1, 63) +check('', '', 0, 0, 63) +check('', '', 0, 1, 63) +check('', '', 0, 2, 63) +check('', '', 0, 3, 63) +check('', '', 0, 4, 63) +check('', '', 1, None, 0) +check('', '', 1, -4, 0) +check('', '', 1, -3, 0) +check('', '', 1, -2, 0) +check('', '', 1, -1, 0) +check('', '', 1, 0, 0) +check('', '', 1, 1, 0) +check('', '', 1, 2, 0) +check('', '', 1, 3, 0) +check('', '', 1, 4, 0) +check('', '', 2, None, 0) +check('', '', 2, -4, 0) +check('', '', 2, -3, 0) +check('', '', 2, -2, 0) +check('', '', 2, -1, 0) +check('', '', 2, 0, 0) +check('', '', 2, 1, 0) +check('', '', 2, 2, 0) +check('', '', 2, 3, 0) +check('', '', 2, 4, 0) +check('', '', 3, None, 0) +check('', '', 3, -4, 0) +check('', '', 3, -3, 0) +check('', '', 3, -2, 0) +check('', '', 3, -1, 0) +check('', '', 3, 0, 0) +check('', '', 3, 1, 0) +check('', '', 3, 2, 0) +check('', '', 3, 3, 0) +check('', '', 3, 4, 0) +check('', '', 4, None, 0) +check('', '', 4, -4, 0) +check('', '', 4, -3, 0) +check('', '', 4, -2, 0) +check('', '', 4, -1, 0) +check('', '', 4, 0, 0) +check('', '', 4, 1, 0) +check('', '', 4, 2, 0) +check('', '', 4, 3, 0) +check('', '', 4, 4, 0) +check('', '', None, None, 63) +check('', '', None, -4, 63) +check('', '', None, -3, 63) +check('', '', None, -2, 63) +check('', '', None, -1, 63) +check('', '', None, 0, 63) +check('', '', None, 1, 63) +check('', '', None, 2, 63) +check('', '', None, 3, 63) +check('', '', None, 4, 63) +check('', '', -4, None, 63) +check('', '', -4, -4, 63) +check('', '', -4, -3, 63) +check('', '', -4, -2, 63) +check('', '', -4, -1, 63) +check('', '', -4, 0, 63) +check('', '', -4, 1, 63) +check('', '', -4, 2, 63) +check('', '', -4, 3, 63) +check('', '', -4, 4, 63) +check('', '', -3, None, 63) +check('', '', -3, -4, 63) +check('', '', -3, -3, 63) +check('', '', -3, -2, 63) +check('', '', -3, -1, 63) +check('', '', -3, 0, 63) +check('', '', -3, 1, 63) +check('', '', -3, 2, 63) +check('', '', -3, 3, 63) +check('', '', -3, 4, 63) +check('', '', -2, None, 63) +check('', '', -2, -4, 63) +check('', '', -2, -3, 63) +check('', '', -2, -2, 63) +check('', '', -2, -1, 63) +check('', '', -2, 0, 63) +check('', '', -2, 1, 63) +check('', '', -2, 2, 63) +check('', '', -2, 3, 63) +check('', '', -2, 4, 63) +check('', '', -1, None, 63) +check('', '', -1, -4, 63) +check('', '', -1, -3, 63) +check('', '', -1, -2, 63) +check('', '', -1, -1, 63) +check('', '', -1, 0, 63) +check('', '', -1, 1, 63) +check('', '', -1, 2, 63) +check('', '', -1, 3, 63) +check('', '', -1, 4, 63) +check('', '', 0, None, 63) +check('', '', 0, -4, 63) +check('', '', 0, -3, 63) +check('', '', 0, -2, 63) +check('', '', 0, -1, 63) +check('', '', 0, 0, 63) +check('', '', 0, 1, 63) +check('', '', 0, 2, 63) +check('', '', 0, 3, 63) +check('', '', 0, 4, 63) +check('', '', 1, None, 0) +check('', '', 1, -4, 0) +check('', '', 1, -3, 0) +check('', '', 1, -2, 0) +check('', '', 1, -1, 0) +check('', '', 1, 0, 0) +check('', '', 1, 1, 0) +check('', '', 1, 2, 0) +check('', '', 1, 3, 0) +check('', '', 1, 4, 0) +check('', '', 2, None, 0) +check('', '', 2, -4, 0) +check('', '', 2, -3, 0) +check('', '', 2, -2, 0) +check('', '', 2, -1, 0) +check('', '', 2, 0, 0) +check('', '', 2, 1, 0) +check('', '', 2, 2, 0) +check('', '', 2, 3, 0) +check('', '', 2, 4, 0) +check('', '', 3, None, 0) +check('', '', 3, -4, 0) +check('', '', 3, -3, 0) +check('', '', 3, -2, 0) +check('', '', 3, -1, 0) +check('', '', 3, 0, 0) +check('', '', 3, 1, 0) +check('', '', 3, 2, 0) +check('', '', 3, 3, 0) +check('', '', 3, 4, 0) +check('', '', 4, None, 0) +check('', '', 4, -4, 0) +check('', '', 4, -3, 0) +check('', '', 4, -2, 0) +check('', '', 4, -1, 0) +check('', '', 4, 0, 0) +check('', '', 4, 1, 0) +check('', '', 4, 2, 0) +check('', '', 4, 3, 0) +check('', '', 4, 4, 0) +check('0', '0', None, None, 63) +check('0', '', None, -4, 63) +check('0', '', None, -3, 63) +check('0', '', None, -2, 63) +check('0', '', None, -1, 63) +check('0', '', None, 0, 63) +check('0', '0', None, 1, 63) +check('0', '0', None, 2, 63) +check('0', '0', None, 3, 63) +check('0', '0', None, 4, 63) +check('0', '0', -4, None, 63) +check('0', '', -4, -4, 63) +check('0', '', -4, -3, 63) +check('0', '', -4, -2, 63) +check('0', '', -4, -1, 63) +check('0', '', -4, 0, 63) +check('0', '0', -4, 1, 63) +check('0', '0', -4, 2, 63) +check('0', '0', -4, 3, 63) +check('0', '0', -4, 4, 63) +check('0', '0', -3, None, 63) +check('0', '', -3, -4, 63) +check('0', '', -3, -3, 63) +check('0', '', -3, -2, 63) +check('0', '', -3, -1, 63) +check('0', '', -3, 0, 63) +check('0', '0', -3, 1, 63) +check('0', '0', -3, 2, 63) +check('0', '0', -3, 3, 63) +check('0', '0', -3, 4, 63) +check('0', '0', -2, None, 63) +check('0', '', -2, -4, 63) +check('0', '', -2, -3, 63) +check('0', '', -2, -2, 63) +check('0', '', -2, -1, 63) +check('0', '', -2, 0, 63) +check('0', '0', -2, 1, 63) +check('0', '0', -2, 2, 63) +check('0', '0', -2, 3, 63) +check('0', '0', -2, 4, 63) +check('0', '0', -1, None, 63) +check('0', '', -1, -4, 63) +check('0', '', -1, -3, 63) +check('0', '', -1, -2, 63) +check('0', '', -1, -1, 63) +check('0', '', -1, 0, 63) +check('0', '0', -1, 1, 63) +check('0', '0', -1, 2, 63) +check('0', '0', -1, 3, 63) +check('0', '0', -1, 4, 63) +check('0', '0', 0, None, 63) +check('0', '', 0, -4, 63) +check('0', '', 0, -3, 63) +check('0', '', 0, -2, 63) +check('0', '', 0, -1, 63) +check('0', '', 0, 0, 63) +check('0', '0', 0, 1, 63) +check('0', '0', 0, 2, 63) +check('0', '0', 0, 3, 63) +check('0', '0', 0, 4, 63) +check('0', '', 1, None, 63) +check('0', '', 1, -4, 0) +check('0', '', 1, -3, 0) +check('0', '', 1, -2, 0) +check('0', '', 1, -1, 0) +check('0', '', 1, 0, 0) +check('0', '', 1, 1, 63) +check('0', '', 1, 2, 63) +check('0', '', 1, 3, 63) +check('0', '', 1, 4, 63) +check('0', '', 2, None, 0) +check('0', '', 2, -4, 0) +check('0', '', 2, -3, 0) +check('0', '', 2, -2, 0) +check('0', '', 2, -1, 0) +check('0', '', 2, 0, 0) +check('0', '', 2, 1, 0) +check('0', '', 2, 2, 0) +check('0', '', 2, 3, 0) +check('0', '', 2, 4, 0) +check('0', '', 3, None, 0) +check('0', '', 3, -4, 0) +check('0', '', 3, -3, 0) +check('0', '', 3, -2, 0) +check('0', '', 3, -1, 0) +check('0', '', 3, 0, 0) +check('0', '', 3, 1, 0) +check('0', '', 3, 2, 0) +check('0', '', 3, 3, 0) +check('0', '', 3, 4, 0) +check('0', '', 4, None, 0) +check('0', '', 4, -4, 0) +check('0', '', 4, -3, 0) +check('0', '', 4, -2, 0) +check('0', '', 4, -1, 0) +check('0', '', 4, 0, 0) +check('0', '', 4, 1, 0) +check('0', '', 4, 2, 0) +check('0', '', 4, 3, 0) +check('0', '', 4, 4, 0) +check('0', '0', None, None, 63) +check('0', '', None, -4, 63) +check('0', '', None, -3, 63) +check('0', '', None, -2, 63) +check('0', '', None, -1, 63) +check('0', '', None, 0, 63) +check('0', '0', None, 1, 63) +check('0', '0', None, 2, 63) +check('0', '0', None, 3, 63) +check('0', '0', None, 4, 63) +check('0', '0', -4, None, 63) +check('0', '', -4, -4, 63) +check('0', '', -4, -3, 63) +check('0', '', -4, -2, 63) +check('0', '', -4, -1, 63) +check('0', '', -4, 0, 63) +check('0', '0', -4, 1, 63) +check('0', '0', -4, 2, 63) +check('0', '0', -4, 3, 63) +check('0', '0', -4, 4, 63) +check('0', '0', -3, None, 63) +check('0', '', -3, -4, 63) +check('0', '', -3, -3, 63) +check('0', '', -3, -2, 63) +check('0', '', -3, -1, 63) +check('0', '', -3, 0, 63) +check('0', '0', -3, 1, 63) +check('0', '0', -3, 2, 63) +check('0', '0', -3, 3, 63) +check('0', '0', -3, 4, 63) +check('0', '0', -2, None, 63) +check('0', '', -2, -4, 63) +check('0', '', -2, -3, 63) +check('0', '', -2, -2, 63) +check('0', '', -2, -1, 63) +check('0', '', -2, 0, 63) +check('0', '0', -2, 1, 63) +check('0', '0', -2, 2, 63) +check('0', '0', -2, 3, 63) +check('0', '0', -2, 4, 63) +check('0', '0', -1, None, 63) +check('0', '', -1, -4, 63) +check('0', '', -1, -3, 63) +check('0', '', -1, -2, 63) +check('0', '', -1, -1, 63) +check('0', '', -1, 0, 63) +check('0', '0', -1, 1, 63) +check('0', '0', -1, 2, 63) +check('0', '0', -1, 3, 63) +check('0', '0', -1, 4, 63) +check('0', '0', 0, None, 63) +check('0', '', 0, -4, 63) +check('0', '', 0, -3, 63) +check('0', '', 0, -2, 63) +check('0', '', 0, -1, 63) +check('0', '', 0, 0, 63) +check('0', '0', 0, 1, 63) +check('0', '0', 0, 2, 63) +check('0', '0', 0, 3, 63) +check('0', '0', 0, 4, 63) +check('0', '', 1, None, 63) +check('0', '', 1, -4, 0) +check('0', '', 1, -3, 0) +check('0', '', 1, -2, 0) +check('0', '', 1, -1, 0) +check('0', '', 1, 0, 0) +check('0', '', 1, 1, 63) +check('0', '', 1, 2, 63) +check('0', '', 1, 3, 63) +check('0', '', 1, 4, 63) +check('0', '', 2, None, 0) +check('0', '', 2, -4, 0) +check('0', '', 2, -3, 0) +check('0', '', 2, -2, 0) +check('0', '', 2, -1, 0) +check('0', '', 2, 0, 0) +check('0', '', 2, 1, 0) +check('0', '', 2, 2, 0) +check('0', '', 2, 3, 0) +check('0', '', 2, 4, 0) +check('0', '', 3, None, 0) +check('0', '', 3, -4, 0) +check('0', '', 3, -3, 0) +check('0', '', 3, -2, 0) +check('0', '', 3, -1, 0) +check('0', '', 3, 0, 0) +check('0', '', 3, 1, 0) +check('0', '', 3, 2, 0) +check('0', '', 3, 3, 0) +check('0', '', 3, 4, 0) +check('0', '', 4, None, 0) +check('0', '', 4, -4, 0) +check('0', '', 4, -3, 0) +check('0', '', 4, -2, 0) +check('0', '', 4, -1, 0) +check('0', '', 4, 0, 0) +check('0', '', 4, 1, 0) +check('0', '', 4, 2, 0) +check('0', '', 4, 3, 0) +check('0', '', 4, 4, 0) +check('0', '0', None, None, 63) +check('0', '', None, -4, 63) +check('0', '', None, -3, 63) +check('0', '', None, -2, 63) +check('0', '', None, -1, 63) +check('0', '', None, 0, 63) +check('0', '0', None, 1, 63) +check('0', '0', None, 2, 63) +check('0', '0', None, 3, 63) +check('0', '0', None, 4, 63) +check('0', '0', -4, None, 63) +check('0', '', -4, -4, 63) +check('0', '', -4, -3, 63) +check('0', '', -4, -2, 63) +check('0', '', -4, -1, 63) +check('0', '', -4, 0, 63) +check('0', '0', -4, 1, 63) +check('0', '0', -4, 2, 63) +check('0', '0', -4, 3, 63) +check('0', '0', -4, 4, 63) +check('0', '0', -3, None, 63) +check('0', '', -3, -4, 63) +check('0', '', -3, -3, 63) +check('0', '', -3, -2, 63) +check('0', '', -3, -1, 63) +check('0', '', -3, 0, 63) +check('0', '0', -3, 1, 63) +check('0', '0', -3, 2, 63) +check('0', '0', -3, 3, 63) +check('0', '0', -3, 4, 63) +check('0', '0', -2, None, 63) +check('0', '', -2, -4, 63) +check('0', '', -2, -3, 63) +check('0', '', -2, -2, 63) +check('0', '', -2, -1, 63) +check('0', '', -2, 0, 63) +check('0', '0', -2, 1, 63) +check('0', '0', -2, 2, 63) +check('0', '0', -2, 3, 63) +check('0', '0', -2, 4, 63) +check('0', '0', -1, None, 63) +check('0', '', -1, -4, 63) +check('0', '', -1, -3, 63) +check('0', '', -1, -2, 63) +check('0', '', -1, -1, 63) +check('0', '', -1, 0, 63) +check('0', '0', -1, 1, 63) +check('0', '0', -1, 2, 63) +check('0', '0', -1, 3, 63) +check('0', '0', -1, 4, 63) +check('0', '0', 0, None, 63) +check('0', '', 0, -4, 63) +check('0', '', 0, -3, 63) +check('0', '', 0, -2, 63) +check('0', '', 0, -1, 63) +check('0', '', 0, 0, 63) +check('0', '0', 0, 1, 63) +check('0', '0', 0, 2, 63) +check('0', '0', 0, 3, 63) +check('0', '0', 0, 4, 63) +check('0', '', 1, None, 63) +check('0', '', 1, -4, 0) +check('0', '', 1, -3, 0) +check('0', '', 1, -2, 0) +check('0', '', 1, -1, 0) +check('0', '', 1, 0, 0) +check('0', '', 1, 1, 63) +check('0', '', 1, 2, 63) +check('0', '', 1, 3, 63) +check('0', '', 1, 4, 63) +check('0', '', 2, None, 0) +check('0', '', 2, -4, 0) +check('0', '', 2, -3, 0) +check('0', '', 2, -2, 0) +check('0', '', 2, -1, 0) +check('0', '', 2, 0, 0) +check('0', '', 2, 1, 0) +check('0', '', 2, 2, 0) +check('0', '', 2, 3, 0) +check('0', '', 2, 4, 0) +check('0', '', 3, None, 0) +check('0', '', 3, -4, 0) +check('0', '', 3, -3, 0) +check('0', '', 3, -2, 0) +check('0', '', 3, -1, 0) +check('0', '', 3, 0, 0) +check('0', '', 3, 1, 0) +check('0', '', 3, 2, 0) +check('0', '', 3, 3, 0) +check('0', '', 3, 4, 0) +check('0', '', 4, None, 0) +check('0', '', 4, -4, 0) +check('0', '', 4, -3, 0) +check('0', '', 4, -2, 0) +check('0', '', 4, -1, 0) +check('0', '', 4, 0, 0) +check('0', '', 4, 1, 0) +check('0', '', 4, 2, 0) +check('0', '', 4, 3, 0) +check('0', '', 4, 4, 0) +check('0', '0', None, None, 63) +check('0', '', None, -4, 63) +check('0', '', None, -3, 63) +check('0', '', None, -2, 63) +check('0', '', None, -1, 63) +check('0', '', None, 0, 63) +check('0', '0', None, 1, 63) +check('0', '0', None, 2, 63) +check('0', '0', None, 3, 63) +check('0', '0', None, 4, 63) +check('0', '0', -4, None, 63) +check('0', '', -4, -4, 63) +check('0', '', -4, -3, 63) +check('0', '', -4, -2, 63) +check('0', '', -4, -1, 63) +check('0', '', -4, 0, 63) +check('0', '0', -4, 1, 63) +check('0', '0', -4, 2, 63) +check('0', '0', -4, 3, 63) +check('0', '0', -4, 4, 63) +check('0', '0', -3, None, 63) +check('0', '', -3, -4, 63) +check('0', '', -3, -3, 63) +check('0', '', -3, -2, 63) +check('0', '', -3, -1, 63) +check('0', '', -3, 0, 63) +check('0', '0', -3, 1, 63) +check('0', '0', -3, 2, 63) +check('0', '0', -3, 3, 63) +check('0', '0', -3, 4, 63) +check('0', '0', -2, None, 63) +check('0', '', -2, -4, 63) +check('0', '', -2, -3, 63) +check('0', '', -2, -2, 63) +check('0', '', -2, -1, 63) +check('0', '', -2, 0, 63) +check('0', '0', -2, 1, 63) +check('0', '0', -2, 2, 63) +check('0', '0', -2, 3, 63) +check('0', '0', -2, 4, 63) +check('0', '0', -1, None, 63) +check('0', '', -1, -4, 63) +check('0', '', -1, -3, 63) +check('0', '', -1, -2, 63) +check('0', '', -1, -1, 63) +check('0', '', -1, 0, 63) +check('0', '0', -1, 1, 63) +check('0', '0', -1, 2, 63) +check('0', '0', -1, 3, 63) +check('0', '0', -1, 4, 63) +check('0', '0', 0, None, 63) +check('0', '', 0, -4, 63) +check('0', '', 0, -3, 63) +check('0', '', 0, -2, 63) +check('0', '', 0, -1, 63) +check('0', '', 0, 0, 63) +check('0', '0', 0, 1, 63) +check('0', '0', 0, 2, 63) +check('0', '0', 0, 3, 63) +check('0', '0', 0, 4, 63) +check('0', '', 1, None, 63) +check('0', '', 1, -4, 0) +check('0', '', 1, -3, 0) +check('0', '', 1, -2, 0) +check('0', '', 1, -1, 0) +check('0', '', 1, 0, 0) +check('0', '', 1, 1, 63) +check('0', '', 1, 2, 63) +check('0', '', 1, 3, 63) +check('0', '', 1, 4, 63) +check('0', '', 2, None, 0) +check('0', '', 2, -4, 0) +check('0', '', 2, -3, 0) +check('0', '', 2, -2, 0) +check('0', '', 2, -1, 0) +check('0', '', 2, 0, 0) +check('0', '', 2, 1, 0) +check('0', '', 2, 2, 0) +check('0', '', 2, 3, 0) +check('0', '', 2, 4, 0) +check('0', '', 3, None, 0) +check('0', '', 3, -4, 0) +check('0', '', 3, -3, 0) +check('0', '', 3, -2, 0) +check('0', '', 3, -1, 0) +check('0', '', 3, 0, 0) +check('0', '', 3, 1, 0) +check('0', '', 3, 2, 0) +check('0', '', 3, 3, 0) +check('0', '', 3, 4, 0) +check('0', '', 4, None, 0) +check('0', '', 4, -4, 0) +check('0', '', 4, -3, 0) +check('0', '', 4, -2, 0) +check('0', '', 4, -1, 0) +check('0', '', 4, 0, 0) +check('0', '', 4, 1, 0) +check('0', '', 4, 2, 0) +check('0', '', 4, 3, 0) +check('0', '', 4, 4, 0) +check('01', '01', None, None, 63) +check('01', '', None, -4, 63) +check('01', '', None, -3, 63) +check('01', '', None, -2, 63) +check('01', '0', None, -1, 63) +check('01', '', None, 0, 63) +check('01', '0', None, 1, 63) +check('01', '01', None, 2, 63) +check('01', '01', None, 3, 63) +check('01', '01', None, 4, 63) +check('01', '01', -4, None, 63) +check('01', '', -4, -4, 63) +check('01', '', -4, -3, 63) +check('01', '', -4, -2, 63) +check('01', '0', -4, -1, 63) +check('01', '', -4, 0, 63) +check('01', '0', -4, 1, 63) +check('01', '01', -4, 2, 63) +check('01', '01', -4, 3, 63) +check('01', '01', -4, 4, 63) +check('01', '01', -3, None, 63) +check('01', '', -3, -4, 63) +check('01', '', -3, -3, 63) +check('01', '', -3, -2, 63) +check('01', '0', -3, -1, 63) +check('01', '', -3, 0, 63) +check('01', '0', -3, 1, 63) +check('01', '01', -3, 2, 63) +check('01', '01', -3, 3, 63) +check('01', '01', -3, 4, 63) +check('01', '01', -2, None, 63) +check('01', '', -2, -4, 63) +check('01', '', -2, -3, 63) +check('01', '', -2, -2, 63) +check('01', '0', -2, -1, 63) +check('01', '', -2, 0, 63) +check('01', '0', -2, 1, 63) +check('01', '01', -2, 2, 63) +check('01', '01', -2, 3, 63) +check('01', '01', -2, 4, 63) +check('01', '1', -1, None, 63) +check('01', '', -1, -4, 0) +check('01', '', -1, -3, 0) +check('01', '', -1, -2, 0) +check('01', '', -1, -1, 63) +check('01', '', -1, 0, 0) +check('01', '', -1, 1, 63) +check('01', '1', -1, 2, 63) +check('01', '1', -1, 3, 63) +check('01', '1', -1, 4, 63) +check('01', '01', 0, None, 63) +check('01', '', 0, -4, 63) +check('01', '', 0, -3, 63) +check('01', '', 0, -2, 63) +check('01', '0', 0, -1, 63) +check('01', '', 0, 0, 63) +check('01', '0', 0, 1, 63) +check('01', '01', 0, 2, 63) +check('01', '01', 0, 3, 63) +check('01', '01', 0, 4, 63) +check('01', '1', 1, None, 63) +check('01', '', 1, -4, 0) +check('01', '', 1, -3, 0) +check('01', '', 1, -2, 0) +check('01', '', 1, -1, 63) +check('01', '', 1, 0, 0) +check('01', '', 1, 1, 63) +check('01', '1', 1, 2, 63) +check('01', '1', 1, 3, 63) +check('01', '1', 1, 4, 63) +check('01', '', 2, None, 63) +check('01', '', 2, -4, 0) +check('01', '', 2, -3, 0) +check('01', '', 2, -2, 0) +check('01', '', 2, -1, 0) +check('01', '', 2, 0, 0) +check('01', '', 2, 1, 0) +check('01', '', 2, 2, 63) +check('01', '', 2, 3, 63) +check('01', '', 2, 4, 63) +check('01', '', 3, None, 0) +check('01', '', 3, -4, 0) +check('01', '', 3, -3, 0) +check('01', '', 3, -2, 0) +check('01', '', 3, -1, 0) +check('01', '', 3, 0, 0) +check('01', '', 3, 1, 0) +check('01', '', 3, 2, 0) +check('01', '', 3, 3, 0) +check('01', '', 3, 4, 0) +check('01', '', 4, None, 0) +check('01', '', 4, -4, 0) +check('01', '', 4, -3, 0) +check('01', '', 4, -2, 0) +check('01', '', 4, -1, 0) +check('01', '', 4, 0, 0) +check('01', '', 4, 1, 0) +check('01', '', 4, 2, 0) +check('01', '', 4, 3, 0) +check('01', '', 4, 4, 0) +check('01', '01', None, None, 63) +check('01', '', None, -4, 63) +check('01', '', None, -3, 63) +check('01', '', None, -2, 63) +check('01', '0', None, -1, 63) +check('01', '', None, 0, 63) +check('01', '0', None, 1, 63) +check('01', '01', None, 2, 63) +check('01', '01', None, 3, 63) +check('01', '01', None, 4, 63) +check('01', '01', -4, None, 63) +check('01', '', -4, -4, 63) +check('01', '', -4, -3, 63) +check('01', '', -4, -2, 63) +check('01', '0', -4, -1, 63) +check('01', '', -4, 0, 63) +check('01', '0', -4, 1, 63) +check('01', '01', -4, 2, 63) +check('01', '01', -4, 3, 63) +check('01', '01', -4, 4, 63) +check('01', '01', -3, None, 63) +check('01', '', -3, -4, 63) +check('01', '', -3, -3, 63) +check('01', '', -3, -2, 63) +check('01', '0', -3, -1, 63) +check('01', '', -3, 0, 63) +check('01', '0', -3, 1, 63) +check('01', '01', -3, 2, 63) +check('01', '01', -3, 3, 63) +check('01', '01', -3, 4, 63) +check('01', '01', -2, None, 63) +check('01', '', -2, -4, 63) +check('01', '', -2, -3, 63) +check('01', '', -2, -2, 63) +check('01', '0', -2, -1, 63) +check('01', '', -2, 0, 63) +check('01', '0', -2, 1, 63) +check('01', '01', -2, 2, 63) +check('01', '01', -2, 3, 63) +check('01', '01', -2, 4, 63) +check('01', '1', -1, None, 63) +check('01', '', -1, -4, 0) +check('01', '', -1, -3, 0) +check('01', '', -1, -2, 0) +check('01', '', -1, -1, 63) +check('01', '', -1, 0, 0) +check('01', '', -1, 1, 63) +check('01', '1', -1, 2, 63) +check('01', '1', -1, 3, 63) +check('01', '1', -1, 4, 63) +check('01', '01', 0, None, 63) +check('01', '', 0, -4, 63) +check('01', '', 0, -3, 63) +check('01', '', 0, -2, 63) +check('01', '0', 0, -1, 63) +check('01', '', 0, 0, 63) +check('01', '0', 0, 1, 63) +check('01', '01', 0, 2, 63) +check('01', '01', 0, 3, 63) +check('01', '01', 0, 4, 63) +check('01', '1', 1, None, 63) +check('01', '', 1, -4, 0) +check('01', '', 1, -3, 0) +check('01', '', 1, -2, 0) +check('01', '', 1, -1, 63) +check('01', '', 1, 0, 0) +check('01', '', 1, 1, 63) +check('01', '1', 1, 2, 63) +check('01', '1', 1, 3, 63) +check('01', '1', 1, 4, 63) +check('01', '', 2, None, 63) +check('01', '', 2, -4, 0) +check('01', '', 2, -3, 0) +check('01', '', 2, -2, 0) +check('01', '', 2, -1, 0) +check('01', '', 2, 0, 0) +check('01', '', 2, 1, 0) +check('01', '', 2, 2, 63) +check('01', '', 2, 3, 63) +check('01', '', 2, 4, 63) +check('01', '', 3, None, 0) +check('01', '', 3, -4, 0) +check('01', '', 3, -3, 0) +check('01', '', 3, -2, 0) +check('01', '', 3, -1, 0) +check('01', '', 3, 0, 0) +check('01', '', 3, 1, 0) +check('01', '', 3, 2, 0) +check('01', '', 3, 3, 0) +check('01', '', 3, 4, 0) +check('01', '', 4, None, 0) +check('01', '', 4, -4, 0) +check('01', '', 4, -3, 0) +check('01', '', 4, -2, 0) +check('01', '', 4, -1, 0) +check('01', '', 4, 0, 0) +check('01', '', 4, 1, 0) +check('01', '', 4, 2, 0) +check('01', '', 4, 3, 0) +check('01', '', 4, 4, 0) +check('01', '01', None, None, 63) +check('01', '', None, -4, 63) +check('01', '', None, -3, 63) +check('01', '', None, -2, 63) +check('01', '0', None, -1, 63) +check('01', '', None, 0, 63) +check('01', '0', None, 1, 63) +check('01', '01', None, 2, 63) +check('01', '01', None, 3, 63) +check('01', '01', None, 4, 63) +check('01', '01', -4, None, 63) +check('01', '', -4, -4, 63) +check('01', '', -4, -3, 63) +check('01', '', -4, -2, 63) +check('01', '0', -4, -1, 63) +check('01', '', -4, 0, 63) +check('01', '0', -4, 1, 63) +check('01', '01', -4, 2, 63) +check('01', '01', -4, 3, 63) +check('01', '01', -4, 4, 63) +check('01', '01', -3, None, 63) +check('01', '', -3, -4, 63) +check('01', '', -3, -3, 63) +check('01', '', -3, -2, 63) +check('01', '0', -3, -1, 63) +check('01', '', -3, 0, 63) +check('01', '0', -3, 1, 63) +check('01', '01', -3, 2, 63) +check('01', '01', -3, 3, 63) +check('01', '01', -3, 4, 63) +check('01', '01', -2, None, 63) +check('01', '', -2, -4, 63) +check('01', '', -2, -3, 63) +check('01', '', -2, -2, 63) +check('01', '0', -2, -1, 63) +check('01', '', -2, 0, 63) +check('01', '0', -2, 1, 63) +check('01', '01', -2, 2, 63) +check('01', '01', -2, 3, 63) +check('01', '01', -2, 4, 63) +check('01', '1', -1, None, 63) +check('01', '', -1, -4, 0) +check('01', '', -1, -3, 0) +check('01', '', -1, -2, 0) +check('01', '', -1, -1, 63) +check('01', '', -1, 0, 0) +check('01', '', -1, 1, 63) +check('01', '1', -1, 2, 63) +check('01', '1', -1, 3, 63) +check('01', '1', -1, 4, 63) +check('01', '01', 0, None, 63) +check('01', '', 0, -4, 63) +check('01', '', 0, -3, 63) +check('01', '', 0, -2, 63) +check('01', '0', 0, -1, 63) +check('01', '', 0, 0, 63) +check('01', '0', 0, 1, 63) +check('01', '01', 0, 2, 63) +check('01', '01', 0, 3, 63) +check('01', '01', 0, 4, 63) +check('01', '1', 1, None, 63) +check('01', '', 1, -4, 0) +check('01', '', 1, -3, 0) +check('01', '', 1, -2, 0) +check('01', '', 1, -1, 63) +check('01', '', 1, 0, 0) +check('01', '', 1, 1, 63) +check('01', '1', 1, 2, 63) +check('01', '1', 1, 3, 63) +check('01', '1', 1, 4, 63) +check('01', '', 2, None, 63) +check('01', '', 2, -4, 0) +check('01', '', 2, -3, 0) +check('01', '', 2, -2, 0) +check('01', '', 2, -1, 0) +check('01', '', 2, 0, 0) +check('01', '', 2, 1, 0) +check('01', '', 2, 2, 63) +check('01', '', 2, 3, 63) +check('01', '', 2, 4, 63) +check('01', '', 3, None, 0) +check('01', '', 3, -4, 0) +check('01', '', 3, -3, 0) +check('01', '', 3, -2, 0) +check('01', '', 3, -1, 0) +check('01', '', 3, 0, 0) +check('01', '', 3, 1, 0) +check('01', '', 3, 2, 0) +check('01', '', 3, 3, 0) +check('01', '', 3, 4, 0) +check('01', '', 4, None, 0) +check('01', '', 4, -4, 0) +check('01', '', 4, -3, 0) +check('01', '', 4, -2, 0) +check('01', '', 4, -1, 0) +check('01', '', 4, 0, 0) +check('01', '', 4, 1, 0) +check('01', '', 4, 2, 0) +check('01', '', 4, 3, 0) +check('01', '', 4, 4, 0) +check('01', '01', None, None, 63) +check('01', '', None, -4, 63) +check('01', '', None, -3, 63) +check('01', '', None, -2, 63) +check('01', '0', None, -1, 63) +check('01', '', None, 0, 63) +check('01', '0', None, 1, 63) +check('01', '01', None, 2, 63) +check('01', '01', None, 3, 63) +check('01', '01', None, 4, 63) +check('01', '01', -4, None, 63) +check('01', '', -4, -4, 63) +check('01', '', -4, -3, 63) +check('01', '', -4, -2, 63) +check('01', '0', -4, -1, 63) +check('01', '', -4, 0, 63) +check('01', '0', -4, 1, 63) +check('01', '01', -4, 2, 63) +check('01', '01', -4, 3, 63) +check('01', '01', -4, 4, 63) +check('01', '01', -3, None, 63) +check('01', '', -3, -4, 63) +check('01', '', -3, -3, 63) +check('01', '', -3, -2, 63) +check('01', '0', -3, -1, 63) +check('01', '', -3, 0, 63) +check('01', '0', -3, 1, 63) +check('01', '01', -3, 2, 63) +check('01', '01', -3, 3, 63) +check('01', '01', -3, 4, 63) +check('01', '01', -2, None, 63) +check('01', '', -2, -4, 63) +check('01', '', -2, -3, 63) +check('01', '', -2, -2, 63) +check('01', '0', -2, -1, 63) +check('01', '', -2, 0, 63) +check('01', '0', -2, 1, 63) +check('01', '01', -2, 2, 63) +check('01', '01', -2, 3, 63) +check('01', '01', -2, 4, 63) +check('01', '1', -1, None, 63) +check('01', '', -1, -4, 0) +check('01', '', -1, -3, 0) +check('01', '', -1, -2, 0) +check('01', '', -1, -1, 63) +check('01', '', -1, 0, 0) +check('01', '', -1, 1, 63) +check('01', '1', -1, 2, 63) +check('01', '1', -1, 3, 63) +check('01', '1', -1, 4, 63) +check('01', '01', 0, None, 63) +check('01', '', 0, -4, 63) +check('01', '', 0, -3, 63) +check('01', '', 0, -2, 63) +check('01', '0', 0, -1, 63) +check('01', '', 0, 0, 63) +check('01', '0', 0, 1, 63) +check('01', '01', 0, 2, 63) +check('01', '01', 0, 3, 63) +check('01', '01', 0, 4, 63) +check('01', '1', 1, None, 63) +check('01', '', 1, -4, 0) +check('01', '', 1, -3, 0) +check('01', '', 1, -2, 0) +check('01', '', 1, -1, 63) +check('01', '', 1, 0, 0) +check('01', '', 1, 1, 63) +check('01', '1', 1, 2, 63) +check('01', '1', 1, 3, 63) +check('01', '1', 1, 4, 63) +check('01', '', 2, None, 63) +check('01', '', 2, -4, 0) +check('01', '', 2, -3, 0) +check('01', '', 2, -2, 0) +check('01', '', 2, -1, 0) +check('01', '', 2, 0, 0) +check('01', '', 2, 1, 0) +check('01', '', 2, 2, 63) +check('01', '', 2, 3, 63) +check('01', '', 2, 4, 63) +check('01', '', 3, None, 0) +check('01', '', 3, -4, 0) +check('01', '', 3, -3, 0) +check('01', '', 3, -2, 0) +check('01', '', 3, -1, 0) +check('01', '', 3, 0, 0) +check('01', '', 3, 1, 0) +check('01', '', 3, 2, 0) +check('01', '', 3, 3, 0) +check('01', '', 3, 4, 0) +check('01', '', 4, None, 0) +check('01', '', 4, -4, 0) +check('01', '', 4, -3, 0) +check('01', '', 4, -2, 0) +check('01', '', 4, -1, 0) +check('01', '', 4, 0, 0) +check('01', '', 4, 1, 0) +check('01', '', 4, 2, 0) +check('01', '', 4, 3, 0) +check('01', '', 4, 4, 0) +check('012', '012', None, None, 63) +check('012', '', None, -4, 63) +check('012', '', None, -3, 63) +check('012', '0', None, -2, 63) +check('012', '01', None, -1, 63) +check('012', '', None, 0, 63) +check('012', '0', None, 1, 63) +check('012', '01', None, 2, 63) +check('012', '012', None, 3, 63) +check('012', '012', None, 4, 63) +check('012', '012', -4, None, 63) +check('012', '', -4, -4, 63) +check('012', '', -4, -3, 63) +check('012', '0', -4, -2, 63) +check('012', '01', -4, -1, 63) +check('012', '', -4, 0, 63) +check('012', '0', -4, 1, 63) +check('012', '01', -4, 2, 63) +check('012', '012', -4, 3, 63) +check('012', '012', -4, 4, 63) +check('012', '012', -3, None, 63) +check('012', '', -3, -4, 63) +check('012', '', -3, -3, 63) +check('012', '0', -3, -2, 63) +check('012', '01', -3, -1, 63) +check('012', '', -3, 0, 63) +check('012', '0', -3, 1, 63) +check('012', '01', -3, 2, 63) +check('012', '012', -3, 3, 63) +check('012', '012', -3, 4, 63) +check('012', '12', -2, None, 63) +check('012', '', -2, -4, 0) +check('012', '', -2, -3, 0) +check('012', '', -2, -2, 63) +check('012', '1', -2, -1, 63) +check('012', '', -2, 0, 0) +check('012', '', -2, 1, 63) +check('012', '1', -2, 2, 63) +check('012', '12', -2, 3, 63) +check('012', '12', -2, 4, 63) +check('012', '2', -1, None, 63) +check('012', '', -1, -4, 0) +check('012', '', -1, -3, 0) +check('012', '', -1, -2, 0) +check('012', '', -1, -1, 63) +check('012', '', -1, 0, 0) +check('012', '', -1, 1, 0) +check('012', '', -1, 2, 63) +check('012', '2', -1, 3, 63) +check('012', '2', -1, 4, 63) +check('012', '012', 0, None, 63) +check('012', '', 0, -4, 63) +check('012', '', 0, -3, 63) +check('012', '0', 0, -2, 63) +check('012', '01', 0, -1, 63) +check('012', '', 0, 0, 63) +check('012', '0', 0, 1, 63) +check('012', '01', 0, 2, 63) +check('012', '012', 0, 3, 63) +check('012', '012', 0, 4, 63) +check('012', '12', 1, None, 63) +check('012', '', 1, -4, 0) +check('012', '', 1, -3, 0) +check('012', '', 1, -2, 63) +check('012', '1', 1, -1, 63) +check('012', '', 1, 0, 0) +check('012', '', 1, 1, 63) +check('012', '1', 1, 2, 63) +check('012', '12', 1, 3, 63) +check('012', '12', 1, 4, 63) +check('012', '2', 2, None, 63) +check('012', '', 2, -4, 0) +check('012', '', 2, -3, 0) +check('012', '', 2, -2, 0) +check('012', '', 2, -1, 63) +check('012', '', 2, 0, 0) +check('012', '', 2, 1, 0) +check('012', '', 2, 2, 63) +check('012', '2', 2, 3, 63) +check('012', '2', 2, 4, 63) +check('012', '', 3, None, 63) +check('012', '', 3, -4, 0) +check('012', '', 3, -3, 0) +check('012', '', 3, -2, 0) +check('012', '', 3, -1, 0) +check('012', '', 3, 0, 0) +check('012', '', 3, 1, 0) +check('012', '', 3, 2, 0) +check('012', '', 3, 3, 63) +check('012', '', 3, 4, 63) +check('012', '', 4, None, 0) +check('012', '', 4, -4, 0) +check('012', '', 4, -3, 0) +check('012', '', 4, -2, 0) +check('012', '', 4, -1, 0) +check('012', '', 4, 0, 0) +check('012', '', 4, 1, 0) +check('012', '', 4, 2, 0) +check('012', '', 4, 3, 0) +check('012', '', 4, 4, 0) +check('012', '012', None, None, 63) +check('012', '', None, -4, 63) +check('012', '', None, -3, 63) +check('012', '0', None, -2, 63) +check('012', '01', None, -1, 63) +check('012', '', None, 0, 63) +check('012', '0', None, 1, 63) +check('012', '01', None, 2, 63) +check('012', '012', None, 3, 63) +check('012', '012', None, 4, 63) +check('012', '012', -4, None, 63) +check('012', '', -4, -4, 63) +check('012', '', -4, -3, 63) +check('012', '0', -4, -2, 63) +check('012', '01', -4, -1, 63) +check('012', '', -4, 0, 63) +check('012', '0', -4, 1, 63) +check('012', '01', -4, 2, 63) +check('012', '012', -4, 3, 63) +check('012', '012', -4, 4, 63) +check('012', '012', -3, None, 63) +check('012', '', -3, -4, 63) +check('012', '', -3, -3, 63) +check('012', '0', -3, -2, 63) +check('012', '01', -3, -1, 63) +check('012', '', -3, 0, 63) +check('012', '0', -3, 1, 63) +check('012', '01', -3, 2, 63) +check('012', '012', -3, 3, 63) +check('012', '012', -3, 4, 63) +check('012', '12', -2, None, 63) +check('012', '', -2, -4, 0) +check('012', '', -2, -3, 0) +check('012', '', -2, -2, 63) +check('012', '1', -2, -1, 63) +check('012', '', -2, 0, 0) +check('012', '', -2, 1, 63) +check('012', '1', -2, 2, 63) +check('012', '12', -2, 3, 63) +check('012', '12', -2, 4, 63) +check('012', '2', -1, None, 63) +check('012', '', -1, -4, 0) +check('012', '', -1, -3, 0) +check('012', '', -1, -2, 0) +check('012', '', -1, -1, 63) +check('012', '', -1, 0, 0) +check('012', '', -1, 1, 0) +check('012', '', -1, 2, 63) +check('012', '2', -1, 3, 63) +check('012', '2', -1, 4, 63) +check('012', '012', 0, None, 63) +check('012', '', 0, -4, 63) +check('012', '', 0, -3, 63) +check('012', '0', 0, -2, 63) +check('012', '01', 0, -1, 63) +check('012', '', 0, 0, 63) +check('012', '0', 0, 1, 63) +check('012', '01', 0, 2, 63) +check('012', '012', 0, 3, 63) +check('012', '012', 0, 4, 63) +check('012', '12', 1, None, 63) +check('012', '', 1, -4, 0) +check('012', '', 1, -3, 0) +check('012', '', 1, -2, 63) +check('012', '1', 1, -1, 63) +check('012', '', 1, 0, 0) +check('012', '', 1, 1, 63) +check('012', '1', 1, 2, 63) +check('012', '12', 1, 3, 63) +check('012', '12', 1, 4, 63) +check('012', '2', 2, None, 63) +check('012', '', 2, -4, 0) +check('012', '', 2, -3, 0) +check('012', '', 2, -2, 0) +check('012', '', 2, -1, 63) +check('012', '', 2, 0, 0) +check('012', '', 2, 1, 0) +check('012', '', 2, 2, 63) +check('012', '2', 2, 3, 63) +check('012', '2', 2, 4, 63) +check('012', '', 3, None, 63) +check('012', '', 3, -4, 0) +check('012', '', 3, -3, 0) +check('012', '', 3, -2, 0) +check('012', '', 3, -1, 0) +check('012', '', 3, 0, 0) +check('012', '', 3, 1, 0) +check('012', '', 3, 2, 0) +check('012', '', 3, 3, 63) +check('012', '', 3, 4, 63) +check('012', '', 4, None, 0) +check('012', '', 4, -4, 0) +check('012', '', 4, -3, 0) +check('012', '', 4, -2, 0) +check('012', '', 4, -1, 0) +check('012', '', 4, 0, 0) +check('012', '', 4, 1, 0) +check('012', '', 4, 2, 0) +check('012', '', 4, 3, 0) +check('012', '', 4, 4, 0) +check('012', '012', None, None, 63) +check('012', '', None, -4, 63) +check('012', '', None, -3, 63) +check('012', '0', None, -2, 63) +check('012', '01', None, -1, 63) +check('012', '', None, 0, 63) +check('012', '0', None, 1, 63) +check('012', '01', None, 2, 63) +check('012', '012', None, 3, 63) +check('012', '012', None, 4, 63) +check('012', '012', -4, None, 63) +check('012', '', -4, -4, 63) +check('012', '', -4, -3, 63) +check('012', '0', -4, -2, 63) +check('012', '01', -4, -1, 63) +check('012', '', -4, 0, 63) +check('012', '0', -4, 1, 63) +check('012', '01', -4, 2, 63) +check('012', '012', -4, 3, 63) +check('012', '012', -4, 4, 63) +check('012', '012', -3, None, 63) +check('012', '', -3, -4, 63) +check('012', '', -3, -3, 63) +check('012', '0', -3, -2, 63) +check('012', '01', -3, -1, 63) +check('012', '', -3, 0, 63) +check('012', '0', -3, 1, 63) +check('012', '01', -3, 2, 63) +check('012', '012', -3, 3, 63) +check('012', '012', -3, 4, 63) +check('012', '12', -2, None, 63) +check('012', '', -2, -4, 0) +check('012', '', -2, -3, 0) +check('012', '', -2, -2, 63) +check('012', '1', -2, -1, 63) +check('012', '', -2, 0, 0) +check('012', '', -2, 1, 63) +check('012', '1', -2, 2, 63) +check('012', '12', -2, 3, 63) +check('012', '12', -2, 4, 63) +check('012', '2', -1, None, 63) +check('012', '', -1, -4, 0) +check('012', '', -1, -3, 0) +check('012', '', -1, -2, 0) +check('012', '', -1, -1, 63) +check('012', '', -1, 0, 0) +check('012', '', -1, 1, 0) +check('012', '', -1, 2, 63) +check('012', '2', -1, 3, 63) +check('012', '2', -1, 4, 63) +check('012', '012', 0, None, 63) +check('012', '', 0, -4, 63) +check('012', '', 0, -3, 63) +check('012', '0', 0, -2, 63) +check('012', '01', 0, -1, 63) +check('012', '', 0, 0, 63) +check('012', '0', 0, 1, 63) +check('012', '01', 0, 2, 63) +check('012', '012', 0, 3, 63) +check('012', '012', 0, 4, 63) +check('012', '12', 1, None, 63) +check('012', '', 1, -4, 0) +check('012', '', 1, -3, 0) +check('012', '', 1, -2, 63) +check('012', '1', 1, -1, 63) +check('012', '', 1, 0, 0) +check('012', '', 1, 1, 63) +check('012', '1', 1, 2, 63) +check('012', '12', 1, 3, 63) +check('012', '12', 1, 4, 63) +check('012', '2', 2, None, 63) +check('012', '', 2, -4, 0) +check('012', '', 2, -3, 0) +check('012', '', 2, -2, 0) +check('012', '', 2, -1, 63) +check('012', '', 2, 0, 0) +check('012', '', 2, 1, 0) +check('012', '', 2, 2, 63) +check('012', '2', 2, 3, 63) +check('012', '2', 2, 4, 63) +check('012', '', 3, None, 63) +check('012', '', 3, -4, 0) +check('012', '', 3, -3, 0) +check('012', '', 3, -2, 0) +check('012', '', 3, -1, 0) +check('012', '', 3, 0, 0) +check('012', '', 3, 1, 0) +check('012', '', 3, 2, 0) +check('012', '', 3, 3, 63) +check('012', '', 3, 4, 63) +check('012', '', 4, None, 0) +check('012', '', 4, -4, 0) +check('012', '', 4, -3, 0) +check('012', '', 4, -2, 0) +check('012', '', 4, -1, 0) +check('012', '', 4, 0, 0) +check('012', '', 4, 1, 0) +check('012', '', 4, 2, 0) +check('012', '', 4, 3, 0) +check('012', '', 4, 4, 0) +check('012', '012', None, None, 63) +check('012', '', None, -4, 63) +check('012', '', None, -3, 63) +check('012', '0', None, -2, 63) +check('012', '01', None, -1, 63) +check('012', '', None, 0, 63) +check('012', '0', None, 1, 63) +check('012', '01', None, 2, 63) +check('012', '012', None, 3, 63) +check('012', '012', None, 4, 63) +check('012', '012', -4, None, 63) +check('012', '', -4, -4, 63) +check('012', '', -4, -3, 63) +check('012', '0', -4, -2, 63) +check('012', '01', -4, -1, 63) +check('012', '', -4, 0, 63) +check('012', '0', -4, 1, 63) +check('012', '01', -4, 2, 63) +check('012', '012', -4, 3, 63) +check('012', '012', -4, 4, 63) +check('012', '012', -3, None, 63) +check('012', '', -3, -4, 63) +check('012', '', -3, -3, 63) +check('012', '0', -3, -2, 63) +check('012', '01', -3, -1, 63) +check('012', '', -3, 0, 63) +check('012', '0', -3, 1, 63) +check('012', '01', -3, 2, 63) +check('012', '012', -3, 3, 63) +check('012', '012', -3, 4, 63) +check('012', '12', -2, None, 63) +check('012', '', -2, -4, 0) +check('012', '', -2, -3, 0) +check('012', '', -2, -2, 63) +check('012', '1', -2, -1, 63) +check('012', '', -2, 0, 0) +check('012', '', -2, 1, 63) +check('012', '1', -2, 2, 63) +check('012', '12', -2, 3, 63) +check('012', '12', -2, 4, 63) +check('012', '2', -1, None, 63) +check('012', '', -1, -4, 0) +check('012', '', -1, -3, 0) +check('012', '', -1, -2, 0) +check('012', '', -1, -1, 63) +check('012', '', -1, 0, 0) +check('012', '', -1, 1, 0) +check('012', '', -1, 2, 63) +check('012', '2', -1, 3, 63) +check('012', '2', -1, 4, 63) +check('012', '012', 0, None, 63) +check('012', '', 0, -4, 63) +check('012', '', 0, -3, 63) +check('012', '0', 0, -2, 63) +check('012', '01', 0, -1, 63) +check('012', '', 0, 0, 63) +check('012', '0', 0, 1, 63) +check('012', '01', 0, 2, 63) +check('012', '012', 0, 3, 63) +check('012', '012', 0, 4, 63) +check('012', '12', 1, None, 63) +check('012', '', 1, -4, 0) +check('012', '', 1, -3, 0) +check('012', '', 1, -2, 63) +check('012', '1', 1, -1, 63) +check('012', '', 1, 0, 0) +check('012', '', 1, 1, 63) +check('012', '1', 1, 2, 63) +check('012', '12', 1, 3, 63) +check('012', '12', 1, 4, 63) +check('012', '2', 2, None, 63) +check('012', '', 2, -4, 0) +check('012', '', 2, -3, 0) +check('012', '', 2, -2, 0) +check('012', '', 2, -1, 63) +check('012', '', 2, 0, 0) +check('012', '', 2, 1, 0) +check('012', '', 2, 2, 63) +check('012', '2', 2, 3, 63) +check('012', '2', 2, 4, 63) +check('012', '', 3, None, 63) +check('012', '', 3, -4, 0) +check('012', '', 3, -3, 0) +check('012', '', 3, -2, 0) +check('012', '', 3, -1, 0) +check('012', '', 3, 0, 0) +check('012', '', 3, 1, 0) +check('012', '', 3, 2, 0) +check('012', '', 3, 3, 63) +check('012', '', 3, 4, 63) +check('012', '', 4, None, 0) +check('012', '', 4, -4, 0) +check('012', '', 4, -3, 0) +check('012', '', 4, -2, 0) +check('012', '', 4, -1, 0) +check('012', '', 4, 0, 0) +check('012', '', 4, 1, 0) +check('012', '', 4, 2, 0) +check('012', '', 4, 3, 0) +check('012', '', 4, 4, 0) diff --git a/pypy/objspace/std/test/test_bytearrayobject.py b/pypy/objspace/std/test/test_bytearrayobject.py --- a/pypy/objspace/std/test/test_bytearrayobject.py +++ b/pypy/objspace/std/test/test_bytearrayobject.py @@ -228,9 +228,11 @@ assert bytearray(b'ab').startswith(bytearray(b'b'), 1) is True assert bytearray(b'ab').startswith(bytearray(b''), 2) is True assert bytearray(b'ab').startswith(bytearray(b''), 3) is False + assert bytearray(b'0').startswith(bytearray(b''), 1, -1) is False assert bytearray(b'ab').endswith(bytearray(b'b'), 1) is True assert bytearray(b'ab').endswith(bytearray(b''), 2) is True assert bytearray(b'ab').endswith(bytearray(b''), 3) is False + assert bytearray(b'0').endswith(bytearray(b''), 1, -1) is False def test_startswith_self(self): b = bytearray(b'abcd') diff --git a/pypy/objspace/std/test/test_bytesobject.py b/pypy/objspace/std/test/test_bytesobject.py --- a/pypy/objspace/std/test/test_bytesobject.py +++ b/pypy/objspace/std/test/test_bytesobject.py @@ -424,6 +424,14 @@ assert b'ab'.startswith(b'b', 1) is True assert b'abc'.startswith(b'bc', 1, 2) is False assert b'abc'.startswith(b'c', -1, 4) is True + assert b'0'.startswith(b'', 1, -1) is False + assert b'0'.startswith(b'', 1, 0) is False + assert b'0'.startswith(b'', 1) is True + assert b'0'.startswith(b'', 1, None) is True + assert b''.startswith(b'', 1, -1) is False + assert b''.startswith(b'', 1, 0) is False + assert b''.startswith(b'', 1) is False + assert b''.startswith(b'', 1, None) is False def test_startswith_too_large(self): assert b'ab'.startswith(b'b', 1) is True @@ -467,6 +475,7 @@ assert b'abc'.endswith(b'bc', 1) is True assert b'abc'.endswith(b'bc', 2) is False assert b'abc'.endswith(b'b', -3, -1) is True + assert b'0'.endswith(b'', 1, -1) is False def test_endswith_tuple(self): assert not b'hello'.endswith((b'he', b'ha')) diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -1,5 +1,5 @@ # -*- encoding: utf-8 -*- -import py +import py, os try: from hypothesis import given, strategies, settings, example HAS_HYPOTHESIS = True @@ -605,6 +605,14 @@ assert 'ab'.startswith('b', 1) is True assert 'abc'.startswith('bc', 1, 2) is False assert 'abc'.startswith('c', -1, 4) is True + assert '0'.startswith('', 1, -1) is False + assert '0'.startswith('', 1, 0) is False + assert '0'.startswith('', 1) is True + assert '0'.startswith('', 1, None) is True + assert ''.startswith('', 1, -1) is False + assert ''.startswith('', 1, 0) is False + assert ''.startswith('', 1) is False + assert ''.startswith('', 1, None) is False try: 'hello'.startswith(['o']) except TypeError as e: @@ -662,6 +670,7 @@ assert 'abc'.endswith('bc', 1) is True assert 'abc'.endswith('bc', 2) is False assert 'abc'.endswith('b', -3, -1) is True + assert '0'.endswith('', 1, -1) is False try: 'hello'.endswith(['o']) except TypeError as e: @@ -1363,3 +1372,7 @@ def test_newlist_utf8_non_ascii(self): 'ä'.split("\n")[0] # does not crash + + with open(os.path.join(os.path.dirname(__file__), 'startswith.py')) as f: + exec 'def test_startswith_endswith_external(self): """%s"""\n' % ( + f.read(),) diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py --- a/pypy/objspace/std/unicodeobject.py +++ b/pypy/objspace/std/unicodeobject.py @@ -674,9 +674,6 @@ def descr_startswith(self, space, w_prefix, w_start=None, w_end=None): start, end = self._unwrap_and_compute_idx_params(space, w_start, w_end) value = self._utf8 - if (start > 0 and not space.is_none(w_end) and - space.getindex_w(w_end, None) == 0): - return space.w_False if space.isinstance_w(w_prefix, space.w_tuple): return self._startswith_tuple(space, value, w_prefix, start, end) try: @@ -689,7 +686,7 @@ def _startswith(self, space, value, w_prefix, start, end): prefix = self.convert_arg_to_w_unicode(space, w_prefix)._utf8 - if start > len(value): + if start > end: return False if len(prefix) == 0: return True @@ -698,10 +695,6 @@ def descr_endswith(self, space, w_suffix, w_start=None, w_end=None): start, end = self._unwrap_and_compute_idx_params(space, w_start, w_end) value = self._utf8 - # match cpython behaviour - if (start > 0 and not space.is_none(w_end) and - space.getindex_w(w_end, None) == 0): - return space.w_False if space.isinstance_w(w_suffix, space.w_tuple): return self._endswith_tuple(space, value, w_suffix, start, end) try: @@ -714,7 +707,7 @@ def _endswith(self, space, value, w_prefix, start, end): prefix = self.convert_arg_to_w_unicode(space, w_prefix)._utf8 - if start > len(value): + if start > end: return False if len(prefix) == 0: return True From pypy.commits at gmail.com Mon Jul 15 11:01:36 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 15 Jul 2019 08:01:36 -0700 (PDT) Subject: [pypy-commit] pypy arm64: close to be merged branch Message-ID: <5d2c9550.1c69fb81.e7e4f.d90d@mx.google.com> Author: fijal Branch: arm64 Changeset: r97004:4bddf4462063 Date: 2019-07-15 16:59 +0200 http://bitbucket.org/pypy/pypy/changeset/4bddf4462063/ Log: close to be merged branch diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO --- a/rpython/jit/backend/aarch64/TODO +++ b/rpython/jit/backend/aarch64/TODO @@ -1,5 +1,4 @@ * cond_call and following guard_exception -* stack check * We can try to make generate_quick_failure() emit two instructions less: From pypy.commits at gmail.com Mon Jul 15 11:01:39 2019 From: pypy.commits at gmail.com (fijal) Date: Mon, 15 Jul 2019 08:01:39 -0700 (PDT) Subject: [pypy-commit] pypy default: merge arm64 support Message-ID: <5d2c9553.1c69fb81.4971d.421c@mx.google.com> Author: fijal Branch: Changeset: r97005:f3b7650ebfc0 Date: 2019-07-15 17:00 +0200 http://bitbucket.org/pypy/pypy/changeset/f3b7650ebfc0/ Log: merge arm64 support diff too long, truncating to 2000 out of 6406 lines diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py --- a/rpython/config/translationoption.py +++ b/rpython/config/translationoption.py @@ -1,5 +1,6 @@ import sys import os +import platform as _stdlib_platform from rpython.config.config import OptionDescription, BoolOption, IntOption, ArbitraryOption, FloatOption from rpython.config.config import ChoiceOption, StrOption, Config, ConflictConfigError from rpython.config.config import ConfigError @@ -30,7 +31,9 @@ False) # Windows doesn't work. Please # add other platforms here if it works on them. - +MACHINE = _stdlib_platform.machine() +if MACHINE == 'aarch64': + SUPPORT__THREAD = False # (*) NOTE: __thread on OS/X does not work together with # pthread_key_create(): when the destructor is called, the __thread is # already freed! diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/aarch64/TODO @@ -0,0 +1,35 @@ +* cond_call and following guard_exception + + +* We can try to make generate_quick_failure() emit two instructions less: + the two store_reg() [one in generate_quick_failure and the other in + push_gcmap]. Instead we'd load the values in ip2 and ip3, and the + store_regs would occur inside self.failure_recovery_code + (which 'target' points to). + + +* use STP instead of STR in all long sequences of STR. Same with LDR + +* use "STR xzr, [..]" instead of "gen_load_int(ip, 0); STR ip, [..]". + Search around for gen_load_int(...0): it occurs at least in pop_gcmap() + _build_failure_recovery(), build_frame_realloc_slowpath(), etc. + + +* malloc_cond() and malloc_cond_varsize_frame() hard-code forward jump + distances by guessing the number of instructions that follows. Bad + idea because some of these instructions could easily be optimized in + the future to be a bit shorter. Rewrite this two places to use the + proper way instead of a magic "40" (or at least assert that it was + really 40). + + +* use "CBNZ register, offset" (compare-and-branch-if-not-zero) + instead of a CMP+BNE pair. Same with CBZ instead of CMP+BEQ + + +* when we need to save things on the stack, we typically push two words + and pop them later. It would be cheaper if we reserved two locations + in the stack from _call_header, then we could just write there. + *OR* + maybe it's enough if we use the form "str x0, [sp, !#offset]" which + combines in a single instruction the "str" with the change of sp diff --git a/rpython/jit/backend/aarch64/__init__.py b/rpython/jit/backend/aarch64/__init__.py new file mode 100644 diff --git a/rpython/jit/backend/aarch64/arch.py b/rpython/jit/backend/aarch64/arch.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/aarch64/arch.py @@ -0,0 +1,14 @@ + +WORD = 8 + +# The stack contains the force_index and the, callee saved registers and +# ABI required information +# All the rest of the data is in a GC-managed variable-size "frame". +# This jitframe object's address is always stored in the register FP +# A jitframe is a jit.backend.llsupport.llmodel.jitframe.JITFRAME +# Stack frame fixed area +# Currently only the force_index +NUM_MANAGED_REGS = 16 +NUM_VFP_REGS = 8 +JITFRAME_FIXED_SIZE = NUM_MANAGED_REGS + NUM_VFP_REGS +# 16 GPR + 8 VFP Regs, for now diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/aarch64/assembler.py @@ -0,0 +1,1482 @@ + +from rpython.jit.backend.aarch64.arch import WORD, JITFRAME_FIXED_SIZE +from rpython.jit.backend.aarch64.codebuilder import InstrBuilder, OverwritingBuilder +from rpython.jit.backend.aarch64.locations import imm, StackLocation, get_fp_offset +#from rpython.jit.backend.arm.helper.regalloc import VMEM_imm_size +from rpython.jit.backend.aarch64.opassembler import ResOpAssembler +from rpython.jit.backend.aarch64.regalloc import (Regalloc, check_imm_arg, + operations as regalloc_operations, guard_operations, comp_operations, + CoreRegisterManager, VFPRegisterManager) +from rpython.jit.backend.aarch64 import registers as r +from rpython.jit.backend.arm import conditions as c +from rpython.jit.backend.llsupport import jitframe, rewrite +from rpython.jit.backend.llsupport.assembler import BaseAssembler +from rpython.jit.backend.llsupport.regalloc import get_scale, valid_addressing_size +from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper +from rpython.jit.backend.model import CompiledLoopToken +from rpython.jit.codewriter.effectinfo import EffectInfo +from rpython.jit.metainterp.history import AbstractFailDescr, FLOAT, INT, VOID +from rpython.jit.metainterp.resoperation import rop +from rpython.rlib.debug import debug_print, debug_start, debug_stop +from rpython.rlib.jit import AsmInfo +from rpython.rlib.objectmodel import we_are_translated, specialize, compute_unique_id +from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref +from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.lltypesystem.lloperation import llop +from rpython.rlib.rjitlog import rjitlog as jl + +class AssemblerARM64(ResOpAssembler): + def __init__(self, cpu, translate_support_code=False): + ResOpAssembler.__init__(self, cpu, translate_support_code) + self.failure_recovery_code = [0, 0, 0, 0] + self.wb_slowpath = [0, 0, 0, 0, 0] + + def assemble_loop(self, jd_id, unique_id, logger, loopname, inputargs, + operations, looptoken, log): + clt = CompiledLoopToken(self.cpu, looptoken.number) + clt._debug_nbargs = len(inputargs) + looptoken.compiled_loop_token = clt + + if not we_are_translated(): + # Arguments should be unique + assert len(set(inputargs)) == len(inputargs) + + self.setup(looptoken) + + frame_info = self.datablockwrapper.malloc_aligned( + jitframe.JITFRAMEINFO_SIZE, alignment=WORD) + clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info) + clt.frame_info.clear() # for now + + if log: + operations = self._inject_debugging_code(looptoken, operations, + 'e', looptoken.number) + + regalloc = Regalloc(assembler=self) + allgcrefs = [] + operations = regalloc.prepare_loop(inputargs, operations, looptoken, + allgcrefs) + self.reserve_gcref_table(allgcrefs) + functionpos = self.mc.get_relative_pos() + + self._call_header_with_stack_check() + self._check_frame_depth_debug(self.mc) + + loop_head = self.mc.get_relative_pos() + looptoken._ll_loop_code = loop_head + # + frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) + self.update_frame_depth(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) + # + size_excluding_failure_stuff = self.mc.get_relative_pos() + + self.write_pending_failure_recoveries() + + full_size = self.mc.get_relative_pos() + rawstart = self.materialize_loop(looptoken) + looptoken._ll_function_addr = rawstart + functionpos + + self.patch_gcref_table(looptoken, rawstart) + self.process_pending_guards(rawstart) + self.fixup_target_tokens(rawstart) + + if log and not we_are_translated(): + self.mc._dump_trace(rawstart, + 'loop.asm') + + ops_offset = self.mc.ops_offset + + if logger: + log = logger.log_trace(jl.MARK_TRACE_ASM, None, self.mc) + log.write(inputargs, operations, ops_offset=ops_offset) + + # legacy + if logger.logger_ops: + logger.logger_ops.log_loop(inputargs, operations, 0, + "rewritten", name=loopname, + ops_offset=ops_offset) + + self.teardown() + + debug_start("jit-backend-addr") + debug_print("Loop %d (%s) has address 0x%x to 0x%x (bootstrap 0x%x)" % ( + looptoken.number, loopname, + r_uint(rawstart + loop_head), + r_uint(rawstart + size_excluding_failure_stuff), + r_uint(rawstart + functionpos))) + debug_print(" gc table: 0x%x" % r_uint(rawstart)) + debug_print(" function: 0x%x" % r_uint(rawstart + functionpos)) + debug_print(" resops: 0x%x" % r_uint(rawstart + loop_head)) + debug_print(" failures: 0x%x" % r_uint(rawstart + + size_excluding_failure_stuff)) + debug_print(" end: 0x%x" % r_uint(rawstart + full_size)) + debug_stop("jit-backend-addr") + + return AsmInfo(ops_offset, rawstart + loop_head, + size_excluding_failure_stuff - loop_head) + + def assemble_bridge(self, logger, faildescr, inputargs, operations, + original_loop_token, log): + if not we_are_translated(): + # Arguments should be unique + assert len(set(inputargs)) == len(inputargs) + + self.setup(original_loop_token) + #self.codemap.inherit_code_from_position(faildescr.adr_jump_offset) + descr_number = compute_unique_id(faildescr) + if log: + operations = self._inject_debugging_code(faildescr, operations, + 'b', descr_number) + + assert isinstance(faildescr, AbstractFailDescr) + + arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs) + + regalloc = Regalloc(assembler=self) + allgcrefs = [] + operations = regalloc.prepare_bridge(inputargs, arglocs, + operations, + allgcrefs, + self.current_clt.frame_info) + self.reserve_gcref_table(allgcrefs) + startpos = self.mc.get_relative_pos() + + self._check_frame_depth(self.mc, regalloc.get_gcmap()) + + bridgestartpos = self.mc.get_relative_pos() + frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) + + codeendpos = self.mc.get_relative_pos() + + self.write_pending_failure_recoveries() + + fullsize = self.mc.get_relative_pos() + rawstart = self.materialize_loop(original_loop_token) + + self.patch_gcref_table(original_loop_token, rawstart) + self.process_pending_guards(rawstart) + + debug_start("jit-backend-addr") + debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" % + (r_uint(descr_number), r_uint(rawstart + startpos), + r_uint(rawstart + codeendpos))) + debug_print(" gc table: 0x%x" % r_uint(rawstart)) + debug_print(" jump target: 0x%x" % r_uint(rawstart + startpos)) + debug_print(" resops: 0x%x" % r_uint(rawstart + bridgestartpos)) + debug_print(" failures: 0x%x" % r_uint(rawstart + codeendpos)) + debug_print(" end: 0x%x" % r_uint(rawstart + fullsize)) + debug_stop("jit-backend-addr") + + # patch the jump from original guard + self.patch_trace(faildescr, original_loop_token, + rawstart + startpos, regalloc) + + self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE, + rawstart) + if not we_are_translated(): + if log: + self.mc._dump_trace(rawstart, 'bridge.asm') + + ops_offset = self.mc.ops_offset + frame_depth = max(self.current_clt.frame_info.jfi_frame_depth, + frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) + self.fixup_target_tokens(rawstart) + self.update_frame_depth(frame_depth) + + if logger: + log = logger.log_trace(jl.MARK_TRACE_ASM, None, self.mc) + log.write(inputargs, operations, ops_offset) + # log that the already written bridge is stitched to a descr! + logger.log_patch_guard(descr_number, rawstart) + + # legacy + if logger.logger_ops: + logger.logger_ops.log_bridge(inputargs, operations, "rewritten", + faildescr, ops_offset=ops_offset) + + self.teardown() + + return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos) + + def setup(self, looptoken): + BaseAssembler.setup(self, looptoken) + assert self.memcpy_addr != 0, 'setup_once() not called?' + if we_are_translated(): + self.debug = False + self.current_clt = looptoken.compiled_loop_token + self.mc = InstrBuilder() + self.pending_guards = [] + #assert self.datablockwrapper is None --- but obscure case + # possible, e.g. getting MemoryError and continuing + allblocks = self.get_asmmemmgr_blocks(looptoken) + self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, + allblocks) + self.mc.datablockwrapper = self.datablockwrapper + self.target_tokens_currently_compiling = {} + self.frame_depth_to_patch = [] + + def teardown(self): + self.current_clt = None + self._regalloc = None + self.mc = None + self.pending_guards = None + + def _push_all_regs_to_jitframe(self, mc, ignored_regs, withfloats, + callee_only=False): + # Push general purpose registers + base_ofs = self.cpu.get_baseofs_of_frame_field() + if callee_only: + regs = CoreRegisterManager.save_around_call_regs + else: + regs = CoreRegisterManager.all_regs + # XXX add special case if ignored_regs are a block at the start of regs + if not ignored_regs: # we want to push a contiguous block of regs + assert base_ofs < 0x100 + for i, reg in enumerate(regs): + mc.STR_ri(reg.value, r.fp.value, base_ofs + i * WORD) + else: + for reg in ignored_regs: + assert not reg.is_vfp_reg() # sanity check + # we can have holes in the list of regs + for i, gpr in enumerate(regs): + if gpr in ignored_regs: + continue + self.store_reg(mc, gpr, r.fp, base_ofs + i * WORD) + + if withfloats: + # Push VFP regs + regs = VFPRegisterManager.all_regs + ofs = len(CoreRegisterManager.all_regs) * WORD + for reg in regs: + mc.STR_di(reg.value, r.fp.value, ofs + base_ofs + reg.value * WORD) + + def _pop_all_regs_from_jitframe(self, mc, ignored_regs, withfloats, + callee_only=False): + # Pop general purpose registers + base_ofs = self.cpu.get_baseofs_of_frame_field() + if callee_only: + regs = CoreRegisterManager.save_around_call_regs + else: + regs = CoreRegisterManager.all_regs + # XXX add special case if ignored_regs are a block at the start of regs + if not ignored_regs: # we want to pop a contiguous block of regs + assert base_ofs < 0x100 + for i, reg in enumerate(regs): + mc.LDR_ri(reg.value, r.fp.value, base_ofs + i * WORD) + else: + for reg in ignored_regs: + assert not reg.is_vfp_reg() # sanity check + # we can have holes in the list of regs + for i, gpr in enumerate(regs): + if gpr in ignored_regs: + continue + ofs = i * WORD + base_ofs + self.load_reg(mc, gpr, r.fp, ofs) + if withfloats: + # Pop VFP regs + regs = VFPRegisterManager.all_regs + ofs = len(CoreRegisterManager.all_regs) * WORD + for reg in regs: + mc.LDR_di(reg.value, r.fp.value, ofs + base_ofs + reg.value * WORD) + + def _build_failure_recovery(self, exc, withfloats=False): + mc = InstrBuilder() + self._push_all_regs_to_jitframe(mc, [], withfloats) + + if exc: + # We might have an exception pending. Load it into r4 + # (this is a register saved across calls) + mc.gen_load_int(r.x5.value, self.cpu.pos_exc_value()) + mc.LDR_ri(r.x4.value, r.x5.value, 0) + # clear the exc flags + mc.gen_load_int(r.x6.value, 0) + mc.STR_ri(r.x6.value, r.x5.value, 0) # pos_exc_value is still in r5 + mc.gen_load_int(r.x5.value, self.cpu.pos_exception()) + mc.STR_ri(r.x6.value, r.x5.value, 0) + # save r4 into 'jf_guard_exc' + offset = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + assert check_imm_arg(abs(offset)) + mc.STR_ri(r.x4.value, r.fp.value, offset) + # now we return from the complete frame, which starts from + # _call_header_with_stack_check(). The LEA in _call_footer below + # throws away most of the frame, including all the PUSHes that we + # did just above. + + # set return value + mc.MOV_rr(r.x0.value, r.fp.value) + + self.gen_func_epilog(mc) + rawstart = mc.materialize(self.cpu, []) + self.failure_recovery_code[exc + 2 * withfloats] = rawstart + + def propagate_memoryerror_if_reg_is_null(self, reg_loc): + # see ../x86/assembler.py:genop_discard_check_memory_error() + self.mc.CMP_ri(reg_loc.value, 0) + self.mc.B_ofs_cond(6 * 4, c.NE) + self.mc.B(self.propagate_exception_path) + + def _build_wb_slowpath(self, withcards, withfloats=False, for_frame=False): + descr = self.cpu.gc_ll_descr.write_barrier_descr + if descr is None: + return + if not withcards: + func = descr.get_write_barrier_fn(self.cpu) + else: + if descr.jit_wb_cards_set == 0: + return + func = descr.get_write_barrier_from_array_fn(self.cpu) + if func == 0: + return + # + # This builds a helper function called from the slow path of + # write barriers. It must save all registers, and optionally + # all vfp registers. It takes a single argument which is in x0. + # It must keep stack alignment accordingly. + mc = InstrBuilder() + # + mc.SUB_ri(r.sp.value, r.sp.value, 2 * WORD) + mc.STR_ri(r.lr.value, r.sp.value, 0) + if not for_frame: + self._push_all_regs_to_jitframe(mc, [], withfloats, callee_only=True) + else: + # NOTE: don't save registers on the jitframe here! It might + # override already-saved values that will be restored + # later... + # + # we're possibly called from the slowpath of malloc + # save the caller saved registers + # assuming we do not collect here + exc0, exc1 = r.x19, r.x20 + mc.SUB_ri(r.sp.value, r.sp.value, (len(r.caller_resp) + 2 + len(r.caller_vfp_resp)) * WORD) + cur_stack = 0 + for i in range(0, len(r.caller_resp), 2): + mc.STP_rri(r.caller_resp[i].value, r.caller_resp[i + 1].value, r.sp.value, i * WORD) + cur_stack = len(r.caller_resp) + mc.STP_rri(exc0.value, exc1.value, r.sp.value, cur_stack * WORD) + cur_stack += 2 + for i in range(len(r.caller_vfp_resp)): + mc.STR_di(r.caller_vfp_resp[i].value, r.sp.value, cur_stack * WORD) + cur_stack += 1 + + self._store_and_reset_exception(mc, exc0, exc1) + mc.BL(func) + # + if not for_frame: + self._pop_all_regs_from_jitframe(mc, [], withfloats, callee_only=True) + else: + exc0, exc1 = r.x19, r.x20 + self._restore_exception(mc, exc0, exc1) + + cur_stack = 0 + for i in range(0, len(r.caller_resp), 2): + mc.LDP_rri(r.caller_resp[i].value, r.caller_resp[i + 1].value, r.sp.value, i * WORD) + cur_stack = len(r.caller_resp) + mc.LDP_rri(exc0.value, exc1.value, r.sp.value, cur_stack * WORD) + cur_stack += 2 + for i in range(len(r.caller_vfp_resp)): + mc.LDR_di(r.caller_vfp_resp[i].value, r.sp.value, cur_stack * WORD) + cur_stack += 1 + + assert exc0 is not None + assert exc1 is not None + + mc.ADD_ri(r.sp.value, r.sp.value, (len(r.caller_resp) + 2 + len(r.caller_vfp_resp)) * WORD) + + # + if withcards: + # A final TEST8 before the RET, for the caller. Careful to + # not follow this instruction with another one that changes + # the status of the CPU flags! + mc.LDRB_ri(r.ip0.value, r.x0.value, descr.jit_wb_if_flag_byteofs) + mc.MOVZ_r_u16(r.ip1.value, 0x80, 0) + mc.TST_rr_shift(r.ip0.value, r.ip1.value, 0) + # + mc.LDR_ri(r.ip1.value, r.sp.value, 0) + mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) + mc.RET_r(r.ip1.value) + # + rawstart = mc.materialize(self.cpu, []) + if for_frame: + self.wb_slowpath[4] = rawstart + else: + self.wb_slowpath[withcards + 2 * withfloats] = rawstart + + def build_frame_realloc_slowpath(self): + # this code should do the following steps + # a) store all registers in the jitframe + # b) fish for the arguments passed by the caller + # c) store the gcmap in the jitframe + # d) call realloc_frame + # e) set the fp to point to the new jitframe + # f) store the address of the new jitframe in the shadowstack + # c) set the gcmap field to 0 in the new jitframe + # g) restore registers and return + mc = InstrBuilder() + self._push_all_regs_to_jitframe(mc, [], self.cpu.supports_floats) + # this is the gcmap stored by push_gcmap(mov=True) in _check_stack_frame + # and the expected_size pushed in _check_stack_frame + # pop the values passed on the stack, gcmap -> r0, expected_size -> r1 + mc.LDP_rri(r.x0.value, r.x1.value, r.sp.value, 0) + + mc.STR_ri(r.lr.value, r.sp.value, 0) + + # store the current gcmap(r0) in the jitframe + gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + mc.STR_ri(r.x0.value, r.fp.value, gcmap_ofs) + + # set first arg, which is the old jitframe address + mc.MOV_rr(r.x0.value, r.fp.value) + + # store a possibly present exception + self._store_and_reset_exception(mc, None, r.x19, on_frame=True) + + # call realloc_frame, it takes two arguments + # arg0: the old jitframe + # arg1: the new size + # + mc.BL(self.cpu.realloc_frame) + + # set fp to the new jitframe returned from the previous call + mc.MOV_rr(r.fp.value, r.x0.value) + + # restore a possibly present exception + self._restore_exception(mc, None, r.x19) + + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + self._load_shadowstack_top(mc, r.x19, gcrootmap) + # store the new jitframe addr in the shadowstack + mc.SUB_ri(r.x19.value, r.x19.value, WORD) + mc.STR_ri(r.x0.value, r.x19.value, 0) + + # reset the jf_gcmap field in the jitframe + mc.gen_load_int(r.ip0.value, 0) + mc.STR_ri(r.ip0.value, r.fp.value, gcmap_ofs) + + # restore registers + self._pop_all_regs_from_jitframe(mc, [], self.cpu.supports_floats) + + # return + mc.LDR_ri(r.lr.value, r.sp.value, 0) + mc.ADD_ri(r.sp.value, r.sp.value, 2*WORD) + mc.RET_r(r.lr.value) + self._frame_realloc_slowpath = mc.materialize(self.cpu, []) + + def _load_shadowstack_top(self, mc, reg, gcrootmap): + rst = gcrootmap.get_root_stack_top_addr() + mc.gen_load_int(reg.value, rst) + self.load_reg(mc, reg, reg) + return rst + + def _store_and_reset_exception(self, mc, excvalloc=None, exctploc=None, + on_frame=False): + """ Resest the exception. If excvalloc is None, then store it on the + frame in jf_guard_exc + """ + assert excvalloc is not r.ip0 + assert exctploc is not r.ip0 + tmpreg = r.ip1 + mc.gen_load_int(r.ip0.value, self.cpu.pos_exc_value()) + if excvalloc is not None: # store + assert excvalloc.is_core_reg() + self.load_reg(mc, excvalloc, r.ip0) + if on_frame: + # store exc_value in JITFRAME + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + assert check_imm_arg(ofs) + # + self.load_reg(mc, r.ip0, r.ip0, helper=tmpreg) + # + self.store_reg(mc, r.ip0, r.fp, ofs, helper=tmpreg) + if exctploc is not None: + # store pos_exception in exctploc + assert exctploc.is_core_reg() + mc.gen_load_int(r.ip0.value, self.cpu.pos_exception()) + self.load_reg(mc, exctploc, r.ip0, helper=tmpreg) + + if on_frame or exctploc is not None: + mc.gen_load_int(r.ip0.value, self.cpu.pos_exc_value()) + + # reset exception + mc.gen_load_int(tmpreg.value, 0) + + self.store_reg(mc, tmpreg, r.ip0, 0) + + mc.gen_load_int(r.ip0.value, self.cpu.pos_exception()) + self.store_reg(mc, tmpreg, r.ip0, 0) + + def _restore_exception(self, mc, excvalloc, exctploc): + assert excvalloc is not r.ip0 + assert exctploc is not r.ip0 + mc.gen_load_int(r.ip0.value, self.cpu.pos_exc_value()) + if excvalloc is not None: + assert excvalloc.is_core_reg() + self.store_reg(mc, excvalloc, r.ip0) + else: + assert exctploc is not r.fp + # load exc_value from JITFRAME and put it in pos_exc_value + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + self.load_reg(mc, r.ip1, r.fp, ofs) + self.store_reg(mc, r.ip1, r.ip0) + # reset exc_value in the JITFRAME + mc.gen_load_int(r.ip1.value, 0) + self.store_reg(mc, r.ip1, r.fp, ofs) + + # restore pos_exception from exctploc register + mc.gen_load_int(r.ip0.value, self.cpu.pos_exception()) + self.store_reg(mc, exctploc, r.ip0) + + def _build_propagate_exception_path(self): + mc = InstrBuilder() + self._store_and_reset_exception(mc, r.x0) + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + # make sure ofs fits into a register + assert check_imm_arg(ofs) + self.store_reg(mc, r.x0, r.fp, ofs) + propagate_exception_descr = rffi.cast(lltype.Signed, + cast_instance_to_gcref(self.cpu.propagate_exception_descr)) + # put propagate_exception_descr into frame + ofs = self.cpu.get_ofs_of_frame_field('jf_descr') + # make sure ofs fits into a register + assert check_imm_arg(ofs) + mc.gen_load_int(r.x0.value, propagate_exception_descr) + self.store_reg(mc, r.x0, r.fp, ofs) + mc.MOV_rr(r.x0.value, r.fp.value) + self.gen_func_epilog(mc) + rawstart = mc.materialize(self.cpu, []) + self.propagate_exception_path = rawstart + + def _build_cond_call_slowpath(self, supports_floats, callee_only): + """ This builds a general call slowpath, for whatever call happens to + come. + + The address of function to call comes in ip1. the result is also stored + in ip1 or ivfp + """ + mc = InstrBuilder() + # + self._push_all_regs_to_jitframe(mc, [], self.cpu.supports_floats, callee_only) + ## args are in their respective positions + mc.SUB_ri(r.sp.value, r.sp.value, 2 * WORD) + mc.STR_ri(r.ip0.value, r.sp.value, WORD) + mc.STR_ri(r.lr.value, r.sp.value, 0) + mc.BLR_r(r.ip1.value) + # callee saved + self._reload_frame_if_necessary(mc) # <- this will not touch x0 + mc.MOV_rr(r.ip1.value, r.x0.value) + self._pop_all_regs_from_jitframe(mc, [], supports_floats, + callee_only) # <- this does not touch ip1 + # return + mc.LDR_ri(r.ip0.value, r.sp.value, 0) + mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) + mc.RET_r(r.ip0.value) + return mc.materialize(self.cpu, []) + + def _build_malloc_slowpath(self, kind): + """ While arriving on slowpath, we have a gcpattern on stack 0. + The arguments are passed in r0 and r10, as follows: + + kind == 'fixed': nursery_head in r0 and the size in r1 - r0. + + kind == 'str/unicode': length of the string to allocate in r0. + + kind == 'var': length to allocate in r1, tid in r0, + and itemsize on the stack. + + This function must preserve all registers apart from r0 and r1. + """ + assert kind in ['fixed', 'str', 'unicode', 'var'] + mc = InstrBuilder() + # + self._push_all_regs_to_jitframe(mc, [r.x0, r.x1], True) + # + if kind == 'fixed': + addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr() + elif kind == 'str': + addr = self.cpu.gc_ll_descr.get_malloc_fn_addr('malloc_str') + elif kind == 'unicode': + addr = self.cpu.gc_ll_descr.get_malloc_fn_addr('malloc_unicode') + else: + addr = self.cpu.gc_ll_descr.get_malloc_slowpath_array_addr() + if kind == 'fixed': + # At this point we know that the values we need to compute the size + # are stored in x0 and x1. + mc.SUB_rr(r.x0.value, r.x1.value, r.x0.value) # compute the size we want + + if hasattr(self.cpu.gc_ll_descr, 'passes_frame'): + mc.MOV_rr(r.x1.value, r.fp.value) + elif kind == 'str' or kind == 'unicode': + mc.MOV_rr(r.x0.value, r.x1.value) + else: # var + # tid is in x0 + # length is in x1 + # gcmap in ip1 + # itemsize in ip2 + mc.MOV_rr(r.x2.value, r.x1.value) + mc.MOV_rr(r.x1.value, r.x0.value) + mc.MOV_rr(r.x0.value, r.ip2.value) # load itemsize, ip2 now free + # store the gc pattern + ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + mc.STR_ri(r.ip1.value, r.fp.value, ofs) + # + mc.SUB_ri(r.sp.value, r.sp.value, 2 * WORD) + mc.STR_ri(r.lr.value, r.sp.value, 0) + # + mc.BL(addr) + # + # If the slowpath malloc failed, we raise a MemoryError that + # always interrupts the current loop, as a "good enough" + # approximation. + mc.CMP_ri(r.x0.value, 0) + mc.B_ofs_cond(4 * 6, c.NE) + mc.B(self.propagate_exception_path) + # jump here + self._reload_frame_if_necessary(mc) + self._pop_all_regs_from_jitframe(mc, [r.x0, r.x1], self.cpu.supports_floats) + # + nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr() + mc.gen_load_int(r.x1.value, nursery_free_adr) + mc.LDR_ri(r.x1.value, r.x1.value, 0) + # clear the gc pattern + mc.gen_load_int(r.ip0.value, 0) + self.store_reg(mc, r.ip0, r.fp, ofs) + # return + mc.LDR_ri(r.lr.value, r.sp.value, 0) + mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) + mc.RET_r(r.lr.value) + + # + rawstart = mc.materialize(self.cpu, []) + return rawstart + + def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, gcmap): + assert size & (WORD-1) == 0 + + self.mc.gen_load_int(r.x0.value, nursery_free_adr) + self.mc.LDR_ri(r.x0.value, r.x0.value, 0) + + if check_imm_arg(size): + self.mc.ADD_ri(r.x1.value, r.x0.value, size) + else: + self.mc.gen_load_int(r.x1.value, size) + self.mc.ADD_rr(r.x1.value, r.x0.value, r.x1.value) + + self.mc.gen_load_int(r.ip0.value, nursery_top_adr) + self.mc.LDR_ri(r.ip0.value, r.ip0.value, 0) + + self.mc.CMP_rr(r.x1.value, r.ip0.value) + + # We load into r0 the address stored at nursery_free_adr We calculate + # the new value for nursery_free_adr and store in r1 The we load the + # address stored in nursery_top_adr into IP If the value in r1 is + # (unsigned) bigger than the one in ip we conditionally call + # malloc_slowpath in case we called malloc_slowpath, which returns the + # new value of nursery_free_adr in r1 and the adr of the new object in + # r0. + + self.mc.B_ofs_cond(10 * 4, c.LO) # 4 for gcmap load, 5 for BL, 1 for B_ofs_cond + self.mc.gen_load_int_full(r.ip1.value, rffi.cast(lltype.Signed, gcmap)) + + self.mc.BL(self.malloc_slowpath) + + self.mc.gen_load_int(r.ip0.value, nursery_free_adr) + self.mc.STR_ri(r.x1.value, r.ip0.value, 0) + + def malloc_cond_varsize_frame(self, nursery_free_adr, nursery_top_adr, + sizeloc, gcmap): + if sizeloc is r.x0: + self.mc.MOV_rr(r.x1.value, r.x0.value) + sizeloc = r.x1 + self.mc.gen_load_int(r.x0.value, nursery_free_adr) + self.mc.LDR_ri(r.x0.value, r.x0.value, 0) + # + self.mc.ADD_rr(r.x1.value, r.x0.value, sizeloc.value) + # + self.mc.gen_load_int(r.ip0.value, nursery_top_adr) + self.mc.LDR_ri(r.ip0.value, r.ip0.value, 0) + + self.mc.CMP_rr(r.x1.value, r.ip0.value) + # + self.mc.B_ofs_cond(40, c.LO) # see calculations in malloc_cond + self.mc.gen_load_int_full(r.ip1.value, rffi.cast(lltype.Signed, gcmap)) + + self.mc.BL(self.malloc_slowpath) + + self.mc.gen_load_int(r.ip0.value, nursery_free_adr) + self.mc.STR_ri(r.x1.value, r.ip0.value, 0) + + def malloc_cond_varsize(self, kind, nursery_free_adr, nursery_top_adr, + lengthloc, itemsize, maxlength, gcmap, + arraydescr): + from rpython.jit.backend.llsupport.descr import ArrayDescr + assert isinstance(arraydescr, ArrayDescr) + + # lengthloc is the length of the array, which we must not modify! + assert lengthloc is not r.x0 and lengthloc is not r.x1 + if lengthloc.is_core_reg(): + varsizeloc = lengthloc + else: + assert lengthloc.is_stack() + self.regalloc_mov(lengthloc, r.x1) + varsizeloc = r.x1 + # + if check_imm_arg(maxlength): + self.mc.CMP_ri(varsizeloc.value, maxlength) + else: + self.mc.gen_load_int(r.ip0.value, maxlength) + self.mc.CMP_rr(varsizeloc.value, r.ip0.value) + jmp_adr0 = self.mc.currpos() # jump to (large) + self.mc.BRK() + # + self.mc.gen_load_int(r.x0.value, nursery_free_adr) + self.mc.LDR_ri(r.x0.value, r.x0.value, 0) + + + if valid_addressing_size(itemsize): + shiftsize = get_scale(itemsize) + else: + shiftsize = self._mul_const_scaled(self.mc, r.lr, varsizeloc, + itemsize) + varsizeloc = r.lr + # now varsizeloc is a register != x0. The size of + # the variable part of the array is (varsizeloc << shiftsize) + assert arraydescr.basesize >= self.gc_minimal_size_in_nursery + constsize = arraydescr.basesize + self.gc_size_of_header + force_realignment = (itemsize % WORD) != 0 + if force_realignment: + constsize += WORD - 1 + self.mc.gen_load_int(r.ip0.value, constsize) + # constsize + (varsizeloc << shiftsize) + self.mc.ADD_rr_shifted(r.x1.value, r.ip0.value, varsizeloc.value, + shiftsize) + self.mc.ADD_rr(r.x1.value, r.x1.value, r.x0.value) + if force_realignment: + # -WORD = 0xfffffffffffffff8 + self.mc.gen_load_int(r.ip0.value, -WORD) + self.mc.AND_rr(r.x1.value, r.x1.value, r.ip0.value) + # now x1 contains the total size in bytes, rounded up to a multiple + # of WORD, plus nursery_free_adr + # + self.mc.gen_load_int(r.ip0.value, nursery_top_adr) + self.mc.LDR_ri(r.ip0.value, r.ip0.value, 0) + + self.mc.CMP_rr(r.x1.value, r.ip0.value) + jmp_adr1 = self.mc.currpos() # jump to (after-call) + self.mc.BRK() + # + # (large) + currpos = self.mc.currpos() + pmc = OverwritingBuilder(self.mc, jmp_adr0, WORD) + pmc.B_ofs_cond(currpos - jmp_adr0, c.GT) + # + # save the gcmap + self.mc.gen_load_int_full(r.ip1.value, rffi.cast(lltype.Signed, gcmap)) + # + + if kind == rewrite.FLAG_ARRAY: + self.mc.gen_load_int(r.x0.value, arraydescr.tid) + self.regalloc_mov(lengthloc, r.x1) + self.mc.gen_load_int(r.ip2.value, itemsize) + addr = self.malloc_slowpath_varsize + else: + if kind == rewrite.FLAG_STR: + addr = self.malloc_slowpath_str + else: + assert kind == rewrite.FLAG_UNICODE + addr = self.malloc_slowpath_unicode + self.regalloc_mov(lengthloc, r.x1) + self.mc.BL(addr) + # + jmp_location = self.mc.currpos() # jump to (done) + self.mc.BRK() + # (after-call) + currpos = self.mc.currpos() + pmc = OverwritingBuilder(self.mc, jmp_adr1, WORD) + pmc.B_ofs_cond(currpos - jmp_adr1, c.LS) + # + # write down the tid, but not if it's the result of the CALL + self.mc.gen_load_int(r.ip0.value, arraydescr.tid) + self.mc.STR_ri(r.ip0.value, r.x0.value, 0) + + # while we're at it, this line is not needed if we've done the CALL + self.mc.gen_load_int(r.ip0.value, nursery_free_adr) + self.mc.STR_ri(r.x1.value, r.ip0.value, 0) + # (done) + # skip instructions after call + currpos = self.mc.currpos() + pmc = OverwritingBuilder(self.mc, jmp_location, WORD) + pmc.B_ofs(currpos - jmp_location) + + def _mul_const_scaled(self, mc, targetreg, sourcereg, itemsize): + """Produce one operation to do roughly + targetreg = sourcereg * itemsize + except that the targetreg may still need shifting by 0,1,2,3. + """ + if (itemsize & 7) == 0: + shiftsize = 3 + elif (itemsize & 3) == 0: + shiftsize = 2 + elif (itemsize & 1) == 0: + shiftsize = 1 + else: + shiftsize = 0 + itemsize >>= shiftsize + # + if valid_addressing_size(itemsize - 1): + self.mc.ADD_rr_shifted(targetreg.value, sourcereg.value, sourcereg.value, + get_scale(itemsize - 1)) + elif valid_addressing_size(itemsize): + self.mc.LSL_ri(targetreg.value, sourcereg.value, + get_scale(itemsize)) + else: + mc.gen_load_int(targetreg.value, itemsize) + mc.MUL_rr(targetreg.value, sourcereg.value, targetreg.value) + # + return shiftsize + + + def _build_stack_check_slowpath(self): + _, _, slowpathaddr = self.cpu.insert_stack_check() + if slowpathaddr == 0 or not self.cpu.propagate_exception_descr: + return # no stack check (for tests, or non-translated) + # + # make a "function" that is called immediately at the start of + # an assembler function. In particular, the stack looks like: + # + # | retaddr of caller | <-- aligned to a multiple of 16 + # | saved argument regs | + # | my own retaddr | <-- sp + # +-----------------------+ + # + mc = InstrBuilder() + # save argument registers and return address + mc.SUB_ri(r.sp.value, r.sp.value, (len(r.argument_regs) + 2) * WORD) + mc.STR_ri(r.lr.value, r.sp.value, 0) + for i in range(0, len(r.argument_regs), 2): + mc.STP_rri(r.argument_regs[i].value, r.argument_regs[i + 1].value, + r.sp.value, (i + 2) * WORD) + # stack is aligned here + # Pass current stack pointer as argument to the call + mc.SUB_ri(r.x0.value, r.sp.value, 0) + # + mc.BL(slowpathaddr) + + # check for an exception + mc.gen_load_int(r.x0.value, self.cpu.pos_exception()) + mc.LDR_ri(r.x0.value, r.x0.value, 0) + mc.TST_rr_shift(r.x0.value, r.x0.value, 0) + # + # restore registers and return + # We check for c.EQ here, meaning all bits zero in this case + + jmp = mc.currpos() + mc.BRK() + + for i in range(0, len(r.argument_regs), 2): + mc.LDP_rri(r.argument_regs[i].value, r.argument_regs[i + 1].value, + r.sp.value, (i + 2) * WORD) + mc.LDR_ri(r.ip0.value, r.sp.value, 0) + mc.ADD_ri(r.sp.value, r.sp.value, (len(r.argument_regs) + 2) * WORD) + mc.RET_r(r.ip0.value) + + # jump here + + pmc = OverwritingBuilder(mc, jmp, WORD) + pmc.B_ofs_cond(mc.currpos() - jmp, c.NE) + + mc.ADD_ri(r.sp.value, r.sp.value, (len(r.argument_regs) + 2) * WORD) + mc.B(self.propagate_exception_path) + # + + rawstart = mc.materialize(self.cpu, []) + self.stack_check_slowpath = rawstart + + def _check_frame_depth_debug(self, mc): + pass + + def _check_frame_depth(self, mc, gcmap, expected_size=-1): + """ check if the frame is of enough depth to follow this bridge. + Otherwise reallocate the frame in a helper. + There are other potential solutions + to that, but this one does not sound too bad. + """ + descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) + ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) + mc.LDR_ri(r.ip0.value, r.fp.value, ofs) + stack_check_cmp_ofs = mc.currpos() + if expected_size == -1: + for _ in range(mc.get_max_size_of_gen_load_int()): + mc.NOP() + else: + mc.gen_load_int(r.ip1.value, expected_size) + mc.CMP_rr(r.ip0.value, r.ip1.value) + + jg_location = mc.currpos() + mc.BRK() + + # the size value is still stored in ip1 + mc.SUB_ri(r.sp.value, r.sp.value, 2*WORD) + mc.STR_ri(r.ip1.value, r.sp.value, WORD) + + mc.gen_load_int(r.ip0.value, rffi.cast(lltype.Signed, gcmap)) + mc.STR_ri(r.ip0.value, r.sp.value, 0) + + mc.BL(self._frame_realloc_slowpath) + + # patch jg_location above + currpos = mc.currpos() + pmc = OverwritingBuilder(mc, jg_location, WORD) + pmc.B_ofs_cond(currpos - jg_location, c.GE) + + self.frame_depth_to_patch.append(stack_check_cmp_ofs) + + def update_frame_depth(self, frame_depth): + baseofs = self.cpu.get_baseofs_of_frame_field() + self.current_clt.frame_info.update_frame_depth(baseofs, frame_depth) + + def _reload_frame_if_necessary(self, mc): + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + rst = gcrootmap.get_root_stack_top_addr() + mc.gen_load_int(r.ip0.value, rst) + self.load_reg(mc, r.ip0, r.ip0) + mc.SUB_ri(r.ip0.value, r.ip0.value, WORD) + mc.LDR_ri(r.fp.value, r.ip0.value, 0) + wbdescr = self.cpu.gc_ll_descr.write_barrier_descr + if gcrootmap and wbdescr: + # frame never uses card marking, so we enforce this is not + # an array + self._write_barrier_fastpath(mc, wbdescr, [r.fp], array=False, + is_frame=True) + + def generate_quick_failure(self, guardtok): + startpos = self.mc.currpos() + faildescrindex, target = self.store_info_on_descr(startpos, guardtok) + self.load_from_gc_table(r.ip0.value, faildescrindex) + ofs = self.cpu.get_ofs_of_frame_field('jf_descr') + self.store_reg(self.mc, r.ip0, r.fp, ofs) + self.push_gcmap(self.mc, gcmap=guardtok.gcmap) + assert target + self.mc.BL(target) + return startpos + + def push_gcmap(self, mc, gcmap, store=True): + assert store + ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + ptr = rffi.cast(lltype.Signed, gcmap) + mc.gen_load_int(r.ip0.value, ptr) + self.store_reg(mc, r.ip0, r.fp, ofs) + + def pop_gcmap(self, mc): + ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + mc.gen_load_int(r.ip0.value, 0) + self.store_reg(mc, r.ip0, r.fp, ofs) + + def write_pending_failure_recoveries(self): + for tok in self.pending_guards: + #generate the exit stub and the encoded representation + tok.pos_recovery_stub = self.generate_quick_failure(tok) + + def reserve_gcref_table(self, allgcrefs): + gcref_table_size = len(allgcrefs) * WORD + # align to a multiple of 16 and reserve space at the beginning + # of the machine code for the gc table. This lets us write + # machine code with relative addressing (LDR literal). + gcref_table_size = (gcref_table_size + 15) & ~15 + mc = self.mc + assert mc.get_relative_pos() == 0 + for i in range(gcref_table_size): + mc.writechar('\x00') + self.setup_gcrefs_list(allgcrefs) + + def patch_gcref_table(self, looptoken, rawstart): + # the gc table is at the start of the machine code + self.gc_table_addr = rawstart + tracer = self.cpu.gc_ll_descr.make_gcref_tracer(rawstart, + self._allgcrefs) + gcreftracers = self.get_asmmemmgr_gcreftracers(looptoken) + gcreftracers.append(tracer) # keepalive + self.teardown_gcrefs_list() + + def patch_stack_checks(self, framedepth, rawstart): + for ofs in self.frame_depth_to_patch: + mc = InstrBuilder() + mc.gen_load_int(r.ip1.value, framedepth) + mc.copy_to_raw_memory(ofs + rawstart) + + def load_from_gc_table(self, regnum, index): + address_in_buffer = index * WORD # at the start of the buffer + p_location = self.mc.get_relative_pos(break_basic_block=False) + offset = address_in_buffer - p_location + self.mc.LDR_r_literal(regnum, offset) + + def materialize_loop(self, looptoken): + self.datablockwrapper.done() # finish using cpu.asmmemmgr + self.datablockwrapper = None + allblocks = self.get_asmmemmgr_blocks(looptoken) + size = self.mc.get_relative_pos() + res = self.mc.materialize(self.cpu, allblocks, + self.cpu.gc_ll_descr.gcrootmap) + #self.cpu.codemap.register_codemap( + # self.codemap.get_final_bytecode(res, size)) + return res + + def patch_trace(self, faildescr, looptoken, bridge_addr, regalloc): + b = InstrBuilder() + patch_addr = faildescr.adr_jump_offset + assert patch_addr != 0 + b.BL(bridge_addr) + b.copy_to_raw_memory(patch_addr) + faildescr.adr_jump_offset = 0 + + def process_pending_guards(self, block_start): + clt = self.current_clt + for tok in self.pending_guards: + descr = tok.faildescr + assert isinstance(descr, AbstractFailDescr) + failure_recovery_pos = block_start + tok.pos_recovery_stub + descr.adr_jump_offset = failure_recovery_pos + relative_offset = tok.pos_recovery_stub - tok.offset + guard_pos = block_start + tok.offset + if not tok.guard_not_invalidated(): + # patch the guard jump to the stub + # overwrite the generate BRK with a B_offs to the pos of the + # stub + mc = InstrBuilder() + mc.B_ofs_cond(relative_offset, c.get_opposite_of(tok.fcond)) + mc.copy_to_raw_memory(guard_pos) + if tok.extra_offset != -1: + mc = InstrBuilder() + relative_offset = tok.pos_recovery_stub - tok.extra_offset + guard_pos = block_start + tok.extra_offset + mc.B_ofs_cond(relative_offset, c.get_opposite_of(tok.extra_cond)) + mc.copy_to_raw_memory(guard_pos) + else: + clt.invalidate_positions.append((guard_pos, relative_offset)) + + def fixup_target_tokens(self, rawstart): + for targettoken in self.target_tokens_currently_compiling: + targettoken._ll_loop_code += rawstart + self.target_tokens_currently_compiling = None + + def _call_header_with_stack_check(self): + self._call_header() + if self.stack_check_slowpath == 0: + pass # no stack check (e.g. not translated) + else: + endaddr, lengthaddr, _ = self.cpu.insert_stack_check() + # load stack end + self.mc.gen_load_int(r.lr.value, endaddr) # load lr, [end] + self.mc.LDR_ri(r.lr.value, r.lr.value, 0) # LDR lr, lr + # load stack length + self.mc.gen_load_int(r.ip1.value, lengthaddr) # load ip1, lengh + self.mc.LDR_ri(r.ip1.value, r.ip1.value, 0) # ldr ip1, *lengh + # calculate ofs + self.mc.SUB_ri(r.ip0.value, r.sp.value, 0) # ip0 = sp + # otherwise we can't use sp + self.mc.SUB_rr(r.lr.value, r.lr.value, r.ip0.value) # lr = lr - ip0 + # if ofs + self.mc.CMP_rr(r.lr.value, r.ip1.value) # CMP ip0, ip1 + pos = self.mc.currpos() + self.mc.BRK() + self.mc.BL(self.stack_check_slowpath) # call if ip0 > ip1 + pmc = OverwritingBuilder(self.mc, pos, WORD) + pmc.B_ofs_cond(self.mc.currpos() - pos, c.LS) + + def _call_header(self): + stack_size = (len(r.callee_saved_registers) + 4) * WORD + self.mc.STP_rr_preindex(r.lr.value, r.fp.value, r.sp.value, -stack_size) + for i in range(0, len(r.callee_saved_registers), 2): + self.mc.STP_rri(r.callee_saved_registers[i].value, + r.callee_saved_registers[i + 1].value, + r.sp.value, + (i + 4) * WORD) + + self.saved_threadlocal_addr = 3 * WORD # at offset 3 from location 'sp' + self.mc.STR_ri(r.x1.value, r.sp.value, 3 * WORD) + + # set fp to point to the JITFRAME, passed in argument 'x0' + self.mc.MOV_rr(r.fp.value, r.x0.value) + # + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + self.gen_shadowstack_header(gcrootmap) + + def _assemble(self, regalloc, inputargs, operations): + #self.guard_success_cc = c.cond_none + regalloc.compute_hint_frame_locations(operations) + self._walk_operations(inputargs, operations, regalloc) + #assert self.guard_success_cc == c.cond_none + frame_depth = regalloc.get_final_frame_depth() + jump_target_descr = regalloc.jump_target_descr + if jump_target_descr is not None: + tgt_depth = jump_target_descr._arm_clt.frame_info.jfi_frame_depth + target_frame_depth = tgt_depth - JITFRAME_FIXED_SIZE + frame_depth = max(frame_depth, target_frame_depth) + return frame_depth + + def _walk_operations(self, inputargs, operations, regalloc): + self._regalloc = regalloc + regalloc.operations = operations + while regalloc.position() < len(operations) - 1: + regalloc.next_instruction() + i = regalloc.position() + op = operations[i] + self.mc.mark_op(op) + opnum = op.getopnum() + if rop.has_no_side_effect(opnum) and op not in regalloc.longevity: + regalloc.possibly_free_vars_for_op(op) + elif not we_are_translated() and op.getopnum() == rop.FORCE_SPILL: + regalloc.force_spill_var(op.getarg(0)) + elif ((rop.returns_bool_result(opnum) or op.is_ovf()) and + i < len(operations) - 1 and + regalloc.next_op_can_accept_cc(operations, i) or + operations[i].is_ovf()): + if operations[i].is_ovf(): + assert operations[i + 1].getopnum() in [rop.GUARD_OVERFLOW, + rop.GUARD_NO_OVERFLOW] + guard_op = operations[i + 1] + guard_num = guard_op.getopnum() + arglocs, fcond = guard_operations[guard_num](regalloc, guard_op, op) + if arglocs is not None: + asm_guard_operations[guard_num](self, op, guard_op, fcond, arglocs) + regalloc.next_instruction() # advance one more + if guard_op.is_guard(): # can be also cond_call + regalloc.possibly_free_vars(guard_op.getfailargs()) + regalloc.possibly_free_vars_for_op(guard_op) + elif (rop.is_call_may_force(op.getopnum()) or + rop.is_call_release_gil(op.getopnum()) or + rop.is_call_assembler(op.getopnum())): + guard_op = operations[i + 1] # has to exist + guard_num = guard_op.getopnum() + assert guard_num in (rop.GUARD_NOT_FORCED, rop.GUARD_NOT_FORCED_2) + arglocs, fcond = guard_operations[guard_num](regalloc, guard_op, op) + if arglocs is not None: + asm_guard_operations[guard_num](self, op, guard_op, fcond, arglocs) + # fcond is abused here to pass the number of args + regalloc.next_instruction() # advance one more + regalloc.possibly_free_vars(guard_op.getfailargs()) + regalloc.possibly_free_vars_for_op(guard_op) + else: + arglocs = regalloc_operations[opnum](regalloc, op) + if arglocs is not None: + asm_operations[opnum](self, op, arglocs) + if rop.is_guard(opnum): + regalloc.possibly_free_vars(op.getfailargs()) + if op.type != 'v': + regalloc.possibly_free_var(op) + regalloc.possibly_free_vars_for_op(op) + regalloc.free_temp_vars() + regalloc._check_invariants() + if not we_are_translated(): + self.mc.BRK() + self.mc.mark_op(None) # end of the loop + regalloc.operations = None + + def dispatch_comparison(self, op): + opnum = op.getopnum() + arglocs = comp_operations[opnum](self._regalloc, op, True) + assert arglocs is not None + return asm_comp_operations[opnum](self, op, arglocs) + + # regalloc support + def load(self, loc, value): + """load an immediate value into a register""" + assert (loc.is_core_reg() and value.is_imm() + or loc.is_vfp_reg() and value.is_imm_float()) + if value.is_imm(): + self.mc.gen_load_int(loc.value, value.getint()) + elif value.is_imm_float(): + self.mc.gen_load_int(r.ip0.value, value.getint()) + self.mc.LDR_di(loc.value, r.ip0.value, 0) + + def _mov_stack_to_loc(self, prev_loc, loc): + offset = prev_loc.value + if loc.is_core_reg(): + assert prev_loc.type != FLOAT, 'trying to load from an \ + incompatible location into a core register' + # unspill a core register + assert 0 <= offset <= (1<<15) - 1 + self.mc.LDR_ri(loc.value, r.fp.value, offset) + return + if loc.is_vfp_reg(): + assert prev_loc.type == FLOAT, 'trying to load from an \ + incompatible location into a float register' + assert 0 <= offset <= (1 << 15) - 1 + self.mc.LDR_di(loc.value, r.fp.value, offset) + return + assert False + # elif loc.is_vfp_reg(): + # assert prev_loc.type == FLOAT, 'trying to load from an \ + # incompatible location into a float register' + # # load spilled value into vfp reg + # is_imm = check_imm_arg(offset) + # helper, save = self.get_tmp_reg() + # save_helper = not is_imm and save + # elif loc.is_raw_sp(): + # assert (loc.type == prev_loc.type == FLOAT + # or (loc.type != FLOAT and prev_loc.type != FLOAT)) + # tmp = loc + # if loc.is_float(): + # loc = r.vfp_ip + # else: + # loc, save_helper = self.get_tmp_reg() + # assert not save_helper + # helper, save_helper = self.get_tmp_reg([loc]) + # assert not save_helper + # else: + # assert 0, 'unsupported case' + + # if save_helper: + # self.mc.PUSH([helper.value], cond=cond) + # self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=helper) + # if save_helper: + # self.mc.POP([helper.value], cond=cond) + + def _mov_reg_to_loc(self, prev_loc, loc): + if loc.is_core_reg(): + self.mc.MOV_rr(loc.value, prev_loc.value) + elif loc.is_stack(): + self.mc.STR_ri(prev_loc.value, r.fp.value, loc.value) + else: + assert False + + def _mov_imm_to_loc(self, prev_loc, loc): + if loc.is_core_reg(): + self.mc.gen_load_int(loc.value, prev_loc.value) + elif loc.is_stack(): + self.mc.gen_load_int(r.ip0.value, prev_loc.value) + self.mc.STR_ri(r.ip0.value, r.fp.value, loc.value) + else: + assert False + + def new_stack_loc(self, i, tp): + base_ofs = self.cpu.get_baseofs_of_frame_field() + return StackLocation(i, get_fp_offset(base_ofs, i), tp) + + def mov_loc_to_raw_stack(self, loc, pos): + if loc.is_core_reg(): + self.mc.STR_ri(loc.value, r.sp.value, pos) + elif loc.is_stack(): + self.mc.LDR_ri(r.ip0.value, r.fp.value, loc.value) + self.mc.STR_ri(r.ip0.value, r.sp.value, pos) + elif loc.is_vfp_reg(): + self.mc.STR_di(loc.value, r.sp.value, pos) + elif loc.is_imm(): + self.mc.gen_load_int(r.ip0.value, loc.value) + self.mc.STR_ri(r.ip0.value, r.sp.value, pos) + else: + assert False, "wrong loc" + + def mov_raw_stack_to_loc(self, pos, loc): + if loc.is_core_reg(): + self.mc.LDR_ri(loc.value, r.sp.value, pos) + elif loc.is_stack(): + self.mc.LDR_ri(r.ip0.value, r.sp.value, pos) + self.mc.STR_ri(r.ip0.value, r.fp.value, loc.value) + elif loc.is_vfp_reg(): + self.mc.LDR_di(loc.value, r.sp.value, pos) + else: + assert False, "wrong loc" + + def _mov_imm_float_to_loc(self, prev_loc, loc): + if loc.is_vfp_reg(): + self.load(loc, prev_loc) + elif loc.is_stack(): + self.load(r.vfp_ip, prev_loc) + self._mov_vfp_reg_to_loc(r.vfp_ip, loc) + else: + assert False, "wrong loc" + + def _mov_vfp_reg_to_loc(self, prev_loc, loc): + if loc.is_stack(): + self.mc.STR_di(prev_loc.value, r.fp.value, loc.value) + elif loc.is_vfp_reg(): + self.mc.FMOV_dd(loc.value, prev_loc.value) + else: + assert False, "wrong loc" + + def push_locations(self, locs): + if not locs: + return + depth = len(locs) * WORD + depth += depth & WORD # align + self.mc.SUB_ri(r.sp.value, r.sp.value, depth) + for i, loc in enumerate(locs): + self.mov_loc_to_raw_stack(loc, i * WORD) + + def pop_locations(self, locs): + if not locs: + return + depth = len(locs) * WORD + depth += depth & WORD # align + for i, loc in enumerate(locs): + self.mov_raw_stack_to_loc(i * WORD, loc) + self.mc.ADD_ri(r.sp.value, r.sp.value, depth) + + def regalloc_mov(self, prev_loc, loc): + """Moves a value from a previous location to some other location""" + if prev_loc.is_imm(): + return self._mov_imm_to_loc(prev_loc, loc) + elif prev_loc.is_core_reg(): + self._mov_reg_to_loc(prev_loc, loc) + elif prev_loc.is_stack(): + self._mov_stack_to_loc(prev_loc, loc) + elif prev_loc.is_imm_float(): + self._mov_imm_float_to_loc(prev_loc, loc) + elif prev_loc.is_vfp_reg(): + self._mov_vfp_reg_to_loc(prev_loc, loc) + else: + assert 0, 'unsupported case' + mov_loc_loc = regalloc_mov + + def gen_func_epilog(self, mc=None): + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if mc is None: + mc = self.mc + if gcrootmap and gcrootmap.is_shadow_stack: + self.gen_footer_shadowstack(gcrootmap, mc) + + # pop all callee saved registers + + stack_size = (len(r.callee_saved_registers) + 4) * WORD + + for i in range(0, len(r.callee_saved_registers), 2): + mc.LDP_rri(r.callee_saved_registers[i].value, + r.callee_saved_registers[i + 1].value, + r.sp.value, + (i + 4) * WORD) + mc.LDP_rr_postindex(r.lr.value, r.fp.value, r.sp.value, stack_size) + + + mc.RET_r(r.lr.value) + + def gen_shadowstack_header(self, gcrootmap): + # we push two words, like the x86 backend does: + # the '1' is to benefit from the shadowstack 'is_minor' optimization + rst = gcrootmap.get_root_stack_top_addr() + self.mc.gen_load_int(r.ip1.value, rst) + # x8 = *ip1 + self.load_reg(self.mc, r.x8, r.ip1) + # x8[0] = 1 + self.mc.gen_load_int(r.ip0.value, 1) + self.store_reg(self.mc, r.ip0, r.x8) + # x8[1] = r.fp + self.store_reg(self.mc, r.fp, r.x8, WORD) + # *ip1 = x8 + 2 * WORD + self.mc.ADD_ri(r.x8.value, r.x8.value, 2 * WORD) + self.store_reg(self.mc, r.x8, r.ip1) + + def gen_footer_shadowstack(self, gcrootmap, mc): + rst = gcrootmap.get_root_stack_top_addr() + mc.gen_load_int(r.ip0.value, rst) + self.load_reg(mc, r.ip1, r.ip0) + mc.SUB_ri(r.ip1.value, r.ip1.value, 2 * WORD) # two words, see above + self.store_reg(mc, r.ip1, r.ip0) + + def store_reg(self, mc, source, base, ofs=0, helper=None): + if source.is_vfp_reg(): + return self._store_vfp_reg(mc, source, base, ofs) + else: + return self._store_core_reg(mc, source, base, ofs) + + def _store_vfp_reg(self, mc, source, base, ofs): + assert ofs <= (1 << 15) - 1 + mc.STR_di(source.value, base.value, ofs) + + def _store_core_reg(self, mc, source, base, ofs): + # XXX fix: + assert ofs & 0x7 == 0 + assert 0 <= ofs < 32768 + mc.STR_ri(source.value, base.value, ofs) + #if check_imm_arg(ofs): + # mc.STR_ri(source.value, base.value, imm=ofs) + #else: + # mc.gen_load_int(r.ip1, ofs) + # mc.STR_rr(source.value, base.value, r.ip1) + + def load_reg(self, mc, target, base, ofs=0, helper=r.ip0): + assert target.is_core_reg() + if check_imm_arg(abs(ofs)): + mc.LDR_ri(target.value, base.value, ofs) + else: + mc.gen_load_int(helper.value, ofs) + mc.LDR_rr(target.value, base.value, helper.value) + + def check_frame_before_jump(self, target_token): + if target_token in self.target_tokens_currently_compiling: + return + if target_token._arm_clt is self.current_clt: + return + # We can have a frame coming from god knows where that's + # passed to a jump to another loop. Make sure it has the + # correct depth + expected_size = target_token._arm_clt.frame_info.jfi_frame_depth + self._check_frame_depth(self.mc, self._regalloc.get_gcmap(), + expected_size=expected_size) + + # ../x86/assembler.py:668 + def redirect_call_assembler(self, oldlooptoken, newlooptoken): + # some minimal sanity checking + old_nbargs = oldlooptoken.compiled_loop_token._debug_nbargs + new_nbargs = newlooptoken.compiled_loop_token._debug_nbargs + assert old_nbargs == new_nbargs + # we overwrite the instructions at the old _ll_function_addr + # to start with a JMP to the new _ll_function_addr. + # Ideally we should rather patch all existing CALLs, but well. + oldadr = oldlooptoken._ll_function_addr + target = newlooptoken._ll_function_addr + # copy frame-info data + baseofs = self.cpu.get_baseofs_of_frame_field() + newlooptoken.compiled_loop_token.update_frame_info( + oldlooptoken.compiled_loop_token, baseofs) + mc = InstrBuilder() + mc.B(target) + mc.copy_to_raw_memory(oldadr) + # + jl.redirect_assembler(oldlooptoken, newlooptoken, newlooptoken.number) + + + +def not_implemented(msg): + msg = '[ARM64/asm] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) + raise NotImplementedError(msg) + + +def notimplemented_op(self, op, arglocs): + print "[ARM64/asm] %s not implemented" % op.getopname() + raise NotImplementedError(op) + +def notimplemented_comp_op(self, op, arglocs): + print "[ARM64/asm] %s not implemented" % op.getopname() + raise NotImplementedError(op) + +def notimplemented_guard_op(self, op, guard_op, fcond, arglocs): + print "[ARM64/asm] %s not implemented" % op.getopname() + raise NotImplementedError(op) + +asm_operations = [notimplemented_op] * (rop._LAST + 1) +asm_guard_operations = [notimplemented_guard_op] * (rop._LAST + 1) +asm_comp_operations = [notimplemented_comp_op] * (rop._LAST + 1) +asm_extra_operations = {} + +for name, value in ResOpAssembler.__dict__.iteritems(): + if name.startswith('emit_opx_'): + opname = name[len('emit_opx_'):] + num = getattr(EffectInfo, 'OS_' + opname.upper()) + asm_extra_operations[num] = value + elif name.startswith('emit_op_'): + opname = name[len('emit_op_'):] + num = getattr(rop, opname.upper()) + asm_operations[num] = value + elif name.startswith('emit_guard_op_'): + opname = name[len('emit_guard_op_'):] + num = getattr(rop, opname.upper()) + asm_guard_operations[num] = value + elif name.startswith('emit_comp_op_'): + opname = name[len('emit_comp_op_'):] + num = getattr(rop, opname.upper()) + asm_comp_operations[num] = value diff --git a/rpython/jit/backend/aarch64/callbuilder.py b/rpython/jit/backend/aarch64/callbuilder.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/aarch64/callbuilder.py @@ -0,0 +1,291 @@ + +from rpython.jit.backend.llsupport.callbuilder import AbstractCallBuilder +from rpython.jit.backend.aarch64.arch import WORD +from rpython.jit.metainterp.history import INT, FLOAT, REF +from rpython.jit.backend.aarch64 import registers as r +from rpython.jit.backend.arm import conditions as c +from rpython.jit.backend.aarch64.jump import remap_frame_layout # we use arm algo +from rpython.jit.backend.llsupport import llerrno +from rpython.jit.backend.aarch64.codebuilder import OverwritingBuilder + +from rpython.rlib.objectmodel import we_are_translated +from rpython.rtyper.lltypesystem import rffi + +class Aarch64CallBuilder(AbstractCallBuilder): + def __init__(self, assembler, fnloc, arglocs, + resloc=r.x0, restype=INT, ressize=WORD, ressigned=True): + AbstractCallBuilder.__init__(self, assembler, fnloc, arglocs, + resloc, restype, ressize) + self.current_sp = 0 + + def prepare_arguments(self): + arglocs = self.arglocs + non_float_locs = [] + non_float_regs = [] + float_locs = [] + float_regs = [] + stack_locs = [] + free_regs = [r.x7, r.x6, r.x5, r.x4, r.x3, r.x2, r.x1, r.x0] + free_float_regs = [r.d7, r.d6, r.d5, r.d4, r.d3, r.d2, r.d1, r.d0] + for arg in arglocs: + if arg.type == FLOAT: + if free_float_regs: + float_locs.append(arg) + float_regs.append(free_float_regs.pop()) + else: + stack_locs.append(arg) + else: + if free_regs: + non_float_locs.append(arg) + non_float_regs.append(free_regs.pop()) + else: + stack_locs.append(arg) + + if stack_locs: + adj = len(stack_locs) + (len(stack_locs) & 1) + self.mc.SUB_ri(r.sp.value, r.sp.value, adj * WORD) + self.current_sp = adj * WORD + c = 0 + for loc in stack_locs: + self.asm.mov_loc_to_raw_stack(loc, c) + c += WORD + + move_back = False + if not self.fnloc.is_imm(): + if self.fnloc.is_core_reg(): + self.mc.MOV_rr(r.ip1.value, self.fnloc.value) + else: + assert self.fnloc.is_stack() + self.mc.LDR_ri(r.ip1.value, r.fp.value, self.fnloc.value) + self.fnloc = r.x8 + move_back = True + + remap_frame_layout(self.asm, non_float_locs, non_float_regs, r.ip0) + if float_locs: + remap_frame_layout(self.asm, float_locs, float_regs, r.d8) + + if move_back: + self.mc.MOV_rr(r.x8.value, r.ip1.value) + + def push_gcmap(self): + noregs = self.asm.cpu.gc_ll_descr.is_shadow_stack() + gcmap = self.asm._regalloc.get_gcmap([r.x0], noregs=noregs) + self.asm.push_gcmap(self.mc, gcmap) + + def pop_gcmap(self): + self.asm._reload_frame_if_necessary(self.mc) + self.asm.pop_gcmap(self.mc) + + def emit_raw_call(self): + #the actual call + if self.fnloc.is_imm(): + self.mc.BL(self.fnloc.value) + return + if self.fnloc.is_stack(): + assert False, "we should never be here" + else: + assert self.fnloc.is_core_reg() + assert self.fnloc is r.x8 + self.mc.BLR_r(self.fnloc.value) + + def restore_stack_pointer(self): + assert self.current_sp & 1 == 0 # always adjusted to 16 bytes + if self.current_sp == 0: + return + self.mc.ADD_ri(r.sp.value, r.sp.value, self.current_sp) + self.current_sp = 0 + + def load_result(self): + resloc = self.resloc + if self.restype == 'S': + assert False, "not supported yet" + XXX + self.mc.VMOV_sc(resloc.value, r.s0.value) + elif self.restype == 'L': + assert False, "not possible on 64bit backend" + YYY + assert resloc.is_vfp_reg() + self.mc.FMDRR(resloc.value, r.r0.value, r.r1.value) + # ensure the result is wellformed and stored in the correct location + if resloc is not None and resloc.is_core_reg(): + self._ensure_result_bit_extension(resloc, + self.ressize, self.ressign) + + def _ensure_result_bit_extension(self, resloc, size, signed): + if size == WORD: + return + if size == 4: + if not signed: # unsigned int + self.mc.LSL_ri(resloc.value, resloc.value, 32) + self.mc.LSR_ri(resloc.value, resloc.value, 32) + else: # signed int + self.mc.LSL_ri(resloc.value, resloc.value, 32) + self.mc.ASR_ri(resloc.value, resloc.value, 32) + elif size == 2: + if not signed: + self.mc.LSL_ri(resloc.value, resloc.value, 48) + self.mc.LSR_ri(resloc.value, resloc.value, 48) + else: + self.mc.LSL_ri(resloc.value, resloc.value, 48) + self.mc.ASR_ri(resloc.value, resloc.value, 48) + elif size == 1: + if not signed: # unsigned char + self.mc.AND_ri(resloc.value, resloc.value, 0xFF) + else: + self.mc.LSL_ri(resloc.value, resloc.value, 56) + self.mc.ASR_ri(resloc.value, resloc.value, 56) + + def call_releasegil_addr_and_move_real_arguments(self, fastgil): + assert self.is_call_release_gil + assert not self.asm._is_asmgcc() + RFASTGILPTR = r.x19 # constant &rpy_fastgil + RSHADOWOLD = r.x20 # old value of the shadowstack pointer, + # which we save here for later comparison + + gcrootmap = self.asm.cpu.gc_ll_descr.gcrootmap + if gcrootmap: + rst = gcrootmap.get_root_stack_top_addr() + self.mc.gen_load_int(r.ip1.value, rst) + self.mc.LDR_ri(RSHADOWOLD.value, r.ip1.value, 0) + + # change 'rpy_fastgil' to 0 (it should be non-zero right now) + self.mc.gen_load_int(RFASTGILPTR.value, fastgil) + self.mc.STLR(r.xzr.value, RFASTGILPTR.value) + + if not we_are_translated(): # for testing: we should not access + self.mc.ADD_ri(r.fp.value, r.fp.value, 1) # fp any more + + def write_real_errno(self, save_err): + if save_err & rffi.RFFI_READSAVED_ERRNO: + # Just before a call, read '*_errno' and write it into the + # real 'errno'. The x0-x7 registers contain arguments to the + # future call; + # the x8-x10 registers contain various stuff. XXX what? + # We still have x11 and up. + if save_err & rffi.RFFI_ALT_ERRNO: + rpy_errno = llerrno.get_alt_errno_offset(self.asm.cpu) + else: + rpy_errno = llerrno.get_rpy_errno_offset(self.asm.cpu) + p_errno = llerrno.get_p_errno_offset(self.asm.cpu) + self.mc.LDR_ri(r.x11.value, r.sp.value, + self.asm.saved_threadlocal_addr + self.current_sp) + self.mc.LDR_ri(r.ip0.value, r.x11.value, p_errno) + self.mc.LDR_ri(r.x11.value, r.x11.value, rpy_errno) + self.mc.STR_ri(r.x11.value, r.ip0.value, 0) + elif save_err & rffi.RFFI_ZERO_ERRNO_BEFORE: + # Same, but write zero. + p_errno = llerrno.get_p_errno_offset(self.asm.cpu) + self.mc.LDR_ri(r.x11.value, r.sp.value, + self.asm.saved_threadlocal_addr + self.current_sp) + self.mc.LDR_ri(r.ip0.value, r.x11.value, p_errno) + self.mc.MOVZ_r_u16(r.x11.value, 0, 0) + self.mc.STR_ri(r.x11.value, r.ip0.value, 0) + + def read_real_errno(self, save_err): + if save_err & rffi.RFFI_SAVE_ERRNO: + # Just after a call, read the real 'errno' and save a copy of + # it inside our thread-local '*_errno'. Registers x11 and up + # are unused here, and registers x2-x3 never contain anything + # after the call. + if save_err & rffi.RFFI_ALT_ERRNO: + rpy_errno = llerrno.get_alt_errno_offset(self.asm.cpu) + else: + rpy_errno = llerrno.get_rpy_errno_offset(self.asm.cpu) + p_errno = llerrno.get_p_errno_offset(self.asm.cpu) + self.mc.LDR_ri(r.x3.value, r.sp.value, + self.asm.saved_threadlocal_addr) + self.mc.LDR_ri(r.ip0.value, r.x3.value, p_errno) + self.mc.LDR_ri(r.ip0.value, r.ip0.value, 0) + self.mc.STR_ri(r.ip0.value, r.x3.value, rpy_errno) + + def move_real_result_and_call_reacqgil_addr(self, fastgil): + # try to reacquire the lock. The following two values are saved + # across the call and are still alive now: + RFASTGILPTR = r.x19 # constant &rpy_fastgil + RSHADOWOLD = r.x20 # old value of the shadowstack pointer + + # this comes from gcc compiling this code: + # while (__atomic_test_and_set(&lock, __ATOMIC_ACQUIRE)) + # ; + self.mc.gen_load_int(r.x2.value, 1) + self.mc.LDXR(r.x1.value, RFASTGILPTR.value) + self.mc.STXR(r.x3.value, r.x2.value, RFASTGILPTR.value) + self.mc.CBNZ_w(r.x3.value, -8) + # now x1 is the old value of the lock, and the lock contains 1 + + b1_location = self.mc.currpos() + self.mc.BRK() # boehm: patched with a CBZ (jump if x1 == 0) + # shadowstack: patched with CBNZ instead + + gcrootmap = self.asm.cpu.gc_ll_descr.gcrootmap + if gcrootmap: + # When doing a call_release_gil with shadowstack, there + # is the risk that the 'rpy_fastgil' was free but the + # current shadowstack can be the one of a different + # thread. So here we check if the shadowstack pointer + # is still the same as before we released the GIL (saved + # in 'x20'), and if not, we fall back to 'reacqgil_addr'. + rst = gcrootmap.get_root_stack_top_addr() + self.mc.gen_load_int(r.ip1.value, rst) + self.mc.LDR_ri(r.ip0.value, r.ip1.value, 0) # new shadowstack + self.mc.CMP_rr(r.ip0.value, RSHADOWOLD.value) + b3_location = self.mc.currpos() + self.mc.BRK() # B.eq forward + + # revert the rpy_fastgil acquired above, so that the + # general 'reacqgil_addr' below can acquire it again... + self.mc.STR_ri(r.xzr.value, RFASTGILPTR.value, 0) + + # patch the b1_location above, with "CBNZ here" + pmc = OverwritingBuilder(self.mc, b1_location, WORD) + pmc.CBNZ(r.x1.value, self.mc.currpos() - b1_location) + + open_location = b3_location + else: + open_location = b1_location + + # Yes, we need to call the reacqgil() function. + # save the result we just got + RSAVEDRES = RFASTGILPTR # can reuse this reg here to save things + reg = self.resloc + if reg is not None: + if reg.is_core_reg(): + self.mc.MOV_rr(RSAVEDRES.value, reg.value) + elif reg.is_vfp_reg(): + self.mc.SUB_ri(r.sp.value, r.sp.value, 2 * WORD) + self.mc.STR_di(reg.value, r.sp.value, 0) + + # call the function + self.mc.BL(self.asm.reacqgil_addr) + + # restore the saved register + if reg is not None: + if reg.is_core_reg(): + self.mc.MOV_rr(reg.value, RSAVEDRES.value) + elif reg.is_vfp_reg(): + self.mc.LDR_di(reg.value, r.sp.value, 0) + self.mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) + + # now patch the still-open jump above: + # boehm: patch b1_location with a CBZ(x1) + # shadowstack: patch b3_location with BEQ + pmc = OverwritingBuilder(self.mc, open_location, WORD) + offset = self.mc.currpos() - open_location + if gcrootmap: + pmc.B_ofs_cond(offset, c.EQ) + else: + pmc.CBZ(r.x1.value, offset) + + if not we_are_translated(): # for testing: now we can accesss + self.mc.SUB_ri(r.fp.value, r.fp.value, 1) # fp again + + def get_result_locs(self): + if self.resloc is None: + return [], [] + if self.resloc.is_vfp_reg(): + if self.restype == 'L': # long long + return [r.r0], [] + else: + return [], [r.d0] + assert self.resloc.is_core_reg() + return [r.r0], [] diff --git a/rpython/jit/backend/aarch64/codebuilder.py b/rpython/jit/backend/aarch64/codebuilder.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/aarch64/codebuilder.py @@ -0,0 +1,591 @@ + +from rpython.rlib.objectmodel import we_are_translated +from rpython.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin +from rpython.jit.backend.aarch64.locations import RegisterLocation +from rpython.jit.backend.aarch64 import registers as r +from rpython.rlib.rarithmetic import intmask +from rpython.rtyper.lltypesystem import lltype, rffi, llmemory +from rpython.tool.udir import udir + +clear_cache = rffi.llexternal( + "__clear_cache", + [llmemory.Address, llmemory.Address], + lltype.Void, + _nowrapper=True, + sandboxsafe=True) + + +class AbstractAarch64Builder(object): + def write32(self, word): + self.writechar(chr(word & 0xFF)) + self.writechar(chr((word >> 8) & 0xFF)) + self.writechar(chr((word >> 16) & 0xFF)) + self.writechar(chr((word >> 24) & 0xFF)) + + def RET_r(self, arg): + self.write32((0b1101011001011111 << 16) | (arg << 5)) + + def STR_ri(self, rt, rn, offset): + base = 0b1111100100 + assert offset & 0x7 == 0 + assert 0 <= offset < 32768 + self.write32((base << 22) | ((offset >> 3) << 10) | + (rn << 5) | rt) + + def STR_di(self, rt, rn, offset): + base = 0b1111110100 + assert offset & 0x7 == 0 + assert 0 <= offset < 32768 + self.write32((base << 22) | ((offset >> 3) << 10) | (rn << 5) | rt) + + def STR_dd(self, rt, rn, rm): + base = 0b11111100001 + self.write32((base << 21) | (rm << 16) | (0b011010 << 10) | (rn << 5) | rt) + + def STP_rr_preindex(self, reg1, reg2, rn, offset): + base = 0b1010100110 + assert -512 <= offset < 512 + assert offset & 0x7 == 0 + self.write32((base << 22) | ((0x7F & (offset >> 3)) << 15) | + (reg2 << 10) | (rn << 5) | reg1) + + def STP_rri(self, reg1, reg2, rn, offset): + base = 0b1010100100 + assert -512 <= offset < 512 + assert offset & 0x7 == 0 + self.write32((base << 22) | ((0x7F & (offset >> 3)) << 15) | + (reg2 << 10) | (rn << 5) | reg1) + + def STR_size_rr(self, scale, rt, rn, rm): + base = 0b111000001 + assert 0 <= scale <= 3 + self.write32((scale << 30) | (base << 21) | (rm << 16) | (0b11 << 13) | + (0b010 << 10) | (rn << 5) | rt) + + def STR_size_ri(self, scale, rt, rn, imm): + assert 0 <= imm < 4096 + assert 0 <= scale <= 3 + base = 0b11100100 + self.write32((scale << 30) | (base << 22) | (imm >> scale << 10) | (rn << 5) | rt) + + def STRB_ri(self, rt, rn, imm): + self.STR_size_ri(0, rt, rn, imm) + + def STRH_ri(self, rt, rn, imm): + self.STR_size_ri(1, rt, rn, imm) + + def STRW_ri(self, rt, rn, imm): + self.STR_size_ri(2, rt, rn, imm) + + def MOV_rr(self, rd, rn): + self.ORR_rr(rd, r.xzr.value, rn) + + def UMOV_rd(self, rd, rn): + base = 0b0100111000001000001111 + self.write32((base << 10) | (rn << 5) | rd) + + def INS_dr(self, rd, rn): + base = 0b0100111000001000000111 + self.write32((base << 10) | (rn << 5) | rd) + + def ORR_rr(self, rd, rn, rm): + base = 0b10101010000 + self.write32((base << 21) | (rm << 16) | + (rn << 5) | rd) + + def MOVK_r_u16(self, rd, immed, shift): + base = 0b111100101 + assert 0 <= immed < 1 << 16 + assert shift in (0, 16, 32, 48) + self.write32((base << 23) | (shift >> 4 << 21) | (immed << 5) | rd) + + def MOVZ_r_u16(self, rd, immed, shift): + base = 0b110100101 + assert 0 <= immed < 1 << 16 + assert shift in (0, 16, 32, 48) + self.write32((base << 23) | (shift >> 4 << 21) | (immed << 5) | rd) + + def MOVN_r_u16(self, rd, immed): + base = 0b10010010100 + assert 0 <= immed < 1 << 16 + self.write32((base << 21) | (immed << 5) | rd) + + def ADD_ri(self, rd, rn, constant, s=0): + base = 0b1001000100 | (s << 7) + assert 0 <= constant < 4096 + self.write32((base << 22) | (constant << 10) | + (rn << 5) | rd) + + def SUB_ri(self, rd, rn, constant, s=0): + base = 0b1101000100 | (s << 7) + assert 0 <= constant < 4096 + self.write32((base << 22) | (constant << 10) | (rn << 5) | rd) + + def LDP_rri(self, reg1, reg2, rn, offset): + base = 0b1010100101 + assert -512 <= offset < 512 + assert offset & 0x7 == 0 + assert reg1 != reg2 + self.write32((base << 22) | ((0x7F & (offset >> 3)) << 15) | + (reg2 << 10) | (rn << 5) | reg1) From pypy.commits at gmail.com Tue Jul 16 07:59:09 2019 From: pypy.commits at gmail.com (mattip) Date: Tue, 16 Jul 2019 04:59:09 -0700 (PDT) Subject: [pypy-commit] pypy default: add conftest to skip on non-aarch64 Message-ID: <5d2dbc0d.1c69fb81.21b90.f5d0@mx.google.com> Author: Matti Picus Branch: Changeset: r97006:3b62053cc1e4 Date: 2019-07-16 06:53 -0500 http://bitbucket.org/pypy/pypy/changeset/3b62053cc1e4/ Log: add conftest to skip on non-aarch64 diff --git a/rpython/jit/backend/aarch64/test/conftest.py b/rpython/jit/backend/aarch64/test/conftest.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/aarch64/test/conftest.py @@ -0,0 +1,13 @@ +""" +This disables the backend tests on non ARMv7 platforms. +Note that you need "--slow" to run translation tests. +""" +import py, os +from rpython.jit.backend import detect_cpu + +cpu = detect_cpu.autodetect() + +def pytest_collect_directory(path, parent): + if not cpu.startswith('aarch64'): + py.test.skip("AARCH64 tests skipped: cpu is %r" % (cpu,)) +pytest_collect_file = pytest_collect_directory From pypy.commits at gmail.com Tue Jul 16 07:59:11 2019 From: pypy.commits at gmail.com (mattip) Date: Tue, 16 Jul 2019 04:59:11 -0700 (PDT) Subject: [pypy-commit] pypy default: fix tabs, whatsnew Message-ID: <5d2dbc0f.1c69fb81.843ee.7a26@mx.google.com> Author: Matti Picus Branch: Changeset: r97007:624e331a6fa0 Date: 2019-07-16 06:57 -0500 http://bitbucket.org/pypy/pypy/changeset/624e331a6fa0/ Log: fix tabs, whatsnew diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -45,3 +45,12 @@ Instead, replace it in ``rewrite.py`` with a direct call to ``memcpy()`` and new basic operation, ``load_effective_address``, which the backend can even decide not to implement. + +.. branch: arm64 +Add a JIT backend for ARM64 (aarch64) + +.. branch: fix-test-vmprof-closed-file + + +.. branch: fix_darwin_list_dir_test + diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py --- a/rpython/jit/backend/aarch64/assembler.py +++ b/rpython/jit/backend/aarch64/assembler.py @@ -980,9 +980,9 @@ def reserve_gcref_table(self, allgcrefs): gcref_table_size = len(allgcrefs) * WORD - # align to a multiple of 16 and reserve space at the beginning - # of the machine code for the gc table. This lets us write - # machine code with relative addressing (LDR literal). + # align to a multiple of 16 and reserve space at the beginning + # of the machine code for the gc table. This lets us write + # machine code with relative addressing (LDR literal). gcref_table_size = (gcref_table_size + 15) & ~15 mc = self.mc assert mc.get_relative_pos() == 0 From pypy.commits at gmail.com Tue Jul 16 10:35:45 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 16 Jul 2019 07:35:45 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Kill this test, duplicated my mistake during an earlier merge Message-ID: <5d2de0c1.1c69fb81.4e1ae.c85d@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r97008:b37a055d1f41 Date: 2019-07-16 16:25 +0200 http://bitbucket.org/pypy/pypy/changeset/b37a055d1f41/ Log: Kill this test, duplicated my mistake during an earlier merge diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -51,71 +51,6 @@ if HAS_HYPOTHESIS: - @given(strategies.text(), strategies.integers(min_value=0, max_value=10), - strategies.integers(min_value=-1, max_value=10)) - def test_hypo_index_find(self, u, start, len1): - if start + len1 < 0: - return # skip this case - v = u[start : start + len1] - space = self.space - w_u = space.newutf8(u.encode('utf8'), len(u)) - w_v = space.newutf8(v.encode('utf8'), len(v)) - expected = u.find(v, start, start + len1) - try: - w_index = space.call_method(w_u, 'index', w_v, - space.newint(start), - space.newint(start + len1)) - except OperationError as e: - if not e.match(space, space.w_ValueError): - raise - assert expected == -1 - else: - assert space.int_w(w_index) == expected >= 0 - - w_index = space.call_method(w_u, 'find', w_v, - space.newint(start), - space.newint(start + len1)) - assert space.int_w(w_index) == expected - rexpected = u.rfind(v, start, start + len1) - try: - w_index = space.call_method(w_u, 'rindex', w_v, - space.newint(start), - space.newint(start + len1)) - except OperationError as e: - if not e.match(space, space.w_ValueError): - raise - assert rexpected == -1 - else: - assert space.int_w(w_index) == rexpected >= 0 - - w_index = space.call_method(w_u, 'rfind', w_v, - space.newint(start), - space.newint(start + len1)) - assert space.int_w(w_index) == rexpected - - expected = u.startswith(v, start) - w_res = space.call_method(w_u, 'startswith', w_v, - space.newint(start)) - assert w_res is space.newbool(expected) - - expected = u.startswith(v, start, start + len1) - w_res = space.call_method(w_u, 'startswith', w_v, - space.newint(start), - space.newint(start + len1)) - assert w_res is space.newbool(expected) - - expected = u.endswith(v, start) - w_res = space.call_method(w_u, 'endswith', w_v, - space.newint(start)) - assert w_res is space.newbool(expected) - - expected = u.endswith(v, start, start + len1) - w_res = space.call_method(w_u, 'endswith', w_v, - space.newint(start), - space.newint(start + len1)) - assert w_res is space.newbool(expected) - - @given(u=strategies.text(), start=strategies.integers(min_value=0, max_value=10), len1=strategies.integers(min_value=-1, max_value=10)) From pypy.commits at gmail.com Tue Jul 16 10:35:47 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 16 Jul 2019 07:35:47 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Remove tests for startswith/endswith from test_hypo_index_find: Message-ID: <5d2de0c3.1c69fb81.3c153.e24e@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r97009:a7ebeb02e68d Date: 2019-07-16 16:34 +0200 http://bitbucket.org/pypy/pypy/changeset/a7ebeb02e68d/ Log: Remove tests for startswith/endswith from test_hypo_index_find: 7b256d2286ec should cover these cases and give the same result as CPython3.6 diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -95,38 +95,6 @@ space.newint(start + len1)) assert space.int_w(w_index) == rexpected - expected = u.startswith(v, start) - if expected and start > len(u): - expected = False # python2 vs. python3 - w_res = space.call_method(w_u, 'startswith', w_v, - space.newint(start)) - assert w_res is space.newbool(expected) - - expected = u.startswith(v, start, start + len1) - if ((expected and start > len(u)) or - (start > 0 and start + len1 ==0)): - expected = False # python2 vs. python3 - w_res = space.call_method(w_u, 'startswith', w_v, - space.newint(start), - space.newint(start + len1)) - assert w_res is space.newbool(expected) - - expected = u.endswith(v, start) - if expected and start > len(u): - expected = False # python2 vs. python3 - w_res = space.call_method(w_u, 'endswith', w_v, - space.newint(start)) - assert w_res is space.newbool(expected) - - expected = u.endswith(v, start, start + len1) - if ((expected and start > len(u)) or - (start > 0 and start + len1 ==0)): - expected = False # python2 vs. python3 - w_res = space.call_method(w_u, 'endswith', w_v, - space.newint(start), - space.newint(start + len1)) - assert w_res is space.newbool(expected) - class AppTestUnicodeStringStdOnly: def test_compares(self): From pypy.commits at gmail.com Fri Jul 19 16:46:22 2019 From: pypy.commits at gmail.com (arigo) Date: Fri, 19 Jul 2019 13:46:22 -0700 (PDT) Subject: [pypy-commit] cffi default: improve comment Message-ID: <5d322c1e.1c69fb81.843ee.a511@mx.google.com> Author: Armin Rigo Branch: Changeset: r3282:158f2ff652b7 Date: 2019-07-19 22:45 +0200 http://bitbucket.org/cffi/cffi/changeset/158f2ff652b7/ Log: improve comment diff --git a/doc/source/whatsnew.rst b/doc/source/whatsnew.rst --- a/doc/source/whatsnew.rst +++ b/doc/source/whatsnew.rst @@ -8,7 +8,7 @@ * ``ffi.from_buffer("type *", ..)`` is now supported, in addition to ``"type[]"``. You can then write ``p.field`` to access the items, instead - of ``p[0].field``. Be careful that no bounds checking is performed, so + of only ``p[0].field``. Be careful that no bounds checking is performed, so ``p[n]`` might access data out of bounds. * fix for structs containing unnamed bitfields like ``int : 1;``. From pypy.commits at gmail.com Fri Jul 19 16:47:54 2019 From: pypy.commits at gmail.com (arigo) Date: Fri, 19 Jul 2019 13:47:54 -0700 (PDT) Subject: [pypy-commit] pypy default: update to cffi/158f2ff652b7 Message-ID: <5d322c7a.1c69fb81.a33dd.abf3@mx.google.com> Author: Armin Rigo Branch: Changeset: r97010:3cb9cee3bc8e Date: 2019-07-19 22:47 +0200 http://bitbucket.org/pypy/pypy/changeset/3cb9cee3bc8e/ Log: update to cffi/158f2ff652b7 diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -145,12 +145,16 @@ return ''.join(parts) def _warn_for_string_literal(csource): - if '"' in csource: - import warnings - warnings.warn("String literal found in cdef() or type source. " - "String literals are ignored here, but you should " - "remove them anyway because some character sequences " - "confuse pre-parsing.") + if '"' not in csource: + return + for line in csource.splitlines(): + if '"' in line and not line.lstrip().startswith('#'): + import warnings + warnings.warn("String literal found in cdef() or type source. " + "String literals are ignored here, but you should " + "remove them anyway because some character sequences " + "confuse pre-parsing.") + break def _preprocess(csource): # Remove comments. NOTE: this only work because the cdef() section From pypy.commits at gmail.com Sat Jul 20 12:26:25 2019 From: pypy.commits at gmail.com (arigo) Date: Sat, 20 Jul 2019 09:26:25 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Merged in coolrr/pypy/Ram-Rachum/faulthandleris_enabled-should-return-fal-1563636614875 (pull request #658) Message-ID: <5d3340b1.1c69fb81.18a4f.b774@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r97013:85e8c3a0df6a Date: 2019-07-20 16:25 +0000 http://bitbucket.org/pypy/pypy/changeset/85e8c3a0df6a/ Log: Merged in coolrr/pypy/Ram-Rachum/faulthandleris_enabled-should- return-fal-1563636614875 (pull request #658) Add more stubs to faulthandler.py, fixed diff --git a/lib_pypy/faulthandler.py b/lib_pypy/faulthandler.py --- a/lib_pypy/faulthandler.py +++ b/lib_pypy/faulthandler.py @@ -5,5 +5,14 @@ def enable(*args, **kwargs): pass +def disable(*args, **kwargs): + pass + +def is_enabled(*args, **kwargs): + return False + def register(*args, **kwargs): pass + +def cancel_dump_traceback_later(*args, **kwargs): + pass From pypy.commits at gmail.com Sat Jul 20 12:26:33 2019 From: pypy.commits at gmail.com (coolrr) Date: Sat, 20 Jul 2019 09:26:33 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Add more stubs to faulthandler.py Message-ID: <5d3340b9.1c69fb81.32ef2.dcc0@mx.google.com> Author: Ram Rachum Branch: py3.6 Changeset: r97011:522da302c3c6 Date: 2019-07-20 11:11 +0300 http://bitbucket.org/pypy/pypy/changeset/522da302c3c6/ Log: Add more stubs to faulthandler.py These are needed to run Pytest on PyPy3 on Windows. diff --git a/lib_pypy/faulthandler.py b/lib_pypy/faulthandler.py --- a/lib_pypy/faulthandler.py +++ b/lib_pypy/faulthandler.py @@ -5,5 +5,14 @@ def enable(*args, **kwargs): pass +def disable(*args, **kwargs): + pass + +def is_enabled(*args, **kwargs): + return True + def register(*args, **kwargs): pass + +def cancel_dump_traceback_later(*args, **kwargs): + pass From pypy.commits at gmail.com Sat Jul 20 12:26:34 2019 From: pypy.commits at gmail.com (coolrr) Date: Sat, 20 Jul 2019 09:26:34 -0700 (PDT) Subject: [pypy-commit] pypy Ram-Rachum/faulthandleris_enabled-should-return-fal-1563636614875: faulthandler.is_enabled should return `False` Message-ID: <5d3340ba.1c69fb81.9b46c.4013@mx.google.com> Author: Ram Rachum Branch: Ram-Rachum/faulthandleris_enabled-should-return-fal-1563636614875 Changeset: r97012:c1a0a4fef77b Date: 2019-07-20 15:31 +0000 http://bitbucket.org/pypy/pypy/changeset/c1a0a4fef77b/ Log: faulthandler.is_enabled should return `False` diff --git a/lib_pypy/faulthandler.py b/lib_pypy/faulthandler.py --- a/lib_pypy/faulthandler.py +++ b/lib_pypy/faulthandler.py @@ -9,7 +9,7 @@ pass def is_enabled(*args, **kwargs): - return True + return False def register(*args, **kwargs): pass From pypy.commits at gmail.com Sat Jul 20 14:55:10 2019 From: pypy.commits at gmail.com (arigo) Date: Sat, 20 Jul 2019 11:55:10 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Update docstring Message-ID: <5d33638e.1c69fb81.4c82b.852f@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r97014:add29730da7d Date: 2019-07-20 20:54 +0200 http://bitbucket.org/pypy/pypy/changeset/add29730da7d/ Log: Update docstring diff --git a/lib_pypy/faulthandler.py b/lib_pypy/faulthandler.py --- a/lib_pypy/faulthandler.py +++ b/lib_pypy/faulthandler.py @@ -1,6 +1,5 @@ -# This is only imported for platforms where the built-in faulthandler module is not -# available. It provides no function at all so far, but it is enough to start the -# CPython test suite. +# This is a dummy module imported for platforms where the built-in +# faulthandler module is not available. def enable(*args, **kwargs): pass From pypy.commits at gmail.com Mon Jul 22 22:07:29 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 22 Jul 2019 19:07:29 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: issue #3041 Message-ID: <5d366be1.1c69fb81.89c00.a200@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r97016:0fcdbc3de300 Date: 2019-07-23 04:06 +0200 http://bitbucket.org/pypy/pypy/changeset/0fcdbc3de300/ Log: issue #3041 Implement PyGILState_Check() diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -986,8 +986,9 @@ gil_release = (gil == "release" or gil == "around") pygilstate_ensure = (gil == "pygilstate_ensure") pygilstate_release = (gil == "pygilstate_release") + pygilstate_check = (gil == "pygilstate_check") assert (gil is None or gil_acquire or gil_release - or pygilstate_ensure or pygilstate_release) + or pygilstate_ensure or pygilstate_release or pygilstate_check) expected_nb_args = len(argtypesw) + pygilstate_ensure if isinstance(restype, lltype.Ptr) and error_value == 0: @@ -1027,6 +1028,9 @@ else: rgil.acquire() args += (pystate.PyGILState_UNLOCKED,) + elif pygilstate_check: + result = cpyext_glob_tid_ptr[0] == tid + return rffi.cast(restype, result) else: if cpyext_glob_tid_ptr[0] != tid: no_gil_error(pname) diff --git a/pypy/module/cpyext/pystate.py b/pypy/module/cpyext/pystate.py --- a/pypy/module/cpyext/pystate.py +++ b/pypy/module/cpyext/pystate.py @@ -252,6 +252,11 @@ space.threadlocals.get_ec = get_possibly_deleted_ec + at cpython_api([], rffi.INT_real, error=CANNOT_FAIL, gil="pygilstate_check") +def PyGILState_Check(space): + assert False, "the logic is completely inside wrapper_second_level" + + @cpython_api([], PyGILState_STATE, error=CANNOT_FAIL, gil="pygilstate_ensure") def PyGILState_Ensure(space, previous_state): # The argument 'previous_state' is not part of the API; it is inserted diff --git a/pypy/module/cpyext/test/test_pystate.py b/pypy/module/cpyext/test/test_pystate.py --- a/pypy/module/cpyext/test/test_pystate.py +++ b/pypy/module/cpyext/test/test_pystate.py @@ -154,6 +154,8 @@ if (tstate == NULL) { return PyLong_FromLong(0); } + if (PyGILState_Check() != 0) + return PyLong_FromLong(-1); dict = PyThreadState_GetDict(); if (dict != NULL) { return PyLong_FromLong(1); @@ -163,12 +165,18 @@ if (dict == NULL) { return PyLong_FromLong(2); } + if (PyGILState_Check() != 1) + return PyLong_FromLong(-2); PyGILState_Release(gilstate); + if (PyGILState_Check() != 0) + return PyLong_FromLong(-3); PyEval_RestoreThread(tstate); if (PyThreadState_Get() != tstate) { return PyLong_FromLong(3); } + if (PyGILState_Check() != 1) + return PyLong_FromLong(-4); return PyLong_FromLong(4); """)]) From pypy.commits at gmail.com Tue Jul 23 00:37:28 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 22 Jul 2019 21:37:28 -0700 (PDT) Subject: [pypy-commit] cffi default: Issue #413 Message-ID: <5d368f08.1c69fb81.4eff3.440c@mx.google.com> Author: Armin Rigo Branch: Changeset: r3283:f34ec7d90cd6 Date: 2019-07-23 06:37 +0200 http://bitbucket.org/cffi/cffi/changeset/f34ec7d90cd6/ Log: Issue #413 Test and "fix" for a corner case: now it gives a RuntimeError with a message, instead of a C-level infinite recursion diff --git a/c/realize_c_type.c b/c/realize_c_type.c --- a/c/realize_c_type.c +++ b/c/realize_c_type.c @@ -413,19 +413,12 @@ } static PyObject * -realize_c_type_or_func(builder_c_t *builder, - _cffi_opcode_t opcodes[], int index) +realize_c_type_or_func_now(builder_c_t *builder, _cffi_opcode_t op, + _cffi_opcode_t opcodes[], int index) { PyObject *x, *y, *z; - _cffi_opcode_t op = opcodes[index]; Py_ssize_t length = -1; - if ((((uintptr_t)op) & 1) == 0) { - x = (PyObject *)op; - Py_INCREF(x); - return x; - } - switch (_CFFI_GETOP(op)) { case _CFFI_OP_PRIMITIVE: @@ -638,11 +631,40 @@ break; } + case 255: /* recursion detection */ + PyErr_Format(PyExc_RuntimeError, + "found a situation in which we try to build a type recursively. " + "This is known to occur e.g. in ``struct s { void(*callable)" + "(struct s); }''. Please report if you get this error and " + "really need support for your case."); + return NULL; + default: PyErr_Format(PyExc_NotImplementedError, "op=%d", (int)_CFFI_GETOP(op)); return NULL; } + return x; +} + +static PyObject * +realize_c_type_or_func(builder_c_t *builder, + _cffi_opcode_t opcodes[], int index) +{ + PyObject *x; + _cffi_opcode_t op = opcodes[index]; + + if ((((uintptr_t)op) & 1) == 0) { + x = (PyObject *)op; + Py_INCREF(x); + return x; + } + + opcodes[index] = (_cffi_opcode_t)255; /* recursion detection */ + x = realize_c_type_or_func_now(builder, op, opcodes, index); + if (opcodes[index] == (_cffi_opcode_t)255) + opcodes[index] = op; + if (x != NULL && opcodes == builder->ctx.types && opcodes[index] != x) { assert((((uintptr_t)x) & 1) == 0); assert((((uintptr_t)opcodes[index]) & 1) == 1); @@ -650,7 +672,7 @@ opcodes[index] = x; } return x; -}; +} static CTypeDescrObject * realize_c_func_return_type(builder_c_t *builder, diff --git a/testing/cffi1/test_recompiler.py b/testing/cffi1/test_recompiler.py --- a/testing/cffi1/test_recompiler.py +++ b/testing/cffi1/test_recompiler.py @@ -2412,3 +2412,15 @@ a = ffi.new("struct A *") assert ffi.sizeof(a[0]) == ffi.sizeof("unsigned") assert ffi.sizeof(b[0]) == ffi.sizeof(a[0]) + +def test_struct_with_func_with_struct_arg(): + ffi = FFI() + ffi.cdef("""struct BinaryTree { + int (* CompareKey)(struct BinaryTree tree); + };""") + lib = verify(ffi, "test_struct_with_func_with_struct_arg", """ + struct BinaryTree { + int (* CompareKey)(struct BinaryTree tree); + }; + """) + py.test.raises(RuntimeError, ffi.new, "struct BinaryTree *") From pypy.commits at gmail.com Tue Jul 23 00:51:10 2019 From: pypy.commits at gmail.com (arigo) Date: Mon, 22 Jul 2019 21:51:10 -0700 (PDT) Subject: [pypy-commit] pypy default: update to cffi/f34ec7d90cd6 Message-ID: <5d36923e.1c69fb81.f6d50.8d33@mx.google.com> Author: Armin Rigo Branch: Changeset: r97017:69d0c4bbdf2f Date: 2019-07-23 06:50 +0200 http://bitbucket.org/pypy/pypy/changeset/69d0c4bbdf2f/ Log: update to cffi/f34ec7d90cd6 diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py b/extra_tests/cffi_tests/cffi1/test_recompiler.py --- a/extra_tests/cffi_tests/cffi1/test_recompiler.py +++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py @@ -2413,3 +2413,15 @@ a = ffi.new("struct A *") assert ffi.sizeof(a[0]) == ffi.sizeof("unsigned") assert ffi.sizeof(b[0]) == ffi.sizeof(a[0]) + +def test_struct_with_func_with_struct_arg(): + ffi = FFI() + ffi.cdef("""struct BinaryTree { + int (* CompareKey)(struct BinaryTree tree); + };""") + lib = verify(ffi, "test_struct_with_func_with_struct_arg", """ + struct BinaryTree { + int (* CompareKey)(struct BinaryTree tree); + }; + """) + py.test.raises(RuntimeError, ffi.new, "struct BinaryTree *") diff --git a/pypy/module/_cffi_backend/realize_c_type.py b/pypy/module/_cffi_backend/realize_c_type.py --- a/pypy/module/_cffi_backend/realize_c_type.py +++ b/pypy/module/_cffi_backend/realize_c_type.py @@ -405,6 +405,20 @@ if from_ffi and ffi.cached_types[index] is not None: return ffi.cached_types[index] + opcodes[index] = rffi.cast(rffi.VOIDP, 255) + try: + x = realize_c_type_or_func_now(ffi, op, opcodes, index) + finally: + if opcodes[index] == rffi.cast(rffi.VOIDP, 255): + opcodes[index] = op + + if from_ffi: + assert ffi.cached_types[index] is None or ffi.cached_types[index] is x + ffi.cached_types[index] = x + + return x + +def realize_c_type_or_func_now(ffi, op, opcodes, index): case = getop(op) if case == cffi_opcode.OP_PRIMITIVE: @@ -446,13 +460,16 @@ 'c_type_index') x = realize_c_type_or_func(ffi, ffi.ctxobj.ctx.c_types, type_index) + elif case == 255: + raise oefmt(ffi.space.w_RuntimeError, + "found a situation in which we try to build a type recursively. " + "This is known to occur e.g. in ``struct s { void(*callable)" + "(struct s); }''. Please report if you get this error and " + "really need support for your case.") + else: raise oefmt(ffi.space.w_NotImplementedError, "op=%d", case) - if from_ffi: - assert ffi.cached_types[index] is None or ffi.cached_types[index] is x - ffi.cached_types[index] = x - return x diff --git a/pypy/module/_cffi_backend/test/test_recompiler.py b/pypy/module/_cffi_backend/test/test_recompiler.py --- a/pypy/module/_cffi_backend/test/test_recompiler.py +++ b/pypy/module/_cffi_backend/test/test_recompiler.py @@ -2140,3 +2140,19 @@ assert seen == [2 * 4, p] ffi.release(p) # no effect assert seen == [2 * 4, p] + + def test_struct_with_func_with_struct_arg(self): + ffi, lib = self.prepare("""struct BinaryTree { + int (* CompareKey)(struct BinaryTree tree); + };""", + "test_struct_with_func_with_struct_arg", """ + struct BinaryTree { + int (* CompareKey)(struct BinaryTree tree); + }; + """) + e = raises(RuntimeError, ffi.new, "struct BinaryTree *") + assert str(e.value) == ( + "found a situation in which we try to build a type recursively. " + "This is known to occur e.g. in ``struct s { void(*callable)" + "(struct s); }''. Please report if you get this error and " + "really need support for your case.") From pypy.commits at gmail.com Wed Jul 24 07:04:13 2019 From: pypy.commits at gmail.com (arigo) Date: Wed, 24 Jul 2019 04:04:13 -0700 (PDT) Subject: [pypy-commit] pypy default: Change the API of rffi.get_nonmovingbuffer(), now renamed to Message-ID: <5d383b2d.1c69fb81.58ab2.9f82@mx.google.com> Author: Armin Rigo Branch: Changeset: r97018:19e211d4c76b Date: 2019-07-24 11:53 +0200 http://bitbucket.org/pypy/pypy/changeset/19e211d4c76b/ Log: Change the API of rffi.get_nonmovingbuffer(), now renamed to rffi.get_nonmovingbuffer_ll(), because it is not safe: it needs to return the real llstr object on which it operated, and this is the object that needs to be passed to free_nonmovingbuffer_ll(). Otherwise, it's possible to come up with rpython code that would, say, convert a char to a string once for get() and once for free(), which defeats pinning. diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -10,6 +10,7 @@ from rpython.rlib.objectmodel import we_are_translated, instantiate from rpython.rlib.objectmodel import keepalive_until_here from rpython.rtyper.lltypesystem import lltype, llmemory, rffi +from rpython.rtyper.annlowlevel import llstr from pypy.interpreter.error import OperationError, oefmt from pypy.module import _cffi_backend @@ -163,9 +164,9 @@ cif_descr = self.cif_descr # 'self' should have been promoted here size = cif_descr.exchange_size mustfree_max_plus_1 = 0 + keepalives = [llstr(None)] * len(args_w) # llstrings buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw') try: - keepalives = [None] * len(args_w) # None or strings for i in range(len(args_w)): data = rffi.ptradd(buffer, cif_descr.exchange_args[i]) w_obj = args_w[i] @@ -191,9 +192,10 @@ if flag == 1: lltype.free(raw_cdata, flavor='raw') elif flag >= 4: - value = keepalives[i] - assert value is not None - rffi.free_nonmovingbuffer(value, raw_cdata, chr(flag)) + llobj = keepalives[i] + assert llobj # not NULL + rffi.free_nonmovingbuffer_ll(raw_cdata, + llobj, chr(flag)) lltype.free(buffer, flavor='raw') keepalive_until_here(args_w) return w_res diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -303,16 +303,8 @@ else: return lltype.nullptr(rffi.CCHARP.TO) - def _prepare_pointer_call_argument(self, w_init, cdata, keepalives, i): + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if self.accept_str and space.isinstance_w(w_init, space.w_bytes): - # special case to optimize strings passed to a "char *" argument - value = space.bytes_w(w_init) - if isinstance(self.ctitem, ctypeprim.W_CTypePrimitiveBool): - self._must_be_string_of_zero_or_one(value) - keepalives[i] = value - return misc.write_string_as_charp(cdata, value) - # if (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): length = space.int_w(space.len(w_init)) @@ -358,14 +350,27 @@ return 1 def convert_argument_from_object(self, cdata, w_ob, keepalives, i): + # writes the pointer to cdata[0], writes the must-free flag in + # the byte just before cdata[0], and returns True if something + # must be done later to free. from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag - result = (not isinstance(w_ob, cdataobj.W_CData) and - self._prepare_pointer_call_argument(w_ob, cdata, - keepalives, i)) + if isinstance(w_ob, cdataobj.W_CData): + result = 0 + else: + space = self.space + if self.accept_str and space.isinstance_w(w_ob, space.w_bytes): + # special case to optimize strings passed to a "char *" argument + value = space.bytes_w(w_ob) + if isinstance(self.ctitem, ctypeprim.W_CTypePrimitiveBool): + self._must_be_string_of_zero_or_one(value) + keepalives[i] = misc.write_string_as_charp(cdata, value) + return True + result = self._prepare_pointer_call_argument(w_ob, cdata) + if result == 0: self.convert_from_object(cdata, w_ob) set_mustfree_flag(cdata, result) - return result + return result == 1 # 0 or 2 => False, nothing to do later def getcfield(self, attr): from pypy.module._cffi_backend.ctypestruct import W_CTypeStructOrUnion 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 @@ -111,11 +111,13 @@ def write_raw_longdouble_data(target, source): rffi.cast(rffi.LONGDOUBLEP, target)[0] = source - at jit.dont_look_inside # lets get_nonmovingbuffer_final_null be inlined + at jit.dont_look_inside # lets get_nonmovingbuffer_ll_final_null be inlined def write_string_as_charp(target, string): - buf, buf_flag = rffi.get_nonmovingbuffer_final_null(string) + from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag + buf, llobj, buf_flag = rffi.get_nonmovingbuffer_ll_final_null(string) + set_mustfree_flag(target, ord(buf_flag)) # 4, 5 or 6 rffi.cast(rffi.CCHARPP, target)[0] = buf - return ord(buf_flag) # 4, 5 or 6 + return llobj # ____________________________________________________________ diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py --- a/pypy/module/_ssl/interp_ssl.py +++ b/pypy/module/_ssl/interp_ssl.py @@ -140,7 +140,7 @@ def __init__(self, ctx, protos): self.protos = protos - self.buf, self.bufflag = rffi.get_nonmovingbuffer(protos) + self.buf, self.llobj, self.bufflag = rffi.get_nonmovingbuffer_ll(protos) NPN_STORAGE.set(rffi.cast(lltype.Unsigned, self.buf), self) # set both server and client callbacks, because the context @@ -151,8 +151,8 @@ ctx, self.selectNPN_cb, self.buf) def __del__(self): - rffi.free_nonmovingbuffer( - self.protos, self.buf, self.bufflag) + rffi.free_nonmovingbuffer_ll( + self.buf, self.llobj, self.bufflag) @staticmethod def advertiseNPN_cb(s, data_ptr, len_ptr, args): @@ -186,7 +186,7 @@ def __init__(self, ctx, protos): self.protos = protos - self.buf, self.bufflag = rffi.get_nonmovingbuffer(protos) + self.buf, self.llobj, self.bufflag = rffi.get_nonmovingbuffer_ll(protos) ALPN_STORAGE.set(rffi.cast(lltype.Unsigned, self.buf), self) with rffi.scoped_str2charp(protos) as protos_buf: @@ -197,8 +197,8 @@ ctx, self.selectALPN_cb, self.buf) def __del__(self): - rffi.free_nonmovingbuffer( - self.protos, self.buf, self.bufflag) + rffi.free_nonmovingbuffer_ll( + self.buf, self.llobj, self.bufflag) @staticmethod def selectALPN_cb(s, out_ptr, outlen_ptr, client, client_len, args): diff --git a/rpython/rlib/rdtoa.py b/rpython/rlib/rdtoa.py --- a/rpython/rlib/rdtoa.py +++ b/rpython/rlib/rdtoa.py @@ -60,14 +60,14 @@ try: # note: don't use the class scoped_view_charp here, it # break some tests because this function is used by the GC - ll_input, flag = rffi.get_nonmovingbuffer_final_null(input) + ll_input, llobj, flag = rffi.get_nonmovingbuffer_ll_final_null(input) try: result = dg_strtod(ll_input, end_ptr) endpos = (rffi.cast(lltype.Signed, end_ptr[0]) - rffi.cast(lltype.Signed, ll_input)) finally: - rffi.free_nonmovingbuffer(input, ll_input, flag) + rffi.free_nonmovingbuffer_ll(ll_input, llobj, flag) finally: lltype.free(end_ptr, flavor='raw') diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -7,7 +7,7 @@ from rpython.rtyper.lltypesystem.llmemory import itemoffsetof from rpython.rtyper.llannotation import lltype_to_annotation from rpython.tool.sourcetools import func_with_new_name -from rpython.rlib.objectmodel import Symbolic, specialize +from rpython.rlib.objectmodel import Symbolic, specialize, not_rpython from rpython.rlib.objectmodel import keepalive_until_here, enforceargs from rpython.rlib import rarithmetic, rgc from rpython.rtyper.extregistry import ExtRegistryEntry @@ -269,10 +269,11 @@ arg = args[i] if TARGET == CCHARP or TARGET is VOIDP: if arg is None: + from rpython.rtyper.annlowlevel import llstr arg = lltype.nullptr(CCHARP.TO) # None => (char*)NULL - to_free = to_free + (arg, '\x04') + to_free = to_free + (arg, llstr(None), '\x04') elif isinstance(arg, str): - tup = get_nonmovingbuffer_final_null(arg) + tup = get_nonmovingbuffer_ll_final_null(arg) to_free = to_free + tup arg = tup[0] elif isinstance(arg, unicode): @@ -306,10 +307,10 @@ arg = args[i] if TARGET == CCHARP or TARGET is VOIDP: if arg is None: - to_free = to_free[2:] + to_free = to_free[3:] elif isinstance(arg, str): - free_nonmovingbuffer(arg, to_free[0], to_free[1]) - to_free = to_free[2:] + free_nonmovingbuffer_ll(to_free[0], to_free[1], to_free[2]) + to_free = to_free[3:] elif TARGET == CWCHARP: if arg is None: to_free = to_free[1:] @@ -835,84 +836,85 @@ return assert_str0(charpsize2str(cp, size)) charp2str._annenforceargs_ = [lltype.SomePtr(TYPEP)] - # str -> char*, flag + # str -> (buf, llobj, flag) # Can't inline this because of the raw address manipulation. @jit.dont_look_inside - def get_nonmovingbuffer(data): + def get_nonmovingbuffer_ll(data): """ Either returns a non-moving copy or performs neccessary pointer arithmetic to return a pointer to the characters of a string if the string is already nonmovable or could be pinned. Must be followed by a - free_nonmovingbuffer call. + free_nonmovingbuffer_ll call. - Also returns a char: - * \4: no pinning, returned pointer is inside 'data' which is nonmovable - * \5: 'data' was pinned, returned pointer is inside + The return type is a 3-tuple containing the "char *" result, + a pointer to the low-level string object, and a flag as a char: + + * \4: no pinning, returned pointer is inside nonmovable 'llobj' + * \5: 'llobj' was pinned, returned pointer is inside * \6: pinning failed, returned pointer is raw malloced For strings (not unicodes), the len()th character of the resulting raw buffer is available, but not initialized. Use - get_nonmovingbuffer_final_null() instead of get_nonmovingbuffer() + get_nonmovingbuffer_ll_final_null() instead of get_nonmovingbuffer_ll() to get a regular null-terminated "char *". """ - lldata = llstrtype(data) + llobj = llstrtype(data) count = len(data) if rgc.must_split_gc_address_space(): flag = '\x06' # always make a copy in this case - elif we_are_translated_to_c() and not rgc.can_move(data): + elif we_are_translated_to_c() and not rgc.can_move(llobj): flag = '\x04' # no copy needed else: - if we_are_translated_to_c() and rgc.pin(data): + if we_are_translated_to_c() and rgc.pin(llobj): flag = '\x05' # successfully pinned else: flag = '\x06' # must still make a copy if flag == '\x06': buf = lltype.malloc(TYPEP.TO, count + (TYPEP is CCHARP), flavor='raw') - copy_string_to_raw(lldata, buf, 0, count) - return buf, '\x06' + copy_string_to_raw(llobj, buf, 0, count) + return buf, llobj, '\x06' # ^^^ raw malloc used to get a nonmovable copy # # following code is executed after we're translated to C, if: # - rgc.can_move(data) and rgc.pin(data) both returned true # - rgc.can_move(data) returned false - data_start = cast_ptr_to_adr(lldata) + \ + data_start = cast_ptr_to_adr(llobj) + \ offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0) - return cast(TYPEP, data_start), flag + return cast(TYPEP, data_start), llobj, flag # ^^^ already nonmovable. Therefore it's not raw allocated nor # pinned. - get_nonmovingbuffer._always_inline_ = 'try' # get rid of the returned tuple - get_nonmovingbuffer._annenforceargs_ = [strtype] + get_nonmovingbuffer_ll._always_inline_ = 'try' # get rid of the returned tuple + get_nonmovingbuffer_ll._annenforceargs_ = [strtype] @jit.dont_look_inside - def get_nonmovingbuffer_final_null(data): - tup = get_nonmovingbuffer(data) - buf, flag = tup + def get_nonmovingbuffer_ll_final_null(data): + tup = get_nonmovingbuffer_ll(data) + buf = tup[0] buf[len(data)] = lastchar return tup - get_nonmovingbuffer_final_null._always_inline_ = 'try' - get_nonmovingbuffer_final_null._annenforceargs_ = [strtype] + get_nonmovingbuffer_ll_final_null._always_inline_ = 'try' + get_nonmovingbuffer_ll_final_null._annenforceargs_ = [strtype] - # (str, char*, char) -> None + # args-from-tuple-returned-by-get_nonmoving_buffer() -> None # Can't inline this because of the raw address manipulation. @jit.dont_look_inside - def free_nonmovingbuffer(data, buf, flag): + def free_nonmovingbuffer_ll(buf, llobj, flag): """ - Keep 'data' alive and unpin it if it was pinned (flag==\5). + Keep 'llobj' alive and unpin it if it was pinned (flag==\5). Otherwise free the non-moving copy (flag==\6). """ if flag == '\x05': - rgc.unpin(data) + rgc.unpin(llobj) if flag == '\x06': lltype.free(buf, flavor='raw') # if flag == '\x04': data was already nonmovable, # we have nothing to clean up - keepalive_until_here(data) - free_nonmovingbuffer._annenforceargs_ = [strtype, None, None] + keepalive_until_here(llobj) # int -> (char*, str, int) # Can't inline this because of the raw address manipulation. @@ -1002,24 +1004,41 @@ charpsize2str._annenforceargs_ = [None, int] return (str2charp, free_charp, charp2str, - get_nonmovingbuffer, free_nonmovingbuffer, - get_nonmovingbuffer_final_null, + get_nonmovingbuffer_ll, free_nonmovingbuffer_ll, + get_nonmovingbuffer_ll_final_null, alloc_buffer, str_from_buffer, keep_buffer_alive_until_here, charp2strn, charpsize2str, str2chararray, str2rawmem, ) (str2charp, free_charp, charp2str, - get_nonmovingbuffer, free_nonmovingbuffer, get_nonmovingbuffer_final_null, + get_nonmovingbuffer_ll, free_nonmovingbuffer_ll, + get_nonmovingbuffer_ll_final_null, alloc_buffer, str_from_buffer, keep_buffer_alive_until_here, charp2strn, charpsize2str, str2chararray, str2rawmem, ) = make_string_mappings(str) (unicode2wcharp, free_wcharp, wcharp2unicode, - get_nonmoving_unicodebuffer, free_nonmoving_unicodebuffer, __not_usable, + get_nonmoving_unicodebuffer_ll, free_nonmoving_unicodebuffer_ll, __not_usable, alloc_unicodebuffer, unicode_from_buffer, keep_unicodebuffer_alive_until_here, wcharp2unicoden, wcharpsize2unicode, unicode2wchararray, unicode2rawmem, ) = make_string_mappings(unicode) + + at not_rpython +def _deprecated_get_nonmovingbuffer(*args): + raise Exception( +"""The function rffi.get_nonmovingbuffer() has been removed because +it was unsafe. Use rffi.get_nonmovingbuffer_ll() instead. It returns +a 3-tuple instead of a 2-tuple, and all three arguments must be passed +to rffi.free_nonmovingbuffer_ll() (instead of the original string and the +two tuple items). Or else, use a high-level API like +'with rffi.scoped_nonmovingbuffer()'.""") + +get_nonmovingbuffer = _deprecated_get_nonmovingbuffer +get_nonmovingbuffer_final_null = _deprecated_get_nonmovingbuffer +free_nonmovingbuffer = _deprecated_get_nonmovingbuffer + + def wcharpsize2utf8(w, size): """ Helper to convert WCHARP pointer to utf8 in one go. Equivalent to wcharpsize2unicode().encode("utf8") @@ -1315,14 +1334,13 @@ class scoped_nonmovingbuffer: def __init__(self, data): - self.data = data + self.buf, self.llobj, self.flag = get_nonmovingbuffer_ll(data) __init__._annenforceargs_ = [None, annmodel.SomeString(can_be_None=False)] def __enter__(self): - self.buf, self.flag = get_nonmovingbuffer(self.data) return self.buf def __exit__(self, *args): - free_nonmovingbuffer(self.data, self.buf, self.flag) + free_nonmovingbuffer_ll(self.buf, self.llobj, self.flag) __init__._always_inline_ = 'try' __enter__._always_inline_ = 'try' __exit__._always_inline_ = 'try' @@ -1334,13 +1352,13 @@ content of the 'char[]' array will not be modified. """ def __init__(self, data): - self.data = data + self.buf, self.llobj, self.flag = get_nonmovingbuffer_ll_final_null( + data) __init__._annenforceargs_ = [None, annmodel.SomeString(can_be_None=False)] def __enter__(self): - self.buf, self.flag = get_nonmovingbuffer_final_null(self.data) return self.buf def __exit__(self, *args): - free_nonmovingbuffer(self.data, self.buf, self.flag) + free_nonmovingbuffer_ll(self.buf, self.llobj, self.flag) __init__._always_inline_ = 'try' __enter__._always_inline_ = 'try' __exit__._always_inline_ = 'try' diff --git a/rpython/rtyper/lltypesystem/test/test_rffi.py b/rpython/rtyper/lltypesystem/test/test_rffi.py --- a/rpython/rtyper/lltypesystem/test/test_rffi.py +++ b/rpython/rtyper/lltypesystem/test/test_rffi.py @@ -535,7 +535,7 @@ def test_nonmovingbuffer(self): d = 'some cool data that should not move' def f(): - buf, flag = get_nonmovingbuffer(d) + buf, llobj, flag = get_nonmovingbuffer_ll(d) try: counter = 0 for i in range(len(d)): @@ -543,7 +543,7 @@ counter += 1 return counter finally: - free_nonmovingbuffer(d, buf, flag) + free_nonmovingbuffer_ll(buf, llobj, flag) assert f() == len(d) fn = self.compile(f, [], gcpolicy='ref') assert fn() == len(d) @@ -553,13 +553,13 @@ def f(): counter = 0 for n in range(32): - buf, flag = get_nonmovingbuffer(d) + buf, llobj, flag = get_nonmovingbuffer_ll(d) try: for i in range(len(d)): if buf[i] == d[i]: counter += 1 finally: - free_nonmovingbuffer(d, buf, flag) + free_nonmovingbuffer_ll(buf, llobj, flag) return counter fn = self.compile(f, [], gcpolicy='semispace') # The semispace gc uses raw_malloc for its internal data structs @@ -574,13 +574,13 @@ def f(): counter = 0 for n in range(32): - buf, flag = get_nonmovingbuffer(d) + buf, llobj, flag = get_nonmovingbuffer_ll(d) try: for i in range(len(d)): if buf[i] == d[i]: counter += 1 finally: - free_nonmovingbuffer(d, buf, flag) + free_nonmovingbuffer_ll(buf, llobj, flag) return counter fn = self.compile(f, [], gcpolicy='incminimark') # The incminimark gc uses raw_malloc for its internal data structs From pypy.commits at gmail.com Wed Jul 24 07:04:15 2019 From: pypy.commits at gmail.com (arigo) Date: Wed, 24 Jul 2019 04:04:15 -0700 (PDT) Subject: [pypy-commit] pypy default: Broken line, get_L2cache_linux2_cpuinfo_s390x() was never called. Comment it Message-ID: <5d383b2f.1c69fb81.90047.4841@mx.google.com> Author: Armin Rigo Branch: Changeset: r97019:3576fb517a7b Date: 2019-07-24 13:03 +0200 http://bitbucket.org/pypy/pypy/changeset/3576fb517a7b/ Log: Broken line, get_L2cache_linux2_cpuinfo_s390x() was never called. Comment it out entirely instead of fixing the call because it is unknown at this point if get_L2cache_linux2_cpuinfo_s390x() actually works on s390x. diff --git a/rpython/memory/gc/env.py b/rpython/memory/gc/env.py --- a/rpython/memory/gc/env.py +++ b/rpython/memory/gc/env.py @@ -137,8 +137,8 @@ return get_L2cache_linux2_cpuinfo() if arch in ('alpha', 'ppc'): return get_L2cache_linux2_cpuinfo(label='L2 cache') - if arch in ('s390x'): - return get_L2cache_linux2_cpuinfo_s390x() + #if arch == 's390x': untested + # return get_L2cache_linux2_cpuinfo_s390x() if arch == 'ia64': return get_L2cache_linux2_ia64() if arch in ('parisc', 'parisc64'): From pypy.commits at gmail.com Wed Jul 24 07:54:23 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 24 Jul 2019 04:54:23 -0700 (PDT) Subject: [pypy-commit] extradoc extradoc: add a draft Message-ID: <5d3846ef.1c69fb81.cc30a.6d0f@mx.google.com> Author: fijal Branch: extradoc Changeset: r5951:0dd699c2378b Date: 2019-07-24 13:54 +0200 http://bitbucket.org/pypy/extradoc/changeset/0dd699c2378b/ Log: add a draft diff --git a/blog/draft/2019-07-arm64.rst b/blog/draft/2019-07-arm64.rst new file mode 100644 --- /dev/null +++ b/blog/draft/2019-07-arm64.rst @@ -0,0 +1,136 @@ +Hello everyone + +We are pleased to announce that we have successfully ported PyPy +to Aarch64 (also known as a 64bit ARM) platform, thanks to funding +provided by ARM Holdings Ltd. and Crossbar.io. + +We are presenting here the benchmark run done on a Graviton A1 machine +from AWS. There is a very serious word of warning: Graviton A1 are +virtual machines and as such, are not suitable for benchmarking. If someone +has access to a beefy enough (16G) ARM64 server and is willing to give +us access to it, we are happy to redo the benchmarks on a real machine. +My main concern here is that while a vCPU is 1-1 with a real CPU, it's not +clear to me how caches are shared and how they cross CPU boundaries. + +We are not interested in comparing machines, so what we are showing is +a relative speedup to CPython (2.7.15), compared to PyPy (hg id 2417f925ce94). + +In the last column is a comparison - how much do we speedup on arm64, vs +how much do we speed up on x86_64. One important thing to note is that +by no means this is a representative enough benchmark set that we can average +anything. Read numbers per-benchmark. + ++------------------------------+----------+----------+----------+ +|*Benchmark name* |x86_64 |Aarch64 |relative | ++------------------------------+----------+----------+----------+ +|ai |5.66 |5.34 |0.94 | ++------------------------------+----------+----------+----------+ +|bm_chameleon |2.85 |6.57 |2.30 | ++------------------------------+----------+----------+----------+ +|bm_dulwich_log |1.98 |1.34 |0.68 | ++------------------------------+----------+----------+----------+ +|bm_krakatau |1.20 |0.69 |0.58 | ++------------------------------+----------+----------+----------+ +|bm_mako |4.88 |6.38 |1.31 | ++------------------------------+----------+----------+----------+ +|bm_mdp |0.82 |0.74 |0.90 | ++------------------------------+----------+----------+----------+ +|chaos |25.40 |25.52 |1.00 | ++------------------------------+----------+----------+----------+ +|crypto_pyaes |32.35 |31.92 |0.99 | ++------------------------------+----------+----------+----------+ +|deltablue |1.60 |1.48 |0.93 | ++------------------------------+----------+----------+----------+ +|django |14.15 |13.71 |0.97 | ++------------------------------+----------+----------+----------+ +|eparse |1.43 |1.12 |0.78 | ++------------------------------+----------+----------+----------+ +|fannkuch |4.83 |6.53 |1.35 | ++------------------------------+----------+----------+----------+ +|float |8.43 |8.16 |0.97 | ++------------------------------+----------+----------+----------+ +|genshi_text |3.70 |3.61 |0.98 | ++------------------------------+----------+----------+----------+ +|genshi_xml |2.97 |1.64 |0.55 | ++------------------------------+----------+----------+----------+ +|go |2.77 |2.47 |0.89 | ++------------------------------+----------+----------+----------+ +|hexiom2 |9.35 |8.03 |0.86 | ++------------------------------+----------+----------+----------+ +|html5lib |2.88 |1.93 |0.67 | ++------------------------------+----------+----------+----------+ +|json_bench |2.85 |2.81 |0.99 | ++------------------------------+----------+----------+----------+ +|meteor-contest |2.21 |2.27 |1.03 | ++------------------------------+----------+----------+----------+ +|nbody_modified |9.86 |8.59 |0.87 | ++------------------------------+----------+----------+----------+ +|nqueens |1.12 |1.02 |0.91 | ++------------------------------+----------+----------+----------+ +|pidigits |0.99 |0.62 |0.63 | ++------------------------------+----------+----------+----------+ +|pyflate-fast |3.86 |4.62 |1.20 | ++------------------------------+----------+----------+----------+ +|pypy_interp |2.12 |2.03 |0.95 | ++------------------------------+----------+----------+----------+ +|pyxl_bench |1.72 |1.37 |0.80 | ++------------------------------+----------+----------+----------+ +|raytrace-simple |58.86 |44.21 |0.75 | ++------------------------------+----------+----------+----------+ +|richards |52.68 |44.90 |0.85 | ++------------------------------+----------+----------+----------+ +|rietveld |1.52 |1.28 |0.84 | ++------------------------------+----------+----------+----------+ +|spambayes |1.87 |1.58 |0.85 | ++------------------------------+----------+----------+----------+ +|spectral-norm |21.38 |20.28 |0.95 | ++------------------------------+----------+----------+----------+ +|spitfire |1.28 |2.77 |2.17 | ++------------------------------+----------+----------+----------+ +|spitfire_cstringio |7.84 |7.42 |0.95 | ++------------------------------+----------+----------+----------+ +|sqlalchemy_declarative |1.76 |1.05 |0.60 | ++------------------------------+----------+----------+----------+ +|sqlalchemy_imperative |0.63 |0.60 |0.95 | ++------------------------------+----------+----------+----------+ +|sqlitesynth |1.17 |1.00 |0.86 | ++------------------------------+----------+----------+----------+ +|sympy_expand |1.32 |1.25 |0.95 | ++------------------------------+----------+----------+----------+ +|sympy_integrate |1.10 |1.01 |0.91 | ++------------------------------+----------+----------+----------+ +|sympy_str |0.65 |0.62 |0.95 | ++------------------------------+----------+----------+----------+ +|sympy_sum |1.87 |1.79 |0.96 | ++------------------------------+----------+----------+----------+ +|telco |30.38 |19.09 |0.63 | ++------------------------------+----------+----------+----------+ +|twisted_iteration |13.24 |8.95 |0.68 | ++------------------------------+----------+----------+----------+ +|twisted_names |5.27 |3.31 |0.63 | ++------------------------------+----------+----------+----------+ +|twisted_pb |5.85 |2.90 |0.50 | ++------------------------------+----------+----------+----------+ +|twisted_tcp |3.03 |2.08 |0.68 | ++------------------------------+----------+----------+----------+ + +Note that we see a wide variance. There are generally three groups of +benchmarks - those that run at more or less the same speed, those that +run at 2x the speedup and those that run at 0.5x the speedup of x86_64. + +This can be related to a variety of issues, mostly related to differences +in architecture. What *is* however interesting is that compared to older +ARM boards, the branch predictor got a lot better, which means the speedups +will be smaller, since "sophisticated" branchy code, like source code of +CPython just runs a lot faster. + +One takeaway here is that there is a lot of improvement to be done in PyPy. +This is true for both of the above platforms, but probably more so for Aarch64 +which comes with really a lot of registers. PyPy backend has been written with +x86 (the 32bit variant) in mind, which is very register poor. We think we can +improve somewhat in the area of emitting more modern code and it will probably +make somewhat more difference on Aarch64 than on x86_64, where running old +crappy code efficiently has been a massive focus. + +Best, +Maciej Fijalkowski, Armin Rigo and the PyPy team From pypy.commits at gmail.com Wed Jul 24 08:15:30 2019 From: pypy.commits at gmail.com (arigo) Date: Wed, 24 Jul 2019 05:15:30 -0700 (PDT) Subject: [pypy-commit] extradoc extradoc: Tweaks Message-ID: <5d384be2.1c69fb81.f5922.e15b@mx.google.com> Author: Armin Rigo Branch: extradoc Changeset: r5952:95f7083ab191 Date: 2019-07-24 14:15 +0200 http://bitbucket.org/pypy/extradoc/changeset/95f7083ab191/ Log: Tweaks diff --git a/blog/draft/2019-07-arm64.rst b/blog/draft/2019-07-arm64.rst --- a/blog/draft/2019-07-arm64.rst +++ b/blog/draft/2019-07-arm64.rst @@ -14,6 +14,9 @@ We are not interested in comparing machines, so what we are showing is a relative speedup to CPython (2.7.15), compared to PyPy (hg id 2417f925ce94). +This is the "Aarch64" column. In the "x86_64" column we do the same on +a Linux laptop running x86_64, comparing CPython 2.7.16 with the most +recent release, PyPy 7.1.1. In the last column is a comparison - how much do we speedup on arm64, vs how much do we speed up on x86_64. One important thing to note is that @@ -121,16 +124,17 @@ This can be related to a variety of issues, mostly related to differences in architecture. What *is* however interesting is that compared to older ARM boards, the branch predictor got a lot better, which means the speedups -will be smaller, since "sophisticated" branchy code, like source code of -CPython just runs a lot faster. +will be smaller: "sophisticated" branchy code like CPython itself +just runs a lot faster. One takeaway here is that there is a lot of improvement to be done in PyPy. This is true for both of the above platforms, but probably more so for Aarch64 -which comes with really a lot of registers. PyPy backend has been written with +which comes with really a lot of registers. The PyPy backend has been written with x86 (the 32bit variant) in mind, which is very register poor. We think we can improve somewhat in the area of emitting more modern code and it will probably -make somewhat more difference on Aarch64 than on x86_64, where running old -crappy code efficiently has been a massive focus. +make somewhat more difference on Aarch64 than on x86_64. (There are also still +a few missing features in the Aarch64 backend, which are implemented as calls +instead of inlined instructions.) Best, Maciej Fijalkowski, Armin Rigo and the PyPy team From pypy.commits at gmail.com Wed Jul 24 08:28:28 2019 From: pypy.commits at gmail.com (Julian Berman) Date: Wed, 24 Jul 2019 05:28:28 -0700 (PDT) Subject: [pypy-commit] extradoc extradoc: Copy-edit. Message-ID: <5d384eec.1c69fb81.f6221.23ff@mx.google.com> Author: Julian Berman Branch: extradoc Changeset: r5953:e49a4b5cc87d Date: 2019-07-24 08:27 -0400 http://bitbucket.org/pypy/extradoc/changeset/e49a4b5cc87d/ Log: Copy-edit. diff --git a/blog/draft/2019-07-arm64.rst b/blog/draft/2019-07-arm64.rst --- a/blog/draft/2019-07-arm64.rst +++ b/blog/draft/2019-07-arm64.rst @@ -1,27 +1,28 @@ -Hello everyone +Hello everyone. We are pleased to announce that we have successfully ported PyPy -to Aarch64 (also known as a 64bit ARM) platform, thanks to funding +to the AArch64 platform (also known as 64-bit ARM), thanks to funding provided by ARM Holdings Ltd. and Crossbar.io. We are presenting here the benchmark run done on a Graviton A1 machine -from AWS. There is a very serious word of warning: Graviton A1 are +from AWS. There is a very serious word of warning: Graviton A1's are virtual machines and as such, are not suitable for benchmarking. If someone has access to a beefy enough (16G) ARM64 server and is willing to give us access to it, we are happy to redo the benchmarks on a real machine. -My main concern here is that while a vCPU is 1-1 with a real CPU, it's not -clear to me how caches are shared and how they cross CPU boundaries. +Our main concern here is that while a vCPU is 1-to-1 with a real CPU, it's +not clear to us how caches are shared, and how they cross CPU boundaries. -We are not interested in comparing machines, so what we are showing is -a relative speedup to CPython (2.7.15), compared to PyPy (hg id 2417f925ce94). -This is the "Aarch64" column. In the "x86_64" column we do the same on -a Linux laptop running x86_64, comparing CPython 2.7.16 with the most -recent release, PyPy 7.1.1. +We are not here interested in comparing machines, so what we are showing is +the relative speedup of PyPy (hg id 2417f925ce94) compared to CPython +(2.7.15). This is the "AArch64" column. In the "x86_64" column we do the +same on a Linux laptop running x86_64, comparing CPython 2.7.16 with the +most recent release, PyPy 7.1.1. -In the last column is a comparison - how much do we speedup on arm64, vs -how much do we speed up on x86_64. One important thing to note is that -by no means this is a representative enough benchmark set that we can average -anything. Read numbers per-benchmark. +In the last column is a relative comparison between the ARM +architectures: how much the speedup is on arm64 vs. the same benchmark +on x86_64. One important thing to note is that by no means is this +suite a representative enough benchmark set for us to average together +results. Read the numbers individually per-benchmark. +------------------------------+----------+----------+----------+ |*Benchmark name* |x86_64 |Aarch64 |relative | @@ -117,24 +118,25 @@ |twisted_tcp |3.03 |2.08 |0.68 | +------------------------------+----------+----------+----------+ -Note that we see a wide variance. There are generally three groups of +Note also that we see a wide variance. There are generally three groups of benchmarks - those that run at more or less the same speed, those that run at 2x the speedup and those that run at 0.5x the speedup of x86_64. -This can be related to a variety of issues, mostly related to differences -in architecture. What *is* however interesting is that compared to older -ARM boards, the branch predictor got a lot better, which means the speedups -will be smaller: "sophisticated" branchy code like CPython itself -just runs a lot faster. +The variance and disparity are likely related to a variety of issues, +mostly due to differences in architecture. What *is* however +interesting is that compared to older ARM boards, the branch predictor +has gotten a lot better, which means the speedups will be smaller: +"sophisticated" branchy code like CPython itself just runs a lot faster. -One takeaway here is that there is a lot of improvement to be done in PyPy. -This is true for both of the above platforms, but probably more so for Aarch64 -which comes with really a lot of registers. The PyPy backend has been written with -x86 (the 32bit variant) in mind, which is very register poor. We think we can -improve somewhat in the area of emitting more modern code and it will probably -make somewhat more difference on Aarch64 than on x86_64. (There are also still -a few missing features in the Aarch64 backend, which are implemented as calls -instead of inlined instructions.) +One takeaway here is that there is a lot of improvement left to be done +in PyPy. This is true for both of the above platforms, but probably more +so for AArch64, which comes with a large number of registers. The PyPy +backend was written with x86 (the 32-bit variant) in mind, which is very +register poor. We think we can improve somewhat in the area of emitting +more modern machine code, which should be more impactful for AArch64 +than x86_64. There are also still a few missing features in the AArch64 +backend, which are implemented as calls instead of inlined instructions, +which we hope to improve. Best, Maciej Fijalkowski, Armin Rigo and the PyPy team From pypy.commits at gmail.com Wed Jul 24 10:16:35 2019 From: pypy.commits at gmail.com (rlamy) Date: Wed, 24 Jul 2019 07:16:35 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: hg merge default Message-ID: <5d386843.1c69fb81.57d7e.1485@mx.google.com> Author: Ronan Lamy Branch: py3.6 Changeset: r97020:7560947dd35d Date: 2019-07-24 15:15 +0100 http://bitbucket.org/pypy/pypy/changeset/7560947dd35d/ Log: hg merge default diff too long, truncating to 2000 out of 7363 lines diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py b/extra_tests/cffi_tests/cffi1/test_recompiler.py --- a/extra_tests/cffi_tests/cffi1/test_recompiler.py +++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py @@ -2413,3 +2413,15 @@ a = ffi.new("struct A *") assert ffi.sizeof(a[0]) == ffi.sizeof("unsigned") assert ffi.sizeof(b[0]) == ffi.sizeof(a[0]) + +def test_struct_with_func_with_struct_arg(): + ffi = FFI() + ffi.cdef("""struct BinaryTree { + int (* CompareKey)(struct BinaryTree tree); + };""") + lib = verify(ffi, "test_struct_with_func_with_struct_arg", """ + struct BinaryTree { + int (* CompareKey)(struct BinaryTree tree); + }; + """) + py.test.raises(RuntimeError, ffi.new, "struct BinaryTree *") diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -145,12 +145,16 @@ return ''.join(parts) def _warn_for_string_literal(csource): - if '"' in csource: - import warnings - warnings.warn("String literal found in cdef() or type source. " - "String literals are ignored here, but you should " - "remove them anyway because some character sequences " - "confuse pre-parsing.") + if '"' not in csource: + return + for line in csource.splitlines(): + if '"' in line and not line.lstrip().startswith('#'): + import warnings + warnings.warn("String literal found in cdef() or type source. " + "String literals are ignored here, but you should " + "remove them anyway because some character sequences " + "confuse pre-parsing.") + break def _preprocess(csource): # Remove comments. NOTE: this only work because the cdef() section diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -49,3 +49,12 @@ Instead, replace it in ``rewrite.py`` with a direct call to ``memcpy()`` and new basic operation, ``load_effective_address``, which the backend can even decide not to implement. + +.. branch: arm64 +Add a JIT backend for ARM64 (aarch64) + +.. branch: fix-test-vmprof-closed-file + + +.. branch: fix_darwin_list_dir_test + diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py --- a/pypy/module/_cffi_backend/ctypefunc.py +++ b/pypy/module/_cffi_backend/ctypefunc.py @@ -10,6 +10,7 @@ from rpython.rlib.objectmodel import we_are_translated, instantiate from rpython.rlib.objectmodel import keepalive_until_here from rpython.rtyper.lltypesystem import lltype, llmemory, rffi +from rpython.rtyper.annlowlevel import llstr from pypy.interpreter.error import OperationError, oefmt from pypy.module import _cffi_backend @@ -163,9 +164,9 @@ cif_descr = self.cif_descr # 'self' should have been promoted here size = cif_descr.exchange_size mustfree_max_plus_1 = 0 + keepalives = [llstr(None)] * len(args_w) # llstrings buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw') try: - keepalives = [None] * len(args_w) # None or strings for i in range(len(args_w)): data = rffi.ptradd(buffer, cif_descr.exchange_args[i]) w_obj = args_w[i] @@ -191,9 +192,10 @@ if flag == 1: lltype.free(raw_cdata, flavor='raw') elif flag >= 4: - value = keepalives[i] - assert value is not None - rffi.free_nonmovingbuffer(value, raw_cdata, chr(flag)) + llobj = keepalives[i] + assert llobj # not NULL + rffi.free_nonmovingbuffer_ll(raw_cdata, + llobj, chr(flag)) lltype.free(buffer, flavor='raw') keepalive_until_here(args_w) return w_res diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py --- a/pypy/module/_cffi_backend/ctypeptr.py +++ b/pypy/module/_cffi_backend/ctypeptr.py @@ -305,16 +305,8 @@ else: return lltype.nullptr(rffi.CCHARP.TO) - def _prepare_pointer_call_argument(self, w_init, cdata, keepalives, i): + def _prepare_pointer_call_argument(self, w_init, cdata): space = self.space - if self.accept_str and space.isinstance_w(w_init, space.w_bytes): - # special case to optimize strings passed to a "char *" argument - value = space.bytes_w(w_init) - if isinstance(self.ctitem, ctypeprim.W_CTypePrimitiveBool): - self._must_be_string_of_zero_or_one(value) - keepalives[i] = value - return misc.write_string_as_charp(cdata, value) - # if (space.isinstance_w(w_init, space.w_list) or space.isinstance_w(w_init, space.w_tuple)): length = space.int_w(space.len(w_init)) @@ -360,14 +352,27 @@ return 1 def convert_argument_from_object(self, cdata, w_ob, keepalives, i): + # writes the pointer to cdata[0], writes the must-free flag in + # the byte just before cdata[0], and returns True if something + # must be done later to free. from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag - result = (not isinstance(w_ob, cdataobj.W_CData) and - self._prepare_pointer_call_argument(w_ob, cdata, - keepalives, i)) + if isinstance(w_ob, cdataobj.W_CData): + result = 0 + else: + space = self.space + if self.accept_str and space.isinstance_w(w_ob, space.w_bytes): + # special case to optimize strings passed to a "char *" argument + value = space.bytes_w(w_ob) + if isinstance(self.ctitem, ctypeprim.W_CTypePrimitiveBool): + self._must_be_string_of_zero_or_one(value) + keepalives[i] = misc.write_string_as_charp(cdata, value) + return True + result = self._prepare_pointer_call_argument(w_ob, cdata) + if result == 0: self.convert_from_object(cdata, w_ob) set_mustfree_flag(cdata, result) - return result + return result == 1 # 0 or 2 => False, nothing to do later def getcfield(self, attr): from pypy.module._cffi_backend.ctypestruct import W_CTypeStructOrUnion 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 @@ -112,11 +112,13 @@ def write_raw_longdouble_data(target, source): rffi.cast(rffi.LONGDOUBLEP, target)[0] = source - at jit.dont_look_inside # lets get_nonmovingbuffer_final_null be inlined + at jit.dont_look_inside # lets get_nonmovingbuffer_ll_final_null be inlined def write_string_as_charp(target, string): - buf, buf_flag = rffi.get_nonmovingbuffer_final_null(string) + from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag + buf, llobj, buf_flag = rffi.get_nonmovingbuffer_ll_final_null(string) + set_mustfree_flag(target, ord(buf_flag)) # 4, 5 or 6 rffi.cast(rffi.CCHARPP, target)[0] = buf - return ord(buf_flag) # 4, 5 or 6 + return llobj # ____________________________________________________________ diff --git a/pypy/module/_cffi_backend/realize_c_type.py b/pypy/module/_cffi_backend/realize_c_type.py --- a/pypy/module/_cffi_backend/realize_c_type.py +++ b/pypy/module/_cffi_backend/realize_c_type.py @@ -405,6 +405,20 @@ if from_ffi and ffi.cached_types[index] is not None: return ffi.cached_types[index] + opcodes[index] = rffi.cast(rffi.VOIDP, 255) + try: + x = realize_c_type_or_func_now(ffi, op, opcodes, index) + finally: + if opcodes[index] == rffi.cast(rffi.VOIDP, 255): + opcodes[index] = op + + if from_ffi: + assert ffi.cached_types[index] is None or ffi.cached_types[index] is x + ffi.cached_types[index] = x + + return x + +def realize_c_type_or_func_now(ffi, op, opcodes, index): case = getop(op) if case == cffi_opcode.OP_PRIMITIVE: @@ -446,13 +460,16 @@ 'c_type_index') x = realize_c_type_or_func(ffi, ffi.ctxobj.ctx.c_types, type_index) + elif case == 255: + raise oefmt(ffi.space.w_RuntimeError, + "found a situation in which we try to build a type recursively. " + "This is known to occur e.g. in ``struct s { void(*callable)" + "(struct s); }''. Please report if you get this error and " + "really need support for your case.") + else: raise oefmt(ffi.space.w_NotImplementedError, "op=%d", case) - if from_ffi: - assert ffi.cached_types[index] is None or ffi.cached_types[index] is x - ffi.cached_types[index] = x - return x diff --git a/pypy/module/_cffi_backend/test/test_recompiler.py b/pypy/module/_cffi_backend/test/test_recompiler.py --- a/pypy/module/_cffi_backend/test/test_recompiler.py +++ b/pypy/module/_cffi_backend/test/test_recompiler.py @@ -2141,3 +2141,19 @@ assert seen == [2 * 4, p] ffi.release(p) # no effect assert seen == [2 * 4, p] + + def test_struct_with_func_with_struct_arg(self): + ffi, lib = self.prepare("""struct BinaryTree { + int (* CompareKey)(struct BinaryTree tree); + };""", + "test_struct_with_func_with_struct_arg", """ + struct BinaryTree { + int (* CompareKey)(struct BinaryTree tree); + }; + """) + e = raises(RuntimeError, ffi.new, "struct BinaryTree *") + assert str(e.value) == ( + "found a situation in which we try to build a type recursively. " + "This is known to occur e.g. in ``struct s { void(*callable)" + "(struct s); }''. Please report if you get this error and " + "really need support for your case.") diff --git a/pypy/module/_vmprof/test/test__vmprof.py b/pypy/module/_vmprof/test/test__vmprof.py --- a/pypy/module/_vmprof/test/test__vmprof.py +++ b/pypy/module/_vmprof/test/test__vmprof.py @@ -114,14 +114,17 @@ @py.test.mark.xfail(sys.platform.startswith('freebsd'), reason = "not implemented") def test_get_profile_path(self): import _vmprof - tmpfile = open(self.tmpfilename, 'wb') - assert _vmprof.get_profile_path() is None - _vmprof.enable(tmpfile.fileno(), 0.01, 0, 0, 0, 0) - path = _vmprof.get_profile_path() + with open(self.tmpfilename, "wb") as tmpfile: + assert _vmprof.get_profile_path() is None + _vmprof.enable(tmpfile.fileno(), 0.01, 0, 0, 0, 0) + path = _vmprof.get_profile_path() + _vmprof.disable() + if path != tmpfile.name: with open(path, "rb") as fd1: - assert fd1.read() == tmpfile.read() - _vmprof.disable() + with open(self.tmpfilename, "rb") as fd2: + assert fd1.read() == fd2.read() + assert _vmprof.get_profile_path() is None def test_stop_sampling(self): diff --git a/rpython/config/translationoption.py b/rpython/config/translationoption.py --- a/rpython/config/translationoption.py +++ b/rpython/config/translationoption.py @@ -1,5 +1,6 @@ import sys import os +import platform as _stdlib_platform from rpython.config.config import OptionDescription, BoolOption, IntOption, ArbitraryOption, FloatOption from rpython.config.config import ChoiceOption, StrOption, Config, ConflictConfigError from rpython.config.config import ConfigError @@ -30,7 +31,9 @@ False) # Windows doesn't work. Please # add other platforms here if it works on them. - +MACHINE = _stdlib_platform.machine() +if MACHINE == 'aarch64': + SUPPORT__THREAD = False # (*) NOTE: __thread on OS/X does not work together with # pthread_key_create(): when the destructor is called, the __thread is # already freed! diff --git a/rpython/jit/backend/aarch64/TODO b/rpython/jit/backend/aarch64/TODO new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/aarch64/TODO @@ -0,0 +1,35 @@ +* cond_call and following guard_exception + + +* We can try to make generate_quick_failure() emit two instructions less: + the two store_reg() [one in generate_quick_failure and the other in + push_gcmap]. Instead we'd load the values in ip2 and ip3, and the + store_regs would occur inside self.failure_recovery_code + (which 'target' points to). + + +* use STP instead of STR in all long sequences of STR. Same with LDR + +* use "STR xzr, [..]" instead of "gen_load_int(ip, 0); STR ip, [..]". + Search around for gen_load_int(...0): it occurs at least in pop_gcmap() + _build_failure_recovery(), build_frame_realloc_slowpath(), etc. + + +* malloc_cond() and malloc_cond_varsize_frame() hard-code forward jump + distances by guessing the number of instructions that follows. Bad + idea because some of these instructions could easily be optimized in + the future to be a bit shorter. Rewrite this two places to use the + proper way instead of a magic "40" (or at least assert that it was + really 40). + + +* use "CBNZ register, offset" (compare-and-branch-if-not-zero) + instead of a CMP+BNE pair. Same with CBZ instead of CMP+BEQ + + +* when we need to save things on the stack, we typically push two words + and pop them later. It would be cheaper if we reserved two locations + in the stack from _call_header, then we could just write there. + *OR* + maybe it's enough if we use the form "str x0, [sp, !#offset]" which + combines in a single instruction the "str" with the change of sp diff --git a/rpython/jit/backend/aarch64/__init__.py b/rpython/jit/backend/aarch64/__init__.py new file mode 100644 diff --git a/rpython/jit/backend/aarch64/arch.py b/rpython/jit/backend/aarch64/arch.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/aarch64/arch.py @@ -0,0 +1,14 @@ + +WORD = 8 + +# The stack contains the force_index and the, callee saved registers and +# ABI required information +# All the rest of the data is in a GC-managed variable-size "frame". +# This jitframe object's address is always stored in the register FP +# A jitframe is a jit.backend.llsupport.llmodel.jitframe.JITFRAME +# Stack frame fixed area +# Currently only the force_index +NUM_MANAGED_REGS = 16 +NUM_VFP_REGS = 8 +JITFRAME_FIXED_SIZE = NUM_MANAGED_REGS + NUM_VFP_REGS +# 16 GPR + 8 VFP Regs, for now diff --git a/rpython/jit/backend/aarch64/assembler.py b/rpython/jit/backend/aarch64/assembler.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/aarch64/assembler.py @@ -0,0 +1,1482 @@ + +from rpython.jit.backend.aarch64.arch import WORD, JITFRAME_FIXED_SIZE +from rpython.jit.backend.aarch64.codebuilder import InstrBuilder, OverwritingBuilder +from rpython.jit.backend.aarch64.locations import imm, StackLocation, get_fp_offset +#from rpython.jit.backend.arm.helper.regalloc import VMEM_imm_size +from rpython.jit.backend.aarch64.opassembler import ResOpAssembler +from rpython.jit.backend.aarch64.regalloc import (Regalloc, check_imm_arg, + operations as regalloc_operations, guard_operations, comp_operations, + CoreRegisterManager, VFPRegisterManager) +from rpython.jit.backend.aarch64 import registers as r +from rpython.jit.backend.arm import conditions as c +from rpython.jit.backend.llsupport import jitframe, rewrite +from rpython.jit.backend.llsupport.assembler import BaseAssembler +from rpython.jit.backend.llsupport.regalloc import get_scale, valid_addressing_size +from rpython.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper +from rpython.jit.backend.model import CompiledLoopToken +from rpython.jit.codewriter.effectinfo import EffectInfo +from rpython.jit.metainterp.history import AbstractFailDescr, FLOAT, INT, VOID +from rpython.jit.metainterp.resoperation import rop +from rpython.rlib.debug import debug_print, debug_start, debug_stop +from rpython.rlib.jit import AsmInfo +from rpython.rlib.objectmodel import we_are_translated, specialize, compute_unique_id +from rpython.rlib.rarithmetic import r_uint +from rpython.rtyper.annlowlevel import llhelper, cast_instance_to_gcref +from rpython.rtyper.lltypesystem import lltype, rffi +from rpython.rtyper.lltypesystem.lloperation import llop +from rpython.rlib.rjitlog import rjitlog as jl + +class AssemblerARM64(ResOpAssembler): + def __init__(self, cpu, translate_support_code=False): + ResOpAssembler.__init__(self, cpu, translate_support_code) + self.failure_recovery_code = [0, 0, 0, 0] + self.wb_slowpath = [0, 0, 0, 0, 0] + + def assemble_loop(self, jd_id, unique_id, logger, loopname, inputargs, + operations, looptoken, log): + clt = CompiledLoopToken(self.cpu, looptoken.number) + clt._debug_nbargs = len(inputargs) + looptoken.compiled_loop_token = clt + + if not we_are_translated(): + # Arguments should be unique + assert len(set(inputargs)) == len(inputargs) + + self.setup(looptoken) + + frame_info = self.datablockwrapper.malloc_aligned( + jitframe.JITFRAMEINFO_SIZE, alignment=WORD) + clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info) + clt.frame_info.clear() # for now + + if log: + operations = self._inject_debugging_code(looptoken, operations, + 'e', looptoken.number) + + regalloc = Regalloc(assembler=self) + allgcrefs = [] + operations = regalloc.prepare_loop(inputargs, operations, looptoken, + allgcrefs) + self.reserve_gcref_table(allgcrefs) + functionpos = self.mc.get_relative_pos() + + self._call_header_with_stack_check() + self._check_frame_depth_debug(self.mc) + + loop_head = self.mc.get_relative_pos() + looptoken._ll_loop_code = loop_head + # + frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) + self.update_frame_depth(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) + # + size_excluding_failure_stuff = self.mc.get_relative_pos() + + self.write_pending_failure_recoveries() + + full_size = self.mc.get_relative_pos() + rawstart = self.materialize_loop(looptoken) + looptoken._ll_function_addr = rawstart + functionpos + + self.patch_gcref_table(looptoken, rawstart) + self.process_pending_guards(rawstart) + self.fixup_target_tokens(rawstart) + + if log and not we_are_translated(): + self.mc._dump_trace(rawstart, + 'loop.asm') + + ops_offset = self.mc.ops_offset + + if logger: + log = logger.log_trace(jl.MARK_TRACE_ASM, None, self.mc) + log.write(inputargs, operations, ops_offset=ops_offset) + + # legacy + if logger.logger_ops: + logger.logger_ops.log_loop(inputargs, operations, 0, + "rewritten", name=loopname, + ops_offset=ops_offset) + + self.teardown() + + debug_start("jit-backend-addr") + debug_print("Loop %d (%s) has address 0x%x to 0x%x (bootstrap 0x%x)" % ( + looptoken.number, loopname, + r_uint(rawstart + loop_head), + r_uint(rawstart + size_excluding_failure_stuff), + r_uint(rawstart + functionpos))) + debug_print(" gc table: 0x%x" % r_uint(rawstart)) + debug_print(" function: 0x%x" % r_uint(rawstart + functionpos)) + debug_print(" resops: 0x%x" % r_uint(rawstart + loop_head)) + debug_print(" failures: 0x%x" % r_uint(rawstart + + size_excluding_failure_stuff)) + debug_print(" end: 0x%x" % r_uint(rawstart + full_size)) + debug_stop("jit-backend-addr") + + return AsmInfo(ops_offset, rawstart + loop_head, + size_excluding_failure_stuff - loop_head) + + def assemble_bridge(self, logger, faildescr, inputargs, operations, + original_loop_token, log): + if not we_are_translated(): + # Arguments should be unique + assert len(set(inputargs)) == len(inputargs) + + self.setup(original_loop_token) + #self.codemap.inherit_code_from_position(faildescr.adr_jump_offset) + descr_number = compute_unique_id(faildescr) + if log: + operations = self._inject_debugging_code(faildescr, operations, + 'b', descr_number) + + assert isinstance(faildescr, AbstractFailDescr) + + arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs) + + regalloc = Regalloc(assembler=self) + allgcrefs = [] + operations = regalloc.prepare_bridge(inputargs, arglocs, + operations, + allgcrefs, + self.current_clt.frame_info) + self.reserve_gcref_table(allgcrefs) + startpos = self.mc.get_relative_pos() + + self._check_frame_depth(self.mc, regalloc.get_gcmap()) + + bridgestartpos = self.mc.get_relative_pos() + frame_depth_no_fixed_size = self._assemble(regalloc, inputargs, operations) + + codeendpos = self.mc.get_relative_pos() + + self.write_pending_failure_recoveries() + + fullsize = self.mc.get_relative_pos() + rawstart = self.materialize_loop(original_loop_token) + + self.patch_gcref_table(original_loop_token, rawstart) + self.process_pending_guards(rawstart) + + debug_start("jit-backend-addr") + debug_print("bridge out of Guard 0x%x has address 0x%x to 0x%x" % + (r_uint(descr_number), r_uint(rawstart + startpos), + r_uint(rawstart + codeendpos))) + debug_print(" gc table: 0x%x" % r_uint(rawstart)) + debug_print(" jump target: 0x%x" % r_uint(rawstart + startpos)) + debug_print(" resops: 0x%x" % r_uint(rawstart + bridgestartpos)) + debug_print(" failures: 0x%x" % r_uint(rawstart + codeendpos)) + debug_print(" end: 0x%x" % r_uint(rawstart + fullsize)) + debug_stop("jit-backend-addr") + + # patch the jump from original guard + self.patch_trace(faildescr, original_loop_token, + rawstart + startpos, regalloc) + + self.patch_stack_checks(frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE, + rawstart) + if not we_are_translated(): + if log: + self.mc._dump_trace(rawstart, 'bridge.asm') + + ops_offset = self.mc.ops_offset + frame_depth = max(self.current_clt.frame_info.jfi_frame_depth, + frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE) + self.fixup_target_tokens(rawstart) + self.update_frame_depth(frame_depth) + + if logger: + log = logger.log_trace(jl.MARK_TRACE_ASM, None, self.mc) + log.write(inputargs, operations, ops_offset) + # log that the already written bridge is stitched to a descr! + logger.log_patch_guard(descr_number, rawstart) + + # legacy + if logger.logger_ops: + logger.logger_ops.log_bridge(inputargs, operations, "rewritten", + faildescr, ops_offset=ops_offset) + + self.teardown() + + return AsmInfo(ops_offset, startpos + rawstart, codeendpos - startpos) + + def setup(self, looptoken): + BaseAssembler.setup(self, looptoken) + assert self.memcpy_addr != 0, 'setup_once() not called?' + if we_are_translated(): + self.debug = False + self.current_clt = looptoken.compiled_loop_token + self.mc = InstrBuilder() + self.pending_guards = [] + #assert self.datablockwrapper is None --- but obscure case + # possible, e.g. getting MemoryError and continuing + allblocks = self.get_asmmemmgr_blocks(looptoken) + self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr, + allblocks) + self.mc.datablockwrapper = self.datablockwrapper + self.target_tokens_currently_compiling = {} + self.frame_depth_to_patch = [] + + def teardown(self): + self.current_clt = None + self._regalloc = None + self.mc = None + self.pending_guards = None + + def _push_all_regs_to_jitframe(self, mc, ignored_regs, withfloats, + callee_only=False): + # Push general purpose registers + base_ofs = self.cpu.get_baseofs_of_frame_field() + if callee_only: + regs = CoreRegisterManager.save_around_call_regs + else: + regs = CoreRegisterManager.all_regs + # XXX add special case if ignored_regs are a block at the start of regs + if not ignored_regs: # we want to push a contiguous block of regs + assert base_ofs < 0x100 + for i, reg in enumerate(regs): + mc.STR_ri(reg.value, r.fp.value, base_ofs + i * WORD) + else: + for reg in ignored_regs: + assert not reg.is_vfp_reg() # sanity check + # we can have holes in the list of regs + for i, gpr in enumerate(regs): + if gpr in ignored_regs: + continue + self.store_reg(mc, gpr, r.fp, base_ofs + i * WORD) + + if withfloats: + # Push VFP regs + regs = VFPRegisterManager.all_regs + ofs = len(CoreRegisterManager.all_regs) * WORD + for reg in regs: + mc.STR_di(reg.value, r.fp.value, ofs + base_ofs + reg.value * WORD) + + def _pop_all_regs_from_jitframe(self, mc, ignored_regs, withfloats, + callee_only=False): + # Pop general purpose registers + base_ofs = self.cpu.get_baseofs_of_frame_field() + if callee_only: + regs = CoreRegisterManager.save_around_call_regs + else: + regs = CoreRegisterManager.all_regs + # XXX add special case if ignored_regs are a block at the start of regs + if not ignored_regs: # we want to pop a contiguous block of regs + assert base_ofs < 0x100 + for i, reg in enumerate(regs): + mc.LDR_ri(reg.value, r.fp.value, base_ofs + i * WORD) + else: + for reg in ignored_regs: + assert not reg.is_vfp_reg() # sanity check + # we can have holes in the list of regs + for i, gpr in enumerate(regs): + if gpr in ignored_regs: + continue + ofs = i * WORD + base_ofs + self.load_reg(mc, gpr, r.fp, ofs) + if withfloats: + # Pop VFP regs + regs = VFPRegisterManager.all_regs + ofs = len(CoreRegisterManager.all_regs) * WORD + for reg in regs: + mc.LDR_di(reg.value, r.fp.value, ofs + base_ofs + reg.value * WORD) + + def _build_failure_recovery(self, exc, withfloats=False): + mc = InstrBuilder() + self._push_all_regs_to_jitframe(mc, [], withfloats) + + if exc: + # We might have an exception pending. Load it into r4 + # (this is a register saved across calls) + mc.gen_load_int(r.x5.value, self.cpu.pos_exc_value()) + mc.LDR_ri(r.x4.value, r.x5.value, 0) + # clear the exc flags + mc.gen_load_int(r.x6.value, 0) + mc.STR_ri(r.x6.value, r.x5.value, 0) # pos_exc_value is still in r5 + mc.gen_load_int(r.x5.value, self.cpu.pos_exception()) + mc.STR_ri(r.x6.value, r.x5.value, 0) + # save r4 into 'jf_guard_exc' + offset = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + assert check_imm_arg(abs(offset)) + mc.STR_ri(r.x4.value, r.fp.value, offset) + # now we return from the complete frame, which starts from + # _call_header_with_stack_check(). The LEA in _call_footer below + # throws away most of the frame, including all the PUSHes that we + # did just above. + + # set return value + mc.MOV_rr(r.x0.value, r.fp.value) + + self.gen_func_epilog(mc) + rawstart = mc.materialize(self.cpu, []) + self.failure_recovery_code[exc + 2 * withfloats] = rawstart + + def propagate_memoryerror_if_reg_is_null(self, reg_loc): + # see ../x86/assembler.py:genop_discard_check_memory_error() + self.mc.CMP_ri(reg_loc.value, 0) + self.mc.B_ofs_cond(6 * 4, c.NE) + self.mc.B(self.propagate_exception_path) + + def _build_wb_slowpath(self, withcards, withfloats=False, for_frame=False): + descr = self.cpu.gc_ll_descr.write_barrier_descr + if descr is None: + return + if not withcards: + func = descr.get_write_barrier_fn(self.cpu) + else: + if descr.jit_wb_cards_set == 0: + return + func = descr.get_write_barrier_from_array_fn(self.cpu) + if func == 0: + return + # + # This builds a helper function called from the slow path of + # write barriers. It must save all registers, and optionally + # all vfp registers. It takes a single argument which is in x0. + # It must keep stack alignment accordingly. + mc = InstrBuilder() + # + mc.SUB_ri(r.sp.value, r.sp.value, 2 * WORD) + mc.STR_ri(r.lr.value, r.sp.value, 0) + if not for_frame: + self._push_all_regs_to_jitframe(mc, [], withfloats, callee_only=True) + else: + # NOTE: don't save registers on the jitframe here! It might + # override already-saved values that will be restored + # later... + # + # we're possibly called from the slowpath of malloc + # save the caller saved registers + # assuming we do not collect here + exc0, exc1 = r.x19, r.x20 + mc.SUB_ri(r.sp.value, r.sp.value, (len(r.caller_resp) + 2 + len(r.caller_vfp_resp)) * WORD) + cur_stack = 0 + for i in range(0, len(r.caller_resp), 2): + mc.STP_rri(r.caller_resp[i].value, r.caller_resp[i + 1].value, r.sp.value, i * WORD) + cur_stack = len(r.caller_resp) + mc.STP_rri(exc0.value, exc1.value, r.sp.value, cur_stack * WORD) + cur_stack += 2 + for i in range(len(r.caller_vfp_resp)): + mc.STR_di(r.caller_vfp_resp[i].value, r.sp.value, cur_stack * WORD) + cur_stack += 1 + + self._store_and_reset_exception(mc, exc0, exc1) + mc.BL(func) + # + if not for_frame: + self._pop_all_regs_from_jitframe(mc, [], withfloats, callee_only=True) + else: + exc0, exc1 = r.x19, r.x20 + self._restore_exception(mc, exc0, exc1) + + cur_stack = 0 + for i in range(0, len(r.caller_resp), 2): + mc.LDP_rri(r.caller_resp[i].value, r.caller_resp[i + 1].value, r.sp.value, i * WORD) + cur_stack = len(r.caller_resp) + mc.LDP_rri(exc0.value, exc1.value, r.sp.value, cur_stack * WORD) + cur_stack += 2 + for i in range(len(r.caller_vfp_resp)): + mc.LDR_di(r.caller_vfp_resp[i].value, r.sp.value, cur_stack * WORD) + cur_stack += 1 + + assert exc0 is not None + assert exc1 is not None + + mc.ADD_ri(r.sp.value, r.sp.value, (len(r.caller_resp) + 2 + len(r.caller_vfp_resp)) * WORD) + + # + if withcards: + # A final TEST8 before the RET, for the caller. Careful to + # not follow this instruction with another one that changes + # the status of the CPU flags! + mc.LDRB_ri(r.ip0.value, r.x0.value, descr.jit_wb_if_flag_byteofs) + mc.MOVZ_r_u16(r.ip1.value, 0x80, 0) + mc.TST_rr_shift(r.ip0.value, r.ip1.value, 0) + # + mc.LDR_ri(r.ip1.value, r.sp.value, 0) + mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) + mc.RET_r(r.ip1.value) + # + rawstart = mc.materialize(self.cpu, []) + if for_frame: + self.wb_slowpath[4] = rawstart + else: + self.wb_slowpath[withcards + 2 * withfloats] = rawstart + + def build_frame_realloc_slowpath(self): + # this code should do the following steps + # a) store all registers in the jitframe + # b) fish for the arguments passed by the caller + # c) store the gcmap in the jitframe + # d) call realloc_frame + # e) set the fp to point to the new jitframe + # f) store the address of the new jitframe in the shadowstack + # c) set the gcmap field to 0 in the new jitframe + # g) restore registers and return + mc = InstrBuilder() + self._push_all_regs_to_jitframe(mc, [], self.cpu.supports_floats) + # this is the gcmap stored by push_gcmap(mov=True) in _check_stack_frame + # and the expected_size pushed in _check_stack_frame + # pop the values passed on the stack, gcmap -> r0, expected_size -> r1 + mc.LDP_rri(r.x0.value, r.x1.value, r.sp.value, 0) + + mc.STR_ri(r.lr.value, r.sp.value, 0) + + # store the current gcmap(r0) in the jitframe + gcmap_ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + mc.STR_ri(r.x0.value, r.fp.value, gcmap_ofs) + + # set first arg, which is the old jitframe address + mc.MOV_rr(r.x0.value, r.fp.value) + + # store a possibly present exception + self._store_and_reset_exception(mc, None, r.x19, on_frame=True) + + # call realloc_frame, it takes two arguments + # arg0: the old jitframe + # arg1: the new size + # + mc.BL(self.cpu.realloc_frame) + + # set fp to the new jitframe returned from the previous call + mc.MOV_rr(r.fp.value, r.x0.value) + + # restore a possibly present exception + self._restore_exception(mc, None, r.x19) + + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + self._load_shadowstack_top(mc, r.x19, gcrootmap) + # store the new jitframe addr in the shadowstack + mc.SUB_ri(r.x19.value, r.x19.value, WORD) + mc.STR_ri(r.x0.value, r.x19.value, 0) + + # reset the jf_gcmap field in the jitframe + mc.gen_load_int(r.ip0.value, 0) + mc.STR_ri(r.ip0.value, r.fp.value, gcmap_ofs) + + # restore registers + self._pop_all_regs_from_jitframe(mc, [], self.cpu.supports_floats) + + # return + mc.LDR_ri(r.lr.value, r.sp.value, 0) + mc.ADD_ri(r.sp.value, r.sp.value, 2*WORD) + mc.RET_r(r.lr.value) + self._frame_realloc_slowpath = mc.materialize(self.cpu, []) + + def _load_shadowstack_top(self, mc, reg, gcrootmap): + rst = gcrootmap.get_root_stack_top_addr() + mc.gen_load_int(reg.value, rst) + self.load_reg(mc, reg, reg) + return rst + + def _store_and_reset_exception(self, mc, excvalloc=None, exctploc=None, + on_frame=False): + """ Resest the exception. If excvalloc is None, then store it on the + frame in jf_guard_exc + """ + assert excvalloc is not r.ip0 + assert exctploc is not r.ip0 + tmpreg = r.ip1 + mc.gen_load_int(r.ip0.value, self.cpu.pos_exc_value()) + if excvalloc is not None: # store + assert excvalloc.is_core_reg() + self.load_reg(mc, excvalloc, r.ip0) + if on_frame: + # store exc_value in JITFRAME + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + assert check_imm_arg(ofs) + # + self.load_reg(mc, r.ip0, r.ip0, helper=tmpreg) + # + self.store_reg(mc, r.ip0, r.fp, ofs, helper=tmpreg) + if exctploc is not None: + # store pos_exception in exctploc + assert exctploc.is_core_reg() + mc.gen_load_int(r.ip0.value, self.cpu.pos_exception()) + self.load_reg(mc, exctploc, r.ip0, helper=tmpreg) + + if on_frame or exctploc is not None: + mc.gen_load_int(r.ip0.value, self.cpu.pos_exc_value()) + + # reset exception + mc.gen_load_int(tmpreg.value, 0) + + self.store_reg(mc, tmpreg, r.ip0, 0) + + mc.gen_load_int(r.ip0.value, self.cpu.pos_exception()) + self.store_reg(mc, tmpreg, r.ip0, 0) + + def _restore_exception(self, mc, excvalloc, exctploc): + assert excvalloc is not r.ip0 + assert exctploc is not r.ip0 + mc.gen_load_int(r.ip0.value, self.cpu.pos_exc_value()) + if excvalloc is not None: + assert excvalloc.is_core_reg() + self.store_reg(mc, excvalloc, r.ip0) + else: + assert exctploc is not r.fp + # load exc_value from JITFRAME and put it in pos_exc_value + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + self.load_reg(mc, r.ip1, r.fp, ofs) + self.store_reg(mc, r.ip1, r.ip0) + # reset exc_value in the JITFRAME + mc.gen_load_int(r.ip1.value, 0) + self.store_reg(mc, r.ip1, r.fp, ofs) + + # restore pos_exception from exctploc register + mc.gen_load_int(r.ip0.value, self.cpu.pos_exception()) + self.store_reg(mc, exctploc, r.ip0) + + def _build_propagate_exception_path(self): + mc = InstrBuilder() + self._store_and_reset_exception(mc, r.x0) + ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc') + # make sure ofs fits into a register + assert check_imm_arg(ofs) + self.store_reg(mc, r.x0, r.fp, ofs) + propagate_exception_descr = rffi.cast(lltype.Signed, + cast_instance_to_gcref(self.cpu.propagate_exception_descr)) + # put propagate_exception_descr into frame + ofs = self.cpu.get_ofs_of_frame_field('jf_descr') + # make sure ofs fits into a register + assert check_imm_arg(ofs) + mc.gen_load_int(r.x0.value, propagate_exception_descr) + self.store_reg(mc, r.x0, r.fp, ofs) + mc.MOV_rr(r.x0.value, r.fp.value) + self.gen_func_epilog(mc) + rawstart = mc.materialize(self.cpu, []) + self.propagate_exception_path = rawstart + + def _build_cond_call_slowpath(self, supports_floats, callee_only): + """ This builds a general call slowpath, for whatever call happens to + come. + + The address of function to call comes in ip1. the result is also stored + in ip1 or ivfp + """ + mc = InstrBuilder() + # + self._push_all_regs_to_jitframe(mc, [], self.cpu.supports_floats, callee_only) + ## args are in their respective positions + mc.SUB_ri(r.sp.value, r.sp.value, 2 * WORD) + mc.STR_ri(r.ip0.value, r.sp.value, WORD) + mc.STR_ri(r.lr.value, r.sp.value, 0) + mc.BLR_r(r.ip1.value) + # callee saved + self._reload_frame_if_necessary(mc) # <- this will not touch x0 + mc.MOV_rr(r.ip1.value, r.x0.value) + self._pop_all_regs_from_jitframe(mc, [], supports_floats, + callee_only) # <- this does not touch ip1 + # return + mc.LDR_ri(r.ip0.value, r.sp.value, 0) + mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) + mc.RET_r(r.ip0.value) + return mc.materialize(self.cpu, []) + + def _build_malloc_slowpath(self, kind): + """ While arriving on slowpath, we have a gcpattern on stack 0. + The arguments are passed in r0 and r10, as follows: + + kind == 'fixed': nursery_head in r0 and the size in r1 - r0. + + kind == 'str/unicode': length of the string to allocate in r0. + + kind == 'var': length to allocate in r1, tid in r0, + and itemsize on the stack. + + This function must preserve all registers apart from r0 and r1. + """ + assert kind in ['fixed', 'str', 'unicode', 'var'] + mc = InstrBuilder() + # + self._push_all_regs_to_jitframe(mc, [r.x0, r.x1], True) + # + if kind == 'fixed': + addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr() + elif kind == 'str': + addr = self.cpu.gc_ll_descr.get_malloc_fn_addr('malloc_str') + elif kind == 'unicode': + addr = self.cpu.gc_ll_descr.get_malloc_fn_addr('malloc_unicode') + else: + addr = self.cpu.gc_ll_descr.get_malloc_slowpath_array_addr() + if kind == 'fixed': + # At this point we know that the values we need to compute the size + # are stored in x0 and x1. + mc.SUB_rr(r.x0.value, r.x1.value, r.x0.value) # compute the size we want + + if hasattr(self.cpu.gc_ll_descr, 'passes_frame'): + mc.MOV_rr(r.x1.value, r.fp.value) + elif kind == 'str' or kind == 'unicode': + mc.MOV_rr(r.x0.value, r.x1.value) + else: # var + # tid is in x0 + # length is in x1 + # gcmap in ip1 + # itemsize in ip2 + mc.MOV_rr(r.x2.value, r.x1.value) + mc.MOV_rr(r.x1.value, r.x0.value) + mc.MOV_rr(r.x0.value, r.ip2.value) # load itemsize, ip2 now free + # store the gc pattern + ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + mc.STR_ri(r.ip1.value, r.fp.value, ofs) + # + mc.SUB_ri(r.sp.value, r.sp.value, 2 * WORD) + mc.STR_ri(r.lr.value, r.sp.value, 0) + # + mc.BL(addr) + # + # If the slowpath malloc failed, we raise a MemoryError that + # always interrupts the current loop, as a "good enough" + # approximation. + mc.CMP_ri(r.x0.value, 0) + mc.B_ofs_cond(4 * 6, c.NE) + mc.B(self.propagate_exception_path) + # jump here + self._reload_frame_if_necessary(mc) + self._pop_all_regs_from_jitframe(mc, [r.x0, r.x1], self.cpu.supports_floats) + # + nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr() + mc.gen_load_int(r.x1.value, nursery_free_adr) + mc.LDR_ri(r.x1.value, r.x1.value, 0) + # clear the gc pattern + mc.gen_load_int(r.ip0.value, 0) + self.store_reg(mc, r.ip0, r.fp, ofs) + # return + mc.LDR_ri(r.lr.value, r.sp.value, 0) + mc.ADD_ri(r.sp.value, r.sp.value, 2 * WORD) + mc.RET_r(r.lr.value) + + # + rawstart = mc.materialize(self.cpu, []) + return rawstart + + def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, gcmap): + assert size & (WORD-1) == 0 + + self.mc.gen_load_int(r.x0.value, nursery_free_adr) + self.mc.LDR_ri(r.x0.value, r.x0.value, 0) + + if check_imm_arg(size): + self.mc.ADD_ri(r.x1.value, r.x0.value, size) + else: + self.mc.gen_load_int(r.x1.value, size) + self.mc.ADD_rr(r.x1.value, r.x0.value, r.x1.value) + + self.mc.gen_load_int(r.ip0.value, nursery_top_adr) + self.mc.LDR_ri(r.ip0.value, r.ip0.value, 0) + + self.mc.CMP_rr(r.x1.value, r.ip0.value) + + # We load into r0 the address stored at nursery_free_adr We calculate + # the new value for nursery_free_adr and store in r1 The we load the + # address stored in nursery_top_adr into IP If the value in r1 is + # (unsigned) bigger than the one in ip we conditionally call + # malloc_slowpath in case we called malloc_slowpath, which returns the + # new value of nursery_free_adr in r1 and the adr of the new object in + # r0. + + self.mc.B_ofs_cond(10 * 4, c.LO) # 4 for gcmap load, 5 for BL, 1 for B_ofs_cond + self.mc.gen_load_int_full(r.ip1.value, rffi.cast(lltype.Signed, gcmap)) + + self.mc.BL(self.malloc_slowpath) + + self.mc.gen_load_int(r.ip0.value, nursery_free_adr) + self.mc.STR_ri(r.x1.value, r.ip0.value, 0) + + def malloc_cond_varsize_frame(self, nursery_free_adr, nursery_top_adr, + sizeloc, gcmap): + if sizeloc is r.x0: + self.mc.MOV_rr(r.x1.value, r.x0.value) + sizeloc = r.x1 + self.mc.gen_load_int(r.x0.value, nursery_free_adr) + self.mc.LDR_ri(r.x0.value, r.x0.value, 0) + # + self.mc.ADD_rr(r.x1.value, r.x0.value, sizeloc.value) + # + self.mc.gen_load_int(r.ip0.value, nursery_top_adr) + self.mc.LDR_ri(r.ip0.value, r.ip0.value, 0) + + self.mc.CMP_rr(r.x1.value, r.ip0.value) + # + self.mc.B_ofs_cond(40, c.LO) # see calculations in malloc_cond + self.mc.gen_load_int_full(r.ip1.value, rffi.cast(lltype.Signed, gcmap)) + + self.mc.BL(self.malloc_slowpath) + + self.mc.gen_load_int(r.ip0.value, nursery_free_adr) + self.mc.STR_ri(r.x1.value, r.ip0.value, 0) + + def malloc_cond_varsize(self, kind, nursery_free_adr, nursery_top_adr, + lengthloc, itemsize, maxlength, gcmap, + arraydescr): + from rpython.jit.backend.llsupport.descr import ArrayDescr + assert isinstance(arraydescr, ArrayDescr) + + # lengthloc is the length of the array, which we must not modify! + assert lengthloc is not r.x0 and lengthloc is not r.x1 + if lengthloc.is_core_reg(): + varsizeloc = lengthloc + else: + assert lengthloc.is_stack() + self.regalloc_mov(lengthloc, r.x1) + varsizeloc = r.x1 + # + if check_imm_arg(maxlength): + self.mc.CMP_ri(varsizeloc.value, maxlength) + else: + self.mc.gen_load_int(r.ip0.value, maxlength) + self.mc.CMP_rr(varsizeloc.value, r.ip0.value) + jmp_adr0 = self.mc.currpos() # jump to (large) + self.mc.BRK() + # + self.mc.gen_load_int(r.x0.value, nursery_free_adr) + self.mc.LDR_ri(r.x0.value, r.x0.value, 0) + + + if valid_addressing_size(itemsize): + shiftsize = get_scale(itemsize) + else: + shiftsize = self._mul_const_scaled(self.mc, r.lr, varsizeloc, + itemsize) + varsizeloc = r.lr + # now varsizeloc is a register != x0. The size of + # the variable part of the array is (varsizeloc << shiftsize) + assert arraydescr.basesize >= self.gc_minimal_size_in_nursery + constsize = arraydescr.basesize + self.gc_size_of_header + force_realignment = (itemsize % WORD) != 0 + if force_realignment: + constsize += WORD - 1 + self.mc.gen_load_int(r.ip0.value, constsize) + # constsize + (varsizeloc << shiftsize) + self.mc.ADD_rr_shifted(r.x1.value, r.ip0.value, varsizeloc.value, + shiftsize) + self.mc.ADD_rr(r.x1.value, r.x1.value, r.x0.value) + if force_realignment: + # -WORD = 0xfffffffffffffff8 + self.mc.gen_load_int(r.ip0.value, -WORD) + self.mc.AND_rr(r.x1.value, r.x1.value, r.ip0.value) + # now x1 contains the total size in bytes, rounded up to a multiple + # of WORD, plus nursery_free_adr + # + self.mc.gen_load_int(r.ip0.value, nursery_top_adr) + self.mc.LDR_ri(r.ip0.value, r.ip0.value, 0) + + self.mc.CMP_rr(r.x1.value, r.ip0.value) + jmp_adr1 = self.mc.currpos() # jump to (after-call) + self.mc.BRK() + # + # (large) + currpos = self.mc.currpos() + pmc = OverwritingBuilder(self.mc, jmp_adr0, WORD) + pmc.B_ofs_cond(currpos - jmp_adr0, c.GT) + # + # save the gcmap + self.mc.gen_load_int_full(r.ip1.value, rffi.cast(lltype.Signed, gcmap)) + # + + if kind == rewrite.FLAG_ARRAY: + self.mc.gen_load_int(r.x0.value, arraydescr.tid) + self.regalloc_mov(lengthloc, r.x1) + self.mc.gen_load_int(r.ip2.value, itemsize) + addr = self.malloc_slowpath_varsize + else: + if kind == rewrite.FLAG_STR: + addr = self.malloc_slowpath_str + else: + assert kind == rewrite.FLAG_UNICODE + addr = self.malloc_slowpath_unicode + self.regalloc_mov(lengthloc, r.x1) + self.mc.BL(addr) + # + jmp_location = self.mc.currpos() # jump to (done) + self.mc.BRK() + # (after-call) + currpos = self.mc.currpos() + pmc = OverwritingBuilder(self.mc, jmp_adr1, WORD) + pmc.B_ofs_cond(currpos - jmp_adr1, c.LS) + # + # write down the tid, but not if it's the result of the CALL + self.mc.gen_load_int(r.ip0.value, arraydescr.tid) + self.mc.STR_ri(r.ip0.value, r.x0.value, 0) + + # while we're at it, this line is not needed if we've done the CALL + self.mc.gen_load_int(r.ip0.value, nursery_free_adr) + self.mc.STR_ri(r.x1.value, r.ip0.value, 0) + # (done) + # skip instructions after call + currpos = self.mc.currpos() + pmc = OverwritingBuilder(self.mc, jmp_location, WORD) + pmc.B_ofs(currpos - jmp_location) + + def _mul_const_scaled(self, mc, targetreg, sourcereg, itemsize): + """Produce one operation to do roughly + targetreg = sourcereg * itemsize + except that the targetreg may still need shifting by 0,1,2,3. + """ + if (itemsize & 7) == 0: + shiftsize = 3 + elif (itemsize & 3) == 0: + shiftsize = 2 + elif (itemsize & 1) == 0: + shiftsize = 1 + else: + shiftsize = 0 + itemsize >>= shiftsize + # + if valid_addressing_size(itemsize - 1): + self.mc.ADD_rr_shifted(targetreg.value, sourcereg.value, sourcereg.value, + get_scale(itemsize - 1)) + elif valid_addressing_size(itemsize): + self.mc.LSL_ri(targetreg.value, sourcereg.value, + get_scale(itemsize)) + else: + mc.gen_load_int(targetreg.value, itemsize) + mc.MUL_rr(targetreg.value, sourcereg.value, targetreg.value) + # + return shiftsize + + + def _build_stack_check_slowpath(self): + _, _, slowpathaddr = self.cpu.insert_stack_check() + if slowpathaddr == 0 or not self.cpu.propagate_exception_descr: + return # no stack check (for tests, or non-translated) + # + # make a "function" that is called immediately at the start of + # an assembler function. In particular, the stack looks like: + # + # | retaddr of caller | <-- aligned to a multiple of 16 + # | saved argument regs | + # | my own retaddr | <-- sp + # +-----------------------+ + # + mc = InstrBuilder() + # save argument registers and return address + mc.SUB_ri(r.sp.value, r.sp.value, (len(r.argument_regs) + 2) * WORD) + mc.STR_ri(r.lr.value, r.sp.value, 0) + for i in range(0, len(r.argument_regs), 2): + mc.STP_rri(r.argument_regs[i].value, r.argument_regs[i + 1].value, + r.sp.value, (i + 2) * WORD) + # stack is aligned here + # Pass current stack pointer as argument to the call + mc.SUB_ri(r.x0.value, r.sp.value, 0) + # + mc.BL(slowpathaddr) + + # check for an exception + mc.gen_load_int(r.x0.value, self.cpu.pos_exception()) + mc.LDR_ri(r.x0.value, r.x0.value, 0) + mc.TST_rr_shift(r.x0.value, r.x0.value, 0) + # + # restore registers and return + # We check for c.EQ here, meaning all bits zero in this case + + jmp = mc.currpos() + mc.BRK() + + for i in range(0, len(r.argument_regs), 2): + mc.LDP_rri(r.argument_regs[i].value, r.argument_regs[i + 1].value, + r.sp.value, (i + 2) * WORD) + mc.LDR_ri(r.ip0.value, r.sp.value, 0) + mc.ADD_ri(r.sp.value, r.sp.value, (len(r.argument_regs) + 2) * WORD) + mc.RET_r(r.ip0.value) + + # jump here + + pmc = OverwritingBuilder(mc, jmp, WORD) + pmc.B_ofs_cond(mc.currpos() - jmp, c.NE) + + mc.ADD_ri(r.sp.value, r.sp.value, (len(r.argument_regs) + 2) * WORD) + mc.B(self.propagate_exception_path) + # + + rawstart = mc.materialize(self.cpu, []) + self.stack_check_slowpath = rawstart + + def _check_frame_depth_debug(self, mc): + pass + + def _check_frame_depth(self, mc, gcmap, expected_size=-1): + """ check if the frame is of enough depth to follow this bridge. + Otherwise reallocate the frame in a helper. + There are other potential solutions + to that, but this one does not sound too bad. + """ + descrs = self.cpu.gc_ll_descr.getframedescrs(self.cpu) + ofs = self.cpu.unpack_fielddescr(descrs.arraydescr.lendescr) + mc.LDR_ri(r.ip0.value, r.fp.value, ofs) + stack_check_cmp_ofs = mc.currpos() + if expected_size == -1: + for _ in range(mc.get_max_size_of_gen_load_int()): + mc.NOP() + else: + mc.gen_load_int(r.ip1.value, expected_size) + mc.CMP_rr(r.ip0.value, r.ip1.value) + + jg_location = mc.currpos() + mc.BRK() + + # the size value is still stored in ip1 + mc.SUB_ri(r.sp.value, r.sp.value, 2*WORD) + mc.STR_ri(r.ip1.value, r.sp.value, WORD) + + mc.gen_load_int(r.ip0.value, rffi.cast(lltype.Signed, gcmap)) + mc.STR_ri(r.ip0.value, r.sp.value, 0) + + mc.BL(self._frame_realloc_slowpath) + + # patch jg_location above + currpos = mc.currpos() + pmc = OverwritingBuilder(mc, jg_location, WORD) + pmc.B_ofs_cond(currpos - jg_location, c.GE) + + self.frame_depth_to_patch.append(stack_check_cmp_ofs) + + def update_frame_depth(self, frame_depth): + baseofs = self.cpu.get_baseofs_of_frame_field() + self.current_clt.frame_info.update_frame_depth(baseofs, frame_depth) + + def _reload_frame_if_necessary(self, mc): + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + rst = gcrootmap.get_root_stack_top_addr() + mc.gen_load_int(r.ip0.value, rst) + self.load_reg(mc, r.ip0, r.ip0) + mc.SUB_ri(r.ip0.value, r.ip0.value, WORD) + mc.LDR_ri(r.fp.value, r.ip0.value, 0) + wbdescr = self.cpu.gc_ll_descr.write_barrier_descr + if gcrootmap and wbdescr: + # frame never uses card marking, so we enforce this is not + # an array + self._write_barrier_fastpath(mc, wbdescr, [r.fp], array=False, + is_frame=True) + + def generate_quick_failure(self, guardtok): + startpos = self.mc.currpos() + faildescrindex, target = self.store_info_on_descr(startpos, guardtok) + self.load_from_gc_table(r.ip0.value, faildescrindex) + ofs = self.cpu.get_ofs_of_frame_field('jf_descr') + self.store_reg(self.mc, r.ip0, r.fp, ofs) + self.push_gcmap(self.mc, gcmap=guardtok.gcmap) + assert target + self.mc.BL(target) + return startpos + + def push_gcmap(self, mc, gcmap, store=True): + assert store + ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + ptr = rffi.cast(lltype.Signed, gcmap) + mc.gen_load_int(r.ip0.value, ptr) + self.store_reg(mc, r.ip0, r.fp, ofs) + + def pop_gcmap(self, mc): + ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap') + mc.gen_load_int(r.ip0.value, 0) + self.store_reg(mc, r.ip0, r.fp, ofs) + + def write_pending_failure_recoveries(self): + for tok in self.pending_guards: + #generate the exit stub and the encoded representation + tok.pos_recovery_stub = self.generate_quick_failure(tok) + + def reserve_gcref_table(self, allgcrefs): + gcref_table_size = len(allgcrefs) * WORD + # align to a multiple of 16 and reserve space at the beginning + # of the machine code for the gc table. This lets us write + # machine code with relative addressing (LDR literal). + gcref_table_size = (gcref_table_size + 15) & ~15 + mc = self.mc + assert mc.get_relative_pos() == 0 + for i in range(gcref_table_size): + mc.writechar('\x00') + self.setup_gcrefs_list(allgcrefs) + + def patch_gcref_table(self, looptoken, rawstart): + # the gc table is at the start of the machine code + self.gc_table_addr = rawstart + tracer = self.cpu.gc_ll_descr.make_gcref_tracer(rawstart, + self._allgcrefs) + gcreftracers = self.get_asmmemmgr_gcreftracers(looptoken) + gcreftracers.append(tracer) # keepalive + self.teardown_gcrefs_list() + + def patch_stack_checks(self, framedepth, rawstart): + for ofs in self.frame_depth_to_patch: + mc = InstrBuilder() + mc.gen_load_int(r.ip1.value, framedepth) + mc.copy_to_raw_memory(ofs + rawstart) + + def load_from_gc_table(self, regnum, index): + address_in_buffer = index * WORD # at the start of the buffer + p_location = self.mc.get_relative_pos(break_basic_block=False) + offset = address_in_buffer - p_location + self.mc.LDR_r_literal(regnum, offset) + + def materialize_loop(self, looptoken): + self.datablockwrapper.done() # finish using cpu.asmmemmgr + self.datablockwrapper = None + allblocks = self.get_asmmemmgr_blocks(looptoken) + size = self.mc.get_relative_pos() + res = self.mc.materialize(self.cpu, allblocks, + self.cpu.gc_ll_descr.gcrootmap) + #self.cpu.codemap.register_codemap( + # self.codemap.get_final_bytecode(res, size)) + return res + + def patch_trace(self, faildescr, looptoken, bridge_addr, regalloc): + b = InstrBuilder() + patch_addr = faildescr.adr_jump_offset + assert patch_addr != 0 + b.BL(bridge_addr) + b.copy_to_raw_memory(patch_addr) + faildescr.adr_jump_offset = 0 + + def process_pending_guards(self, block_start): + clt = self.current_clt + for tok in self.pending_guards: + descr = tok.faildescr + assert isinstance(descr, AbstractFailDescr) + failure_recovery_pos = block_start + tok.pos_recovery_stub + descr.adr_jump_offset = failure_recovery_pos + relative_offset = tok.pos_recovery_stub - tok.offset + guard_pos = block_start + tok.offset + if not tok.guard_not_invalidated(): + # patch the guard jump to the stub + # overwrite the generate BRK with a B_offs to the pos of the + # stub + mc = InstrBuilder() + mc.B_ofs_cond(relative_offset, c.get_opposite_of(tok.fcond)) + mc.copy_to_raw_memory(guard_pos) + if tok.extra_offset != -1: + mc = InstrBuilder() + relative_offset = tok.pos_recovery_stub - tok.extra_offset + guard_pos = block_start + tok.extra_offset + mc.B_ofs_cond(relative_offset, c.get_opposite_of(tok.extra_cond)) + mc.copy_to_raw_memory(guard_pos) + else: + clt.invalidate_positions.append((guard_pos, relative_offset)) + + def fixup_target_tokens(self, rawstart): + for targettoken in self.target_tokens_currently_compiling: + targettoken._ll_loop_code += rawstart + self.target_tokens_currently_compiling = None + + def _call_header_with_stack_check(self): + self._call_header() + if self.stack_check_slowpath == 0: + pass # no stack check (e.g. not translated) + else: + endaddr, lengthaddr, _ = self.cpu.insert_stack_check() + # load stack end + self.mc.gen_load_int(r.lr.value, endaddr) # load lr, [end] + self.mc.LDR_ri(r.lr.value, r.lr.value, 0) # LDR lr, lr + # load stack length + self.mc.gen_load_int(r.ip1.value, lengthaddr) # load ip1, lengh + self.mc.LDR_ri(r.ip1.value, r.ip1.value, 0) # ldr ip1, *lengh + # calculate ofs + self.mc.SUB_ri(r.ip0.value, r.sp.value, 0) # ip0 = sp + # otherwise we can't use sp + self.mc.SUB_rr(r.lr.value, r.lr.value, r.ip0.value) # lr = lr - ip0 + # if ofs + self.mc.CMP_rr(r.lr.value, r.ip1.value) # CMP ip0, ip1 + pos = self.mc.currpos() + self.mc.BRK() + self.mc.BL(self.stack_check_slowpath) # call if ip0 > ip1 + pmc = OverwritingBuilder(self.mc, pos, WORD) + pmc.B_ofs_cond(self.mc.currpos() - pos, c.LS) + + def _call_header(self): + stack_size = (len(r.callee_saved_registers) + 4) * WORD + self.mc.STP_rr_preindex(r.lr.value, r.fp.value, r.sp.value, -stack_size) + for i in range(0, len(r.callee_saved_registers), 2): + self.mc.STP_rri(r.callee_saved_registers[i].value, + r.callee_saved_registers[i + 1].value, + r.sp.value, + (i + 4) * WORD) + + self.saved_threadlocal_addr = 3 * WORD # at offset 3 from location 'sp' + self.mc.STR_ri(r.x1.value, r.sp.value, 3 * WORD) + + # set fp to point to the JITFRAME, passed in argument 'x0' + self.mc.MOV_rr(r.fp.value, r.x0.value) + # + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + self.gen_shadowstack_header(gcrootmap) + + def _assemble(self, regalloc, inputargs, operations): + #self.guard_success_cc = c.cond_none + regalloc.compute_hint_frame_locations(operations) + self._walk_operations(inputargs, operations, regalloc) + #assert self.guard_success_cc == c.cond_none + frame_depth = regalloc.get_final_frame_depth() + jump_target_descr = regalloc.jump_target_descr + if jump_target_descr is not None: + tgt_depth = jump_target_descr._arm_clt.frame_info.jfi_frame_depth + target_frame_depth = tgt_depth - JITFRAME_FIXED_SIZE + frame_depth = max(frame_depth, target_frame_depth) + return frame_depth + + def _walk_operations(self, inputargs, operations, regalloc): + self._regalloc = regalloc + regalloc.operations = operations + while regalloc.position() < len(operations) - 1: + regalloc.next_instruction() + i = regalloc.position() + op = operations[i] + self.mc.mark_op(op) + opnum = op.getopnum() + if rop.has_no_side_effect(opnum) and op not in regalloc.longevity: + regalloc.possibly_free_vars_for_op(op) + elif not we_are_translated() and op.getopnum() == rop.FORCE_SPILL: + regalloc.force_spill_var(op.getarg(0)) + elif ((rop.returns_bool_result(opnum) or op.is_ovf()) and + i < len(operations) - 1 and + regalloc.next_op_can_accept_cc(operations, i) or + operations[i].is_ovf()): + if operations[i].is_ovf(): + assert operations[i + 1].getopnum() in [rop.GUARD_OVERFLOW, + rop.GUARD_NO_OVERFLOW] + guard_op = operations[i + 1] + guard_num = guard_op.getopnum() + arglocs, fcond = guard_operations[guard_num](regalloc, guard_op, op) + if arglocs is not None: + asm_guard_operations[guard_num](self, op, guard_op, fcond, arglocs) + regalloc.next_instruction() # advance one more + if guard_op.is_guard(): # can be also cond_call + regalloc.possibly_free_vars(guard_op.getfailargs()) + regalloc.possibly_free_vars_for_op(guard_op) + elif (rop.is_call_may_force(op.getopnum()) or + rop.is_call_release_gil(op.getopnum()) or + rop.is_call_assembler(op.getopnum())): + guard_op = operations[i + 1] # has to exist + guard_num = guard_op.getopnum() + assert guard_num in (rop.GUARD_NOT_FORCED, rop.GUARD_NOT_FORCED_2) + arglocs, fcond = guard_operations[guard_num](regalloc, guard_op, op) + if arglocs is not None: + asm_guard_operations[guard_num](self, op, guard_op, fcond, arglocs) + # fcond is abused here to pass the number of args + regalloc.next_instruction() # advance one more + regalloc.possibly_free_vars(guard_op.getfailargs()) + regalloc.possibly_free_vars_for_op(guard_op) + else: + arglocs = regalloc_operations[opnum](regalloc, op) + if arglocs is not None: + asm_operations[opnum](self, op, arglocs) + if rop.is_guard(opnum): + regalloc.possibly_free_vars(op.getfailargs()) + if op.type != 'v': + regalloc.possibly_free_var(op) + regalloc.possibly_free_vars_for_op(op) + regalloc.free_temp_vars() + regalloc._check_invariants() + if not we_are_translated(): + self.mc.BRK() + self.mc.mark_op(None) # end of the loop + regalloc.operations = None + + def dispatch_comparison(self, op): + opnum = op.getopnum() + arglocs = comp_operations[opnum](self._regalloc, op, True) + assert arglocs is not None + return asm_comp_operations[opnum](self, op, arglocs) + + # regalloc support + def load(self, loc, value): + """load an immediate value into a register""" + assert (loc.is_core_reg() and value.is_imm() + or loc.is_vfp_reg() and value.is_imm_float()) + if value.is_imm(): + self.mc.gen_load_int(loc.value, value.getint()) + elif value.is_imm_float(): + self.mc.gen_load_int(r.ip0.value, value.getint()) + self.mc.LDR_di(loc.value, r.ip0.value, 0) + + def _mov_stack_to_loc(self, prev_loc, loc): + offset = prev_loc.value + if loc.is_core_reg(): + assert prev_loc.type != FLOAT, 'trying to load from an \ + incompatible location into a core register' + # unspill a core register + assert 0 <= offset <= (1<<15) - 1 + self.mc.LDR_ri(loc.value, r.fp.value, offset) + return + if loc.is_vfp_reg(): + assert prev_loc.type == FLOAT, 'trying to load from an \ + incompatible location into a float register' + assert 0 <= offset <= (1 << 15) - 1 + self.mc.LDR_di(loc.value, r.fp.value, offset) + return + assert False + # elif loc.is_vfp_reg(): + # assert prev_loc.type == FLOAT, 'trying to load from an \ + # incompatible location into a float register' + # # load spilled value into vfp reg + # is_imm = check_imm_arg(offset) + # helper, save = self.get_tmp_reg() + # save_helper = not is_imm and save + # elif loc.is_raw_sp(): + # assert (loc.type == prev_loc.type == FLOAT + # or (loc.type != FLOAT and prev_loc.type != FLOAT)) + # tmp = loc + # if loc.is_float(): + # loc = r.vfp_ip + # else: + # loc, save_helper = self.get_tmp_reg() + # assert not save_helper + # helper, save_helper = self.get_tmp_reg([loc]) + # assert not save_helper + # else: + # assert 0, 'unsupported case' + + # if save_helper: + # self.mc.PUSH([helper.value], cond=cond) + # self.load_reg(self.mc, loc, r.fp, offset, cond=cond, helper=helper) + # if save_helper: + # self.mc.POP([helper.value], cond=cond) + + def _mov_reg_to_loc(self, prev_loc, loc): + if loc.is_core_reg(): + self.mc.MOV_rr(loc.value, prev_loc.value) + elif loc.is_stack(): + self.mc.STR_ri(prev_loc.value, r.fp.value, loc.value) + else: + assert False + + def _mov_imm_to_loc(self, prev_loc, loc): + if loc.is_core_reg(): + self.mc.gen_load_int(loc.value, prev_loc.value) + elif loc.is_stack(): + self.mc.gen_load_int(r.ip0.value, prev_loc.value) + self.mc.STR_ri(r.ip0.value, r.fp.value, loc.value) + else: + assert False + + def new_stack_loc(self, i, tp): + base_ofs = self.cpu.get_baseofs_of_frame_field() + return StackLocation(i, get_fp_offset(base_ofs, i), tp) + + def mov_loc_to_raw_stack(self, loc, pos): + if loc.is_core_reg(): + self.mc.STR_ri(loc.value, r.sp.value, pos) + elif loc.is_stack(): + self.mc.LDR_ri(r.ip0.value, r.fp.value, loc.value) + self.mc.STR_ri(r.ip0.value, r.sp.value, pos) + elif loc.is_vfp_reg(): + self.mc.STR_di(loc.value, r.sp.value, pos) + elif loc.is_imm(): + self.mc.gen_load_int(r.ip0.value, loc.value) + self.mc.STR_ri(r.ip0.value, r.sp.value, pos) + else: + assert False, "wrong loc" + + def mov_raw_stack_to_loc(self, pos, loc): + if loc.is_core_reg(): + self.mc.LDR_ri(loc.value, r.sp.value, pos) + elif loc.is_stack(): + self.mc.LDR_ri(r.ip0.value, r.sp.value, pos) + self.mc.STR_ri(r.ip0.value, r.fp.value, loc.value) + elif loc.is_vfp_reg(): + self.mc.LDR_di(loc.value, r.sp.value, pos) + else: + assert False, "wrong loc" + + def _mov_imm_float_to_loc(self, prev_loc, loc): + if loc.is_vfp_reg(): + self.load(loc, prev_loc) + elif loc.is_stack(): + self.load(r.vfp_ip, prev_loc) + self._mov_vfp_reg_to_loc(r.vfp_ip, loc) + else: + assert False, "wrong loc" + + def _mov_vfp_reg_to_loc(self, prev_loc, loc): + if loc.is_stack(): + self.mc.STR_di(prev_loc.value, r.fp.value, loc.value) + elif loc.is_vfp_reg(): + self.mc.FMOV_dd(loc.value, prev_loc.value) + else: + assert False, "wrong loc" + + def push_locations(self, locs): + if not locs: + return + depth = len(locs) * WORD + depth += depth & WORD # align + self.mc.SUB_ri(r.sp.value, r.sp.value, depth) + for i, loc in enumerate(locs): + self.mov_loc_to_raw_stack(loc, i * WORD) + + def pop_locations(self, locs): + if not locs: + return + depth = len(locs) * WORD + depth += depth & WORD # align + for i, loc in enumerate(locs): + self.mov_raw_stack_to_loc(i * WORD, loc) + self.mc.ADD_ri(r.sp.value, r.sp.value, depth) + + def regalloc_mov(self, prev_loc, loc): + """Moves a value from a previous location to some other location""" + if prev_loc.is_imm(): + return self._mov_imm_to_loc(prev_loc, loc) + elif prev_loc.is_core_reg(): + self._mov_reg_to_loc(prev_loc, loc) + elif prev_loc.is_stack(): + self._mov_stack_to_loc(prev_loc, loc) + elif prev_loc.is_imm_float(): + self._mov_imm_float_to_loc(prev_loc, loc) + elif prev_loc.is_vfp_reg(): + self._mov_vfp_reg_to_loc(prev_loc, loc) + else: + assert 0, 'unsupported case' + mov_loc_loc = regalloc_mov + + def gen_func_epilog(self, mc=None): + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if mc is None: + mc = self.mc + if gcrootmap and gcrootmap.is_shadow_stack: + self.gen_footer_shadowstack(gcrootmap, mc) + + # pop all callee saved registers + + stack_size = (len(r.callee_saved_registers) + 4) * WORD + + for i in range(0, len(r.callee_saved_registers), 2): + mc.LDP_rri(r.callee_saved_registers[i].value, + r.callee_saved_registers[i + 1].value, + r.sp.value, + (i + 4) * WORD) + mc.LDP_rr_postindex(r.lr.value, r.fp.value, r.sp.value, stack_size) + + + mc.RET_r(r.lr.value) + + def gen_shadowstack_header(self, gcrootmap): + # we push two words, like the x86 backend does: + # the '1' is to benefit from the shadowstack 'is_minor' optimization + rst = gcrootmap.get_root_stack_top_addr() + self.mc.gen_load_int(r.ip1.value, rst) + # x8 = *ip1 + self.load_reg(self.mc, r.x8, r.ip1) + # x8[0] = 1 + self.mc.gen_load_int(r.ip0.value, 1) + self.store_reg(self.mc, r.ip0, r.x8) + # x8[1] = r.fp + self.store_reg(self.mc, r.fp, r.x8, WORD) + # *ip1 = x8 + 2 * WORD + self.mc.ADD_ri(r.x8.value, r.x8.value, 2 * WORD) + self.store_reg(self.mc, r.x8, r.ip1) + + def gen_footer_shadowstack(self, gcrootmap, mc): + rst = gcrootmap.get_root_stack_top_addr() + mc.gen_load_int(r.ip0.value, rst) + self.load_reg(mc, r.ip1, r.ip0) + mc.SUB_ri(r.ip1.value, r.ip1.value, 2 * WORD) # two words, see above + self.store_reg(mc, r.ip1, r.ip0) + + def store_reg(self, mc, source, base, ofs=0, helper=None): + if source.is_vfp_reg(): + return self._store_vfp_reg(mc, source, base, ofs) + else: + return self._store_core_reg(mc, source, base, ofs) + + def _store_vfp_reg(self, mc, source, base, ofs): + assert ofs <= (1 << 15) - 1 + mc.STR_di(source.value, base.value, ofs) + + def _store_core_reg(self, mc, source, base, ofs): + # XXX fix: + assert ofs & 0x7 == 0 + assert 0 <= ofs < 32768 + mc.STR_ri(source.value, base.value, ofs) + #if check_imm_arg(ofs): + # mc.STR_ri(source.value, base.value, imm=ofs) + #else: + # mc.gen_load_int(r.ip1, ofs) + # mc.STR_rr(source.value, base.value, r.ip1) + + def load_reg(self, mc, target, base, ofs=0, helper=r.ip0): + assert target.is_core_reg() + if check_imm_arg(abs(ofs)): + mc.LDR_ri(target.value, base.value, ofs) + else: + mc.gen_load_int(helper.value, ofs) + mc.LDR_rr(target.value, base.value, helper.value) + + def check_frame_before_jump(self, target_token): + if target_token in self.target_tokens_currently_compiling: + return + if target_token._arm_clt is self.current_clt: + return + # We can have a frame coming from god knows where that's + # passed to a jump to another loop. Make sure it has the + # correct depth + expected_size = target_token._arm_clt.frame_info.jfi_frame_depth + self._check_frame_depth(self.mc, self._regalloc.get_gcmap(), + expected_size=expected_size) + + # ../x86/assembler.py:668 + def redirect_call_assembler(self, oldlooptoken, newlooptoken): + # some minimal sanity checking + old_nbargs = oldlooptoken.compiled_loop_token._debug_nbargs + new_nbargs = newlooptoken.compiled_loop_token._debug_nbargs + assert old_nbargs == new_nbargs + # we overwrite the instructions at the old _ll_function_addr + # to start with a JMP to the new _ll_function_addr. + # Ideally we should rather patch all existing CALLs, but well. + oldadr = oldlooptoken._ll_function_addr + target = newlooptoken._ll_function_addr + # copy frame-info data + baseofs = self.cpu.get_baseofs_of_frame_field() + newlooptoken.compiled_loop_token.update_frame_info( + oldlooptoken.compiled_loop_token, baseofs) + mc = InstrBuilder() + mc.B(target) + mc.copy_to_raw_memory(oldadr) + # + jl.redirect_assembler(oldlooptoken, newlooptoken, newlooptoken.number) + + + +def not_implemented(msg): + msg = '[ARM64/asm] %s\n' % msg + if we_are_translated(): + llop.debug_print(lltype.Void, msg) + raise NotImplementedError(msg) + + +def notimplemented_op(self, op, arglocs): + print "[ARM64/asm] %s not implemented" % op.getopname() + raise NotImplementedError(op) + +def notimplemented_comp_op(self, op, arglocs): + print "[ARM64/asm] %s not implemented" % op.getopname() + raise NotImplementedError(op) + +def notimplemented_guard_op(self, op, guard_op, fcond, arglocs): + print "[ARM64/asm] %s not implemented" % op.getopname() + raise NotImplementedError(op) + +asm_operations = [notimplemented_op] * (rop._LAST + 1) +asm_guard_operations = [notimplemented_guard_op] * (rop._LAST + 1) +asm_comp_operations = [notimplemented_comp_op] * (rop._LAST + 1) +asm_extra_operations = {} + +for name, value in ResOpAssembler.__dict__.iteritems(): + if name.startswith('emit_opx_'): + opname = name[len('emit_opx_'):] + num = getattr(EffectInfo, 'OS_' + opname.upper()) + asm_extra_operations[num] = value + elif name.startswith('emit_op_'): + opname = name[len('emit_op_'):] + num = getattr(rop, opname.upper()) + asm_operations[num] = value + elif name.startswith('emit_guard_op_'): + opname = name[len('emit_guard_op_'):] + num = getattr(rop, opname.upper()) + asm_guard_operations[num] = value + elif name.startswith('emit_comp_op_'): + opname = name[len('emit_comp_op_'):] + num = getattr(rop, opname.upper()) + asm_comp_operations[num] = value diff --git a/rpython/jit/backend/aarch64/callbuilder.py b/rpython/jit/backend/aarch64/callbuilder.py new file mode 100644 --- /dev/null +++ b/rpython/jit/backend/aarch64/callbuilder.py @@ -0,0 +1,291 @@ + +from rpython.jit.backend.llsupport.callbuilder import AbstractCallBuilder +from rpython.jit.backend.aarch64.arch import WORD +from rpython.jit.metainterp.history import INT, FLOAT, REF +from rpython.jit.backend.aarch64 import registers as r +from rpython.jit.backend.arm import conditions as c +from rpython.jit.backend.aarch64.jump import remap_frame_layout # we use arm algo +from rpython.jit.backend.llsupport import llerrno +from rpython.jit.backend.aarch64.codebuilder import OverwritingBuilder + +from rpython.rlib.objectmodel import we_are_translated +from rpython.rtyper.lltypesystem import rffi + +class Aarch64CallBuilder(AbstractCallBuilder): + def __init__(self, assembler, fnloc, arglocs, + resloc=r.x0, restype=INT, ressize=WORD, ressigned=True): + AbstractCallBuilder.__init__(self, assembler, fnloc, arglocs, + resloc, restype, ressize) + self.current_sp = 0 + + def prepare_arguments(self): + arglocs = self.arglocs + non_float_locs = [] + non_float_regs = [] + float_locs = [] + float_regs = [] + stack_locs = [] + free_regs = [r.x7, r.x6, r.x5, r.x4, r.x3, r.x2, r.x1, r.x0] + free_float_regs = [r.d7, r.d6, r.d5, r.d4, r.d3, r.d2, r.d1, r.d0] + for arg in arglocs: + if arg.type == FLOAT: + if free_float_regs: + float_locs.append(arg) + float_regs.append(free_float_regs.pop()) + else: + stack_locs.append(arg) + else: + if free_regs: + non_float_locs.append(arg) + non_float_regs.append(free_regs.pop()) + else: + stack_locs.append(arg) + + if stack_locs: + adj = len(stack_locs) + (len(stack_locs) & 1) + self.mc.SUB_ri(r.sp.value, r.sp.value, adj * WORD) + self.current_sp = adj * WORD + c = 0 + for loc in stack_locs: + self.asm.mov_loc_to_raw_stack(loc, c) + c += WORD + + move_back = False + if not self.fnloc.is_imm(): + if self.fnloc.is_core_reg(): + self.mc.MOV_rr(r.ip1.value, self.fnloc.value) + else: + assert self.fnloc.is_stack() + self.mc.LDR_ri(r.ip1.value, r.fp.value, self.fnloc.value) + self.fnloc = r.x8 + move_back = True + + remap_frame_layout(self.asm, non_float_locs, non_float_regs, r.ip0) + if float_locs: + remap_frame_layout(self.asm, float_locs, float_regs, r.d8) + + if move_back: + self.mc.MOV_rr(r.x8.value, r.ip1.value) + + def push_gcmap(self): + noregs = self.asm.cpu.gc_ll_descr.is_shadow_stack() + gcmap = self.asm._regalloc.get_gcmap([r.x0], noregs=noregs) + self.asm.push_gcmap(self.mc, gcmap) + + def pop_gcmap(self): + self.asm._reload_frame_if_necessary(self.mc) + self.asm.pop_gcmap(self.mc) + + def emit_raw_call(self): + #the actual call + if self.fnloc.is_imm(): + self.mc.BL(self.fnloc.value) + return + if self.fnloc.is_stack(): + assert False, "we should never be here" + else: + assert self.fnloc.is_core_reg() + assert self.fnloc is r.x8 + self.mc.BLR_r(self.fnloc.value) + + def restore_stack_pointer(self): + assert self.current_sp & 1 == 0 # always adjusted to 16 bytes + if self.current_sp == 0: + return + self.mc.ADD_ri(r.sp.value, r.sp.value, self.current_sp) + self.current_sp = 0 + + def load_result(self): + resloc = self.resloc + if self.restype == 'S': + assert False, "not supported yet" + XXX + self.mc.VMOV_sc(resloc.value, r.s0.value) + elif self.restype == 'L': + assert False, "not possible on 64bit backend" + YYY + assert resloc.is_vfp_reg() + self.mc.FMDRR(resloc.value, r.r0.value, r.r1.value) + # ensure the result is wellformed and stored in the correct location + if resloc is not None and resloc.is_core_reg(): + self._ensure_result_bit_extension(resloc, + self.ressize, self.ressign) + + def _ensure_result_bit_extension(self, resloc, size, signed): + if size == WORD: + return + if size == 4: + if not signed: # unsigned int + self.mc.LSL_ri(resloc.value, resloc.value, 32) + self.mc.LSR_ri(resloc.value, resloc.value, 32) + else: # signed int + self.mc.LSL_ri(resloc.value, resloc.value, 32) + self.mc.ASR_ri(resloc.value, resloc.value, 32) + elif size == 2: + if not signed: + self.mc.LSL_ri(resloc.value, resloc.value, 48) + self.mc.LSR_ri(resloc.value, resloc.value, 48) + else: + self.mc.LSL_ri(resloc.value, resloc.value, 48) + self.mc.ASR_ri(resloc.value, resloc.value, 48) + elif size == 1: + if not signed: # unsigned char + self.mc.AND_ri(resloc.value, resloc.value, 0xFF) + else: + self.mc.LSL_ri(resloc.value, resloc.value, 56) + self.mc.ASR_ri(resloc.value, resloc.value, 56) + + def call_releasegil_addr_and_move_real_arguments(self, fastgil): + assert self.is_call_release_gil + assert not self.asm._is_asmgcc() + RFASTGILPTR = r.x19 # constant &rpy_fastgil + RSHADOWOLD = r.x20 # old value of the shadowstack pointer, + # which we save here for later comparison + + gcrootmap = self.asm.cpu.gc_ll_descr.gcrootmap + if gcrootmap: + rst = gcrootmap.get_root_stack_top_addr() + self.mc.gen_load_int(r.ip1.value, rst) + self.mc.LDR_ri(RSHADOWOLD.value, r.ip1.value, 0) + + # change 'rpy_fastgil' to 0 (it should be non-zero right now) + self.mc.gen_load_int(RFASTGILPTR.value, fastgil) + self.mc.STLR(r.xzr.value, RFASTGILPTR.value) + + if not we_are_translated(): # for testing: we should not access + self.mc.ADD_ri(r.fp.value, r.fp.value, 1) # fp any more + + def write_real_errno(self, save_err): + if save_err & rffi.RFFI_READSAVED_ERRNO: + # Just before a call, read '*_errno' and write it into the + # real 'errno'. The x0-x7 registers contain arguments to the From pypy.commits at gmail.com Wed Jul 24 10:26:04 2019 From: pypy.commits at gmail.com (fijal) Date: Wed, 24 Jul 2019 07:26:04 -0700 (PDT) Subject: [pypy-commit] pypy default: threadlocalref get Message-ID: <5d386a7c.1c69fb81.5cc82.cae5@mx.google.com> Author: fijal Branch: Changeset: r97021:6885d94b89cf Date: 2019-07-24 16:25 +0200 http://bitbucket.org/pypy/pypy/changeset/6885d94b89cf/ Log: threadlocalref get diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -297,6 +297,16 @@ arg, res = arglocs self.mc.FSQRT_dd(res.value, arg.value) + def threadlocalref_get(self, op, arglocs): + res_loc, = arglocs + ofs_loc = self.imm(op.getarg(1).getint()) + calldescr = op.getdescr() + ofs = self.saved_threadlocal_addr + self.load_reg(self.mc, res_loc, r.sp, ofs) + scale = get_scale(calldescr.get_result_size()) + signed = (calldescr.is_result_signed() != 0) + self._load_from_mem(res_loc, res_loc, ofs_loc, scale, signed) + emit_op_float_lt = gen_float_comp_op('float_lt', c.VFP_LT) emit_op_float_le = gen_float_comp_op('float_le', c.VFP_LE) emit_op_float_eq = gen_float_comp_op('float_eq', c.EQ) diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -506,6 +506,10 @@ res = self.force_allocate_reg(op) return [loc1, res] + def _prepare_threadlocalref_get(self, op): + res_loc = self.force_allocate_reg(op) + return [res_loc] + prepare_op_convert_float_bytes_to_longlong = prepare_unary prepare_op_convert_longlong_bytes_to_float = prepare_unary @@ -583,10 +587,10 @@ args = self._prepare_op_math_sqrt(op) self.assembler.math_sqrt(op, args) return - #elif oopspecindex == EffectInfo.OS_THREADLOCALREF_GET: - # args = self._prepare_threadlocalref_get(op, fcond) - # self.perform_extra(op, args, fcond) - # return + elif oopspecindex == EffectInfo.OS_THREADLOCALREF_GET: + args = self._prepare_threadlocalref_get(op) + self.assembler.threadlocalref_get(op, args) + return #elif oopspecindex == EffectInfo.OS_MATH_READ_TIMESTAMP: # ... return self._prepare_call(op) From pypy.commits at gmail.com Wed Jul 24 10:40:54 2019 From: pypy.commits at gmail.com (Raemi) Date: Wed, 24 Jul 2019 07:40:54 -0700 (PDT) Subject: [pypy-commit] extradoc extradoc: trying to make the blog post a bit more appealing :) Message-ID: <5d386df6.1c69fb81.2742f.8e66@mx.google.com> Author: Remi Meier Branch: extradoc Changeset: r5954:925d7c1b0666 Date: 2019-07-24 16:40 +0200 http://bitbucket.org/pypy/extradoc/changeset/925d7c1b0666/ Log: trying to make the blog post a bit more appealing :) diff --git a/blog/draft/2019-07-arm64-relative.png b/blog/draft/2019-07-arm64-relative.png new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e9caaefc53af5bc4d6fcdb21d9b839b8dbb52d4b GIT binary patch [cut] diff --git a/blog/draft/2019-07-arm64-speedups.png b/blog/draft/2019-07-arm64-speedups.png new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..60de3896d627f6e54e2ac80d0163a74501c3f20a GIT binary patch [cut] diff --git a/blog/draft/2019-07-arm64.rst b/blog/draft/2019-07-arm64.rst --- a/blog/draft/2019-07-arm64.rst +++ b/blog/draft/2019-07-arm64.rst @@ -1,142 +1,60 @@ Hello everyone. -We are pleased to announce that we have successfully ported PyPy -to the AArch64 platform (also known as 64-bit ARM), thanks to funding -provided by ARM Holdings Ltd. and Crossbar.io. +We are pleased to announce the availability of the new PyPy for AArch64. This +port brings PyPy's high-performance just-in-time compiler to the AArch64 +platform, also known as 64-bit ARM. This work was funded by ARM Holdings Ltd. +and Crossbar.io. -We are presenting here the benchmark run done on a Graviton A1 machine -from AWS. There is a very serious word of warning: Graviton A1's are +To show how well the new PyPy port performs, we compare the performance of PyPy +against CPython on a set of benchmarks. As a point of comparison, we include the +results of PyPy on x86_64. Note, however, that the results presented here were +measured on a Graviton A1 machine from AWS, which comes with a very serious +word of warning: Graviton A1's are virtual machines and as such, are not suitable for benchmarking. If someone has access to a beefy enough (16G) ARM64 server and is willing to give us access to it, we are happy to redo the benchmarks on a real machine. -Our main concern here is that while a vCPU is 1-to-1 with a real CPU, it's +Our main concern here is that while a virtual CPU is 1-to-1 with a real CPU, it's not clear to us how caches are shared, and how they cross CPU boundaries. -We are not here interested in comparing machines, so what we are showing is -the relative speedup of PyPy (hg id 2417f925ce94) compared to CPython -(2.7.15). This is the "AArch64" column. In the "x86_64" column we do the -same on a Linux laptop running x86_64, comparing CPython 2.7.16 with the -most recent release, PyPy 7.1.1. +The following graph shows the speedup of PyPy (hg id 2417f925ce94) compared to +CPython (2.7.15) on AArch64, as well as the speedups on a x86_64 Linux laptop, +comparing the most recent release, PyPy 7.1.1, to CPython 2.7.16. -In the last column is a relative comparison between the ARM -architectures: how much the speedup is on arm64 vs. the same benchmark -on x86_64. One important thing to note is that by no means is this -suite a representative enough benchmark set for us to average together -results. Read the numbers individually per-benchmark. +.. image:: 2019-07-arm64-speedups.png -+------------------------------+----------+----------+----------+ -|*Benchmark name* |x86_64 |Aarch64 |relative | -+------------------------------+----------+----------+----------+ -|ai |5.66 |5.34 |0.94 | -+------------------------------+----------+----------+----------+ -|bm_chameleon |2.85 |6.57 |2.30 | -+------------------------------+----------+----------+----------+ -|bm_dulwich_log |1.98 |1.34 |0.68 | -+------------------------------+----------+----------+----------+ -|bm_krakatau |1.20 |0.69 |0.58 | -+------------------------------+----------+----------+----------+ -|bm_mako |4.88 |6.38 |1.31 | -+------------------------------+----------+----------+----------+ -|bm_mdp |0.82 |0.74 |0.90 | -+------------------------------+----------+----------+----------+ -|chaos |25.40 |25.52 |1.00 | -+------------------------------+----------+----------+----------+ -|crypto_pyaes |32.35 |31.92 |0.99 | -+------------------------------+----------+----------+----------+ -|deltablue |1.60 |1.48 |0.93 | -+------------------------------+----------+----------+----------+ -|django |14.15 |13.71 |0.97 | -+------------------------------+----------+----------+----------+ -|eparse |1.43 |1.12 |0.78 | -+------------------------------+----------+----------+----------+ -|fannkuch |4.83 |6.53 |1.35 | -+------------------------------+----------+----------+----------+ -|float |8.43 |8.16 |0.97 | -+------------------------------+----------+----------+----------+ -|genshi_text |3.70 |3.61 |0.98 | -+------------------------------+----------+----------+----------+ -|genshi_xml |2.97 |1.64 |0.55 | -+------------------------------+----------+----------+----------+ -|go |2.77 |2.47 |0.89 | -+------------------------------+----------+----------+----------+ -|hexiom2 |9.35 |8.03 |0.86 | -+------------------------------+----------+----------+----------+ -|html5lib |2.88 |1.93 |0.67 | -+------------------------------+----------+----------+----------+ -|json_bench |2.85 |2.81 |0.99 | -+------------------------------+----------+----------+----------+ -|meteor-contest |2.21 |2.27 |1.03 | -+------------------------------+----------+----------+----------+ -|nbody_modified |9.86 |8.59 |0.87 | -+------------------------------+----------+----------+----------+ -|nqueens |1.12 |1.02 |0.91 | -+------------------------------+----------+----------+----------+ -|pidigits |0.99 |0.62 |0.63 | -+------------------------------+----------+----------+----------+ -|pyflate-fast |3.86 |4.62 |1.20 | -+------------------------------+----------+----------+----------+ -|pypy_interp |2.12 |2.03 |0.95 | -+------------------------------+----------+----------+----------+ -|pyxl_bench |1.72 |1.37 |0.80 | -+------------------------------+----------+----------+----------+ -|raytrace-simple |58.86 |44.21 |0.75 | -+------------------------------+----------+----------+----------+ -|richards |52.68 |44.90 |0.85 | -+------------------------------+----------+----------+----------+ -|rietveld |1.52 |1.28 |0.84 | -+------------------------------+----------+----------+----------+ -|spambayes |1.87 |1.58 |0.85 | -+------------------------------+----------+----------+----------+ -|spectral-norm |21.38 |20.28 |0.95 | -+------------------------------+----------+----------+----------+ -|spitfire |1.28 |2.77 |2.17 | -+------------------------------+----------+----------+----------+ -|spitfire_cstringio |7.84 |7.42 |0.95 | -+------------------------------+----------+----------+----------+ -|sqlalchemy_declarative |1.76 |1.05 |0.60 | -+------------------------------+----------+----------+----------+ -|sqlalchemy_imperative |0.63 |0.60 |0.95 | -+------------------------------+----------+----------+----------+ -|sqlitesynth |1.17 |1.00 |0.86 | -+------------------------------+----------+----------+----------+ -|sympy_expand |1.32 |1.25 |0.95 | -+------------------------------+----------+----------+----------+ -|sympy_integrate |1.10 |1.01 |0.91 | -+------------------------------+----------+----------+----------+ -|sympy_str |0.65 |0.62 |0.95 | -+------------------------------+----------+----------+----------+ -|sympy_sum |1.87 |1.79 |0.96 | -+------------------------------+----------+----------+----------+ -|telco |30.38 |19.09 |0.63 | -+------------------------------+----------+----------+----------+ -|twisted_iteration |13.24 |8.95 |0.68 | -+------------------------------+----------+----------+----------+ -|twisted_names |5.27 |3.31 |0.63 | -+------------------------------+----------+----------+----------+ -|twisted_pb |5.85 |2.90 |0.50 | -+------------------------------+----------+----------+----------+ -|twisted_tcp |3.03 |2.08 |0.68 | -+------------------------------+----------+----------+----------+ +In the majority of benchmarks, the speedups achieved on AArch64 match those +achieved on the x86_64 laptop. Over CPython, PyPy on AArch64 achieves speedups +between 0.6x to 44.9x. These speedups are comparable to x86_64, where they are +between 0.6x and 58.9x. + +The next graph compares between the speedups achieved on AArch64 to the speedups +achieved on x86_64, i.e., how much the speedup is on AArch64 vs. the same +benchmark on x86_64. Note that by no means is this benchmark suite +representative enough to average the results. Read the numbers individually per +benchmark. + +.. image:: 2019-07-arm64-relative.png Note also that we see a wide variance. There are generally three groups of benchmarks - those that run at more or less the same speed, those that -run at 2x the speedup and those that run at 0.5x the speedup of x86_64. +run at 2x the speed and those that run at 0.5x the speed of x86_64. -The variance and disparity are likely related to a variety of issues, -mostly due to differences in architecture. What *is* however -interesting is that compared to older ARM boards, the branch predictor -has gotten a lot better, which means the speedups will be smaller: -"sophisticated" branchy code like CPython itself just runs a lot faster. +The variance and disparity are likely related to a variety of issues, mostly due +to differences in architecture. What *is* however interesting is that compared +to measurements performed on older ARM boards, the branch predictor on the +Graviton A1 machine appears to have improved. As a result, the speedups achieved +by PyPy over CPython are smaller: "sophisticated" branchy code, like CPython +itself, simply runs a lot faster. One takeaway here is that there is a lot of improvement left to be done in PyPy. This is true for both of the above platforms, but probably more so for AArch64, which comes with a large number of registers. The PyPy backend was written with x86 (the 32-bit variant) in mind, which is very register poor. We think we can improve somewhat in the area of emitting -more modern machine code, which should be more impactful for AArch64 -than x86_64. There are also still a few missing features in the AArch64 -backend, which are implemented as calls instead of inlined instructions, -which we hope to improve. +more modern machine code, which should have more impact for AArch64 +than for x86_64. There are also still a few missing features in the AArch64 +backend, which are implemented as calls instead of inlined instructions; +something we hope to improve. Best, Maciej Fijalkowski, Armin Rigo and the PyPy team From pypy.commits at gmail.com Wed Jul 24 11:17:55 2019 From: pypy.commits at gmail.com (rlamy) Date: Wed, 24 Jul 2019 08:17:55 -0700 (PDT) Subject: [pypy-commit] pypy apptest-file: hg merge default Message-ID: <5d3876a3.1c69fb81.409b9.9f6b@mx.google.com> Author: Ronan Lamy Branch: apptest-file Changeset: r97022:531d4c2e2b9e Date: 2019-07-24 16:16 +0100 http://bitbucket.org/pypy/pypy/changeset/531d4c2e2b9e/ Log: hg merge default diff too long, truncating to 2000 out of 37330 lines diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -10,10 +10,6 @@ 32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.3.1 10f1b29a2bd21f837090286174a9ca030b8680b2 release-2.5.0 9c4588d731b7fe0b08669bd732c2b676cb0a8233 release-2.5.1 -fcdb941565156385cbac04cfb891f8f4c7a92ef6 release-2.6.0 -fcdb941565156385cbac04cfb891f8f4c7a92ef6 release-2.6.0 -e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0 -e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0 295ee98b69288471b0fcf2e0ede82ce5209eb90b release-2.6.0 f3ad1e1e1d6215e20d34bb65ab85ff9188c9f559 release-2.6.1 850edf14b2c75573720f59e95767335fb1affe55 release-4.0.0 @@ -24,17 +20,10 @@ b0a649e90b6642251fb4a765fe5b27a97b1319a9 release-5.1.1 80ef432a32d9baa4b3c5a54c215e8ebe499f6374 release-5.1.2 40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2 -40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2 c09c19272c990a0611b17569a0085ad1ab00c8ff release-pypy2.7-v5.3 7e8df3df96417c16c2d55b41352ec82c9c69c978 release-pypy2.7-v5.3.1 -68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0 -68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0 77392ad263504df011ccfcabf6a62e21d04086d0 release-pypy2.7-v5.4.0 -050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1 -050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1 0e2d9a73f5a1818d0245d75daccdbe21b2d5c3ef release-pypy2.7-v5.4.1 -4909c06daf41ce88f87dc01c57959cadad4df4a8 RevDB-pypy2.7-v5.4.1 -4909c06daf41ce88f87dc01c57959cadad4df4a8 RevDB-pypy2.7-v5.4.1 d7724c0a5700b895a47de44074cdf5fd659a988f RevDB-pypy2.7-v5.4.1 aff251e543859ce4508159dd9f1a82a2f553de00 release-pypy2.7-v5.6.0 e90317857d27917bf840caf675832292ee070510 RevDB-pypy2.7-v5.6.1 @@ -45,25 +34,20 @@ 2875f328eae2216a87f3d6f335092832eb031f56 release-pypy3.5-v5.7.1 c925e73810367cd960a32592dd7f728f436c125c release-pypy2.7-v5.8.0 a37ecfe5f142bc971a86d17305cc5d1d70abec64 release-pypy3.5-v5.8.0 -03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0 d72f9800a42b46a8056951b1da2426d2c2d8d502 release-pypy3.5-v5.9.0 -03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0 84a2f3e6a7f88f2fe698e473998755b3bd1a12e2 release-pypy2.7-v5.9.0 0e7ea4fe15e82d5124e805e2e4a37cae1a402d4b release-pypy2.7-v5.10.0 -a91df6163fb76df245091f741dbf6a23ddc72374 release-pypy3.5-v5.10.0 -a91df6163fb76df245091f741dbf6a23ddc72374 release-pypy3.5-v5.10.0 -0000000000000000000000000000000000000000 release-pypy3.5-v5.10.0 -0000000000000000000000000000000000000000 release-pypy3.5-v5.10.0 09f9160b643e3f02ccb8c843b2fbb4e5cbf54082 release-pypy3.5-v5.10.0 3f6eaa010fce78cc7973bdc1dfdb95970f08fed2 release-pypy3.5-v5.10.1 ab0b9caf307db6592905a80b8faffd69b39005b8 release-pypy2.7-v6.0.0 fdd60ed87e941677e8ea11acf9f1819466521bf2 release-pypy3.5-v6.0.0 9112c8071614108b1042bfef0713915107004d62 release-pypy2.7-v7.0.0 1f86f25937b6ae6c8b25236c35228fac587678bf release-pypy3.5-v7.0.0 -dab365a465140aa79a5f3ba4db784c4af4d5c195 release-pypy3.6-v7.0.0 -9112c8071614108b1042bfef0713915107004d62 release-pypy2.7-v7.0.0 c8805ee6d7846ca2722b106eeaa2f128c699aba3 release-pypy2.7-v7.0.0 -1f86f25937b6ae6c8b25236c35228fac587678bf release-pypy3.5-v7.0.0 928a4f70d3de7d17449456946154c5da6e600162 release-pypy3.5-v7.0.0 -dab365a465140aa79a5f3ba4db784c4af4d5c195 release-pypy3.6-v7.0.0 fb40f7a5524c77b80e6c468e087d621610137261 release-pypy3.6-v7.0.0 +990cef41fe11e5d46b019a46aa956ff46ea1a234 release-pypy2.7-v7.1.0 +de061d87e39c7df4e436974096d7982c676a859d release-pypy3.6-v7.1.0 +784b254d669919c872a505b807db8462b6140973 release-pypy3.6-v7.1.1 +8cdda8b8cdb8ff29d9e620cccd6c5edd2f2a23ec release-pypy2.7-v7.1.1 + diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -110,6 +110,7 @@ Devin Jeanpierre Bob Ippolito Bruno Gola + Andrew Lawrence David Malcolm Squeaky Edd Barrett @@ -125,7 +126,6 @@ John Witulski Stefan Beyer Jeremy Thurgood - Andrew Lawrence Greg Price Ivan Sichmann Freitas Dario Bertini @@ -254,6 +254,7 @@ Omer Katz Jacek Generowicz Tomasz Dziopa + Lin Cheng Sylvain Thenault Jakub Stasiak Andrew Dalke @@ -403,6 +404,7 @@ Niclas Olofsson Chris Pressey Tobias Diaz + Paul Graydon Nikolaos-Digenis Karagiannis Kurt Griffiths Ben Mather diff --git a/extra_tests/cffi_tests/cffi0/backend_tests.py b/extra_tests/cffi_tests/cffi0/backend_tests.py --- a/extra_tests/cffi_tests/cffi0/backend_tests.py +++ b/extra_tests/cffi_tests/cffi0/backend_tests.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest import platform import sys, ctypes from cffi import FFI, CDefError, FFIError, VerificationMissing @@ -113,10 +114,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): ffi = FFI(backend=self.Backend()) @@ -141,18 +146,21 @@ ffi = FFI(backend=self.Backend()) p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -260,7 +268,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): ffi = FFI(backend=self.Backend()) @@ -387,7 +396,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -423,13 +433,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct foo*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -451,8 +463,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): ffi = FFI(backend=self.Backend()) @@ -512,11 +526,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union foo*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % SIZE_OF_INT def test_union_opaque(self): @@ -592,7 +608,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -616,7 +633,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -634,7 +652,8 @@ s = ffi.new("struct foo*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -658,18 +677,21 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # ffi.cdef("struct foo { void *p; int *q; short *r; };") s = ffi.new("struct foo *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) @@ -688,7 +710,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -913,10 +936,14 @@ assert s.e == 4294967295 assert s[0].e == 4294967295 s.e = s.e - py.test.raises(TypeError, "s.e = 'B'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) @@ -951,11 +978,14 @@ ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a, b; };") s = ffi.new("struct foo[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): ffi = FFI(backend=self.Backend()) @@ -1012,17 +1042,23 @@ assert ffi.sizeof("struct foo") == 8 s = ffi.new("struct foo *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1280,7 +1316,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): ffi = FFI(backend=self.Backend()) diff --git a/extra_tests/cffi_tests/cffi0/test_ffi_backend.py b/extra_tests/cffi_tests/cffi0/test_ffi_backend.py --- a/extra_tests/cffi_tests/cffi0/test_ffi_backend.py +++ b/extra_tests/cffi_tests/cffi0/test_ffi_backend.py @@ -130,6 +130,36 @@ alloc5 = ffi.new_allocator(myalloc5) py.test.raises(MemoryError, alloc5, "int[5]") + def test_new_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { int len[100]; short data[]; }; + struct bar_s { int abc[100]; struct foo_s tail; }; + """) + # loop to try to detect heap overwrites, if the size allocated + # is too small + for i in range(1, 501, 100): + p = ffi.new("struct bar_s *", [[10], [[20], [3,4,5,6,7,8,9] * i]]) + assert p.abc[0] == 10 + assert p.tail.len[0] == 20 + assert p.tail.data[0] == 3 + assert p.tail.data[6] == 9 + assert p.tail.data[7 * i - 1] == 9 + + def test_bogus_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { signed char len; signed char data[]; }; + struct bar_s { struct foo_s foo; int bcd; }; + """) + p = ffi.new("struct bar_s *", [[123, [45, 56, 67, 78]], 9999999]) + assert p.foo.len == 123 + assert p.foo.data[0] == 45 + assert p.foo.data[1] == 56 + assert p.foo.data[2] == 67 + assert p.bcd == 9999999 + assert p.foo.data[3] != 78 # has been overwritten with 9999999 + class TestBitfield: def check(self, source, expected_ofs_y, expected_align, expected_size): @@ -269,12 +299,15 @@ def test_error_cases(self): ffi = FFI() - py.test.raises(TypeError, - 'ffi.cdef("struct s1 { float x:1; };"); ffi.new("struct s1 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s2 { char x:0; };"); ffi.new("struct s2 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s3 { char x:9; };"); ffi.new("struct s3 *")') + ffi.cdef("struct s1 { float x:1; };") + with pytest.raises(TypeError): + ffi.new("struct s1 *") + ffi.cdef("struct s2 { char x:0; };") + with pytest.raises(TypeError): + ffi.new("struct s2 *") + ffi.cdef("struct s3 { char x:9; };") + with pytest.raises(TypeError): + ffi.new("struct s3 *") def test_struct_with_typedef(self): ffi = FFI() diff --git a/extra_tests/cffi_tests/cffi0/test_function.py b/extra_tests/cffi_tests/cffi0/test_function.py --- a/extra_tests/cffi_tests/cffi0/test_function.py +++ b/extra_tests/cffi_tests/cffi0/test_function.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest from cffi import FFI, CDefError import math, os, sys import ctypes.util @@ -91,7 +92,8 @@ """) m = ffi.dlopen(lib_m) assert m.FOOBAR == 42 - py.test.raises(NotImplementedError, "m.baz") + with pytest.raises(NotImplementedError): + m.baz def test_tlsalloc(self): if sys.platform != 'win32': diff --git a/extra_tests/cffi_tests/cffi0/test_parsing.py b/extra_tests/cffi_tests/cffi0/test_parsing.py --- a/extra_tests/cffi_tests/cffi0/test_parsing.py +++ b/extra_tests/cffi_tests/cffi0/test_parsing.py @@ -410,7 +410,17 @@ def test_enum(): ffi = FFI() ffi.cdef(""" - enum Enum { POS = +1, TWO = 2, NIL = 0, NEG = -1, OP = (POS+TWO)-1}; + enum Enum { + POS = +1, + TWO = 2, + NIL = 0, + NEG = -1, + ADDSUB = (POS+TWO)-1, + DIVMULINT = (3 * 3) / 2, + SHIFT = (1 << 3) >> 1, + BINOPS = (0x7 & 0x1) | 0x8, + XOR = 0xf ^ 0xa + }; """) needs_dlopen_none() C = ffi.dlopen(None) @@ -418,7 +428,11 @@ assert C.TWO == 2 assert C.NIL == 0 assert C.NEG == -1 - assert C.OP == 2 + assert C.ADDSUB == 2 + assert C.DIVMULINT == 4 + assert C.SHIFT == 4 + assert C.BINOPS == 0b1001 + assert C.XOR == 0b0101 def test_stdcall(): ffi = FFI() @@ -467,3 +481,40 @@ e = py.test.raises(CDefError, ffi.cdef, 'void foo(void) {}') assert str(e.value) == (':1: unexpected : ' 'this construct is valid C but not valid in cdef()') + +def test_unsigned_int_suffix_for_constant(): + ffi = FFI() + ffi.cdef("""enum e { + bin_0=0b10, + bin_1=0b10u, + bin_2=0b10U, + bin_3=0b10l, + bin_4=0b10L, + bin_5=0b10ll, + bin_6=0b10LL, + oct_0=010, + oct_1=010u, + oct_2=010U, + oct_3=010l, + oct_4=010L, + oct_5=010ll, + oct_6=010LL, + dec_0=10, + dec_1=10u, + dec_2=10U, + dec_3=10l, + dec_4=10L, + dec_5=10ll, + dec_6=10LL, + hex_0=0x10, + hex_1=0x10u, + hex_2=0x10U, + hex_3=0x10l, + hex_4=0x10L, + hex_5=0x10ll, + hex_6=0x10LL,};""") + needs_dlopen_none() + C = ffi.dlopen(None) + for base, expected_result in (('bin', 2), ('oct', 8), ('dec', 10), ('hex', 16)): + for index in range(7): + assert getattr(C, '{base}_{index}'.format(base=base, index=index)) == expected_result diff --git a/extra_tests/cffi_tests/cffi0/test_verify.py b/extra_tests/cffi_tests/cffi0/test_verify.py --- a/extra_tests/cffi_tests/cffi0/test_verify.py +++ b/extra_tests/cffi_tests/cffi0/test_verify.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py, re +import pytest import sys, os, math, weakref from cffi import FFI, VerificationError, VerificationMissing, model, FFIError from extra_tests.cffi_tests.support import * @@ -21,7 +22,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): def verify(self, *args, **kwds): @@ -590,7 +592,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -648,7 +651,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1464,8 +1468,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1533,7 +1539,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2099,6 +2106,11 @@ raise errors[0][1] def test_errno_working_even_with_pypys_jit(): + # NOTE: on some platforms, to work correctly, this test needs to be + # compiled with -pthread. Otherwise, the accesses to errno done from f() + # are compiled by assuming this small library won't be used from multiple + # threads, which is wrong. If you see failures _and_ if you pass your + # own CFLAGS environment variable, please make sure "-pthread" is in it. ffi = FFI() ffi.cdef("int f(int);") lib = ffi.verify(""" @@ -2523,3 +2535,29 @@ x.p = p x.cyclic = x del p, x + +def test_arithmetic_in_cdef(): + for a in [0, 11, 15]: + ffi = FFI() + ffi.cdef(""" + enum FOO { + DIVNN = ((-?) / (-3)), + DIVNP = ((-?) / (+3)), + DIVPN = ((+?) / (-3)), + MODNN = ((-?) % (-3)), + MODNP = ((-?) % (+3)), + MODPN = ((+?) % (-3)), + }; + """.replace('?', str(a))) + lib = ffi.verify(""" + enum FOO { + DIVNN = ((-?) / (-3)), + DIVNP = ((-?) / (+3)), + DIVPN = ((+?) / (-3)), + MODNN = ((-?) % (-3)), + MODNP = ((-?) % (+3)), + MODPN = ((+?) % (-3)), + }; + """.replace('?', str(a))) + # the verify() crashes if the values in the enum are different from + # the values we computed ourselves from the cdef() diff --git a/extra_tests/cffi_tests/cffi0/test_zintegration.py b/extra_tests/cffi_tests/cffi0/test_zintegration.py --- a/extra_tests/cffi_tests/cffi0/test_zintegration.py +++ b/extra_tests/cffi_tests/cffi0/test_zintegration.py @@ -2,11 +2,13 @@ import py, os, sys, shutil import subprocess from extra_tests.cffi_tests.udir import udir +import pytest if sys.platform == 'win32': - py.test.skip('snippets do not run on win32') + pytestmark = pytest.mark.skip('snippets do not run on win32') if sys.version_info < (2, 7): - py.test.skip('fails e.g. on a Debian/Ubuntu which patches virtualenv' + pytestmark = pytest.mark.skip( + 'fails e.g. on a Debian/Ubuntu which patches virtualenv' ' in a non-2.6-friendly way') def create_venv(name): diff --git a/extra_tests/cffi_tests/cffi1/test_ffi_obj.py b/extra_tests/cffi_tests/cffi1/test_ffi_obj.py --- a/extra_tests/cffi_tests/cffi1/test_ffi_obj.py +++ b/extra_tests/cffi_tests/cffi1/test_ffi_obj.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py, sys +import pytest import _cffi_backend as _cffi1_backend @@ -86,9 +87,12 @@ def test_ffi_no_attr(): ffi = _cffi1_backend.FFI() - py.test.raises(AttributeError, "ffi.no_such_name") - py.test.raises(AttributeError, "ffi.no_such_name = 42") - py.test.raises(AttributeError, "del ffi.no_such_name") + with pytest.raises(AttributeError): + ffi.no_such_name + with pytest.raises(AttributeError): + ffi.no_such_name = 42 + with pytest.raises(AttributeError): + del ffi.no_such_name def test_ffi_string(): ffi = _cffi1_backend.FFI() diff --git a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py --- a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py +++ b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest import platform, imp import sys, os, ctypes import cffi @@ -187,10 +188,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}" @@ -213,18 +218,21 @@ def test_new_array_varsize(self): p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -325,7 +333,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): p = ffi.new("int[3][2]", [[10, 11], [12, 13], [14, 15]]) @@ -446,7 +455,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -479,13 +489,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct simple*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -503,8 +515,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): py.test.raises(ffi.error, ffi.new, "struct baz*") @@ -556,11 +570,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union simple_u*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % ( SIZE_OF_INT,) @@ -626,7 +642,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -649,7 +666,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -665,7 +683,8 @@ s = ffi.new("struct string*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -686,17 +705,20 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # s = ffi.new("struct voidp *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) @@ -714,7 +736,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -923,10 +946,14 @@ assert s.e in (4294967295, -1) # two choices assert s[0].e in (4294967295, -1) s.e = s.e - py.test.raises(TypeError, "s.e = 'B3'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B3' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): # enum noncont { A4, B4=42, C4 }; @@ -948,11 +975,14 @@ def test_array_of_struct(self): s = ffi.new("struct ab[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): p = ffi.new("int(**)[5]") @@ -1001,17 +1031,23 @@ assert ffi.sizeof("struct bitfield") == 8 s = ffi.new("struct bitfield *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1236,7 +1272,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): assert ffi.getctype("int") == "int" @@ -1753,7 +1790,8 @@ assert MYFOO == 42 assert myfunc(43) == 44 assert myvar == -5 # but can't be changed, so not very useful - py.test.raises(ImportError, "from _test_import_from_lib.lib import bar") + with pytest.raises(ImportError): + from _test_import_from_lib.lib import bar d = {} exec("from _test_import_from_lib.lib import *", d) assert (set(key for key in d if not key.startswith('_')) == diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py b/extra_tests/cffi_tests/cffi1/test_recompiler.py --- a/extra_tests/cffi_tests/cffi1/test_recompiler.py +++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py @@ -1,6 +1,7 @@ # Generated by pypy/tool/import_cffi.py import sys, os, py +import pytest from cffi import FFI, VerificationError, FFIError, CDefError from cffi import recompiler from extra_tests.cffi_tests.udir import udir @@ -189,20 +190,26 @@ assert lib.a == -2 lib.a = -2147483648 assert lib.a == -2147483648 - py.test.raises(OverflowError, "lib.a = 2147483648") - py.test.raises(OverflowError, "lib.a = -2147483649") + with pytest.raises(OverflowError): + lib.a = 2147483648 + with pytest.raises(OverflowError): + lib.a = -2147483649 lib.b = 525 # try with the first access being in setattr, too assert lib.b == 525 - py.test.raises(AttributeError, "del lib.a") - py.test.raises(AttributeError, "del lib.c") - py.test.raises(AttributeError, "del lib.foobarbaz") + with pytest.raises(AttributeError): + del lib.a + with pytest.raises(AttributeError): + del lib.c + with pytest.raises(AttributeError): + del lib.foobarbaz def test_macro(): ffi = FFI() ffi.cdef("#define FOOBAR ...") lib = verify(ffi, 'test_macro', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_macro_check_value(): # the value '-0x80000000' in C sources does not have a clear meaning @@ -248,7 +255,8 @@ ffi.cdef("static const int FOOBAR;") lib = verify(ffi, 'test_constant', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_check_value_of_static_const(): ffi = FFI() @@ -264,7 +272,8 @@ ffi.cdef("static const double FOOBAR;") lib = verify(ffi, 'test_constant_nonint', "#define FOOBAR (-6912.5)") assert lib.FOOBAR == -6912.5 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_constant_ptr(): ffi = FFI() @@ -316,8 +325,10 @@ p = ffi.new("struct foo_s *", {'a': -32768, 'b': -2147483648}) assert p.a == -32768 assert p.b == -2147483648 - py.test.raises(OverflowError, "p.a -= 1") - py.test.raises(OverflowError, "p.b -= 1") + with pytest.raises(OverflowError): + p.a -= 1 + with pytest.raises(OverflowError): + p.b -= 1 q = ffi.new("struct bar_s *", {'f': p}) assert q.f == p # @@ -388,8 +399,10 @@ assert ffi.sizeof("struct foo_s") == (42 + 11) * 4 p = ffi.new("struct foo_s *") assert p.a[41] == p.b[10] == 0 - py.test.raises(IndexError, "p.a[42]") - py.test.raises(IndexError, "p.b[11]") + with pytest.raises(IndexError): + p.a[42] + with pytest.raises(IndexError): + p.b[11] def test_dotdotdot_global_array(): ffi = FFI() @@ -399,8 +412,10 @@ assert ffi.sizeof(lib.aa) == 41 * 4 assert ffi.sizeof(lib.bb) == 12 * 4 assert lib.aa[40] == lib.bb[11] == 0 - py.test.raises(IndexError, "lib.aa[41]") - py.test.raises(IndexError, "lib.bb[12]") + with pytest.raises(IndexError): + lib.aa[41] + with pytest.raises(IndexError): + lib.bb[12] def test_misdeclared_field_1(): ffi = FFI() @@ -1021,8 +1036,10 @@ assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int') assert s.a[4][7] == 0 - py.test.raises(IndexError, 's.a[4][8]') - py.test.raises(IndexError, 's.a[5][0]') + with pytest.raises(IndexError): + s.a[4][8] + with pytest.raises(IndexError): + s.a[5][0] assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.typeof(s.a[0]) == ffi.typeof("int[8]") @@ -1035,7 +1052,8 @@ s = ffi.new("struct foo_s *") assert ffi.typeof(s.a) == ffi.typeof("int[][7]") assert s.a[4][6] == 0 - py.test.raises(IndexError, 's.a[4][7]') + with pytest.raises(IndexError): + s.a[4][7] assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]") def test_global_var_array_2(): @@ -1044,8 +1062,10 @@ lib = verify(ffi, 'test_global_var_array_2', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][0]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][0] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1055,7 +1075,8 @@ lib = verify(ffi, 'test_global_var_array_3', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') + with pytest.raises(IndexError): + lib.a[0][8] assert ffi.typeof(lib.a) == ffi.typeof("int(*)[8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1065,8 +1086,10 @@ lib = verify(ffi, 'test_global_var_array_4', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][8]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][8] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1339,7 +1362,8 @@ #define aaa 42 """) assert lib.aaa == 42 - py.test.raises(AttributeError, "lib.aaa = 43") + with pytest.raises(AttributeError): + lib.aaa = 43 def test_win32_calling_convention_0(): ffi = FFI() @@ -2315,3 +2339,89 @@ typedef int foo_t; struct foo_s { void (*x)(foo_t); }; """) py.test.raises(TypeError, ffi.new, "struct foo_s *") + +def test_from_buffer_struct(): + ffi = FFI() + ffi.cdef("""struct foo_s { int a, b; };""") + lib = verify(ffi, "test_from_buffer_struct_p", """ + struct foo_s { int a, b; }; + """) + p = ffi.new("struct foo_s *", [-219239, 58974983]) + q = ffi.from_buffer("struct foo_s[]", ffi.buffer(p)) + assert ffi.typeof(q) == ffi.typeof("struct foo_s[]") + assert len(q) == 1 + assert q[0].a == p.a + assert q[0].b == p.b + assert q == p + q = ffi.from_buffer("struct foo_s *", ffi.buffer(p)) + assert ffi.typeof(q) == ffi.typeof("struct foo_s *") + assert q.a == p.a + assert q.b == p.b + assert q[0].a == p.a + assert q[0].b == p.b + assert q == p + +def test_unnamed_bitfield_1(): + ffi = FFI() + ffi.cdef("""struct A { char : 1; };""") + lib = verify(ffi, "test_unnamed_bitfield_1", """ + struct A { char : 1; }; + """) + p = ffi.new("struct A *") + assert ffi.sizeof(p[0]) == 1 + # Note: on gcc, the type name is ignored for anonymous bitfields + # and that's why the result is 1. On MSVC, the result is + # sizeof("char") which is also 1. + +def test_unnamed_bitfield_2(): + ffi = FFI() + ffi.cdef("""struct A { + short c : 1; short : 1; short d : 1; short : 1; };""") + lib = verify(ffi, "test_unnamed_bitfield_2", """ + struct A { + short c : 1; short : 1; short d : 1; short : 1; + }; + """) + p = ffi.new("struct A *") + assert ffi.sizeof(p[0]) == ffi.sizeof("short") + +def test_unnamed_bitfield_3(): + ffi = FFI() + ffi.cdef("""struct A { struct { char : 1; char : 1; } b; };""") + lib = verify(ffi, "test_unnamed_bitfield_3", """ + struct A { struct { char : 1; char : 1; } b; }; + """) + p = ffi.new("struct A *") + assert ffi.sizeof(p[0]) == 1 + # Note: on gcc, the type name is ignored for anonymous bitfields + # and that's why the result is 1. On MSVC, the result is + # sizeof("char") which is also 1. + +def test_unnamed_bitfield_4(): + ffi = FFI() + ffi.cdef("""struct A { struct { + unsigned c : 1; unsigned : 1; unsigned d : 1; unsigned : 1; } a; + }; + struct B { struct A a; };""") + lib = verify(ffi, "test_unnamed_bitfield_4", """ + struct A { struct { + unsigned c : 1; unsigned : 1; unsigned d : 1; unsigned : 1; } a; + }; + struct B { struct A a; }; + """) + b = ffi.new("struct B *") + a = ffi.new("struct A *") + assert ffi.sizeof(a[0]) == ffi.sizeof("unsigned") + assert ffi.sizeof(b[0]) == ffi.sizeof(a[0]) + +def test_struct_with_func_with_struct_arg(): + ffi = FFI() + ffi.cdef("""struct BinaryTree { + int (* CompareKey)(struct BinaryTree tree); + };""") + lib = verify(ffi, "test_struct_with_func_with_struct_arg", """ + struct BinaryTree { + int (* CompareKey)(struct BinaryTree tree); + }; + """) + py.test.raises(RuntimeError, ffi.new, "struct BinaryTree *") diff --git a/extra_tests/cffi_tests/cffi1/test_verify1.py b/extra_tests/cffi_tests/cffi1/test_verify1.py --- a/extra_tests/cffi_tests/cffi1/test_verify1.py +++ b/extra_tests/cffi_tests/cffi1/test_verify1.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import os, sys, math, py +import pytest from cffi import FFI, FFIError, VerificationError, VerificationMissing, model from cffi import CDefError from cffi import recompiler @@ -23,7 +24,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): error = _cffi_backend.FFI.error @@ -572,7 +574,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -630,7 +633,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1434,8 +1438,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1503,7 +1509,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2194,7 +2201,8 @@ ffi = FFI() ffi.cdef("#define FOO 123") lib = ffi.verify("#define FOO 124") # used to complain - e = py.test.raises(ffi.error, "lib.FOO") + with pytest.raises(ffi.error) as e: + lib.FOO assert str(e.value) == ("the C compiler says 'FOO' is equal to 124 (0x7c)," " but the cdef disagrees") diff --git a/extra_tests/cffi_tests/embedding/test_basic.py b/extra_tests/cffi_tests/embedding/test_basic.py --- a/extra_tests/cffi_tests/embedding/test_basic.py +++ b/extra_tests/cffi_tests/embedding/test_basic.py @@ -64,8 +64,8 @@ output = popen.stdout.read() err = popen.wait() if err: - raise OSError("popen failed with exit code %r: %r" % ( - err, args)) + raise OSError(("popen failed with exit code %r: %r\n\n%s" % ( + err, args, output)).rstrip()) print(output.rstrip()) return output @@ -173,7 +173,8 @@ result = popen.stdout.read() err = popen.wait() if err: - raise OSError("%r failed with exit code %r" % (name, err)) + raise OSError("%r failed with exit code %r" % ( + os.path.join(path, executable_name), err)) return result diff --git a/extra_tests/cffi_tests/embedding/test_performance.py b/extra_tests/cffi_tests/embedding/test_performance.py --- a/extra_tests/cffi_tests/embedding/test_performance.py +++ b/extra_tests/cffi_tests/embedding/test_performance.py @@ -3,8 +3,8 @@ from extra_tests.cffi_tests.embedding.test_basic import EmbeddingTests if sys.platform == 'win32': - import py - py.test.skip("written with POSIX functions") + import pytest + pytestmark = pytest.mark.skip("written with POSIX functions") class TestPerformance(EmbeddingTests): diff --git a/lib-python/2.7/ctypes/test/test_byteswap.py b/lib-python/2.7/ctypes/test/test_byteswap.py --- a/lib-python/2.7/ctypes/test/test_byteswap.py +++ b/lib-python/2.7/ctypes/test/test_byteswap.py @@ -2,7 +2,6 @@ from binascii import hexlify from ctypes import * -from ctypes.test import xfail def bin(s): return hexlify(memoryview(s)).upper() diff --git a/lib-python/2.7/ctypes/test/test_loading.py b/lib-python/2.7/ctypes/test/test_loading.py --- a/lib-python/2.7/ctypes/test/test_loading.py +++ b/lib-python/2.7/ctypes/test/test_loading.py @@ -2,7 +2,7 @@ import sys, unittest import os from ctypes.util import find_library -from ctypes.test import is_resource_enabled, xfail +from ctypes.test import is_resource_enabled libc_name = None if os.name == "nt": @@ -80,7 +80,6 @@ self.assertRaises(AttributeError, dll.__getitem__, 1234) - @xfail @unittest.skipUnless(os.name == "nt", 'Windows-specific test') def test_1703286_A(self): from _ctypes import LoadLibrary, FreeLibrary @@ -92,7 +91,6 @@ handle = LoadLibrary("advapi32") FreeLibrary(handle) - @xfail @unittest.skipUnless(os.name == "nt", 'Windows-specific test') def test_1703286_B(self): # Since on winXP 64-bit advapi32 loads like described diff --git a/lib-python/2.7/distutils/sysconfig_pypy.py b/lib-python/2.7/distutils/sysconfig_pypy.py --- a/lib-python/2.7/distutils/sysconfig_pypy.py +++ b/lib-python/2.7/distutils/sysconfig_pypy.py @@ -71,7 +71,7 @@ g['AR'] = "ar" g['ARFLAGS'] = "rc" g['EXE'] = "" - g['LIBDIR'] = os.path.join(sys.prefix, 'lib') + g['LIBDIR'] = os.path.join(sys.prefix, 'bin') # where is the shared library g['VERSION'] = get_python_version() if sys.platform[:6] == "darwin": @@ -86,6 +86,7 @@ arch = platform.machine() g['LDSHARED'] += ' -undefined dynamic_lookup' g['CC'] += ' -arch %s' % (arch,) + g['MACOSX_DEPLOYMENT_TARGET'] = '10.14' global _config_vars _config_vars = g diff --git a/lib-python/2.7/socket.py b/lib-python/2.7/socket.py --- a/lib-python/2.7/socket.py +++ b/lib-python/2.7/socket.py @@ -61,20 +61,22 @@ DeprecationWarning, stacklevel=2) return _realssl.sslwrap_simple(sock, keyfile, certfile) - # we need to import the same constants we used to... - from _ssl import SSLError as sslerror - from _ssl import \ - RAND_add, \ - RAND_status, \ - SSL_ERROR_ZERO_RETURN, \ - SSL_ERROR_WANT_READ, \ - SSL_ERROR_WANT_WRITE, \ - SSL_ERROR_WANT_X509_LOOKUP, \ - SSL_ERROR_SYSCALL, \ - SSL_ERROR_SSL, \ - SSL_ERROR_WANT_CONNECT, \ - SSL_ERROR_EOF, \ - SSL_ERROR_INVALID_ERROR_CODE + # we need to import the same constants we used to, + # see lib_pypy/_cffi_ssl/_stdssl/error.py and __init__.py to prevent + # circular import + # from _ssl import SSLError as sslerror + # from _ssl import \ + # RAND_add, \ + # RAND_status + # SSL_ERROR_ZERO_RETURN, \ + # SSL_ERROR_WANT_READ, \ + # SSL_ERROR_WANT_WRITE, \ + # SSL_ERROR_WANT_X509_LOOKUP, \ + # SSL_ERROR_SYSCALL, \ + # SSL_ERROR_SSL, \ + # SSL_ERROR_WANT_CONNECT, \ + # SSL_ERROR_EOF, \ + # SSL_ERROR_INVALID_ERROR_CODE try: from _ssl import RAND_egd except ImportError: diff --git a/lib-python/2.7/sysconfig.py b/lib-python/2.7/sysconfig.py --- a/lib-python/2.7/sysconfig.py +++ b/lib-python/2.7/sysconfig.py @@ -483,6 +483,7 @@ _CONFIG_VARS['projectbase'] = _PROJECT_BASE _CONFIG_VARS['implementation'] = _get_implementation() _CONFIG_VARS['implementation_lower'] = _get_implementation().lower() + _CONFIG_VARS['LIBRARY'] = '' if os.name in ('nt', 'os2'): _init_non_posix(_CONFIG_VARS) diff --git a/lib-python/2.7/test/capath/efa5f9c3.0 b/lib-python/2.7/test/capath/efa5f9c3.0 new file mode 100644 --- /dev/null +++ b/lib-python/2.7/test/capath/efa5f9c3.0 @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF9zCCA9+gAwIBAgIUH98b4Fw/DyugC9cV7VK7ZODzHsIwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAlhZMRcwFQYDVQQIDA5DYXN0bGUgQW50aHJheDEYMBYG +A1UEBwwPQXJndW1lbnQgQ2xpbmljMSMwIQYDVQQKDBpQeXRob24gU29mdHdhcmUg +Rm91bmRhdGlvbjEjMCEGA1UEAwwac2VsZi1zaWduZWQucHl0aG9udGVzdC5uZXQw +HhcNMTkwNTA4MDEwMjQzWhcNMjcwNzI0MDEwMjQzWjCBijELMAkGA1UEBhMCWFkx +FzAVBgNVBAgMDkNhc3RsZSBBbnRocmF4MRgwFgYDVQQHDA9Bcmd1bWVudCBDbGlu +aWMxIzAhBgNVBAoMGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMSMwIQYDVQQD +DBpzZWxmLXNpZ25lZC5weXRob250ZXN0Lm5ldDCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAMKdJlyCThkahwoBb7pl5q64Pe9Fn5jrIvzsveHTc97TpjV2 +RLfICnXKrltPk/ohkVl6K5SUZQZwMVzFubkyxE0nZPHYHlpiKWQxbsYVkYv01rix +IFdLvaxxbGYke2jwQao31s4o61AdlsfK1SdpHQUynBBMssqI3SB4XPmcA7e+wEEx +jxjVish4ixA1vuIZOx8yibu+CFCf/geEjoBMF3QPdzULzlrCSw8k/45iZCSoNbvK +DoL4TVV07PHOxpheDh8ZQmepGvU6pVqhb9m4lgmV0OGWHgozd5Ur9CbTVDmxIEz3 +TSoRtNJK7qtyZdGNqwjksQxgZTjM/d/Lm/BJG99AiOmYOjsl9gbQMZgvQmMAtUsI +aMJnQuZ6R+KEpW/TR5qSKLWZSG45z/op+tzI2m+cE6HwTRVAWbcuJxcAA55MZjqU +OOOu3BBYMjS5nf2sQ9uoXsVBFH7i0mQqoW1SLzr9opI8KsWwFxQmO2vBxWYaN+lH +OmwBZBwyODIsmI1YGXmTp09NxRYz3Qe5GCgFzYowpMrcxUC24iduIdMwwhRM7rKg +7GtIWMSrFfuI1XCLRmSlhDbhNN6fVg2f8Bo9PdH9ihiIyxSrc+FOUasUYCCJvlSZ +8hFUlLvcmrZlWuazohm0lsXuMK1JflmQr/DA/uXxP9xzFfRy+RU3jDyxJbRHAgMB +AAGjUzBRMB0GA1UdDgQWBBSQJyxiPMRK01i+0BsV9zUwDiBaHzAfBgNVHSMEGDAW +gBSQJyxiPMRK01i+0BsV9zUwDiBaHzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4ICAQCR+7a7N/m+WLkxPPIA/CB4MOr2Uf8ixTv435Nyv6rXOun0+lTP +ExSZ0uYQ+L0WylItI3cQHULldDueD+s8TGzxf5woaLKf6tqyr0NYhKs+UeNEzDnN +9PHQIhX0SZw3XyXGUgPNBfRCg2ZDdtMMdOU4XlQN/IN/9hbYTrueyY7eXq9hmtI9 +1srftAMqr9SR1JP7aHI6DVgrEsZVMTDnfT8WmLSGLlY1HmGfdEn1Ip5sbo9uSkiH +AEPgPfjYIvR5LqTOMn4KsrlZyBbFIDh9Sl99M1kZzgH6zUGVLCDg1y6Cms69fx/e +W1HoIeVkY4b4TY7Bk7JsqyNhIuqu7ARaxkdaZWhYaA2YyknwANdFfNpfH+elCLIk +BUt5S3f4i7DaUePTvKukCZiCq4Oyln7RcOn5If73wCeLB/ZM9Ei1HforyLWP1CN8 +XLfpHaoeoPSWIveI0XHUl65LsPN2UbMbul/F23hwl+h8+BLmyAS680Yhn4zEN6Ku +B7Po90HoFa1Du3bmx4jsN73UkT/dwMTi6K072FbipnC1904oGlWmLwvAHvrtxxmL +Pl3pvEaZIu8wa/PNF6Y7J7VIewikIJq6Ta6FrWeFfzMWOj2qA1ZZi6fUaDSNYvuV +J5quYKCc/O+I/yDDf8wyBbZ/gvUXzUHTMYGG+bFrn1p7XDbYYeEJ6R/xEg== +-----END CERTIFICATE----- diff --git a/lib-python/2.7/test/selfsigned_pythontestdotnet.pem b/lib-python/2.7/test/selfsigned_pythontestdotnet.pem --- a/lib-python/2.7/test/selfsigned_pythontestdotnet.pem +++ b/lib-python/2.7/test/selfsigned_pythontestdotnet.pem @@ -1,16 +1,34 @@ -----BEGIN CERTIFICATE----- -MIIClTCCAf6gAwIBAgIJAKGU95wKR8pTMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV -BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u -IFNvZnR3YXJlIEZvdW5kYXRpb24xIzAhBgNVBAMMGnNlbGYtc2lnbmVkLnB5dGhv -bnRlc3QubmV0MB4XDTE0MTEwMjE4MDkyOVoXDTI0MTAzMDE4MDkyOVowcDELMAkG -A1UEBhMCWFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMwIQYDVQQKDBpQeXRo -b24gU29mdHdhcmUgRm91bmRhdGlvbjEjMCEGA1UEAwwac2VsZi1zaWduZWQucHl0 -aG9udGVzdC5uZXQwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANDXQXW9tjyZ -Xt0Iv2tLL1+jinr4wGg36ioLDLFkMf+2Y1GL0v0BnKYG4N1OKlAU15LXGeGer8vm -Sv/yIvmdrELvhAbbo3w4a9TMYQA4XkIVLdvu3mvNOAet+8PMJxn26dbDhG809ALv -EHY57lQsBS3G59RZyBPVqAqmImWNJnVzAgMBAAGjNzA1MCUGA1UdEQQeMByCGnNl -bGYtc2lnbmVkLnB5dGhvbnRlc3QubmV0MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN -AQEFBQADgYEAIuzAhgMouJpNdf3URCHIineyoSt6WK/9+eyUcjlKOrDoXNZaD72h -TXMeKYoWvJyVcSLKL8ckPtDobgP2OTt0UkyAaj0n+ZHaqq1lH2yVfGUA1ILJv515 -C8BqbvVZuqm3i7ygmw3bqE/lYMgOrYtXXnqOrz6nvsE6Yc9V9rFflOM= +MIIF9zCCA9+gAwIBAgIUH98b4Fw/DyugC9cV7VK7ZODzHsIwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAlhZMRcwFQYDVQQIDA5DYXN0bGUgQW50aHJheDEYMBYG +A1UEBwwPQXJndW1lbnQgQ2xpbmljMSMwIQYDVQQKDBpQeXRob24gU29mdHdhcmUg +Rm91bmRhdGlvbjEjMCEGA1UEAwwac2VsZi1zaWduZWQucHl0aG9udGVzdC5uZXQw +HhcNMTkwNTA4MDEwMjQzWhcNMjcwNzI0MDEwMjQzWjCBijELMAkGA1UEBhMCWFkx +FzAVBgNVBAgMDkNhc3RsZSBBbnRocmF4MRgwFgYDVQQHDA9Bcmd1bWVudCBDbGlu +aWMxIzAhBgNVBAoMGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMSMwIQYDVQQD +DBpzZWxmLXNpZ25lZC5weXRob250ZXN0Lm5ldDCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAMKdJlyCThkahwoBb7pl5q64Pe9Fn5jrIvzsveHTc97TpjV2 +RLfICnXKrltPk/ohkVl6K5SUZQZwMVzFubkyxE0nZPHYHlpiKWQxbsYVkYv01rix +IFdLvaxxbGYke2jwQao31s4o61AdlsfK1SdpHQUynBBMssqI3SB4XPmcA7e+wEEx +jxjVish4ixA1vuIZOx8yibu+CFCf/geEjoBMF3QPdzULzlrCSw8k/45iZCSoNbvK +DoL4TVV07PHOxpheDh8ZQmepGvU6pVqhb9m4lgmV0OGWHgozd5Ur9CbTVDmxIEz3 +TSoRtNJK7qtyZdGNqwjksQxgZTjM/d/Lm/BJG99AiOmYOjsl9gbQMZgvQmMAtUsI +aMJnQuZ6R+KEpW/TR5qSKLWZSG45z/op+tzI2m+cE6HwTRVAWbcuJxcAA55MZjqU +OOOu3BBYMjS5nf2sQ9uoXsVBFH7i0mQqoW1SLzr9opI8KsWwFxQmO2vBxWYaN+lH +OmwBZBwyODIsmI1YGXmTp09NxRYz3Qe5GCgFzYowpMrcxUC24iduIdMwwhRM7rKg +7GtIWMSrFfuI1XCLRmSlhDbhNN6fVg2f8Bo9PdH9ihiIyxSrc+FOUasUYCCJvlSZ +8hFUlLvcmrZlWuazohm0lsXuMK1JflmQr/DA/uXxP9xzFfRy+RU3jDyxJbRHAgMB +AAGjUzBRMB0GA1UdDgQWBBSQJyxiPMRK01i+0BsV9zUwDiBaHzAfBgNVHSMEGDAW +gBSQJyxiPMRK01i+0BsV9zUwDiBaHzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4ICAQCR+7a7N/m+WLkxPPIA/CB4MOr2Uf8ixTv435Nyv6rXOun0+lTP +ExSZ0uYQ+L0WylItI3cQHULldDueD+s8TGzxf5woaLKf6tqyr0NYhKs+UeNEzDnN +9PHQIhX0SZw3XyXGUgPNBfRCg2ZDdtMMdOU4XlQN/IN/9hbYTrueyY7eXq9hmtI9 +1srftAMqr9SR1JP7aHI6DVgrEsZVMTDnfT8WmLSGLlY1HmGfdEn1Ip5sbo9uSkiH +AEPgPfjYIvR5LqTOMn4KsrlZyBbFIDh9Sl99M1kZzgH6zUGVLCDg1y6Cms69fx/e +W1HoIeVkY4b4TY7Bk7JsqyNhIuqu7ARaxkdaZWhYaA2YyknwANdFfNpfH+elCLIk +BUt5S3f4i7DaUePTvKukCZiCq4Oyln7RcOn5If73wCeLB/ZM9Ei1HforyLWP1CN8 +XLfpHaoeoPSWIveI0XHUl65LsPN2UbMbul/F23hwl+h8+BLmyAS680Yhn4zEN6Ku +B7Po90HoFa1Du3bmx4jsN73UkT/dwMTi6K072FbipnC1904oGlWmLwvAHvrtxxmL +Pl3pvEaZIu8wa/PNF6Y7J7VIewikIJq6Ta6FrWeFfzMWOj2qA1ZZi6fUaDSNYvuV +J5quYKCc/O+I/yDDf8wyBbZ/gvUXzUHTMYGG+bFrn1p7XDbYYeEJ6R/xEg== -----END CERTIFICATE----- diff --git a/lib-python/2.7/test/test_ftplib.py b/lib-python/2.7/test/test_ftplib.py --- a/lib-python/2.7/test/test_ftplib.py +++ b/lib-python/2.7/test/test_ftplib.py @@ -234,11 +234,17 @@ def run(self): self.active = True self.__flag.set() - while self.active and asyncore.socket_map: - self.active_lock.acquire() - asyncore.loop(timeout=0.1, count=1) - self.active_lock.release() - asyncore.close_all(ignore_all=True) + try: + while self.active and asyncore.socket_map: + self.active_lock.acquire() + try: + asyncore.loop(timeout=0.1, count=1) + except: + self.active_lock.release() + raise + self.active_lock.release() + finally: + asyncore.close_all(ignore_all=True) def stop(self): assert self.active diff --git a/lib-python/2.7/test/test_ssl.py b/lib-python/2.7/test/test_ssl.py --- a/lib-python/2.7/test/test_ssl.py +++ b/lib-python/2.7/test/test_ssl.py @@ -764,12 +764,17 @@ ctx.set_ciphers("^$:,;?*'dorothyx") @skip_if_broken_ubuntu_ssl - def test_options(self): + def _test_options(self): + ''' + Disable this test, it is too flaky. Different platforms define + different defaults + ''' ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value default = (ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3) if not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0): default |= ssl.OP_NO_COMPRESSION + default |= ssl.OP_ENABLE_MIDDLEBOX_COMPAT self.assertEqual(default, ctx.options) ctx.options |= ssl.OP_NO_TLSv1 self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options) diff --git a/lib-python/2.7/test/test_sys.py b/lib-python/2.7/test/test_sys.py --- a/lib-python/2.7/test/test_sys.py +++ b/lib-python/2.7/test/test_sys.py @@ -216,6 +216,11 @@ raise ValueError() except ValueError, e: pass + except MemoryError: + # Documentation for setrecursionlimit says: "The highest possible + # limit is platform-dependent. ... a too-high limit can lead to a + # crash" so we allow MemoryError here + pass finally: sys.setrecursionlimit(oldlimit) diff --git a/lib-python/2.7/test/test_timeit.py b/lib-python/2.7/test/test_timeit.py --- a/lib-python/2.7/test/test_timeit.py +++ b/lib-python/2.7/test/test_timeit.py @@ -317,9 +317,9 @@ def test_main_recommends_perf(self): s = self.run_main(seconds_per_increment=2.0, switches=['-n35', '-s', 'print("CustomSetup")']) self.assertIn(dedent("""\ - WARNING: timeit is a very unreliable tool. use perf or something else for real measurements + WARNING: timeit is a very unreliable tool. use pyperf or something else for real measurements """), s) - self.assertIn("-m pip install perf", s) + self.assertIn("-m pip install pyperf", s) diff --git a/lib-python/2.7/test/test_unicode.py b/lib-python/2.7/test/test_unicode.py --- a/lib-python/2.7/test/test_unicode.py +++ b/lib-python/2.7/test/test_unicode.py @@ -1652,10 +1652,10 @@ # when a string allocation fails with a MemoryError. # This used to crash the interpreter, # or leak references when the number was smaller. - charwidth = 4 if sys.maxunicode >= 0x10000 else 2 + charwidth = 2 # pypy: the char \u0123 is stored in two utf-8 bytes # Note: sys.maxsize is half of the actual max allocation because of # the signedness of Py_ssize_t. - alloc = lambda: u"a" * (sys.maxsize // charwidth * 2) + alloc = lambda: u"\u0123" * (sys.maxsize // charwidth * 2) self.assertRaises(MemoryError, alloc) self.assertRaises(MemoryError, alloc) diff --git a/lib-python/2.7/timeit.py b/lib-python/2.7/timeit.py --- a/lib-python/2.7/timeit.py +++ b/lib-python/2.7/timeit.py @@ -308,10 +308,10 @@ return 0 setup = "\n".join(setup) or "pass" - print "WARNING: timeit is a very unreliable tool. use perf or something else for real measurements" + print "WARNING: timeit is a very unreliable tool. use pyperf or something else for real measurements" executable = os.path.basename(sys.executable) - print "%s -m pip install perf" % executable - print "%s -m perf timeit %s" % ( + print "%s -m pip install pyperf" % executable + print "%s -m pyperf timeit %s" % ( executable, " ".join([(arg if arg.startswith("-") else repr(arg)) for arg in origargs]), ) diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -176,7 +176,7 @@ RegrTest('test_copy_reg.py', core=True), RegrTest('test_cpickle.py', core=True), RegrTest('test_cprofile.py'), - RegrTest('test_crypt.py', usemodules='crypt'), + RegrTest('test_crypt.py'), RegrTest('test_csv.py', usemodules='_csv'), RegrTest('test_ctypes.py', usemodules="_rawffi thread cpyext"), RegrTest('test_curses.py'), @@ -401,7 +401,7 @@ RegrTest('test_source_encoding.py'), RegrTest('test_spwd.py'), RegrTest('test_sqlite.py', usemodules="thread _rawffi zlib"), - RegrTest('test_ssl.py', usemodules='_ssl _socket select'), + RegrTest('test_ssl.py', usemodules='_socket select'), RegrTest('test_startfile.py'), RegrTest('test_stat.py'), RegrTest('test_str.py', core=True), diff --git a/lib_pypy/_cffi_ssl/LICENSE b/lib_pypy/_cffi_ssl/LICENSE new file mode 100644 --- /dev/null +++ b/lib_pypy/_cffi_ssl/LICENSE @@ -0,0 +1,26 @@ + +Except when otherwise stated (look for LICENSE files in directories or +information at the beginning of each file) all software and +documentation is licensed as follows: + + The MIT License + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + diff --git a/lib_pypy/_cffi_ssl/README.md b/lib_pypy/_cffi_ssl/README.md new file mode 100644 --- /dev/null +++ b/lib_pypy/_cffi_ssl/README.md @@ -0,0 +1,35 @@ +# PyPy's SSL module + +All of the CFFI code is copied from cryptography, wich patches contributed +back to cryptography. PyPy vendors it's own copy of the cffi backend thus +it renames the compiled shared object to _pypy_openssl.so (which means +that cryptography can ship their own cffi backend) + +NOTE: currently, we have the following changes: + +* ``_cffi_src/openssl/callbacks.py`` to not rely on the CPython C API + (this change is now backported) + +* ``_cffi_src/utils.py`` for issue #2575 (29c9a89359e4) + +* ``_cffi_src/openssl/x509_vfy.py`` for issue #2605 (ca4d0c90f5a1) + +* ``_cffi_src/openssl/pypy_win32_extra.py`` for Win32-only functionality like ssl.enum_certificates() + + +# Tests? + +Currently this module is tested using CPython's standard library test suite. + +# Install it into PyPy's source tree + +Copy over all the sources into the folder `lib_pypy/_cffi_ssl/*`. Updating the cffi backend can be simply done by the following command:: + + $ cp -r /src/_cffi_src/* . + +NOTE: you need to keep our version of ``_cffi_src/openssl/callbacks.py`` +for now! + +# Crpytography version + +Copied over release version `1.7.2` diff --git a/lib_pypy/_cffi_ssl/__init__.py b/lib_pypy/_cffi_ssl/__init__.py new file mode 100644 diff --git a/lib_pypy/_cffi_ssl/_cffi_src/__init__.py b/lib_pypy/_cffi_ssl/_cffi_src/__init__.py new file mode 100644 diff --git a/lib_pypy/_cffi_ssl/_cffi_src/build_commoncrypto.py b/lib_pypy/_cffi_ssl/_cffi_src/build_commoncrypto.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_cffi_ssl/_cffi_src/build_commoncrypto.py @@ -0,0 +1,33 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import absolute_import, division, print_function + +from _cffi_src.utils import build_ffi_for_binding + + +ffi = build_ffi_for_binding( + module_name="_commoncrypto", + module_prefix="_cffi_src.commoncrypto.", + modules=[ + "cf", + "common_digest", + "common_hmac", + "common_key_derivation", + "common_cryptor", + "common_symmetric_key_wrap", + "seccertificate", + "secimport", + "secitem", + "seckey", + "seckeychain", + "secpolicy", + "sectransform", + "sectrust", + "secure_transport", + ], + extra_link_args=[ + "-framework", "Security", "-framework", "CoreFoundation" + ], +) diff --git a/lib_pypy/_cffi_ssl/_cffi_src/build_constant_time.py b/lib_pypy/_cffi_ssl/_cffi_src/build_constant_time.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_cffi_ssl/_cffi_src/build_constant_time.py @@ -0,0 +1,27 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import absolute_import, division, print_function + +import os + +from _cffi_src.utils import build_ffi, compiler_type, extra_link_args + + +with open(os.path.join( + os.path.dirname(__file__), "hazmat_src/constant_time.h" +)) as f: + types = f.read() + +with open(os.path.join( + os.path.dirname(__file__), "hazmat_src/constant_time.c" +)) as f: + functions = f.read() + +ffi = build_ffi( + module_name="_constant_time", + cdef_source=types, + verify_source=functions, + extra_link_args=extra_link_args(compiler_type()), +) diff --git a/lib_pypy/_cffi_ssl/_cffi_src/build_openssl.py b/lib_pypy/_cffi_ssl/_cffi_src/build_openssl.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_cffi_ssl/_cffi_src/build_openssl.py @@ -0,0 +1,86 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import absolute_import, division, print_function + +import os +import sys + +from _cffi_src.utils import ( + build_ffi_for_binding, compiler_type, extra_link_args +) + + +def _get_openssl_libraries(platform): + # OpenSSL goes by a different library name on different operating systems. + if platform == "darwin": + return _osx_libraries( + os.environ.get("CRYPTOGRAPHY_OSX_NO_LINK_FLAGS") + ) + elif platform == "win32": + if compiler_type() == "msvc": + libs = ["libeay32", "ssleay32"] + else: + libs = ["ssl", "crypto"] + return libs + ["advapi32", "crypt32", "gdi32", "user32", "ws2_32"] + else: + # In some circumstances, the order in which these libs are + # specified on the linker command-line is significant; + # libssl must come before libcrypto + # (http://marc.info/?l=openssl-users&m=135361825921871) + return ["ssl", "crypto"] + + +def _osx_libraries(build_static): + # For building statically we don't want to pass the -lssl or -lcrypto flags + if build_static == "1": + return [] + else: + return ["ssl", "crypto"] + + +ffi = build_ffi_for_binding( + module_name="_openssl", + module_prefix="_cffi_src.openssl.", + modules=[ + # This goes first so we can define some cryptography-wide symbols. + "cryptography", + + "aes", + "asn1", + "bignum", + "bio", + "cmac", + "cms", + "conf", + "crypto", + "dh", + "dsa", + "ec", + "ecdh", + "ecdsa", + "engine", + "err", + "evp", + "hmac", + "nid", + "objects", + "ocsp", + "opensslv", + "osrandom_engine", + "pem", + "pkcs12", + "rand", + "rsa", + "ssl", + "x509", + "x509name", + "x509v3", + "x509_vfy", + "pkcs7", + "callbacks", + ], + libraries=_get_openssl_libraries(sys.platform), + extra_link_args=extra_link_args(compiler_type()), +) diff --git a/lib_pypy/_cffi_ssl/_cffi_src/build_padding.py b/lib_pypy/_cffi_ssl/_cffi_src/build_padding.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_cffi_ssl/_cffi_src/build_padding.py @@ -0,0 +1,27 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import absolute_import, division, print_function + +import os + +from _cffi_src.utils import build_ffi, compiler_type, extra_link_args + + +with open(os.path.join( + os.path.dirname(__file__), "hazmat_src/padding.h" +)) as f: + types = f.read() + +with open(os.path.join( + os.path.dirname(__file__), "hazmat_src/padding.c" +)) as f: + functions = f.read() + +ffi = build_ffi( + module_name="_padding", + cdef_source=types, + verify_source=functions, + extra_link_args=extra_link_args(compiler_type()), +) diff --git a/lib_pypy/_cffi_ssl/_cffi_src/commoncrypto/__init__.py b/lib_pypy/_cffi_ssl/_cffi_src/commoncrypto/__init__.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_cffi_ssl/_cffi_src/commoncrypto/__init__.py @@ -0,0 +1,5 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import absolute_import, division, print_function diff --git a/lib_pypy/_cffi_ssl/_cffi_src/commoncrypto/cf.py b/lib_pypy/_cffi_ssl/_cffi_src/commoncrypto/cf.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_cffi_ssl/_cffi_src/commoncrypto/cf.py @@ -0,0 +1,113 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. + +from __future__ import absolute_import, division, print_function + +INCLUDES = """ +#include +""" + +TYPES = """ +typedef bool Boolean; +typedef signed long OSStatus; +typedef unsigned char UInt8; +typedef uint32_t UInt32; + +typedef const void * CFAllocatorRef; +const CFAllocatorRef kCFAllocatorDefault; +typedef ... *CFDataRef; +typedef signed long long CFIndex; +typedef ... *CFStringRef; +typedef ... *CFArrayRef; +typedef ... *CFMutableArrayRef; +typedef ... *CFBooleanRef; +typedef ... *CFErrorRef; +typedef ... *CFNumberRef; +typedef ... *CFTypeRef; +typedef ... *CFDictionaryRef; +typedef ... *CFMutableDictionaryRef; +typedef struct { + ...; +} CFDictionaryKeyCallBacks; +typedef struct { + ...; +} CFDictionaryValueCallBacks; +typedef struct { + ...; +} CFRange; +typedef struct { + ...; +} CFArrayCallBacks; + +typedef UInt32 CFStringEncoding; +enum { + kCFStringEncodingASCII = 0x0600 +}; + +enum { + kCFNumberSInt8Type = 1, + kCFNumberSInt16Type = 2, + kCFNumberSInt32Type = 3, + kCFNumberSInt64Type = 4, + kCFNumberFloat32Type = 5, + kCFNumberFloat64Type = 6, + kCFNumberCharType = 7, + kCFNumberShortType = 8, + kCFNumberIntType = 9, + kCFNumberLongType = 10, + kCFNumberLongLongType = 11, + kCFNumberFloatType = 12, + kCFNumberDoubleType = 13, + kCFNumberCFIndexType = 14, + kCFNumberNSIntegerType = 15, + kCFNumberCGFloatType = 16, + kCFNumberMaxType = 16 +}; +typedef int CFNumberType; + +const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks; +const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks; From pypy.commits at gmail.com Wed Jul 24 13:13:41 2019 From: pypy.commits at gmail.com (rlamy) Date: Wed, 24 Jul 2019 10:13:41 -0700 (PDT) Subject: [pypy-commit] pypy py3tests: hg merge py3.6 Message-ID: <5d3891c5.1c69fb81.69fe8.1b59@mx.google.com> Author: Ronan Lamy Branch: py3tests Changeset: r97023:5ec00f642d67 Date: 2019-07-24 18:12 +0100 http://bitbucket.org/pypy/pypy/changeset/5ec00f642d67/ Log: hg merge py3.6 diff too long, truncating to 2000 out of 32952 lines diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -10,10 +10,6 @@ 32f35069a16d819b58c1b6efb17c44e3e53397b2 release-2.3.1 10f1b29a2bd21f837090286174a9ca030b8680b2 release-2.5.0 9c4588d731b7fe0b08669bd732c2b676cb0a8233 release-2.5.1 -fcdb941565156385cbac04cfb891f8f4c7a92ef6 release-2.6.0 -fcdb941565156385cbac04cfb891f8f4c7a92ef6 release-2.6.0 -e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0 -e03971291f3a0729ecd3ee7fae7ddb0bb82d476c release-2.6.0 295ee98b69288471b0fcf2e0ede82ce5209eb90b release-2.6.0 f3ad1e1e1d6215e20d34bb65ab85ff9188c9f559 release-2.6.1 850edf14b2c75573720f59e95767335fb1affe55 release-4.0.0 @@ -24,17 +20,10 @@ b0a649e90b6642251fb4a765fe5b27a97b1319a9 release-5.1.1 80ef432a32d9baa4b3c5a54c215e8ebe499f6374 release-5.1.2 40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2 -40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2 c09c19272c990a0611b17569a0085ad1ab00c8ff release-pypy2.7-v5.3 7e8df3df96417c16c2d55b41352ec82c9c69c978 release-pypy2.7-v5.3.1 -68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0 -68bb3510d8212ae9efb687e12e58c09d29e74f87 release-pypy2.7-v5.4.0 77392ad263504df011ccfcabf6a62e21d04086d0 release-pypy2.7-v5.4.0 -050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1 -050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1 0e2d9a73f5a1818d0245d75daccdbe21b2d5c3ef release-pypy2.7-v5.4.1 -4909c06daf41ce88f87dc01c57959cadad4df4a8 RevDB-pypy2.7-v5.4.1 -4909c06daf41ce88f87dc01c57959cadad4df4a8 RevDB-pypy2.7-v5.4.1 d7724c0a5700b895a47de44074cdf5fd659a988f RevDB-pypy2.7-v5.4.1 aff251e543859ce4508159dd9f1a82a2f553de00 release-pypy2.7-v5.6.0 e90317857d27917bf840caf675832292ee070510 RevDB-pypy2.7-v5.6.1 @@ -45,25 +34,20 @@ 2875f328eae2216a87f3d6f335092832eb031f56 release-pypy3.5-v5.7.1 c925e73810367cd960a32592dd7f728f436c125c release-pypy2.7-v5.8.0 a37ecfe5f142bc971a86d17305cc5d1d70abec64 release-pypy3.5-v5.8.0 -03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0 d72f9800a42b46a8056951b1da2426d2c2d8d502 release-pypy3.5-v5.9.0 -03d614975835870da65ff0481e1edad68ebbcb8d release-pypy2.7-v5.9.0 84a2f3e6a7f88f2fe698e473998755b3bd1a12e2 release-pypy2.7-v5.9.0 0e7ea4fe15e82d5124e805e2e4a37cae1a402d4b release-pypy2.7-v5.10.0 -a91df6163fb76df245091f741dbf6a23ddc72374 release-pypy3.5-v5.10.0 -a91df6163fb76df245091f741dbf6a23ddc72374 release-pypy3.5-v5.10.0 -0000000000000000000000000000000000000000 release-pypy3.5-v5.10.0 -0000000000000000000000000000000000000000 release-pypy3.5-v5.10.0 09f9160b643e3f02ccb8c843b2fbb4e5cbf54082 release-pypy3.5-v5.10.0 3f6eaa010fce78cc7973bdc1dfdb95970f08fed2 release-pypy3.5-v5.10.1 ab0b9caf307db6592905a80b8faffd69b39005b8 release-pypy2.7-v6.0.0 fdd60ed87e941677e8ea11acf9f1819466521bf2 release-pypy3.5-v6.0.0 9112c8071614108b1042bfef0713915107004d62 release-pypy2.7-v7.0.0 1f86f25937b6ae6c8b25236c35228fac587678bf release-pypy3.5-v7.0.0 -dab365a465140aa79a5f3ba4db784c4af4d5c195 release-pypy3.6-v7.0.0 -9112c8071614108b1042bfef0713915107004d62 release-pypy2.7-v7.0.0 c8805ee6d7846ca2722b106eeaa2f128c699aba3 release-pypy2.7-v7.0.0 -1f86f25937b6ae6c8b25236c35228fac587678bf release-pypy3.5-v7.0.0 928a4f70d3de7d17449456946154c5da6e600162 release-pypy3.5-v7.0.0 -dab365a465140aa79a5f3ba4db784c4af4d5c195 release-pypy3.6-v7.0.0 fb40f7a5524c77b80e6c468e087d621610137261 release-pypy3.6-v7.0.0 +990cef41fe11e5d46b019a46aa956ff46ea1a234 release-pypy2.7-v7.1.0 +de061d87e39c7df4e436974096d7982c676a859d release-pypy3.6-v7.1.0 +784b254d669919c872a505b807db8462b6140973 release-pypy3.6-v7.1.1 +8cdda8b8cdb8ff29d9e620cccd6c5edd2f2a23ec release-pypy2.7-v7.1.1 + diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -110,6 +110,7 @@ Devin Jeanpierre Bob Ippolito Bruno Gola + Andrew Lawrence David Malcolm Squeaky Edd Barrett @@ -125,7 +126,6 @@ John Witulski Stefan Beyer Jeremy Thurgood - Andrew Lawrence Greg Price Ivan Sichmann Freitas Dario Bertini @@ -254,6 +254,7 @@ Omer Katz Jacek Generowicz Tomasz Dziopa + Lin Cheng Sylvain Thenault Jakub Stasiak Andrew Dalke @@ -403,6 +404,7 @@ Niclas Olofsson Chris Pressey Tobias Diaz + Paul Graydon Nikolaos-Digenis Karagiannis Kurt Griffiths Ben Mather diff --git a/extra_tests/cffi_tests/cffi0/backend_tests.py b/extra_tests/cffi_tests/cffi0/backend_tests.py --- a/extra_tests/cffi_tests/cffi0/backend_tests.py +++ b/extra_tests/cffi_tests/cffi0/backend_tests.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest import platform import sys, ctypes from cffi import FFI, CDefError, FFIError, VerificationMissing @@ -113,10 +114,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): ffi = FFI(backend=self.Backend()) @@ -141,18 +146,21 @@ ffi = FFI(backend=self.Backend()) p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -260,7 +268,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): ffi = FFI(backend=self.Backend()) @@ -387,7 +396,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -423,13 +433,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct foo*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -451,8 +463,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): ffi = FFI(backend=self.Backend()) @@ -512,11 +526,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union foo*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % SIZE_OF_INT def test_union_opaque(self): @@ -592,7 +608,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -616,7 +633,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -634,7 +652,8 @@ s = ffi.new("struct foo*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -658,18 +677,21 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # ffi.cdef("struct foo { void *p; int *q; short *r; };") s = ffi.new("struct foo *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): ffi = FFI(backend=self.Backend()) @@ -688,7 +710,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -913,10 +936,14 @@ assert s.e == 4294967295 assert s[0].e == 4294967295 s.e = s.e - py.test.raises(TypeError, "s.e = 'B'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): ffi = FFI(backend=self.Backend()) @@ -951,11 +978,14 @@ ffi = FFI(backend=self.Backend()) ffi.cdef("struct foo { int a, b; };") s = ffi.new("struct foo[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): ffi = FFI(backend=self.Backend()) @@ -1012,17 +1042,23 @@ assert ffi.sizeof("struct foo") == 8 s = ffi.new("struct foo *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1280,7 +1316,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): ffi = FFI(backend=self.Backend()) diff --git a/extra_tests/cffi_tests/cffi0/test_ffi_backend.py b/extra_tests/cffi_tests/cffi0/test_ffi_backend.py --- a/extra_tests/cffi_tests/cffi0/test_ffi_backend.py +++ b/extra_tests/cffi_tests/cffi0/test_ffi_backend.py @@ -130,6 +130,36 @@ alloc5 = ffi.new_allocator(myalloc5) py.test.raises(MemoryError, alloc5, "int[5]") + def test_new_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { int len[100]; short data[]; }; + struct bar_s { int abc[100]; struct foo_s tail; }; + """) + # loop to try to detect heap overwrites, if the size allocated + # is too small + for i in range(1, 501, 100): + p = ffi.new("struct bar_s *", [[10], [[20], [3,4,5,6,7,8,9] * i]]) + assert p.abc[0] == 10 + assert p.tail.len[0] == 20 + assert p.tail.data[0] == 3 + assert p.tail.data[6] == 9 + assert p.tail.data[7 * i - 1] == 9 + + def test_bogus_struct_containing_struct_containing_array_varsize(self): + ffi = FFI(backend=self.Backend()) + ffi.cdef(""" + struct foo_s { signed char len; signed char data[]; }; + struct bar_s { struct foo_s foo; int bcd; }; + """) + p = ffi.new("struct bar_s *", [[123, [45, 56, 67, 78]], 9999999]) + assert p.foo.len == 123 + assert p.foo.data[0] == 45 + assert p.foo.data[1] == 56 + assert p.foo.data[2] == 67 + assert p.bcd == 9999999 + assert p.foo.data[3] != 78 # has been overwritten with 9999999 + class TestBitfield: def check(self, source, expected_ofs_y, expected_align, expected_size): @@ -269,12 +299,15 @@ def test_error_cases(self): ffi = FFI() - py.test.raises(TypeError, - 'ffi.cdef("struct s1 { float x:1; };"); ffi.new("struct s1 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s2 { char x:0; };"); ffi.new("struct s2 *")') - py.test.raises(TypeError, - 'ffi.cdef("struct s3 { char x:9; };"); ffi.new("struct s3 *")') + ffi.cdef("struct s1 { float x:1; };") + with pytest.raises(TypeError): + ffi.new("struct s1 *") + ffi.cdef("struct s2 { char x:0; };") + with pytest.raises(TypeError): + ffi.new("struct s2 *") + ffi.cdef("struct s3 { char x:9; };") + with pytest.raises(TypeError): + ffi.new("struct s3 *") def test_struct_with_typedef(self): ffi = FFI() diff --git a/extra_tests/cffi_tests/cffi0/test_function.py b/extra_tests/cffi_tests/cffi0/test_function.py --- a/extra_tests/cffi_tests/cffi0/test_function.py +++ b/extra_tests/cffi_tests/cffi0/test_function.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest from cffi import FFI, CDefError import math, os, sys import ctypes.util @@ -91,7 +92,8 @@ """) m = ffi.dlopen(lib_m) assert m.FOOBAR == 42 - py.test.raises(NotImplementedError, "m.baz") + with pytest.raises(NotImplementedError): + m.baz def test_tlsalloc(self): if sys.platform != 'win32': diff --git a/extra_tests/cffi_tests/cffi0/test_parsing.py b/extra_tests/cffi_tests/cffi0/test_parsing.py --- a/extra_tests/cffi_tests/cffi0/test_parsing.py +++ b/extra_tests/cffi_tests/cffi0/test_parsing.py @@ -410,7 +410,17 @@ def test_enum(): ffi = FFI() ffi.cdef(""" - enum Enum { POS = +1, TWO = 2, NIL = 0, NEG = -1, OP = (POS+TWO)-1}; + enum Enum { + POS = +1, + TWO = 2, + NIL = 0, + NEG = -1, + ADDSUB = (POS+TWO)-1, + DIVMULINT = (3 * 3) / 2, + SHIFT = (1 << 3) >> 1, + BINOPS = (0x7 & 0x1) | 0x8, + XOR = 0xf ^ 0xa + }; """) needs_dlopen_none() C = ffi.dlopen(None) @@ -418,7 +428,11 @@ assert C.TWO == 2 assert C.NIL == 0 assert C.NEG == -1 - assert C.OP == 2 + assert C.ADDSUB == 2 + assert C.DIVMULINT == 4 + assert C.SHIFT == 4 + assert C.BINOPS == 0b1001 + assert C.XOR == 0b0101 def test_stdcall(): ffi = FFI() @@ -467,3 +481,40 @@ e = py.test.raises(CDefError, ffi.cdef, 'void foo(void) {}') assert str(e.value) == (':1: unexpected : ' 'this construct is valid C but not valid in cdef()') + +def test_unsigned_int_suffix_for_constant(): + ffi = FFI() + ffi.cdef("""enum e { + bin_0=0b10, + bin_1=0b10u, + bin_2=0b10U, + bin_3=0b10l, + bin_4=0b10L, + bin_5=0b10ll, + bin_6=0b10LL, + oct_0=010, + oct_1=010u, + oct_2=010U, + oct_3=010l, + oct_4=010L, + oct_5=010ll, + oct_6=010LL, + dec_0=10, + dec_1=10u, + dec_2=10U, + dec_3=10l, + dec_4=10L, + dec_5=10ll, + dec_6=10LL, + hex_0=0x10, + hex_1=0x10u, + hex_2=0x10U, + hex_3=0x10l, + hex_4=0x10L, + hex_5=0x10ll, + hex_6=0x10LL,};""") + needs_dlopen_none() + C = ffi.dlopen(None) + for base, expected_result in (('bin', 2), ('oct', 8), ('dec', 10), ('hex', 16)): + for index in range(7): + assert getattr(C, '{base}_{index}'.format(base=base, index=index)) == expected_result diff --git a/extra_tests/cffi_tests/cffi0/test_verify.py b/extra_tests/cffi_tests/cffi0/test_verify.py --- a/extra_tests/cffi_tests/cffi0/test_verify.py +++ b/extra_tests/cffi_tests/cffi0/test_verify.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py, re +import pytest import sys, os, math, weakref from cffi import FFI, VerificationError, VerificationMissing, model, FFIError from extra_tests.cffi_tests.support import * @@ -21,7 +22,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): def verify(self, *args, **kwds): @@ -590,7 +592,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -648,7 +651,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1464,8 +1468,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1533,7 +1539,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2099,6 +2106,11 @@ raise errors[0][1] def test_errno_working_even_with_pypys_jit(): + # NOTE: on some platforms, to work correctly, this test needs to be + # compiled with -pthread. Otherwise, the accesses to errno done from f() + # are compiled by assuming this small library won't be used from multiple + # threads, which is wrong. If you see failures _and_ if you pass your + # own CFLAGS environment variable, please make sure "-pthread" is in it. ffi = FFI() ffi.cdef("int f(int);") lib = ffi.verify(""" @@ -2523,3 +2535,29 @@ x.p = p x.cyclic = x del p, x + +def test_arithmetic_in_cdef(): + for a in [0, 11, 15]: + ffi = FFI() + ffi.cdef(""" + enum FOO { + DIVNN = ((-?) / (-3)), + DIVNP = ((-?) / (+3)), + DIVPN = ((+?) / (-3)), + MODNN = ((-?) % (-3)), + MODNP = ((-?) % (+3)), + MODPN = ((+?) % (-3)), + }; + """.replace('?', str(a))) + lib = ffi.verify(""" + enum FOO { + DIVNN = ((-?) / (-3)), + DIVNP = ((-?) / (+3)), + DIVPN = ((+?) / (-3)), + MODNN = ((-?) % (-3)), + MODNP = ((-?) % (+3)), + MODPN = ((+?) % (-3)), + }; + """.replace('?', str(a))) + # the verify() crashes if the values in the enum are different from + # the values we computed ourselves from the cdef() diff --git a/extra_tests/cffi_tests/cffi0/test_zintegration.py b/extra_tests/cffi_tests/cffi0/test_zintegration.py --- a/extra_tests/cffi_tests/cffi0/test_zintegration.py +++ b/extra_tests/cffi_tests/cffi0/test_zintegration.py @@ -2,11 +2,13 @@ import py, os, sys, shutil import subprocess from extra_tests.cffi_tests.udir import udir +import pytest if sys.platform == 'win32': - py.test.skip('snippets do not run on win32') + pytestmark = pytest.mark.skip('snippets do not run on win32') if sys.version_info < (2, 7): - py.test.skip('fails e.g. on a Debian/Ubuntu which patches virtualenv' + pytestmark = pytest.mark.skip( + 'fails e.g. on a Debian/Ubuntu which patches virtualenv' ' in a non-2.6-friendly way') def create_venv(name): diff --git a/extra_tests/cffi_tests/cffi1/test_ffi_obj.py b/extra_tests/cffi_tests/cffi1/test_ffi_obj.py --- a/extra_tests/cffi_tests/cffi1/test_ffi_obj.py +++ b/extra_tests/cffi_tests/cffi1/test_ffi_obj.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py, sys +import pytest import _cffi_backend as _cffi1_backend @@ -86,9 +87,12 @@ def test_ffi_no_attr(): ffi = _cffi1_backend.FFI() - py.test.raises(AttributeError, "ffi.no_such_name") - py.test.raises(AttributeError, "ffi.no_such_name = 42") - py.test.raises(AttributeError, "del ffi.no_such_name") + with pytest.raises(AttributeError): + ffi.no_such_name + with pytest.raises(AttributeError): + ffi.no_such_name = 42 + with pytest.raises(AttributeError): + del ffi.no_such_name def test_ffi_string(): ffi = _cffi1_backend.FFI() diff --git a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py --- a/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py +++ b/extra_tests/cffi_tests/cffi1/test_new_ffi_1.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import py +import pytest import platform, imp import sys, os, ctypes import cffi @@ -187,10 +188,14 @@ p[9] = 43 assert p[0] == 42 assert p[9] == 43 - py.test.raises(IndexError, "p[10]") - py.test.raises(IndexError, "p[10] = 44") - py.test.raises(IndexError, "p[-1]") - py.test.raises(IndexError, "p[-1] = 44") + with pytest.raises(IndexError): + p[10] + with pytest.raises(IndexError): + p[10] = 44 + with pytest.raises(IndexError): + p[-1] + with pytest.raises(IndexError): + p[-1] = 44 def test_new_array_args(self): # this tries to be closer to C: where we say "int x[5] = {10, 20, ..}" @@ -213,18 +218,21 @@ def test_new_array_varsize(self): p = ffi.new("int[]", 10) # a single integer is the length assert p[9] == 0 - py.test.raises(IndexError, "p[10]") + with pytest.raises(IndexError): + p[10] # py.test.raises(TypeError, ffi.new, "int[]") # p = ffi.new("int[]", [-6, -7]) # a list is all the items, like C assert p[0] == -6 assert p[1] == -7 - py.test.raises(IndexError, "p[2]") + with pytest.raises(IndexError): + p[2] assert repr(p) == "" % (2*SIZE_OF_INT) # p = ffi.new("int[]", 0) - py.test.raises(IndexError, "p[0]") + with pytest.raises(IndexError): + p[0] py.test.raises(ValueError, ffi.new, "int[]", -1) assert repr(p) == "" @@ -325,7 +333,8 @@ p[2][3] = 33 assert p[0][0] == 10 assert p[2][3] == 33 - py.test.raises(IndexError, "p[1][-1]") + with pytest.raises(IndexError): + p[1][-1] def test_constructor_array_of_array(self): p = ffi.new("int[3][2]", [[10, 11], [12, 13], [14, 15]]) @@ -446,7 +455,8 @@ n = ffi.new("int*", 99) p = ffi.new("int*[]", [n]) assert p[0][0] == 99 - py.test.raises(TypeError, "p[0] = None") + with pytest.raises(TypeError): + p[0] = None p[0] = ffi.NULL assert p[0] == ffi.NULL @@ -479,13 +489,15 @@ assert s.a == s.b == s.c == 0 s.b = -23 assert s.b == -23 - py.test.raises(OverflowError, "s.b = 32768") + with pytest.raises(OverflowError): + s.b = 32768 # s = ffi.new("struct simple*", [-2, -3]) assert s.a == -2 assert s.b == -3 assert s.c == 0 - py.test.raises((AttributeError, TypeError), "del s.a") + with pytest.raises((AttributeError, TypeError)): + del s.a assert repr(s) == "" % ( SIZE_OF_INT + 2 * SIZE_OF_SHORT) # @@ -503,8 +515,10 @@ assert s[0].a == s[0].b == s[0].c == 0 s[0].b = -23 assert s[0].b == s.b == -23 - py.test.raises(OverflowError, "s[0].b = -32769") - py.test.raises(IndexError, "s[1]") + with pytest.raises(OverflowError): + s[0].b = -32769 + with pytest.raises(IndexError): + s[1] def test_struct_opaque(self): py.test.raises(ffi.error, ffi.new, "struct baz*") @@ -556,11 +570,13 @@ u.b = -23 assert u.b == -23 assert u.a != 0 - py.test.raises(OverflowError, "u.b = 32768") + with pytest.raises(OverflowError): + u.b = 32768 # u = ffi.new("union simple_u*", [-2]) assert u.a == -2 - py.test.raises((AttributeError, TypeError), "del u.a") + with pytest.raises((AttributeError, TypeError)): + del u.a assert repr(u) == "" % ( SIZE_OF_INT,) @@ -626,7 +642,8 @@ p[3] = b'\x00' assert ffi.string(p) == b"hel" assert ffi.string(p, 2) == b"he" - py.test.raises(IndexError, "p[7] = b'X'") + with pytest.raises(IndexError): + p[7] = b'X' # a = ffi.new("char[]", b"hello\x00world") assert len(a) == 12 @@ -649,7 +666,8 @@ p[3] = u+'\x00' assert ffi.string(p) == u+"hel" assert ffi.string(p, 123) == u+"hel" - py.test.raises(IndexError, "p[7] = u+'X'") + with pytest.raises(IndexError): + p[7] = u+'X' # a = ffi.new("wchar_t[]", u+"hello\x00world") assert len(a) == 12 @@ -665,7 +683,8 @@ s = ffi.new("struct string*", [t]) assert type(s.name) not in (bytes, str, unicode) assert ffi.string(s.name) == b"testing" - py.test.raises(TypeError, "s.name = None") + with pytest.raises(TypeError): + s.name = None s.name = ffi.NULL assert s.name == ffi.NULL @@ -686,17 +705,20 @@ a = ffi.new("int[]", [10, 11, 12]) p = ffi.new("void **", a) vp = p[0] - py.test.raises(TypeError, "vp[0]") + with pytest.raises(TypeError): + vp[0] py.test.raises(TypeError, ffi.new, "short **", a) # s = ffi.new("struct voidp *") s.p = a # works s.q = a # works - py.test.raises(TypeError, "s.r = a") # fails + with pytest.raises(TypeError): + s.r = a # fails b = ffi.cast("int *", a) s.p = b # works s.q = b # works - py.test.raises(TypeError, "s.r = b") # fails + with pytest.raises(TypeError): + s.r = b # fails def test_functionptr_simple(self): py.test.raises(TypeError, ffi.callback, "int(*)(int)", 0) @@ -714,7 +736,8 @@ q = ffi.new("int(**)(int)", p) assert repr(q) == "" % ( SIZE_OF_PTR) - py.test.raises(TypeError, "q(43)") + with pytest.raises(TypeError): + q(43) res = q[0](43) assert res == 44 q = ffi.cast("int(*)(int)", p) @@ -923,10 +946,14 @@ assert s.e in (4294967295, -1) # two choices assert s[0].e in (4294967295, -1) s.e = s.e - py.test.raises(TypeError, "s.e = 'B3'") - py.test.raises(TypeError, "s.e = '2'") - py.test.raises(TypeError, "s.e = '#2'") - py.test.raises(TypeError, "s.e = '#7'") + with pytest.raises(TypeError): + s.e = 'B3' + with pytest.raises(TypeError): + s.e = '2' + with pytest.raises(TypeError): + s.e = '#2' + with pytest.raises(TypeError): + s.e = '#7' def test_enum_non_contiguous(self): # enum noncont { A4, B4=42, C4 }; @@ -948,11 +975,14 @@ def test_array_of_struct(self): s = ffi.new("struct ab[1]") - py.test.raises(AttributeError, 's.b') - py.test.raises(AttributeError, 's.b = 412') + with pytest.raises(AttributeError): + s.b + with pytest.raises(AttributeError): + s.b = 412 s[0].b = 412 assert s[0].b == 412 - py.test.raises(IndexError, 's[1]') + with pytest.raises(IndexError): + s[1] def test_pointer_to_array(self): p = ffi.new("int(**)[5]") @@ -1001,17 +1031,23 @@ assert ffi.sizeof("struct bitfield") == 8 s = ffi.new("struct bitfield *") s.a = 511 - py.test.raises(OverflowError, "s.a = 512") - py.test.raises(OverflowError, "s[0].a = 512") + with pytest.raises(OverflowError): + s.a = 512 + with pytest.raises(OverflowError): + s[0].a = 512 assert s.a == 511 s.a = -512 - py.test.raises(OverflowError, "s.a = -513") - py.test.raises(OverflowError, "s[0].a = -513") + with pytest.raises(OverflowError): + s.a = -513 + with pytest.raises(OverflowError): + s[0].a = -513 assert s.a == -512 s.c = 3 assert s.c == 3 - py.test.raises(OverflowError, "s.c = 4") - py.test.raises(OverflowError, "s[0].c = 4") + with pytest.raises(OverflowError): + s.c = 4 + with pytest.raises(OverflowError): + s[0].c = 4 s.c = -4 assert s.c == -4 @@ -1236,7 +1272,8 @@ p = ffi.new("struct foo_s *", 10) # a single integer is the length assert p.len == 0 assert p.data[9] == 0 - py.test.raises(IndexError, "p.data[10]") + with pytest.raises(IndexError): + p.data[10] def test_ffi_typeof_getcname(self): assert ffi.getctype("int") == "int" @@ -1753,7 +1790,8 @@ assert MYFOO == 42 assert myfunc(43) == 44 assert myvar == -5 # but can't be changed, so not very useful - py.test.raises(ImportError, "from _test_import_from_lib.lib import bar") + with pytest.raises(ImportError): + from _test_import_from_lib.lib import bar d = {} exec("from _test_import_from_lib.lib import *", d) assert (set(key for key in d if not key.startswith('_')) == diff --git a/extra_tests/cffi_tests/cffi1/test_recompiler.py b/extra_tests/cffi_tests/cffi1/test_recompiler.py --- a/extra_tests/cffi_tests/cffi1/test_recompiler.py +++ b/extra_tests/cffi_tests/cffi1/test_recompiler.py @@ -1,6 +1,7 @@ # Generated by pypy/tool/import_cffi.py import sys, os, py +import pytest from cffi import FFI, VerificationError, FFIError, CDefError from cffi import recompiler from extra_tests.cffi_tests.udir import udir @@ -189,20 +190,26 @@ assert lib.a == -2 lib.a = -2147483648 assert lib.a == -2147483648 - py.test.raises(OverflowError, "lib.a = 2147483648") - py.test.raises(OverflowError, "lib.a = -2147483649") + with pytest.raises(OverflowError): + lib.a = 2147483648 + with pytest.raises(OverflowError): + lib.a = -2147483649 lib.b = 525 # try with the first access being in setattr, too assert lib.b == 525 - py.test.raises(AttributeError, "del lib.a") - py.test.raises(AttributeError, "del lib.c") - py.test.raises(AttributeError, "del lib.foobarbaz") + with pytest.raises(AttributeError): + del lib.a + with pytest.raises(AttributeError): + del lib.c + with pytest.raises(AttributeError): + del lib.foobarbaz def test_macro(): ffi = FFI() ffi.cdef("#define FOOBAR ...") lib = verify(ffi, 'test_macro', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_macro_check_value(): # the value '-0x80000000' in C sources does not have a clear meaning @@ -248,7 +255,8 @@ ffi.cdef("static const int FOOBAR;") lib = verify(ffi, 'test_constant', "#define FOOBAR (-6912)") assert lib.FOOBAR == -6912 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_check_value_of_static_const(): ffi = FFI() @@ -264,7 +272,8 @@ ffi.cdef("static const double FOOBAR;") lib = verify(ffi, 'test_constant_nonint', "#define FOOBAR (-6912.5)") assert lib.FOOBAR == -6912.5 - py.test.raises(AttributeError, "lib.FOOBAR = 2") + with pytest.raises(AttributeError): + lib.FOOBAR = 2 def test_constant_ptr(): ffi = FFI() @@ -316,8 +325,10 @@ p = ffi.new("struct foo_s *", {'a': -32768, 'b': -2147483648}) assert p.a == -32768 assert p.b == -2147483648 - py.test.raises(OverflowError, "p.a -= 1") - py.test.raises(OverflowError, "p.b -= 1") + with pytest.raises(OverflowError): + p.a -= 1 + with pytest.raises(OverflowError): + p.b -= 1 q = ffi.new("struct bar_s *", {'f': p}) assert q.f == p # @@ -388,8 +399,10 @@ assert ffi.sizeof("struct foo_s") == (42 + 11) * 4 p = ffi.new("struct foo_s *") assert p.a[41] == p.b[10] == 0 - py.test.raises(IndexError, "p.a[42]") - py.test.raises(IndexError, "p.b[11]") + with pytest.raises(IndexError): + p.a[42] + with pytest.raises(IndexError): + p.b[11] def test_dotdotdot_global_array(): ffi = FFI() @@ -399,8 +412,10 @@ assert ffi.sizeof(lib.aa) == 41 * 4 assert ffi.sizeof(lib.bb) == 12 * 4 assert lib.aa[40] == lib.bb[11] == 0 - py.test.raises(IndexError, "lib.aa[41]") - py.test.raises(IndexError, "lib.bb[12]") + with pytest.raises(IndexError): + lib.aa[41] + with pytest.raises(IndexError): + lib.bb[12] def test_misdeclared_field_1(): ffi = FFI() @@ -1021,8 +1036,10 @@ assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.sizeof(s.a) == 40 * ffi.sizeof('int') assert s.a[4][7] == 0 - py.test.raises(IndexError, 's.a[4][8]') - py.test.raises(IndexError, 's.a[5][0]') + with pytest.raises(IndexError): + s.a[4][8] + with pytest.raises(IndexError): + s.a[5][0] assert ffi.typeof(s.a) == ffi.typeof("int[5][8]") assert ffi.typeof(s.a[0]) == ffi.typeof("int[8]") @@ -1035,7 +1052,8 @@ s = ffi.new("struct foo_s *") assert ffi.typeof(s.a) == ffi.typeof("int[][7]") assert s.a[4][6] == 0 - py.test.raises(IndexError, 's.a[4][7]') + with pytest.raises(IndexError): + s.a[4][7] assert ffi.typeof(s.a[0]) == ffi.typeof("int[7]") def test_global_var_array_2(): @@ -1044,8 +1062,10 @@ lib = verify(ffi, 'test_global_var_array_2', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][0]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][0] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1055,7 +1075,8 @@ lib = verify(ffi, 'test_global_var_array_3', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') + with pytest.raises(IndexError): + lib.a[0][8] assert ffi.typeof(lib.a) == ffi.typeof("int(*)[8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1065,8 +1086,10 @@ lib = verify(ffi, 'test_global_var_array_4', 'int a[10][8];') lib.a[9][7] = 123456 assert lib.a[9][7] == 123456 - py.test.raises(IndexError, 'lib.a[0][8]') - py.test.raises(IndexError, 'lib.a[10][8]') + with pytest.raises(IndexError): + lib.a[0][8] + with pytest.raises(IndexError): + lib.a[10][8] assert ffi.typeof(lib.a) == ffi.typeof("int[10][8]") assert ffi.typeof(lib.a[0]) == ffi.typeof("int[8]") @@ -1339,7 +1362,8 @@ #define aaa 42 """) assert lib.aaa == 42 - py.test.raises(AttributeError, "lib.aaa = 43") + with pytest.raises(AttributeError): + lib.aaa = 43 def test_win32_calling_convention_0(): ffi = FFI() @@ -2315,3 +2339,89 @@ typedef int foo_t; struct foo_s { void (*x)(foo_t); }; """) py.test.raises(TypeError, ffi.new, "struct foo_s *") + +def test_from_buffer_struct(): + ffi = FFI() + ffi.cdef("""struct foo_s { int a, b; };""") + lib = verify(ffi, "test_from_buffer_struct_p", """ + struct foo_s { int a, b; }; + """) + p = ffi.new("struct foo_s *", [-219239, 58974983]) + q = ffi.from_buffer("struct foo_s[]", ffi.buffer(p)) + assert ffi.typeof(q) == ffi.typeof("struct foo_s[]") + assert len(q) == 1 + assert q[0].a == p.a + assert q[0].b == p.b + assert q == p + q = ffi.from_buffer("struct foo_s *", ffi.buffer(p)) + assert ffi.typeof(q) == ffi.typeof("struct foo_s *") + assert q.a == p.a + assert q.b == p.b + assert q[0].a == p.a + assert q[0].b == p.b + assert q == p + +def test_unnamed_bitfield_1(): + ffi = FFI() + ffi.cdef("""struct A { char : 1; };""") + lib = verify(ffi, "test_unnamed_bitfield_1", """ + struct A { char : 1; }; + """) + p = ffi.new("struct A *") + assert ffi.sizeof(p[0]) == 1 + # Note: on gcc, the type name is ignored for anonymous bitfields + # and that's why the result is 1. On MSVC, the result is + # sizeof("char") which is also 1. + +def test_unnamed_bitfield_2(): + ffi = FFI() + ffi.cdef("""struct A { + short c : 1; short : 1; short d : 1; short : 1; };""") + lib = verify(ffi, "test_unnamed_bitfield_2", """ + struct A { + short c : 1; short : 1; short d : 1; short : 1; + }; + """) + p = ffi.new("struct A *") + assert ffi.sizeof(p[0]) == ffi.sizeof("short") + +def test_unnamed_bitfield_3(): + ffi = FFI() + ffi.cdef("""struct A { struct { char : 1; char : 1; } b; };""") + lib = verify(ffi, "test_unnamed_bitfield_3", """ + struct A { struct { char : 1; char : 1; } b; }; + """) + p = ffi.new("struct A *") + assert ffi.sizeof(p[0]) == 1 + # Note: on gcc, the type name is ignored for anonymous bitfields + # and that's why the result is 1. On MSVC, the result is + # sizeof("char") which is also 1. + +def test_unnamed_bitfield_4(): + ffi = FFI() + ffi.cdef("""struct A { struct { + unsigned c : 1; unsigned : 1; unsigned d : 1; unsigned : 1; } a; + }; + struct B { struct A a; };""") + lib = verify(ffi, "test_unnamed_bitfield_4", """ + struct A { struct { + unsigned c : 1; unsigned : 1; unsigned d : 1; unsigned : 1; } a; + }; + struct B { struct A a; }; + """) + b = ffi.new("struct B *") + a = ffi.new("struct A *") + assert ffi.sizeof(a[0]) == ffi.sizeof("unsigned") + assert ffi.sizeof(b[0]) == ffi.sizeof(a[0]) + +def test_struct_with_func_with_struct_arg(): + ffi = FFI() + ffi.cdef("""struct BinaryTree { + int (* CompareKey)(struct BinaryTree tree); + };""") + lib = verify(ffi, "test_struct_with_func_with_struct_arg", """ + struct BinaryTree { + int (* CompareKey)(struct BinaryTree tree); + }; + """) + py.test.raises(RuntimeError, ffi.new, "struct BinaryTree *") diff --git a/extra_tests/cffi_tests/cffi1/test_verify1.py b/extra_tests/cffi_tests/cffi1/test_verify1.py --- a/extra_tests/cffi_tests/cffi1/test_verify1.py +++ b/extra_tests/cffi_tests/cffi1/test_verify1.py @@ -1,5 +1,6 @@ # Generated by pypy/tool/import_cffi.py import os, sys, math, py +import pytest from cffi import FFI, FFIError, VerificationError, VerificationMissing, model from cffi import CDefError from cffi import recompiler @@ -23,7 +24,8 @@ extra_compile_args.append('-Qunused-arguments') else: # assume a standard gcc - extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion'] + extra_compile_args = ['-Werror', '-Wall', '-Wextra', '-Wconversion', + '-Wno-unused-parameter'] class FFI(FFI): error = _cffi_backend.FFI.error @@ -572,7 +574,8 @@ assert ffi.sizeof('struct foo_s') == 19 * ffi.sizeof('int') s = ffi.new("struct foo_s *") assert ffi.sizeof(s.a) == 17 * ffi.sizeof('int') - py.test.raises(IndexError, 's.a[17]') + with pytest.raises(IndexError): + s.a[17] def test_struct_array_c99_1(): if sys.platform == 'win32': @@ -630,7 +633,8 @@ ffi.verify("struct foo_s { int a:2, b:3; };") s = ffi.new("struct foo_s *") s.b = 3 - py.test.raises(OverflowError, "s.b = 4") + with pytest.raises(OverflowError): + s.b = 4 assert s.b == 3 def test_struct_with_bitfield_enum(): @@ -1434,8 +1438,10 @@ p = ffi.new("struct foo_s *") p.x = 1 assert p.x is True - py.test.raises(OverflowError, "p.x = -1") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(OverflowError): + p.x = -1 + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foop(1) is False assert lib.foop(True) is False assert lib.foop(0) is True @@ -1503,7 +1509,8 @@ } """ % (type, type)) p = ffi.new("struct foo_s *") - py.test.raises(TypeError, "p.x = 0.0") + with pytest.raises(TypeError): + p.x = 0.0 assert lib.foo(42) == 0 assert lib.foo(0) == 1 py.test.raises(TypeError, lib.foo, 0.0) @@ -2194,7 +2201,8 @@ ffi = FFI() ffi.cdef("#define FOO 123") lib = ffi.verify("#define FOO 124") # used to complain - e = py.test.raises(ffi.error, "lib.FOO") + with pytest.raises(ffi.error) as e: + lib.FOO assert str(e.value) == ("the C compiler says 'FOO' is equal to 124 (0x7c)," " but the cdef disagrees") diff --git a/extra_tests/cffi_tests/embedding/test_basic.py b/extra_tests/cffi_tests/embedding/test_basic.py --- a/extra_tests/cffi_tests/embedding/test_basic.py +++ b/extra_tests/cffi_tests/embedding/test_basic.py @@ -64,8 +64,8 @@ output = popen.stdout.read() err = popen.wait() if err: - raise OSError("popen failed with exit code %r: %r" % ( - err, args)) + raise OSError(("popen failed with exit code %r: %r\n\n%s" % ( + err, args, output)).rstrip()) print(output.rstrip()) return output @@ -173,7 +173,8 @@ result = popen.stdout.read() err = popen.wait() if err: - raise OSError("%r failed with exit code %r" % (name, err)) + raise OSError("%r failed with exit code %r" % ( + os.path.join(path, executable_name), err)) return result diff --git a/extra_tests/cffi_tests/embedding/test_performance.py b/extra_tests/cffi_tests/embedding/test_performance.py --- a/extra_tests/cffi_tests/embedding/test_performance.py +++ b/extra_tests/cffi_tests/embedding/test_performance.py @@ -3,8 +3,8 @@ from extra_tests.cffi_tests.embedding.test_basic import EmbeddingTests if sys.platform == 'win32': - import py - py.test.skip("written with POSIX functions") + import pytest + pytestmark = pytest.mark.skip("written with POSIX functions") class TestPerformance(EmbeddingTests): diff --git a/lib-python/2.7/test/capath/efa5f9c3.0 b/lib-python/2.7/test/capath/efa5f9c3.0 new file mode 100644 --- /dev/null +++ b/lib-python/2.7/test/capath/efa5f9c3.0 @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF9zCCA9+gAwIBAgIUH98b4Fw/DyugC9cV7VK7ZODzHsIwDQYJKoZIhvcNAQEL +BQAwgYoxCzAJBgNVBAYTAlhZMRcwFQYDVQQIDA5DYXN0bGUgQW50aHJheDEYMBYG +A1UEBwwPQXJndW1lbnQgQ2xpbmljMSMwIQYDVQQKDBpQeXRob24gU29mdHdhcmUg +Rm91bmRhdGlvbjEjMCEGA1UEAwwac2VsZi1zaWduZWQucHl0aG9udGVzdC5uZXQw +HhcNMTkwNTA4MDEwMjQzWhcNMjcwNzI0MDEwMjQzWjCBijELMAkGA1UEBhMCWFkx +FzAVBgNVBAgMDkNhc3RsZSBBbnRocmF4MRgwFgYDVQQHDA9Bcmd1bWVudCBDbGlu +aWMxIzAhBgNVBAoMGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMSMwIQYDVQQD +DBpzZWxmLXNpZ25lZC5weXRob250ZXN0Lm5ldDCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAMKdJlyCThkahwoBb7pl5q64Pe9Fn5jrIvzsveHTc97TpjV2 +RLfICnXKrltPk/ohkVl6K5SUZQZwMVzFubkyxE0nZPHYHlpiKWQxbsYVkYv01rix +IFdLvaxxbGYke2jwQao31s4o61AdlsfK1SdpHQUynBBMssqI3SB4XPmcA7e+wEEx +jxjVish4ixA1vuIZOx8yibu+CFCf/geEjoBMF3QPdzULzlrCSw8k/45iZCSoNbvK +DoL4TVV07PHOxpheDh8ZQmepGvU6pVqhb9m4lgmV0OGWHgozd5Ur9CbTVDmxIEz3 +TSoRtNJK7qtyZdGNqwjksQxgZTjM/d/Lm/BJG99AiOmYOjsl9gbQMZgvQmMAtUsI +aMJnQuZ6R+KEpW/TR5qSKLWZSG45z/op+tzI2m+cE6HwTRVAWbcuJxcAA55MZjqU +OOOu3BBYMjS5nf2sQ9uoXsVBFH7i0mQqoW1SLzr9opI8KsWwFxQmO2vBxWYaN+lH +OmwBZBwyODIsmI1YGXmTp09NxRYz3Qe5GCgFzYowpMrcxUC24iduIdMwwhRM7rKg +7GtIWMSrFfuI1XCLRmSlhDbhNN6fVg2f8Bo9PdH9ihiIyxSrc+FOUasUYCCJvlSZ +8hFUlLvcmrZlWuazohm0lsXuMK1JflmQr/DA/uXxP9xzFfRy+RU3jDyxJbRHAgMB +AAGjUzBRMB0GA1UdDgQWBBSQJyxiPMRK01i+0BsV9zUwDiBaHzAfBgNVHSMEGDAW +gBSQJyxiPMRK01i+0BsV9zUwDiBaHzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4ICAQCR+7a7N/m+WLkxPPIA/CB4MOr2Uf8ixTv435Nyv6rXOun0+lTP +ExSZ0uYQ+L0WylItI3cQHULldDueD+s8TGzxf5woaLKf6tqyr0NYhKs+UeNEzDnN +9PHQIhX0SZw3XyXGUgPNBfRCg2ZDdtMMdOU4XlQN/IN/9hbYTrueyY7eXq9hmtI9 +1srftAMqr9SR1JP7aHI6DVgrEsZVMTDnfT8WmLSGLlY1HmGfdEn1Ip5sbo9uSkiH +AEPgPfjYIvR5LqTOMn4KsrlZyBbFIDh9Sl99M1kZzgH6zUGVLCDg1y6Cms69fx/e +W1HoIeVkY4b4TY7Bk7JsqyNhIuqu7ARaxkdaZWhYaA2YyknwANdFfNpfH+elCLIk +BUt5S3f4i7DaUePTvKukCZiCq4Oyln7RcOn5If73wCeLB/ZM9Ei1HforyLWP1CN8 +XLfpHaoeoPSWIveI0XHUl65LsPN2UbMbul/F23hwl+h8+BLmyAS680Yhn4zEN6Ku +B7Po90HoFa1Du3bmx4jsN73UkT/dwMTi6K072FbipnC1904oGlWmLwvAHvrtxxmL +Pl3pvEaZIu8wa/PNF6Y7J7VIewikIJq6Ta6FrWeFfzMWOj2qA1ZZi6fUaDSNYvuV +J5quYKCc/O+I/yDDf8wyBbZ/gvUXzUHTMYGG+bFrn1p7XDbYYeEJ6R/xEg== +-----END CERTIFICATE----- diff --git a/lib-python/3/_osx_support.py b/lib-python/3/_osx_support.py --- a/lib-python/3/_osx_support.py +++ b/lib-python/3/_osx_support.py @@ -107,7 +107,9 @@ if m is not None: _SYSTEM_VERSION = '.'.join(m.group(1).split('.')[:2]) # else: fall back to the default behaviour - + if not _SYSTEM_VERSION: + # minimum supported MACOSX_DEPLOYMENT_TARGET version + return '10.14' return _SYSTEM_VERSION def _remove_original_values(_config_vars): diff --git a/lib-python/3/ctypes/test/test_loading.py b/lib-python/3/ctypes/test/test_loading.py --- a/lib-python/3/ctypes/test/test_loading.py +++ b/lib-python/3/ctypes/test/test_loading.py @@ -4,7 +4,6 @@ import unittest import test.support from ctypes.util import find_library -from ctypes.test import xfail libc_name = None @@ -82,7 +81,6 @@ self.assertRaises(AttributeError, dll.__getitem__, 1234) @unittest.skipUnless(os.name == "nt", 'Windows-specific test') - @xfail def test_1703286_A(self): from _ctypes import LoadLibrary, FreeLibrary # On winXP 64-bit, advapi32 loads at an address that does @@ -94,7 +92,6 @@ FreeLibrary(handle) @unittest.skipUnless(os.name == "nt", 'Windows-specific test') - @xfail def test_1703286_B(self): # Since on winXP 64-bit advapi32 loads like described # above, the (arbitrarily selected) CloseEventLog function diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py --- a/lib-python/3/datetime.py +++ b/lib-python/3/datetime.py @@ -6,6 +6,7 @@ import time as _time import math as _math +import sys # for cpyext, use these as base classes from __pypy__._pypydatetime import dateinterop, deltainterop, timeinterop @@ -1379,7 +1380,8 @@ def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0): - if isinstance(year, bytes) and len(year) == 10 and 1 <= year[2]&0x7F <= 12: + if (isinstance(year, (bytes, str)) and len(year) == 10 and + 1 <= ord(year[2:3])&0x7F <= 12): # Pickle support self = dateinterop.__new__(cls) self.__setstate(year, month) @@ -1456,6 +1458,14 @@ # 23 hours at 1969-09-30 13:00:00 in Kwajalein. # Let's probe 24 hours in the past to detect a transition: max_fold_seconds = 24 * 3600 + + # On Windows localtime_s throws an OSError for negative values, + # thus we can't perform fold detection for values of time less + # than the max time fold. See comments in _datetimemodule's + # version of this method for more details. + if t < max_fold_seconds and sys.platform.startswith("win"): + return result + y, m, d, hh, mm, ss = converter(t - max_fold_seconds)[:6] probe1 = cls(y, m, d, hh, mm, ss, us, tz) trans = result - probe1 - timedelta(0, max_fold_seconds) diff --git a/lib-python/3/pdb.py b/lib-python/3/pdb.py --- a/lib-python/3/pdb.py +++ b/lib-python/3/pdb.py @@ -341,8 +341,14 @@ def interaction(self, frame, traceback): # Restore the previous signal handler at the Pdb prompt. if Pdb._previous_sigint_handler: - signal.signal(signal.SIGINT, Pdb._previous_sigint_handler) - Pdb._previous_sigint_handler = None + try: + signal.signal(signal.SIGINT, Pdb._previous_sigint_handler) + Pdb._previous_sigint_handler = None + except ValueError: + # ValueError happens when we're in a non-main thread, + # if we already invoked pdb in the same program from the + # main thread. (PyPy fix) + pass if self.setup(frame, traceback): # no interaction desired at this time (happens if .pdbrc contains # a command like "continue") diff --git a/lib-python/3/sysconfig.py b/lib-python/3/sysconfig.py --- a/lib-python/3/sysconfig.py +++ b/lib-python/3/sysconfig.py @@ -563,6 +563,7 @@ _CONFIG_VARS['abiflags'] = '' _CONFIG_VARS['implementation'] = _get_implementation() _CONFIG_VARS['implementation_lower'] = _get_implementation().lower() + _CONFIG_VARS['LIBRARY'] = '' if os.name == 'nt': _init_non_posix(_CONFIG_VARS) diff --git a/lib-python/3/test/test_timeit.py b/lib-python/3/test/test_timeit.py --- a/lib-python/3/test/test_timeit.py +++ b/lib-python/3/test/test_timeit.py @@ -366,9 +366,9 @@ def test_main_recommends_perf(self): s = self.run_main(seconds_per_increment=2.0, switches=['-n35', '-s', 'print("CustomSetup")']) self.assertIn(dedent("""\ - WARNING: timeit is a very unreliable tool. use perf or something else for real measurements + WARNING: timeit is a very unreliable tool. use pyperf or something else for real measurements """), s) - self.assertIn("-m pip install perf", s) + self.assertIn("-m pip install pyperf", s) def autorange(self, callback=None): timer = FakeTimer(seconds_per_increment=0.001) diff --git a/lib-python/3/timeit.py b/lib-python/3/timeit.py --- a/lib-python/3/timeit.py +++ b/lib-python/3/timeit.py @@ -310,10 +310,10 @@ return 0 setup = "\n".join(setup) or "pass" - print("WARNING: timeit is a very unreliable tool. use perf or something else for real measurements") + print("WARNING: timeit is a very unreliable tool. use pyperf or something else for real measurements") executable = os.path.basename(sys.executable) - print("%s -m pip install perf" % executable) - print("%s -m perf timeit %s" % ( + print("%s -m pip install pyperf" % executable) + print("%s -m pyperf timeit %s" % ( executable, " ".join([(arg if arg.startswith("-") else repr(arg)) for arg in origargs]), )) diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -172,7 +172,7 @@ RegrTest('test_coroutines.py'), RegrTest('test_cprofile.py'), RegrTest('test_crashers.py'), - RegrTest('test_crypt.py', usemodules='crypt'), + RegrTest('test_crypt.py'), RegrTest('test_csv.py', usemodules='_csv'), RegrTest('test_ctypes.py', usemodules="_rawffi thread cpyext"), RegrTest('test_curses.py'), diff --git a/lib_pypy/_blake2/_blake2_build.py b/lib_pypy/_blake2/_blake2_build.py --- a/lib_pypy/_blake2/_blake2_build.py +++ b/lib_pypy/_blake2/_blake2_build.py @@ -4,17 +4,18 @@ from cffi import FFI -IS_ARM = platform.machine().startswith('arm') IS_WIN = sys.platform == 'win32' -if IS_ARM: - # XXX Choose neon accelaration - define_macros = [] - extra_compile_args = [] -elif IS_WIN: +if IS_WIN: + BLAKE2_USE_SSE = True extra_compile_args = [] define_macros = [('__SSE2__', '1')] +elif platform.machine().startswith('x86'): + BLAKE2_USE_SSE = True + extra_compile_args = ['-msse2'] + define_macros = [] else: - extra_compile_args = ['-msse2'] + BLAKE2_USE_SSE = False + extra_compile_args = [] define_macros = [] @@ -80,13 +81,18 @@ _libdir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'impl')) +if BLAKE2_USE_SSE: + sourcesB=[os.path.join(_libdir, 'blake2b.c'), ] + sourcesS=[os.path.join(_libdir, 'blake2s.c'), ] +else: + sourcesB=[os.path.join(_libdir, 'blake2b-ref.c'), ] + sourcesS=[os.path.join(_libdir, 'blake2s-ref.c'), ] blake2b_ffi = FFI() blake2b_ffi.cdef(blake_cdef) blake2b_ffi.set_source( '_blake2b_cffi', blake2b_source, - sources=[os.path.join(_libdir, 'blake2b.c'), - ], + sources=sourcesB, include_dirs=[_libdir], extra_compile_args=extra_compile_args, define_macros=define_macros, @@ -102,8 +108,7 @@ blake2s_ffi.cdef(blake_cdef) blake2s_ffi.set_source( '_blake2s_cffi', _replace_b2s(blake2b_source), - sources=[os.path.join(_libdir, 'blake2s.c'), - ], + sources=sourcesS, include_dirs=[_libdir], extra_compile_args=extra_compile_args, define_macros=define_macros, diff --git a/lib_pypy/_blake2/impl/blake2b.o b/lib_pypy/_blake2/impl/blake2b.o deleted file mode 100644 index 0957bfc2e8b188b193b9eee3808641a638e0a2f7..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch [cut] diff --git a/lib_pypy/_cffi_ssl/.gitignore b/lib_pypy/_cffi_ssl/.gitignore deleted file mode 100644 --- a/lib_pypy/_cffi_ssl/.gitignore +++ /dev/null @@ -1,95 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -env/ -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*,cover -.hypothesis/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule - -# dotenv -.env - -# virtualenv -.venv/ -venv/ -ENV/ - -# Spyder project settings -.spyderproject - -# Rope project settings -.ropeproject - -# Vim - -*.swp -*.swo diff --git a/lib_pypy/_cffi_ssl/__init__.py b/lib_pypy/_cffi_ssl/__init__.py new file mode 100644 diff --git a/lib_pypy/_cffi_ssl/_cffi_src/openssl/ssl.py b/lib_pypy/_cffi_ssl/_cffi_src/openssl/ssl.py --- a/lib_pypy/_cffi_ssl/_cffi_src/openssl/ssl.py +++ b/lib_pypy/_cffi_ssl/_cffi_src/openssl/ssl.py @@ -40,6 +40,11 @@ */ static const long Cryptography_HAS_OP_NO_COMPRESSION; +/* Internally invented symbol to tell us if SSL_OP_ENABLE_MIDDLEBOX_COMPAT is + * supported + */ +static const long Cryptography_HAS_OP_ENABLE_MIDDLEBOX_COMPAT; + static const long Cryptography_HAS_SSL_OP_MSIE_SSLV2_RSA_PADDING; static const long Cryptography_HAS_SSL_SET_SSL_CTX; static const long Cryptography_HAS_SSL_OP_NO_TICKET; @@ -71,7 +76,9 @@ static const long SSL_OP_MICROSOFT_SESS_ID_BUG; static const long SSL_OP_NETSCAPE_CHALLENGE_BUG; static const long SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; +static const long SSL_OP_NO_SSLv2; static const long SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG; +static const long SSL_OP_ENABLE_MIDDLEBOX_COMPAT; static const long SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER; static const long SSL_OP_MSIE_SSLV2_RSA_PADDING; static const long SSL_OP_SSLEAY_080_CLIENT_DH_BUG; @@ -559,6 +566,13 @@ const long SSL_OP_NO_COMPRESSION = 0; #endif +#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT +static const long Cryptography_HAS_OP_ENABLE_MIDDLEBOX_COMPAT = 1; +#else +static const long Cryptography_HAS_OP_ENABLE_MIDDLEBOX_COMPAT = 0; +const long SSL_OP_ENABLE_MIDDLEBOX_COMPAT = 0; +#endif + #ifdef SSL_OP_NO_TLSv1_1 static const long Cryptography_HAS_TLSv1_1 = 1; #else diff --git a/lib_pypy/_cffi_ssl/_stdssl/__init__.py b/lib_pypy/_cffi_ssl/_stdssl/__init__.py --- a/lib_pypy/_cffi_ssl/_stdssl/__init__.py +++ b/lib_pypy/_cffi_ssl/_stdssl/__init__.py @@ -1,7 +1,6 @@ import sys import time import _thread -import socket import weakref from _pypy_openssl import ffi from _pypy_openssl import lib @@ -21,6 +20,7 @@ pyerr_write_unraisable) from _cffi_ssl._stdssl import error from select import select +import socket from enum import IntEnum as _IntEnum if sys.platform == 'win32': @@ -70,6 +70,7 @@ globals()[name[4:]] = getattr(lib, name) OP_ALL = lib.SSL_OP_ALL & ~lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS +OP_NO_SSLv2 = lib.SSL_OP_NO_SSLv2 SSL_CLIENT = 0 SSL_SERVER = 1 @@ -78,7 +79,8 @@ if lib.Cryptography_HAS_SSL2: PROTOCOL_SSLv2 = 0 -PROTOCOL_SSLv3 = 1 +if lib.Cryptography_HAS_SSL3_METHOD: + PROTOCOL_SSLv3 = 1 PROTOCOL_SSLv23 = 2 PROTOCOL_TLS = PROTOCOL_SSLv23 PROTOCOL_TLSv1 = 3 @@ -220,6 +222,7 @@ def _new__ssl_socket(sslctx, sock, socket_type, server_hostname, inbio, outbio): self = _SSLSocket(sslctx) ctx = sslctx.ctx + self.owner = None if server_hostname: self.server_hostname = server_hostname.decode('idna', 'strict') @@ -288,7 +291,8 @@ def owner(self, value): if value is None: self._owner = None - self._owner = weakref.ref(value) + else: + self._owner = weakref.ref(value) @property def context(self): @@ -804,7 +808,7 @@ method = lib.TLSv1_1_method() elif lib.Cryptography_HAS_TLSv1_2 and protocol == PROTOCOL_TLSv1_2 : method = lib.TLSv1_2_method() - elif protocol == PROTOCOL_SSLv3 and lib.Cryptography_HAS_SSL3_METHOD: + elif lib.Cryptography_HAS_SSL3_METHOD and protocol == PROTOCOL_SSLv3: method = lib.SSLv3_method() elif lib.Cryptography_HAS_SSL2 and protocol == PROTOCOL_SSLv2: method = lib.SSLv2_method() @@ -835,7 +839,7 @@ options = lib.SSL_OP_ALL & ~lib.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS if not lib.Cryptography_HAS_SSL2 or protocol != PROTOCOL_SSLv2: options |= lib.SSL_OP_NO_SSLv2 - if protocol != PROTOCOL_SSLv3: + if not lib.Cryptography_HAS_SSL3_METHOD or protocol != PROTOCOL_SSLv3: options |= lib.SSL_OP_NO_SSLv3 # Minimal security flags for server and client side context. # Client sockets ignore server-side parameters. @@ -1055,7 +1059,7 @@ self._add_ca_certs(buf, len(buf), ca_file_type) # load cafile or capath - if cafile or capath: + if cafile is not None or capath is not None: if cafile is None: cafilebuf = ffi.NULL else: @@ -1564,3 +1568,5 @@ "enough data to seed the PRNG"); return bytecount +socket.RAND_add = RAND_add +socket.RAND_status = RAND_status diff --git a/lib_pypy/_cffi_ssl/_stdssl/error.py b/lib_pypy/_cffi_ssl/_stdssl/error.py --- a/lib_pypy/_cffi_ssl/_stdssl/error.py +++ b/lib_pypy/_cffi_ssl/_stdssl/error.py @@ -1,5 +1,6 @@ import sys import os +import socket import traceback from _pypy_openssl import ffi from _pypy_openssl import lib @@ -26,6 +27,13 @@ if self.strerror and isinstance(self.strerror, str): return self.strerror return str(self.args) +# these are expected on socket as well +socket.sslerror = SSLError +for v in [ 'SSL_ERROR_ZERO_RETURN', 'SSL_ERROR_WANT_READ', + 'SSL_ERROR_WANT_WRITE', 'SSL_ERROR_WANT_X509_LOOKUP', 'SSL_ERROR_SYSCALL', + 'SSL_ERROR_SSL', 'SSL_ERROR_WANT_CONNECT', 'SSL_ERROR_EOF', + 'SSL_ERROR_INVALID_ERROR_CODE' ]: + setattr(socket, v, locals()[v]) class SSLZeroReturnError(SSLError): """ SSL/TLS session closed cleanly. """ diff --git a/lib_pypy/_cffi_ssl/_stdssl/utility.py b/lib_pypy/_cffi_ssl/_stdssl/utility.py --- a/lib_pypy/_cffi_ssl/_stdssl/utility.py +++ b/lib_pypy/_cffi_ssl/_stdssl/utility.py @@ -19,7 +19,7 @@ elif isinstance(view, memoryview): # NOTE pypy limitation StringBuffer does not allow # to get a raw address to the string! - view = bytes(view) + view = view.tobytes() # dont call call ffi.from_buffer(bytes(view)), arguments # like ints/bools should result in a TypeError return ffi.from_buffer(view) diff --git a/lib_pypy/_cffi_ssl/_stdssl/win32_extra.py b/lib_pypy/_cffi_ssl/_stdssl/win32_extra.py --- a/lib_pypy/_cffi_ssl/_stdssl/win32_extra.py +++ b/lib_pypy/_cffi_ssl/_stdssl/win32_extra.py @@ -1,101 +1,101 @@ from _pypy_openssl import lib, ffi - - -def enum_certificates(store_name): - """Retrieve certificates from Windows' cert store. - -store_name may be one of 'CA', 'ROOT' or 'MY'. The system may provide -more cert storages, too. The function returns a list of (bytes, -encoding_type, trust) tuples. The encoding_type flag can be interpreted -with X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. The trust setting is either -a set of OIDs or the boolean True. - """ - hStore = lib.CertOpenStore(lib.CERT_STORE_PROV_SYSTEM_A, 0, ffi.NULL, - lib.CERT_STORE_READONLY_FLAG | lib.CERT_SYSTEM_STORE_LOCAL_MACHINE, - bytes(store_name, "ascii")) - if hStore == ffi.NULL: - raise WindowsError(*ffi.getwinerror()) - - result = [] - pCertCtx = ffi.NULL - try: - while True: - pCertCtx = lib.CertEnumCertificatesInStore(hStore, pCertCtx) - if pCertCtx == ffi.NULL: - break - cert = ffi.buffer(pCertCtx.pbCertEncoded, pCertCtx.cbCertEncoded)[:] - enc = certEncodingType(pCertCtx.dwCertEncodingType) - keyusage = parseKeyUsage(pCertCtx, lib.CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG) - if keyusage is True: - keyusage = parseKeyUsage(pCertCtx, lib.CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG) - result.append((cert, enc, keyusage)) - finally: - if pCertCtx != ffi.NULL: - lib.CertFreeCertificateContext(pCertCtx) - if not lib.CertCloseStore(hStore, 0): - # This error case might shadow another exception. - raise WindowsError(*ffi.getwinerror()) - return result - - -def enum_crls(store_name): - """Retrieve CRLs from Windows' cert store. - -store_name may be one of 'CA', 'ROOT' or 'MY'. The system may provide -more cert storages, too. The function returns a list of (bytes, -encoding_type) tuples. The encoding_type flag can be interpreted with -X509_ASN_ENCODING or PKCS_7_ASN_ENCODING.""" - hStore = lib.CertOpenStore(lib.CERT_STORE_PROV_SYSTEM_A, 0, ffi.NULL, - lib.CERT_STORE_READONLY_FLAG | lib.CERT_SYSTEM_STORE_LOCAL_MACHINE, - bytes(store_name, "ascii")) - if hStore == ffi.NULL: - raise WindowsError(*ffi.getwinerror()) - - result = [] - pCrlCtx = ffi.NULL - try: - while True: - pCrlCtx = lib.CertEnumCRLsInStore(hStore, pCrlCtx) - if pCrlCtx == ffi.NULL: - break - crl = ffi.buffer(pCrlCtx.pbCrlEncoded, pCrlCtx.cbCrlEncoded)[:] - enc = certEncodingType(pCrlCtx.dwCertEncodingType) - result.append((crl, enc)) - finally: - if pCrlCtx != ffi.NULL: - lib.CertFreeCRLContext(pCrlCtx) - if not lib.CertCloseStore(hStore, 0): - # This error case might shadow another exception. - raise WindowsError(*ffi.getwinerror()) - return result - - -def certEncodingType(encodingType): - if encodingType == lib.X509_ASN_ENCODING: - return "x509_asn" - if encodingType == lib.PKCS_7_ASN_ENCODING: - return "pkcs_7_asn" - return encodingType - -def parseKeyUsage(pCertCtx, flags): - pSize = ffi.new("DWORD *") - if not lib.CertGetEnhancedKeyUsage(pCertCtx, flags, ffi.NULL, pSize): - error_with_message = ffi.getwinerror() - if error_with_message[0] == lib.CRYPT_E_NOT_FOUND: - return True - raise WindowsError(*error_with_message) - - pUsageMem = ffi.new("char[]", pSize[0]) - pUsage = ffi.cast("PCERT_ENHKEY_USAGE", pUsageMem) - if not lib.CertGetEnhancedKeyUsage(pCertCtx, flags, pUsage, pSize): - error_with_message = ffi.getwinerror() - if error_with_message[0] == lib.CRYPT_E_NOT_FOUND: - return True - raise WindowsError(*error_with_message) - - retval = set() - for i in range(pUsage.cUsageIdentifier): - if pUsage.rgpszUsageIdentifier[i]: - oid = ffi.string(pUsage.rgpszUsageIdentifier[i]).decode('ascii') - retval.add(oid) - return retval + + +def enum_certificates(store_name): + """Retrieve certificates from Windows' cert store. + +store_name may be one of 'CA', 'ROOT' or 'MY'. The system may provide +more cert storages, too. The function returns a list of (bytes, +encoding_type, trust) tuples. The encoding_type flag can be interpreted +with X509_ASN_ENCODING or PKCS_7_ASN_ENCODING. The trust setting is either +a set of OIDs or the boolean True. + """ + hStore = lib.CertOpenStore(lib.CERT_STORE_PROV_SYSTEM_A, 0, ffi.NULL, + lib.CERT_STORE_READONLY_FLAG | lib.CERT_SYSTEM_STORE_LOCAL_MACHINE, + bytes(store_name, "ascii")) + if hStore == ffi.NULL: + raise WindowsError(*ffi.getwinerror()) + + result = [] + pCertCtx = ffi.NULL + try: + while True: + pCertCtx = lib.CertEnumCertificatesInStore(hStore, pCertCtx) + if pCertCtx == ffi.NULL: + break + cert = ffi.buffer(pCertCtx.pbCertEncoded, pCertCtx.cbCertEncoded)[:] + enc = certEncodingType(pCertCtx.dwCertEncodingType) + keyusage = parseKeyUsage(pCertCtx, lib.CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG) + if keyusage is True: + keyusage = parseKeyUsage(pCertCtx, lib.CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG) + result.append((cert, enc, keyusage)) + finally: + if pCertCtx != ffi.NULL: + lib.CertFreeCertificateContext(pCertCtx) + if not lib.CertCloseStore(hStore, 0): + # This error case might shadow another exception. + raise WindowsError(*ffi.getwinerror()) + return result + + +def enum_crls(store_name): + """Retrieve CRLs from Windows' cert store. + +store_name may be one of 'CA', 'ROOT' or 'MY'. The system may provide +more cert storages, too. The function returns a list of (bytes, +encoding_type) tuples. The encoding_type flag can be interpreted with +X509_ASN_ENCODING or PKCS_7_ASN_ENCODING.""" + hStore = lib.CertOpenStore(lib.CERT_STORE_PROV_SYSTEM_A, 0, ffi.NULL, + lib.CERT_STORE_READONLY_FLAG | lib.CERT_SYSTEM_STORE_LOCAL_MACHINE, + bytes(store_name, "ascii")) + if hStore == ffi.NULL: + raise WindowsError(*ffi.getwinerror()) + + result = [] + pCrlCtx = ffi.NULL + try: + while True: + pCrlCtx = lib.CertEnumCRLsInStore(hStore, pCrlCtx) + if pCrlCtx == ffi.NULL: + break From pypy.commits at gmail.com Wed Jul 24 13:47:39 2019 From: pypy.commits at gmail.com (rlamy) Date: Wed, 24 Jul 2019 10:47:39 -0700 (PDT) Subject: [pypy-commit] pypy py3tests: dummy merge with apptest-file Message-ID: <5d3899bb.1c69fb81.59d5a.9186@mx.google.com> Author: Ronan Lamy Branch: py3tests Changeset: r97024:c3e614c36972 Date: 2019-07-24 18:46 +0100 http://bitbucket.org/pypy/pypy/changeset/c3e614c36972/ Log: dummy merge with apptest-file From pypy.commits at gmail.com Thu Jul 25 03:26:21 2019 From: pypy.commits at gmail.com (Raemi) Date: Thu, 25 Jul 2019 00:26:21 -0700 (PDT) Subject: [pypy-commit] extradoc extradoc: some final improvements from my side Message-ID: <5d39599d.1c69fb81.536f7.3031@mx.google.com> Author: Remi Meier Branch: extradoc Changeset: r5955:e71b2e056b2f Date: 2019-07-25 09:25 +0200 http://bitbucket.org/pypy/extradoc/changeset/e71b2e056b2f/ Log: some final improvements from my side diff --git a/blog/draft/2019-07-arm64.rst b/blog/draft/2019-07-arm64.rst --- a/blog/draft/2019-07-arm64.rst +++ b/blog/draft/2019-07-arm64.rst @@ -2,59 +2,64 @@ We are pleased to announce the availability of the new PyPy for AArch64. This port brings PyPy's high-performance just-in-time compiler to the AArch64 -platform, also known as 64-bit ARM. This work was funded by ARM Holdings Ltd. -and Crossbar.io. +platform, also known as 64-bit ARM. With the addition of AArch64, PyPy now +supports a total of 6 architectures: x86 (32 & 64bit), ARM (32 & 64bit), PPC64, +and s390x. The AArch64 work was funded by ARM Holdings Ltd. and Crossbar.io. -To show how well the new PyPy port performs, we compare the performance of PyPy -against CPython on a set of benchmarks. As a point of comparison, we include the -results of PyPy on x86_64. Note, however, that the results presented here were -measured on a Graviton A1 machine from AWS, which comes with a very serious -word of warning: Graviton A1's are -virtual machines and as such, are not suitable for benchmarking. If someone -has access to a beefy enough (16G) ARM64 server and is willing to give -us access to it, we are happy to redo the benchmarks on a real machine. -Our main concern here is that while a virtual CPU is 1-to-1 with a real CPU, it's -not clear to us how caches are shared, and how they cross CPU boundaries. +PyPy has a good record of boosting the performance of Python programs on the +existing platforms. To show how well the new PyPy port performs, we compare the +performance of PyPy against CPython on a set of benchmarks. As a point of +comparison, we include the results of PyPy on x86_64. -The following graph shows the speedup of PyPy (hg id 2417f925ce94) compared to -CPython (2.7.15) on AArch64, as well as the speedups on a x86_64 Linux laptop, +Note, however, that the results presented here were measured on a Graviton A1 +machine from AWS, which comes with a very serious word of warning: Graviton A1's +are virtual machines, and, as such, they are not suitable for benchmarking. If +someone has access to a beefy enough (16G) ARM64 server and is willing to give +us access to it, we are happy to redo the benchmarks on a real machine. One +major concern is that while a virtual CPU is 1-to-1 with a real CPU, it is not +clear to us how CPU caches are shared across virtual CPUs. Also, note that by no +means is this benchmark suite representative enough to average the results. Read +the numbers individually per benchmark. + +The following graph shows the speedups on AArch64 of PyPy (hg id 2417f925ce94) compared to +CPython (2.7.15), as well as the speedups on a x86_64 Linux laptop comparing the most recent release, PyPy 7.1.1, to CPython 2.7.16. .. image:: 2019-07-arm64-speedups.png In the majority of benchmarks, the speedups achieved on AArch64 match those achieved on the x86_64 laptop. Over CPython, PyPy on AArch64 achieves speedups -between 0.6x to 44.9x. These speedups are comparable to x86_64, where they are -between 0.6x and 58.9x. +between 0.6x to 44.9x. These speedups are comparable to x86_64, where the +numbers are between 0.6x and 58.9x. The next graph compares between the speedups achieved on AArch64 to the speedups -achieved on x86_64, i.e., how much the speedup is on AArch64 vs. the same -benchmark on x86_64. Note that by no means is this benchmark suite -representative enough to average the results. Read the numbers individually per -benchmark. +achieved on x86_64, i.e., how great the speedup is on AArch64 vs. the same +benchmark on x86_64. This comparison should give a rough idea about the +quality of the generated code for the new platform. .. image:: 2019-07-arm64-relative.png -Note also that we see a wide variance. There are generally three groups of +Note that we see a large variance: There are generally three groups of benchmarks - those that run at more or less the same speed, those that -run at 2x the speed and those that run at 0.5x the speed of x86_64. +run at 2x the speed, and those that run at 0.5x the speed of x86_64. The variance and disparity are likely related to a variety of issues, mostly due -to differences in architecture. What *is* however interesting is that compared +to differences in architecture. What *is* however interesting is that, compared to measurements performed on older ARM boards, the branch predictor on the Graviton A1 machine appears to have improved. As a result, the speedups achieved -by PyPy over CPython are smaller: "sophisticated" branchy code, like CPython -itself, simply runs a lot faster. +by PyPy over CPython are smaller than on older ARM boards: sufficiently branchy +code, like CPython itself, simply runs a lot faster. As a result, the advantage +of the non-branchy code generated by PyPy's just-in-time compiler is smaller. -One takeaway here is that there is a lot of improvement left to be done -in PyPy. This is true for both of the above platforms, but probably more -so for AArch64, which comes with a large number of registers. The PyPy -backend was written with x86 (the 32-bit variant) in mind, which is very -register poor. We think we can improve somewhat in the area of emitting -more modern machine code, which should have more impact for AArch64 -than for x86_64. There are also still a few missing features in the AArch64 -backend, which are implemented as calls instead of inlined instructions; -something we hope to improve. +One takeaway here is that many possible improvements for PyPy yet to be +implemented. This is true for both of the above platforms, but probably more so +for AArch64, which comes with a large number of CPU registers. The PyPy backend +was written with x86 (the 32-bit variant) in mind, which has a really low number +of registers. We think that we can improve in the area of emitting more modern +machine code, which may have a higher impact on AArch64 than on x86_64. There is +also a number of missing features in the AArch64 backend. These features are +currently implemented as expensive function calls instead of inlined native +instructions, something we intend to improve. Best, Maciej Fijalkowski, Armin Rigo and the PyPy team From pypy.commits at gmail.com Thu Jul 25 03:44:12 2019 From: pypy.commits at gmail.com (Raemi) Date: Thu, 25 Jul 2019 00:44:12 -0700 (PDT) Subject: [pypy-commit] extradoc extradoc: final fixes.. Message-ID: <5d395dcc.1c69fb81.3c153.546c@mx.google.com> Author: Remi Meier Branch: extradoc Changeset: r5956:f800f7a9c095 Date: 2019-07-25 09:44 +0200 http://bitbucket.org/pypy/extradoc/changeset/f800f7a9c095/ Log: final fixes.. diff --git a/blog/draft/2019-07-arm64.rst b/blog/draft/2019-07-arm64.rst --- a/blog/draft/2019-07-arm64.rst +++ b/blog/draft/2019-07-arm64.rst @@ -48,10 +48,10 @@ to measurements performed on older ARM boards, the branch predictor on the Graviton A1 machine appears to have improved. As a result, the speedups achieved by PyPy over CPython are smaller than on older ARM boards: sufficiently branchy -code, like CPython itself, simply runs a lot faster. As a result, the advantage +code, like CPython itself, simply runs a lot faster. Hence, the advantage of the non-branchy code generated by PyPy's just-in-time compiler is smaller. -One takeaway here is that many possible improvements for PyPy yet to be +One takeaway here is that many possible improvements for PyPy have yet to be implemented. This is true for both of the above platforms, but probably more so for AArch64, which comes with a large number of CPU registers. The PyPy backend was written with x86 (the 32-bit variant) in mind, which has a really low number @@ -62,4 +62,5 @@ instructions, something we intend to improve. Best, + Maciej Fijalkowski, Armin Rigo and the PyPy team From pypy.commits at gmail.com Thu Jul 25 08:08:09 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 25 Jul 2019 05:08:09 -0700 (PDT) Subject: [pypy-commit] pypy default: Fix for 19e211d4c76b (oops, sorry) Message-ID: <5d399ba9.1c69fb81.90047.8fef@mx.google.com> Author: Armin Rigo Branch: Changeset: r97025:2315521d2c5d Date: 2019-07-25 14:07 +0200 http://bitbucket.org/pypy/pypy/changeset/2315521d2c5d/ Log: Fix for 19e211d4c76b (oops, sorry) diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -1365,12 +1365,11 @@ class scoped_nonmoving_unicodebuffer: def __init__(self, data): - self.data = data + self.buf, self.llobj, self.flag = get_nonmoving_unicodebuffer_ll(data) def __enter__(self): - self.buf, self.flag = get_nonmoving_unicodebuffer(self.data) return self.buf def __exit__(self, *args): - free_nonmoving_unicodebuffer(self.data, self.buf, self.flag) + free_nonmoving_unicodebuffer_ll(self.buf, self.llobj, self.flag) __init__._always_inline_ = 'try' __enter__._always_inline_ = 'try' __exit__._always_inline_ = 'try' diff --git a/rpython/rtyper/lltypesystem/test/test_rffi.py b/rpython/rtyper/lltypesystem/test/test_rffi.py --- a/rpython/rtyper/lltypesystem/test/test_rffi.py +++ b/rpython/rtyper/lltypesystem/test/test_rffi.py @@ -917,6 +917,15 @@ assert buf[2] == 'r' assert buf[3] == '\x00' +def test_scoped_nonmoving_unicodebuffer(): + s = u'bar' + with scoped_nonmoving_unicodebuffer(s) as buf: + assert buf[0] == u'b' + assert buf[1] == u'a' + assert buf[2] == u'r' + with py.test.raises(IndexError): + buf[3] + def test_wcharp2utf8n(): w = 'hello\x00\x00\x00\x00' u, i = wcharp2utf8n(w, len(w)) From pypy.commits at gmail.com Thu Jul 25 08:10:15 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 25 Jul 2019 05:10:15 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: hg merge default Message-ID: <5d399c27.1c69fb81.e0a41.c9da@mx.google.com> Author: Armin Rigo Branch: py3.6 Changeset: r97026:6667f0f93e93 Date: 2019-07-25 14:09 +0200 http://bitbucket.org/pypy/pypy/changeset/6667f0f93e93/ Log: hg merge default diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -297,6 +297,16 @@ arg, res = arglocs self.mc.FSQRT_dd(res.value, arg.value) + def threadlocalref_get(self, op, arglocs): + res_loc, = arglocs + ofs_loc = self.imm(op.getarg(1).getint()) + calldescr = op.getdescr() + ofs = self.saved_threadlocal_addr + self.load_reg(self.mc, res_loc, r.sp, ofs) + scale = get_scale(calldescr.get_result_size()) + signed = (calldescr.is_result_signed() != 0) + self._load_from_mem(res_loc, res_loc, ofs_loc, scale, signed) + emit_op_float_lt = gen_float_comp_op('float_lt', c.VFP_LT) emit_op_float_le = gen_float_comp_op('float_le', c.VFP_LE) emit_op_float_eq = gen_float_comp_op('float_eq', c.EQ) diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -506,6 +506,10 @@ res = self.force_allocate_reg(op) return [loc1, res] + def _prepare_threadlocalref_get(self, op): + res_loc = self.force_allocate_reg(op) + return [res_loc] + prepare_op_convert_float_bytes_to_longlong = prepare_unary prepare_op_convert_longlong_bytes_to_float = prepare_unary @@ -583,10 +587,10 @@ args = self._prepare_op_math_sqrt(op) self.assembler.math_sqrt(op, args) return - #elif oopspecindex == EffectInfo.OS_THREADLOCALREF_GET: - # args = self._prepare_threadlocalref_get(op, fcond) - # self.perform_extra(op, args, fcond) - # return + elif oopspecindex == EffectInfo.OS_THREADLOCALREF_GET: + args = self._prepare_threadlocalref_get(op) + self.assembler.threadlocalref_get(op, args) + return #elif oopspecindex == EffectInfo.OS_MATH_READ_TIMESTAMP: # ... return self._prepare_call(op) diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -1365,12 +1365,11 @@ class scoped_nonmoving_unicodebuffer: def __init__(self, data): - self.data = data + self.buf, self.llobj, self.flag = get_nonmoving_unicodebuffer_ll(data) def __enter__(self): - self.buf, self.flag = get_nonmoving_unicodebuffer(self.data) return self.buf def __exit__(self, *args): - free_nonmoving_unicodebuffer(self.data, self.buf, self.flag) + free_nonmoving_unicodebuffer_ll(self.buf, self.llobj, self.flag) __init__._always_inline_ = 'try' __enter__._always_inline_ = 'try' __exit__._always_inline_ = 'try' diff --git a/rpython/rtyper/lltypesystem/test/test_rffi.py b/rpython/rtyper/lltypesystem/test/test_rffi.py --- a/rpython/rtyper/lltypesystem/test/test_rffi.py +++ b/rpython/rtyper/lltypesystem/test/test_rffi.py @@ -917,6 +917,15 @@ assert buf[2] == 'r' assert buf[3] == '\x00' +def test_scoped_nonmoving_unicodebuffer(): + s = u'bar' + with scoped_nonmoving_unicodebuffer(s) as buf: + assert buf[0] == u'b' + assert buf[1] == u'a' + assert buf[2] == u'r' + with py.test.raises(IndexError): + buf[3] + def test_wcharp2utf8n(): w = 'hello\x00\x00\x00\x00' u, i = wcharp2utf8n(w, len(w)) From pypy.commits at gmail.com Thu Jul 25 11:21:00 2019 From: pypy.commits at gmail.com (arigo) Date: Thu, 25 Jul 2019 08:21:00 -0700 (PDT) Subject: [pypy-commit] pypy default: cpyext: add a workaround that should make one case work (typically seen only Message-ID: <5d39c8dc.1c69fb81.d5363.42cd@mx.google.com> Author: Armin Rigo Branch: Changeset: r97027:c89821342184 Date: 2019-07-25 17:20 +0200 http://bitbucket.org/pypy/pypy/changeset/c89821342184/ Log: cpyext: add a workaround that should make one case work (typically seen only with C++ code) diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py --- a/pypy/module/cpyext/api.py +++ b/pypy/module/cpyext/api.py @@ -1004,6 +1004,12 @@ deadlock_error(pname) rgil.acquire() assert cpyext_glob_tid_ptr[0] == 0 + if gil_auto_workaround: + # while we're in workaround-land, detect when a regular PyXxx() + # function is invoked at .so load-time, e.g. by a C++ global + # variable with an initializer, and in this case make sure we + # initialize things. + space.fromcache(State).make_sure_cpyext_is_imported() elif pygilstate_ensure: if cpyext_glob_tid_ptr[0] == tid: cpyext_glob_tid_ptr[0] = 0 @@ -1719,8 +1725,8 @@ def load_cpyext_module(space, name, path, dll, initptr): from rpython.rlib import rdynload - space.getbuiltinmodule("cpyext") # mandatory to init cpyext state = space.fromcache(State) + state.make_sure_cpyext_is_imported() w_mod = state.find_extension(name, path) if w_mod is not None: rdynload.dlclose(dll) diff --git a/pypy/module/cpyext/state.py b/pypy/module/cpyext/state.py --- a/pypy/module/cpyext/state.py +++ b/pypy/module/cpyext/state.py @@ -45,6 +45,13 @@ # XXX will leak if _PyDateTime_Import already called self.datetimeAPI = [] + self.cpyext_is_imported = False + + def make_sure_cpyext_is_imported(self): + if not self.cpyext_is_imported: + self.space.getbuiltinmodule("cpyext") # mandatory to init cpyext + self.cpyext_is_imported = True + def set_exception(self, operror): self.clear_exception() ec = self.space.getexecutioncontext() From pypy.commits at gmail.com Thu Jul 25 15:16:09 2019 From: pypy.commits at gmail.com (rlamy) Date: Thu, 25 Jul 2019 12:16:09 -0700 (PDT) Subject: [pypy-commit] pypy apptest-file: Use a separate flag for new-style apptests Message-ID: <5d39fff9.1c69fb81.8c392.3916@mx.google.com> Author: Ronan Lamy Branch: apptest-file Changeset: r97028:d7026dea7f27 Date: 2019-07-25 20:15 +0100 http://bitbucket.org/pypy/pypy/changeset/d7026dea7f27/ Log: Use a separate flag for new-style apptests diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -45,13 +45,17 @@ def pytest_configure(config): global option option = config.option - config.addinivalue_line('python_files', APPLEVEL_FN) + if config.getoption('direct_apptest') or not config.getoption('runappdirect'): + config.addinivalue_line('python_files', APPLEVEL_FN) def pytest_addoption(parser): group = parser.getgroup("pypy options") group.addoption('-A', '--runappdirect', action="store_true", default=False, dest="runappdirect", - help="run applevel tests directly on python interpreter (not through PyPy)") + help="run legacy applevel tests directly on python interpreter (not through PyPy)") + group.addoption('-D', '--direct-apptest', action="store_true", + default=False, dest="direct_apptest", + help="run applevel_XXX.py tests directly on host interpreter") group.addoption('--direct', action="store_true", default=False, dest="rundirect", help="run pexpect tests directly") @@ -92,7 +96,7 @@ def pytest_pycollect_makemodule(path, parent): if path.fnmatch(APPLEVEL_FN): - if parent.config.getoption('runappdirect'): + if parent.config.getoption('direct_apptest'): return from pypy.tool.pytest.apptest2 import AppTestModule rewrite = parent.config.getoption('applevel_rewrite') @@ -196,6 +200,8 @@ appclass.obj.space = LazyObjSpaceGetter() appclass.obj.runappdirect = option.runappdirect - def pytest_ignore_collect(path, config): + if (config.getoption('direct_apptest') and not path.isdir() + and not path.fnmatch(APPLEVEL_FN)): + return True return path.check(link=1) diff --git a/pypy/module/_cppyy/test/conftest.py b/pypy/module/_cppyy/test/conftest.py --- a/pypy/module/_cppyy/test/conftest.py +++ b/pypy/module/_cppyy/test/conftest.py @@ -41,17 +41,14 @@ disabled = None def pytest_configure(config): - if config.getoption('runappdirect'): - return + if config.getoption('runappdirect') or config.getoption('direct_apptest'): + return # "can't run dummy tests in -A" if py.path.local.sysfind('genreflex') is None: import pypy.module._cppyy.capi.loadable_capi as lcapi try: import ctypes ctypes.CDLL(lcapi.backend_library) except Exception as e: - if config.option.runappdirect: - return # "can't run dummy tests in -A" - # build dummy backend (which has reflex info and calls hard-wired) import os from rpython.translator.tool.cbuild import ExternalCompilationInfo From pypy.commits at gmail.com Thu Jul 25 22:16:34 2019 From: pypy.commits at gmail.com (rlamy) Date: Thu, 25 Jul 2019 19:16:34 -0700 (PDT) Subject: [pypy-commit] pypy apptest-file: Make 'pytest -D' runs compatible with recent versions of pytest Message-ID: <5d3a6282.1c69fb81.4971d.bab0@mx.google.com> Author: Ronan Lamy Branch: apptest-file Changeset: r97029:a41d9a2f1935 Date: 2019-07-26 03:15 +0100 http://bitbucket.org/pypy/pypy/changeset/a41d9a2f1935/ Log: Make 'pytest -D' runs compatible with recent versions of pytest diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -38,15 +38,17 @@ def pytest_report_header(): return "pytest-%s from %s" % (pytest.__version__, pytest.__file__) -def pytest_addhooks(pluginmanager): - from rpython.conftest import LeakFinder - pluginmanager.register(LeakFinder()) - def pytest_configure(config): global option option = config.option - if config.getoption('direct_apptest') or not config.getoption('runappdirect'): + mode_A = config.getoption('runappdirect') + mode_D = config.getoption('direct_apptest') + if mode_D or not mode_A: config.addinivalue_line('python_files', APPLEVEL_FN) + if not mode_A and not mode_D: # 'own' tests + from rpython.conftest import LeakFinder + config.pluginmanager.register(LeakFinder()) + config.addinivalue_line('addopts', '--assert=reinterp') def pytest_addoption(parser): group = parser.getgroup("pypy options") @@ -109,7 +111,7 @@ return isinstance(item, AppTestFunction) def pytest_collection_modifyitems(config, items): - if config.option.runappdirect: + if config.getoption('runappdirect') or config.getoption('direct_apptest'): return for item in items: if isinstance(item, py.test.Function): diff --git a/pypy/module/cpyext/test/conftest.py b/pypy/module/cpyext/test/conftest.py --- a/pypy/module/cpyext/test/conftest.py +++ b/pypy/module/cpyext/test/conftest.py @@ -2,7 +2,7 @@ import pytest def pytest_configure(config): - if config.option.runappdirect: + if config.getoption('runappdirect') or config.getoption('direct_apptest'): import sys import py from pypy import pypydir @@ -20,7 +20,8 @@ import pypy.module.cpyext.test.test_cpyext -def pytest_funcarg__api(request): + at pytest.fixture +def api(request): return request.cls.api if os.name == 'nt': diff --git a/pytest.ini b/pytest.ini --- a/pytest.ini +++ b/pytest.ini @@ -1,2 +1,2 @@ [pytest] -addopts = --assert=reinterp -rf +addopts = -rf From pypy.commits at gmail.com Fri Jul 26 13:40:09 2019 From: pypy.commits at gmail.com (rlamy) Date: Fri, 26 Jul 2019 10:40:09 -0700 (PDT) Subject: [pypy-commit] pypy apptest-file: --assert=reinterp needs to be passed earlier to have an effect Message-ID: <5d3b3af9.1c69fb81.73dc2.047d@mx.google.com> Author: Ronan Lamy Branch: apptest-file Changeset: r97030:eb81f61e9baa Date: 2019-07-26 18:39 +0100 http://bitbucket.org/pypy/pypy/changeset/eb81f61e9baa/ Log: --assert=reinterp needs to be passed earlier to have an effect diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -38,6 +38,11 @@ def pytest_report_header(): return "pytest-%s from %s" % (pytest.__version__, pytest.__file__) + at pytest.hookimpl(tryfirst=True) +def pytest_cmdline_preparse(config, args): + if not (set(args) & {'-D', '--direct-apptest'}): + args.append('--assert=reinterp') + def pytest_configure(config): global option option = config.option @@ -48,7 +53,6 @@ if not mode_A and not mode_D: # 'own' tests from rpython.conftest import LeakFinder config.pluginmanager.register(LeakFinder()) - config.addinivalue_line('addopts', '--assert=reinterp') def pytest_addoption(parser): group = parser.getgroup("pypy options") From pypy.commits at gmail.com Mon Jul 29 12:23:00 2019 From: pypy.commits at gmail.com (rlamy) Date: Mon, 29 Jul 2019 09:23:00 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Add missing branches to whatsnew Message-ID: <5d3f1d64.1c69fb81.e5628.1730@mx.google.com> Author: Ronan Lamy Branch: py3.6 Changeset: r97031:72f1ec088dc7 Date: 2019-07-29 17:22 +0100 http://bitbucket.org/pypy/pypy/changeset/72f1ec088dc7/ Log: Add missing branches to whatsnew diff --git a/pypy/doc/whatsnew-pypy3-head.rst b/pypy/doc/whatsnew-pypy3-head.rst --- a/pypy/doc/whatsnew-pypy3-head.rst +++ b/pypy/doc/whatsnew-pypy3-head.rst @@ -16,3 +16,13 @@ .. branch: setitem2d Allow 2d indexing in ``memoryview.__setitem__`` (issue bb-3028) + +.. branch: py3.6-socket-fix +.. branch: fix-importerror +.. branch: dj_s390 +.. branch: bpo-35409 +.. branch: remove_array_with_char_test +.. branch: fix_test_unicode_outofrange +.. branch: Ram-Rachum/faulthandleris_enabled-should-return-fal-1563636614875 +.. branch: Anthony-Sottile/fix-leak-of-file-descriptor-with-_iofile-1559687440863 + From pypy.commits at gmail.com Mon Jul 29 14:30:50 2019 From: pypy.commits at gmail.com (rlamy) Date: Mon, 29 Jul 2019 11:30:50 -0700 (PDT) Subject: [pypy-commit] pypy py3.6: Skip pypy-incompatible test (see issue #3048) Message-ID: <5d3f3b5a.1c69fb81.843ee.1fad@mx.google.com> Author: Ronan Lamy Branch: py3.6 Changeset: r97032:73b10d9d0f3e Date: 2019-07-29 19:29 +0100 http://bitbucket.org/pypy/pypy/changeset/73b10d9d0f3e/ Log: Skip pypy-incompatible test (see issue #3048) diff --git a/lib-python/3/test/test_warnings/__init__.py b/lib-python/3/test/test_warnings/__init__.py --- a/lib-python/3/test/test_warnings/__init__.py +++ b/lib-python/3/test/test_warnings/__init__.py @@ -843,13 +843,14 @@ class PyWarningsDisplayTests(WarningsDisplayTests, unittest.TestCase): module = py_warnings + @support.cpython_only # no tracemalloc on pypy def test_tracemalloc(self): self.addCleanup(support.unlink, support.TESTFN) with open(support.TESTFN, 'w') as fp: fp.write(textwrap.dedent(""" import gc - + def func(): f = open(__file__) # Fully initialise GC for clearer error @@ -868,8 +869,8 @@ stderr = '\n'.join(stderr.splitlines()) stderr = re.sub('<.*>', '<...>', stderr) expected = textwrap.dedent(''' - {fname}:9: ResourceWarning: unclosed file <...> - f = None + {fname}:10: ResourceWarning: unclosed file <...> + gc.collect() Object allocated at (most recent call first): File "{fname}", lineno 5 f = open(__file__) From pypy.commits at gmail.com Tue Jul 30 12:15:57 2019 From: pypy.commits at gmail.com (rlamy) Date: Tue, 30 Jul 2019 09:15:57 -0700 (PDT) Subject: [pypy-commit] pypy apptest-file: Update testing docs Message-ID: <5d406d3d.1c69fb81.46a14.643b@mx.google.com> Author: Ronan Lamy Branch: apptest-file Changeset: r97033:6662c6e06a92 Date: 2019-07-30 17:14 +0100 http://bitbucket.org/pypy/pypy/changeset/6662c6e06a92/ Log: Update testing docs diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst --- a/pypy/doc/coding-guide.rst +++ b/pypy/doc/coding-guide.rst @@ -456,13 +456,10 @@ Testing modules in ``lib_pypy/`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can go to the :source:`pypy/module/test_lib_pypy/` directory and invoke the testing tool -("py.test" or "python ../../pypy/test_all.py") to run tests against the -lib_pypy hierarchy. Note, that tests in :source:`pypy/module/test_lib_pypy/` are allowed -and encouraged to let their tests run at interpreter level although -:source:`lib_pypy/` modules eventually live at PyPy's application level. -This allows us to quickly test our python-coded reimplementations -against CPython. +You can go to the :source:`pypy/module/test_lib_pypy/` directory and invoke the +testing tool ("py.test" or "python ../../pypy/test_all.py") to run tests +against the lib_pypy hierarchy. This allows us to quickly test our +python-coded reimplementations against CPython. Testing modules in ``pypy/module`` @@ -585,25 +582,42 @@ module global level and use plain 'assert' statements thanks to the usage of the `py.test`_ tool. - -Application Level tests +Application level tests ~~~~~~~~~~~~~~~~~~~~~~~ For testing the conformance and well-behavedness of PyPy it is often sufficient to write "normal" application-level Python code that doesn't need to be aware of any particular -coding style or restrictions. If we have a choice we often -use application level tests which usually look like this:: +coding style or restrictions. If we have a choice we often +use application level tests which are in files whose name starts with the +`apptest_` prefix and look like this:: - def app_test_something(): + def test_this(): # application level test code +These application level test functions will run on top +of PyPy, i.e. they have no access to interpreter details. + +By default, they run on top of an untranslated PyPy which runs on top of the +host interpreter. When passing the `-D` option, they run directly on top of the +host interpreter, which is usually a translated pypy executable in this case:: + + pypy3 -m pytest -D pypy/ + +Note that in interpreted mode, only a small subset of pytest's functionality is +available. + +Mixed-level tests (deprecated) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Mixed-level tests are similar to application-level tests, the difference being +that they're just snippets of app-level code embedded in an interp-level test +file, like this:: + class AppTestSomething(object): def test_this(self): # application level test code -These application level test functions will run on top -of PyPy, i.e. they have no access to interpreter details. You cannot use imported modules from global level because they are imported at interpreter-level while you test code runs at application level. If you need to use modules diff --git a/pypy/doc/contributing.rst b/pypy/doc/contributing.rst --- a/pypy/doc/contributing.rst +++ b/pypy/doc/contributing.rst @@ -329,11 +329,18 @@ Testing After Translation ^^^^^^^^^^^^^^^^^^^^^^^^^ -While the usual invocation of `pytest` translates a piece of RPython code and -runs it, we have a test extension to run tests without translation, directly -on the host python. This is very convenient for modules such as `cpyext`, to -compare and contrast test results between CPython and PyPy. Untranslated tests -are invoked by using the `-A` or `--runappdirect` option to `pytest`:: +While the usual invocation of `pytest` runs app-level tests on an untranslated +PyPy that runs on top of CPython, we have a test extension to run tests +directly on the host python. This is very convenient for modules such as +`cpyext`, to compare and contrast test results between CPython and PyPy. + +App-level tests run directly on the host interpreter when passing `-D` or +`--apptest-direct` to `pytest`:: + + pypy3 -m pytest -D pypy/interpreter/test/apptest_pyframe.py + +Mixed-level tests are invoked by using the `-A` or `--runappdirect` option to +`pytest`:: python2 pytest.py -A pypy/module/cpyext/test From pypy.commits at gmail.com Tue Jul 30 14:23:18 2019 From: pypy.commits at gmail.com (arigo) Date: Tue, 30 Jul 2019 11:23:18 -0700 (PDT) Subject: [pypy-commit] pypy default: Merged in Bystroushaak/pypy/feature_closed_prop_to_rfile (pull request #649) Message-ID: <5d408b16.1c69fb81.c3714.9bf1@mx.google.com> Author: Armin Rigo Branch: Changeset: r97036:cd5ae5acffdd Date: 2019-07-30 18:22 +0000 http://bitbucket.org/pypy/pypy/changeset/cd5ae5acffdd/ Log: Merged in Bystroushaak/pypy/feature_closed_prop_to_rfile (pull request #649) RFile; added property .closed to mirror standard `file` behaviour. diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py --- a/rpython/rlib/rfile.py +++ b/rpython/rlib/rfile.py @@ -312,6 +312,10 @@ if not self._ll_file: raise ValueError("I/O operation on closed file") + @property + def closed(self): + return not self._ll_file + def _fread(self, buf, n, stream): if not self._univ_newline: return c_fread(buf, 1, n, stream) diff --git a/rpython/rlib/test/test_rfile.py b/rpython/rlib/test/test_rfile.py --- a/rpython/rlib/test/test_rfile.py +++ b/rpython/rlib/test/test_rfile.py @@ -411,7 +411,10 @@ def f(): with open(fname, "w") as f: f.write("dupa") + assert not f.closed + try: + assert f.closed f.write("dupb") except ValueError: pass From pypy.commits at gmail.com Tue Jul 30 14:23:27 2019 From: pypy.commits at gmail.com (Bystroushaak) Date: Tue, 30 Jul 2019 11:23:27 -0700 (PDT) Subject: [pypy-commit] pypy feature_closed_prop_to_rfile: RFile; added property .closed to mirror standard `file` behaviour. Message-ID: <5d408b1f.1c69fb81.74fa4.c96a@mx.google.com> Author: Bystroushaak Branch: feature_closed_prop_to_rfile Changeset: r97034:5f379993c867 Date: 2019-07-09 17:26 +0200 http://bitbucket.org/pypy/pypy/changeset/5f379993c867/ Log: RFile; added property .closed to mirror standard `file` behaviour. diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py --- a/rpython/rlib/rfile.py +++ b/rpython/rlib/rfile.py @@ -312,6 +312,10 @@ if not self._ll_file: raise ValueError("I/O operation on closed file") + @property + def closed(self): + return not self._ll_file + def _fread(self, buf, n, stream): if not self._univ_newline: return c_fread(buf, 1, n, stream) From pypy.commits at gmail.com Tue Jul 30 14:23:29 2019 From: pypy.commits at gmail.com (Bystroushaak) Date: Tue, 30 Jul 2019 11:23:29 -0700 (PDT) Subject: [pypy-commit] pypy feature_closed_prop_to_rfile: RFile; added tests of the .closed property. Message-ID: <5d408b21.1c69fb81.ba0a4.1086@mx.google.com> Author: Bystroushaak Branch: feature_closed_prop_to_rfile Changeset: r97035:997051ecfc27 Date: 2019-07-29 16:34 +0200 http://bitbucket.org/pypy/pypy/changeset/997051ecfc27/ Log: RFile; added tests of the .closed property. diff --git a/rpython/rlib/test/test_rfile.py b/rpython/rlib/test/test_rfile.py --- a/rpython/rlib/test/test_rfile.py +++ b/rpython/rlib/test/test_rfile.py @@ -411,7 +411,10 @@ def f(): with open(fname, "w") as f: f.write("dupa") + assert not f.closed + try: + assert f.closed f.write("dupb") except ValueError: pass From pypy.commits at gmail.com Tue Jul 30 15:57:11 2019 From: pypy.commits at gmail.com (rlamy) Date: Tue, 30 Jul 2019 12:57:11 -0700 (PDT) Subject: [pypy-commit] pypy py3tests: Use -D flag for new-style apptests Message-ID: <5d40a117.1c69fb81.3cd03.ee24@mx.google.com> Author: Ronan Lamy Branch: py3tests Changeset: r97037:694c772c9e9f Date: 2019-07-30 18:14 +0100 http://bitbucket.org/pypy/pypy/changeset/694c772c9e9f/ Log: Use -D flag for new-style apptests diff --git a/pypy/conftest.py b/pypy/conftest.py --- a/pypy/conftest.py +++ b/pypy/conftest.py @@ -47,31 +47,39 @@ def pytest_report_header(): return "pytest-%s from %s" % (pytest.__version__, pytest.__file__) -def pytest_addhooks(pluginmanager): - if sys.version_info < (3,): - from rpython.conftest import LeakFinder - pluginmanager.register(LeakFinder()) + at pytest.hookimpl(tryfirst=True) +def pytest_cmdline_preparse(config, args): + if not (set(args) & {'-D', '--direct-apptest'}): + args.append('--assert=reinterp') def pytest_configure(config): - if HOST_IS_PY3 and not config.getoption('runappdirect'): + if HOST_IS_PY3 and not config.getoption('direct_apptest'): raise ValueError( - "On top of a Python 3 interpreter, the -A flag is mandatory") + "On top of a Python 3 interpreter, the -D flag is mandatory") global option option = config.option + mode_A = config.getoption('runappdirect') + mode_D = config.getoption('direct_apptest') def py3k_skip(message): py.test.skip('[py3k] %s' % message) py.test.py3k_skip = py3k_skip - if HOST_IS_PY3 or not config.getoption('runappdirect'): + if mode_D or not mode_A: config.addinivalue_line('python_files', APPLEVEL_FN) + if not mode_A and not mode_D: # 'own' tests + from rpython.conftest import LeakFinder + config.pluginmanager.register(LeakFinder()) def pytest_addoption(parser): group = parser.getgroup("pypy options") group.addoption('-A', '--runappdirect', action="store_true", default=False, dest="runappdirect", - help="run applevel tests directly on the python interpreter " + + help="run legacy applevel tests directly on the python interpreter " + "specified by --python") group.addoption('--python', type="string", default=PYTHON3, help="python interpreter to run appdirect tests with") + group.addoption('-D', '--direct-apptest', action="store_true", + default=False, dest="direct_apptest", + help="run applevel_XXX.py tests directly on host interpreter") group.addoption('--direct', action="store_true", default=False, dest="rundirect", help="run pexpect tests directly") @@ -114,9 +122,9 @@ ensure_pytest_builtin_helpers() def pytest_pycollect_makemodule(path, parent): - if HOST_IS_PY3: - return - elif path.fnmatch(APPLEVEL_FN): + if path.fnmatch(APPLEVEL_FN): + if parent.config.getoption('direct_apptest'): + return from pypy.tool.pytest.apptest2 import AppTestModule rewrite = parent.config.getoption('applevel_rewrite') return AppTestModule(path, parent, rewrite_asserts=rewrite) @@ -128,7 +136,7 @@ return isinstance(item, AppTestFunction) def pytest_collection_modifyitems(config, items): - if config.option.runappdirect: + if config.getoption('runappdirect') or config.getoption('direct_apptest'): return for item in items: if isinstance(item, py.test.Function): @@ -219,8 +227,8 @@ appclass.obj.space = LazyObjSpaceGetter() appclass.obj.runappdirect = option.runappdirect - def pytest_ignore_collect(path, config): - if (HOST_IS_PY3 and not path.isdir() and not path.fnmatch(APPLEVEL_FN)): + if (config.getoption('direct_apptest') and not path.isdir() + and not path.fnmatch(APPLEVEL_FN)): return True return path.check(link=1) diff --git a/pypy/module/_continuation/test/conftest.py b/pypy/module/_continuation/test/conftest.py --- a/pypy/module/_continuation/test/conftest.py +++ b/pypy/module/_continuation/test/conftest.py @@ -2,6 +2,7 @@ def pytest_configure(config): if (not config.getoption('runappdirect') and + not config.getoption('direct_apptest') and sys.platform.startswith('linux')): from rpython.rlib.rvmprof.cintf import configure_libbacktrace_linux configure_libbacktrace_linux() diff --git a/pypy/module/_cppyy/test/conftest.py b/pypy/module/_cppyy/test/conftest.py --- a/pypy/module/_cppyy/test/conftest.py +++ b/pypy/module/_cppyy/test/conftest.py @@ -41,17 +41,14 @@ disabled = None def pytest_configure(config): - if config.getoption('runappdirect'): - return + if config.getoption('runappdirect') or config.getoption('direct_apptest'): + return # "can't run dummy tests in -A" if py.path.local.sysfind('genreflex') is None: import pypy.module._cppyy.capi.loadable_capi as lcapi try: import ctypes ctypes.CDLL(lcapi.backend_library) except Exception as e: - if config.option.runappdirect: - return # "can't run dummy tests in -A" - # build dummy backend (which has reflex info and calls hard-wired) import os from rpython.translator.tool.cbuild import ExternalCompilationInfo diff --git a/pypy/module/cpyext/test/conftest.py b/pypy/module/cpyext/test/conftest.py --- a/pypy/module/cpyext/test/conftest.py +++ b/pypy/module/cpyext/test/conftest.py @@ -2,7 +2,7 @@ import pytest def pytest_configure(config): - if config.option.runappdirect: + if config.getoption('runappdirect') or config.getoption('direct_apptest'): import sys import py from pypy import pypydir @@ -20,7 +20,8 @@ import pypy.module.cpyext.test.test_cpyext -def pytest_funcarg__api(request): + at pytest.fixture +def api(request): return request.cls.api if os.name == 'nt': diff --git a/pytest.ini b/pytest.ini --- a/pytest.ini +++ b/pytest.ini @@ -1,2 +1,2 @@ [pytest] -addopts = --assert=reinterp -rf +addopts = -rf From pypy.commits at gmail.com Wed Jul 31 09:06:29 2019 From: pypy.commits at gmail.com (rlamy) Date: Wed, 31 Jul 2019 06:06:29 -0700 (PDT) Subject: [pypy-commit] pypy apptest-file: fix option name Message-ID: <5d419255.1c69fb81.57d7e.a20c@mx.google.com> Author: Ronan Lamy Branch: apptest-file Changeset: r97038:0cc7bfd94fd8 Date: 2019-07-31 14:05 +0100 http://bitbucket.org/pypy/pypy/changeset/0cc7bfd94fd8/ Log: fix option name diff --git a/pypy/doc/contributing.rst b/pypy/doc/contributing.rst --- a/pypy/doc/contributing.rst +++ b/pypy/doc/contributing.rst @@ -335,7 +335,7 @@ `cpyext`, to compare and contrast test results between CPython and PyPy. App-level tests run directly on the host interpreter when passing `-D` or -`--apptest-direct` to `pytest`:: +`--direct-apptest` to `pytest`:: pypy3 -m pytest -D pypy/interpreter/test/apptest_pyframe.py From pypy.commits at gmail.com Wed Jul 31 12:35:47 2019 From: pypy.commits at gmail.com (rlamy) Date: Wed, 31 Jul 2019 09:35:47 -0700 (PDT) Subject: [pypy-commit] pypy apptest-file: remove one-shot helper script Message-ID: <5d41c363.1c69fb81.66c89.355c@mx.google.com> Author: Ronan Lamy Branch: apptest-file Changeset: r97039:d8e5b6784927 Date: 2019-07-31 17:32 +0100 http://bitbucket.org/pypy/pypy/changeset/d8e5b6784927/ Log: remove one-shot helper script diff --git a/rename_moduledef.py b/rename_moduledef.py deleted file mode 100644 --- a/rename_moduledef.py +++ /dev/null @@ -1,22 +0,0 @@ -import py -import subprocess - -here = py.path.local('.') -moddir = here / 'pypy' / 'module' -blacklist = ['test_lib_pypy'] -modules = [path for path in moddir.listdir() if - path.isdir() and (path / '__init__.py').isfile() and - path.basename not in blacklist] - - -def doit(p): - if not (p / '__init__.py').isfile(): - return - init = (p / '__init__.py').relto(here) - target = (p / 'moduledef.py').relto(here) - subprocess.call(['hg', 'mv', init, target]) - subprocess.call(['touch', init]) - subprocess.call(['hg', 'add', init]) - -for p in modules: - doit(p) From pypy.commits at gmail.com Wed Jul 31 12:49:45 2019 From: pypy.commits at gmail.com (rlamy) Date: Wed, 31 Jul 2019 09:49:45 -0700 (PDT) Subject: [pypy-commit] pypy py3tests: remove one-shot helper script Message-ID: <5d41c6a9.1c69fb81.ba0a4.fbd7@mx.google.com> Author: Ronan Lamy Branch: py3tests Changeset: r97040:f97eefdfc74e Date: 2019-07-31 17:49 +0100 http://bitbucket.org/pypy/pypy/changeset/f97eefdfc74e/ Log: remove one-shot helper script diff --git a/rename_moduledef.py b/rename_moduledef.py deleted file mode 100644 --- a/rename_moduledef.py +++ /dev/null @@ -1,22 +0,0 @@ -import py -import subprocess - -here = py.path.local('.') -moddir = here / 'pypy' / 'module' -blacklist = ['test_lib_pypy'] -modules = [path for path in moddir.listdir() if - path.isdir() and (path / '__init__.py').isfile() and - path.basename not in blacklist] - - -def doit(p): - if not (p / '__init__.py').isfile(): - return - init = (p / '__init__.py').relto(here) - target = (p / 'moduledef.py').relto(here) - subprocess.call(['hg', 'mv', init, target]) - subprocess.call(['touch', init]) - subprocess.call(['hg', 'add', init]) - -for p in modules: - doit(p)