Author: Armin Rigo <[email protected]>
Branch:
Changeset: r74943:e6ad4389d70b
Date: 2014-12-15 17:19 +0000
http://bitbucket.org/pypy/pypy/changeset/e6ad4389d70b/
Log: Do a ll_clear_indexes() instead of allocating a new array for
d.indexes when we can
diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -330,6 +330,20 @@
keepalive_until_here(newp)
return newp
[email protected]_look_inside
[email protected]()
+def ll_arrayclear(p):
+ # Equivalent to memset(array, 0). Only for GcArray(primitive-type) for
now.
+ from rpython.rlib.objectmodel import keepalive_until_here
+
+ length = len(p)
+ ARRAY = lltype.typeOf(p).TO
+ offset = llmemory.itemoffsetof(ARRAY, 0)
+ dest_addr = llmemory.cast_ptr_to_adr(p) + offset
+ llmemory.raw_memclear(dest_addr, llmemory.sizeof(ARRAY.OF) * length)
+ keepalive_until_here(p)
+
+
def no_release_gil(func):
func._dont_inline_ = True
func._no_release_gil_ = True
diff --git a/rpython/rlib/test/test_rgc.py b/rpython/rlib/test/test_rgc.py
--- a/rpython/rlib/test/test_rgc.py
+++ b/rpython/rlib/test/test_rgc.py
@@ -158,6 +158,16 @@
assert a2[2].x == 3
assert a2[2].y == 15
+def test_ll_arrayclear():
+ TYPE = lltype.GcArray(lltype.Signed)
+ a1 = lltype.malloc(TYPE, 10)
+ for i in range(10):
+ a1[i] = 100 + i
+ rgc.ll_arrayclear(a1)
+ assert len(a1) == 10
+ for i in range(10):
+ assert a1[i] == 0
+
def test__contains_gcptr():
assert not rgc._contains_gcptr(lltype.Signed)
assert not rgc._contains_gcptr(
diff --git a/rpython/rtyper/lltypesystem/rordereddict.py
b/rpython/rtyper/lltypesystem/rordereddict.py
--- a/rpython/rtyper/lltypesystem/rordereddict.py
+++ b/rpython/rtyper/lltypesystem/rordereddict.py
@@ -418,6 +418,7 @@
TYPE_LONG = lltype.Unsigned
def ll_malloc_indexes_and_choose_lookup(d, n):
+ # keep in sync with ll_clear_indexes() below
if n <= 256:
d.indexes = lltype.cast_opaque_ptr(llmemory.GCREF,
lltype.malloc(DICTINDEX_BYTE.TO, n,
@@ -439,6 +440,16 @@
zero=True))
d.lookup_function_no = FUNC_LONG
+def ll_clear_indexes(d, n):
+ if n <= 256:
+ rgc.ll_arrayclear(lltype.cast_opaque_ptr(DICTINDEX_BYTE, d.indexes))
+ elif n <= 65536:
+ rgc.ll_arrayclear(lltype.cast_opaque_ptr(DICTINDEX_SHORT, d.indexes))
+ elif IS_64BIT and n <= 2 ** 32:
+ rgc.ll_arrayclear(lltype.cast_opaque_ptr(DICTINDEX_INT, d.indexes))
+ else:
+ rgc.ll_arrayclear(lltype.cast_opaque_ptr(DICTINDEX_LONG, d.indexes))
+
def ll_call_insert_clean_function(d, hash, i):
DICT = lltype.typeOf(d).TO
if d.lookup_function_no == FUNC_BYTE:
@@ -704,13 +715,17 @@
ll_dict_reindex(d, new_size)
def ll_dict_reindex(d, new_size):
- ll_malloc_indexes_and_choose_lookup(d, new_size)
+ if bool(d.indexes) and _ll_len_of_d_indexes(d) == new_size:
+ ll_clear_indexes(d, new_size) # hack: we can reuse the same array
+ else:
+ ll_malloc_indexes_and_choose_lookup(d, new_size)
d.resize_counter = new_size * 2 - d.num_items * 3
assert d.resize_counter > 0
#
entries = d.entries
i = 0
- while i < d.num_used_items:
+ ibound = d.num_used_items
+ while i < ibound:
if entries.valid(i):
hash = entries.hash(i)
ll_call_insert_clean_function(d, hash, i)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit