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

Reply via email to