[pypy-commit] stmgc c7-refactor: The tree data structure can explode when fed non-aligned addresses.
arigo
noreply at buildbot.pypy.org
Wed Feb 26 14:13:54 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: c7-refactor
Changeset: r867:e6d52f7b3ef1
Date: 2014-02-26 14:13 +0100
http://bitbucket.org/pypy/stmgc/changeset/e6d52f7b3ef1/
Log: The tree data structure can explode when fed non-aligned addresses.
Assert that they are aligned and fix the tests.
diff --git a/c7/stm/list.c b/c7/stm/list.c
--- a/c7/stm/list.c
+++ b/c7/stm/list.c
@@ -54,23 +54,23 @@
static void tree_free(struct tree_s *tree)
{
free(tree->raw_start);
+ assert(memset(tree, 0xDD, sizeof(struct tree_s)));
free(tree);
}
static void _tree_compress(struct tree_s *tree)
{
- wlog_t *item;
- struct tree_s tree_copy;
- memset(&tree_copy, 0, sizeof(struct tree_s));
+ wlog_t *item;
+ struct tree_s tree_copy;
+ memset(&tree_copy, 0, sizeof(struct tree_s));
- TREE_LOOP_FORWARD(*tree, item)
- {
- tree_insert(&tree_copy, item->addr, item->val);
+ TREE_LOOP_FORWARD(*tree, item) {
+ tree_insert(&tree_copy, item->addr, item->val);
} TREE_LOOP_END;
- free(tree->raw_start);
- *tree = tree_copy;
+ free(tree->raw_start);
+ *tree = tree_copy;
}
static wlog_t *_tree_find(char *entry, uintptr_t addr)
@@ -122,6 +122,7 @@
static void tree_insert(struct tree_s *tree, uintptr_t addr, uintptr_t val)
{
assert(addr != 0); /* the NULL key is reserved */
+ assert(!(addr & (sizeof(void *) - 1))); /* the key must be aligned */
retry:;
wlog_t *wlog;
uintptr_t key = addr;
@@ -129,6 +130,7 @@
char *p = (char *)(tree->toplevel.items);
char *entry;
while (1) {
+ assert(shift < TREE_DEPTH_MAX * TREE_BITS);
p += (key >> shift) & TREE_MASK;
shift += TREE_BITS;
entry = *(char **)p;
diff --git a/c7/stm/list.h b/c7/stm/list.h
--- a/c7/stm/list.h
+++ b/c7/stm/list.h
@@ -138,6 +138,7 @@
continue; \
if (((long)_entry) & 1) \
{ /* points to a further level: enter it */ \
+ assert(_stackp - _stack < TREE_DEPTH_MAX); \
_stackp->next = _next; \
_stackp->end = _end; \
_stackp++; \
diff --git a/c7/test/test_list.py b/c7/test/test_list.py
--- a/c7/test/test_list.py
+++ b/c7/test/test_list.py
@@ -65,34 +65,34 @@
def test_tree_add():
t = lib.tree_create()
- lib.tree_insert(t, 23, 456)
- for i in range(100):
- assert lib.tree_contains(t, i) == (i == 23)
+ lib.tree_insert(t, 23000, 456)
+ for i in range(0, 100000, 1000):
+ assert lib.tree_contains(t, i) == (i == 23000)
lib.tree_free(t)
def test_tree_is_cleared():
t = lib.tree_create()
assert lib.tree_is_cleared(t)
- lib.tree_insert(t, 23, 456)
+ lib.tree_insert(t, 23000, 456)
assert not lib.tree_is_cleared(t)
lib.tree_free(t)
def test_tree_delete_item():
t = lib.tree_create()
- lib.tree_insert(t, 23, 456)
- lib.tree_insert(t, 42, 34289)
+ lib.tree_insert(t, 23000, 456)
+ lib.tree_insert(t, 42000, 34289)
assert not lib.tree_is_cleared(t)
- assert lib.tree_contains(t, 23)
- res = lib.tree_delete_item(t, 23)
+ assert lib.tree_contains(t, 23000)
+ res = lib.tree_delete_item(t, 23000)
assert res
- assert not lib.tree_contains(t, 23)
- res = lib.tree_delete_item(t, 23)
+ assert not lib.tree_contains(t, 23000)
+ res = lib.tree_delete_item(t, 23000)
assert not res
- res = lib.tree_delete_item(t, 21)
+ res = lib.tree_delete_item(t, 21000)
assert not res
assert not lib.tree_is_cleared(t)
- assert lib.tree_contains(t, 42)
- res = lib.tree_delete_item(t, 42)
+ assert lib.tree_contains(t, 42000)
+ res = lib.tree_delete_item(t, 42000)
assert res
assert not lib.tree_is_cleared(t) # not cleared, but still empty
for i in range(100):
@@ -101,18 +101,18 @@
def test_tree_walk():
t = lib.tree_create()
- lib.tree_insert(t, 23, 456)
- lib.tree_insert(t, 42, 34289)
+ lib.tree_insert(t, 23000, 456)
+ lib.tree_insert(t, 42000, 34289)
a = ffi.new("uintptr_t[10]")
res = lib.test_tree_walk(t, a)
assert res == 2
- assert a[0] == 23
- assert a[1] == 42
+ assert ((a[0] == 23000 and a[1] == 42000) or
+ (a[0] == 42000 and a[1] == 23000))
lib.tree_free(t)
def test_tree_walk_big():
t = lib.tree_create()
- values = [random.randrange(0, 1000000) for i in range(300)]
+ values = random.sample(xrange(0, 1000000, 8), 300)
for x in values:
lib.tree_insert(t, x, x)
a = ffi.new("uintptr_t[1000]")
More information about the pypy-commit
mailing list