From eb3e935b9704c591be9a951df48c1bea0b428be1 Mon Sep 17 00:00:00 2001 From: Jonathan Chambers Date: Tue, 15 Dec 2020 13:49:41 -0500 Subject: [PATCH] Implement check for sufficient execution stack. Enable across platforms and expose to embedding API. --- mono/metadata/icall.c | 35 +---------------------------------- mono/metadata/threads.c | 30 ++++++++++++++++++++++++++++++ mono/metadata/threads.h | 2 ++ 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index ffec0503c95..6dbd881b152 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -1017,40 +1017,7 @@ ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (M ICALL_EXPORT MonoBoolean ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void) { -#if defined(TARGET_WIN32) || defined(HOST_WIN32) - // It does not work on win32 -#elif defined(TARGET_ANDROID) || defined(__linux__) - // No need for now -#else - guint8 *stack_addr; - guint8 *current; - size_t stack_size; - int min_size; - MonoInternalThread *thread; - - mono_thread_info_get_stack_bounds (&stack_addr, &stack_size); - /* if we have no info we are optimistic and assume there is enough room */ - if (!stack_addr) - return TRUE; - - thread = mono_thread_internal_current (); - // .net seems to check that at least 50% of stack is available - min_size = thread->stack_size / 2; - - // TODO: It's not always set - if (!min_size) - return TRUE; - - current = (guint8 *)&stack_addr; - if (current > stack_addr) { - if ((current - stack_addr) < min_size) - return FALSE; - } else { - if (current - (stack_addr - stack_size) < min_size) - return FALSE; - } -#endif - return TRUE; + return mono_thread_has_sufficient_execution_stack (); } ICALL_EXPORT MonoObject * diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c index 379c7a7c6bd..23b2835b27e 100644 --- a/mono/metadata/threads.c +++ b/mono/metadata/threads.c @@ -5678,3 +5678,33 @@ MonoException* mono_unity_thread_check_exception() unlock_thread(thread); return NULL; } + +mono_bool mono_thread_has_sufficient_execution_stack (void) +{ + guint8* stack_addr; + guint8* current; + size_t stack_size; + size_t min_size; + + mono_thread_info_get_stack_bounds (&stack_addr, &stack_size); + /* if we have no info we are optimistic and assume there is enough room */ + if (!stack_addr || !stack_size) + return TRUE; + + min_size = stack_size / 2; + + // TODO: It's not always set + if (!min_size) + return TRUE; + + current = (guint8*)&stack_addr; + if (current > stack_addr) { + if ((current - stack_addr) < min_size) + return FALSE; + } + else { + if (current - (stack_addr - stack_size) < min_size) + return FALSE; + } + return TRUE; +} diff --git a/mono/metadata/threads.h b/mono/metadata/threads.h index bad65287b58..b8cac2a1fd6 100644 --- a/mono/metadata/threads.h +++ b/mono/metadata/threads.h @@ -57,6 +57,8 @@ MONO_API mono_bool mono_thread_is_foreign (MonoThread *thread); extern MONO_API mono_bool mono_thread_detach_if_exiting (void); +MONO_API mono_bool mono_thread_has_sufficient_execution_stack (void); + MONO_END_DECLS #endif /* _MONO_METADATA_THREADS_H_ */ -- GitLab