[pypy-commit] stmgc c7-refactor: in-progress
arigo
noreply at buildbot.pypy.org
Mon Feb 17 16:09:34 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: c7-refactor
Changeset: r758:4ab38af77c28
Date: 2014-02-17 16:09 +0100
http://bitbucket.org/pypy/stmgc/changeset/4ab38af77c28/
Log: in-progress
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -38,6 +38,9 @@
/* objects that are allocated crossing a page boundary have this
flag set */
GCFLAG_CROSS_PAGE = 0x02,
+ /* only used during collections to mark an obj as moved out of the
+ generation it was in */
+ GCFLAG_MOVED = 0x04,
};
#define CROSS_PAGE_BOUNDARY(start, stop) \
diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -3,6 +3,18 @@
#endif
+/* Outside the nursery, we are taking from the highest addresses
+ complete pages, one at a time, which uniformly contain objects
+ of size "8 * N" for any "2 <= N < GC_N_SMALL_REQUESTS". We are
+ taking from the lowest addresses large objects, which are
+ guaranteed to be at least 256 bytes long (actually 288),
+ allocated by largemalloc.c.
+*/
+
+#define GC_N_SMALL_REQUESTS 36
+#define GC_MEDIUM_REQUEST (GC_N_SMALL_REQUESTS * 8)
+
+
static void setup_gcpage(void)
{
/* NB. the very last page is not used, which allows a speed-up in
@@ -11,21 +23,65 @@
uintptr_t length = (NB_PAGES - END_NURSERY_PAGE - 1) * 4096UL;
largemalloc_init_arena(base, length);
- uninitialized_page_start = (stm_char *)(END_NURSERY_PAGE * 4096UL);
- uninitialized_page_stop = (stm_char *)((NB_PAGES - 1) * 4096UL);
+ uninitialized_page_start = stm_object_pages + END_NURSERY_PAGE * 4096UL;
+ uninitialized_page_stop = stm_object_pages + (NB_PAGES - 1) * 4096UL;
+
+ assert(GC_MEDIUM_REQUEST >= (1 << 8));
+}
+
+static char *allocate_outside_nursery(uint64_t size)
+{
+ /* not thread-safe! Use only when holding the mutex */
+ assert(_has_mutex());
+
+ OPT_ASSERT(size >= 16);
+ OPT_ASSERT((size & 7) == 0);
+
+ uint64_t index = size / 8;
+ if (index < GC_N_SMALL_REQUESTS) {
+ assert(index >= 2);
+ // XXX! TEMPORARY!
+ return allocate_outside_nursery(GC_MEDIUM_REQUEST);
+ }
+ else {
+ /* The object is too large to fit inside the uniform pages.
+ Allocate it with largemalloc.c from the lower addresses */
+ char *addr = large_malloc(size);
+
+ if (addr + size > uninitialized_page_start) {
+ uintptr_t pagenum =
+ (uninitialized_page_start - stm_object_pages) / 4096UL;
+ uintptr_t pagecount =
+ (addr + size - uninitialized_page_start) / 4096UL + 20;
+ uintptr_t pagemax =
+ (uninitialized_page_stop - uninitialized_page_start) / 4096UL;
+ if (pagecount > pagemax)
+ pagecount = pagemax;
+ pages_initialize_shared(pagenum, pagecount);
+
+ uninitialized_page_start += pagecount * 4096UL;
+ }
+
+ assert(get_single_creation_marker(
+ (stm_char *)(addr - stm_object_pages)) == 0);
+ return addr;
+ }
}
object_t *_stm_allocate_old(ssize_t size_rounded_up)
{
- /* XXX not thread-safe! */
+ /* XXX not thread-safe! and only for tests, don't use when a
+ transaction might be running! */
+ assert(size_rounded_up >= 16);
+ assert((size_rounded_up & 7) == 0);
+
char *addr = large_malloc(size_rounded_up);
- stm_char* o = (stm_char *)(addr - stm_object_pages);
- if (o + size_rounded_up > uninitialized_page_start) {
+ if (addr + size_rounded_up > uninitialized_page_start) {
uintptr_t pagenum =
- ((uint64_t)uninitialized_page_start) / 4096UL;
+ (uninitialized_page_start - stm_object_pages) / 4096UL;
uintptr_t pagecount =
- (o + size_rounded_up - uninitialized_page_start) / 4096UL + 20;
+ (addr + size_rounded_up - uninitialized_page_start) / 4096UL + 20;
uintptr_t pagemax =
(uninitialized_page_stop - uninitialized_page_start) / 4096UL;
if (pagecount > pagemax)
@@ -37,6 +93,7 @@
memset(addr, 0, size_rounded_up);
+ stm_char* o = (stm_char *)(addr - stm_object_pages);
if (CROSS_PAGE_BOUNDARY(o, o + size_rounded_up))
((object_t *)o)->stm_flags = GCFLAG_CROSS_PAGE;
diff --git a/c7/stm/gcpage.h b/c7/stm/gcpage.h
--- a/c7/stm/gcpage.h
+++ b/c7/stm/gcpage.h
@@ -1,3 +1,5 @@
-static stm_char *uninitialized_page_start;
-static stm_char *uninitialized_page_stop;
+static char *uninitialized_page_start; /* within segment 0 */
+static char *uninitialized_page_stop;
+
+static char *allocate_outside_nursery(uint64_t size);
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -51,14 +51,46 @@
return (uintptr_t)obj < NURSERY_START + NURSERY_SIZE;
}
+static bool _is_young(object_t *obj)
+{
+ return _stm_in_nursery(obj); /* for now */
+}
+
/************************************************************/
static void minor_trace_if_young(object_t **pobj)
{
- //...
+ /* takes a normal pointer to a thread-local pointer to an object */
+ object_t *obj = *pobj;
+ if (obj == NULL)
+ return;
+ if (!_is_young(obj))
+ return;
+
+ /* the location the object moved to is the second word in 'obj' */
+ object_t *TLPREFIX *pforwarded_array = (object_t *TLPREFIX *)obj;
+
+ if (UNLIKELY(obj->stm_flags & GCFLAG_MOVED)) {
+ *pobj = pforwarded_array[1]; /* already moved */
+ return;
+ }
+
+#if 0
+ /* move obj to somewhere else */
+ size_t size = stmcb_size_rounded_up(stm_object_pages + (uintptr_t)*pobj);
+ bool is_small;
+ object_t *moved = stm_big_small_alloc_old(size, &is_small);
+
+ memcpy((void*)real_address(moved),
+ (void*)real_address(*pobj),
+ size);
+#endif
+
abort();
+
+ allocate_outside_nursery(-1);
}
static void minor_trace_roots(void)
diff --git a/c7/stm/pages.c b/c7/stm/pages.c
--- a/c7/stm/pages.c
+++ b/c7/stm/pages.c
@@ -94,12 +94,15 @@
memset(addr, newvalue, size >> 8);
}
+static uint8_t get_single_creation_marker(stm_char *p)
+{
+ uintptr_t cmaddr = ((uintptr_t)p) >> 8;
+ return ((stm_creation_marker_t *)cmaddr)->cm;
+}
+
static void set_single_creation_marker(stm_char *p, int newvalue)
{
- assert((((uintptr_t)p) & 255) == 0);
-
uintptr_t cmaddr = ((uintptr_t)p) >> 8;
-
((stm_creation_marker_t *)cmaddr)->cm = newvalue;
LIST_APPEND(STM_PSEGMENT->creation_markers, cmaddr);
}
diff --git a/c7/stm/pages.h b/c7/stm/pages.h
--- a/c7/stm/pages.h
+++ b/c7/stm/pages.h
@@ -30,5 +30,6 @@
}
static void set_creation_markers(stm_char *p, uint64_t size, int newvalue);
+static uint8_t get_single_creation_marker(stm_char *p);
static void set_single_creation_marker(stm_char *p, int newvalue);
static void reset_all_creation_markers(void);
More information about the pypy-commit
mailing list