Author: Armin Rigo <ar...@tunes.org> Branch: py3.5 Changeset: r88993:28385e50deee Date: 2016-12-10 15:10 +0100 http://bitbucket.org/pypy/pypy/changeset/28385e50deee/
Log: hg merge default diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -71,8 +71,11 @@ Analyzing performance of applications is always tricky. We have various tools, for example a `jitviewer`_ that help us analyze performance. -The jitviewer shows the code generated by the PyPy JIT in a hierarchical way, -as shown by the screenshot below: +The old tool was partly rewritten and combined with vmprof. The service is +hosted at `vmprof.com`_. + +The following shows an old image of the jitviewer. +The code generated by the PyPy JIT in a hierarchical way: - at the bottom level, it shows the Python source code of the compiled loops @@ -84,13 +87,17 @@ .. image:: image/jitviewer.png -The jitviewer is a web application based on flask and jinja2 (and jQuery on -the client): if you have great web developing skills and want to help PyPy, +The jitviewer is a web application based on django and angularjs: +if you have great web developing skills and want to help PyPy, this is an ideal task to get started, because it does not require any deep -knowledge of the internals. +knowledge of the internals. Head over to `vmprof-python`_, `vmprof-server`_ and +`vmprof-integration`_ to find open issues and documentation. -.. _jitviewer: http://bitbucket.org/pypy/jitviewer - +.. _jitviewer: http://vmprof.com +.. _vmprof.com: http://vmprof.com +.. _vmprof-python: https://github.com/vmprof/vmprof-python +.. _vmprof-server: https://github.com/vmprof/vmprof-server +.. _vmprof-integration: https://github.com/vmprof/vmprof-integration Optimized Unicode Representation -------------------------------- 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 @@ -47,3 +47,10 @@ .. branch: desc-specialize Refactor FunctionDesc.specialize() and related code (RPython annotator). + +.. branch: raw-calloc + +.. branch: issue2446 + +Assign ``tp_doc`` to the new TypeObject's type dictionary ``__doc__`` key +so it will be picked up by app-level objects of that type diff --git a/pypy/interpreter/test/test_unicodehelper.py b/pypy/interpreter/test/test_unicodehelper.py new file mode 100644 --- /dev/null +++ b/pypy/interpreter/test/test_unicodehelper.py @@ -0,0 +1,26 @@ +from pypy.interpreter.unicodehelper import encode_utf8, decode_utf8 + +class FakeSpace: + pass + +def test_encode_utf8(): + space = FakeSpace() + assert encode_utf8(space, u"abc") == "abc" + assert encode_utf8(space, u"\u1234") == "\xe1\x88\xb4" + assert encode_utf8(space, u"\ud800") == "\xed\xa0\x80" + assert encode_utf8(space, u"\udc00") == "\xed\xb0\x80" + # for the following test, go to lengths to avoid CPython's optimizer + # and .pyc file storage, which collapse the two surrogates into one + c = u"\udc00" + assert encode_utf8(space, u"\ud800" + c) == "\xf0\x90\x80\x80" + +def test_decode_utf8(): + space = FakeSpace() + assert decode_utf8(space, "abc") == u"abc" + assert decode_utf8(space, "\xe1\x88\xb4") == u"\u1234" + assert decode_utf8(space, "\xed\xa0\x80") == u"\ud800" + assert decode_utf8(space, "\xed\xb0\x80") == u"\udc00" + got = decode_utf8(space, "\xed\xa0\x80\xed\xb0\x80") + assert map(ord, got) == [0xd800, 0xdc00] + got = decode_utf8(space, "\xf0\x90\x80\x80") + assert map(ord, got) == [0x10000] diff --git a/pypy/interpreter/unicodehelper.py b/pypy/interpreter/unicodehelper.py --- a/pypy/interpreter/unicodehelper.py +++ b/pypy/interpreter/unicodehelper.py @@ -142,6 +142,8 @@ def encode_utf8(space, uni, allow_surrogates=False): # Note that Python3 tends to forbid lone surrogates + # Also, note that the two characters \d800\dc00 are considered as + # a paired surrogate, and turn into a single 4-byte utf8 char. return runicode.unicode_encode_utf_8( uni, len(uni), "strict", errorhandler=encode_error_handler(space), diff --git a/pypy/module/_cffi_backend/test/test_ffi_obj.py b/pypy/module/_cffi_backend/test/test_ffi_obj.py --- a/pypy/module/_cffi_backend/test/test_ffi_obj.py +++ b/pypy/module/_cffi_backend/test/test_ffi_obj.py @@ -401,7 +401,8 @@ retries += 1 assert retries <= 5 import gc; gc.collect() - assert seen == [40, 40, raw1, raw2] + assert (seen == [40, 40, raw1, raw2] or + seen == [40, 40, raw2, raw1]) assert repr(seen[2]) == "<cdata 'char[]' owning 41 bytes>" assert repr(seen[3]) == "<cdata 'char[]' owning 41 bytes>" diff --git a/pypy/module/cpyext/test/test_typeobject.py b/pypy/module/cpyext/test/test_typeobject.py --- a/pypy/module/cpyext/test/test_typeobject.py +++ b/pypy/module/cpyext/test/test_typeobject.py @@ -145,7 +145,7 @@ assert fuu2(u"abc").baz().escape() raises(TypeError, module.fooType.object_member.__get__, 1) - def test_multiple_inheritance(self): + def test_multiple_inheritance1(self): module = self.import_module(name='foo') obj = module.UnicodeSubtype(u'xyz') obj2 = module.UnicodeSubtype2() @@ -397,7 +397,7 @@ assert space.int_w(space.getattr(w_class, w_name)) == 1 space.delitem(w_dict, w_name) - def test_multiple_inheritance(self, space, api): + def test_multiple_inheritance2(self, space, api): w_class = space.appexec([], """(): class A(object): pass @@ -1132,3 +1132,38 @@ print(repr(X)) X() + + def test_multiple_inheritance3(self): + module = self.import_extension('foo', [ + ("new_obj", "METH_NOARGS", + ''' + PyObject *obj; + PyTypeObject *Base1, *Base2, *Base12; + Base1 = (PyTypeObject*)PyType_Type.tp_alloc(&PyType_Type, 0); + Base2 = (PyTypeObject*)PyType_Type.tp_alloc(&PyType_Type, 0); + Base12 = (PyTypeObject*)PyType_Type.tp_alloc(&PyType_Type, 0); + Base1->tp_name = "Base1"; + Base2->tp_name = "Base2"; + Base12->tp_name = "Base12"; + Base1->tp_basicsize = sizeof(PyHeapTypeObject); + Base2->tp_basicsize = sizeof(PyHeapTypeObject); + Base12->tp_basicsize = sizeof(PyHeapTypeObject); + Base1->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; + Base2->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; + Base12->tp_flags = Py_TPFLAGS_DEFAULT; + Base12->tp_base = Base1; + Base12->tp_bases = PyTuple_Pack(2, Base1, Base2); + Base12->tp_doc = "The Base12 type or object"; + if (PyType_Ready(Base1) < 0) return NULL; + if (PyType_Ready(Base2) < 0) return NULL; + if (PyType_Ready(Base12) < 0) return NULL; + obj = PyObject_New(PyObject, Base12); + return obj; + ''' + )]) + obj = module.new_obj() + assert 'Base12' in str(obj) + assert type(obj).__doc__ == "The Base12 type or object" + assert obj.__doc__ == "The Base12 type or object" + + diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py --- a/pypy/module/cpyext/typeobject.py +++ b/pypy/module/cpyext/typeobject.py @@ -326,6 +326,8 @@ w_obj = W_PyCWrapperObject(space, pto, method_name, wrapper_func, wrapper_func_kwds, doc, func_voidp, offset=offset) dict_w[method_name] = space.wrap(w_obj) + if pto.c_tp_doc: + dict_w['__doc__'] = space.newbytes(rffi.charp2str(pto.c_tp_doc)) if pto.c_tp_new: add_tp_new_wrapper(space, dict_w, pto) @@ -461,13 +463,17 @@ convert_member_defs(space, dict_w, pto.c_tp_members, self) name = rffi.charp2str(pto.c_tp_name) - new_layout = (pto.c_tp_basicsize > rffi.sizeof(PyObject.TO) or - pto.c_tp_itemsize > 0) + flag_heaptype = pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE + if flag_heaptype: + minsize = rffi.sizeof(PyHeapTypeObject.TO) + else: + minsize = rffi.sizeof(PyObject.TO) + new_layout = (pto.c_tp_basicsize > minsize or pto.c_tp_itemsize > 0) W_TypeObject.__init__(self, space, name, bases_w or [space.w_object], dict_w, force_new_layout=new_layout) self.flag_cpytype = True - self.flag_heaptype = pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE + self.flag_heaptype = flag_heaptype # if a sequence or a mapping, then set the flag to force it if pto.c_tp_as_sequence and pto.c_tp_as_sequence.c_sq_item: self.flag_map_or_seq = 'S' diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py --- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py +++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_ffi_backend.py @@ -494,3 +494,15 @@ def test_negative_array_size(self): ffi = FFI() py.test.raises(ValueError, ffi.cast, "int[-5]", 0) + + def test_cannot_instantiate_manually(self): + ffi = FFI() + ct = type(ffi.typeof("void *")) + py.test.raises(TypeError, ct) + py.test.raises(TypeError, ct, ffi.NULL) + for cd in [type(ffi.cast("void *", 0)), + type(ffi.new("char[]", 3)), + type(ffi.gc(ffi.NULL, lambda x: None))]: + py.test.raises(TypeError, cd) + py.test.raises(TypeError, cd, ffi.NULL) + py.test.raises(TypeError, cd, ffi.typeof("void *")) diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_ffi_obj.py b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_ffi_obj.py --- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_ffi_obj.py +++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_ffi_obj.py @@ -361,7 +361,8 @@ retries += 1 assert retries <= 5 import gc; gc.collect() - assert seen == [40, 40, raw1, raw2] + assert (seen == [40, 40, raw1, raw2] or + seen == [40, 40, raw2, raw1]) assert repr(seen[2]) == "<cdata 'char[]' owning 41 bytes>" assert repr(seen[3]) == "<cdata 'char[]' owning 41 bytes>" diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py --- a/rpython/jit/codewriter/jtransform.py +++ b/rpython/jit/codewriter/jtransform.py @@ -593,6 +593,8 @@ log.WARNING('ignoring hint %r at %r' % (hints, self.graph)) def _rewrite_raw_malloc(self, op, name, args): + # NB. the operation 'raw_malloc' is not supported; this is for + # the operation 'malloc'/'malloc_varsize' with {flavor: 'gc'} d = op.args[1].value.copy() d.pop('flavor') add_memory_pressure = d.pop('add_memory_pressure', False) diff --git a/rpython/jit/codewriter/support.py b/rpython/jit/codewriter/support.py --- a/rpython/jit/codewriter/support.py +++ b/rpython/jit/codewriter/support.py @@ -142,10 +142,14 @@ assert len(lst) == len(args_v), ( "not supported so far: 'greens' variables contain Void") # a crash here means that you have to reorder the variable named in - # the JitDriver. Indeed, greens and reds must both be sorted: first - # all INTs, followed by all REFs, followed by all FLOATs. + # the JitDriver. lst2 = sort_vars(lst) - assert lst == lst2 + assert lst == lst2, ("You have to reorder the variables named in " + "the JitDriver (both the 'greens' and 'reds' independently). " + "They must be sorted like this: first all the integer-like, " + "then all the pointer-like, and finally the floats.\n" + "Got: %r\n" + "Expected: %r" % (lst, lst2)) return lst # return (_sort(greens_v, True), _sort(reds_v, False)) diff --git a/rpython/memory/gctransform/transform.py b/rpython/memory/gctransform/transform.py --- a/rpython/memory/gctransform/transform.py +++ b/rpython/memory/gctransform/transform.py @@ -427,6 +427,13 @@ return result mh._ll_malloc_fixedsize = _ll_malloc_fixedsize + def _ll_malloc_fixedsize_zero(size): + result = mh.allocate(size, zero=True) + if not result: + raise MemoryError() + return result + mh._ll_malloc_fixedsize_zero = _ll_malloc_fixedsize_zero + def _ll_compute_size(length, size, itemsize): try: varsize = ovfcheck(itemsize * length) @@ -453,10 +460,9 @@ def _ll_malloc_varsize_no_length_zero(length, size, itemsize): tot_size = _ll_compute_size(length, size, itemsize) - result = mh.allocate(tot_size) + result = mh.allocate(tot_size, zero=True) if not result: raise MemoryError() - llmemory.raw_memclear(result, tot_size) return result mh.ll_malloc_varsize_no_length_zero = _ll_malloc_varsize_no_length_zero @@ -470,17 +476,16 @@ mh = mallocHelpers() mh.allocate = llmemory.raw_malloc ll_raw_malloc_fixedsize = mh._ll_malloc_fixedsize + ll_raw_malloc_fixedsize_zero = mh._ll_malloc_fixedsize_zero ll_raw_malloc_varsize_no_length = mh.ll_malloc_varsize_no_length ll_raw_malloc_varsize = mh.ll_malloc_varsize ll_raw_malloc_varsize_no_length_zero = mh.ll_malloc_varsize_no_length_zero - stack_mh = mallocHelpers() - stack_mh.allocate = lambda size: llop.stack_malloc(llmemory.Address, size) - ll_stack_malloc_fixedsize = stack_mh._ll_malloc_fixedsize - if self.translator: self.raw_malloc_fixedsize_ptr = self.inittime_helper( ll_raw_malloc_fixedsize, [lltype.Signed], llmemory.Address) + self.raw_malloc_fixedsize_zero_ptr = self.inittime_helper( + ll_raw_malloc_fixedsize_zero, [lltype.Signed], llmemory.Address) self.raw_malloc_varsize_no_length_ptr = self.inittime_helper( ll_raw_malloc_varsize_no_length, [lltype.Signed]*3, llmemory.Address, inline=False) self.raw_malloc_varsize_ptr = self.inittime_helper( @@ -488,9 +493,6 @@ self.raw_malloc_varsize_no_length_zero_ptr = self.inittime_helper( ll_raw_malloc_varsize_no_length_zero, [lltype.Signed]*3, llmemory.Address, inline=False) - self.stack_malloc_fixedsize_ptr = self.inittime_helper( - ll_stack_malloc_fixedsize, [lltype.Signed], llmemory.Address) - def gct_malloc(self, hop, add_flags=None): TYPE = hop.spaceop.result.concretetype.TO assert not TYPE._is_varsize() @@ -503,21 +505,16 @@ hop.cast_result(v_raw) def gct_fv_raw_malloc(self, hop, flags, TYPE, c_size): - v_raw = hop.genop("direct_call", [self.raw_malloc_fixedsize_ptr, c_size], + if flags.get('zero'): + ll_func = self.raw_malloc_fixedsize_zero_ptr + else: + ll_func = self.raw_malloc_fixedsize_ptr + v_raw = hop.genop("direct_call", [ll_func, c_size], resulttype=llmemory.Address) - if flags.get('zero'): - hop.genop("raw_memclear", [v_raw, c_size]) if flags.get('track_allocation', True): hop.genop("track_alloc_start", [v_raw]) return v_raw - def gct_fv_stack_malloc(self, hop, flags, TYPE, c_size): - v_raw = hop.genop("direct_call", [self.stack_malloc_fixedsize_ptr, c_size], - resulttype=llmemory.Address) - if flags.get('zero'): - hop.genop("raw_memclear", [v_raw, c_size]) - return v_raw - def gct_malloc_varsize(self, hop, add_flags=None): flags = hop.spaceop.args[1].value if add_flags: diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -1778,22 +1778,23 @@ finally: lltype.free(l_utsbuf, flavor='raw') -# These are actually macros on some/most systems -c_makedev = external('makedev', [rffi.INT, rffi.INT], rffi.INT, macro=True) -c_major = external('major', [rffi.INT], rffi.INT, macro=True) -c_minor = external('minor', [rffi.INT], rffi.INT, macro=True) +if sys.platform != 'win32': + # These are actually macros on some/most systems + c_makedev = external('makedev', [rffi.INT, rffi.INT], rffi.INT, macro=True) + c_major = external('major', [rffi.INT], rffi.INT, macro=True) + c_minor = external('minor', [rffi.INT], rffi.INT, macro=True) -@replace_os_function('makedev') -def makedev(maj, min): - return c_makedev(maj, min) + @replace_os_function('makedev') + def makedev(maj, min): + return c_makedev(maj, min) -@replace_os_function('major') -def major(dev): - return c_major(dev) + @replace_os_function('major') + def major(dev): + return c_major(dev) -@replace_os_function('minor') -def minor(dev): - return c_minor(dev) + @replace_os_function('minor') + def minor(dev): + return c_minor(dev) #___________________________________________________________________ diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -398,7 +398,7 @@ baseofs = offsetof(_c.sockaddr_un, 'c_sun_path') self.setdata(sun, baseofs + len(path)) rffi.setintfield(sun, 'c_sun_family', AF_UNIX) - if _c.linux and path.startswith('\x00'): + if _c.linux and path[0] == '\x00': # Linux abstract namespace extension if len(path) > sizeof(_c.sockaddr_un.c_sun_path): raise RSocketError("AF_UNIX path too long") diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py --- a/rpython/rlib/test/test_rposix.py +++ b/rpython/rlib/test/test_rposix.py @@ -281,6 +281,7 @@ def test_isatty(self): assert rposix.isatty(-1) is False + @py.test.mark.skipif("not hasattr(rposix, 'makedev')") def test_makedev(self): dev = rposix.makedev(24, 7) assert rposix.major(dev) == 24 diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py --- a/rpython/rtyper/llinterp.py +++ b/rpython/rtyper/llinterp.py @@ -997,11 +997,14 @@ # __________________________________________________________ # operations on addresses - def op_raw_malloc(self, size): + def op_raw_malloc(self, size, zero): + assert lltype.typeOf(size) == lltype.Signed + return llmemory.raw_malloc(size, zero=zero) + + def op_boehm_malloc(self, size): assert lltype.typeOf(size) == lltype.Signed return llmemory.raw_malloc(size) - - op_boehm_malloc = op_boehm_malloc_atomic = op_raw_malloc + op_boehm_malloc_atomic = op_boehm_malloc def op_boehm_register_finalizer(self, p, finalizer): pass @@ -1069,9 +1072,6 @@ assert offset.TYPE == ARGTYPE getattr(addr, str(ARGTYPE).lower())[offset.repeat] = value - def op_stack_malloc(self, size): # mmh - raise NotImplementedError("backend only") - def op_track_alloc_start(self, addr): # we don't do tracking at this level checkadr(addr) diff --git a/rpython/rtyper/lltypesystem/llarena.py b/rpython/rtyper/lltypesystem/llarena.py --- a/rpython/rtyper/lltypesystem/llarena.py +++ b/rpython/rtyper/lltypesystem/llarena.py @@ -506,13 +506,17 @@ llimpl_malloc = rffi.llexternal('malloc', [lltype.Signed], llmemory.Address, sandboxsafe=True, _nowrapper=True) +llimpl_calloc = rffi.llexternal('calloc', [lltype.Signed, lltype.Signed], + llmemory.Address, + sandboxsafe=True, _nowrapper=True) llimpl_free = rffi.llexternal('free', [llmemory.Address], lltype.Void, sandboxsafe=True, _nowrapper=True) def llimpl_arena_malloc(nbytes, zero): - addr = llimpl_malloc(nbytes) - if bool(addr): - llimpl_arena_reset(addr, nbytes, zero) + if zero: + addr = llimpl_calloc(nbytes, 1) + else: + addr = llimpl_malloc(nbytes) return addr llimpl_arena_malloc._always_inline_ = True register_external(arena_malloc, [int, int], llmemory.Address, diff --git a/rpython/rtyper/lltypesystem/llmemory.py b/rpython/rtyper/lltypesystem/llmemory.py --- a/rpython/rtyper/lltypesystem/llmemory.py +++ b/rpython/rtyper/lltypesystem/llmemory.py @@ -7,6 +7,7 @@ import weakref from rpython.annotator.bookkeeper import analyzer_for from rpython.annotator.model import SomeInteger, SomeObject, SomeString, s_Bool +from rpython.annotator.model import SomeBool from rpython.rlib.objectmodel import Symbolic, specialize from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.lltypesystem.lltype import SomePtr @@ -936,14 +937,15 @@ # ____________________________________________________________ -def raw_malloc(size): +def raw_malloc(size, zero=False): if not isinstance(size, AddressOffset): raise NotImplementedError(size) - return size._raw_malloc([], zero=False) + return size._raw_malloc([], zero=zero) @analyzer_for(raw_malloc) -def ann_raw_malloc(s_size): +def ann_raw_malloc(s_size, s_zero=None): assert isinstance(s_size, SomeInteger) # XXX add noneg...? + assert s_zero is None or isinstance(s_zero, SomeBool) return SomeAddress() diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py --- a/rpython/rtyper/lltypesystem/lloperation.py +++ b/rpython/rtyper/lltypesystem/lloperation.py @@ -396,7 +396,6 @@ 'raw_store': LLOp(canrun=True), 'bare_raw_store': LLOp(), 'gc_load_indexed': LLOp(sideeffects=False, canrun=True), - 'stack_malloc': LLOp(), # mmh 'track_alloc_start': LLOp(), 'track_alloc_stop': LLOp(), 'adr_add': LLOp(canfold=True), diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py --- a/rpython/rtyper/rbuiltin.py +++ b/rpython/rtyper/rbuiltin.py @@ -574,10 +574,14 @@ # memory addresses @typer_for(llmemory.raw_malloc) -def rtype_raw_malloc(hop): - v_size, = hop.inputargs(lltype.Signed) +def rtype_raw_malloc(hop, i_zero=None): + v_size = hop.inputarg(lltype.Signed, arg=0) + v_zero, = parse_kwds(hop, (i_zero, None)) + if v_zero is None: + v_zero = hop.inputconst(lltype.Bool, False) hop.exception_cannot_occur() - return hop.genop('raw_malloc', [v_size], resulttype=llmemory.Address) + return hop.genop('raw_malloc', [v_size, v_zero], + resulttype=llmemory.Address) @typer_for(llmemory.raw_malloc_usage) def rtype_raw_malloc_usage(hop): diff --git a/rpython/rtyper/test/test_llinterp.py b/rpython/rtyper/test/test_llinterp.py --- a/rpython/rtyper/test/test_llinterp.py +++ b/rpython/rtyper/test/test_llinterp.py @@ -372,19 +372,6 @@ result = interpret(getids, [i, j]) assert result -def test_stack_malloc(): - py.test.skip("stack-flavored mallocs no longer supported") - class A(object): - pass - def f(): - a = A() - a.i = 1 - return a.i - interp, graph = get_interpreter(f, []) - graph.startblock.operations[0].args[1] = inputconst(Void, {'flavor': "stack"}) - result = interp.eval_graph(graph, []) - assert result == 1 - def test_invalid_stack_access(): py.test.skip("stack-flavored mallocs no longer supported") class A(object): diff --git a/rpython/translator/c/funcgen.py b/rpython/translator/c/funcgen.py --- a/rpython/translator/c/funcgen.py +++ b/rpython/translator/c/funcgen.py @@ -608,16 +608,6 @@ return 'GC_REGISTER_FINALIZER(%s, (GC_finalization_proc)%s, NULL, NULL, NULL);' \ % (self.expr(op.args[0]), self.expr(op.args[1])) - def OP_RAW_MALLOC(self, op): - eresult = self.expr(op.result) - esize = self.expr(op.args[0]) - return "OP_RAW_MALLOC(%s, %s, void *);" % (esize, eresult) - - def OP_STACK_MALLOC(self, op): - eresult = self.expr(op.result) - esize = self.expr(op.args[0]) - return "OP_STACK_MALLOC(%s, %s, void *);" % (esize, eresult) - def OP_DIRECT_FIELDPTR(self, op): return self.OP_GETFIELD(op, ampersand='&') diff --git a/rpython/translator/c/src/mem.h b/rpython/translator/c/src/mem.h --- a/rpython/translator/c/src/mem.h +++ b/rpython/translator/c/src/mem.h @@ -8,11 +8,14 @@ #define OP_STACK_CURRENT(r) r = (Signed)&r -#define OP_RAW_MALLOC(size, r, restype) { \ - r = (restype) malloc(size); \ - if (r != NULL) { \ - COUNT_MALLOC; \ - } \ +#define OP_RAW_MALLOC(size, zero, result) { \ + if (zero) \ + result = calloc(size, 1); \ + else \ + result = malloc(size); \ + if (result != NULL) { \ + COUNT_MALLOC; \ + } \ } #define OP_RAW_FREE(p, r) free(p); COUNT_FREE; @@ -26,10 +29,6 @@ #define alloca _alloca #endif -#define OP_STACK_MALLOC(size,r,restype) \ - r = (restype) alloca(size); \ - if (r != NULL) memset((void*) r, 0, size); - #define OP_RAW_MEMCOPY(x,y,size,r) memcpy(y,x,size); #define OP_RAW_MEMMOVE(x,y,size,r) memmove(y,x,size); diff --git a/rpython/translator/c/test/test_lladdresses.py b/rpython/translator/c/test/test_lladdresses.py --- a/rpython/translator/c/test/test_lladdresses.py +++ b/rpython/translator/c/test/test_lladdresses.py @@ -32,7 +32,29 @@ assert res == 42 res = fc(1) assert res == 1 - + +def test_memory_access_zero(): + def f(): + blocks = [] + for i in range(1000): + addr = raw_malloc(16, zero=False) + addr.signed[1] = 10000 + i + blocks.append(addr) + for addr in blocks: + raw_free(addr) + result = 0 + blocks = [] + for i in range(1000): + addr = raw_malloc(16, zero=True) + result |= addr.signed[1] + blocks.append(addr) + for addr in blocks: + raw_free(addr) + return result + fc = compile(f, []) + res = fc() + assert res == 0 + def test_memory_float(): S = lltype.GcStruct("S", ("x", lltype.Float), ("y", lltype.Float)) offset = FieldOffset(S, 'x') @@ -155,18 +177,6 @@ fn = compile(f, [int]) assert fn(1) == 2 -def test_flavored_malloc_stack(): - class A(object): - _alloc_flavor_ = "stack" - def __init__(self, val): - self.val = val - def f(x): - a = A(x + 1) - result = a.val - return result - fn = compile(f, [int]) - assert fn(1) == 2 - def test_gcref(): if sys.platform == 'darwin': py.test.skip("'boehm' may crash") _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit