Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit