From 6e473031582abca312d89b9859e03b081cfc1e7a Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 31 Oct 2024 19:19:59 +0100 Subject: [PATCH 01/12] Playing around with some ideas --- src/native/monodroid/debug.cc | 2 +- src/native/monodroid/embedded-assemblies.hh | 9 +++- src/native/monodroid/monodroid-glue.cc | 15 +++++-- src/native/monodroid/osbridge.cc | 23 +++++++--- src/native/monodroid/xamarin_getifaddrs.cc | 32 ++++++------- src/native/runtime-base/android-system.cc | 2 +- src/native/runtime-base/cpu-arch-detect.cc | 8 ++-- src/native/runtime-base/jni-wrappers.hh | 8 ++-- src/native/shared/cpp-util.hh | 50 ++++++++++++++++++--- 9 files changed, 107 insertions(+), 42 deletions(-) diff --git a/src/native/monodroid/debug.cc b/src/native/monodroid/debug.cc index 139e8a24aae..add61468747 100644 --- a/src/native/monodroid/debug.cc +++ b/src/native/monodroid/debug.cc @@ -603,7 +603,7 @@ Debug::enable_soft_breakpoints (void) void* xamarin::android::conn_thread (void *arg) { - abort_if_invalid_pointer_argument (arg); + abort_if_invalid_pointer_argument (arg, "arg"); int res; Debug *instance = static_cast (arg); diff --git a/src/native/monodroid/embedded-assemblies.hh b/src/native/monodroid/embedded-assemblies.hh index 1bf6b358705..cfaaf4b9e40 100644 --- a/src/native/monodroid/embedded-assemblies.hh +++ b/src/native/monodroid/embedded-assemblies.hh @@ -26,6 +26,7 @@ #include "cppcompat.hh" #include "shared-constants.hh" #include "xxhash.hh" +#include "util.hh" #include @@ -158,7 +159,13 @@ namespace xamarin::android::internal { { area = static_cast(runtime_config_data); - abort_unless (runtime_config_data_size < std::numeric_limits::max (), "Runtime config binary blob size exceeds %u bytes", std::numeric_limits::max ()); + abort_unless ( + runtime_config_data_size < std::numeric_limits::max (), + [] { + return Util::monodroid_strdup_printf ("Runtime config binary blob size exceeds %u bytes", + std::numeric_limits::max ()); + } + ); size = static_cast(runtime_config_data_size); } diff --git a/src/native/monodroid/monodroid-glue.cc b/src/native/monodroid/monodroid-glue.cc index cd8d899a35d..a4d92ba1461 100644 --- a/src/native/monodroid/monodroid-glue.cc +++ b/src/native/monodroid/monodroid-glue.cc @@ -912,7 +912,12 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec jnienv_register_jni_natives = reinterpret_cast(mono_method_get_unmanaged_callers_only_ftnptr (registerType, &error)); } } - abort_unless (registerType != nullptr, "INTERNAL ERROR: Unable to find Android.Runtime.JNIEnvInit.RegisterJniNatives! %s", mono_error_get_message (&error)); + abort_unless ( + registerType != nullptr, + [&error] { + return Util::monodroid_strdup_printf("INTERNAL ERROR: Unable to find Android.Runtime.JNIEnvInit.RegisterJniNatives! %s", mono_error_get_message (&error)); + } + ); jclass lrefLoaderClass = env->GetObjectClass (loader); init.Loader_loadClass = env->GetMethodID (lrefLoaderClass, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); @@ -937,8 +942,12 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec abort_unless ( initialize != nullptr, - "Failed to obtain unmanaged-callers-only pointer to the Android.Runtime.JNIEnvInit.Initialize method. %s", - mono_error_get_message (&error) + [&error] { + return Util::monodroid_strdup_printf ( + "Failed to obtain unmanaged-callers-only pointer to the Android.Runtime.JNIEnvInit.Initialize method. %s", + mono_error_get_message (&error) + ); + } ); initialize (&init); diff --git a/src/native/monodroid/osbridge.cc b/src/native/monodroid/osbridge.cc index fe68ce59d06..cc900a30906 100644 --- a/src/native/monodroid/osbridge.cc +++ b/src/native/monodroid/osbridge.cc @@ -683,7 +683,7 @@ OSBridge::target_from_jobject (jobject jobj) int OSBridge::scc_get_stashed_index (MonoGCBridgeSCC *scc) { - abort_if_invalid_pointer_argument (scc); + abort_if_invalid_pointer_argument (scc, "scc"); abort_unless (scc->num_objs < 0, "Attempted to load stashed index from an object which does not contain one."); return -scc->num_objs - 1; @@ -862,8 +862,14 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri mono_field_get_value (obj, bridge_info->handle, &jref); if (jref) { alive++; - if (j > 0) - abort_unless (sccs [i]->is_alive, "Bridge SCC at index %d must be alive", i); + if (j > 0) { + abort_unless ( + sccs [i]->is_alive, + [&i] { + return Util::monodroid_strdup_printf ("Bridge SCC at index %d must be alive", i); + } + ); + } sccs [i]->is_alive = 1; mono_field_get_value (obj, bridge_info->refs_added, &refs_added); if (refs_added) { @@ -885,7 +891,10 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri } } } else { - abort_unless (!sccs [i]->is_alive, "Bridge SCC at index %d must NOT be alive", i); + abort_unless ( + !sccs [i]->is_alive, + [&i] { return Util::monodroid_strdup_printf ("Bridge SCC at index %d must NOT be alive", i); } + ); } } } @@ -993,8 +1002,8 @@ OSBridge::ensure_jnienv (void) void OSBridge::initialize_on_onload (JavaVM *vm, JNIEnv *env) { - abort_if_invalid_pointer_argument (env); - abort_if_invalid_pointer_argument (vm); + abort_if_invalid_pointer_argument (env, "env"); + abort_if_invalid_pointer_argument (vm, "vm"); jvm = vm; jclass lref = env->FindClass ("java/lang/Runtime"); @@ -1018,7 +1027,7 @@ OSBridge::initialize_on_onload (JavaVM *vm, JNIEnv *env) void OSBridge::initialize_on_runtime_init (JNIEnv *env, jclass runtimeClass) { - abort_if_invalid_pointer_argument (env); + abort_if_invalid_pointer_argument (env, "env"); GCUserPeer_class = RuntimeUtil::get_class_from_runtime_field(env, runtimeClass, "mono_android_GCUserPeer", true); GCUserPeer_ctor = env->GetMethodID (GCUserPeer_class, "", "()V"); abort_unless (GCUserPeer_class != nullptr && GCUserPeer_ctor != nullptr, "Failed to load mono.android.GCUserPeer!"); diff --git a/src/native/monodroid/xamarin_getifaddrs.cc b/src/native/monodroid/xamarin_getifaddrs.cc index 17f0f8a7ba6..9f071132976 100644 --- a/src/native/monodroid/xamarin_getifaddrs.cc +++ b/src/native/monodroid/xamarin_getifaddrs.cc @@ -370,8 +370,8 @@ get_ifaddrs_impl (int (**getifaddrs_implementation) (struct _monodroid_ifaddrs * { void *libc; - abort_if_invalid_pointer_argument (getifaddrs_implementation); - abort_if_invalid_pointer_argument (freeifaddrs_implementation); + abort_if_invalid_pointer_argument (getifaddrs_implementation, "getifaddrs_implementation"); + abort_if_invalid_pointer_argument (freeifaddrs_implementation, "freeifaddrs_implementation"); libc = dlopen ("libc.so", RTLD_NOW); if (libc) { @@ -416,7 +416,7 @@ free_single_xamarin_ifaddrs (struct _monodroid_ifaddrs **ifap) static int open_netlink_session (netlink_session *session) { - abort_if_invalid_pointer_argument (session); + abort_if_invalid_pointer_argument (session, "session"); memset (session, 0, sizeof (*session)); session->sock_fd = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); @@ -488,9 +488,9 @@ send_netlink_dump_request (netlink_session *session, int type) static int append_ifaddr (struct _monodroid_ifaddrs *addr, struct _monodroid_ifaddrs **ifaddrs_head, struct _monodroid_ifaddrs **last_ifaddr) { - abort_if_invalid_pointer_argument (addr); - abort_if_invalid_pointer_argument (ifaddrs_head); - abort_if_invalid_pointer_argument (last_ifaddr); + abort_if_invalid_pointer_argument (addr, "addr"); + abort_if_invalid_pointer_argument (ifaddrs_head, "ifaddrs_head"); + abort_if_invalid_pointer_argument (last_ifaddr, "last_ifaddr"); if (!*ifaddrs_head) { *ifaddrs_head = *last_ifaddr = addr; @@ -524,9 +524,9 @@ parse_netlink_reply (netlink_session *session, struct _monodroid_ifaddrs **ifadd int ret = -1; unsigned char *response = NULL; - abort_if_invalid_pointer_argument (session); - abort_if_invalid_pointer_argument (ifaddrs_head); - abort_if_invalid_pointer_argument (last_ifaddr); + abort_if_invalid_pointer_argument (session, "session"); + abort_if_invalid_pointer_argument (ifaddrs_head, "ifaddrs_head"); + abort_if_invalid_pointer_argument (last_ifaddr, "last_ifaddr"); size_t buf_size = static_cast(getpagesize ()); log_debug (LOG_NETLINK, "receive buffer size == %d", buf_size); @@ -626,9 +626,9 @@ parse_netlink_reply (netlink_session *session, struct _monodroid_ifaddrs **ifadd static int fill_sa_address (struct sockaddr **sa, struct ifaddrmsg *net_address, void *rta_data, size_t rta_payload_length) { - abort_if_invalid_pointer_argument (sa); - abort_if_invalid_pointer_argument (net_address); - abort_if_invalid_pointer_argument (rta_data); + abort_if_invalid_pointer_argument (sa, "sa"); + abort_if_invalid_pointer_argument (net_address, "net_address"); + abort_if_invalid_pointer_argument (rta_data, "rta_data"); switch (net_address->ifa_family) { case AF_INET: { @@ -688,8 +688,8 @@ fill_sa_address (struct sockaddr **sa, struct ifaddrmsg *net_address, void *rta_ static int fill_ll_address (struct sockaddr_ll_extended **sa, struct ifinfomsg *net_interface, void *rta_data, size_t rta_payload_length) { - abort_if_invalid_pointer_argument (sa); - abort_if_invalid_pointer_argument (net_interface); + abort_if_invalid_pointer_argument (sa, "sa"); + abort_if_invalid_pointer_argument (net_interface, "net_interface"); /* Always allocate, do not free - caller may reuse the same variable */ *sa = reinterpret_cast(calloc (1, sizeof (**sa))); @@ -845,7 +845,7 @@ get_link_address (const struct nlmsghdr *message, struct _monodroid_ifaddrs **if struct sockaddr **sa; size_t payload_size; - abort_if_invalid_pointer_argument (message); + abort_if_invalid_pointer_argument (message, "message"); net_address = reinterpret_cast (NLMSG_DATA (message)); length = static_cast(IFA_PAYLOAD (message)); log_debug (LOG_NETLINK, " address data length: %u", length); @@ -995,7 +995,7 @@ get_link_info (const struct nlmsghdr *message) struct _monodroid_ifaddrs *ifa = NULL; struct sockaddr_ll_extended *sa = NULL; - abort_if_invalid_pointer_argument (message); + abort_if_invalid_pointer_argument (message, "message"); net_interface = reinterpret_cast (NLMSG_DATA (message)); length = static_cast(message->nlmsg_len - NLMSG_LENGTH (sizeof (*net_interface))); if (length <= 0) { diff --git a/src/native/runtime-base/android-system.cc b/src/native/runtime-base/android-system.cc index 025362628ae..44745a7f34f 100644 --- a/src/native/runtime-base/android-system.cc +++ b/src/native/runtime-base/android-system.cc @@ -323,7 +323,7 @@ AndroidSystem::load_dso (const char *path, unsigned int dl_flags, bool skip_exis void* AndroidSystem::load_dso_from_specified_dirs (const char **directories, size_t num_entries, const char *dso_name, unsigned int dl_flags) noexcept { - abort_if_invalid_pointer_argument (directories); + abort_if_invalid_pointer_argument (directories, "directories"); if (dso_name == nullptr) return nullptr; diff --git a/src/native/runtime-base/cpu-arch-detect.cc b/src/native/runtime-base/cpu-arch-detect.cc index d8bcb7dd5fc..7a7a47b0059 100644 --- a/src/native/runtime-base/cpu-arch-detect.cc +++ b/src/native/runtime-base/cpu-arch-detect.cc @@ -10,7 +10,7 @@ static inline constexpr size_t BUF_SIZE = 512uz; static int find_in_maps (const char *str) { - abort_if_invalid_pointer_argument (str); + abort_if_invalid_pointer_argument (str, "str"); FILE *maps = fopen ("/proc/self/maps", "r"); char *line; @@ -112,9 +112,9 @@ get_running_on_cpu (unsigned short *running_on_cpu) void _monodroid_detect_cpu_and_architecture (unsigned short *built_for_cpu, unsigned short *running_on_cpu, unsigned char *is64bit) { - abort_if_invalid_pointer_argument (built_for_cpu); - abort_if_invalid_pointer_argument (running_on_cpu); - abort_if_invalid_pointer_argument (is64bit); + abort_if_invalid_pointer_argument (built_for_cpu, "built_for_cpu"); + abort_if_invalid_pointer_argument (running_on_cpu, "running_on_cpu"); + abort_if_invalid_pointer_argument (is64bit, "is64bit"); *is64bit = is_64_bit (); get_built_for_cpu (built_for_cpu); diff --git a/src/native/runtime-base/jni-wrappers.hh b/src/native/runtime-base/jni-wrappers.hh index afe95e25b7b..e9dde0eb083 100644 --- a/src/native/runtime-base/jni-wrappers.hh +++ b/src/native/runtime-base/jni-wrappers.hh @@ -20,21 +20,21 @@ namespace xamarin::android : env (_env), jstr (nullptr) { - abort_if_invalid_pointer_argument (_env); + abort_if_invalid_pointer_argument (_env, "_env"); } explicit jstring_wrapper (JNIEnv *_env, const jobject jo) noexcept : env (_env), jstr (reinterpret_cast (jo)) { - abort_if_invalid_pointer_argument (_env); + abort_if_invalid_pointer_argument (_env, "_env"); } explicit jstring_wrapper (JNIEnv *_env, const jstring js) noexcept : env (_env), jstr (js) { - abort_if_invalid_pointer_argument (_env); + abort_if_invalid_pointer_argument (_env, "_env"); } jstring_wrapper (const jstring_wrapper&) = delete; @@ -137,7 +137,7 @@ namespace xamarin::android : env (_env), arr (_arr) { - abort_if_invalid_pointer_argument (_env); + abort_if_invalid_pointer_argument (_env, "_env"); if (_arr != nullptr) { len = static_cast(_env->GetArrayLength (_arr)); if (len > sizeof (static_wrappers) / sizeof (jstring_wrapper)) diff --git a/src/native/shared/cpp-util.hh b/src/native/shared/cpp-util.hh index 160fa844e36..8e83c409e85 100644 --- a/src/native/shared/cpp-util.hh +++ b/src/native/shared/cpp-util.hh @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -14,6 +15,7 @@ #include "helpers.hh" + static inline void do_abort_unless (const char* fmt, ...) { @@ -27,13 +29,51 @@ do_abort_unless (const char* fmt, ...) xamarin::android::Helpers::abort_application (n == -1 ? "Unable to allocate memory for abort message" : message); } -#define abort_unless(_condition_, _fmt_, ...) \ - if (!(_condition_)) [[unlikely]] { \ - do_abort_unless ("%s:%d (%s): " _fmt_, __FILE__, __LINE__, __FUNCTION__, ## __VA_ARGS__); \ +// #define abort_unless(_condition_, _fmt_, ...) \ +// if (!(_condition_)) [[unlikely]] { \ +// do_abort_unless ("%s:%d (%s): " _fmt_, __FILE__, __LINE__, __FUNCTION__, ## __VA_ARGS__); \ +// } + +template F> +[[gnu::always_inline, gnu::flatten]] +static inline void +abort_unless (bool condition, F&& get_message, std::source_location sloc = std::source_location::current ()) noexcept +{ + if (condition) [[likely]] { + return; } -#define abort_if_invalid_pointer_argument(_ptr_) abort_unless ((_ptr_) != nullptr, "Parameter '%s' must be a valid pointer", #_ptr_) -#define abort_if_negative_integer_argument(_arg_) abort_unless ((_arg_) > 0, "Parameter '%s' must be larger than 0", #_arg_) +// static_assert (std::is_same, char*>::value, "get_message must return 'char*'"); + xamarin::android::Helpers::abort_application (std::invoke (get_message), true /* log_location */, sloc); +} + +[[gnu::always_inline, gnu::flatten]] +static inline void +abort_unless (bool condition, const char *message, std::source_location sloc = std::source_location::current ()) noexcept +{ + if (condition) [[likely]] { + return; + } + xamarin::android::Helpers::abort_application (message, true /* log_location */, sloc); +} + +// #define abort_if_invalid_pointer_argument(_ptr_) abort_unless ((_ptr_) != nullptr, "Parameter '%s' must be a valid pointer", #_ptr_) +// #define abort_if_negative_integer_argument(_arg_) abort_unless ((_arg_) > 0, "Parameter '%s' must be larger than 0", #_arg_) + +template +[[gnu::always_inline, gnu::flatten]] +static inline void +abort_if_invalid_pointer_argument (T *ptr, const char *ptr_name, std::source_location sloc = std::source_location::current ()) noexcept +{ + abort_unless (ptr != nullptr, "Parameter '%s' must be a valid pointer", sloc); +} + +[[gnu::always_inline, gnu::flatten]] +static inline void +abort_if_negative_integer_argument (int arg, const char *arg_name, std::source_location sloc = std::source_location::current ()) noexcept +{ + abort_unless (arg > 0, "Parameter '%s' must be a valid pointer", sloc); +} // Helper to use in "printf debugging". Normally not used in code anywhere. No code should be shipped with any // of the calls present. From 5cfaf381a03c419bb2468bb128136166fa97b56a Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Mon, 4 Nov 2024 20:55:16 +0100 Subject: [PATCH 02/12] More consistent use of std::string_view + remove unused code --- src/native/monodroid/embedded-assemblies.hh | 17 +++-- src/native/monodroid/monodroid-glue.cc | 7 +- src/native/monodroid/osbridge.cc | 6 +- src/native/runtime-base/shared-constants.hh | 5 +- src/native/runtime-base/util.hh | 23 ------- src/native/shared/cpp-util.hh | 72 +++++++-------------- 6 files changed, 47 insertions(+), 83 deletions(-) diff --git a/src/native/monodroid/embedded-assemblies.hh b/src/native/monodroid/embedded-assemblies.hh index cfaaf4b9e40..6aad3fd223b 100644 --- a/src/native/monodroid/embedded-assemblies.hh +++ b/src/native/monodroid/embedded-assemblies.hh @@ -88,23 +88,28 @@ namespace xamarin::android::internal { static constexpr std::string_view zip_path_separator { "/" }; static constexpr std::string_view apk_lib_dir_name { "lib" }; + static constexpr size_t assemblies_prefix_size = calc_size(apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator); - static constexpr auto assemblies_prefix = concat_string_views (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator); + static constexpr auto assemblies_prefix_array = concat_string_views (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator); + static constexpr std::string_view assemblies_prefix { assemblies_prefix_array }; // We have two records for each assembly, for names with and without the extension static constexpr uint32_t assembly_store_index_entries_per_assembly = 2; static constexpr uint32_t number_of_assembly_store_files = 1; static constexpr std::string_view dso_suffix { ".so" }; - static constexpr auto apk_lib_prefix = assemblies_prefix; // concat_const (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator); + static constexpr std::string_view apk_lib_prefix = assemblies_prefix; // concat_const (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator); static constexpr std::string_view assembly_store_prefix { "libassemblies." }; static constexpr std::string_view assembly_store_extension { ".blob" }; static constexpr size_t assembly_store_file_name_size = calc_size (assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); - static constexpr auto assembly_store_file_name = concat_string_views (assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); + static constexpr auto assembly_store_file_name_array = concat_string_views (assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); + static constexpr std::string_view assembly_store_file_name { assembly_store_file_name_array }; static constexpr size_t assembly_store_file_path_size = calc_size(apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator, assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); - static constexpr auto assembly_store_file_path = concat_string_views (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator, assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); + static constexpr auto assembly_store_file_path_array = concat_string_views (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator, assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); + static constexpr std::string_view assembly_store_file_path { assembly_store_file_path_array }; + static constexpr size_t dso_size_overhead = ArchiveDSOStubConfig::PayloadSectionOffset + (ArchiveDSOStubConfig::SectionHeaderEntryCount * ArchiveDSOStubConfig::SectionHeaderEntrySize); public: @@ -162,8 +167,8 @@ namespace xamarin::android::internal { abort_unless ( runtime_config_data_size < std::numeric_limits::max (), [] { - return Util::monodroid_strdup_printf ("Runtime config binary blob size exceeds %u bytes", - std::numeric_limits::max ()); + return detail::_format_message ("Runtime config binary blob size exceeds %u bytes", + std::numeric_limits::max ()); } ); size = static_cast(runtime_config_data_size); diff --git a/src/native/monodroid/monodroid-glue.cc b/src/native/monodroid/monodroid-glue.cc index a4d92ba1461..09a4dba28f2 100644 --- a/src/native/monodroid/monodroid-glue.cc +++ b/src/native/monodroid/monodroid-glue.cc @@ -915,7 +915,10 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec abort_unless ( registerType != nullptr, [&error] { - return Util::monodroid_strdup_printf("INTERNAL ERROR: Unable to find Android.Runtime.JNIEnvInit.RegisterJniNatives! %s", mono_error_get_message (&error)); + return detail::_format_message ( + "INTERNAL ERROR: Unable to find Android.Runtime.JNIEnvInit.RegisterJniNatives! %s", + mono_error_get_message (&error) + ); } ); @@ -943,7 +946,7 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec abort_unless ( initialize != nullptr, [&error] { - return Util::monodroid_strdup_printf ( + return detail::_format_message ( "Failed to obtain unmanaged-callers-only pointer to the Android.Runtime.JNIEnvInit.Initialize method. %s", mono_error_get_message (&error) ); diff --git a/src/native/monodroid/osbridge.cc b/src/native/monodroid/osbridge.cc index cc900a30906..d2725d278e2 100644 --- a/src/native/monodroid/osbridge.cc +++ b/src/native/monodroid/osbridge.cc @@ -865,9 +865,7 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri if (j > 0) { abort_unless ( sccs [i]->is_alive, - [&i] { - return Util::monodroid_strdup_printf ("Bridge SCC at index %d must be alive", i); - } + [&i] { return detail::_format_message ("Bridge SCC at index %d must be alive", i); } ); } sccs [i]->is_alive = 1; @@ -893,7 +891,7 @@ OSBridge::gc_cleanup_after_java_collection (JNIEnv *env, int num_sccs, MonoGCBri } else { abort_unless ( !sccs [i]->is_alive, - [&i] { return Util::monodroid_strdup_printf ("Bridge SCC at index %d must NOT be alive", i); } + [&i] { return detail::_format_message ("Bridge SCC at index %d must NOT be alive", i); } ); } } diff --git a/src/native/runtime-base/shared-constants.hh b/src/native/runtime-base/shared-constants.hh index 001a53651e9..a3355963b59 100644 --- a/src/native/runtime-base/shared-constants.hh +++ b/src/native/runtime-base/shared-constants.hh @@ -40,10 +40,13 @@ namespace xamarin::android::internal static constexpr std::string_view DLL_EXTENSION { ".dll" }; static constexpr std::string_view PDB_EXTENSION { ".pdb" }; + private: static constexpr std::string_view RUNTIME_CONFIG_BLOB_BASE_NAME { "libarc.bin" }; static constexpr size_t runtime_config_blob_name_size = calc_size (RUNTIME_CONFIG_BLOB_BASE_NAME, MANGLED_ASSEMBLY_NAME_EXT); - static constexpr auto RUNTIME_CONFIG_BLOB_NAME = concat_string_views (RUNTIME_CONFIG_BLOB_BASE_NAME, MANGLED_ASSEMBLY_NAME_EXT); + static constexpr auto RUNTIME_CONFIG_BLOB_NAME_ARRAY = concat_string_views (RUNTIME_CONFIG_BLOB_BASE_NAME, MANGLED_ASSEMBLY_NAME_EXT); + public: + static constexpr std::string_view RUNTIME_CONFIG_BLOB_NAME { RUNTIME_CONFIG_BLOB_NAME_ARRAY }; static constexpr std::string_view MONO_SGEN_SO { "libmonosgen-2.0.so" }; static constexpr std::string_view MONO_SGEN_ARCH_SO { "libmonosgen-" __BITNESS__ "-2.0.so" }; static constexpr std::string_view OVERRIDE_DIRECTORY_NAME { ".__override__" }; diff --git a/src/native/runtime-base/util.hh b/src/native/runtime-base/util.hh index 8dd7f432664..97db495dbea 100644 --- a/src/native/runtime-base/util.hh +++ b/src/native/runtime-base/util.hh @@ -47,9 +47,6 @@ namespace xamarin::android { class Util { - static constexpr std::array hex_chars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - static constexpr uint32_t ms_in_nsec = 1000000ULL; - public: static void initialize () noexcept; @@ -197,13 +194,6 @@ namespace xamarin::android return p != nullptr && p [N - 1] == '\0'; } - template - static bool ends_with (const char *str, helper_char_array const& end) noexcept - { - char *p = const_cast (strstr (str, end.data ())); - return p != nullptr && p [N - 1] == '\0'; - } - template static bool ends_with (internal::string_base const& str, const char (&end)[N]) noexcept { @@ -230,19 +220,6 @@ namespace xamarin::android return memcmp (str.get () + len - end_length, end.data (), end_length) == 0; } - template - static bool ends_with (internal::string_base const& str, helper_char_array const& end) noexcept - { - constexpr size_t end_length = N - 1uz; - - size_t len = str.length (); - if (len < end_length) [[unlikely]] { - return false; - } - - return memcmp (str.get () + len - end_length, end.data (), end_length) == 0; - } - template static const TChar* find_last (internal::string_base const& str, const char ch) noexcept { diff --git a/src/native/shared/cpp-util.hh b/src/native/shared/cpp-util.hh index 8e83c409e85..f893d6614e3 100644 --- a/src/native/shared/cpp-util.hh +++ b/src/native/shared/cpp-util.hh @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -15,35 +16,33 @@ #include "helpers.hh" +namespace xamarin::android::detail { + [[gnu::always_inline, gnu::flatten]] + static inline const char* + _format_message (const char *format, ...) noexcept + { + va_list ap; + va_start (ap, format); -static inline void -do_abort_unless (const char* fmt, ...) -{ - va_list ap; - - va_start (ap, fmt); - char *message = nullptr; - int n = vasprintf (&message, fmt, ap); - va_end (ap); + char *message; + int ret = vasprintf (&message, format, ap); - xamarin::android::Helpers::abort_application (n == -1 ? "Unable to allocate memory for abort message" : message); + va_end (ap); + return ret == -1 ? "Out of memory" : message; + } } -// #define abort_unless(_condition_, _fmt_, ...) \ -// if (!(_condition_)) [[unlikely]] { \ -// do_abort_unless ("%s:%d (%s): " _fmt_, __FILE__, __LINE__, __FUNCTION__, ## __VA_ARGS__); \ -// } - template F> [[gnu::always_inline, gnu::flatten]] static inline void abort_unless (bool condition, F&& get_message, std::source_location sloc = std::source_location::current ()) noexcept { + static_assert (std::is_same::type, const char*>::value, "get_message must return 'const char*'"); + if (condition) [[likely]] { return; } -// static_assert (std::is_same, char*>::value, "get_message must return 'char*'"); xamarin::android::Helpers::abort_application (std::invoke (get_message), true /* log_location */, sloc); } @@ -57,22 +56,27 @@ abort_unless (bool condition, const char *message, std::source_location sloc = s xamarin::android::Helpers::abort_application (message, true /* log_location */, sloc); } -// #define abort_if_invalid_pointer_argument(_ptr_) abort_unless ((_ptr_) != nullptr, "Parameter '%s' must be a valid pointer", #_ptr_) -// #define abort_if_negative_integer_argument(_arg_) abort_unless ((_arg_) > 0, "Parameter '%s' must be larger than 0", #_arg_) - template [[gnu::always_inline, gnu::flatten]] static inline void abort_if_invalid_pointer_argument (T *ptr, const char *ptr_name, std::source_location sloc = std::source_location::current ()) noexcept { - abort_unless (ptr != nullptr, "Parameter '%s' must be a valid pointer", sloc); + abort_unless ( + ptr != nullptr, + [&ptr_name] { return xamarin::android::detail::_format_message ("Parameter '%s' must be a valid pointer", ptr_name); }, + sloc + ); } [[gnu::always_inline, gnu::flatten]] static inline void abort_if_negative_integer_argument (int arg, const char *arg_name, std::source_location sloc = std::source_location::current ()) noexcept { - abort_unless (arg > 0, "Parameter '%s' must be a valid pointer", sloc); + abort_unless ( + arg > 0, + [&arg_name] { return xamarin::android::detail::_format_message ("Parameter '%s' must be a valid pointer", arg_name); }, + sloc + ); } // Helper to use in "printf debugging". Normally not used in code anywhere. No code should be shipped with any @@ -106,32 +110,6 @@ namespace xamarin::android template using c_unique_ptr = std::unique_ptr>; - template - struct helper_char_array final - { - constexpr char* data () noexcept - { - return _elems; - } - - constexpr const char* data () const noexcept - { - return _elems; - } - - constexpr char const& operator[] (size_t n) const noexcept - { - return _elems[n]; - } - - constexpr char& operator[] (size_t n) noexcept - { - return _elems[n]; - } - - char _elems[Size]{}; - }; - template using char_array = std::array; From 96b6e4270c48655b89b85464a48b982e955bef4f Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 7 Nov 2024 14:13:30 +0100 Subject: [PATCH 03/12] Making EmbeddedAssemblies a static type In process to remove object instances for a slightly faster startup --- .../monodroid/embedded-assemblies-zip.cc | 20 +-- src/native/monodroid/embedded-assemblies.cc | 14 +- src/native/monodroid/embedded-assemblies.hh | 140 +++++++++--------- src/native/monodroid/monodroid-glue.cc | 2 +- 4 files changed, 87 insertions(+), 89 deletions(-) diff --git a/src/native/monodroid/embedded-assemblies-zip.cc b/src/native/monodroid/embedded-assemblies-zip.cc index 3f91b71dc9a..82a56859d88 100644 --- a/src/native/monodroid/embedded-assemblies-zip.cc +++ b/src/native/monodroid/embedded-assemblies-zip.cc @@ -298,7 +298,7 @@ EmbeddedAssemblies::zip_load_assembly_store_entries (std::vector const& } void -EmbeddedAssemblies::zip_load_entries (int fd, const char *apk_name, [[maybe_unused]] monodroid_should_register should_register) +EmbeddedAssemblies::zip_load_entries (int fd, const char *apk_name, [[maybe_unused]] monodroid_should_register should_register) noexcept { uint32_t cd_offset; uint32_t cd_size; @@ -412,7 +412,7 @@ EmbeddedAssemblies::set_debug_entry_data (XamarinAndroidBundledAssembly &entry, } bool -EmbeddedAssemblies::zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries) +EmbeddedAssemblies::zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries) noexcept { // The simplest case - no file comment off_t ret = ::lseek (fd, -ZIP_EOCD_LEN, SEEK_END); @@ -478,7 +478,7 @@ EmbeddedAssemblies::zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_ } bool -EmbeddedAssemblies::zip_adjust_data_offset (int fd, ZipEntryLoadState &state) +EmbeddedAssemblies::zip_adjust_data_offset (int fd, ZipEntryLoadState &state) noexcept { static constexpr size_t LH_FILE_NAME_LENGTH_OFFSET = 26uz; static constexpr size_t LH_EXTRA_LENGTH_OFFSET = 28uz; @@ -530,7 +530,7 @@ EmbeddedAssemblies::zip_adjust_data_offset (int fd, ZipEntryLoadState &state) template bool -EmbeddedAssemblies::zip_extract_cd_info (std::array const& buf, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries) +EmbeddedAssemblies::zip_extract_cd_info (std::array const& buf, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries) noexcept { constexpr size_t EOCD_TOTAL_ENTRIES_OFFSET = 10uz; constexpr size_t EOCD_CD_SIZE_OFFSET = 12uz; @@ -558,7 +558,7 @@ EmbeddedAssemblies::zip_extract_cd_info (std::array const& buf template force_inline bool -EmbeddedAssemblies::zip_ensure_valid_params (T const& buf, size_t index, size_t to_read) const noexcept +EmbeddedAssemblies::zip_ensure_valid_params (T const& buf, size_t index, size_t to_read) noexcept { if (index + to_read > buf.size ()) { log_error (LOG_ASSEMBLY, "Buffer too short to read %u bytes of data", to_read); @@ -570,7 +570,7 @@ EmbeddedAssemblies::zip_ensure_valid_params (T const& buf, size_t index, size_t template bool -EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, uint16_t& dst) const noexcept +EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, uint16_t& dst) noexcept { if (!zip_ensure_valid_params (src, source_index, sizeof (dst))) { return false; @@ -583,7 +583,7 @@ EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, uint16_t& template bool -EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, uint32_t& dst) const noexcept +EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, uint32_t& dst) noexcept { if (!zip_ensure_valid_params (src, source_index, sizeof (dst))) { return false; @@ -600,7 +600,7 @@ EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, uint32_t& template bool -EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, std::array& dst_sig) const noexcept +EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, std::array& dst_sig) noexcept { if (!zip_ensure_valid_params (src, source_index, dst_sig.size ())) { return false; @@ -612,7 +612,7 @@ EmbeddedAssemblies::zip_read_field (T const& src, size_t source_index, std::arra template bool -EmbeddedAssemblies::zip_read_field (T const& buf, size_t index, size_t count, dynamic_local_string& characters) const noexcept +EmbeddedAssemblies::zip_read_field (T const& buf, size_t index, size_t count, dynamic_local_string& characters) noexcept { if (!zip_ensure_valid_params (buf, index, count)) { return false; @@ -623,7 +623,7 @@ EmbeddedAssemblies::zip_read_field (T const& buf, size_t index, size_t count, dy } bool -EmbeddedAssemblies::zip_read_entry_info (std::vector const& buf, dynamic_local_string& file_name, ZipEntryLoadState &state) +EmbeddedAssemblies::zip_read_entry_info (std::vector const& buf, dynamic_local_string& file_name, ZipEntryLoadState &state) noexcept { constexpr size_t CD_COMPRESSION_METHOD_OFFSET = 10uz; constexpr size_t CD_UNCOMPRESSED_SIZE_OFFSET = 24uz; diff --git a/src/native/monodroid/embedded-assemblies.cc b/src/native/monodroid/embedded-assemblies.cc index 6a20df0bc59..f5855dfd832 100644 --- a/src/native/monodroid/embedded-assemblies.cc +++ b/src/native/monodroid/embedded-assemblies.cc @@ -65,7 +65,7 @@ class MonoGuidString final char *guid = nullptr; }; -void EmbeddedAssemblies::set_assemblies_prefix (const char *prefix) +void EmbeddedAssemblies::set_assemblies_prefix (const char *prefix) noexcept { if (assemblies_prefix_override != nullptr) delete[] assemblies_prefix_override; @@ -912,7 +912,7 @@ EmbeddedAssemblies::md_mmap_apk_file (int fd, uint32_t offset, size_t size, cons } void -EmbeddedAssemblies::gather_bundled_assemblies_from_apk (const char* apk, monodroid_should_register should_register) +EmbeddedAssemblies::gather_bundled_assemblies_from_apk (const char* apk, monodroid_should_register should_register) noexcept { int fd; @@ -1284,12 +1284,10 @@ EmbeddedAssemblies::register_from_filesystem (const char *lib_dir_path,bool look } auto register_fn = - application_config.have_assembly_store ? std::mem_fn (&EmbeddedAssemblies::maybe_register_blob_from_filesystem) : + application_config.have_assembly_store ? &EmbeddedAssemblies::maybe_register_blob_from_filesystem : (look_for_mangled_names ? - std::mem_fn (&EmbeddedAssemblies::maybe_register_assembly_from_filesystem) : - std::mem_fn (&EmbeddedAssemblies::maybe_register_assembly_from_filesystem - ) - ); + &EmbeddedAssemblies::maybe_register_assembly_from_filesystem : + &EmbeddedAssemblies::maybe_register_assembly_from_filesystem); size_t assembly_count = 0uz; do { @@ -1334,7 +1332,7 @@ EmbeddedAssemblies::register_from_filesystem (const char *lib_dir_path,bool look } // We get `true` if it's time to terminate - if (register_fn (this, should_register, assembly_count, cur, state)) { + if (register_fn (should_register, assembly_count, cur, state)) { break; } } while (true); diff --git a/src/native/monodroid/embedded-assemblies.hh b/src/native/monodroid/embedded-assemblies.hh index 6aad3fd223b..1ac42b9d1de 100644 --- a/src/native/monodroid/embedded-assemblies.hh +++ b/src/native/monodroid/embedded-assemblies.hh @@ -130,14 +130,14 @@ namespace xamarin::android::internal { /* returns current number of *all* assemblies found from all invocations */ template - size_t register_from_apk (const char *apk_file) noexcept + static size_t register_from_apk (const char *apk_file) noexcept { static_assert (should_register_fn != nullptr, "should_register_fn is a required template parameter"); return register_from_apk (apk_file, should_register_fn); } template - size_t register_from_filesystem () noexcept + static size_t register_from_filesystem () noexcept { static_assert (should_register_fn != nullptr, "should_register_fn is a required template parameter"); return register_from_filesystem (should_register_fn); @@ -148,19 +148,19 @@ namespace xamarin::android::internal { return assemblies_prefix; } - bool get_register_debug_symbols () const + static bool get_register_debug_symbols () noexcept { return register_debug_symbols; } - void set_register_debug_symbols (bool value) + static void set_register_debug_symbols (bool value) noexcept { register_debug_symbols = value; } - void set_assemblies_prefix (const char *prefix); + static void set_assemblies_prefix (const char *prefix) noexcept; - void get_runtime_config_blob (const char *& area, uint32_t& size) const + static void get_runtime_config_blob (const char *& area, uint32_t& size) noexcept { area = static_cast(runtime_config_data); @@ -174,7 +174,7 @@ namespace xamarin::android::internal { size = static_cast(runtime_config_data_size); } - void unmap_runtime_config_blob () + static void unmap_runtime_config_blob () noexcept { if (runtime_config_blob_mmap.area == nullptr) { return; @@ -185,17 +185,17 @@ namespace xamarin::android::internal { runtime_config_blob_mmap.size = 0; } - bool have_runtime_config_blob () const noexcept + static bool have_runtime_config_blob () noexcept { return application_config.have_runtime_config_blob && runtime_config_blob_mmap.area != nullptr; } - bool keep_scanning () const noexcept + static bool keep_scanning () noexcept { return need_to_scan_more_apks; } - void ensure_valid_assembly_stores () const noexcept + static void ensure_valid_assembly_stores () noexcept { if (!application_config.have_assembly_store) { return; @@ -207,32 +207,32 @@ namespace xamarin::android::internal { private: STATIC_IN_ANDROID_RELEASE const char* typemap_managed_to_java (MonoType *type, MonoClass *klass, const uint8_t *mvid) noexcept; STATIC_IN_ANDROID_RELEASE MonoReflectionType* typemap_java_to_managed (hash_t hash, const MonoString *java_type_name) noexcept; - size_t register_from_apk (const char *apk_file, monodroid_should_register should_register) noexcept; - size_t register_from_filesystem (monodroid_should_register should_register) noexcept; - size_t register_from_filesystem (const char *dir, bool look_for_mangled_names, monodroid_should_register should_register) noexcept; + static size_t register_from_apk (const char *apk_file, monodroid_should_register should_register) noexcept; + static size_t register_from_filesystem (monodroid_should_register should_register) noexcept; + static size_t register_from_filesystem (const char *dir, bool look_for_mangled_names, monodroid_should_register should_register) noexcept; template - bool maybe_register_assembly_from_filesystem (monodroid_should_register should_register, size_t& assembly_count, const dirent* dir_entry, ZipEntryLoadState& state) noexcept; - bool maybe_register_blob_from_filesystem (monodroid_should_register should_register, size_t& assembly_count, const dirent* dir_entry, ZipEntryLoadState& state) noexcept; + static bool maybe_register_assembly_from_filesystem (monodroid_should_register should_register, size_t& assembly_count, const dirent* dir_entry, ZipEntryLoadState& state) noexcept; + static bool maybe_register_blob_from_filesystem (monodroid_should_register should_register, size_t& assembly_count, const dirent* dir_entry, ZipEntryLoadState& state) noexcept; - void gather_bundled_assemblies_from_apk (const char* apk, monodroid_should_register should_register); + static void gather_bundled_assemblies_from_apk (const char* apk, monodroid_should_register should_register) noexcept; template - MonoAssembly* individual_assemblies_open_from_bundles (dynamic_local_string& name, TLoaderData loader_data, bool ref_only) noexcept; + static MonoAssembly* individual_assemblies_open_from_bundles (dynamic_local_string& name, TLoaderData loader_data, bool ref_only) noexcept; template - MonoAssembly* assembly_store_open_from_bundles (dynamic_local_string& name, TLoaderData loader_data, bool ref_only) noexcept; + static MonoAssembly* assembly_store_open_from_bundles (dynamic_local_string& name, TLoaderData loader_data, bool ref_only) noexcept; template - MonoAssembly* open_from_bundles (MonoAssemblyName* aname, TLoaderData loader_data, MonoError *error, bool ref_only) noexcept; + static MonoAssembly* open_from_bundles (MonoAssemblyName* aname, TLoaderData loader_data, MonoError *error, bool ref_only) noexcept; template - void map_runtime_file (XamarinAndroidBundledAssembly& file) noexcept; - void map_assembly (XamarinAndroidBundledAssembly& file) noexcept; - void map_debug_data (XamarinAndroidBundledAssembly& file) noexcept; + static void map_runtime_file (XamarinAndroidBundledAssembly& file) noexcept; + static void map_assembly (XamarinAndroidBundledAssembly& file) noexcept; + static void map_debug_data (XamarinAndroidBundledAssembly& file) noexcept; template - MonoAssembly* load_bundled_assembly ( + static MonoAssembly* load_bundled_assembly ( XamarinAndroidBundledAssembly& assembly, dynamic_local_string const& name, dynamic_local_string const& abi_name, @@ -254,37 +254,37 @@ namespace xamarin::android::internal { static MonoAssembly* open_from_bundles_full (MonoAssemblyName *aname, char **assemblies_path, void *user_data); static MonoAssembly* open_from_bundles (MonoAssemblyLoadContextGCHandle alc_gchandle, MonoAssemblyName *aname, char **assemblies_path, void *user_data, MonoError *error); - void set_assembly_data_and_size (uint8_t* source_assembly_data, uint32_t source_assembly_data_size, uint8_t*& dest_assembly_data, uint32_t& dest_assembly_data_size) noexcept; - void get_assembly_data (uint8_t *data, uint32_t data_size, const char *name, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept; - void get_assembly_data (XamarinAndroidBundledAssembly const& e, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept; - void get_assembly_data (AssemblyStoreSingleAssemblyRuntimeData const& e, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept; + static void set_assembly_data_and_size (uint8_t* source_assembly_data, uint32_t source_assembly_data_size, uint8_t*& dest_assembly_data, uint32_t& dest_assembly_data_size) noexcept; + static void get_assembly_data (uint8_t *data, uint32_t data_size, const char *name, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept; + static void get_assembly_data (XamarinAndroidBundledAssembly const& e, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept; + static void get_assembly_data (AssemblyStoreSingleAssemblyRuntimeData const& e, uint8_t*& assembly_data, uint32_t& assembly_data_size) noexcept; - void zip_load_entries (int fd, const char *apk_name, monodroid_should_register should_register); - void zip_load_individual_assembly_entries (std::vector const& buf, uint32_t num_entries, monodroid_should_register should_register, ZipEntryLoadState &state) noexcept; - void zip_load_assembly_store_entries (std::vector const& buf, uint32_t num_entries, ZipEntryLoadState &state) noexcept; - bool zip_load_entry_common (size_t entry_index, std::vector const& buf, dynamic_local_string &entry_name, ZipEntryLoadState &state) noexcept; - bool zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries); - bool zip_adjust_data_offset (int fd, ZipEntryLoadState &state); + static void zip_load_entries (int fd, const char *apk_name, monodroid_should_register should_register) noexcept; + static void zip_load_individual_assembly_entries (std::vector const& buf, uint32_t num_entries, monodroid_should_register should_register, ZipEntryLoadState &state) noexcept; + static void zip_load_assembly_store_entries (std::vector const& buf, uint32_t num_entries, ZipEntryLoadState &state) noexcept; + static bool zip_load_entry_common (size_t entry_index, std::vector const& buf, dynamic_local_string &entry_name, ZipEntryLoadState &state) noexcept; + static bool zip_read_cd_info (int fd, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries) noexcept; + static bool zip_adjust_data_offset (int fd, ZipEntryLoadState &state) noexcept; template - bool zip_extract_cd_info (std::array const& buf, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries); + static bool zip_extract_cd_info (std::array const& buf, uint32_t& cd_offset, uint32_t& cd_size, uint16_t& cd_entries) noexcept; template - bool zip_ensure_valid_params (T const& buf, size_t index, size_t to_read) const noexcept; + static bool zip_ensure_valid_params (T const& buf, size_t index, size_t to_read) noexcept; template - bool zip_read_field (T const& src, size_t source_index, uint16_t& dst) const noexcept; + static bool zip_read_field (T const& src, size_t source_index, uint16_t& dst) noexcept; template - bool zip_read_field (T const& src, size_t source_index, uint32_t& dst) const noexcept; + static bool zip_read_field (T const& src, size_t source_index, uint32_t& dst) noexcept; template - bool zip_read_field (T const& src, size_t source_index, std::array& dst_sig) const noexcept; + static bool zip_read_field (T const& src, size_t source_index, std::array& dst_sig) noexcept; template - bool zip_read_field (T const& buf, size_t index, size_t count, dynamic_local_string& characters) const noexcept; + static bool zip_read_field (T const& buf, size_t index, size_t count, dynamic_local_string& characters) noexcept; - bool zip_read_entry_info (std::vector const& buf, dynamic_local_string& file_name, ZipEntryLoadState &state); + static bool zip_read_entry_info (std::vector const& buf, dynamic_local_string& file_name, ZipEntryLoadState &state) noexcept; [[gnu::always_inline]] static std::tuple get_wrapper_dso_payload_pointer_and_size (md_mmap_info const& map_info, const char *file_name) noexcept @@ -318,7 +318,7 @@ namespace xamarin::android::internal { } [[gnu::always_inline]] - void store_mapped_runtime_config_data (md_mmap_info const& map_info, const char *file_name) noexcept + static void store_mapped_runtime_config_data (md_mmap_info const& map_info, const char *file_name) noexcept { auto [payload_start, payload_size] = get_wrapper_dso_payload_pointer_and_size (map_info, file_name); log_debug (LOG_ASSEMBLY, "Runtime config: payload pointer %p ; size %zu", payload_start, payload_size); @@ -327,7 +327,7 @@ namespace xamarin::android::internal { runtime_config_blob_found = true; } - std::tuple get_assemblies_prefix_and_length () const noexcept + static std::tuple get_assemblies_prefix_and_length () noexcept { if (assemblies_prefix_override != nullptr) { return { assemblies_prefix_override, static_cast(strlen (assemblies_prefix_override)) }; @@ -340,7 +340,7 @@ namespace xamarin::android::internal { return {assemblies_prefix.data (), assemblies_prefix.size () - 1}; } - bool all_required_zip_entries_found () const noexcept + static bool all_required_zip_entries_found () noexcept { return number_of_mapped_assembly_stores == number_of_assembly_store_files && number_of_zip_dso_entries >= application_config.number_of_shared_libraries @@ -362,21 +362,21 @@ namespace xamarin::android::internal { static const TypeMapModuleEntry* binary_search (uint32_t key, const TypeMapModuleEntry *arr, uint32_t n) noexcept; #endif template - void set_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string const& entry_name) noexcept; - void set_assembly_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string const& entry_name) noexcept; - void set_debug_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string const& entry_name) noexcept; - void map_assembly_store (dynamic_local_string const& entry_name, ZipEntryLoadState &state) noexcept; - const AssemblyStoreIndexEntry* find_assembly_store_entry (hash_t hash, const AssemblyStoreIndexEntry *entries, size_t entry_count) noexcept; - void store_individual_assembly_data (dynamic_local_string const& entry_name, ZipEntryLoadState const& state, monodroid_should_register should_register) noexcept; - - constexpr size_t get_mangled_name_max_size_overhead () + static void set_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string const& entry_name) noexcept; + static void set_assembly_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string const& entry_name) noexcept; + static void set_debug_entry_data (XamarinAndroidBundledAssembly &entry, ZipEntryLoadState const& state, dynamic_local_string const& entry_name) noexcept; + static void map_assembly_store (dynamic_local_string const& entry_name, ZipEntryLoadState &state) noexcept; + static const AssemblyStoreIndexEntry* find_assembly_store_entry (hash_t hash, const AssemblyStoreIndexEntry *entries, size_t entry_count) noexcept; + static void store_individual_assembly_data (dynamic_local_string const& entry_name, ZipEntryLoadState const& state, monodroid_should_register should_register) noexcept; + + constexpr static size_t get_mangled_name_max_size_overhead () { return SharedConstants::MANGLED_ASSEMBLY_NAME_EXT.size() + std::max (SharedConstants::MANGLED_ASSEMBLY_REGULAR_ASSEMBLY_MARKER.size(), SharedConstants::MANGLED_ASSEMBLY_SATELLITE_ASSEMBLY_MARKER.size()) + 1; // For the extra `-` char in the culture portion of satellite assembly's name } - void configure_state_for_individual_assembly_load (ZipEntryLoadState& state) noexcept + static void configure_state_for_individual_assembly_load (ZipEntryLoadState& state) noexcept { state.bundled_assemblies_slow_path = bundled_assembly_index >= application_config.number_of_assemblies_in_apk; state.max_assembly_name_size = application_config.bundled_assembly_name_width - 1; @@ -430,13 +430,13 @@ namespace xamarin::android::internal { static inline constexpr bool UnmangleSatelliteAssembly = true; static inline constexpr bool UnmangleRegularAssembly = false; - std::vector *bundled_debug_data = nullptr; - std::vector *extra_bundled_assemblies = nullptr; + static inline std::vector *bundled_debug_data = nullptr; + static inline std::vector *extra_bundled_assemblies = nullptr; - bool register_debug_symbols; - bool have_and_want_debug_symbols; - size_t bundled_assembly_index = 0uz; - size_t number_of_found_assemblies = 0uz; + static inline bool register_debug_symbols; + static inline bool have_and_want_debug_symbols; + static inline size_t bundled_assembly_index = 0uz; + static inline size_t number_of_found_assemblies = 0uz; #if defined (DEBUG) TypeMappingInfo *java_to_managed_maps; @@ -444,18 +444,18 @@ namespace xamarin::android::internal { TypeMap *type_maps; size_t type_map_count; #endif // DEBUG - const char *assemblies_prefix_override = nullptr; - - md_mmap_info runtime_config_blob_mmap{}; - void *runtime_config_data = nullptr; - size_t runtime_config_data_size = 0uz; - bool runtime_config_blob_found = false; - uint32_t number_of_mapped_assembly_stores = 0u; - uint32_t number_of_zip_dso_entries = 0u; - bool need_to_scan_more_apks = true; - - AssemblyStoreIndexEntry *assembly_store_hashes; - xamarin::android::mutex assembly_decompress_mutex; + static inline const char *assemblies_prefix_override = nullptr; + + static inline md_mmap_info runtime_config_blob_mmap{}; + static inline void *runtime_config_data = nullptr; + static inline size_t runtime_config_data_size = 0uz; + static inline bool runtime_config_blob_found = false; + static inline uint32_t number_of_mapped_assembly_stores = 0u; + static inline uint32_t number_of_zip_dso_entries = 0u; + static inline bool need_to_scan_more_apks = true; + + static inline AssemblyStoreIndexEntry *assembly_store_hashes; + static inline xamarin::android::mutex assembly_decompress_mutex; }; } diff --git a/src/native/monodroid/monodroid-glue.cc b/src/native/monodroid/monodroid-glue.cc index 09a4dba28f2..d9eca63b7a4 100644 --- a/src/native/monodroid/monodroid-glue.cc +++ b/src/native/monodroid/monodroid-glue.cc @@ -256,7 +256,7 @@ MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, } } - size_t cur_num_assemblies = embeddedAssemblies.register_from_apk (apk_file.get_cstr ()); + size_t cur_num_assemblies = EmbeddedAssemblies::register_from_apk (apk_file.get_cstr ()); *out_user_assemblies_count += (cur_num_assemblies - prev_num_assemblies); prev_num_assemblies = cur_num_assemblies; From 80154b51db738471760a441f2087bd528f0444d6 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Wed, 13 Nov 2024 10:39:59 -0800 Subject: [PATCH 04/12] More cleanup --- src/native/runtime-base/android-system.hh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/native/runtime-base/android-system.hh b/src/native/runtime-base/android-system.hh index 3afe52debb3..4ff2afe982d 100644 --- a/src/native/runtime-base/android-system.hh +++ b/src/native/runtime-base/android-system.hh @@ -174,13 +174,15 @@ namespace xamarin::android::internal { static bool is_interpreter_enabled () noexcept { - return get_mono_aot_mode () == MonoAotMode::MONO_AOT_MODE_INTERP_ONLY; - } - - // Hack, see comment for `aot_mode_last_is_interpreter` at the bottom of the class declaration - static bool is_aot_mode_last_really_interpreter_mode () noexcept - { - return false; + switch (get_mono_aot_mode ()) { + case MonoAotMode::MONO_AOT_MODE_INTERP: + case MonoAotMode::MONO_AOT_MODE_INTERP_ONLY: + case MonoAotMode::MONO_AOT_MODE_INTERP_LLVMONLY: + return true; + + default: + return false; + } } static void set_running_in_emulator (bool yesno) noexcept From 4218e1bae5de07504e55d1c7a99b131695ebb411 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Wed, 13 Nov 2024 10:58:18 -0800 Subject: [PATCH 05/12] More move to static, more cleanup --- src/native/monodroid/debug.cc | 2 +- src/native/monodroid/embedded-assemblies.cc | 10 ++++----- src/native/monodroid/embedded-assemblies.hh | 14 ++++++------ src/native/monodroid/globals.cc | 3 --- src/native/monodroid/globals.hh | 1 - src/native/monodroid/internal-pinvokes.cc | 2 +- src/native/monodroid/monodroid-glue.cc | 24 ++++++++++----------- 7 files changed, 26 insertions(+), 30 deletions(-) diff --git a/src/native/monodroid/debug.cc b/src/native/monodroid/debug.cc index add61468747..db787268f41 100644 --- a/src/native/monodroid/debug.cc +++ b/src/native/monodroid/debug.cc @@ -515,7 +515,7 @@ Debug::start_debugging (void) if (sdb_fd == 0) return; - embeddedAssemblies.set_register_debug_symbols (true); + EmbeddedAssemblies::set_register_debug_symbols (true); char *debug_arg = Util::monodroid_strdup_printf ("--debugger-agent=transport=socket-fd,address=%d,embedding=1", sdb_fd); std::array debug_options = { diff --git a/src/native/monodroid/embedded-assemblies.cc b/src/native/monodroid/embedded-assemblies.cc index f5855dfd832..db3704f160f 100644 --- a/src/native/monodroid/embedded-assemblies.cc +++ b/src/native/monodroid/embedded-assemblies.cc @@ -493,7 +493,7 @@ MonoAssembly* EmbeddedAssemblies::open_from_bundles (MonoAssemblyLoadContextGCHandle alc_gchandle, MonoAssemblyName *aname, [[maybe_unused]] char **assemblies_path, [[maybe_unused]] void *user_data, MonoError *error) { constexpr bool ref_only = false; - return embeddedAssemblies.open_from_bundles (aname, alc_gchandle, error, ref_only); + return EmbeddedAssemblies::open_from_bundles (aname, alc_gchandle, error, ref_only); } MonoAssembly* @@ -501,17 +501,17 @@ EmbeddedAssemblies::open_from_bundles_full (MonoAssemblyName *aname, [[maybe_unu { constexpr bool ref_only = false; - return embeddedAssemblies.open_from_bundles (aname, ref_only /* loader_data */, nullptr /* error */, ref_only); + return EmbeddedAssemblies::open_from_bundles (aname, ref_only /* loader_data */, nullptr /* error */, ref_only); } void -EmbeddedAssemblies::install_preload_hooks_for_appdomains () +EmbeddedAssemblies::install_preload_hooks_for_appdomains () noexcept { mono_install_assembly_preload_hook (open_from_bundles_full, nullptr); } void -EmbeddedAssemblies::install_preload_hooks_for_alc () +EmbeddedAssemblies::install_preload_hooks_for_alc () noexcept { mono_install_assembly_preload_hook_v3 ( open_from_bundles, @@ -679,7 +679,7 @@ EmbeddedAssemblies::typemap_java_to_managed (hash_t hash, const MonoString *java } else { MonoAssemblyLoadContextGCHandle alc_gchandle = mono_alc_get_default_gchandle (); MonoError mono_error; - assm = embeddedAssemblies.open_from_bundles (assembly_name, alc_gchandle, &mono_error, false /* ref_only */); + assm = EmbeddedAssemblies::open_from_bundles (assembly_name, alc_gchandle, &mono_error, false /* ref_only */); } if (assm == nullptr) { diff --git a/src/native/monodroid/embedded-assemblies.hh b/src/native/monodroid/embedded-assemblies.hh index 1ac42b9d1de..efaa296a0a7 100644 --- a/src/native/monodroid/embedded-assemblies.hh +++ b/src/native/monodroid/embedded-assemblies.hh @@ -122,11 +122,11 @@ namespace xamarin::android::internal { {} #endif // def RELEASE - STATIC_IN_ANDROID_RELEASE const char* typemap_managed_to_java (MonoReflectionType *type, const uint8_t *mvid) noexcept; + static const char* typemap_managed_to_java (MonoReflectionType *type, const uint8_t *mvid) noexcept; - void install_preload_hooks_for_appdomains (); - void install_preload_hooks_for_alc (); - STATIC_IN_ANDROID_RELEASE MonoReflectionType* typemap_java_to_managed (MonoString *java_type) noexcept; + static void install_preload_hooks_for_appdomains () noexcept; + static void install_preload_hooks_for_alc () noexcept; + static MonoReflectionType* typemap_java_to_managed (MonoString *java_type) noexcept; /* returns current number of *all* assemblies found from all invocations */ template @@ -205,8 +205,8 @@ namespace xamarin::android::internal { } private: - STATIC_IN_ANDROID_RELEASE const char* typemap_managed_to_java (MonoType *type, MonoClass *klass, const uint8_t *mvid) noexcept; - STATIC_IN_ANDROID_RELEASE MonoReflectionType* typemap_java_to_managed (hash_t hash, const MonoString *java_type_name) noexcept; + static const char* typemap_managed_to_java (MonoType *type, MonoClass *klass, const uint8_t *mvid) noexcept; + static MonoReflectionType* typemap_java_to_managed (hash_t hash, const MonoString *java_type_name) noexcept; static size_t register_from_apk (const char *apk_file, monodroid_should_register should_register) noexcept; static size_t register_from_filesystem (monodroid_should_register should_register) noexcept; static size_t register_from_filesystem (const char *dir, bool look_for_mangled_names, monodroid_should_register should_register) noexcept; @@ -247,7 +247,7 @@ namespace xamarin::android::internal { bool typemap_load_file (int dir_fd, const char *dir_path, const char *file_path, TypeMap &module); bool typemap_load_file (BinaryTypeMapHeader &header, const char *dir_path, const char *file_path, int file_fd, TypeMap &module); static ssize_t do_read (int fd, void *buf, size_t count); - const TypeMapEntry *typemap_managed_to_java (const char *managed_type_name) noexcept; + static const TypeMapEntry *typemap_managed_to_java (const char *managed_type_name) noexcept; #endif // DEBUG static md_mmap_info md_mmap_apk_file (int fd, uint32_t offset, size_t size, const char* filename); diff --git a/src/native/monodroid/globals.cc b/src/native/monodroid/globals.cc index eb1a2c87fe4..7822952f8f0 100644 --- a/src/native/monodroid/globals.cc +++ b/src/native/monodroid/globals.cc @@ -3,10 +3,7 @@ using namespace xamarin::android; using namespace xamarin::android::internal; -Util utils; -AndroidSystem androidSystem; OSBridge osBridge; -EmbeddedAssemblies embeddedAssemblies; MonodroidRuntime monodroidRuntime; Timing *timing = nullptr; diff --git a/src/native/monodroid/globals.hh b/src/native/monodroid/globals.hh index 7717ec2ec79..6f1649d9796 100644 --- a/src/native/monodroid/globals.hh +++ b/src/native/monodroid/globals.hh @@ -11,7 +11,6 @@ extern xamarin::android::Debug debug; extern xamarin::android::internal::OSBridge osBridge; -extern xamarin::android::internal::EmbeddedAssemblies embeddedAssemblies; extern xamarin::android::internal::MonodroidRuntime monodroidRuntime; extern xamarin::android::Timing *timing; diff --git a/src/native/monodroid/internal-pinvokes.cc b/src/native/monodroid/internal-pinvokes.cc index 0df3d868715..2324084a3f7 100644 --- a/src/native/monodroid/internal-pinvokes.cc +++ b/src/native/monodroid/internal-pinvokes.cc @@ -21,7 +21,7 @@ monodroid_get_system_property (const char *name, char **value) int monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix) { - embeddedAssemblies.set_assemblies_prefix (prefix); + EmbeddedAssemblies::set_assemblies_prefix (prefix); return 0; } diff --git a/src/native/monodroid/monodroid-glue.cc b/src/native/monodroid/monodroid-glue.cc index d9eca63b7a4..d40d9b264ae 100644 --- a/src/native/monodroid/monodroid-glue.cc +++ b/src/native/monodroid/monodroid-glue.cc @@ -228,7 +228,7 @@ inline void MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, size_t *out_user_assemblies_count, bool have_split_apks) { if (!AndroidSystem::is_embedded_dso_mode_enabled ()) { - *out_user_assemblies_count = embeddedAssemblies.register_from_filesystem (); + *out_user_assemblies_count = EmbeddedAssemblies::register_from_filesystem (); return; } @@ -261,12 +261,12 @@ MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, *out_user_assemblies_count += (cur_num_assemblies - prev_num_assemblies); prev_num_assemblies = cur_num_assemblies; - if (!embeddedAssemblies.keep_scanning ()) { + if (!EmbeddedAssemblies::keep_scanning ()) { break; } } - embeddedAssemblies.ensure_valid_assembly_stores (); + EmbeddedAssemblies::ensure_valid_assembly_stores (); } #if defined (DEBUG) @@ -495,7 +495,7 @@ MonodroidRuntime::set_debug_options (void) if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_DEBUG_PROPERTY, nullptr) == 0) return; - embeddedAssemblies.set_register_debug_symbols (true); + EmbeddedAssemblies::set_register_debug_symbols (true); mono_debug_init (MONO_DEBUG_FORMAT_MONO); } @@ -513,7 +513,7 @@ MonodroidRuntime::mono_runtime_init ([[maybe_unused]] JNIEnv *env, [[maybe_unuse } else if (options.debug && cur_time > options.timeout_time) { log_warn (LOG_DEBUGGER, "Not starting the debugger as the timeout value has been reached; current-time: %lli timeout: %lli", cur_time, options.timeout_time); } else if (options.debug && cur_time <= options.timeout_time) { - embeddedAssemblies.set_register_debug_symbols (true); + EmbeddedAssemblies::set_register_debug_symbols (true); int loglevel; if (Logger::have_debugger_log_level ()) @@ -687,7 +687,7 @@ MonodroidRuntime::mono_runtime_init ([[maybe_unused]] JNIEnv *env, [[maybe_unuse * Looking for assemblies from the update dir takes precedence over * everything else, and thus must go LAST. */ - embeddedAssemblies.install_preload_hooks_for_appdomains (); + EmbeddedAssemblies::install_preload_hooks_for_appdomains (); #ifndef RELEASE mono_install_assembly_preload_hook (open_from_update_dir, nullptr); #endif @@ -702,7 +702,7 @@ MonodroidRuntime::mono_runtime_init ([[maybe_unused]] JNIEnv *env, [[maybe_unuse void MonodroidRuntime::cleanup_runtime_config ([[maybe_unused]] MonovmRuntimeConfigArguments *args, [[maybe_unused]] void *user_data) { - embeddedAssemblies.unmap_runtime_config_blob (); + EmbeddedAssemblies::unmap_runtime_config_blob (); } MonoDomain* @@ -712,14 +712,14 @@ MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks gather_bundled_assemblies (runtimeApks, &user_assemblies_count, have_split_apks); - if (embeddedAssemblies.have_runtime_config_blob ()) { + if (EmbeddedAssemblies::have_runtime_config_blob ()) { size_t blob_time_index; if (FastTiming::enabled ()) [[unlikely]] { blob_time_index = internal_timing->start_event (TimingEventKind::RuntimeConfigBlob); } runtime_config_args.kind = 1; - embeddedAssemblies.get_runtime_config_blob (runtime_config_args.runtimeconfig.data.data, runtime_config_args.runtimeconfig.data.data_len); + EmbeddedAssemblies::get_runtime_config_blob (runtime_config_args.runtimeconfig.data.data, runtime_config_args.runtimeconfig.data.data_len); monovm_runtimeconfig_initialize (&runtime_config_args, cleanup_runtime_config, nullptr); if (FastTiming::enabled ()) [[unlikely]] { @@ -1267,7 +1267,7 @@ MonodroidRuntime::create_and_initialize_domain (JNIEnv* env, jclass runtimeClass default_alc = mono_alc_get_default_gchandle (); abort_unless (default_alc != nullptr, "Default AssemblyLoadContext not found"); - embeddedAssemblies.install_preload_hooks_for_alc (); + EmbeddedAssemblies::install_preload_hooks_for_alc (); log_debug (LOG_ASSEMBLY, "ALC hooks installed"); bool preload = (AndroidSystem::is_assembly_preload_enabled () || (is_running_on_desktop && force_preload_assemblies)); @@ -1289,13 +1289,13 @@ MonodroidRuntime::monodroid_unhandled_exception (MonoObject *java_exception) MonoReflectionType* MonodroidRuntime::typemap_java_to_managed (MonoString *java_type_name) noexcept { - return embeddedAssemblies.typemap_java_to_managed (java_type_name); + return EmbeddedAssemblies::typemap_java_to_managed (java_type_name); } const char* MonodroidRuntime::typemap_managed_to_java (MonoReflectionType *type, const uint8_t *mvid) noexcept { - return embeddedAssemblies.typemap_managed_to_java (type, mvid); + return EmbeddedAssemblies::typemap_managed_to_java (type, mvid); } #endif // !def RELEASE From ab571703428193856410412c9c27db908f96d5a9 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Wed, 13 Nov 2024 14:50:37 -0800 Subject: [PATCH 06/12] MonodroidRuntime is static now --- src/native/monodroid/globals.cc | 1 - src/native/monodroid/globals.hh | 1 - src/native/monodroid/internal-pinvokes.cc | 16 +-- .../monodroid/monodroid-glue-internal.hh | 116 ++++++++---------- src/native/monodroid/monodroid-glue.cc | 74 +++++------ 5 files changed, 99 insertions(+), 109 deletions(-) diff --git a/src/native/monodroid/globals.cc b/src/native/monodroid/globals.cc index 7822952f8f0..d5fdf4d08e4 100644 --- a/src/native/monodroid/globals.cc +++ b/src/native/monodroid/globals.cc @@ -4,7 +4,6 @@ using namespace xamarin::android; using namespace xamarin::android::internal; OSBridge osBridge; -MonodroidRuntime monodroidRuntime; Timing *timing = nullptr; Debug debug; diff --git a/src/native/monodroid/globals.hh b/src/native/monodroid/globals.hh index 6f1649d9796..046a0ff770f 100644 --- a/src/native/monodroid/globals.hh +++ b/src/native/monodroid/globals.hh @@ -11,7 +11,6 @@ extern xamarin::android::Debug debug; extern xamarin::android::internal::OSBridge osBridge; -extern xamarin::android::internal::MonodroidRuntime monodroidRuntime; extern xamarin::android::Timing *timing; #endif // !__GLOBALS_H diff --git a/src/native/monodroid/internal-pinvokes.cc b/src/native/monodroid/internal-pinvokes.cc index 2324084a3f7..c61768ea173 100644 --- a/src/native/monodroid/internal-pinvokes.cc +++ b/src/native/monodroid/internal-pinvokes.cc @@ -135,13 +135,13 @@ _monodroid_gc_wait_for_bridge_processing () void monodroid_clear_gdb_wait () { - monodroidRuntime.set_monodroid_gdb_wait (false); + MonodroidRuntime::set_monodroid_gdb_wait (false); } void* _monodroid_get_identity_hash_code (JNIEnv *env, void *v) { - intptr_t rv = env->CallStaticIntMethod (monodroidRuntime.get_java_class_System (), monodroidRuntime.get_java_class_method_System_identityHashCode (), v); + intptr_t rv = env->CallStaticIntMethod (MonodroidRuntime::get_java_class_System (), MonodroidRuntime::get_java_class_method_System_identityHashCode (), v); return (void*) rv; } @@ -149,9 +149,9 @@ void* _monodroid_timezone_get_default_id () { JNIEnv *env = osBridge.ensure_jnienv (); - jmethodID getDefault = env->GetStaticMethodID (monodroidRuntime.get_java_class_TimeZone (), "getDefault", "()Ljava/util/TimeZone;"); - jmethodID getID = env->GetMethodID (monodroidRuntime.get_java_class_TimeZone (), "getID", "()Ljava/lang/String;"); - jobject d = env->CallStaticObjectMethod (monodroidRuntime.get_java_class_TimeZone (), getDefault); + jmethodID getDefault = env->GetStaticMethodID (MonodroidRuntime::get_java_class_TimeZone (), "getDefault", "()Ljava/util/TimeZone;"); + jmethodID getID = env->GetMethodID (MonodroidRuntime::get_java_class_TimeZone (), "getID", "()Ljava/lang/String;"); + jobject d = env->CallStaticObjectMethod (MonodroidRuntime::get_java_class_TimeZone (), getDefault); jstring id = reinterpret_cast (env->CallObjectMethod (d, getID)); const char *mutf8 = env->GetStringUTFChars (id, nullptr); @@ -175,7 +175,7 @@ void _monodroid_counters_dump ([[maybe_unused]] const char *format, [[maybe_unused]] va_list args) { #if !defined (NET) - monodroidRuntime.dump_counters_v (format, args); + MonodroidRuntime::dump_counters_v (format, args); #endif // ndef NET } @@ -234,7 +234,7 @@ monodroid_strdup_printf (const char *format, ...) char* monodroid_TypeManager_get_java_class_name (jclass klass) { - return monodroidRuntime.get_java_class_name_for_TypeManager (klass); + return MonodroidRuntime::get_java_class_name_for_TypeManager (klass); } int @@ -333,5 +333,5 @@ monodroid_log_traces (uint32_t kind, const char *first_line) JNIEnv *env = osBridge.ensure_jnienv (); auto tk = static_cast(kind); - monodroidRuntime.log_traces (env, tk, first_line); + MonodroidRuntime::log_traces (env, tk, first_line); } diff --git a/src/native/monodroid/monodroid-glue-internal.hh b/src/native/monodroid/monodroid-glue-internal.hh index abbd8a8d4c6..59f00ceffd2 100644 --- a/src/native/monodroid/monodroid-glue-internal.hh +++ b/src/native/monodroid/monodroid-glue-internal.hh @@ -115,45 +115,45 @@ namespace xamarin::android::internal static constexpr int XA_LOG_COUNTERS = MONO_COUNTER_JIT | MONO_COUNTER_METADATA | MONO_COUNTER_GC | MONO_COUNTER_GENERICS | MONO_COUNTER_INTERP; public: - void Java_mono_android_Runtime_register (JNIEnv *env, jstring managedType, jclass nativeClass, jstring methods); - void Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, + static void Java_mono_android_Runtime_register (JNIEnv *env, jstring managedType, jclass nativeClass, jstring methods) noexcept; + static void Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, jstring runtimeNativeLibDir, jobjectArray appDirs, jint localDateTimeOffset, jobject loader, jobjectArray assembliesJava, jboolean isEmulator, - jboolean haveSplitApks); + jboolean haveSplitApks) noexcept; - jint Java_JNI_OnLoad (JavaVM *vm, void *reserved); + static jint Java_JNI_OnLoad (JavaVM *vm, void *reserved) noexcept; - jclass get_java_class_System () const + static jclass get_java_class_System () noexcept { return java_System; } - jmethodID get_java_class_method_System_identityHashCode () const + static jmethodID get_java_class_method_System_identityHashCode () noexcept { return java_System_identityHashCode; } - jclass get_java_class_TimeZone () const + static jclass get_java_class_TimeZone () noexcept { return java_TimeZone; } - void set_monodroid_gdb_wait (bool yes_no) + static void set_monodroid_gdb_wait (bool yes_no) noexcept { monodroid_gdb_wait = yes_no; } - void propagate_uncaught_exception (JNIEnv *env, jobject javaThread, jthrowable javaException); - char* get_java_class_name_for_TypeManager (jclass klass); - void log_traces (JNIEnv *env, TraceKind kind, const char *first_line) noexcept; + static void propagate_uncaught_exception (JNIEnv *env, jobject javaThread, jthrowable javaException) noexcept; + static char* get_java_class_name_for_TypeManager (jclass klass) noexcept; + static void log_traces (JNIEnv *env, TraceKind kind, const char *first_line) noexcept; private: static void mono_log_handler (const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data); static void mono_log_standard_streams_handler (const char *str, mono_bool is_stdout); // A reference to unique_ptr is not the best practice ever, but it's faster this way - void setup_mono_tracing (std::unique_ptr const& mono_log_mask, bool have_log_assembly, bool have_log_gc); - void install_logging_handlers (); + static void setup_mono_tracing (std::unique_ptr const& mono_log_mask, bool have_log_assembly, bool have_log_gc) noexcept; + static void install_logging_handlers () noexcept; unsigned int convert_dl_flags (int flags); @@ -174,45 +174,45 @@ namespace xamarin::android::internal fnptr = reinterpret_cast(symptr); } - void create_xdg_directory (jstring_wrapper& home, size_t home_len, std::string_view const& relative_path, std::string_view const& environment_variable_name) noexcept; - void create_xdg_directories_and_environment (jstring_wrapper &homeDir); - void lookup_bridge_info (MonoClass *klass, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info); - void lookup_bridge_info (MonoImage *image, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info); - void load_assembly (MonoDomain *domain, jstring_wrapper &assembly); - void load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, jstring_wrapper &assembly); - void load_assemblies (load_assemblies_context_type ctx, bool preload, jstring_array_wrapper &assemblies); - - void set_debug_options (); - void parse_gdb_options (); - void mono_runtime_init (JNIEnv *env, dynamic_local_string& runtime_args); - void init_android_runtime (JNIEnv *env, jclass runtimeClass, jobject loader); - void set_environment_variable_for_directory (const char *name, jstring_wrapper &value, bool createDirectory, mode_t mode); - - void set_environment_variable_for_directory (const char *name, jstring_wrapper &value) + static void create_xdg_directory (jstring_wrapper& home, size_t home_len, std::string_view const& relative_path, std::string_view const& environment_variable_name) noexcept; + static void create_xdg_directories_and_environment (jstring_wrapper &homeDir) noexcept; + static void lookup_bridge_info (MonoClass *klass, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) noexcept; + static void lookup_bridge_info (MonoImage *image, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) noexcept; + static void load_assembly (MonoDomain *domain, jstring_wrapper &assembly) noexcept; + static void load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, jstring_wrapper &assembly) noexcept; + static void load_assemblies (load_assemblies_context_type ctx, bool preload, jstring_array_wrapper &assemblies) noexcept; + + static void set_debug_options () noexcept; + static void parse_gdb_options () noexcept; + static void mono_runtime_init (JNIEnv *env, dynamic_local_string& runtime_args) noexcept; + static void init_android_runtime (JNIEnv *env, jclass runtimeClass, jobject loader) noexcept; + static void set_environment_variable_for_directory (const char *name, jstring_wrapper &value, bool createDirectory, mode_t mode) noexcept; + + static void set_environment_variable_for_directory (const char *name, jstring_wrapper &value) noexcept { set_environment_variable_for_directory (name, value, true, DEFAULT_DIRECTORY_MODE); } - void set_environment_variable (const char *name, jstring_wrapper &value) + static void set_environment_variable (const char *name, jstring_wrapper &value) noexcept { set_environment_variable_for_directory (name, value, false, 0); } static void monodroid_unhandled_exception (MonoObject *java_exception); - MonoClass* get_android_runtime_class (); + static MonoClass* get_android_runtime_class () noexcept; - MonoDomain* create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks, bool is_root_domain, bool have_split_apks); - MonoDomain* create_and_initialize_domain (JNIEnv* env, jclass runtimeClass, jstring_array_wrapper &runtimeApks, + static MonoDomain* create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks, bool is_root_domain, bool have_split_apks) noexcept; + static MonoDomain* create_and_initialize_domain (JNIEnv* env, jclass runtimeClass, jstring_array_wrapper &runtimeApks, jstring_array_wrapper &assemblies, jobjectArray assembliesBytes, jstring_array_wrapper &assembliesPaths, jobject loader, bool is_root_domain, bool force_preload_assemblies, - bool have_split_apks); + bool have_split_apks) noexcept; - void gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, size_t *out_user_assemblies_count, bool have_split_apks); + static void gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, size_t *out_user_assemblies_count, bool have_split_apks) noexcept; static bool should_register_file (const char *filename); - void set_trace_options (); - void set_profile_options (); + static void set_trace_options () noexcept; + static void set_profile_options () noexcept; - void log_jit_event (MonoMethod *method, const char *event_name); + static void log_jit_event (MonoMethod *method, const char *event_name) noexcept; static void jit_begin (MonoProfiler *prof, MonoMethod *method); static void jit_failed (MonoProfiler *prof, MonoMethod *method); static void jit_done (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo); @@ -236,44 +236,36 @@ namespace xamarin::android::internal #endif // def RELEASE #if defined (DEBUG) - void set_debug_env_vars (void); - bool parse_runtime_args (dynamic_local_string &runtime_args, RuntimeOptions *options); - int monodroid_debug_connect (int sock, struct sockaddr_in addr); - int monodroid_debug_accept (int sock, struct sockaddr_in addr); + static inline void set_debug_env_vars (void) noexcept; + static inline bool parse_runtime_args (dynamic_local_string &runtime_args, RuntimeOptions *options) noexcept; + static inline int monodroid_debug_connect (int sock, struct sockaddr_in addr) noexcept; + static inline int monodroid_debug_accept (int sock, struct sockaddr_in addr) noexcept; #endif // DEBUG #if !defined (RELEASE) static MonoAssembly* open_from_update_dir (MonoAssemblyName *aname, char **assemblies_path, void *user_data); #endif private: - MonoMethod *registerType = nullptr; - volatile bool monodroid_gdb_wait = true; - jclass java_System; - jmethodID java_System_identityHashCode; - jmethodID Class_getName; - jclass java_TimeZone; - timing_period jit_time; - FILE *jit_log; - MonoProfilerHandle profiler_handle; + static inline MonoMethod *registerType = nullptr; + static inline bool monodroid_gdb_wait = true; + static inline jclass java_System; + static inline jmethodID java_System_identityHashCode; + static inline jmethodID Class_getName; + static inline jclass java_TimeZone; + static inline timing_period jit_time; + static inline FILE *jit_log = nullptr; + static inline MonoProfilerHandle profiler_handle; /* * If set, monodroid will spin in a loop until the debugger breaks the wait by * clearing monodroid_gdb_wait. */ - bool wait_for_gdb; - - /* The context (mapping to a Mono AppDomain) that is currently selected as the - * active context from the point of view of Java. We cannot rely on the value - * of `mono_domain_get` for this as it's stored per-thread and we want to be - * able to switch our different contexts from different threads. - */ - int current_context_id = -1; - - jnienv_register_jni_natives_fn jnienv_register_jni_natives = nullptr; - MonoAssemblyLoadContextGCHandle default_alc = nullptr; + static inline bool wait_for_gdb = false; + static inline jnienv_register_jni_natives_fn jnienv_register_jni_natives = nullptr; + static inline MonoAssemblyLoadContextGCHandle default_alc = nullptr; static MonoCoreRuntimeProperties monovm_core_properties; - MonovmRuntimeConfigArguments runtime_config_args; + static inline MonovmRuntimeConfigArguments runtime_config_args; }; } #endif diff --git a/src/native/monodroid/monodroid-glue.cc b/src/native/monodroid/monodroid-glue.cc index d40d9b264ae..a90e239e83f 100644 --- a/src/native/monodroid/monodroid-glue.cc +++ b/src/native/monodroid/monodroid-glue.cc @@ -102,7 +102,7 @@ MonodroidRuntime::thread_end ([[maybe_unused]] MonoProfiler *prof, [[maybe_unuse } inline void -MonodroidRuntime::log_jit_event (MonoMethod *method, const char *event_name) +MonodroidRuntime::log_jit_event (MonoMethod *method, const char *event_name) noexcept { jit_time.mark_end (); @@ -120,19 +120,19 @@ MonodroidRuntime::log_jit_event (MonoMethod *method, const char *event_name) void MonodroidRuntime::jit_begin ([[maybe_unused]] MonoProfiler *prof, MonoMethod *method) { - monodroidRuntime.log_jit_event (method, "begin"); + MonodroidRuntime::log_jit_event (method, "begin"); } void MonodroidRuntime::jit_failed ([[maybe_unused]] MonoProfiler *prof, MonoMethod *method) { - monodroidRuntime.log_jit_event (method, "failed"); + MonodroidRuntime::log_jit_event (method, "failed"); } void MonodroidRuntime::jit_done ([[maybe_unused]] MonoProfiler *prof, MonoMethod *method, [[maybe_unused]] MonoJitInfo* jinfo) { - monodroidRuntime.log_jit_event (method, "done"); + MonodroidRuntime::log_jit_event (method, "done"); } #ifndef RELEASE @@ -225,7 +225,7 @@ MonodroidRuntime::should_register_file ([[maybe_unused]] const char *filename) } inline void -MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, size_t *out_user_assemblies_count, bool have_split_apks) +MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, size_t *out_user_assemblies_count, bool have_split_apks) noexcept { if (!AndroidSystem::is_embedded_dso_mode_enabled ()) { *out_user_assemblies_count = EmbeddedAssemblies::register_from_filesystem (); @@ -271,7 +271,7 @@ MonodroidRuntime::gather_bundled_assemblies (jstring_array_wrapper &runtimeApks, #if defined (DEBUG) int -MonodroidRuntime::monodroid_debug_connect (int sock, struct sockaddr_in addr) +MonodroidRuntime::monodroid_debug_connect (int sock, struct sockaddr_in addr) noexcept { long flags = fcntl (sock, F_GETFL, nullptr); flags |= O_NONBLOCK; @@ -316,7 +316,7 @@ MonodroidRuntime::monodroid_debug_connect (int sock, struct sockaddr_in addr) } int -MonodroidRuntime::monodroid_debug_accept (int sock, struct sockaddr_in addr) +MonodroidRuntime::monodroid_debug_accept (int sock, struct sockaddr_in addr) noexcept { ssize_t res = bind (sock, (struct sockaddr *) &addr, sizeof (addr)); if (res < 0) @@ -342,7 +342,7 @@ MonodroidRuntime::monodroid_debug_accept (int sock, struct sockaddr_in addr) #endif inline jint -MonodroidRuntime::Java_JNI_OnLoad (JavaVM *vm, [[maybe_unused]] void *reserved) +MonodroidRuntime::Java_JNI_OnLoad (JavaVM *vm, [[maybe_unused]] void *reserved) noexcept { JNIEnv *env; @@ -355,7 +355,7 @@ MonodroidRuntime::Java_JNI_OnLoad (JavaVM *vm, [[maybe_unused]] void *reserved) } void -MonodroidRuntime::parse_gdb_options () +MonodroidRuntime::parse_gdb_options () noexcept { dynamic_local_string val; @@ -389,7 +389,7 @@ MonodroidRuntime::parse_gdb_options () #if defined (DEBUG) bool -MonodroidRuntime::parse_runtime_args (dynamic_local_string &runtime_args, RuntimeOptions *options) +MonodroidRuntime::parse_runtime_args (dynamic_local_string &runtime_args, RuntimeOptions *options) noexcept { if (runtime_args.length () == 0) { log_warn (LOG_DEFAULT, "runtime args empty"); @@ -490,7 +490,7 @@ MonodroidRuntime::parse_runtime_args (dynamic_local_string& runtime_args) +MonodroidRuntime::mono_runtime_init ([[maybe_unused]] JNIEnv *env, [[maybe_unused]] dynamic_local_string& runtime_args) noexcept { #if defined (DEBUG) RuntimeOptions options{}; @@ -706,7 +706,7 @@ MonodroidRuntime::cleanup_runtime_config ([[maybe_unused]] MonovmRuntimeConfigAr } MonoDomain* -MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks, bool is_root_domain, bool have_split_apks) +MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks, bool is_root_domain, bool have_split_apks) noexcept { size_t user_assemblies_count = 0uz; @@ -773,7 +773,7 @@ MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks } force_inline void -MonodroidRuntime::lookup_bridge_info (MonoClass *klass, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) +MonodroidRuntime::lookup_bridge_info (MonoClass *klass, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) noexcept { info->klass = klass; info->handle = mono_class_get_field_from_name (info->klass, const_cast ("handle")); @@ -798,7 +798,7 @@ MonodroidRuntime::lookup_bridge_info (MonoClass *klass, const OSBridge::MonoJava } force_inline void -MonodroidRuntime::lookup_bridge_info (MonoImage *image, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) +MonodroidRuntime::lookup_bridge_info (MonoImage *image, const OSBridge::MonoJavaGCBridgeType *type, OSBridge::MonoJavaGCBridgeInfo *info) noexcept { lookup_bridge_info ( mono_class_from_name (image, type->_namespace, type->_typename), @@ -814,7 +814,7 @@ MonodroidRuntime::monodroid_debugger_unhandled_exception (MonoException *ex) } void -MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobject loader) +MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobject loader) noexcept { constexpr std::string_view icall_typemap_java_to_managed { "Java.Interop.TypeManager::monodroid_typemap_java_to_managed" }; constexpr std::string_view icall_typemap_managed_to_java { "Android.Runtime.JNIEnv::monodroid_typemap_managed_to_java" }; @@ -960,7 +960,7 @@ MonodroidRuntime::init_android_runtime (JNIEnv *env, jclass runtimeClass, jobjec } MonoClass* -MonodroidRuntime::get_android_runtime_class () +MonodroidRuntime::get_android_runtime_class () noexcept { MonoAssembly *assm = Util::monodroid_load_assembly (default_alc, SharedConstants::MONO_ANDROID_ASSEMBLY_NAME.data ()); MonoImage *image = mono_assembly_get_image (assm); @@ -968,7 +968,7 @@ MonodroidRuntime::get_android_runtime_class () } inline void -MonodroidRuntime::propagate_uncaught_exception (JNIEnv *env, jobject javaThread, jthrowable javaException) +MonodroidRuntime::propagate_uncaught_exception (JNIEnv *env, jobject javaThread, jthrowable javaException) noexcept { MonoClass *runtime = get_android_runtime_class (); MonoMethod *method = mono_class_get_method_from_name (runtime, "PropagateUncaughtException", 3); @@ -991,7 +991,7 @@ setup_gc_logging (void) } inline void -MonodroidRuntime::set_environment_variable_for_directory (const char *name, jstring_wrapper &value, bool createDirectory, mode_t mode) +MonodroidRuntime::set_environment_variable_for_directory (const char *name, jstring_wrapper &value, bool createDirectory, mode_t mode) noexcept { if (createDirectory) { int rv = Util::create_directory (value.get_cstr (), mode); @@ -1016,7 +1016,7 @@ MonodroidRuntime::create_xdg_directory (jstring_wrapper& home, size_t home_len, } inline void -MonodroidRuntime::create_xdg_directories_and_environment (jstring_wrapper &homeDir) +MonodroidRuntime::create_xdg_directories_and_environment (jstring_wrapper &homeDir) noexcept { size_t home_len = strlen (homeDir.get_cstr ()); @@ -1031,7 +1031,7 @@ MonodroidRuntime::create_xdg_directories_and_environment (jstring_wrapper &homeD #if DEBUG void -MonodroidRuntime::set_debug_env_vars (void) +MonodroidRuntime::set_debug_env_vars (void) noexcept { dynamic_local_string value; if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_ENV_PROPERTY, value) == 0) @@ -1071,7 +1071,7 @@ MonodroidRuntime::set_debug_env_vars (void) #endif /* DEBUG */ inline void -MonodroidRuntime::set_trace_options (void) +MonodroidRuntime::set_trace_options (void) noexcept { dynamic_local_string value; if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_TRACE_PROPERTY, value) == 0) @@ -1081,7 +1081,7 @@ MonodroidRuntime::set_trace_options (void) } inline void -MonodroidRuntime::set_profile_options () +MonodroidRuntime::set_profile_options () noexcept { // We want to avoid dynamic allocation, thus let’s create a buffer that can take both the property value and a // path without allocation @@ -1146,7 +1146,7 @@ MonodroidRuntime::set_profile_options () } inline void -MonodroidRuntime::load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, jstring_wrapper &assembly) +MonodroidRuntime::load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, jstring_wrapper &assembly) noexcept { size_t total_time_index; if (FastTiming::enabled ()) [[unlikely]] { @@ -1178,7 +1178,7 @@ MonodroidRuntime::load_assembly (MonoAssemblyLoadContextGCHandle alc_handle, jst } inline void -MonodroidRuntime::load_assembly (MonoDomain *domain, jstring_wrapper &assembly) +MonodroidRuntime::load_assembly (MonoDomain *domain, jstring_wrapper &assembly) noexcept { size_t total_time_index; if (FastTiming::enabled ()) [[unlikely]] { @@ -1216,7 +1216,7 @@ MonodroidRuntime::load_assembly (MonoDomain *domain, jstring_wrapper &assembly) } inline void -MonodroidRuntime::load_assemblies (load_assemblies_context_type ctx, bool preload, jstring_array_wrapper &assemblies) +MonodroidRuntime::load_assemblies (load_assemblies_context_type ctx, bool preload, jstring_array_wrapper &assemblies) noexcept { size_t total_time_index; if (FastTiming::enabled ()) [[unlikely]] { @@ -1251,7 +1251,7 @@ MonoDomain* MonodroidRuntime::create_and_initialize_domain (JNIEnv* env, jclass runtimeClass, jstring_array_wrapper &runtimeApks, jstring_array_wrapper &assemblies, [[maybe_unused]] jobjectArray assembliesBytes, [[maybe_unused]] jstring_array_wrapper &assembliesPaths, jobject loader, bool is_root_domain, - bool force_preload_assemblies, bool have_split_apks) + bool force_preload_assemblies, bool have_split_apks) noexcept { MonoDomain* domain = create_domain (env, runtimeApks, is_root_domain, have_split_apks); // Asserting this on desktop apparently breaks a Designer test @@ -1300,7 +1300,7 @@ MonodroidRuntime::typemap_managed_to_java (MonoReflectionType *type, const uint8 #endif // !def RELEASE force_inline void -MonodroidRuntime::setup_mono_tracing (std::unique_ptr const& mono_log_mask, bool have_log_assembly, bool have_log_gc) +MonodroidRuntime::setup_mono_tracing (std::unique_ptr const& mono_log_mask, bool have_log_assembly, bool have_log_gc) noexcept { constexpr std::string_view MASK_ASM { "asm" }; constexpr std::string_view MASK_DLL { "dll" }; @@ -1373,7 +1373,7 @@ MonodroidRuntime::setup_mono_tracing (std::unique_ptr const& mono_log_ma } force_inline void -MonodroidRuntime::install_logging_handlers () +MonodroidRuntime::install_logging_handlers () noexcept { mono_trace_set_log_handler (mono_log_handler, nullptr); mono_trace_set_print_handler (mono_log_standard_streams_handler); @@ -1384,7 +1384,7 @@ inline void MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray runtimeApksJava, jstring runtimeNativeLibDir, jobjectArray appDirs, jint localDateTimeOffset, jobject loader, jobjectArray assembliesJava, jboolean isEmulator, - jboolean haveSplitApks) + jboolean haveSplitApks) noexcept { char *mono_log_mask_raw = nullptr; char *mono_log_level_raw = nullptr; @@ -1558,7 +1558,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM *vm, void *reserved) { Util::initialize (); - return monodroidRuntime.Java_JNI_OnLoad (vm, reserved); + return MonodroidRuntime::Java_JNI_OnLoad (vm, reserved); } /* !DO NOT REMOVE! Used by the Android Designer */ @@ -1568,7 +1568,7 @@ Java_mono_android_Runtime_init (JNIEnv *env, jclass klass, jstring lang, jobject [[maybe_unused]] jobjectArray externalStorageDirs, jobjectArray assembliesJava, [[maybe_unused]] jstring packageName, [[maybe_unused]] jint apiLevel, [[maybe_unused]] jobjectArray environmentVariables) { - monodroidRuntime.Java_mono_android_Runtime_initInternal ( + MonodroidRuntime::Java_mono_android_Runtime_initInternal ( env, klass, lang, @@ -1589,7 +1589,7 @@ Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, jobjectArray assembliesJava, jboolean isEmulator, jboolean haveSplitApks) { - monodroidRuntime.Java_mono_android_Runtime_initInternal ( + MonodroidRuntime::Java_mono_android_Runtime_initInternal ( env, klass, lang, @@ -1605,7 +1605,7 @@ Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang, } force_inline void -MonodroidRuntime::Java_mono_android_Runtime_register (JNIEnv *env, jstring managedType, jclass nativeClass, jstring methods) +MonodroidRuntime::Java_mono_android_Runtime_register (JNIEnv *env, jstring managedType, jclass nativeClass, jstring methods) noexcept { size_t total_time_index; @@ -1649,11 +1649,11 @@ JNICALL Java_mono_android_Runtime_dumpTimingData ([[maybe_unused]] JNIEnv *env, JNIEXPORT void JNICALL Java_mono_android_Runtime_register (JNIEnv *env, [[maybe_unused]] jclass klass, jstring managedType, jclass nativeClass, jstring methods) { - monodroidRuntime.Java_mono_android_Runtime_register (env, managedType, nativeClass, methods); + MonodroidRuntime::Java_mono_android_Runtime_register (env, managedType, nativeClass, methods); } char* -MonodroidRuntime::get_java_class_name_for_TypeManager (jclass klass) +MonodroidRuntime::get_java_class_name_for_TypeManager (jclass klass) noexcept { if (klass == nullptr || Class_getName == nullptr) return nullptr; @@ -1694,5 +1694,5 @@ get_jnienv (void) JNIEXPORT void JNICALL Java_mono_android_Runtime_propagateUncaughtException (JNIEnv *env, [[maybe_unused]] jclass klass, jobject javaThread, jthrowable javaException) { - monodroidRuntime.propagate_uncaught_exception (env, javaThread, javaException); + MonodroidRuntime::propagate_uncaught_exception (env, javaThread, javaException); } From 62663e9bbc8b8b8c64ad204b990c4e73bcf5bf88 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Wed, 13 Nov 2024 16:33:44 -0800 Subject: [PATCH 07/12] Buglets fixed --- src/native/monodroid/embedded-assemblies-zip.cc | 4 ++-- src/native/monodroid/embedded-assemblies.hh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/native/monodroid/embedded-assemblies-zip.cc b/src/native/monodroid/embedded-assemblies-zip.cc index 82a56859d88..f8d4811df7b 100644 --- a/src/native/monodroid/embedded-assemblies-zip.cc +++ b/src/native/monodroid/embedded-assemblies-zip.cc @@ -257,7 +257,7 @@ EmbeddedAssemblies::zip_load_assembly_store_entries (std::vector const& dynamic_local_string entry_name; bool assembly_store_found = false; - log_debug (LOG_ASSEMBLY, "Looking for assembly stores in APK ('%s)", assembly_store_file_path.data ()); + log_debug (LOG_ASSEMBLY, "Looking for assembly stores in APK ('%s')", assembly_store_file_path.data ()); for (size_t i = 0uz; i < num_entries; i++) { if (all_required_zip_entries_found ()) { need_to_scan_more_apks = false; @@ -269,7 +269,7 @@ EmbeddedAssemblies::zip_load_assembly_store_entries (std::vector const& continue; } - if (!assembly_store_found && Util::ends_with (entry_name, assembly_store_file_path)) { + if (!assembly_store_found && Util::ends_with (entry_name, assembly_store_file_path.data ())) { assembly_store_found = true; map_assembly_store (entry_name, state); continue; diff --git a/src/native/monodroid/embedded-assemblies.hh b/src/native/monodroid/embedded-assemblies.hh index efaa296a0a7..88d57c21d47 100644 --- a/src/native/monodroid/embedded-assemblies.hh +++ b/src/native/monodroid/embedded-assemblies.hh @@ -454,8 +454,8 @@ namespace xamarin::android::internal { static inline uint32_t number_of_zip_dso_entries = 0u; static inline bool need_to_scan_more_apks = true; - static inline AssemblyStoreIndexEntry *assembly_store_hashes; - static inline xamarin::android::mutex assembly_decompress_mutex; + static inline AssemblyStoreIndexEntry *assembly_store_hashes = nullptr; + static inline xamarin::android::mutex assembly_decompress_mutex {}; }; } From e20cbdd90b21b79b45ce1af79a49f42cf642f03d Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 21 Nov 2024 14:06:41 +0100 Subject: [PATCH 08/12] Trying to find out why AppContext.GetData doesn't appear to work --- src/native/monodroid/embedded-assemblies-zip.cc | 9 +++++++++ src/native/monodroid/embedded-assemblies.hh | 4 +++- src/native/monodroid/monodroid-glue.cc | 5 ++++- src/native/runtime-base/shared-constants.hh | 5 +++-- src/native/runtime-base/util.hh | 5 +++++ 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/native/monodroid/embedded-assemblies-zip.cc b/src/native/monodroid/embedded-assemblies-zip.cc index f8d4811df7b..0926b72c83c 100644 --- a/src/native/monodroid/embedded-assemblies-zip.cc +++ b/src/native/monodroid/embedded-assemblies-zip.cc @@ -46,6 +46,7 @@ EmbeddedAssemblies::zip_load_entry_common (size_t entry_index, std::vectorstart_event (TimingEventKind::RuntimeConfigBlob); @@ -720,7 +721,9 @@ MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks runtime_config_args.kind = 1; EmbeddedAssemblies::get_runtime_config_blob (runtime_config_args.runtimeconfig.data.data, runtime_config_args.runtimeconfig.data.data_len); - monovm_runtimeconfig_initialize (&runtime_config_args, cleanup_runtime_config, nullptr); + log_info (LOG_ASSEMBLY, " rc data == %p; rc size == %zu", runtime_config_args.runtimeconfig.data.data, runtime_config_args.runtimeconfig.data.data_len); + int ret = monovm_runtimeconfig_initialize (&runtime_config_args, cleanup_runtime_config, nullptr); + log_info (LOG_ASSEMBLY, " ret == %d", ret); if (FastTiming::enabled ()) [[unlikely]] { internal_timing->end_event (blob_time_index); diff --git a/src/native/runtime-base/shared-constants.hh b/src/native/runtime-base/shared-constants.hh index a3355963b59..963faacd1f1 100644 --- a/src/native/runtime-base/shared-constants.hh +++ b/src/native/runtime-base/shared-constants.hh @@ -40,13 +40,14 @@ namespace xamarin::android::internal static constexpr std::string_view DLL_EXTENSION { ".dll" }; static constexpr std::string_view PDB_EXTENSION { ".pdb" }; - private: +// private: static constexpr std::string_view RUNTIME_CONFIG_BLOB_BASE_NAME { "libarc.bin" }; static constexpr size_t runtime_config_blob_name_size = calc_size (RUNTIME_CONFIG_BLOB_BASE_NAME, MANGLED_ASSEMBLY_NAME_EXT); static constexpr auto RUNTIME_CONFIG_BLOB_NAME_ARRAY = concat_string_views (RUNTIME_CONFIG_BLOB_BASE_NAME, MANGLED_ASSEMBLY_NAME_EXT); public: - static constexpr std::string_view RUNTIME_CONFIG_BLOB_NAME { RUNTIME_CONFIG_BLOB_NAME_ARRAY }; + // .data() must be used otherwise string_view length will include the trailing \0 in the array + static constexpr std::string_view RUNTIME_CONFIG_BLOB_NAME { RUNTIME_CONFIG_BLOB_NAME_ARRAY.data () }; static constexpr std::string_view MONO_SGEN_SO { "libmonosgen-2.0.so" }; static constexpr std::string_view MONO_SGEN_ARCH_SO { "libmonosgen-" __BITNESS__ "-2.0.so" }; static constexpr std::string_view OVERRIDE_DIRECTORY_NAME { ".__override__" }; diff --git a/src/native/runtime-base/util.hh b/src/native/runtime-base/util.hh index 97db495dbea..554f421c510 100644 --- a/src/native/runtime-base/util.hh +++ b/src/native/runtime-base/util.hh @@ -167,6 +167,11 @@ namespace xamarin::android return false; } + log_debug (LOG_ASSEMBLY, " ends_with: '%s' -> '%s'; sv.length () == %zu", + str.get () + str.length () - sv.length (), + sv.data (), + sv.length () + ); return memcmp (str.get () + str.length () - sv.length (), sv.data (), sv.length ()) == 0; } From b4d4572d33138229498312a9c7d5abebc029d4ee Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Thu, 21 Nov 2024 18:11:21 +0100 Subject: [PATCH 09/12] Cleanup --- src/native/monodroid/embedded-assemblies-zip.cc | 9 --------- src/native/monodroid/embedded-assemblies.hh | 11 ++++++++--- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/native/monodroid/embedded-assemblies-zip.cc b/src/native/monodroid/embedded-assemblies-zip.cc index 0926b72c83c..f8d4811df7b 100644 --- a/src/native/monodroid/embedded-assemblies-zip.cc +++ b/src/native/monodroid/embedded-assemblies-zip.cc @@ -46,7 +46,6 @@ EmbeddedAssemblies::zip_load_entry_common (size_t entry_index, std::vector (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator); - static constexpr std::string_view assemblies_prefix { assemblies_prefix_array }; + + // .data() must be used otherwise string_view length will include the trailing \0 in the array + static constexpr std::string_view assemblies_prefix { assemblies_prefix_array.data () }; // We have two records for each assembly, for names with and without the extension static constexpr uint32_t assembly_store_index_entries_per_assembly = 2; @@ -104,11 +106,14 @@ namespace xamarin::android::internal { static constexpr size_t assembly_store_file_name_size = calc_size (assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); static constexpr auto assembly_store_file_name_array = concat_string_views (assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); - static constexpr std::string_view assembly_store_file_name { assembly_store_file_name_array }; + + // .data() must be used otherwise string_view length will include the trailing \0 in the array + static constexpr std::string_view assembly_store_file_name { assembly_store_file_name_array.data () }; static constexpr size_t assembly_store_file_path_size = calc_size(apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator, assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); static constexpr auto assembly_store_file_path_array = concat_string_views (apk_lib_dir_name, zip_path_separator, SharedConstants::android_lib_abi, zip_path_separator, assembly_store_prefix, SharedConstants::android_lib_abi, assembly_store_extension, dso_suffix); - static constexpr std::string_view assembly_store_file_path { assembly_store_file_path_array }; + // .data() must be used otherwise string_view length will include the trailing \0 in the array + static constexpr std::string_view assembly_store_file_path { assembly_store_file_path_array.data () }; static constexpr size_t dso_size_overhead = ArchiveDSOStubConfig::PayloadSectionOffset + (ArchiveDSOStubConfig::SectionHeaderEntryCount * ArchiveDSOStubConfig::SectionHeaderEntrySize); From 41bb6505ae4fd3a2f4a54ee1192a22a51ae75d0b Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Mon, 25 Nov 2024 13:19:09 +0100 Subject: [PATCH 10/12] Lengths and offsets... --- src/native/monodroid/embedded-assemblies.hh | 4 ++-- src/native/monodroid/internal-pinvokes.cc | 2 +- src/native/monodroid/monodroid-glue.cc | 5 +---- src/native/runtime-base/shared-constants.hh | 2 +- src/native/runtime-base/util.hh | 10 +++++----- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/native/monodroid/embedded-assemblies.hh b/src/native/monodroid/embedded-assemblies.hh index d84c3f03e19..ff153942724 100644 --- a/src/native/monodroid/embedded-assemblies.hh +++ b/src/native/monodroid/embedded-assemblies.hh @@ -341,10 +341,10 @@ namespace xamarin::android::internal { } if (application_config.have_assembly_store) { - return { apk_lib_prefix.data (), apk_lib_prefix.size () - 1 }; + return { apk_lib_prefix.data (), apk_lib_prefix.size () }; } - return {assemblies_prefix.data (), assemblies_prefix.size () - 1}; + return {assemblies_prefix.data (), assemblies_prefix.size () }; } static bool all_required_zip_entries_found () noexcept diff --git a/src/native/monodroid/internal-pinvokes.cc b/src/native/monodroid/internal-pinvokes.cc index c61768ea173..81367aaea29 100644 --- a/src/native/monodroid/internal-pinvokes.cc +++ b/src/native/monodroid/internal-pinvokes.cc @@ -22,7 +22,7 @@ int monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix) { EmbeddedAssemblies::set_assemblies_prefix (prefix); - return 0; + return 0; } void diff --git a/src/native/monodroid/monodroid-glue.cc b/src/native/monodroid/monodroid-glue.cc index 47d72442040..a90e239e83f 100644 --- a/src/native/monodroid/monodroid-glue.cc +++ b/src/native/monodroid/monodroid-glue.cc @@ -713,7 +713,6 @@ MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks gather_bundled_assemblies (runtimeApks, &user_assemblies_count, have_split_apks); if (EmbeddedAssemblies::have_runtime_config_blob ()) { - log_info (LOG_ASSEMBLY, "Got runtime config blob"); size_t blob_time_index; if (FastTiming::enabled ()) [[unlikely]] { blob_time_index = internal_timing->start_event (TimingEventKind::RuntimeConfigBlob); @@ -721,9 +720,7 @@ MonodroidRuntime::create_domain (JNIEnv *env, jstring_array_wrapper &runtimeApks runtime_config_args.kind = 1; EmbeddedAssemblies::get_runtime_config_blob (runtime_config_args.runtimeconfig.data.data, runtime_config_args.runtimeconfig.data.data_len); - log_info (LOG_ASSEMBLY, " rc data == %p; rc size == %zu", runtime_config_args.runtimeconfig.data.data, runtime_config_args.runtimeconfig.data.data_len); - int ret = monovm_runtimeconfig_initialize (&runtime_config_args, cleanup_runtime_config, nullptr); - log_info (LOG_ASSEMBLY, " ret == %d", ret); + monovm_runtimeconfig_initialize (&runtime_config_args, cleanup_runtime_config, nullptr); if (FastTiming::enabled ()) [[unlikely]] { internal_timing->end_event (blob_time_index); diff --git a/src/native/runtime-base/shared-constants.hh b/src/native/runtime-base/shared-constants.hh index 963faacd1f1..0b7264d5ce4 100644 --- a/src/native/runtime-base/shared-constants.hh +++ b/src/native/runtime-base/shared-constants.hh @@ -40,7 +40,7 @@ namespace xamarin::android::internal static constexpr std::string_view DLL_EXTENSION { ".dll" }; static constexpr std::string_view PDB_EXTENSION { ".pdb" }; -// private: + private: static constexpr std::string_view RUNTIME_CONFIG_BLOB_BASE_NAME { "libarc.bin" }; static constexpr size_t runtime_config_blob_name_size = calc_size (RUNTIME_CONFIG_BLOB_BASE_NAME, MANGLED_ASSEMBLY_NAME_EXT); static constexpr auto RUNTIME_CONFIG_BLOB_NAME_ARRAY = concat_string_views (RUNTIME_CONFIG_BLOB_BASE_NAME, MANGLED_ASSEMBLY_NAME_EXT); diff --git a/src/native/runtime-base/util.hh b/src/native/runtime-base/util.hh index 554f421c510..d3a8d950dbb 100644 --- a/src/native/runtime-base/util.hh +++ b/src/native/runtime-base/util.hh @@ -167,11 +167,11 @@ namespace xamarin::android return false; } - log_debug (LOG_ASSEMBLY, " ends_with: '%s' -> '%s'; sv.length () == %zu", - str.get () + str.length () - sv.length (), - sv.data (), - sv.length () - ); + // log_debug (LOG_ASSEMBLY, " ends_with: '%s' -> '%s'; sv.length () == %zu", + // str.get () + str.length () - sv.length (), + // sv.data (), + // sv.length () + // ); return memcmp (str.get () + str.length () - sv.length (), sv.data (), sv.length ()) == 0; } From 9794be218c204a99961fca09de6b95c110c43a4a Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Tue, 26 Nov 2024 09:51:09 +0100 Subject: [PATCH 11/12] Cleanup --- src/native/monodroid/embedded-assemblies-zip.cc | 2 +- src/native/runtime-base/util.hh | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/native/monodroid/embedded-assemblies-zip.cc b/src/native/monodroid/embedded-assemblies-zip.cc index f8d4811df7b..d807c633a23 100644 --- a/src/native/monodroid/embedded-assemblies-zip.cc +++ b/src/native/monodroid/embedded-assemblies-zip.cc @@ -269,7 +269,7 @@ EmbeddedAssemblies::zip_load_assembly_store_entries (std::vector const& continue; } - if (!assembly_store_found && Util::ends_with (entry_name, assembly_store_file_path.data ())) { + if (!assembly_store_found && Util::ends_with (entry_name, assembly_store_file_path)) { assembly_store_found = true; map_assembly_store (entry_name, state); continue; diff --git a/src/native/runtime-base/util.hh b/src/native/runtime-base/util.hh index d3a8d950dbb..97db495dbea 100644 --- a/src/native/runtime-base/util.hh +++ b/src/native/runtime-base/util.hh @@ -167,11 +167,6 @@ namespace xamarin::android return false; } - // log_debug (LOG_ASSEMBLY, " ends_with: '%s' -> '%s'; sv.length () == %zu", - // str.get () + str.length () - sv.length (), - // sv.data (), - // sv.length () - // ); return memcmp (str.get () + str.length () - sv.length (), sv.data (), sv.length ()) == 0; } From d9d80ea2dd23183b8cf10ebc51f454b862aced24 Mon Sep 17 00:00:00 2001 From: Marek Habersack Date: Tue, 3 Dec 2024 13:38:51 +0100 Subject: [PATCH 12/12] Address feedback --- src/native/shared/cpp-util.hh | 63 +++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/src/native/shared/cpp-util.hh b/src/native/shared/cpp-util.hh index f893d6614e3..a4546971a29 100644 --- a/src/native/shared/cpp-util.hh +++ b/src/native/shared/cpp-util.hh @@ -7,9 +7,12 @@ #include #include #include +#include #include +#include #include #include +#include #include #include @@ -30,6 +33,50 @@ namespace xamarin::android::detail { va_end (ap); return ret == -1 ? "Out of memory" : message; } + + [[gnu::always_inline]] + static inline std::string get_function_name (const char *signature) + { + using std::operator""sv; + + std::string_view sig { signature }; + if (sig.length () == 0) { + return ""; + } + + auto splitSignature = sig | std::views::split ("::"sv) | std::ranges::to> (); + + std::string ret; + if (splitSignature.size () > 1) { + ret.append (splitSignature [splitSignature.size () - 2]); + ret.append ("::"sv); + } + std::string_view func_name { splitSignature[splitSignature.size () - 1] }; + std::string_view::size_type args_pos = func_name.find ('('); + std::string_view::size_type name_start_pos = func_name.find (' '); + + if (name_start_pos == std::string_view::npos) { + name_start_pos = 0; + } else { + name_start_pos++; // point to after the space which separates return type from name + if (name_start_pos >= func_name.length ()) [[unlikely]] { + name_start_pos = 0; + } + } + + if (args_pos == std::string_view::npos) { + ret.append (func_name.substr (name_start_pos)); + } else { + // If there's a snafu with positions, start from 0 + if (name_start_pos >= args_pos || name_start_pos > func_name.length ()) [[unlikely]] { + name_start_pos = 0; + } + + ret.append (func_name.substr (name_start_pos, args_pos - name_start_pos)); + } + + return ret; + } } template F> @@ -63,7 +110,13 @@ abort_if_invalid_pointer_argument (T *ptr, const char *ptr_name, std::source_loc { abort_unless ( ptr != nullptr, - [&ptr_name] { return xamarin::android::detail::_format_message ("Parameter '%s' must be a valid pointer", ptr_name); }, + [&ptr_name, &sloc] { + return xamarin::android::detail::_format_message ( + "%s: parameter '%s' must be a valid pointer", + xamarin::android::detail::get_function_name (sloc.function_name ()).c_str (), + ptr_name + ); + }, sloc ); } @@ -74,7 +127,13 @@ abort_if_negative_integer_argument (int arg, const char *arg_name, std::source_l { abort_unless ( arg > 0, - [&arg_name] { return xamarin::android::detail::_format_message ("Parameter '%s' must be a valid pointer", arg_name); }, + [&arg_name, &sloc] { + return xamarin::android::detail::_format_message ( + "%s: parameter '%s' must be a valid pointer", + xamarin::android::detail::get_function_name (sloc.function_name ()).c_str (), + arg_name + ); + }, sloc ); }