diff options
author | Alexander Ederer <alexander.ederer@unity3d.com> | 2021-11-23 17:38:05 +0300 |
---|---|---|
committer | Alexander Ederer <alexander.ederer@unity3d.com> | 2021-11-23 17:38:05 +0300 |
commit | b005ad5f517c0635172a842c13fefd3ff692a072 (patch) | |
tree | 6c354d979da06abd7a20d08f0e7599dffbdccd12 | |
parent | 2e82b58b12ad2cf9d59a770809b1af3594e53781 (diff) | |
parent | b8a4d0dfcd7545e2a422237db0af75f72cf10e96 (diff) |
Merge branch 'unity-master' into platform/hmi/qnx
-rw-r--r-- | .gitmodules | 2 | ||||
-rw-r--r-- | finalize.c | 10 | ||||
-rw-r--r-- | include/gc.h | 4 | ||||
-rw-r--r-- | include/gc_mark.h | 7 | ||||
-rw-r--r-- | mark.c | 20 | ||||
-rw-r--r-- | os_dep.c | 12 |
6 files changed, 51 insertions, 4 deletions
diff --git a/.gitmodules b/.gitmodules index f7c7ca9d..6f8c5623 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "libatomic_ops"] path = libatomic_ops - url = git://github.com/Unity-Technologies/libatomic_ops.git + url = https://github.com/Unity-Technologies/libatomic_ops.git branch = unity-release-7_4 @@ -1264,6 +1264,14 @@ GC_INNER void GC_finalize(void) #endif /* !JAVA_FINALIZATION_NOT_NEEDED */ +static volatile GC_bool GC_interrupt_finalizers = FALSE; + +void +GC_set_interrupt_finalizers(void) +{ + GC_interrupt_finalizers = TRUE; +} + /* Returns true if it is worth calling GC_invoke_finalizers. (Useful if */ /* finalizers can only be called from some kind of "safe state" and */ /* getting into that safe state is expensive.) */ @@ -1284,7 +1292,7 @@ GC_API int GC_CALL GC_invoke_finalizers(void) word bytes_freed_before = 0; /* initialized to prevent warning. */ DCL_LOCK_STATE; - while (GC_should_invoke_finalizers()) { + while (GC_should_invoke_finalizers() && !GC_interrupt_finalizers) { struct finalizable_object * curr_fo; # ifdef THREADS diff --git a/include/gc.h b/include/gc.h index 3d10a9a4..fb7d73d5 100644 --- a/include/gc.h +++ b/include/gc.h @@ -1294,6 +1294,10 @@ GC_API GC_await_finalize_proc GC_CALL GC_get_await_finalize_proc(void); /* Does not use any synchronization. */ GC_API int GC_CALL GC_should_invoke_finalizers(void); +/* Sets flag to signal GC_invoke_finalizers to break */ +/* Does not use any synchronization. */ +GC_API void GC_CALL GC_set_interrupt_finalizers(void); + GC_API int GC_CALL GC_invoke_finalizers(void); /* Run finalizers for all objects that are ready to */ /* be finalized. Return the number of finalizers */ diff --git a/include/gc_mark.h b/include/gc_mark.h index 108794de..2e468850 100644 --- a/include/gc_mark.h +++ b/include/gc_mark.h @@ -310,6 +310,13 @@ GC_API int GC_CALL GC_is_tmp_root(void *); GC_API void GC_CALL GC_print_trace(GC_word /* gc_no */); GC_API void GC_CALL GC_print_trace_inner(GC_word /* gc_no */); +/* Set the client for when mark stack is empty. A client can use */ +/* this callback to process (un)marked objects and push additional */ +/* work onto the stack. Useful for implementing ephemerons. */ +typedef void (GC_CALLBACK* GC_mark_stack_empty_proc)(void); +GC_API void GC_CALL GC_set_mark_stack_empty (GC_mark_stack_empty_proc); +GC_API GC_mark_stack_empty_proc GC_CALL GC_get_mark_stack_empty (void); + #ifdef __cplusplus } /* extern "C" */ #endif @@ -116,6 +116,7 @@ GC_INNER size_t GC_mark_stack_size = 0; GC_INNER mark_state_t GC_mark_state = MS_NONE; GC_INNER GC_bool GC_mark_stack_too_small = FALSE; +GC_INNER GC_bool GC_mark_stack_empty_called = FALSE; static struct hblk * scan_ptr; @@ -400,11 +401,26 @@ static void alloc_mark_stack(size_t); MARK_FROM_MARK_STACK(); break; } else { - GC_mark_state = MS_NONE; if (GC_mark_stack_too_small) { + GC_mark_state = MS_NONE; alloc_mark_stack(2*GC_mark_stack_size); + return(TRUE); + } else { + GC_mark_stack_empty_proc mark_stack_empty_proc = GC_get_mark_stack_empty(); + if (GC_mark_stack_empty_called || !mark_stack_empty_proc) { + GC_mark_state = MS_NONE; + GC_mark_stack_empty_called = FALSE; + return(TRUE); + } else { + if (mark_stack_empty_proc != 0) + mark_stack_empty_proc(); + + /* break below here loops us around the mark phase once again */ + /* to process any items push by the callback */ + GC_mark_stack_empty_called = TRUE; + } } - return(TRUE); + break; } case MS_INVALID: @@ -2809,6 +2809,18 @@ void GC_reset_default_push_other_roots(void) #endif } +GC_push_other_roots_proc GC_on_mark_stack_empty; + +GC_API void GC_CALL GC_set_mark_stack_empty (GC_mark_stack_empty_proc fn) +{ + GC_on_mark_stack_empty = fn; +} + +GC_API GC_mark_stack_empty_proc GC_CALL GC_get_mark_stack_empty (void) +{ + return GC_on_mark_stack_empty; +} + /* * Routines for accessing dirty bits on virtual pages. * There are six ways to maintain this information: |