[pypy-commit] stmgc c8-card-marking: progress
Raemi
noreply at buildbot.pypy.org
Thu Feb 26 21:46:49 CET 2015
Author: Remi Meier <remi.meier at gmail.com>
Branch: c8-card-marking
Changeset: r1672:023ed269165f
Date: 2015-02-26 21:22 +0100
http://bitbucket.org/pypy/stmgc/changeset/023ed269165f/
Log: progress
diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -445,6 +445,7 @@
}
+static void reset_cards_from_modified_objects(void);
static void reset_wb_executed_flags(void);
static void readd_wb_executed_flags(void);
static void check_all_write_barrier_flags(char *segbase, struct list_s *list);
@@ -527,6 +528,8 @@
STM_PSEGMENT->transaction_state = TS_NONE;
STM_PSEGMENT->safe_point = SP_NO_TRANSACTION;
+ reset_cards_from_modified_objects();
+
list_clear(STM_PSEGMENT->modified_old_objects);
STM_PSEGMENT->last_commit_log_entry = new;
release_modification_lock(STM_SEGMENT->segment_num);
@@ -553,6 +556,8 @@
check_all_write_barrier_flags(STM_SEGMENT->segment_base,
STM_PSEGMENT->modified_old_objects);
+ reset_cards_from_modified_objects();
+
/* compare with _validate_and_attach: */
STM_PSEGMENT->transaction_state = TS_NONE;
STM_PSEGMENT->safe_point = SP_NO_TRANSACTION;
@@ -576,10 +581,13 @@
}
-static bool obj_should_use_cards(object_t *obj)
+static bool obj_should_use_cards(char *seg_base, object_t *obj)
{
+ if (is_small_uniform(obj))
+ return false;
+
struct object_s *realobj = (struct object_s *)
- REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
+ REAL_ADDRESS(seg_base, obj);
long supports = stmcb_obj_supports_cards(realobj);
if (!supports)
return false;
@@ -750,7 +758,7 @@
{
/* the PyPy JIT calls this function directly if it finds that an
array doesn't have the GCFLAG_CARDS_SET */
- bool mark_card = obj_should_use_cards(obj);
+ bool mark_card = obj_should_use_cards(STM_SEGMENT->segment_base, obj);
write_slowpath_common(obj, mark_card);
return mark_card;
}
@@ -835,6 +843,20 @@
STM_SEGMENT->transaction_read_version = 1;
}
+static void reset_cards_from_modified_objects(void)
+{
+ struct list_s *list = STM_PSEGMENT->modified_old_objects;
+ struct stm_undo_s *undo = (struct stm_undo_s *)list->items;
+ struct stm_undo_s *end = (struct stm_undo_s *)(list->items + list->count);
+
+ for (; undo < end; undo++) {
+ object_t *obj = undo->object;
+ if (obj_should_use_cards(STM_SEGMENT->segment_base, obj))
+ _reset_object_cards(get_priv_segment(STM_SEGMENT->segment_num),
+ obj, CARD_CLEAR, false);
+ }
+}
+
static void reset_wb_executed_flags(void)
{
dprintf(("reset_wb_executed_flags()\n"));
@@ -984,9 +1006,9 @@
LIST_FOREACH_R(STM_PSEGMENT->new_objects, object_t *,
({
assert(item->stm_flags & GCFLAG_WB_EXECUTED);
- _cards_cleared_in_object(pseg, item); /* check for C8 */
-
item->stm_flags &= ~GCFLAG_WB_EXECUTED;
+ if (obj_should_use_cards(pseg->pub.segment_base, item))
+ _reset_object_cards(pseg, item, CARD_CLEAR, false);
synchronize_object_enqueue(item, true);
}));
synchronize_objects_flush();
@@ -1020,7 +1042,6 @@
bool was_inev = STM_PSEGMENT->transaction_state == TS_INEVITABLE;
_validate_and_add_to_commit_log();
-
/* XXX do we still need a s_mutex_lock() section here? */
s_mutex_lock();
@@ -1081,7 +1102,7 @@
undo->backup,
SLICE_SIZE(undo->slice));
- if (obj_should_use_cards(obj))
+ if (obj_should_use_cards(pseg->pub.segment_base, obj))
_reset_object_cards(pseg, obj, CARD_CLEAR, false);
/* XXXXXXXXX: only reset cards of slice!! ^^^^^^^ */
@@ -1124,14 +1145,8 @@
/* some new objects may have cards when aborting, clear them too */
LIST_FOREACH_R(pseg->new_objects, object_t * /*item*/,
{
- struct object_s *realobj = (struct object_s *)
- REAL_ADDRESS(pseg->pub.segment_base, item);
-
- if (realobj->stm_flags & GCFLAG_CARDS_SET) {
- /* CARDS_SET is enough since other HAS_CARDS objs
- are already cleared */
+ if (obj_should_use_cards(pseg->pub.segment_base, item))
_reset_object_cards(pseg, item, CARD_CLEAR, false);
- }
});
acquire_modification_lock(segment_num);
@@ -1318,7 +1333,7 @@
static void _card_wise_synchronize_object_now(object_t *obj, ssize_t obj_size)
{
assert(obj_size >= 32);
- assert(obj_should_use_cards(obj));
+ assert(obj_should_use_cards(STM_SEGMENT->segment_base, obj));
assert(!(obj->stm_flags & GCFLAG_CARDS_SET));
uintptr_t offset_itemsize[2];
@@ -1434,7 +1449,7 @@
OPT_ASSERT(obj_size <= GC_LAST_SMALL_SIZE);
_synchronize_fragment((stm_char *)obj, obj_size);
return;
- } else if (ignore_cards || !obj_should_use_cards(obj)) {
+ } else if (ignore_cards || !obj_should_use_cards(STM_SEGMENT->segment_base, obj)) {
/* else, a more complicated case for large objects, to copy
around data only within the needed pages */
_page_wise_synchronize_object_now(obj, obj_size);
diff --git a/c8/stm/misc.c b/c8/stm/misc.c
--- a/c8/stm/misc.c
+++ b/c8/stm/misc.c
@@ -111,6 +111,15 @@
}
+uint8_t _stm_get_card_value(object_t *obj, long idx)
+{
+ struct stm_read_marker_s *cards = get_read_marker(STM_SEGMENT->segment_base,
+ (uintptr_t)obj);
+ return cards[get_index_to_card_index(idx)].rm;
+}
+
+
+
static struct stm_commit_log_entry_s *_last_cl_entry;
static long _last_cl_entry_index;
void _stm_start_enum_last_cl_entry()
diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c
--- a/c8/stm/nursery.c
+++ b/c8/stm/nursery.c
@@ -250,8 +250,6 @@
uintptr_t card_index = 1;
uintptr_t last_card_index = get_index_to_card_index(size - 1); /* max valid index */
- assert(cards->rm == STM_SEGMENT->transaction_read_version); /* stm_read() */
-
/* XXX: merge ranges */
while (card_index <= last_card_index) {
if (cards[card_index].rm == CARD_MARKED) {
diff --git a/c8/stmgc.h b/c8/stmgc.h
--- a/c8/stmgc.h
+++ b/c8/stmgc.h
@@ -94,6 +94,7 @@
char *_stm_real_address(object_t *o);
#ifdef STM_TESTS
#include <stdbool.h>
+uint8_t _stm_get_card_value(object_t *obj, long idx);
bool _stm_was_read(object_t *obj);
bool _stm_was_written(object_t *obj);
bool _stm_was_written_card(object_t *obj);
diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -11,6 +11,7 @@
#define _STM_GCFLAG_WRITE_BARRIER ...
#define _STM_FAST_ALLOC ...
#define _STM_CARD_SIZE ...
+#define _STM_CARD_MARKED ...
typedef struct {
...;
@@ -46,6 +47,8 @@
/*void stm_write_card(); use _checked_stm_write_card() instead */
+uint8_t _stm_get_card_value(object_t *obj, long idx);
+
void stm_setup(void);
void stm_teardown(void);
void stm_register_thread_local(stm_thread_local_t *tl);
@@ -396,6 +399,10 @@
NB_SEGMENTS = lib.STM_NB_SEGMENTS
FAST_ALLOC = lib._STM_FAST_ALLOC
CARD_SIZE = lib._STM_CARD_SIZE # 16b at least
+CARD_CLEAR = 0
+CARD_MARKED = lib._STM_CARD_MARKED
+CARD_MARKED_OLD = CARD_MARKED + 1
+
class Conflict(Exception):
pass
diff --git a/c8/test/test_card_marking.py b/c8/test/test_card_marking.py
--- a/c8/test/test_card_marking.py
+++ b/c8/test/test_card_marking.py
@@ -2,6 +2,8 @@
import py
+get_card_value = lib._stm_get_card_value
+
class TestBasic(BaseTest):
def _collect(self, kind):
@@ -221,3 +223,24 @@
assert stm_get_char(o, 1000+CARD_SIZE*12) == 'e'
self.commit_transaction()
+
+
+ def test_clear_cards(self):
+ o = stm_allocate_old(1000+20*CARD_SIZE)
+
+ self.start_transaction()
+ assert get_card_value(o, 1000) == CARD_CLEAR
+ stm_set_char(o, 'a', 1000, True)
+ assert get_card_value(o, 1000) == CARD_MARKED
+ assert o in old_objects_with_cards_set()
+
+ stm_minor_collect()
+ assert get_card_value(o, 1000) == CARD_MARKED_OLD
+ self.commit_transaction()
+
+ self.start_transaction()
+ assert get_card_value(o, 1000) == CARD_CLEAR
+ stm_set_char(o, 'b', 1000, True)
+ assert get_card_value(o, 1000) == CARD_MARKED
+ assert o in old_objects_with_cards_set()
+ self.commit_transaction()
diff --git a/c8/test/test_random.py b/c8/test/test_random.py
--- a/c8/test/test_random.py
+++ b/c8/test/test_random.py
@@ -428,7 +428,7 @@
r = thread_state.get_random_root()
trs = thread_state.transaction_state
is_ref = global_state.has_ref_type(r)
- try_cards = global_state.rnd.randrange(1, 100) > 5 and False
+ try_cards = global_state.rnd.randrange(1, 100) > 5 # and False
#
# decide on a value to write
if is_ref:
More information about the pypy-commit
mailing list