[pypy-commit] pypy default: Kill unused method
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r64846:35e9a41d7bdd Date: 2013-06-11 11:56 +0200 http://bitbucket.org/pypy/pypy/changeset/35e9a41d7bdd/ Log:Kill unused method diff --git a/pypy/module/sys/__init__.py b/pypy/module/sys/__init__.py --- a/pypy/module/sys/__init__.py +++ b/pypy/module/sys/__init__.py @@ -103,11 +103,6 @@ 'flags' : 'app.null_sysflags', } -def setbuiltinmodule(self, w_module, name): -w_name = self.space.wrap(name) -w_modules = self.get('modules') -self.space.setitem(w_modules, w_name, w_module) - def startup(self, space): if space.config.translating and not we_are_translated(): # don't get the filesystemencoding at translation time ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Issue #1514
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r64847:92546f437072 Date: 2013-06-11 12:40 +0200 http://bitbucket.org/pypy/pypy/changeset/92546f437072/ Log:Issue #1514 A test for reimporting built-in modules (as opposed to reloading them). diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -565,6 +565,22 @@ assert sys.path is oldpath assert 'setdefaultencoding' in dir(sys) +def test_reimport_builtin(self): +# ...but not reload()! +import sys +oldpath = sys.path +sys.setdefaultencoding = test_reimport_builtin removed this + +del sys.modules['sys'] +import sys as sys1 +assert sys.modules['sys'] is sys1 is sys + +assert sys.path is oldpath +assert sys.setdefaultencoding == test_reimport_builtin removed this + +reload(sys) # fix it for people that want 'setdefaultencoding' +assert sys.setdefaultencoding != test_reimport_builtin removed this + def test_reload_infinite(self): import infinite_reload ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Fix for 92546f437072.
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r64848:f26956c61773 Date: 2013-06-11 12:41 +0200 http://bitbucket.org/pypy/pypy/changeset/f26956c61773/ Log:Fix for 92546f437072. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -381,8 +381,10 @@ except AttributeError: return self.__class__.__name__ -def setbuiltinmodule(self, importname): -NOT_RPYTHON. load a lazy pypy/module and put it into sys.modules +def _prepare_mixedmodule(self, importname): +NOT_RPYTHON. Load the RPython code of a lazy pypy/module and put +it into 'self.builtin_modules', without any further initialization. + if '.' in importname: fullname = importname importname = fullname.rsplit('.', 1)[1] @@ -401,20 +403,22 @@ return name -def getbuiltinmodule(self, name, force_init=False): -w_name = self.wrap(name) -w_modules = self.sys.get('modules') -try: -w_mod = self.getitem(w_modules, w_name) -except OperationError, e: -if not e.match(self, self.w_KeyError): -raise -else: -if not force_init: -return w_mod +@jit.elidable +def getbuiltinmodule(self, name): +Return the built-in module 'name'. The first time it is seen, +it is initialized and stored in 'sys.modules'. This function is +elidable by the JIT because its effect is idempotent (if you call +it twice with the same name, you're getting the same effect as if +it was only called once). + +return self.loadbuiltinmodule(name, force_in_sys_modules=False, + force_init=False) -# If the module is a builtin but not yet imported, -# retrieve it and initialize it +def loadbuiltinmodule(self, name, force_in_sys_modules, force_init): +For the importing logic. Get the built-in module, stick it +into 'sys.modules' if not initialized or if force_in_sys_modules, +and initialize it if it was not already or if force_init. + try: w_mod = self.builtin_modules[name] except KeyError: @@ -422,15 +426,20 @@ self.w_SystemError, getbuiltinmodule() called with non-builtin module %s, name) -else: -# Add the module to sys.modules -self.setitem(w_modules, w_name, w_mod) -# And initialize it -from pypy.interpreter.module import Module -if isinstance(w_mod, Module): -w_mod.init(self) -return w_mod +from pypy.interpreter.module import Module +if isinstance(w_mod, Module) and not w_mod.startup_called: +force_in_sys_modules = True # not initialized so far: +force_init = True# force initialization + +if force_in_sys_modules: +w_sys_modules = self.sys.get('modules') +self.setitem(w_sys_modules, self.wrap(name), w_mod) + +if force_init and isinstance(w_mod, Module): +w_mod.init(self) + +return w_mod def get_builtinmodule_to_install(self): NOT_RPYTHON @@ -547,12 +556,12 @@ def install_mixedmodule(self, mixedname, installed_builtin_modules): NOT_RPYTHON -modname = self.setbuiltinmodule(mixedname) -if modname: -assert modname not in installed_builtin_modules, ( -duplicate interp-level module enabled for the -app-level module %r % (modname,)) -installed_builtin_modules.append(modname) +modname = self._prepare_mixedmodule(mixedname) +assert modname +assert modname not in installed_builtin_modules, ( +duplicate interp-level module enabled for the +app-level module %r % (modname,)) +installed_builtin_modules.append(modname) def setup_builtin_modules(self): NOT_RPYTHON: only for initializing the space. diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -573,14 +573,16 @@ load_extension_module(space, filename, modulename) @jit.dont_look_inside -def load_module(space, w_modulename, find_info, reuse=False): +def load_module(space, w_modulename, find_info, reuse=False, force_init=False): if find_info is None: return if find_info.w_loader: return space.call_method(find_info.w_loader, load_module, w_modulename) if find_info.modtype == C_BUILTIN: -return space.getbuiltinmodule(find_info.filename, force_init=True) +return space.loadbuiltinmodule(find_info.filename, +
[pypy-commit] pypy default: Add two new tests, one of which fails on PyPy because we don't
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r64850:7d2924ddfa80 Date: 2013-06-11 13:24 +0200 http://bitbucket.org/pypy/pypy/changeset/7d2924ddfa80/ Log:Add two new tests, one of which fails on PyPy because we don't create several module objects for the same *built-in* module. diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py --- a/pypy/module/imp/test/test_app.py +++ b/pypy/module/imp/test/test_app.py @@ -200,3 +200,48 @@ except KeyError: pass rmtree(dir_name, True) + +def test_builtin_reimport(self): +# from https://bugs.pypy.org/issue1514 +import sys, marshal + +old = marshal.loads +marshal.loads = 42 + +# save, re-import, restore. +saved = sys.modules.pop('marshal') +__import__('marshal') +sys.modules['marshal'] = saved + +assert marshal.loads == 42 +import marshal +assert marshal.loads == 42 +marshal.loads = old + +def test_builtin_reimport_mess(self): +# taken from https://bugs.pypy.org/issue1514, with extra cases +# that show a difference with CPython: we can get on CPython +# several module objects for the same built-in module :-( +skip(several built-in module objects: not supported by pypy) +import sys, marshal + +old = marshal.loads +marshal.loads = 42 + +# save, re-import, restore. +saved = sys.modules.pop('marshal') +marshal2 = __import__('marshal') +assert marshal2 is not marshal +assert marshal2.loads is old +assert marshal2 is sys.modules['marshal'] +assert marshal is saved +assert marshal.loads == 42 + +import marshal +assert marshal.loads is old + +sys.modules['marshal'] = saved +import marshal +assert marshal.loads == 42 + +marshal.loads = old ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Fix this test to also pass on CPython
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r64849:93a61b856da8 Date: 2013-06-11 13:24 +0200 http://bitbucket.org/pypy/pypy/changeset/93a61b856da8/ Log:Fix this test to also pass on CPython diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -566,20 +566,19 @@ assert 'setdefaultencoding' in dir(sys) def test_reimport_builtin(self): -# ...but not reload()! -import sys +import sys, time oldpath = sys.path -sys.setdefaultencoding = test_reimport_builtin removed this +time.tzset = test_reimport_builtin removed this -del sys.modules['sys'] -import sys as sys1 -assert sys.modules['sys'] is sys1 is sys +del sys.modules['time'] +import time as time1 +assert sys.modules['time'] is time1 -assert sys.path is oldpath -assert sys.setdefaultencoding == test_reimport_builtin removed this +assert time.tzset == test_reimport_builtin removed this -reload(sys) # fix it for people that want 'setdefaultencoding' -assert sys.setdefaultencoding != test_reimport_builtin removed this +reload(time1) # don't leave a broken time.tzset behind +import time +assert time.tzset != test_reimport_builtin removed this def test_reload_infinite(self): import infinite_reload ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: backout f26956c61773.
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r64852:1265890f2384 Date: 2013-06-11 13:34 +0200 http://bitbucket.org/pypy/pypy/changeset/1265890f2384/ Log:backout f26956c61773. diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -381,10 +381,8 @@ except AttributeError: return self.__class__.__name__ -def _prepare_mixedmodule(self, importname): -NOT_RPYTHON. Load the RPython code of a lazy pypy/module and put -it into 'self.builtin_modules', without any further initialization. - +def setbuiltinmodule(self, importname): +NOT_RPYTHON. load a lazy pypy/module and put it into sys.modules if '.' in importname: fullname = importname importname = fullname.rsplit('.', 1)[1] @@ -403,22 +401,20 @@ return name -@jit.elidable -def getbuiltinmodule(self, name): -Return the built-in module 'name'. The first time it is seen, -it is initialized and stored in 'sys.modules'. This function is -elidable by the JIT because its effect is idempotent (if you call -it twice with the same name, you're getting the same effect as if -it was only called once). - -return self.loadbuiltinmodule(name, force_in_sys_modules=False, - force_init=False) +def getbuiltinmodule(self, name, force_init=False): +w_name = self.wrap(name) +w_modules = self.sys.get('modules') +try: +w_mod = self.getitem(w_modules, w_name) +except OperationError, e: +if not e.match(self, self.w_KeyError): +raise +else: +if not force_init: +return w_mod -def loadbuiltinmodule(self, name, force_in_sys_modules, force_init): -For the importing logic. Get the built-in module, stick it -into 'sys.modules' if not initialized or if force_in_sys_modules, -and initialize it if it was not already or if force_init. - +# If the module is a builtin but not yet imported, +# retrieve it and initialize it try: w_mod = self.builtin_modules[name] except KeyError: @@ -426,20 +422,15 @@ self.w_SystemError, getbuiltinmodule() called with non-builtin module %s, name) +else: +# Add the module to sys.modules +self.setitem(w_modules, w_name, w_mod) -from pypy.interpreter.module import Module -if isinstance(w_mod, Module) and not w_mod.startup_called: -force_in_sys_modules = True # not initialized so far: -force_init = True# force initialization - -if force_in_sys_modules: -w_sys_modules = self.sys.get('modules') -self.setitem(w_sys_modules, self.wrap(name), w_mod) - -if force_init and isinstance(w_mod, Module): -w_mod.init(self) - -return w_mod +# And initialize it +from pypy.interpreter.module import Module +if isinstance(w_mod, Module): +w_mod.init(self) +return w_mod def get_builtinmodule_to_install(self): NOT_RPYTHON @@ -556,12 +547,12 @@ def install_mixedmodule(self, mixedname, installed_builtin_modules): NOT_RPYTHON -modname = self._prepare_mixedmodule(mixedname) -assert modname -assert modname not in installed_builtin_modules, ( -duplicate interp-level module enabled for the -app-level module %r % (modname,)) -installed_builtin_modules.append(modname) +modname = self.setbuiltinmodule(mixedname) +if modname: +assert modname not in installed_builtin_modules, ( +duplicate interp-level module enabled for the +app-level module %r % (modname,)) +installed_builtin_modules.append(modname) def setup_builtin_modules(self): NOT_RPYTHON: only for initializing the space. diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -573,16 +573,14 @@ load_extension_module(space, filename, modulename) @jit.dont_look_inside -def load_module(space, w_modulename, find_info, reuse=False, force_init=False): +def load_module(space, w_modulename, find_info, reuse=False): if find_info is None: return if find_info.w_loader: return space.call_method(find_info.w_loader, load_module, w_modulename) if find_info.modtype == C_BUILTIN: -return space.loadbuiltinmodule(find_info.filename, - force_in_sys_modules=True, -
[pypy-commit] pypy default: Add a simpler test (missing so far) that shows what I did to be wrong.
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r64851:4dce95a2e895 Date: 2013-06-11 13:33 +0200 http://bitbucket.org/pypy/pypy/changeset/4dce95a2e895/ Log:Add a simpler test (missing so far) that shows what I did to be wrong. diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -565,6 +565,13 @@ assert sys.path is oldpath assert 'setdefaultencoding' in dir(sys) +def test_reimport_builtin_simple_case(self): +import sys, time +time.foo = bar +del sys.modules['time'] +import time +assert not hasattr(time, 'foo') + def test_reimport_builtin(self): import sys, time oldpath = sys.path ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Easy fix
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r64854:ad3579cf28fe Date: 2013-06-11 13:39 +0200 http://bitbucket.org/pypy/pypy/changeset/ad3579cf28fe/ Log:Easy fix diff --git a/pypy/interpreter/mixedmodule.py b/pypy/interpreter/mixedmodule.py --- a/pypy/interpreter/mixedmodule.py +++ b/pypy/interpreter/mixedmodule.py @@ -43,6 +43,7 @@ # the module was already imported. Refresh its content with # the saved dict, as done with built-in and extension modules # on CPython. +space.call_method(self.w_dict, 'clear') space.call_method(self.w_dict, 'update', self.w_initialdict) for w_submodule in self.submodules_w: diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -573,7 +573,6 @@ assert hasattr(time, 'tzset') def test_reimport_builtin_simple_case_2(self): -skip(fix me) import sys, time time.foo = bar del sys.modules['time'] ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: Kill even the easy fix, add a test (thanks amaury)
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r64855:ece10991099e Date: 2013-06-11 13:56 +0200 http://bitbucket.org/pypy/pypy/changeset/ece10991099e/ Log:Kill even the easy fix, add a test (thanks amaury) diff --git a/pypy/interpreter/mixedmodule.py b/pypy/interpreter/mixedmodule.py --- a/pypy/interpreter/mixedmodule.py +++ b/pypy/interpreter/mixedmodule.py @@ -43,7 +43,6 @@ # the module was already imported. Refresh its content with # the saved dict, as done with built-in and extension modules # on CPython. -space.call_method(self.w_dict, 'clear') space.call_method(self.w_dict, 'update', self.w_initialdict) for w_submodule in self.submodules_w: diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -565,6 +565,12 @@ assert sys.path is oldpath assert 'setdefaultencoding' in dir(sys) +def test_reload_builtin_doesnt_clear(self): +import sys +sys.foobar = baz +reload(sys) +assert sys.foobar == baz + def test_reimport_builtin_simple_case_1(self): import sys, time del time.tzset @@ -573,6 +579,7 @@ assert hasattr(time, 'tzset') def test_reimport_builtin_simple_case_2(self): +skip(fix me) import sys, time time.foo = bar del sys.modules['time'] ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy default: try to be on the safe side
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r64856:9e9835f0f54b Date: 2013-06-11 15:22 +0200 http://bitbucket.org/pypy/pypy/changeset/9e9835f0f54b/ Log:try to be on the safe side diff --git a/pypy/module/sys/app.py b/pypy/module/sys/app.py --- a/pypy/module/sys/app.py +++ b/pypy/module/sys/app.py @@ -29,14 +29,13 @@ try: # first try to print the exception's class name stderr = sys.stderr -stderr.write(getattr(exctype, '__name__', exctype)) +stderr.write(str(getattr(exctype, '__name__', exctype))) # then attempt to get the str() of the exception try: s = str(value) except: s = 'failure of str() on the exception instance' -# then print it, and don't worry too much about the extra space -# between the exception class and the ':' +# then print it if s: stderr.write(': %s\n' % (s,)) else: ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] stmgc default: in-progress
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r92:b30306fc8a86 Date: 2013-06-11 16:28 +0200 http://bitbucket.org/pypy/stmgc/changeset/b30306fc8a86/ Log:in-progress diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -35,6 +35,10 @@ return (P-h_revision == stm_private_rev_num) || (P-h_tid GCFLAG_PRIVATE_FROM_PROTECTED); } +int _stm_is_private(gcptr P) +{ + return is_private(P); +} // @@ -208,82 +212,89 @@ } } -#if 0 -static gcptr _latest_gcptr(gcptr R) +gcptr _stm_nonrecord_barrier(gcptr G) { - /* don't use, for tests only */ + /* follows the logic in stm_DirectReadBarrier() */ + struct tx_descriptor *d = thread_descriptor; + gcptr P = G; revision_t v; - retry: - v = R-h_revision; - if (!(v 1)) // is a pointer, i.e. -{// has a more recent revision - if (v 2) + + if (P-h_tid GCFLAG_PRIVATE_FROM_PROTECTED) +{ +private_from_protected: + if (!(((gcptr)P-h_revision)-h_revision 1)) { - v = ~2; - if (!stmgc_is_young_in(thread_descriptor, (gcptr)v)) -return NULL; /* can't access */ + fprintf(stderr, _stm_nonrecord_barrier: %p - NULL + private_from_protected but protected changed\n, G); + return NULL; } - R = (gcptr)v; - goto retry; -} - return R; -} - -gcptr _stm_nonrecord_barrier(gcptr obj, int *result) -{ - /* warning, this is for tests only, and it is not thread-safe! */ - struct tx_descriptor *d = thread_descriptor; - if (gcptrlist_size(d-stolen_objects) 0) -stmgc_normalize_stolen_objects(); - - enum protection_class_t e = stmgc_classify(obj); - if (e == K_PRIVATE) -{ - *result = 2; /* 'obj' a private object to start with */ - return obj; -} - obj = _latest_gcptr(obj); - if (obj == NULL) -{ - assert(e == K_PUBLIC); - *result = 3; /* can't check anything: we'd need foreign access */ - return NULL; -} - if (stmgc_classify(obj) == K_PRIVATE) -{ - *result = 1; - return obj; + goto add_in_recent_reads_cache; } - wlog_t *item; - G2L_LOOP_FORWARD(d-public_to_private, item) + if (P-h_tid GCFLAG_PUBLIC) { - gcptr R = item-addr; - gcptr L = item-val; - if (_latest_gcptr(R) == obj) + while (v = ACCESS_ONCE(P-h_revision), !(v 1)) { - /* 'obj' has a private version. The way we detect this lets us - find it even if we already have a committed version that - will cause conflict. */ - *result = 1; - return L; + if (v 2) +goto follow_stub; + + P = (gcptr)v; + assert(P-h_tid GCFLAG_PUBLIC); } -} G2L_LOOP_END; - if (obj-h_revision d-start_time) -{ - /* 'obj' has no private version, and the public version was modified */ - *result = -1; - return NULL; + if (P-h_tid GCFLAG_PUBLIC_TO_PRIVATE) +{ + wlog_t *item; + G2L_FIND(d-public_to_private, P, item, goto no_private_obj); + + P = item-val; +found_in_stolen_objects: + assert(!(P-h_tid GCFLAG_PUBLIC)); + assert(is_private(P)); + fprintf(stderr, _stm_nonrecord_barrier: %p - %p + public_to_private\n, G, P); + return P; + +no_private_obj:; + gcptr L = _stm_find_stolen_objects(d, P); + if (L != NULL) +{ + P = L; + goto found_in_stolen_objects; +} +} + + if (UNLIKELY(v d-start_time)) +{ + fprintf(stderr, _stm_nonrecord_barrier: %p - NULL changed\n, G); + return NULL; // object too recent +} + fprintf(stderr, _stm_nonrecord_barrier: %p - %p public\n, G, P); } else { - /* 'obj' has only an up-to-date public version */ - *result = 0; - return obj; + fprintf(stderr, _stm_nonrecord_barrier: %p - %p protected\n, G, P); +} + + register_in_list_of_read_objects: + add_in_recent_reads_cache: + return P; + + follow_stub:; + P = (gcptr)(v - 2); + assert(!(P-h_tid GCFLAG_PUBLIC)); + if (P-h_tid GCFLAG_PRIVATE_FROM_PROTECTED) +{ + fprintf(stderr, _stm_nonrecord_barrier: %p - %p handle + private_from_protected\n, G, P); + goto private_from_protected; +} + else +{ + fprintf(stderr, read_barrier: %p - %p handle\n, G, P); + goto register_in_list_of_read_objects; } } -#endif #if 0 void *stm_DirectReadBarrierFromR(void *G1, void *R_Container1, size_t offset) diff --git a/c4/et.h b/c4/et.h --- a/c4/et.h +++ b/c4/et.h @@ -164,7 +164,9 @@ gcptr stm_DirectReadBarrier(gcptr); gcptr stm_RepeatReadBarrier(gcptr); gcptr stm_WriteBarrier(gcptr); -gcptr _stm_nonrecord_barrier(gcptr, int *); +gcptr _stm_nonrecord_barrier(gcptr); /* debugging: read barrier, but +
[pypy-commit] stmgc default: Fixes. Now I have a clear idea about which thread can change exactly
Author: Armin Rigo ar...@tunes.org Branch: Changeset: r93:2d0f4e06ce3a Date: 2013-06-11 22:49 +0200 http://bitbucket.org/pypy/stmgc/changeset/2d0f4e06ce3a/ Log:Fixes. Now I have a clear idea about which thread can change exactly which parts of which objects. diff --git a/c4/doc-objects.txt b/c4/doc-objects.txt --- a/c4/doc-objects.txt +++ b/c4/doc-objects.txt @@ -245,3 +245,28 @@ make a stub with h_revision = private object | 2 after a CPU write barrier, make the public h_revision to point to the stub + + + +Change to the flags and h_revision +-- + +The flags are in `h_tid`. Changes to this field and `h_revision` must +not occur uncontrolled: + +- private copies: the thread that owns the private copy can change +freely the `h_tid` and `h_revision` fields. The other threads must not +touch them, and must read them carefully. This concerns only stealing +threads, on GCFLAG_PRIVATE_FROM_PROTECTED objects. The flag +GCFLAG_PRIVATE_FROM_PROTECTED itself is only changed when the owning +thread has got its collection_lock, and as long as it is set, h_revision +points to the backup copy. + +- protected copies (includes backup copies): any change requires the +owning thread's collection_lock. During stealing, other threads +might add (with the collection_lock) the flags GCFLAG_PUBLIC or +GCFLAG_PUBLIC_TO_PRIVATE. + +- public copies: must be changed carefully: `h_tid` is only modified to +add GCFLAG_PUBLIC_TO_PRIVATE; and `h_revision` changes are done with +bool_cas() in a thread-controlled way. diff --git a/c4/et.c b/c4/et.c --- a/c4/et.c +++ b/c4/et.c @@ -75,9 +75,11 @@ gcptr P = G; revision_t v; + restart_all: if (P-h_tid GCFLAG_PRIVATE_FROM_PROTECTED) { -private_from_protected: + assert(!(P-h_revision 1)); /* pointer to the backup copy */ + /* check P-h_revision-h_revision: if a pointer, then it means the backup copy has been stolen into a public object and then modified by some other thread. Abort. */ @@ -86,15 +88,20 @@ goto add_in_recent_reads_cache; } + /* else, for the rest of this function, we can assume that P was not + a private copy */ if (P-h_tid GCFLAG_PUBLIC) { /* follow the chained list of h_revision's as long as they are - regular pointers */ -retry: + regular pointers. We will only find more public objects + along this chain. + */ +restart_all_public: v = ACCESS_ONCE(P-h_revision); if (!(v 1)) // is a pointer, i.e. {// has a more recent revision +retry: if (v 2) goto follow_stub; @@ -114,23 +121,33 @@ doing this write occasionally based on a counter in d */ P_prev-h_revision = v; P = (gcptr)v; - goto retry; + v = ACCESS_ONCE(P-h_revision); + if (!(v 1)) // is a pointer, i.e. has a more recent rev +goto retry; +} + + /* We reach this point if P != G only. Check again the + read_barrier_cache: if P now hits the cache, just return it + */ + if (FXCACHE_AT(P) == P) +{ + fprintf(stderr, read_barrier: %p - %p fxcache\n, G, P); + return P; } } - /* if we land on a P in read_barrier_cache: just return it */ - if (FXCACHE_AT(P) == P) -{ - fprintf(stderr, read_barrier: %p - %p fxcache\n, G, P); - return P; -} - + /* If we land on a P with GCFLAG_PUBLIC_TO_PRIVATE, it might be + because *we* have an entry in d-public_to_private. (It might + also be someone else.) + */ if (P-h_tid GCFLAG_PUBLIC_TO_PRIVATE) { wlog_t *item; retry_public_to_private:; G2L_FIND(d-public_to_private, P, item, goto no_private_obj); + /* We have a key in 'public_to_private'. The value is the + corresponding private object. */ P = item-val; assert(!(P-h_tid GCFLAG_PUBLIC)); assert(is_private(P)); @@ -138,6 +155,8 @@ return P; no_private_obj: + /* Key not found. It might be because there really is none, or + because we still have it waiting in 'stolen_objects'. */ if (d-public_descriptor-stolen_objects.size 0) { spinlock_acquire(d-public_descriptor-collection_lock, 'N'); @@ -147,7 +166,8 @@ } } - if (UNLIKELY(v d-start_time)) // object too recent? + /* The answer is a public object. Is it too recent? */ + if (UNLIKELY(v d-start_time)) { if (v = LOCKED) { @@ -161,10 +181,17 @@ } else { + /* Not private and not public: it's a protected object + */ fprintf(stderr, read_barrier: %p - %p
[pypy-commit] extradoc extradoc: py3k status update #11
Author: Philip Jenvey pjen...@underboss.org Branch: extradoc Changeset: r4975:bce4d23f15e1 Date: 2013-06-11 16:38 -0700 http://bitbucket.org/pypy/extradoc/changeset/bce4d23f15e1/ Log:py3k status update #11 diff --git a/blog/draft/py3k-status-update-11.rst b/blog/draft/py3k-status-update-11.rst new file mode 100644 --- /dev/null +++ b/blog/draft/py3k-status-update-11.rst @@ -0,0 +1,63 @@ +Py3k status update #11 +-- + +This is the 11th status update about our work on the `py3k branch`_, which we +can work on thanks to all of the people who donated_ to the `py3k proposal`_. + +Here's some highlights of the progress made since the previous update: + +* PyPy py3k now matches CPython 3's hash code for + int/float/complex/Decimal/Fraction + +* Various outstanding unicode identifier related issues were + resolved. E.g. test_importlib/pep263/ucn/unicode all now fully pass. Various + usage of identifiers (in particular type and module names) have been fixed to + handle non-ascii names -- mostly around display of reprs and exception + messages. + +* The unicodedata database has been upgraded to 6.0.0. + +* Windows support has greatly improved, though it could still use some more + help (but so does the default branch to a certain degree). + +* Probably the last of the parsing related bugs/features have been taken care + of. + +* Of course various other smaller miscellaneous fixes + +This leaves the branch w/ only about 5 outstanding failures of the stdlib test +suite: + +* test_float + + 1 failing test about containment of floats in collections. + +* test_memoryview + + Various failures: requires some bytes/str changes among other things (Manuel + Jacob's has some progress on this on the `py3k-memoryview branch`_) + +* test_multiprocessing + + 1 or more tests deadlock on some platforms + +* test_sys and test_threading + + 2 failing tests for the New GIL's new API + +Probably the biggest feature left to tackle is the New GIL. + +We're now pretty close to pushing an initial release. We had planned for one +around PyCon, but having missed that we've put some more effort into the branch +to provide a more fully-fledged initial release. + +Thanks to the following for their contributions: Manuel Jacob, Amaury Forgeot +d'Arc, Karl Ramm, Jason Chu and Christian Hudson. + +cheers, +Phil + +.. _donated: http://morepypy.blogspot.com/2012/01/py3k-and-numpy-first-stage-thanks-to.html +.. _`py3k proposal`: http://pypy.org/py3donate.html +.. _`py3k branch`: https://bitbucket.org/pypy/pypy/commits/all/tip/branch%28%22py3k%22%29 +.. _`py3k-memoryview branch`: https://bitbucket.org/pypy/pypy/compare/py3k-memoryview..py3k ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit
[pypy-commit] pypy py3k: merge default
Author: Philip Jenvey pjen...@underboss.org Branch: py3k Changeset: r64858:f1b58638d8bd Date: 2013-06-11 17:00 -0700 http://bitbucket.org/pypy/pypy/changeset/f1b58638d8bd/ Log:merge default diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py --- a/lib_pypy/cffi/api.py +++ b/lib_pypy/cffi/api.py @@ -361,13 +361,13 @@ backend = ffi._backend try: if '.' not in name and '/' not in name: -raise OSError +raise OSError(library not found: %r % (name,)) backendlib = backend.load_library(name, flags) except OSError: import ctypes.util path = ctypes.util.find_library(name) if path is None: -raise OSError(library not found: %r % (name,)) +raise # propagate the original OSError backendlib = backend.load_library(path, flags) copied_enums = [] # 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 @@ -289,16 +289,6 @@ with verify() (see pypy/module/_cffi_backend/ctypefunc.py for details))) -if USE_C_LIBFFI_MSVC and is_result_type: -# MSVC returns small structures in registers. Pretend int32 or -# int64 return type. This is needed as a workaround for what -# is really a bug of libffi_msvc seen as an independent library -# (ctypes has a similar workaround). -if ctype.size = 4: -return clibffi.ffi_type_sint32 -if ctype.size = 8: -return clibffi.ffi_type_sint64 - # walk the fields, expanding arrays into repetitions; first, # only count how many flattened fields there are nflat = 0 @@ -318,6 +308,16 @@ a struct with a zero-length array)) nflat += flat +if USE_C_LIBFFI_MSVC and is_result_type: +# MSVC returns small structures in registers. Pretend int32 or +# int64 return type. This is needed as a workaround for what +# is really a bug of libffi_msvc seen as an independent library +# (ctypes has a similar workaround). +if ctype.size = 4: +return clibffi.ffi_type_sint32 +if ctype.size = 8: +return clibffi.ffi_type_sint64 + # allocate an array of (nflat + 1) ffi_types elements = self.fb_alloc(rffi.sizeof(FFI_TYPE_P) * (nflat + 1)) elements = rffi.cast(FFI_TYPE_PP, elements) diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py --- a/pypy/module/imp/test/test_app.py +++ b/pypy/module/imp/test/test_app.py @@ -217,6 +217,52 @@ pass rmtree(dir_name, True) +def test_builtin_reimport(self): +# from https://bugs.pypy.org/issue1514 +skip(fix me) +import sys, marshal + +old = marshal.loads +marshal.loads = 42 + +# save, re-import, restore. +saved = sys.modules.pop('marshal') +__import__('marshal') +sys.modules['marshal'] = saved + +assert marshal.loads == 42 +import marshal +assert marshal.loads == 42 +marshal.loads = old + +def test_builtin_reimport_mess(self): +# taken from https://bugs.pypy.org/issue1514, with extra cases +# that show a difference with CPython: we can get on CPython +# several module objects for the same built-in module :-( +skip(several built-in module objects: not supported by pypy) +import sys, marshal + +old = marshal.loads +marshal.loads = 42 + +# save, re-import, restore. +saved = sys.modules.pop('marshal') +marshal2 = __import__('marshal') +assert marshal2 is not marshal +assert marshal2.loads is old +assert marshal2 is sys.modules['marshal'] +assert marshal is saved +assert marshal.loads == 42 + +import marshal +assert marshal.loads is old + +sys.modules['marshal'] = saved +import marshal +assert marshal.loads == 42 + +marshal.loads = old + def test_get_tag(self): import imp import sys diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -625,6 +625,43 @@ assert sys.path is oldpath assert 'settrace' in dir(sys) +def test_reload_builtin_doesnt_clear(self): +import sys +sys.foobar = baz +reload(sys) +assert sys.foobar == baz + +def test_reimport_builtin_simple_case_1(self): +import sys, time +del time.tzset +del sys.modules['time'] +import time +assert hasattr(time, 'tzset') + +def
[pypy-commit] pypy py3k: simplify
Author: Philip Jenvey pjen...@underboss.org Branch: py3k Changeset: r64859:391ba71b1425 Date: 2013-06-11 17:14 -0700 http://bitbucket.org/pypy/pypy/changeset/391ba71b1425/ Log:simplify diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py --- a/pypy/interpreter/error.py +++ b/pypy/interpreter/error.py @@ -379,7 +379,6 @@ return tuple(parts), tuple(formats) def get_operrcls2(valuefmt): -from rpython.rlib.runicode import str_decode_utf_8 valuefmt = valuefmt.decode('ascii') strings, formats = decompose_valuefmt(valuefmt) assert len(strings) == len(formats) + 1 @@ -407,8 +406,7 @@ if fmt == 'd': result = str(value).decode('ascii') elif fmt == '8': -result, _ = str_decode_utf_8(value, len(value), - 'strict') +result = value.decode('utf-8') elif fmt == 'R': result = space.unicode_w(space.repr(value)) elif fmt in 'NT': @@ -440,7 +438,7 @@ Supports the standard %s and %d formats, plus the following: -%8 - The result of arg.decode('utf-8', 'strict') +%8 - The result of arg.decode('utf-8') %N - The result of w_arg.getname(space) %R - The result of space.unicode_w(space.repr(w_arg)) %T - The result of space.type(w_arg).getname(space) ___ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit