Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r88922:e3f6864ebcdc Date: 2016-12-07 09:18 +0100 http://bitbucket.org/pypy/pypy/changeset/e3f6864ebcdc/
Log: hg merge raw-calloc Replace malloc+memset with a single calloc. This might be useful for large allocations. Also remove the deprecated stack_malloc. 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/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/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