Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Unity-Technologies/bdwgc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Chambers <joncham@gmail.com>2019-02-11 23:55:47 +0300
committerJonathan Chambers <joncham@gmail.com>2019-02-21 22:15:37 +0300
commiteaafcc146b9e033c24c592689afa8a6f3242d659 (patch)
tree1878cea2463ad2bc27286225055223d8067aa6ef
parentcd2c41ba19df1eb52ee1d7c41cc9d27fea053947 (diff)
Add GC_gcj_vector_malloc to support marking complex (value types with reference fields) arrays.
-rw-r--r--gcj_mlc.c89
-rw-r--r--include/gc_gcj.h6
2 files changed, 95 insertions, 0 deletions
diff --git a/gcj_mlc.c b/gcj_mlc.c
index acb7b114..d3b36a59 100644
--- a/gcj_mlc.c
+++ b/gcj_mlc.c
@@ -46,13 +46,24 @@
#endif
GC_bool GC_gcj_malloc_initialized = FALSE;
+#ifdef GC_ASSERTIONS
+ GC_INNER /* variable is also used in thread_local_alloc.c */
+#else
+ STATIC
+#endif
+GC_bool GC_gcj_vector_initialized = FALSE;
+
int GC_gcj_kind = 0; /* Object kind for objects with descriptors */
/* in "vtable". */
int GC_gcj_debug_kind = 0;
/* The kind of objects that is always marked */
/* with a mark proc call. */
+int GC_gcj_vector_kind = 0; /* Object kind for objects with descriptors */
+ /* in "vtable". */
+
GC_INNER ptr_t * GC_gcjobjfreelist = NULL;
+GC_INNER ptr_t * GC_gcjvecfreelist = NULL;
STATIC struct GC_ms_entry * GC_gcj_fake_mark_proc(word * addr GC_ATTR_UNUSED,
struct GC_ms_entry *mark_stack_ptr,
@@ -121,6 +132,36 @@ GC_API void GC_CALL GC_init_gcj_malloc(int mp_index,
UNLOCK();
}
+/* Caller does not hold allocation lock. */
+GC_API void GC_CALL GC_init_gcj_vector (int mp_index,
+ void * /* really GC_mark_proc */mp)
+{
+ DCL_LOCK_STATE;
+
+ if (mp == 0) /* In case GC_DS_PROC is unused. */
+ ABORT ("GC_init_gcj_vector: bad index");
+
+ GC_init (); /* In case it's not already done. */
+ LOCK ();
+ if (GC_gcj_vector_initialized) {
+ UNLOCK ();
+ return;
+ }
+ GC_gcj_vector_initialized = TRUE;
+
+ GC_ASSERT (GC_mark_procs[mp_index] == (GC_mark_proc)0); /* unused */
+ GC_mark_procs[mp_index ] = (GC_mark_proc)(word)mp;
+ if ((unsigned)mp_index >= GC_n_mark_procs)
+ ABORT ("GC_init_gcj_vector: bad index");
+ GC_gcjvecfreelist = (ptr_t *)GC_new_free_list_inner ();
+ GC_gcj_vector_kind = GC_new_kind_inner (GC_gcjvecfreelist,
+ GC_MAKE_PROC (mp_index,
+ 0),
+ FALSE, TRUE);
+
+ UNLOCK ();
+}
+
#define GENERAL_MALLOC_INNER(lb,k) \
GC_clear_stack(GC_generic_malloc_inner(lb, k))
@@ -197,6 +238,54 @@ static void maybe_finalize(void)
GC_dirty(op);
return((void *) op);
}
+
+#ifdef THREAD_LOCAL_ALLOC
+#error No THREAD_LOCAL_ALLOC support for GC_gcj_vector_malloc
+#else
+ GC_API GC_ATTR_MALLOC void * GC_CALL GC_gcj_vector_malloc (size_t lb,
+ void * ptr_to_struct_containing_descr)
+#endif
+ {
+ ptr_t op;
+ DCL_LOCK_STATE;
+
+ GC_DBG_COLLECT_AT_MALLOC (lb);
+ if (SMALL_OBJ (lb)) {
+ word lg;
+
+ LOCK ();
+ lg = GC_size_map[lb];
+ op = GC_gcjvecfreelist[lg];
+ if (EXPECT (0 == op, FALSE)) {
+ maybe_finalize ();
+ op = (ptr_t)GENERAL_MALLOC_INNER ((word)lb, GC_gcj_vector_kind);
+ if (0 == op) {
+ GC_oom_func oom_fn = GC_oom_fn;
+ UNLOCK ();
+ return((*oom_fn)(lb));
+ }
+ }
+ else {
+ GC_gcjvecfreelist[lg] = (ptr_t)obj_link (op);
+ GC_bytes_allocd += GRANULES_TO_BYTES ((word)lg);
+ }
+ GC_ASSERT (((void **)op)[1] == 0);
+ }
+ else {
+ LOCK ();
+ maybe_finalize ();
+ op = (ptr_t)GENERAL_MALLOC_INNER ((word)lb, GC_gcj_vector_kind);
+ if (0 == op) {
+ GC_oom_func oom_fn = GC_oom_fn;
+ UNLOCK ();
+ return((*oom_fn)(lb));
+ }
+ }
+ *(void **)op = ptr_to_struct_containing_descr;
+ UNLOCK ();
+ GC_dirty (op);
+ return((void *)op);
+ }
#endif
/* Similar to GC_gcj_malloc, but add debug info. This is allocated */
diff --git a/include/gc_gcj.h b/include/gc_gcj.h
index 476db221..deca0fee 100644
--- a/include/gc_gcj.h
+++ b/include/gc_gcj.h
@@ -68,6 +68,8 @@
/* (GC_GCJ_RESERVED_MARK_PROC_INDEX in gc_mark.h) is an obvious choice. */
GC_API void GC_CALL GC_init_gcj_malloc(int /* mp_index */,
void * /* really mark_proc */ /* mp */);
+GC_API void GC_CALL GC_init_gcj_vector (int /* mp_index */,
+ void * /* really mark_proc */ /* mp */);
/* Allocate an object, clear it, and store the pointer to the */
/* type structure (vtable in gcj). */
@@ -89,6 +91,10 @@ GC_API GC_ATTR_MALLOC GC_ATTR_ALLOC_SIZE(1) void * GC_CALL
GC_gcj_malloc_ignore_off_page(size_t /* lb */,
void * /* ptr_to_struct_containing_descr */);
+GC_API GC_ATTR_MALLOC void * GC_CALL
+ GC_gcj_vector_malloc(size_t /* lb */,
+ void * /* ptr_to_struct_containing_descr */);
+
/* The kind numbers of normal and debug gcj objects. */
/* Useful only for debug support, we hope. */
GC_API int GC_gcj_kind;