diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index ffec0503c958a28f0cc6c605801b9f3b2644ac85..6dbd881b152bfa31acfa6baa38076d7eed0b1f53 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 379c7a7c6bdee0808347e0e3b52823de27ce56a4..23b2835b27ee79a31a01e0dcb6c4c7c285bd3381 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 bad65287b58d49393c804f3d772af7416ed4aac0..b8cac2a1fd6a093794827760c99f707ac32e4ed9 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_ */